@pie-players/pie-assessment-toolkit 0.3.68 → 0.3.69
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 +80 -8
- package/dist/components/ItemToolBar.custom-element.js +1 -1
- package/dist/components/PieAssessmentToolkit.custom-element.js +13 -13
- package/dist/components/SectionToolBar.custom-element.js +1 -1
- package/dist/components/chunks/ItemToolBar-pe5szfyx.js +46 -0
- package/dist/components/chunks/ItemToolBar-rd7te9r0.js +51 -0
- package/dist/policy/core/compose-decision.js +14 -0
- package/dist/policy/core/decision-types.d.ts +1 -1
- package/dist/policy/sources/PnpPolicySource.d.ts +8 -0
- package/dist/policy/sources/PnpPolicySource.js +19 -10
- package/dist/services/ToolRegistry.d.ts +34 -0
- package/dist/services/ToolRegistry.js +34 -0
- package/dist/services/tool-context.js +8 -3
- package/dist/services/tool-providers/CortexToolProvider.d.ts +18 -0
- package/dist/services/tool-providers/CortexToolProvider.js +32 -0
- package/dist/services/tool-providers/DesmosToolProvider.d.ts +13 -102
- package/dist/services/tool-providers/DesmosToolProvider.js +14 -145
- package/dist/services/tool-providers/GeoGebraToolProvider.d.ts +21 -0
- package/dist/services/tool-providers/GeoGebraToolProvider.js +32 -0
- package/dist/services/tool-providers/LazyCalculatorToolProvider.d.ts +35 -0
- package/dist/services/tool-providers/LazyCalculatorToolProvider.js +95 -0
- package/dist/services/tool-providers/index.d.ts +4 -0
- package/dist/services/tool-providers/index.js +2 -0
- package/dist/tools/client.d.ts +0 -1
- package/dist/tools/client.js +0 -2
- package/dist/tools/internal.d.ts +1 -1
- package/dist/tools/internal.js +1 -1
- package/dist/tools/types.d.ts +1 -66
- package/package.json +22 -12
- package/dist/components/chunks/ItemToolBar-38mhtjsq.js +0 -51
- package/dist/components/chunks/ItemToolBar-9ymm7pd1.js +0 -46
- package/dist/tools/library-loader.d.ts +0 -62
- package/dist/tools/library-loader.js +0 -261
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{B as
|
|
2
|
-
- ${
|
|
3
|
-
- `)}`}var
|
|
4
|
-
`);throw Error(`[tool-config-validation:${
|
|
5
|
-
${Y}`)}function X7(Q,G={}){let Y=l1(G.strictness),J=G.source??"tools",X=D5(G.toolRegistry),j=R7(Q),Z=[],K=Object.values(j.placement).some((H)=>H.length>0)||Object.keys(j.providers).length>0||(j.policy.allowed?.length??0)>0||(j.policy.blocked?.length??0)>0;if(X.size===0&&K)Z.push(c({code:"tools.registryUnavailable",severity:"warning",path:"tools",message:'No tool registry was supplied, so tool ids, placement levels and provider config were not validated. Pass `toolRegistry` — for the packaged capability set, `createPackagedToolRegistry()` from "@pie-players/pie-default-tool-loaders".'}));let W=Object.hasOwn(j.providers,"tts"),B={...j.providers||{}};for(let H of Object.keys(B).sort()){if(H==="tts"){delete B.tts;continue}let N=X.get(H);B[H]=_5(H,B[H],N,Z),V5(H,B[H],N,Z)}let U={...j,providers:B};if(H5(U,X,Z),F5(U,X,Z),A5(U,X,W,Z),W)X6(Z.filter((H)=>H.code==="tools.removedProviderKey"),J);if(Y==="warn")J6(Z,J);let V=Z.filter((H)=>H.severity==="error");if(Y==="error"&&V.length>0)X6(V,J);if(Y==="error"&&V.length===0)J6(Z,J);return{config:U,diagnostics:Z}}import{languageTagLookupSequence as P5,normalizeLanguageTag as W6}from"@pie-players/pie-players-shared/i18n/language-tags";var d1=(Q)=>Array.isArray(Q)&&Q.length>0;function i1(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 Z6(Q,G){if(!Q)return[];let Y=i1(G),J=[];if(d1(Q.accessibilityCatalogs))J.push({context:Y,catalogs:Q.accessibilityCatalogs});if(d1(Q.config?.extractedCatalogs))J.push({context:Y,catalogs:Q.config.extractedCatalogs});if(G.kind==="passage")return J;if(Y.ownerKind!=="itemModel")return J;for(let X of Q.config?.models??[]){if(!d1(X.accessibilityCatalogs))continue;J.push({context:{...Y,modelId:X.id},catalogs:X.accessibilityCatalogs})}return J}var r1=new Set(["speak","break","prosody","emphasis","say-as","sub","mark","phoneme","lang","p","s","voice","audio","lexicon"]),j6=new Set(["script","style","iframe","object","embed","foreignobject","noscript","template"]),K6=new Set(["alphabet","ph","time","strength","rate","pitch","volume","name","interpret-as","format","detail","language","xml:lang","lang","gender","src"]),q6=new Set(["break","mark","lexicon"]);function N5(Q){let G=Q;for(let Y of q6){let J=new RegExp(`<${Y}\\b([^>/]*?)\\s*/>`,"gi");G=G.replace(J,(X,j)=>{let Z=j?j.replace(/\s+$/,""):"";return`<${Y}${Z}></${Y}>`})}return G}var M5=[/^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 O5(Q){if(typeof Q!=="string"||Q.length===0)return!1;let G;try{G=new URL(Q)}catch{return!1}if(G.protocol!=="http:"&&G.protocol!=="https:")return!1;let Y=G.hostname.replace(/^\[|\]$/g,"").replace(/\.$/,"");return!M5.some((J)=>J.test(Y))}function s1(Q){let G=Array.from(Q.children);for(let J of G){let X=J.tagName.toLowerCase();if(j6.has(X)){J.remove();continue}if(s1(J),!r1.has(X)){let j=Q.ownerDocument.createTextNode(J.textContent??"");J.replaceWith(j)}}let Y=Array.from(Q.attributes).map((J)=>J.name);for(let J of Y)if(!K6.has(J.toLowerCase()))Q.removeAttribute(J);if(Q.tagName.toLowerCase()==="audio"){let J=Q.getAttribute("src");if(J!==null&&!O5(J))Q.removeAttribute("src")}}function n1(Q){let G=Q.tagName.toLowerCase(),Y=Array.from(Q.attributes).filter((X)=>K6.has(X.name.toLowerCase())).map((X)=>` ${X.name}="${z5(X.value)}"`).join("");if(q6.has(G))return`<${G}${Y}/>`;let J=[];for(let X of Array.from(Q.childNodes))if(X.nodeType===3)J.push(q1(X.nodeValue??""));else if(X.nodeType===1){let j=X,Z=j.tagName.toLowerCase();if(j6.has(Z))continue;if(r1.has(Z))J.push(n1(j));else J.push(q1(j.textContent??""))}return`<${G}${Y}>${J.join("")}</${G}>`}function o1(Q){let G=String(Q||"").trim();if(!G||!G.includes("<"))return Q;if(typeof DOMParser>"u")return Q;let J=new DOMParser().parseFromString(N5(G),"text/html"),X=J.querySelector("speak");if(X)return s1(X),n1(X);let j=J.createElement("speak");for(let Z of Array.from(J.body.childNodes))j.appendChild(Z);return s1(j),Array.from(j.childNodes).map((Z)=>{if(Z.nodeType===3)return q1(Z.nodeValue??"");if(Z.nodeType===1){let K=Z;if(r1.has(K.tagName.toLowerCase()))return n1(K);return q1(K.textContent??"")}return""}).join("")}function q1(Q){return Q.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function z5(Q){return Q.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}var V6=new Set(["spoken","sign-language","transcript","braille","tactile","simplified-language","audio-description","extended-description"]),a1="ext:";function U6(Q){if(V6.has(Q))return!0;return Q.startsWith(a1)&&Q.length>a1.length}var B6=new Set;function t1(Q,G=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(G.has(Q))throw TypeError("catalog cards must not contain cycles");G.add(Q);try{if(Array.isArray(Q))return Object.freeze(Q.map((X)=>t1(X,G)));let Y=Object.getPrototypeOf(Q);if(Y!==Object.prototype&&Y!==null)throw TypeError("catalog cards must contain only plain objects and arrays");let J={};for(let[X,j]of Object.entries(Q))J[X]=t1(j,G);return Object.freeze(J)}finally{G.delete(Q)}}function D6(Q,G,Y){let J=`${G}|${Q}`;if(B6.has(J))return;B6.add(J);let X=`${Array.from(V6).join(", ")}, or an "${a1}" prefixed vendor extension`;if(G==="card"){console.warn(`[AccessibilityCatalogResolver] catalog "${Y}" 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 "${Y}" cannot match any card. Expected one of: ${X}.`)}var _6=(Q)=>Q.payload!==void 0?"payload":"content";class e1{assessmentCatalogs=new Map;itemCatalogs=new Map;scopedCatalogs=new Map;defaultLanguage="en-US";sanitizedSpokenCache=new Map;catalogChangeListeners=new Set;reportedSnapshotProblems=new Set;constructor(Q,G="en-US"){this.defaultLanguage=G,this.indexCatalogs(Q??[],"assessment")}setDefaultLanguage(Q){this.defaultLanguage=Q}onCatalogsChange(Q){return this.catalogChangeListeners.add(Q),()=>{this.catalogChangeListeners.delete(Q)}}emitCatalogsChange(Q){for(let G of Array.from(this.catalogChangeListeners))try{G(Q)}catch{}}getDefaultLanguage(){return this.defaultLanguage}indexCatalogs(Q,G){let Y=G==="assessment"?this.assessmentCatalogs:this.itemCatalogs;for(let J of this.sanitizeCatalogs(Q)){if(Y.has(J.identifier)){console.warn(`[AccessibilityCatalogResolver] Duplicate ${G} catalog "${J.identifier}" ignored`);continue}Y.set(J.identifier,J)}}insertScopedCatalogs(Q,G){if(!G||G.length===0)return null;let Y=this.getOwnerKey(Q),J=this.scopedCatalogs.get(Y),X=J?.catalogs??new Map,j=[];for(let Z of this.sanitizeCatalogs(G)){if(X.has(Z.identifier)){console.warn(`[AccessibilityCatalogResolver] Duplicate scoped catalog "${Z.identifier}" ignored for ${Y}`);continue}X.set(Z.identifier,Z),j.push(Z.identifier)}if(!J&&j.length>0)this.scopedCatalogs.set(Y,{context:{...Q},catalogs:X});return{key:Y,context:{...Q},catalogs:X,insertedIds:j}}removeScopedInsertion(Q){let G=this.scopedCatalogs.get(Q.key);if(G?.catalogs!==Q.catalogs)return!1;let Y=!1;for(let J of Q.insertedIds)Y=G.catalogs.delete(J)||Y;if(G.catalogs.size===0)this.scopedCatalogs.delete(Q.key);return Y}registerCatalogs(Q,G){let Y=this.insertScopedCatalogs(Q,G);if(Y&&Y.insertedIds.length>0)this.emitCatalogsChange({reason:"scoped-registered",context:Q});let J=!0;return()=>{if(!J)return;if(J=!1,Y&&this.removeScopedInsertion(Y))this.emitCatalogsChange({reason:"scoped-removed",context:Q})}}registerOwner(Q){let{owner:G,entity:Y}=Q,J=i1(G),X=[],j=[];try{j=Z6(Y,G)}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 B=this.insertScopedCatalogs(W.context,W.catalogs);if(B)X.push(B)}catch(B){console.warn("[AccessibilityCatalogResolver] Invalid catalogs on a mounted content owner were ignored; the primary content and other valid catalogs remain available.",B)}if(X.some((W)=>W.insertedIds.length>0))this.emitCatalogsChange({reason:"scoped-registered",context:J});let K=!0;return()=>{if(!K)return;K=!1;let W=!1;for(let B of X)W=this.removeScopedInsertion(B)||W;if(W)this.emitCatalogsChange({reason:"scoped-removed",context:J})}}forOwner(Q){let G={...Q};return Object.freeze({snapshot:()=>this.createOwnerSnapshot(G),onChange:(Y)=>this.onCatalogsChange((J)=>{if(this.catalogChangeAffectsOwner(J,G))Y()})})}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((G)=>G.catalogs.has(Q))}getAlternative(Q,G){if(!U6(G.type))D6(G.type,"lookup",Q);let Y=G.context?this.scopedCatalogs.get(this.getOwnerKey(G.context))?.catalogs.get(Q):null;if(Y){let j=this.findMatchingCard(Y,G);if(j)return this.resolveCard(Q,j,"item")}if(G.context){let j=this.findScopedCandidates(Q,G.context);if(j.length===1){let Z=this.findMatchingCard(j[0],G);if(Z)return this.resolveCard(Q,Z,"item")}else if(j.length>1)return console.warn(`[AccessibilityCatalogResolver] Ambiguous scoped catalog "${Q}" for owner context`,G.context),null}let J=this.itemCatalogs.get(Q);if(J){let j=this.findMatchingCard(J,G);if(j)return this.resolveCard(Q,j,"item")}let X=this.assessmentCatalogs.get(Q);if(X){let j=this.findMatchingCard(X,G);if(j)return this.resolveCard(Q,j,"assessment")}return null}resolveCard(Q,G,Y){return{catalogId:Q,type:G.catalog,language:G.language,content:G.catalog==="spoken"&&G.content!==void 0?this.ensureSpokenSanitized(G.content):G.content,payload:G.payload,source:Y}}ensureSpokenSanitized(Q){let G=this.sanitizedSpokenCache.get(Q);if(G!==void 0)return G;let Y=o1(Q);return this.sanitizedSpokenCache.set(Q,Y),Y}getOwnerKey(Q){return[Q.ownerKind,Q.assessmentId||"",Q.sectionId||"",Q.canonicalItemId||"",Q.itemId||"",Q.passageId||"",Q.modelId||""].join("|")}scopedCatalogEntries(){let Q=[];for(let G of this.scopedCatalogs.values())for(let Y of G.catalogs.entries())Q.push(Y);return Q}findScopedCandidates(Q,G){return Array.from(this.scopedCatalogs.values()).filter((Y)=>this.isCompatibleOwnerContext(Y.context,G)).map((Y)=>Y.catalogs.get(Q)).filter((Y)=>Boolean(Y))}isCompatibleOwnerContext(Q,G){if(Q.ownerKind!==G.ownerKind)return!1;if(G.assessmentId&&Q.assessmentId!==G.assessmentId)return!1;if(G.sectionId&&Q.sectionId!==G.sectionId)return!1;if(G.canonicalItemId&&Q.canonicalItemId!==G.canonicalItemId)return!1;if(G.itemId&&Q.itemId!==G.itemId)return!1;if(G.passageId&&Q.passageId!==G.passageId)return!1;if(G.modelId&&Q.modelId!==G.modelId)return!1;return!0}ownerScopedCatalogEntries(Q){let G=[],Y=this.scopedCatalogs.get(this.getOwnerKey(Q));if(Y)G.push(...Y.catalogs.entries());for(let J of this.scopedCatalogs.values()){if(J===Y)continue;if(!this.isCompatibleOwnerContext(J.context,Q))continue;G.push(...J.catalogs.entries())}return G}createOwnerSnapshot(Q){let G=[],Y=this.ownerScopedCatalogEntries(Q);if(Q.ownerKind==="global")Y.push(...this.assessmentCatalogs.entries());for(let[J,X]of Y)for(let j of X.cards)try{G.push(Object.freeze({catalogId:J,card:t1(j)}))}catch(Z){let K=`${this.getOwnerKey(Q)}\x00${J}`;if(!this.reportedSnapshotProblems.has(K))this.reportedSnapshotProblems.add(K),console.warn(`[AccessibilityCatalogResolver] Catalog "${J}" contains a card that cannot be exposed in an owner snapshot; that card was ignored.`,Z)}return Object.freeze({cards:Object.freeze(G)})}catalogChangeAffectsOwner(Q,G){if(!Q.context)return!1;if(this.isCompatibleOwnerContext(Q.context,G))return!0;if(G.ownerKind==="itemModel"&&G.modelId&&Q.context.ownerKind==="itemModel"&&!Q.context.modelId)return this.isCompatibleOwnerContext({...Q.context,modelId:G.modelId},G);return!1}sanitizeCatalogs(Q){return Q.map((G)=>({...G,cards:G.cards.map((Y)=>{if(!U6(Y.catalog))D6(Y.catalog,"card",G.identifier);return{...Y,content:Y.catalog==="spoken"&&Y.content!==void 0?o1(Y.content):Y.content}})}))}findMatchingCard(Q,G){let{type:Y,language:J,useFallback:X=!0,form:j}=G,Z=[],K=(W)=>{for(let B of P5(W))Z.push((U)=>W6(U.language)===B)};if(J)K(J);if(X)K(this.defaultLanguage),Z.push(()=>!0);for(let W of Z){let B=Q.cards.filter((U)=>U.catalog===Y&&W(U));if(B.length===0)continue;if(j){let U=B.find((V)=>_6(V)===j);if(U)return U}return B[0]}return null}getAllAlternatives(Q){let G=[],Y=new Set,J=(Z,K)=>{let W=`${Z.catalog}|${W6(Z.language)}|${_6(Z)}`;if(Y.has(W))return;Y.add(W),G.push(this.resolveCard(Q,Z,K))},X=this.itemCatalogs.get(Q);if(X)for(let Z of X.cards)J(Z,"item");let j=this.assessmentCatalogs.get(Q);if(j)for(let Z of j.cards)J(Z,"assessment");for(let[Z,K]of this.scopedCatalogEntries()){if(Z!==Q)continue;for(let W of K.cards)J(W,"item")}return G}getAllCatalogIds(){let Q=this.scopedCatalogEntries().map(([G])=>G);return Array.from(new Set([...this.itemCatalogs.keys(),...this.assessmentCatalogs.keys(),...Q]))}getStatistics(){let Q=new Set,G=new Set;for(let Y of this.assessmentCatalogs.values())for(let J of Y.cards)if(Q.add(J.catalog),J.language)G.add(J.language);for(let Y of this.itemCatalogs.values())for(let J of Y.cards)if(Q.add(J.catalog),J.language)G.add(J.language);for(let Y of this.scopedCatalogs.values())for(let J of Y.catalogs.values())for(let X of J.cards)if(Q.add(X.catalog),X.language)G.add(X.language);return{totalCatalogs:this.assessmentCatalogs.size+this.itemCatalogs.size+Array.from(this.scopedCatalogs.values()).reduce((Y,J)=>Y+J.catalogs.size,0),assessmentCatalogs:this.assessmentCatalogs.size,itemCatalogs:this.itemCatalogs.size+Array.from(this.scopedCatalogs.values()).reduce((Y,J)=>Y+J.catalogs.size,0),availableTypes:Q,availableLanguages:G}}hasAlternativeType(Q,G){return this.getAllAlternatives(Q).some((J)=>J.type===G)}getCatalogsByType(Q){let G=new Set;for(let[Y,J]of this.assessmentCatalogs.entries())if(J.cards.some((X)=>X.catalog===Q))G.add(Y);for(let[Y,J]of this.itemCatalogs.entries())if(J.cards.some((X)=>X.catalog===Q))G.add(Y);for(let[Y,J]of this.scopedCatalogEntries())if(J.cards.some((X)=>X.catalog===Q))G.add(Y);return Array.from(G)}reset(){this.assessmentCatalogs.clear(),this.itemCatalogs.clear(),this.scopedCatalogs.clear(),this.sanitizedSpokenCache.clear(),this.reportedSnapshotProblems.clear()}destroy(){this.reset()}}class Q8{elementStates=new Map;listeners=new Set;onStateChange=null;getGlobalElementId(Q,G,Y,J){return`${Q}:${G}:${Y}:${J}`}parseGlobalElementId(Q){let G=Q.split(":");if(G.length!==4)return null;return{assessmentId:G[0],sectionId:G[1],itemId:G[2],elementId:G[3]}}setState(Q,G,Y){let J=this.elementStates.get(Q);if(!J)J=new Map,this.elementStates.set(Q,J);J.set(G,Y),this._notifyListeners(),this._notifyStateChange()}getState(Q,G){return this.elementStates.get(Q)?.get(G)}getElementState(Q){let G=this.elementStates.get(Q);if(!G)return{};return Object.fromEntries(G.entries())}getAllState(){let Q={};for(let[G,Y]of this.elementStates.entries())Q[G]=Object.fromEntries(Y.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[G,Y]of Object.entries(Q)){let J=new Map(Object.entries(Y));this.elementStates.set(G,J)}this._notifyListeners()}clearElement(Q){this.elementStates.delete(Q),this._notifyListeners(),this._notifyStateChange()}clearTool(Q){for(let G of this.elementStates.values())G.delete(Q);this._notifyListeners(),this._notifyStateChange()}clearSection(Q,G){let Y=`${Q}:${G}:`,J=[];for(let X of this.elementStates.keys())if(X.startsWith(Y))J.push(X);for(let X of J)this.elementStates.delete(X);this._notifyListeners(),this._notifyStateChange()}clearAll(){this.elementStates.clear(),this._notifyListeners(),this._notifyStateChange()}}class m7{listeners=new Set;subscribeFrameworkErrors(Q){this.listeners.add(Q);let G=!0;return()=>{if(!G)return;G=!1,this.listeners.delete(Q)}}reportFrameworkError(Q){let G=Array.from(this.listeners);for(let Y of G)try{Y(Q)}catch(J){console.warn("[FrameworkErrorBus] listener failed:",J)}}dispose(){this.listeners.clear()}getListenerCount(){return this.listeners.size}}class G8{serialize(Q,G){return{startContainer:this.getNodePath(Q.startContainer,G),startOffset:Q.startOffset,endContainer:this.getNodePath(Q.endContainer,G),endOffset:Q.endOffset,text:Q.toString()}}deserialize(Q,G){let Y=this.findNodeByPath(Q.startContainer,G),J=this.findNodeByPath(Q.endContainer,G);if(!Y||!J)return null;try{let X=new Range;if(X.setStart(Y,Q.startOffset),X.setEnd(J,Q.endOffset),X.toString()===Q.text)return X;return null}catch(X){return console.warn("Failed to deserialize range:",X),null}}getNodePath(Q,G){if(Q===G)return"";if(Q.nodeType===Node.TEXT_NODE){let Y=Q.parentElement;if(!Y)throw Error("Text node has no parent");let X=Array.from(Y.childNodes).filter((Z)=>Z.nodeType===Node.TEXT_NODE).indexOf(Q);return`${this.getElementPath(Y,G)}::text[${X}]`}if(Q.nodeType===Node.ELEMENT_NODE)return this.getElementPath(Q,G);throw Error(`Unsupported node type: ${Q.nodeType}`)}getElementPath(Q,G){if(Q===G)return"";let Y=[],J=Q;while(J&&J!==G){if(J.id){Y.unshift(`#${J.id}`);break}let X=J.parentElement;if(!X)break;let j=Array.from(X.children).filter((W)=>W.tagName===J.tagName),Z=j.indexOf(J),K=j.length>1?`${J.tagName.toLowerCase()}:nth-of-type(${Z+1})`:J.tagName.toLowerCase();Y.unshift(K),J=X}return Y.join(" > ")}findNodeByPath(Q,G){if(Q==="")return G;if(Q.includes("::text[")){let[Y,J]=Q.split("::text["),X=Number.parseInt(J.replace("]",""),10),j=Y?G.querySelector(Y):G;if(!j)return null;return Array.from(j.childNodes).filter((K)=>K.nodeType===Node.TEXT_NODE)[X]||null}try{return G.querySelector(Q)}catch(Y){return console.warn("Invalid selector path:",Q,Y),null}}serializeMany(Q,G){return Q.map((Y)=>this.serialize(Y,G))}deserializeMany(Q,G){return Q.map((Y)=>this.deserialize(Y,G))}}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 u7{config;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(Q={}){if(this.config=Q,this.rangeSerializer=new G8,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 G of document.querySelectorAll("pie-theme"))this.themeObserver.observe(G,{attributes:!0,attributeFilter:["theme","scheme","provider","variables","style","data-theme","data-color-scheme"]})}parseColor(Q){if(!Q)return null;let G=Q.trim();if(!G)return null;let Y=/^#([a-f\d]{3}|[a-f\d]{6})$/i.exec(G);if(Y){let X=Y[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 J=/^rgba?\((.+)\)$/i.exec(G);if(J){let j=J[1].replace(/\//g,",").split(/[,\s]+/).map((B)=>B.trim()).filter(Boolean),Z=Number(j[0]),K=Number(j[1]),W=Number(j[2]);if(Number.isFinite(Z)&&Number.isFinite(K)&&Number.isFinite(W))return[Z,K,W]}if(typeof document<"u"){let X=document.createElement("span");if(X.style.color=G,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!==G)return this.parseColor(j)}}return null}relativeLuminance([Q,G,Y]){let J=(K)=>{let W=K/255;return W<=0.03928?W/12.92:((W+0.055)/1.055)**2.4},X=J(Q),j=J(G),Z=J(Y);return 0.2126*X+0.7152*j+0.0722*Z}contrastRatio(Q,G){let Y=this.relativeLuminance(Q),J=this.relativeLuminance(G),X=Math.max(Y,J),j=Math.min(Y,J);return(X+0.05)/(j+0.05)}blend(Q,G,Y){return[Math.round(Q[0]*Y+G[0]*(1-Y)),Math.round(Q[1]*Y+G[1]*(1-Y)),Math.round(Q[2]*Y+G[2]*(1-Y))]}resolveAdaptiveTTSStyle(Q){let G=[255,235,59],Y=[17,24,39],J=[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)||J,K=this.parseColor(j?.getPropertyValue("--pie-text"))||Y,W=this.explicitTTSColorOverride?this.parseColor(this.explicitTTSColorOverride.color)||G:this.parseColor(j?.getPropertyValue("--pie-missing"))||G,B=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=B[B.length-1],V=-1/0;for(let g of B){let j7=this.blend(W,Z,g),K7=this.contrastRatio(j7,Z),q7=this.contrastRatio(j7,K),$7=K7*1.2+q7*0.8;if(K7>=1.25&&q7>=2.4){U=g;break}if($7>V)V=$7,U=g}let H=Math.max(0.24,Math.min(0.85,U*0.55)),N=Math.max(0.55,Math.min(0.95,U+0.2)),O=Math.max(0.22,Math.min(0.6,U*0.45)),P=K,$=this.blend(P,Z,N),F=this.contrastRatio($,Z),L=this.relativeLuminance(Z)>0.45?[0,0,0]:[255,255,255],C=F>=1.35?P:L,v=`rgba(${W[0]}, ${W[1]}, ${W[2]}, ${U})`,I=`rgba(${W[0]}, ${W[1]}, ${W[2]}, ${H})`,p=`rgba(${C[0]}, ${C[1]}, ${C[2]}, ${N})`,E=`rgba(${C[0]}, ${C[1]}, ${C[2]}, ${O})`;return{wordHighlight:v,sentenceHighlight:I,wordUnderline:p,wordShadow:E}}applyAdaptiveTTSStyle(Q){if(typeof document>"u")return;let G=this.resolveAdaptiveTTSStyle(Q);document.documentElement.style.setProperty("--pie-tts-word-highlight",G.wordHighlight),document.documentElement.style.setProperty("--pie-tts-sentence-highlight",G.sentenceHighlight),document.documentElement.style.setProperty("--pie-tts-line-highlight",G.sentenceHighlight),document.documentElement.style.setProperty("--pie-tts-word-underline",G.wordUnderline),document.documentElement.style.setProperty("--pie-tts-word-shadow",G.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 G=new Highlight;this.colorHighlights.set(Q,G),CSS.highlights.set(`annotation-${Q}`,G)}}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{B as M3,C as z3,I as O3,J as x,K as P3,L as L3,M as I8,O as $3,Q as L7,R as w3,S as R7,T as E8,b as bG,c as d7,d as V3,e as H3,f as n,g as y,h,i as w,j as f8,k as i7,l as k8,m as T1,n as b,o as A3,p as _,q as m,t as v8,u as F3,v as C1,w as S1,x as N3}from"./chunks/ItemToolBar-rd7te9r0.js";import{ContextProvider as D3,ContextRoot as _3,requestContext as pQ}from"@pie-players/pie-context";import{attachInstrumentationEventBridge as gQ,createStageTracker as cQ,resolveInstrumentationProvider as lQ,TOOLKIT_INSTRUMENTATION_EVENT_MAP as dQ}from"@pie-players/pie-players-shared/pie";import{isInstrumentationProvider as iQ}from"@pie-players/pie-players-shared";import{createPieI18n as sQ,DEFAULT_LOCALE as nQ}from"@pie-players/pie-players-shared/i18n";function j1(G){return{kind:G.kind,severity:G.severity??"error",source:G.source,message:G.message,details:[...G.details||[]],recoverable:G.recoverable===!0,cause:G.cause}}function K1(G){let Q=G.error instanceof Error&&G.error.message.trim().length>0?G.error.message:String(G.error||"Unknown framework error");return j1({kind:G.kind,source:G.source,message:Q,recoverable:G.recoverable,cause:G.error})}var B5={"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"};function Q6(G){let Q=B5[G.context.phase],Y=G.context.providerId?`pie-toolkit-coordinator/${G.context.providerId}`:`pie-toolkit-coordinator:${G.context.phase}`;return K1({kind:Q,source:Y,error:G.error,recoverable:G.recoverable})}function Y6(G){let Q=`[pie-framework:${G.kind}:${G.source}]`;if(G.details.length===0)return`${Q} ${G.message}`;return`${Q} ${G.message}
|
|
2
|
+
- ${G.details.join(`
|
|
3
|
+
- `)}`}var D5="error";function l1(G){if(G==="off"||G==="warn"||G==="error")return G;return D5}function c(G){return G}function _5(G){if(!G)return new Map;return new Map(G.getAllTools().slice().sort((Q,Y)=>Q.toolId.localeCompare(Y.toolId)).map((Q)=>[Q.toolId,Q]))}function V5(G,Q,Y,J){if(!Q||!Y?.provider?.sanitizeConfig)return Q;try{let X=Y.provider.sanitizeConfig(Q);if(!X||typeof X!=="object"||Array.isArray(X))return J.push(c({code:"tools.providerSanitizeFailed",severity:"error",path:`providers.${G}`,message:`Provider sanitizer for "${G}" must return an object.`,providerId:G,toolId:G})),Q;return X}catch(X){return J.push(c({code:"tools.providerSanitizeFailed",severity:"error",path:`providers.${G}`,message:`Provider sanitizer failed for "${G}": ${X instanceof Error?X.message:String(X)}`,providerId:G,toolId:G})),Q}}function H5(G,Q,Y,J){if(!Q||!Y?.provider?.validateConfig)return;try{let X=Y.provider.validateConfig(Q);if(!Array.isArray(X)){J.push(c({code:"tools.invalidProviderValidation",severity:"error",path:`providers.${G}`,message:`Provider validator for "${G}" must return an array.`,providerId:G,toolId:G}));return}for(let j of X)J.push({...j,path:j.path||`providers.${G}`,providerId:j.providerId||G,toolId:j.toolId||G})}catch(X){J.push(c({code:"tools.providerValidateFailed",severity:"error",path:`providers.${G}`,message:`Provider validator failed for "${G}": ${X instanceof Error?X.message:String(X)}`,providerId:G,toolId:G}))}}function A5(G,Q,Y){if(Q.size===0)return;let J=["section","item","passage"];for(let X of J)for(let j of G.placement[X]){let Z=Q.get(j);if(!Z){Y.push(c({code:"tools.unknownToolId",severity:"error",path:`placement.${X}`,message:`Unknown tool id "${j}" in placement.${X}.`,toolId:j}));continue}if(Z.activation==="region"){Y.push(c({code:"tools.unplaceableActivation",severity:"error",path:`placement.${X}`,message:`Tool "${j}" 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:j}));continue}let K=Z.supportedLevels.includes(X),W=X==="item"&&Z.supportedLevels.includes("section");if(!K&&!W)Y.push(c({code:"tools.unsupportedLevel",severity:"error",path:`placement.${X}`,message:`Tool "${j}" does not support level "${X}".`,toolId:j}))}}function F5(G,Q,Y){if(Q.size===0)return;for(let J of G.policy.allowed||[]){if(Q.has(J))continue;Y.push(c({code:"tools.unknownToolId",severity:"error",path:"policy.allowed",message:`Unknown tool id "${J}" in policy.allowed.`,toolId:J}))}for(let J of G.policy.blocked||[]){if(Q.has(J))continue;Y.push(c({code:"tools.unknownToolId",severity:"error",path:"policy.blocked",message:`Unknown tool id "${J}" in policy.blocked.`,toolId:J}))}}function N5(G,Q,Y,J){if(Y)J.push(c({code:"tools.removedProviderKey",severity:"error",path:"providers.tts",message:'Provider key "tts" is no longer supported. Use "providers.textToSpeech".',providerId:"tts",toolId:"textToSpeech"}));for(let X of Object.keys(G.providers).sort()){if(Q.size===0||Q.has(X))continue;J.push(c({code:"tools.unknownProviderKey",severity:"error",path:`providers.${X}`,message:`Unknown provider key "${X}".`,providerId:X,toolId:X}))}}function J6(G,Q){if(G.length===0)return;for(let Y of G){let J=`[tool-config-validation:${Q}]`;console.warn(`${J} ${Y.path} - ${Y.message}`)}}function X6(G,Q){let Y=G.map((J)=>`- ${J.path}: ${J.message}`).join(`
|
|
4
|
+
`);throw Error(`[tool-config-validation:${Q}] Invalid tools config:
|
|
5
|
+
${Y}`)}function X7(G,Q={}){let Y=l1(Q.strictness),J=Q.source??"tools",X=_5(Q.toolRegistry),j=R7(G),Z=[],K=Object.values(j.placement).some((H)=>H.length>0)||Object.keys(j.providers).length>0||(j.policy.allowed?.length??0)>0||(j.policy.blocked?.length??0)>0;if(X.size===0&&K)Z.push(c({code:"tools.registryUnavailable",severity:"warning",path:"tools",message:'No tool registry was supplied, so tool ids, placement levels and provider config were not validated. Pass `toolRegistry` — for the packaged capability set, `createPackagedToolRegistry()` from "@pie-players/pie-default-tool-loaders".'}));let W=Object.hasOwn(j.providers,"tts"),B={...j.providers||{}};for(let H of Object.keys(B).sort()){if(H==="tts"){delete B.tts;continue}let N=X.get(H);B[H]=V5(H,B[H],N,Z),H5(H,B[H],N,Z)}let U={...j,providers:B};if(A5(U,X,Z),F5(U,X,Z),N5(U,X,W,Z),W)X6(Z.filter((H)=>H.code==="tools.removedProviderKey"),J);if(Y==="warn")J6(Z,J);let V=Z.filter((H)=>H.severity==="error");if(Y==="error"&&V.length>0)X6(V,J);if(Y==="error"&&V.length===0)J6(Z,J);return{config:U,diagnostics:Z}}import{languageTagLookupSequence as L5,normalizeLanguageTag as W6}from"@pie-players/pie-players-shared/i18n/language-tags";var d1=(G)=>Array.isArray(G)&&G.length>0;function i1(G){if(G.kind==="passage")return{ownerKind:"passage",assessmentId:G.assessmentId,sectionId:G.sectionId,passageId:G.canonicalItemId||G.itemId};return{ownerKind:"itemModel",assessmentId:G.assessmentId,sectionId:G.sectionId,itemId:G.itemId,canonicalItemId:G.canonicalItemId||G.itemId}}function Z6(G,Q){if(!G)return[];let Y=i1(Q),J=[];if(d1(G.accessibilityCatalogs))J.push({context:Y,catalogs:G.accessibilityCatalogs});if(d1(G.config?.extractedCatalogs))J.push({context:Y,catalogs:G.config.extractedCatalogs});if(Q.kind==="passage")return J;if(Y.ownerKind!=="itemModel")return J;for(let X of G.config?.models??[]){if(!d1(X.accessibilityCatalogs))continue;J.push({context:{...Y,modelId:X.id},catalogs:X.accessibilityCatalogs})}return J}var r1=new Set(["speak","break","prosody","emphasis","say-as","sub","mark","phoneme","lang","p","s","voice","audio","lexicon"]),j6=new Set(["script","style","iframe","object","embed","foreignobject","noscript","template"]),K6=new Set(["alphabet","ph","time","strength","rate","pitch","volume","name","interpret-as","format","detail","language","xml:lang","lang","gender","src"]),q6=new Set(["break","mark","lexicon"]);function M5(G){let Q=G;for(let Y of q6){let J=new RegExp(`<${Y}\\b([^>/]*?)\\s*/>`,"gi");Q=Q.replace(J,(X,j)=>{let Z=j?j.replace(/\s+$/,""):"";return`<${Y}${Z}></${Y}>`})}return Q}var z5=[/^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 O5(G){if(typeof G!=="string"||G.length===0)return!1;let Q;try{Q=new URL(G)}catch{return!1}if(Q.protocol!=="http:"&&Q.protocol!=="https:")return!1;let Y=Q.hostname.replace(/^\[|\]$/g,"").replace(/\.$/,"");return!z5.some((J)=>J.test(Y))}function s1(G){let Q=Array.from(G.children);for(let J of Q){let X=J.tagName.toLowerCase();if(j6.has(X)){J.remove();continue}if(s1(J),!r1.has(X)){let j=G.ownerDocument.createTextNode(J.textContent??"");J.replaceWith(j)}}let Y=Array.from(G.attributes).map((J)=>J.name);for(let J of Y)if(!K6.has(J.toLowerCase()))G.removeAttribute(J);if(G.tagName.toLowerCase()==="audio"){let J=G.getAttribute("src");if(J!==null&&!O5(J))G.removeAttribute("src")}}function n1(G){let Q=G.tagName.toLowerCase(),Y=Array.from(G.attributes).filter((X)=>K6.has(X.name.toLowerCase())).map((X)=>` ${X.name}="${P5(X.value)}"`).join("");if(q6.has(Q))return`<${Q}${Y}/>`;let J=[];for(let X of Array.from(G.childNodes))if(X.nodeType===3)J.push(q1(X.nodeValue??""));else if(X.nodeType===1){let j=X,Z=j.tagName.toLowerCase();if(j6.has(Z))continue;if(r1.has(Z))J.push(n1(j));else J.push(q1(j.textContent??""))}return`<${Q}${Y}>${J.join("")}</${Q}>`}function o1(G){let Q=String(G||"").trim();if(!Q||!Q.includes("<"))return G;if(typeof DOMParser>"u")return G;let J=new DOMParser().parseFromString(M5(Q),"text/html"),X=J.querySelector("speak");if(X)return s1(X),n1(X);let j=J.createElement("speak");for(let Z of Array.from(J.body.childNodes))j.appendChild(Z);return s1(j),Array.from(j.childNodes).map((Z)=>{if(Z.nodeType===3)return q1(Z.nodeValue??"");if(Z.nodeType===1){let K=Z;if(r1.has(K.tagName.toLowerCase()))return n1(K);return q1(K.textContent??"")}return""}).join("")}function q1(G){return G.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function P5(G){return G.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}var V6=new Set(["spoken","sign-language","transcript","braille","tactile","simplified-language","audio-description","extended-description"]),a1="ext:";function U6(G){if(V6.has(G))return!0;return G.startsWith(a1)&&G.length>a1.length}var B6=new Set;function t1(G,Q=new Set){if(G===null||typeof G==="string"||typeof G==="number"||typeof G==="boolean"||typeof G>"u")return G;if(typeof G!=="object")throw TypeError("catalog cards must contain JSON-compatible values");if(Q.has(G))throw TypeError("catalog cards must not contain cycles");Q.add(G);try{if(Array.isArray(G))return Object.freeze(G.map((X)=>t1(X,Q)));let Y=Object.getPrototypeOf(G);if(Y!==Object.prototype&&Y!==null)throw TypeError("catalog cards must contain only plain objects and arrays");let J={};for(let[X,j]of Object.entries(G))J[X]=t1(j,Q);return Object.freeze(J)}finally{Q.delete(G)}}function D6(G,Q,Y){let J=`${Q}|${G}`;if(B6.has(J))return;B6.add(J);let X=`${Array.from(V6).join(", ")}, or an "${a1}" prefixed vendor extension`;if(Q==="card"){console.warn(`[AccessibilityCatalogResolver] catalog "${Y}" has a card of unknown type "${G}"; 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 "${G}" on "${Y}" cannot match any card. Expected one of: ${X}.`)}var _6=(G)=>G.payload!==void 0?"payload":"content";class e1{assessmentCatalogs=new Map;itemCatalogs=new Map;scopedCatalogs=new Map;defaultLanguage="en-US";sanitizedSpokenCache=new Map;catalogChangeListeners=new Set;reportedSnapshotProblems=new Set;constructor(G,Q="en-US"){this.defaultLanguage=Q,this.indexCatalogs(G??[],"assessment")}setDefaultLanguage(G){this.defaultLanguage=G}onCatalogsChange(G){return this.catalogChangeListeners.add(G),()=>{this.catalogChangeListeners.delete(G)}}emitCatalogsChange(G){for(let Q of Array.from(this.catalogChangeListeners))try{Q(G)}catch{}}getDefaultLanguage(){return this.defaultLanguage}indexCatalogs(G,Q){let Y=Q==="assessment"?this.assessmentCatalogs:this.itemCatalogs;for(let J of this.sanitizeCatalogs(G)){if(Y.has(J.identifier)){console.warn(`[AccessibilityCatalogResolver] Duplicate ${Q} catalog "${J.identifier}" ignored`);continue}Y.set(J.identifier,J)}}insertScopedCatalogs(G,Q){if(!Q||Q.length===0)return null;let Y=this.getOwnerKey(G),J=this.scopedCatalogs.get(Y),X=J?.catalogs??new Map,j=[];for(let Z of this.sanitizeCatalogs(Q)){if(X.has(Z.identifier)){console.warn(`[AccessibilityCatalogResolver] Duplicate scoped catalog "${Z.identifier}" ignored for ${Y}`);continue}X.set(Z.identifier,Z),j.push(Z.identifier)}if(!J&&j.length>0)this.scopedCatalogs.set(Y,{context:{...G},catalogs:X});return{key:Y,context:{...G},catalogs:X,insertedIds:j}}removeScopedInsertion(G){let Q=this.scopedCatalogs.get(G.key);if(Q?.catalogs!==G.catalogs)return!1;let Y=!1;for(let J of G.insertedIds)Y=Q.catalogs.delete(J)||Y;if(Q.catalogs.size===0)this.scopedCatalogs.delete(G.key);return Y}registerCatalogs(G,Q){let Y=this.insertScopedCatalogs(G,Q);if(Y&&Y.insertedIds.length>0)this.emitCatalogsChange({reason:"scoped-registered",context:G});let J=!0;return()=>{if(!J)return;if(J=!1,Y&&this.removeScopedInsertion(Y))this.emitCatalogsChange({reason:"scoped-removed",context:G})}}registerOwner(G){let{owner:Q,entity:Y}=G,J=i1(Q),X=[],j=[];try{j=Z6(Y,Q)}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 B=this.insertScopedCatalogs(W.context,W.catalogs);if(B)X.push(B)}catch(B){console.warn("[AccessibilityCatalogResolver] Invalid catalogs on a mounted content owner were ignored; the primary content and other valid catalogs remain available.",B)}if(X.some((W)=>W.insertedIds.length>0))this.emitCatalogsChange({reason:"scoped-registered",context:J});let K=!0;return()=>{if(!K)return;K=!1;let W=!1;for(let B of X)W=this.removeScopedInsertion(B)||W;if(W)this.emitCatalogsChange({reason:"scoped-removed",context:J})}}forOwner(G){let Q={...G};return Object.freeze({snapshot:()=>this.createOwnerSnapshot(Q),onChange:(Y)=>this.onCatalogsChange((J)=>{if(this.catalogChangeAffectsOwner(J,Q))Y()})})}addItemCatalogs(G){if(!G||G.length===0)return;this.indexCatalogs(G,"item"),this.emitCatalogsChange({reason:"item-added"})}clearItemCatalogs(){if(this.itemCatalogs.size===0)return;this.itemCatalogs.clear(),this.emitCatalogsChange({reason:"item-cleared"})}hasCatalog(G){return this.itemCatalogs.has(G)||this.assessmentCatalogs.has(G)||Array.from(this.scopedCatalogs.values()).some((Q)=>Q.catalogs.has(G))}getAlternative(G,Q){if(!U6(Q.type))D6(Q.type,"lookup",G);let Y=Q.context?this.scopedCatalogs.get(this.getOwnerKey(Q.context))?.catalogs.get(G):null;if(Y){let j=this.findMatchingCard(Y,Q);if(j)return this.resolveCard(G,j,"item")}if(Q.context){let j=this.findScopedCandidates(G,Q.context);if(j.length===1){let Z=this.findMatchingCard(j[0],Q);if(Z)return this.resolveCard(G,Z,"item")}else if(j.length>1)return console.warn(`[AccessibilityCatalogResolver] Ambiguous scoped catalog "${G}" for owner context`,Q.context),null}let J=this.itemCatalogs.get(G);if(J){let j=this.findMatchingCard(J,Q);if(j)return this.resolveCard(G,j,"item")}let X=this.assessmentCatalogs.get(G);if(X){let j=this.findMatchingCard(X,Q);if(j)return this.resolveCard(G,j,"assessment")}return null}resolveCard(G,Q,Y){return{catalogId:G,type:Q.catalog,language:Q.language,content:Q.catalog==="spoken"&&Q.content!==void 0?this.ensureSpokenSanitized(Q.content):Q.content,payload:Q.payload,source:Y}}ensureSpokenSanitized(G){let Q=this.sanitizedSpokenCache.get(G);if(Q!==void 0)return Q;let Y=o1(G);return this.sanitizedSpokenCache.set(G,Y),Y}getOwnerKey(G){return[G.ownerKind,G.assessmentId||"",G.sectionId||"",G.canonicalItemId||"",G.itemId||"",G.passageId||"",G.modelId||""].join("|")}scopedCatalogEntries(){let G=[];for(let Q of this.scopedCatalogs.values())for(let Y of Q.catalogs.entries())G.push(Y);return G}findScopedCandidates(G,Q){return Array.from(this.scopedCatalogs.values()).filter((Y)=>this.isCompatibleOwnerContext(Y.context,Q)).map((Y)=>Y.catalogs.get(G)).filter((Y)=>Boolean(Y))}isCompatibleOwnerContext(G,Q){if(G.ownerKind!==Q.ownerKind)return!1;if(Q.assessmentId&&G.assessmentId!==Q.assessmentId)return!1;if(Q.sectionId&&G.sectionId!==Q.sectionId)return!1;if(Q.canonicalItemId&&G.canonicalItemId!==Q.canonicalItemId)return!1;if(Q.itemId&&G.itemId!==Q.itemId)return!1;if(Q.passageId&&G.passageId!==Q.passageId)return!1;if(Q.modelId&&G.modelId!==Q.modelId)return!1;return!0}ownerScopedCatalogEntries(G){let Q=[],Y=this.scopedCatalogs.get(this.getOwnerKey(G));if(Y)Q.push(...Y.catalogs.entries());for(let J of this.scopedCatalogs.values()){if(J===Y)continue;if(!this.isCompatibleOwnerContext(J.context,G))continue;Q.push(...J.catalogs.entries())}return Q}createOwnerSnapshot(G){let Q=[],Y=this.ownerScopedCatalogEntries(G);if(G.ownerKind==="global")Y.push(...this.assessmentCatalogs.entries());for(let[J,X]of Y)for(let j of X.cards)try{Q.push(Object.freeze({catalogId:J,card:t1(j)}))}catch(Z){let K=`${this.getOwnerKey(G)}\x00${J}`;if(!this.reportedSnapshotProblems.has(K))this.reportedSnapshotProblems.add(K),console.warn(`[AccessibilityCatalogResolver] Catalog "${J}" contains a card that cannot be exposed in an owner snapshot; that card was ignored.`,Z)}return Object.freeze({cards:Object.freeze(Q)})}catalogChangeAffectsOwner(G,Q){if(!G.context)return!1;if(this.isCompatibleOwnerContext(G.context,Q))return!0;if(Q.ownerKind==="itemModel"&&Q.modelId&&G.context.ownerKind==="itemModel"&&!G.context.modelId)return this.isCompatibleOwnerContext({...G.context,modelId:Q.modelId},Q);return!1}sanitizeCatalogs(G){return G.map((Q)=>({...Q,cards:Q.cards.map((Y)=>{if(!U6(Y.catalog))D6(Y.catalog,"card",Q.identifier);return{...Y,content:Y.catalog==="spoken"&&Y.content!==void 0?o1(Y.content):Y.content}})}))}findMatchingCard(G,Q){let{type:Y,language:J,useFallback:X=!0,form:j}=Q,Z=[],K=(W)=>{for(let B of L5(W))Z.push((U)=>W6(U.language)===B)};if(J)K(J);if(X)K(this.defaultLanguage),Z.push(()=>!0);for(let W of Z){let B=G.cards.filter((U)=>U.catalog===Y&&W(U));if(B.length===0)continue;if(j){let U=B.find((V)=>_6(V)===j);if(U)return U}return B[0]}return null}getAllAlternatives(G){let Q=[],Y=new Set,J=(Z,K)=>{let W=`${Z.catalog}|${W6(Z.language)}|${_6(Z)}`;if(Y.has(W))return;Y.add(W),Q.push(this.resolveCard(G,Z,K))},X=this.itemCatalogs.get(G);if(X)for(let Z of X.cards)J(Z,"item");let j=this.assessmentCatalogs.get(G);if(j)for(let Z of j.cards)J(Z,"assessment");for(let[Z,K]of this.scopedCatalogEntries()){if(Z!==G)continue;for(let W of K.cards)J(W,"item")}return Q}getAllCatalogIds(){let G=this.scopedCatalogEntries().map(([Q])=>Q);return Array.from(new Set([...this.itemCatalogs.keys(),...this.assessmentCatalogs.keys(),...G]))}getStatistics(){let G=new Set,Q=new Set;for(let Y of this.assessmentCatalogs.values())for(let J of Y.cards)if(G.add(J.catalog),J.language)Q.add(J.language);for(let Y of this.itemCatalogs.values())for(let J of Y.cards)if(G.add(J.catalog),J.language)Q.add(J.language);for(let Y of this.scopedCatalogs.values())for(let J of Y.catalogs.values())for(let X of J.cards)if(G.add(X.catalog),X.language)Q.add(X.language);return{totalCatalogs:this.assessmentCatalogs.size+this.itemCatalogs.size+Array.from(this.scopedCatalogs.values()).reduce((Y,J)=>Y+J.catalogs.size,0),assessmentCatalogs:this.assessmentCatalogs.size,itemCatalogs:this.itemCatalogs.size+Array.from(this.scopedCatalogs.values()).reduce((Y,J)=>Y+J.catalogs.size,0),availableTypes:G,availableLanguages:Q}}hasAlternativeType(G,Q){return this.getAllAlternatives(G).some((J)=>J.type===Q)}getCatalogsByType(G){let Q=new Set;for(let[Y,J]of this.assessmentCatalogs.entries())if(J.cards.some((X)=>X.catalog===G))Q.add(Y);for(let[Y,J]of this.itemCatalogs.entries())if(J.cards.some((X)=>X.catalog===G))Q.add(Y);for(let[Y,J]of this.scopedCatalogEntries())if(J.cards.some((X)=>X.catalog===G))Q.add(Y);return Array.from(Q)}reset(){this.assessmentCatalogs.clear(),this.itemCatalogs.clear(),this.scopedCatalogs.clear(),this.sanitizedSpokenCache.clear(),this.reportedSnapshotProblems.clear()}destroy(){this.reset()}}class G8{elementStates=new Map;listeners=new Set;onStateChange=null;getGlobalElementId(G,Q,Y,J){return`${G}:${Q}:${Y}:${J}`}parseGlobalElementId(G){let Q=G.split(":");if(Q.length!==4)return null;return{assessmentId:Q[0],sectionId:Q[1],itemId:Q[2],elementId:Q[3]}}setState(G,Q,Y){let J=this.elementStates.get(G);if(!J)J=new Map,this.elementStates.set(G,J);J.set(Q,Y),this._notifyListeners(),this._notifyStateChange()}getState(G,Q){return this.elementStates.get(G)?.get(Q)}getElementState(G){let Q=this.elementStates.get(G);if(!Q)return{};return Object.fromEntries(Q.entries())}getAllState(){let G={};for(let[Q,Y]of this.elementStates.entries())G[Q]=Object.fromEntries(Y.entries());return G}subscribe(G){return this.listeners.add(G),()=>this.listeners.delete(G)}_notifyListeners(){for(let G of this.listeners)G(this.elementStates)}setOnStateChange(G){this.onStateChange=G}_notifyStateChange(){if(this.onStateChange)this.onStateChange(this.getAllState())}loadState(G){this.elementStates.clear();for(let[Q,Y]of Object.entries(G)){let J=new Map(Object.entries(Y));this.elementStates.set(Q,J)}this._notifyListeners()}clearElement(G){this.elementStates.delete(G),this._notifyListeners(),this._notifyStateChange()}clearTool(G){for(let Q of this.elementStates.values())Q.delete(G);this._notifyListeners(),this._notifyStateChange()}clearSection(G,Q){let Y=`${G}:${Q}:`,J=[];for(let X of this.elementStates.keys())if(X.startsWith(Y))J.push(X);for(let X of J)this.elementStates.delete(X);this._notifyListeners(),this._notifyStateChange()}clearAll(){this.elementStates.clear(),this._notifyListeners(),this._notifyStateChange()}}class m7{listeners=new Set;subscribeFrameworkErrors(G){this.listeners.add(G);let Q=!0;return()=>{if(!Q)return;Q=!1,this.listeners.delete(G)}}reportFrameworkError(G){let Q=Array.from(this.listeners);for(let Y of Q)try{Y(G)}catch(J){console.warn("[FrameworkErrorBus] listener failed:",J)}}dispose(){this.listeners.clear()}getListenerCount(){return this.listeners.size}}class Q8{serialize(G,Q){return{startContainer:this.getNodePath(G.startContainer,Q),startOffset:G.startOffset,endContainer:this.getNodePath(G.endContainer,Q),endOffset:G.endOffset,text:G.toString()}}deserialize(G,Q){let Y=this.findNodeByPath(G.startContainer,Q),J=this.findNodeByPath(G.endContainer,Q);if(!Y||!J)return null;try{let X=new Range;if(X.setStart(Y,G.startOffset),X.setEnd(J,G.endOffset),X.toString()===G.text)return X;return null}catch(X){return console.warn("Failed to deserialize range:",X),null}}getNodePath(G,Q){if(G===Q)return"";if(G.nodeType===Node.TEXT_NODE){let Y=G.parentElement;if(!Y)throw Error("Text node has no parent");let X=Array.from(Y.childNodes).filter((Z)=>Z.nodeType===Node.TEXT_NODE).indexOf(G);return`${this.getElementPath(Y,Q)}::text[${X}]`}if(G.nodeType===Node.ELEMENT_NODE)return this.getElementPath(G,Q);throw Error(`Unsupported node type: ${G.nodeType}`)}getElementPath(G,Q){if(G===Q)return"";let Y=[],J=G;while(J&&J!==Q){if(J.id){Y.unshift(`#${J.id}`);break}let X=J.parentElement;if(!X)break;let j=Array.from(X.children).filter((W)=>W.tagName===J.tagName),Z=j.indexOf(J),K=j.length>1?`${J.tagName.toLowerCase()}:nth-of-type(${Z+1})`:J.tagName.toLowerCase();Y.unshift(K),J=X}return Y.join(" > ")}findNodeByPath(G,Q){if(G==="")return Q;if(G.includes("::text[")){let[Y,J]=G.split("::text["),X=Number.parseInt(J.replace("]",""),10),j=Y?Q.querySelector(Y):Q;if(!j)return null;return Array.from(j.childNodes).filter((K)=>K.nodeType===Node.TEXT_NODE)[X]||null}try{return Q.querySelector(G)}catch(Y){return console.warn("Invalid selector path:",G,Y),null}}serializeMany(G,Q){return G.map((Y)=>this.serialize(Y,Q))}deserializeMany(G,Q){return G.map((Y)=>this.deserialize(Y,Q))}}var u;(function(G){G.TTS_WORD="tts-word",G.TTS_SENTENCE="tts-sentence",G.ANNOTATION="annotation"})(u||(u={}));var _7;(function(G){G.YELLOW="yellow",G.GREEN="green",G.BLUE="blue",G.PINK="pink",G.ORANGE="orange",G.UNDERLINE="underline"})(_7||(_7={}));class u7{config;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(G={}){if(this.config=G,this.rangeSerializer=new Q8,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 G=()=>this.applyAdaptiveTTSStyle();this.themeObserver=new MutationObserver(G),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(G){if(!G)return null;let Q=G.trim();if(!Q)return null;let Y=/^#([a-f\d]{3}|[a-f\d]{6})$/i.exec(Q);if(Y){let X=Y[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 J=/^rgba?\((.+)\)$/i.exec(Q);if(J){let j=J[1].replace(/\//g,",").split(/[,\s]+/).map((B)=>B.trim()).filter(Boolean),Z=Number(j[0]),K=Number(j[1]),W=Number(j[2]);if(Number.isFinite(Z)&&Number.isFinite(K)&&Number.isFinite(W))return[Z,K,W]}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 j=typeof getComputedStyle==="function"?getComputedStyle(X).color:"";X.remove();let Z=j.trim();if(Z&&Z!==Q)return this.parseColor(j)}}return null}relativeLuminance([G,Q,Y]){let J=(K)=>{let W=K/255;return W<=0.03928?W/12.92:((W+0.055)/1.055)**2.4},X=J(G),j=J(Q),Z=J(Y);return 0.2126*X+0.7152*j+0.0722*Z}contrastRatio(G,Q){let Y=this.relativeLuminance(G),J=this.relativeLuminance(Q),X=Math.max(Y,J),j=Math.min(Y,J);return(X+0.05)/(j+0.05)}blend(G,Q,Y){return[Math.round(G[0]*Y+Q[0]*(1-Y)),Math.round(G[1]*Y+Q[1]*(1-Y)),Math.round(G[2]*Y+Q[2]*(1-Y))]}resolveAdaptiveTTSStyle(G){let Q=[255,235,59],Y=[17,24,39],J=[255,255,255],X=G||(typeof document<"u"?document.documentElement:null),j=X&&typeof getComputedStyle==="function"?getComputedStyle(X):null,Z=this.parseColor(j?.getPropertyValue("--pie-background")||j?.backgroundColor)||J,K=this.parseColor(j?.getPropertyValue("--pie-text"))||Y,W=this.explicitTTSColorOverride?this.parseColor(this.explicitTTSColorOverride.color)||Q:this.parseColor(j?.getPropertyValue("--pie-missing"))||Q,B=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=B[B.length-1],V=-1/0;for(let g of B){let j7=this.blend(W,Z,g),K7=this.contrastRatio(j7,Z),q7=this.contrastRatio(j7,K),$7=K7*1.2+q7*0.8;if(K7>=1.25&&q7>=2.4){U=g;break}if($7>V)V=$7,U=g}let H=Math.max(0.24,Math.min(0.85,U*0.55)),N=Math.max(0.55,Math.min(0.95,U+0.2)),M=Math.max(0.22,Math.min(0.6,U*0.45)),P=K,$=this.blend(P,Z,N),A=this.contrastRatio($,Z),L=this.relativeLuminance(Z)>0.45?[0,0,0]:[255,255,255],T=A>=1.35?P:L,v=`rgba(${W[0]}, ${W[1]}, ${W[2]}, ${U})`,I=`rgba(${W[0]}, ${W[1]}, ${W[2]}, ${H})`,p=`rgba(${T[0]}, ${T[1]}, ${T[2]}, ${N})`,E=`rgba(${T[0]}, ${T[1]}, ${T[2]}, ${M})`;return{wordHighlight:v,sentenceHighlight:I,wordUnderline:p,wordShadow:E}}applyAdaptiveTTSStyle(G){if(typeof document>"u")return;let Q=this.resolveAdaptiveTTSStyle(G);document.documentElement.style.setProperty("--pie-tts-word-highlight",Q.wordHighlight),document.documentElement.style.setProperty("--pie-tts-sentence-highlight",Q.sentenceHighlight),document.documentElement.style.setProperty("--pie-tts-line-highlight",Q.sentenceHighlight),document.documentElement.style.setProperty("--pie-tts-word-underline",Q.wordUnderline),document.documentElement.style.setProperty("--pie-tts-word-shadow",Q.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 G of Object.values(_7)){let Q=new Highlight;this.colorHighlights.set(G,Q),CSS.highlights.set(`annotation-${G}`,Q)}}registerStyles(){if(!this.supported)return;if(typeof document>"u")return;if(document.getElementById("pie-highlight-styles"))return;let G=document.createElement("style");G.id="pie-highlight-styles",G.textContent=`
|
|
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 @@ ${Y}`)}function X7(Q,G={}){let Y=l1(G.strictness),J=G.source??"tools",X=D5(G.too
|
|
|
212
212
|
text-shadow: none;
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
|
-
`,document.head.appendChild(Q)}highlightTTSWord(Q,G,Y){if(!this.ttsWordHighlight)return;this.applyAdaptiveTTSStyle(Q.parentElement),this.clearTTSWord();let J=document.createRange();J.setStart(Q,G),J.setEnd(Q,Y),this.ttsWordHighlight.add(J)}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 G=Q[0]?.startContainer,Y=G?.nodeType===Node.ELEMENT_NODE?G:G?.parentElement;this.applyAdaptiveTTSStyle(Y),this.clearTTSSentence();for(let J of Q)this.ttsSentenceHighlight.add(J);this.highlightTTSElementFallbacks(Q)}highlightTTSSentenceElements(Q){if(!this.ttsSentenceHighlight)return;this.applyAdaptiveTTSStyle(Q[0]||null),this.clearTTSSentence();for(let G of Q)G.setAttribute("data-pie-tts-sentence-element","true"),this.ttsSentenceElementHighlights.add(G)}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,u7.SENTENCE_FALLBACK_SELECTOR)}highlightTTSWordElementFallbacks(Q){if(typeof Element>"u")return;this.highlightElementFallbacks(Q,"data-pie-tts-word-element",this.ttsWordElementHighlights,u7.WORD_FALLBACK_SELECTOR)}highlightElementFallbacks(Q,G,Y,J){for(let X of Q){let j=X.commonAncestorContainer.nodeType===Node.ELEMENT_NODE?X.commonAncestorContainer:X.commonAncestorContainer.parentElement;if(!j)continue;let Z=[],K=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 B of[K,W]){let U=B;while(U){if(U.matches?.(J))Z.push(U);U=U.parentElement}}if(j.matches?.(J))Z.push(j);Z.push(...Array.from(j.querySelectorAll(J)));for(let B of new Set(Z)){try{if(!X.intersectsNode(B)&&!B.contains(K)&&!B.contains(W))continue}catch{continue}B.setAttribute(G,"true"),Y.add(B)}}}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,G=_7.YELLOW){let Y=`annotation-${this.nextAnnotationId++}`,J=Q.cloneRange(),X={id:Y,range:J,type:u.ANNOTATION,color:G,timestamp:Date.now()};this.annotations.set(Y,X);let j=this.colorHighlights.get(G);if(j)j.add(J);return Y}removeAnnotation(Q){let G=this.annotations.get(Q);if(!G){console.warn(`[HighlightCoordinator] Annotation ${Q} not found`);return}console.log(`[HighlightCoordinator] Removing annotation ${Q} (color: ${G.color})`);let Y=this.colorHighlights.get(G.color);if(Y){let J=Y.delete(G.range);console.log("[HighlightCoordinator] Highlight.delete() returned:",J)}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,G){let Y=this.annotations.get(Q);if(!Y)return;let J=Y.color;if(J===G)return;let X=this.colorHighlights.get(J);if(X)X.delete(Y.range);Y.color=G;let j=this.colorHighlights.get(G);if(j)j.add(Y.range)}exportAnnotations(Q=document.body){return this.getAnnotations().map((G)=>({...this.rangeSerializer.serialize(G.range,Q),id:G.id,color:G.color,timestamp:G.timestamp}))}importAnnotations(Q,G=document.body){let Y=0;for(let J of Q){let X=this.rangeSerializer.deserialize(J,G);if(X)this.addAnnotation(X,J.color),Y++}return Y}highlightRange(Q,G,Y=_7.YELLOW){if(!this.supported)return;switch(G){case u.TTS_WORD:case u.TTS_SENTENCE:{let J=G===u.TTS_WORD?this.ttsWordHighlight:this.ttsSentenceHighlight;if(J){if(J.clear(),J.add(Q),G===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,Y);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,G){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,G))},this.applyAdaptiveTTSStyle()}destroy(){if(!this.supported)return;if(this.clearTTS(),this.clearAnnotations(),typeof document<"u"){let Q=document.getElementById("pie-highlight-styles");if(Q)Q.remove()}this.themeObserver?.disconnect(),this.themeObserver=null}}function H6(Q){return(...G)=>{console.debug(`[${Q}]`,...G)}}var a=H6("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 Y8{config;tools=new Map;layerCounters=new Map;listeners=new Set;visibilityState=new Map;constructor(Q={}){this.config=Q,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,G,Y,J=Z7.MODAL){if(a("registerTool called:",{id:Q,name:G,hasElement:!!Y,layer:J}),this.tools.has(Q)){a(`Tool ${Q} is already registered`);return}let X=this.visibilityState.get(Q)??!1;if(!Y){this.tools.set(Q,{id:Q,name:G,element:null,layer:J,isVisible:X,baseZIndex:J}),a("Tool registered without element:",Q);return}let j=J+this.getNextLayerOffset(J);Y.style.zIndex=String(j),Y.style.display=X?"":"none";let Z=()=>this.bringToFront(Y);if(Y.addEventListener("mousedown",Z),this.tools.set(Q,{id:Q,name:G,element:Y,layer:J,isVisible:X,baseZIndex:j,mouseDownHandler:Z}),X)this.bringToFront(Y);a("Tool registered with element:",Q)}unregisterTool(Q){let G=this.tools.get(Q);if(!G)return;if(G.element&&G.mouseDownHandler)G.element.removeEventListener("mousedown",G.mouseDownHandler);this.tools.delete(Q)}releaseTool(Q){this.unregisterTool(Q),this.visibilityState.delete(Q)}showTool(Q){let G=this.tools.get(Q);if(!G){a(`Tool ${Q} not found`);return}if(G.element)G.element.style.display="",this.bringToFront(G.element);G.isVisible=!0,this.visibilityState.set(Q,!0),this.notifyListeners()}hideTool(Q){let G=this.tools.get(Q);if(!G){a(`Tool ${Q} not found`);return}if(G.element)G.element.style.display="none";G.isVisible=!1,this.visibilityState.set(Q,!1),this.notifyListeners()}toggleTool(Q){a("toggleTool called for:",Q);let G=this.tools.get(Q);if(!G){a(`Tool ${Q} not found. Registered tools:`,Array.from(this.tools.keys()));return}if(a("Tool found, current visibility:",G.isVisible),G.isVisible)this.hideTool(Q);else this.showTool(Q)}isToolVisible(Q){let G=this.tools.get(Q);if(G)return G.isVisible;return this.visibilityState.get(Q)??!1}bringToFront(Q){let G=Array.from(this.tools.values()).find((X)=>X.element===Q);if(!G)return;let Y=this.getMaxZIndexInLayer(G.layer),J=Math.max(Y+1,G.layer+1);Q.style.zIndex=String(J),G.baseZIndex=J}getRegisteredTools(){return Array.from(this.tools.keys())}getToolElement(Q){return this.tools.get(Q)?.element??null}getNextLayerOffset(Q){let G=this.layerCounters.get(Q)??0;return this.layerCounters.set(Q,G+1),G}getMaxZIndexInLayer(Q){let G=Q;for(let Y of this.tools.values())if(Y.layer===Q)G=Math.max(G,Y.baseZIndex);return G}resetZIndices(){for(let Q of this.tools.values())if(Q.element)Q.element.style.zIndex=String(Q.baseZIndex)}updateToolElement(Q,G){let Y=this.tools.get(Q);if(!Y){a(`Tool ${Q} not found`);return}if(Y.element&&Y.mouseDownHandler)Y.element.removeEventListener("mousedown",Y.mouseDownHandler);let J=()=>this.bringToFront(G);if(G.addEventListener("mousedown",J),Y.element=G,Y.mouseDownHandler=J,G.style.zIndex=String(Y.baseZIndex),Y.isVisible)G.style.display="";else G.style.display="none"}hideAllTools(){for(let Q of this.tools.keys())this.hideTool(Q);this.notifyListeners()}getToolState(Q){let G=this.tools.get(Q);if(!G)return;return{id:G.id,name:G.name,isVisible:G.isVisible,element:G.element??null,layer:G.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}))}}var L5=/^[a-z][a-z0-9+.-]*:/i,$5=new Set(["http:","https:","data:","blob:"]);function F6(Q){return Q!==void 0&&Q!==1}function w5(Q){if(typeof Q!=="string")return!1;let G=Q.trim();if(!G)return!1;if(G.startsWith("//")||!L5.test(G))return!0;let Y=G.slice(0,G.indexOf(":")+1).toLowerCase();return $5.has(Y)}function A6(Q){if(!Array.isArray(Q))return[];let G=[];for(let Y of Q){if(!Y||typeof Y!=="object")continue;let J=Y;if(!w5(J.src))continue;let X={src:J.src.trim()};if(typeof J.type==="string"&&J.type.trim())X.type=J.type.trim();if(Number.isFinite(J.width))X.width=J.width;if(Number.isFinite(J.height))X.height=J.height;if(G.some((j)=>j.src===X.src))continue;G.push(X)}return G}function N6(Q){if(!Q||typeof Q!=="object")return;let G=Q,Y=Number(G.startSeconds);if(!Number.isFinite(Y)||Y<0)return;let J=Number(G.endSeconds);if(!Number.isFinite(J)||J<=Y)return{startSeconds:Y};return{startSeconds:Y,endSeconds:J}}function M6(Q){if(typeof Q!=="string")return;return Q.trim()||void 0}var R5=100,E5=1;function O6(Q,G,Y){if(!G)return()=>{};let{startSeconds:J,endSeconds:X}=G,j;if(J>0)if(j=()=>{if(Q.currentTime<J)Q.currentTime=J},Q.readyState>=E5)j();else Q.addEventListener("loadedmetadata",j);let Z,K;if(X!==void 0)Z=()=>{if(Q.currentTime>=X)Y()},Q.addEventListener("timeupdate",Z),K=setInterval(()=>{if(!Q.paused)Z?.()},R5);return()=>{if(j)Q.removeEventListener("loadedmetadata",j);if(Z)Q.removeEventListener("timeupdate",Z);if(K!==void 0)clearInterval(K)}}function z6(Q,G){if(!G)return Q;if(Q.includes("#"))return Q;let Y=G.endSeconds!==void 0?`,${G.endSeconds}`:"";return`${Q}#t=${G.startSeconds}${Y}`}function P6(Q){if(!Q)return null;let G=Q.payload;if(!G||typeof G!=="object")return null;let Y=G.media;if(!Y||typeof Y!=="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(F6(Y.version))return console.warn(`[spoken-audio] card's media declares version ${String(Y.version)}, which this build does not render; the card is ignored and read-aloud falls back to the script or generated speech`),null;if(Y.kind!==void 0&&Y.kind!=="audio")return console.warn(`[spoken-audio] card's media is kind "${Y.kind}", not "audio"; a spoken card carries recorded speech, so this card is ignored`),null;let J=A6(Y.sources);if(J.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:J,fragment:N6(G.fragment),label:M6(Y.label)}}var E7=(Q,G)=>{let Y=G?.useSentenceSegmenter!==!1;try{if(!Y)throw Error("Segmenter disabled by policy");let K=globalThis.Intl?.Segmenter;if(typeof K==="function"){let W=new K(G?.locale,{granularity:"sentence"}),B=Array.from(W.segment(Q)).map((U)=>({text:U.segment,offset:U.index})).filter((U)=>U.text.trim().length>0);if(B.length>0)return B}}catch{}let J=/[^.!?]+(?:[.!?]+|$)/g,X=Q.match(J)||[Q],j=[],Z=0;for(let K of X){let W=Q.indexOf(K,Z);if(W===-1)continue;j.push({text:K,offset:W}),Z=W+K.length}return j.length>0?j:[{text:Q,offset:0}]};var L6=5000,$6=2000,w6=(Q)=>String(Q||"").trim().toLowerCase(),b5=()=>{let Q=typeof navigator<"u"?navigator.language||navigator.languages?.[0]:"";return w6(Q||"en-US")},C5=(Q,G)=>{if(G)return Q.find((Z)=>Z.voiceURI===G)||Q.find((Z)=>Z.name===G)||null;let Y=b5(),J=Y.split("-")[0]||"en",X=(Z)=>{let K=w6(Z.lang);return K===Y||K.startsWith(`${J}-`)},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 K=Q.find(Z);if(K)return K}return Q[0]||null},T5=(Q)=>!Q.default;class b7{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 R6(Q)}supportsFeature(Q){return!0}getCapabilities(){return{supportsPause:!0,supportsResume:!0,supportsWordBoundary:!0,supportsVoiceSelection:!0,supportsRateControl:!0,supportsPitchControl:!0,supportsSSML:!1}}destroy(){}}class R6{utterance=null;config=null;_isPlaying=!1;_isPaused=!1;speakRunId=0;settlePendingVoiceWait=null;settlePendingChunk=null;onPlaybackStart=void 0;constructor(Q){this.config=Q}waitForBrowserVoices(Q,G){return new Promise((Y,J)=>{let X=speechSynthesis,j=typeof X.addEventListener==="function"&&typeof X.removeEventListener==="function",Z=j?null:X.onvoiceschanged,K=!1,W=null,B=null,U=()=>{if(W!==null)clearTimeout(W),W=null;if(j)X.removeEventListener("voiceschanged",N);else if(X.onvoiceschanged===O)X.onvoiceschanged=Z;if(B&&this.settlePendingVoiceWait===B)this.settlePendingVoiceWait=null},V=(P,$)=>{if(K)return;if(K=!0,U(),$)J($);else Y(P)},H=()=>{if(Q!==this.speakRunId){V(!1);return}if(X.getVoices().length>0)V(!0)},N=()=>H(),O=(P)=>{try{Z?.call(X,P)}finally{H()}};if(B=()=>V(!1),this.settlePendingVoiceWait=B,W=setTimeout(()=>V(!1,Error(`Configured browser voice "${G}" could not be resolved because the browser did not publish its voice inventory within ${$6/1000} seconds.`)),$6),j)X.addEventListener("voiceschanged",N);else X.onvoiceschanged=O;H()})}async resolveBrowserVoice(Q){let G=typeof this.config?.voice==="string"?this.config.voice.trim():"",Y=speechSynthesis.getVoices();if(G&&Y.length===0){if(!await this.waitForBrowserVoices(Q,G)||Q!==this.speakRunId)return{shouldContinue:!1,voice:null};Y=speechSynthesis.getVoices()}if(Q!==this.speakRunId)return{shouldContinue:!1,voice:null};let J=C5(Y,G||void 0);if(G&&!J)throw Error(`Configured browser voice "${G}" is unavailable. Select a voice exposed by this browser using its voiceURI or name.`);return{shouldContinue:!0,voice:J}}async speak(Q){if(!this.config)throw Error("TTS not initialized");this.stop();let G=this.speakRunId,Y=await this.resolveBrowserVoice(G);if(!Y.shouldContinue)return;let J=this.splitIntoChunks(Q);for(let X of J){if(G!==this.speakRunId)break;if(!await this.speakChunk(X.text,X.offset,G,Y.voice))break}}async speakSegments(Q){if(!this.config)throw Error("TTS not initialized");this.stop();let G=this.speakRunId,Y=await this.resolveBrowserVoice(G);if(!Y.shouldContinue)return;for(let J of Q){if(G!==this.speakRunId)break;let X=this.splitIntoChunks(J.text);for(let Z of X){if(G!==this.speakRunId)break;if(!await this.speakChunk(Z.text,J.startOffset+Z.offset,G,Y.voice))break}let j=Math.max(0,Number(J.pauseMsAfter||0));if(j>0&&G===this.speakRunId){if(!await this.waitForPause(j,G))break}}}async waitForPause(Q,G){return await new Promise((Y)=>setTimeout(Y,Q)),G===this.speakRunId}splitIntoChunks(Q){if(Q.length<=260)return[{text:Q,offset:0}];let Y=this.segmentSentences(Q),J=[],X="",j=0;for(let Z of Y){let K=Z.text.trim();if(!K)continue;let W=Z.text.search(/\S/),B=Z.offset+(W===-1?0:W);if(!X){X=K,j=B;continue}let U=`${X} ${K}`;if(U.length<=260)X=U;else J.push({text:X,offset:j}),X=K,j=B}if(X)J.push({text:X,offset:j});return J.length?J:[{text:Q,offset:0}]}getHighlightMode(){return(this.config?.providerOptions||{}).highlightMode==="word"?"word":"sentence"}getSegmentationPolicy(){let Q=this.config?.providerOptions||{},G=Q.segmenter||{},J=G.mode!=="regexOnly",X=typeof G.locale==="string"&&G.locale.trim().length>0?G.locale:typeof Q.locale==="string"&&Q.locale.trim().length>0?Q.locale:void 0;return{useSentenceSegmenter:J,useWordSegmenter:J,locale:X}}segmentSentences(Q){let G=this.getSegmentationPolicy();return E7(Q,{locale:G.locale,useSentenceSegmenter:G.useSentenceSegmenter})}inferWordLength(Q,G){let Y=Math.max(0,Math.min(G,Math.max(0,Q.length-1)));return Q.slice(Y).match(/^\s*([^\s]+)/)?.[1]?.length||1}async speakChunk(Q,G,Y,J){return new Promise((X,j)=>{if(Y!==this.speakRunId){X(!1);return}let Z=new SpeechSynthesisUtterance(Q);if(this.utterance=Z,J&&T5(J))Z.voice=J;if(this.config?.rate)Z.rate=this.config.rate;if(this.config?.pitch)Z.pitch=this.config.pitch;let K=!1,W=!1,B=null,U=null,V=()=>{if(this.utterance===Z)this.utterance=null},H=()=>{if(B!==null)clearTimeout(B),B=null},N=()=>{Z.onstart=null,Z.onend=null,Z.onerror=null,Z.onpause=null,Z.onresume=null,Z.onboundary=null},O=($,F)=>{if(W)return;if(W=!0,H(),N(),V(),U&&this.settlePendingChunk===U)this.settlePendingChunk=null;if(Y===this.speakRunId)this._isPlaying=!1,this._isPaused=!1;if(F)j(F);else X($)},P=($)=>Error($==="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 ${L6/1000} seconds. The browser speech engine may be unavailable or stuck; try another voice or restart the browser.`);U=()=>O(!1),this.settlePendingChunk=U,Z.onstart=()=>{if(Y!==this.speakRunId){O(!1);return}K=!0,H(),this._isPlaying=!0,this._isPaused=!1;try{this.onPlaybackStart?.()}catch($){console.error("Browser TTS playback-start callback failed",$)}},Z.onend=()=>{if(Y!==this.speakRunId){O(!1);return}if(!K){O(!1,P("ended"));return}O(!0)},Z.onerror=($)=>{if(Y!==this.speakRunId){O(!1);return}if($.error==="interrupted"||$.error==="canceled"){O(!1);return}O(!1,Error(`Speech synthesis error: ${$.error}`))},Z.onpause=()=>{if(Y!==this.speakRunId)return;this._isPaused=!0},Z.onresume=()=>{if(Y!==this.speakRunId)return;this._isPaused=!1},Z.onboundary=($)=>{if(Y!==this.speakRunId)return;if(console.log("[BrowserProvider] Boundary event:",$.name,"charIndex:",$.charIndex,"charLength:",$.charLength),$.name!=="word"||!this.onWordBoundary)return;if(this.getHighlightMode()==="sentence")return;let F=Math.max(0,Math.min($.charIndex,Math.max(0,Q.length-1))),L=Number($.charLength||0),C=this.inferWordLength(Q,F),v=Number.isFinite(L)&&L>0&&L<=80&&F+L<=Q.length?L:C,I=Q.substring(F,Math.min(Q.length,F+v)).trim(),p=G+F;console.log("[BrowserProvider] Calling onWordBoundary with word:",I,"at position:",p),this.onWordBoundary(I,p,v)},B=setTimeout(()=>{if(W||K||Y!==this.speakRunId)return;O(!1,P("timedOut")),speechSynthesis.cancel()},L6);try{speechSynthesis.speak(Z)}catch($){O(!1,$ instanceof Error?$: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,G=this._isPlaying||Q!==null;if(this.speakRunId+=1,this.settlePendingVoiceWait?.(),this.settlePendingChunk?.(),G)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," "),W1=()=>/[\p{L}]+|\d+(?:\.\d+)?|[±√=+\-*/()²³^×÷≤≥≠≈<>|%°'′\u2062]/gu,J8=(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 G=Q.classList;if(G?.contains("sr-only")||G?.contains("pie-sr-only")||G?.contains("visually-hidden"))return!0;if(typeof window<"u"){let Y=window.getComputedStyle(Q);if(Y.display==="none"||Y.visibility==="hidden")return!0;let J=Number.parseFloat(Y.width||"0"),X=Number.parseFloat(Y.height||"0"),j=Number.isFinite(J)&&Number.isFinite(X)&&J<=1&&X<=1,Z=Y.clipPath.includes("inset(50%")||Y.clipPath.includes("inset(100%")||Y.clip.includes("rect(0px, 0px, 0px, 0px)")||Y.clip.includes("rect(0 0 0 0)");if((Y.position==="absolute"||Y.position==="fixed")&&j&&(Y.overflow==="hidden"||Z))return!0;if(Y.opacity==="0"&&j)return!0}return!1},U1=(Q,G)=>{let Y=Q.nodeType===1?Q:Q.parentElement;while(Y){if(J8(Y))return!0;if(G&&Y===G)break;Y=Y.parentElement}return!1};var C6=new Set(["computer-read-aloud","all"]),E6=new Set([...C6,"screen-reader"]),b6=new Set,S5=(Q)=>{let G=Q.getAttribute?.("data-tts-suppress");if(G===null||G===void 0)return!1;let Y=G.trim().toLowerCase();if(C6.has(Y))return!0;if(E6.has(Y))return!1;if(!b6.has(Y))b6.add(Y),console.warn(`[tts] data-tts-suppress="${G}" is not one of ${Array.from(E6).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},B1=(Q,G)=>{let Y=Q.nodeType===1?Q:Q.parentElement;while(Y){if(S5(Y))return!0;if(G&&Y===G)break;Y=Y.parentElement}return!1},V7=(Q,G)=>U1(Q,G)||B1(Q),X8=(Q,G)=>{if(typeof document>"u"||typeof document.createTreeWalker!=="function"||typeof NodeFilter>"u"||typeof Q.intersectsNode!=="function")return{text:Q.toString(),filtered:!1};let Y=[],J=!1,X=document.createTreeWalker(G,NodeFilter.SHOW_TEXT),j=X.nextNode();while(j){let Z=j;if(Q.intersectsNode(Z))if(V7(Z,G))J=!0;else{let K=Z.textContent||"",W=Z===Q.startContainer?Q.startOffset:0,B=Z===Q.endContainer?Q.endOffset:K.length;Y.push(K.slice(W,B))}j=X.nextNode()}return{text:Y.join(""),filtered:J}},Z8=(Q,G,Y)=>{if(!Q||!G)return!1;if(/\s/.test(Q)||/\s/.test(G))return!1;let J=Y?.boundarySpacingMode??"segmenterPreferred";if(J==="none")return!1;if(J==="segmenterPreferred")try{let Z=globalThis.Intl?.Segmenter;if(typeof Z==="function"){let K=new Z(Y?.locale,{granularity:"word"});if(Array.from(K.segment(`${Q}${G}`)).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(G);return X&&j},C7=(Q,G)=>{let Y=new Map;if(typeof document>"u"||typeof document.createTreeWalker!=="function"||typeof NodeFilter>"u")return{text:"",map:Y};let J=[],X=0,j=!0,Z=!1,K=null,W=null,B=document.createTreeWalker(Q,NodeFilter.SHOW_TEXT),U=B.nextNode();while(U){let H=U;if(H.parentElement&&!V7(H,Q)){let O=H.textContent||"",P=O.match(/\S/),$=P?P[0]:null;if(!j&&!Z&&Z8(W,$,G)){if(J.push(" "),K)Y.set(X,K);X++,Z=!0}for(let F=0;F<O.length;F++){let L=O[F],C=/\s/.test(L);if(j){if(!C)j=!1,J.push(L),Y.set(X,{node:H,offset:F}),K={node:H,offset:F},X++,Z=!1,W=L}else if(C){if(!Z)J.push(" "),Y.set(X,{node:H,offset:F}),K={node:H,offset:F},X++;Z=!0}else J.push(L),Y.set(X,{node:H,offset:F}),K={node:H,offset:F},X++,Z=!1,W=L}}U=B.nextNode()}let V=J.join("").trimEnd();while(Y.has(V.length))Y.delete(V.length);return{text:V,map:Y}};var y5=new Set(["speak","p","s","emphasis","prosody","say-as","voice","lang"]),T6=new Set(["audio","phoneme"]),y6=(Q)=>Q.replace(/"/g,'"').replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/ /g," ").replace(/ /g," ").replace(/&/g,"&"),D1=(Q,G,Y)=>{for(let J=0;J<G.length;J++)Q.push({char:G[J],rawOffset:Y===null?null:Y+J})},x5=(Q,G,Y)=>{let J=G.slice(Y).match(/^&(quot|apos|lt|gt|nbsp|amp|#160);/i);if(!J)return 0;return D1(Q,y6(J[0]),Y),J[0].length},S6=(Q)=>{Q.push({char:" ",rawOffset:null})},f5=(Q)=>{let G=new Map,Y=[],J=!0;for(let X of Q){if(/\s/.test(X.char)){if(!J&&Y.length>0){if(Y.push(" "),X.rawOffset!==null)G.set(X.rawOffset,Y.length-1)}J=!0;continue}if(Y.push(X.char),X.rawOffset!==null)G.set(X.rawOffset,Y.length-1);J=!1}while(Y.length>0&&Y[Y.length-1]===" ")Y.pop();for(let[X,j]of G)if(j>=Y.length)G.delete(X);return{text:Y.join(""),rawToSpokenOffsetMap:G}},k5=(Q)=>{return Q.match(/^<\/?\s*([A-Za-z0-9:-]+)/)?.[1]?.toLowerCase()||""},I5=(Q,G)=>{let Y=new RegExp(`${G}\\s*=\\s*("([^"]*)"|'([^']*)')`,"i"),J=Q.match(Y);return y6(J?.[2]??J?.[3]??"")||null},_1=(Q)=>{let G=[],Y=!1,J=!1,X=0;while(X<Q.length){let Z=Q[X];if(Z!=="<"){if(Z==="&"){let H=x5(G,Q,X);if(H>0){X+=H;continue}}D1(G,Z,X),X++;continue}let K=Q.indexOf(">",X+1);if(K<0){D1(G,Z,X),X++;continue}J=!0;let W=Q.slice(X,K+1),B=k5(W),U=/^<\s*\//.test(W),V=/\/\s*>$/.test(W);if(!U&&B==="sub"){let H=I5(W,"alias");if(!H){Y=!0,X=K+1;continue}D1(G,H,null);let N=Q.toLowerCase().indexOf("</sub>",K+1);X=N>=0?N+6:K+1;continue}if(!U&&B==="break"){S6(G),X=K+1;continue}if(!U&&T6.has(B)){if(Y=!0,V){X=K+1;continue}}if(B&&!y5.has(B)&&!T6.has(B)&&B!=="break"&&B!=="sub")Y=!0;if(!U&&(B==="p"||B==="s"))S6(G);X=K+1}let j=f5(G);return{spokenText:T(j.text),rawToSpokenOffsetMap:j.rawToSpokenOffsetMap,unsupportedSemantic:Y,hasMarkup:J}};var v5=W1(),v6=new Map([["zero","0"],["one","1"],["two","2"],["three","3"],["four","4"],["five","5"],["six","6"],["seven","7"],["eight","8"],["nine","9"],["ten","10"]]),h5=[{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}],j8=(Q)=>{let G=[];for(let Y of Q.matchAll(v5)){let J=Y[0],X=Y.index??0;G.push({text:J,normalized:J.toLowerCase(),start:X,end:X+J.length})}return G},K8=(Q)=>v6.get(Q.normalized)||Q.normalized,m5=(Q,G)=>{let Y=[];for(let J=0;J<Q.length;J++){for(let X=0;X<G.length;X++){let j=K8(Q[J]),Z=K8(G[X]);if(j===Z)Y.push({spokenStartToken:J,spokenEndToken:J+1,visibleToken:X,score:10})}for(let X of h5){let j=Q.slice(J,J+X.phrase.length);if(j.length!==X.phrase.length)continue;if(!j.every((Z,K)=>Z.normalized===X.phrase[K]))continue;for(let Z=0;Z<G.length;Z++){if(G[Z].normalized!==X.visible)continue;Y.push({spokenStartToken:J,spokenEndToken:J+X.phrase.length,visibleToken:Z,score:X.score})}}}return Y},u5=(Q,G)=>{let Y=m5(Q,G).sort((W,B)=>Q[W.spokenStartToken].start-Q[B.spokenStartToken].start||G[W.visibleToken].start-G[B.visibleToken].start),J=Array(Y.length).fill(0),X=Array(Y.length).fill(-1);for(let W=0;W<Y.length;W++){let B=Y[W];J[W]=B.score;for(let U=0;U<W;U++){let V=Y[U];if(V.spokenEndToken<=B.spokenStartToken&&V.visibleToken<B.visibleToken){let H=B.spokenStartToken-V.spokenEndToken,N=B.visibleToken-V.visibleToken-1,O=Math.max(0,Math.abs(H-N)-2),P=J[U]+B.score-O;if(P>J[W])J[W]=P,X[W]=U}}}let j=-1;for(let W=0;W<J.length;W++)if(j<0||J[W]>J[j])j=W;if(j<0)return[];let Z=[],K=j;while(K>=0)Z.unshift(Y[K]),K=X[K];return Z.map((W)=>{let B=Q[W.spokenStartToken],U=Q[W.spokenEndToken-1],V=G[W.visibleToken];return{spokenStart:B.start,spokenEnd:U.end,visibleStart:V.start,visibleEnd:V.end,score:W.score}})},p5=(Q,G,Y)=>{if(Q.length===0)return 0;let J=Q.length/Math.max(1,Math.min(G.length,Y.length)),X=Q.reduce((j,Z)=>j+Z.score,0)/Q.length/10;return Math.min(1,J*X)},V1=(Q)=>{let G=_1(Q.speechText),Y=T(Q.visibleText),J=G.spokenText,X=j8(J),j=j8(Y),Z=G.unsupportedSemantic?[]:u5(X,j),K=p5(Z,X,j),W=J===Y&&J.length>0,B=Z.length===1&&Z[0].score===10&&X.length<=2&&j.length<=2,U=G.unsupportedSemantic?"region-fallback":W?"exact-word":Z.length>=2||B?K>=0.12?"anchor-span":"region-fallback":"region-fallback",V=G.unsupportedSemantic?"unsupported":G.hasMarkup?"raw-ssml":"plain-spoken-text";return{speechText:Q.speechText,spokenText:J,visibleText:Y,playbackMode:U,boundaryOffsetMode:V,anchors:Z,confidence:K,spokenTokens:X,visibleTokens:j,rawToSpokenOffsetMap:G.rawToSpokenOffsetMap}},q8=(Q,G)=>Q.find((Y)=>Y.start<=G&&G<Y.end)||null,h6=(Q)=>{if(!Q)return null;if(/^<[^>]+>$/.test(Q.trim()))return null;let G=j8(Q)[0];if(!G)return null;return v6.get(G.normalized)||G.normalized},x6=(Q,G,Y)=>{let J=h6(Y);if(!G||!J)return!1;let X=q8(Q.spokenTokens,G.start);if(!X)return!1;return K8(X)===J},f6=(Q,G)=>{let Y=Q.rawToSpokenOffsetMap.get(G);if(Y!==void 0)return Y;for(let J=G;J<Q.speechText.length;J++){let X=Q.rawToSpokenOffsetMap.get(J);if(X!==void 0)return X;if(Q.speechText[J]===">")break}return null},k6=(Q,G,Y)=>{let J=f6(Q,G);if(J===null)return null;let X=f6(Q,Math.max(G,G+Y-1)),j=q8(Q.spokenTokens,J),Z=X!==null&&X>=J?X-J+1:j?j.end-J:Y;return{start:J,length:Math.max(1,Z)}},I6=(Q,G,Y)=>{if(G<0||G>=Q.spokenText.length)return null;let J=q8(Q.spokenTokens,G);if(!J)return null;return{start:G,length:Math.min(Y,J.end-G)}},m6=(Q,G,Y=1,J)=>{if(Q.boundaryOffsetMode==="unsupported"||!Number.isFinite(G))return null;let X=Math.max(1,Number.isFinite(Y)?Y:1);if(J&&/^<[^>]+>$/.test(J.trim()))return null;if(Q.boundaryOffsetMode==="raw-ssml"){let j=k6(Q,G,X),Z=I6(Q,G,X);if(J){if(x6(Q,j,J))return j;if(x6(Q,Z,J))return Z;if(h6(J))return null}return j||Z}return I6(Q,G,X)||k6(Q,G,X)},u6=(Q,G)=>{if(Q.playbackMode==="region-fallback")return null;let Y=Q.anchors.find((j)=>j.spokenStart<=G&&G<j.spokenEnd);if(Y)return{start:Y.visibleStart,end:Y.visibleEnd};let J=null,X=null;for(let j of Q.anchors){if(j.spokenEnd<=G){J=j;continue}if(j.spokenStart>G){X=j;break}}if(J&&X)return{start:Math.min(J.visibleStart,X.visibleStart),end:Math.max(J.visibleEnd,X.visibleEnd)};return null};var g5=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"]]]),c5=new Map([["","function-application"],["","implicit-multiply"],["","invisible-separator"],["","invisible-plus"]]),p6=new Map([["2",["squared"]],["3",["cubed"]]]),l5=new Map([["msqrt","radical"],["mroot","radical"],["msub","subscript"],["msubsup","subsupscript"],["munder","underscript"],["mover","overscript"],["munderover","underoverscript"],["mmultiscripts","multiscript"],["menclose","enclosure"]]),d5=(Q)=>Q.replace(/\s+/g," ").trim(),H7=(Q)=>(Q.localName||Q.tagName||"").toLowerCase(),i5=(Q)=>Q.nodeType===Node.ELEMENT_NODE,T7=(Q)=>Array.from(Q.childNodes).filter(i5),W8=(Q)=>d5(Q.textContent||""),Q7=(Q,G)=>({type:"element-range",quality:G,element:Q}),s5=(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"}},n5=(Q,G)=>{if(G==="operator"){if(Q==="−")return"-";return Q}return Q.toLowerCase()},r5=(Q,G,Y)=>{if(Y==="fraction")return["over","divided by"];if(Y==="superscript")return p6.get(Q)??[];if(Q==="|")return["absolute value"];if(G==="operator")return g5.get(Q)||[];return[]},F7=(Q)=>{let G=Q.normalized??n5(Q.text,Q.kind||"unknown");return{id:`math-token-${Q.state.nextId++}`,kind:Q.kind,role:Q.role,text:Q.text,normalized:G,spokenAliases:r5(Q.text,Q.kind,Q.role),sourceElement:Q.sourceElement,path:Q.path,target:Q.target||Q7(Q.sourceElement,"element-range"),optional:Q.optional}},A7=(Q,G,Y="tokens")=>{Q[Y].push(G)},g6=(Q,G,Y)=>{T7(Q).forEach((J,X)=>G7(J,G,`${Y}/${H7(J)}[${X}]`))},o5=(Q,G,Y)=>{let J=T7(Q);if(J[0])G7(J[0],G,`${Y}/numerator`);if(A7(G,F7({state:G,kind:"structure",role:"fraction",text:"/",sourceElement:Q,path:Y,target:Q7(Q,"element-range")})),J[1])G7(J[1],G,`${Y}/denominator`)},a5=(Q,G,Y)=>{let J=Q.getAttribute("open")||"(",X=Q.getAttribute("close")||")";A7(G,F7({state:G,kind:"operator",role:J==="|"?"absolute-value-fence":"open-fence",text:J,sourceElement:Q,path:`${Y}/open`,target:Q7(Q,"element-range")})),g6(Q,G,Y),A7(G,F7({state:G,kind:"operator",role:X==="|"?"absolute-value-fence":"close-fence",text:X,sourceElement:Q,path:`${Y}/close`,target:Q7(Q,"element-range")}))},t5=(Q,G,Y)=>{let J=T7(Q);if(J[0])G7(J[0],G,`${Y}/base`);let X=J[1];if(!X)return;let j=W8(X);if(p6.has(j)){A7(G,F7({state:G,kind:"structure",role:"superscript",text:j,normalized:j,sourceElement:X,path:`${Y}/exponent`,target:Q7(Q,"element-range")}));return}G7(X,G,`${Y}/exponent`)},e5=(Q,G,Y,J)=>{A7(G,F7({state:G,kind:"structure",role:J,text:W8(Q)||J,normalized:`\x00${J}`,sourceElement:Q,path:Y,target:Q7(Q,"element-range")}))},QQ=(Q,G,Y)=>{let J=0;for(let X of T7(Q)){if(H7(X)==="mtr"||H7(X)==="mlabeledtr")J++,A7(G,F7({state:G,kind:"layout",role:"table-row",text:`row-${J}`,normalized:`row-${J}`,sourceElement:X,path:`${Y}/row[${J}]`,target:Q7(X,"region-fallback")}),"layoutTargets");G7(X,G,`${Y}/${H7(X)}[${J}]`)}},GQ=(Q,G,Y)=>{let J=W8(Q);if(!J)return;let X=s5(H7(Q)),j=X==="operator"?c5.get(J):void 0,Z=j??(X==="operator"&&(J==="("||J===")")?"grouping-fence":X);A7(G,F7({state:G,kind:X,role:Z,text:J,sourceElement:Q,path:Y,target:j&&Q.parentElement?Q7(Q.parentElement,"region-fallback"):void 0,optional:Boolean(j)||Z==="grouping-fence"}))},G7=(Q,G,Y)=>{let J=H7(Q);switch(J){case"annotation":case"annotation-xml":return;case"semantics":{let X=T7(Q).find((j)=>{let Z=H7(j);return Z!=="annotation"&&Z!=="annotation-xml"});if(X)G7(X,G,`${Y}/presentation`);return}case"mi":case"mn":case"mo":case"mtext":case"ms":case"mspace":GQ(Q,G,Y);return;case"mfrac":o5(Q,G,Y);return;case"msup":t5(Q,G,Y);return;case"mfenced":a5(Q,G,Y);return;case"mtable":QQ(Q,G,Y);return;case"mphantom":return;case"maction":{let X=T7(Q)[0];if(X)G7(X,G,`${Y}/action`);return}default:{let X=l5.get(J);if(X){e5(Q,G,Y,X);return}g6(Q,G,Y)}}},c6=(Q)=>{let G={tokens:[],layoutTargets:[],nextId:0};return G7(Q,G,"/math"),{tokens:G.tokens,layoutTargets:G.layoutTargets,expressionTarget:Q7(Q,"region-fallback")}};var l6=(Q)=>{if(!Q.boundary)return null;return Q.alignment.segments.find((Y)=>Y.speechTokenIds.includes(Q.boundary.token.id))?.target||null};var YQ=(Q)=>{let G=[],Y=new Set,J=(X)=>{let j=X.toLowerCase().trim().split(/\s+/).filter(Boolean);if(j.length===0)return;let Z=j.join(" ");if(Y.has(Z))return;Y.add(Z),G.push(j)};J(Q.normalized);for(let X of Q.spokenAliases)J(X);return G},d6=(Q,G,Y)=>{let J=0;for(let X of Y){if(X.length<=J)continue;let j=!0;for(let Z=0;Z<X.length;Z++){let K=Q[G+Z];if(!K||K.normalized.toLowerCase()!==X[Z]){j=!1;break}}if(j)J=X.length}return J},JQ=(Q,G)=>{let Y=[],J=0;for(let X of G){let j=YQ(X);if(X.optional){let Z=d6(Q,J,j);if(Z>0)Y.push({speechTokens:Q.slice(J,J+Z),math:X}),J+=Z;continue}while(J<Q.length){let Z=d6(Q,J,j);if(Z>0){Y.push({speechTokens:Q.slice(J,J+Z),math:X}),J+=Z;break}J++}}return Y},XQ=(Q,G,Y)=>{let J=Y.filter((Z)=>!Z.optional).length,X=Q.filter((Z)=>!Z.math.optional).length,j=Q.reduce((Z,K)=>Z+K.speechTokens.length,0);return J>0&&X===J&&j===G.length},ZQ=(Q)=>Q.map(({speechTokens:G,math:Y})=>({speechTokenIds:G.map((J)=>J.id),mathTokenIds:[Y.id],score:1,confidence:1,target:Y.target})),i6=(Q)=>{let G=Q.minExactWordConfidence??0.95,Y=JQ(Q.speech.tokens,Q.math.tokens),J=XQ(Y,Q.speech.tokens,Q.math.tokens)?1:0;return{segments:J>=G?ZQ(Y):[],confidence:J,fallbackTarget:Q.math.expressionTarget}};var s6=W1(),jQ=new Map([["zero","0"],["one","1"],["two","2"],["three","3"],["four","4"],["five","5"],["six","6"],["seven","7"],["eight","8"],["nine","9"],["ten","10"]]),n6=(Q)=>{let G=Q.toLowerCase();return jQ.get(G)||G},KQ=(Q)=>{let G=[];for(let Y of Q.matchAll(s6)){let J=Y[0],X=Y.index??0;G.push({id:`speech-token-${G.length}`,text:J,normalized:n6(J),start:X,end:X+J.length,sourceStart:X,sourceEnd:X+J.length,coordinateSystem:"normalized-speech"})}return G},N7=(Q)=>{let G=_1(Q.speechText);return{speechText:Q.speechText,spokenText:G.spokenText,tokens:KQ(G.spokenText),rawToSpokenOffsetMap:G.rawToSpokenOffsetMap,boundaryOffsetSpace:G.unsupportedSemantic?"unsupported":G.hasMarkup?"raw-ssml":"plain-spoken-text",unsupportedSemantic:G.unsupportedSemantic,hasMarkup:G.hasMarkup}},D8=(Q)=>{if(!Q)return null;if(/^<[^>]+>$/.test(Q.trim()))return null;let G=Q.match(s6);if(!G?.[0])return null;return n6(G[0])},qQ=(Q,G)=>Q.find((Y)=>Y.start<=G&&G<Y.end)||null,WQ=(Q,G)=>{let Y=Q.rawToSpokenOffsetMap.get(G);if(Y!==void 0)return Y;for(let J=G;J<Q.speechText.length;J++){let X=Q.rawToSpokenOffsetMap.get(J);if(X!==void 0)return X;if(Q.speechText[J]===">")break}return null},U8=(Q,G,Y)=>{if(G===null)return null;let J=qQ(Q.tokens,G);if(!J)return null;return{token:J,start:G,length:Math.max(1,Math.min(Y,J.end-G)),confidence:0.75}},B8=(Q,G)=>{let Y=D8(G);return Boolean(Q&&Y&&Q.token.normalized===Y)},_8=(Q)=>{if(Q.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(Q.position)||Q.boundaryWord&&/^<[^>]+>$/.test(Q.boundaryWord.trim()))return null;let G=Math.max(1,Number.isFinite(Q.length)?Q.length:1),Y=U8(Q.tokenization,WQ(Q.tokenization,Q.position),G),J=U8(Q.tokenization,Q.position>=0&&Q.position<Q.tokenization.spokenText.length?Q.position:null,G);if(B8(Y,Q.boundaryWord))return{...Y,confidence:1};if(B8(J,Q.boundaryWord))return{...J,confidence:1};if(Q.boundaryWord&&D8(Q.boundaryWord))return null;return Q.tokenization.boundaryOffsetSpace==="raw-ssml"?Y||J:J||Y},r6=(Q)=>{if(Q.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(Q.position)||Q.boundaryWord&&/^<[^>]+>$/.test(Q.boundaryWord.trim()))return null;let G=Math.max(1,Number.isFinite(Q.length)?Q.length:1),Y=U8(Q.tokenization,Q.position>=0&&Q.position<Q.tokenization.spokenText.length?Q.position:null,G);if(B8(Y,Q.boundaryWord))return{...Y,confidence:1};if(Q.boundaryWord&&D8(Q.boundaryWord))return null;return Y};var S7=(Q)=>{let G=N7({speechText:Q.speechText}),Y=c6(Q.mathElement);return{speech:G,math:Y,result:i6({speech:G,math:Y})}};var o6=(Q,G)=>{let Y=r6({tokenization:Q.speech,position:G.position,length:G.length,boundaryWord:G.boundaryWord});return l6({alignment:Q.result,boundary:Y})},a6=(Q,G)=>{if(!G.boundaryWord||/^<[^>]+>$/.test(G.boundaryWord.trim()))return null;let Y=N7({speechText:G.boundaryWord}).tokens[0];if(!Y)return null;let J=Q.math.tokens.filter((X)=>{let j=Y.normalized.toLowerCase();return X.normalized.toLowerCase()===j||X.spokenAliases.some((Z)=>Z.toLowerCase()===j)});return J.length===1?J[0].target:null};var UQ=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"]),BQ=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"]),t6=(Q)=>Q.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),DQ=(Q)=>t6(Q).replace(/"/g,"""),_Q=(Q,G)=>{let Y=Q.toLowerCase(),J=G.trim().toLowerCase();if(Y.startsWith("on"))return!0;if(!BQ.has(Y))return!0;if(J.includes("javascript:"))return!0;if(J.includes("data:text/html"))return!0;return!1},VQ=(Q)=>{let G=Q.localName.toLowerCase();if(!UQ.has(G))return!1;let Y=Q.namespaceURI;return!Y||Y==="http://www.w3.org/1998/Math/MathML"||Y==="http://www.w3.org/1999/xhtml"},e6=(Q)=>{if(Q.nodeType===Node.TEXT_NODE)return t6(Q.textContent||"");if(Q.nodeType===Node.COMMENT_NODE)return"";if(Q.nodeType!==Node.ELEMENT_NODE)return null;let G=Q;if(!VQ(G))return null;let Y=G.localName.toLowerCase(),J=[];for(let Z of Array.from(G.attributes)){let K=Z.name.toLowerCase();if(_Q(K,Z.value))continue;if(K==="xmlns"&&Z.value!=="http://www.w3.org/1998/Math/MathML")return null;J.push(`${K}="${DQ(Z.value)}"`)}if(Y==="math"&&!J.some((Z)=>Z.startsWith("xmlns=")))J.unshift('xmlns="http://www.w3.org/1998/Math/MathML"');let X=[];for(let Z of Array.from(G.childNodes)){let K=e6(Z);if(K===null)return null;X.push(K)}let j=J.length>0?` ${J.join(" ")}`:"";return`<${Y}${j}>${X.join("")}</${Y}>`},HQ=(Q)=>{if(typeof DOMParser<"u")return new DOMParser().parseFromString(Q,"application/xml");return null},H1=(Q)=>{let G=String(Q||"").trim();if(!G)return null;let Y=HQ(G);if(!Y)return null;if(Y.getElementsByTagName("parsererror").length>0)return null;let J=Y.documentElement;if(!J||J.localName.toLowerCase()!=="math")return null;return e6(J)};var Q0=(Q)=>({chars:[],map:new Map,position:0,inLeadingWhitespace:!0,lastCharWasWhitespace:!1,lastMapped:null,options:Q}),G0=(Q)=>Q.classList?.contains("MathJax")||Q.tagName?.toLowerCase()==="mjx-container",Y0=(Q)=>Q.tagName?.toLowerCase()==="mjx-assistive-mml",J0=(Q)=>{let G=Q.tagName?.toLowerCase();return G==="annotation"||G==="annotation-xml"},FQ=(Q)=>{let G=Q.getAttribute("data-mathml");return G&&G.trim()?G:null},AQ=(Q)=>{return Q.querySelector("mjx-assistive-mml math")?.outerHTML||null},NQ=(Q)=>{if(Q.tagName.toLowerCase()==="math")return H1(Q.outerHTML);let G=FQ(Q);if(G){let Y=H1(G);if(Y)return Y}if(G0(Q)){let Y=AQ(Q);if(Y){let J=H1(Y);if(J)return J}}return null};var MQ=new Set(["P","H1","H2","H3","H4","H5","H6","LI","TD","TH","DD","DT","FIGCAPTION","LABEL","BUTTON"]),OQ=new Set(["heading","listitem","option","radio","row","cell","columnheader","rowheader"]),zQ=(Q,G)=>{let Y=Q.parentElement,J=null;while(Y&&Y!==G){let X=(Y.getAttribute("role")||"").toLowerCase(),j=Y.tagName.toUpperCase();if(MQ.has(j)||OQ.has(X)){J=Y;break}Y=Y.parentElement}return J||G},PQ=(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")||G0(Q),M7=(Q,G,Y)=>{if(/[.,;:!?]/.test(G)&&Q.chars.length>0&&Q.chars[Q.chars.length-1]===" ")Q.chars.pop(),Q.position--,Q.map.delete(Q.position);if(Q.chars.push(G),Y)Q.map.set(Q.position,Y),Q.lastMapped=Y;else if(Q.lastMapped)Q.map.set(Q.position,Q.lastMapped);Q.position++},X0=(Q,G)=>{if(Q.inLeadingWhitespace||Q.lastCharWasWhitespace||Q.chars.length===0)return!1;let Y=Q.chars[Q.chars.length-1];return Z8(Y,G,Q.options)},Z0=(Q,G)=>{let Y=G.textContent||"",J=!1;for(let X=0;X<Y.length;X++){let j=Y[X],Z=/\s/.test(j);if(Q.inLeadingWhitespace){if(!Z)Q.inLeadingWhitespace=!1,M7(Q,j,{node:G,offset:X}),J=!0,Q.lastCharWasWhitespace=!1;continue}if(Z){if(!Q.lastCharWasWhitespace)M7(Q," ",{node:G,offset:X});Q.lastCharWasWhitespace=!0;continue}if(!J&&X0(Q,j))M7(Q," ",{node:G,offset:X});M7(Q,j,{node:G,offset:X}),J=!0,Q.lastCharWasWhitespace=!1}},LQ=(Q,G)=>{for(let Y=0;Y<G.text.length;Y++){let J=G.text[Y],X=/\s/.test(J),j=G.map.get(Y)||null,Z=j?.node||Q.lastMapped?.node||null,K=j?.offset??Q.lastMapped?.offset??0,W=j?{node:j.node,offset:j.offset}:Z?{node:Z,offset:K}:null;if(Q.inLeadingWhitespace){if(X)continue;Q.inLeadingWhitespace=!1}if(X){if(!Q.lastCharWasWhitespace)M7(Q," ",W);Q.lastCharWasWhitespace=!0;continue}if(Y===0&&X0(Q,J))M7(Q," ",W);if(M7(Q,J,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:K})}},$Q=(Q)=>{if(typeof DOMParser>"u")return"";let G=new DOMParser().parseFromString(Q,"application/xml");if(G.getElementsByTagName("parsererror").length>0)return"";let Y=[],J=(X)=>{if(X.nodeType===3){let Z=X.textContent||"";if(Z.trim())Y.push(Z);return}if(X.nodeType!==1)return;let j=X;if(J0(j))return;for(let Z of Array.from(j.childNodes))J(Z)};return J(G.documentElement),T(Y.join(" "))},wQ=(Q,G,Y)=>{let J=Q0(Y),X=(K)=>{if(V7(K,Q))return;if(K.nodeType===3){Z0(J,K);return}if(K.nodeType!==1)return;let W=K;if(Y0(W)||J0(W))return;for(let B of Array.from(W.childNodes))X(B)};X(Q),j0(J);let j=T(J.chars.join(""));if(j)return{text:j,map:J.map};let Z=$Q(G);if(!Z)return C7(Q,Y);return{text:Z,map:new Map}},j0=(Q)=>{while(Q.chars.length>0&&/\s/.test(Q.chars[Q.chars.length-1]))Q.chars.pop(),Q.position--,Q.map.delete(Q.position)},RQ=(Q,G)=>{let Y=Q0(G),J=[],X=0,j,Z=!1,K=()=>{let U=T(Y.chars.slice(X,Y.chars.length).join(""));if(U)J.push({type:"text",text:U,sourceElement:j});X=Y.chars.length,j=void 0},W=(U)=>{if(V7(U,Q))return;if(U.nodeType===Node.TEXT_NODE){let N=zQ(U,Q);if(j&&N!==j)K();j=N,Z0(Y,U);return}if(U.nodeType!==Node.ELEMENT_NODE)return;let V=U;if(Y0(V))return;let H=NQ(V);if(H){K();let N=wQ(V,H,G);LQ(Y,N);let O=T(N.text);J.push({type:"math",mathml:H,fallbackText:O,sourceElement:V}),X=Y.chars.length,Z=!0;return}for(let N of Array.from(V.childNodes))W(N)};for(let U of Array.from(Q.childNodes))W(U);j0(Y),K();let B=Y.chars.join("");while(Y.map.has(B.length))Y.map.delete(B.length);return{visibleText:B,map:Y.map,chunks:J,containsMathMarkup:Z}},O7=(Q,G)=>{if(!PQ(Q)){let{text:Y,map:J}=C7(Q,G);return{visibleText:Y,map:J,chunks:Y?[{type:"text",text:Y}]:[],containsMathMarkup:!1}}return RQ(Q,G)};var V8=null,K0=Promise.resolve(),bQ=(Q)=>(Q||"en").split("-")[0].toLowerCase()||"en",CQ=async()=>{if(!V8)V8=import("speech-rule-engine").then((Q)=>{let G=Q.default||Q;if(!G||typeof G.toSpeech!=="function")throw Error("speech-rule-engine did not expose toSpeech");return G});return V8},TQ=(Q)=>Q==="en"?"clearspeak":"mathspeak",q0=(Q)=>!!Q&&typeof Q==="object"&&!Array.isArray(Q),W0=(Q)=>typeof Q==="string"&&Q.trim()?Q.trim():void 0,z7=(Q)=>{if(!q0(Q))return;let G=W0(Q.domain),Y=W0(Q.style),J=q0(Q.engineOptions)?Q.engineOptions:void 0;if(!G&&!Y&&!J)return;return{...G?{domain:G}:{},...Y?{style:Y}:{},...J?{engineOptions:J}:{}}},SQ=async(Q,G,Y,J)=>{let X=bQ(G),j=z7(J);await Q.setupEngine?.({...j?.engineOptions||{},locale:X,domain:j?.domain||TQ(X),...j?.style?{style:j.style}:{},modality:"speech",markup:Y}),await Q.engineReady?.()},yQ=async(Q)=>{let G=K0.then(Q,Q);return K0=G.then(()=>{return},()=>{return}),G},U0=async(Q,G,Y,J,X)=>yQ(async()=>{return await SQ(Q,Y,J,X),Q.toSpeech(G)}),xQ=(Q)=>Q.replace(/^\s*<\?xml[^>]*\?>\s*/i,""),fQ=async(Q,G,Y,J)=>{try{let X=xQ(await U0(Q,G,Y,"ssml",J));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}},F1=async(Q,G={})=>{if(!Q.some((B)=>B.type==="math"))return{speechText:T(Q.map((B)=>B.type==="text"?B.text:B.fallbackText).join(" ")),usedMathSpeech:!1,usedFallback:!1};let Y=null,J=!1,X=!1,j=G.loadSre||CQ,Z=[];for(let B of Q){if(B.type==="text"){Z.push(B.text);continue}try{if(!Y)Y=await j();let U=T(await U0(Y,B.mathml,G.language,"none",G.mathSpeech));if(U){Z.push(U),J=!0;continue}X=!0,Z.push(B.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(B.fallbackText)}}let K=T(Z.join(" ")),W;if(G.produceSsml&&Y&&J&&Q.length===1&&Q[0].type==="math")W=await fQ(Y,Q[0].mathml,G.language,G.mathSpeech)??void 0;return{speechText:K,usedMathSpeech:J,usedFallback:X,ssml:W}};var kQ=(Q,G)=>F1([Q],G),IQ=(Q)=>(Q||"en").split("-")[0].toLowerCase()||"en",vQ=new Set(["H1","H2","H3","H4","H5","H6","LI","LABEL","BUTTON"]),hQ=new Set(["heading","listitem","option","radio"]),mQ=(Q)=>{if(Q.type!=="text"||!Q.sourceElement)return!1;let G=Q.sourceElement.tagName.toUpperCase(),Y=(Q.sourceElement.getAttribute("role")||"").toLowerCase();return vQ.has(G)||hQ.has(Y)},H8=async(Q)=>{let G=Q.resolveMathSpeech??kQ,{visibleText:Y}=Q,J=[],X=0,j=(K)=>{let W=T(K),B=Y.indexOf(W,X),U=B>=0?B:X,V=U+W.length;return X=V,{start:U,end:V}},Z=[];for(let K=0;K<Q.chunks.length;K++){let W=Q.chunks[K];if(W.type==="text"){let N=mQ(W)?[{text:W.text,offset:0}]:E7(W.text,{locale:Q.language});for(let O of N){let P=T(O.text);if(!P)continue;let $=j(P);J.push({sourceChunkIndex:K,segment:{kind:"prose",spokenText:P,visibleText:P,visibleSpan:$}}),Z.push(P)}continue}let B=j(W.fallbackText),U=await G(W,{language:Q.language,produceSsml:Q.produceSsml,mathSpeech:Q.mathSpeech}),V=!U.speechText,H=U.speechText||W.fallbackText;J.push({sourceChunkIndex:K,segment:{kind:"math",spokenText:H,mathml:W.mathml,fallbackText:W.fallbackText,visibleSpan:B,usedFallback:V,ssml:U.ssml}}),Z.push(H)}return{segments:J,locale:IQ(Q.language),visibleText:Y,plainSpeechText:T(Z.join(" "))}};var uQ=(Q)=>(Q||"en").split("-")[0].toLowerCase()||"en",pQ="sre-v1",gQ=256,F8=(Q)=>{if(Array.isArray(Q))return`array:[${Q.map(F8).join(",")}]`;if(Q&&typeof Q==="object")return`object:{${Object.entries(Q).sort(([G],[Y])=>G.localeCompare(Y)).map(([G,Y])=>`${JSON.stringify(G)}:${F8(Y)}`).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)}`},B0=(Q,G,Y,J)=>`${pQ}\x00${uQ(Q)}\x00${G?"ssml":"plain"}\x00${F8(Y??null)}\x00${J}`,A8=(Q={})=>{let G=Math.max(1,Q.maxEntries??gQ),Y=Q.resolve??((j,Z)=>F1([j],Z)),J=new Map,X=(j,Z)=>{J.delete(j),J.set(j,Z);while(J.size>G){let K=J.keys().next().value;if(K!==void 0)J.delete(K)}};return async(j,Z)=>{let K=z7(Z.mathSpeech),W=Z.produceSsml===!0,B=B0(Z.language,W,K,j.mathml),U=J.get(B);if(U)return J.delete(B),J.set(B,U),U;let V=await Y(j,{...Z,mathSpeech:K});if(W&&V.ssml&&G>1)X(B0(Z.language,!1,K,j.mathml),{speechText:V.speechText,usedMathSpeech:V.usedMathSpeech,usedFallback:V.usedFallback});return X(B,V),V}};var cQ=(Q)=>{if(!Q||/^<[^>]+>$/.test(Q.trim()))return null;return N7({speechText:Q}).tokens[0]?.normalized||null},lQ=(Q,G)=>{let Y=N7({speechText:Q.speechText});if(!Number.isFinite(G.position))return{boundary:null,spokenText:Y.spokenText};let J=_8({tokenization:Y,position:G.position,length:G.length,boundaryWord:G.word});return{boundary:J?{start:J.start,length:J.length}:null,spokenText:Y.spokenText}},dQ=(Q,G,Y)=>{if(!Y)return!0;return N7({speechText:Q}).tokens.find((X)=>X.start<=G&&G<X.end)?.normalized===Y},D0=(Q,G)=>{let Y=cQ(G.word);if(Q.id!==G.chunkId)return{chunkId:G.chunkId,normalizedWord:Y,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"boundary chunk id did not match highlight chunk"};if(G.providerOffsetSpace==="unknown"||Q.offsetSpace==="unsupported")return{chunkId:Q.id,normalizedWord:Y,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"boundary offset space is unsupported"};let J,X;if(Q.catalogAlignment)J=m6(Q.catalogAlignment,G.position,G.length,G.word),X=Q.catalogAlignment.spokenText;else{let j=lQ(Q,G);J=j.boundary,X=j.spokenText}if(!J)return{chunkId:Q.id,normalizedWord:Y,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"could not resolve provider boundary to chunk speech"};if(!dQ(X,J.start,Y))return{chunkId:Q.id,normalizedWord:Y,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"could not resolve provider boundary to matching word"};return{chunkId:Q.id,normalizedWord:Y,chunkSpokenStart:J.start,chunkSpokenEnd:J.start+J.length,confidence:Y?1:0.75,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 V0=new Map([["mi","mjx-mi"],["mn","mjx-mn"],["mo","mjx-mo"],["mtext","mjx-mtext"]]),N8="mi,mn,mo,mtext",H0="mjx-mi,mjx-mn,mjx-mo,mjx-mtext",F0=["mjx-mfrac","mjx-msqrt","mjx-mroot","mjx-mtable","mjx-munder","mjx-mover","mjx-munderover"].join(","),A0=(Q)=>{if(Q.type==="text-range")return Q.node.parentElement;return Q.element},A1=(Q)=>{let G=Q;while(G){if(G.localName?.toLowerCase()==="mjx-container")return G;G=G.parentElement}return null},_0=(Q)=>{if(!Q)return!1;if(A1(Q))return!1;return!U1(Q)},N0=(Q)=>{let G=Q.getBoundingClientRect?.();return Boolean(G&&G.width>0&&G.height>0)},M8=(Q)=>{let G=Q;while(G){if(G.localName?.toLowerCase()==="math")return G;G=G.parentElement}return null},M0=(Q,G)=>{if(Q.length===0)return!1;if(Q.length!==G.length)return!1;for(let Y=0;Y<Q.length;Y+=1){let J=V0.get(Q[Y].localName.toLowerCase());if(!J)return!1;if(G[Y].localName.toLowerCase()!==J)return!1}return!0},iQ=(Q,G)=>{if(!Q)return null;if(!V0.has(Q.localName.toLowerCase()))return null;if(G.querySelector(F0))return null;let Y=M8(Q),J=G.querySelector("mjx-math");if(!Y||!J)return null;let X=Array.from(Y.querySelectorAll(N8)),j=X.indexOf(Q);if(j<0)return null;let Z=Array.from(J.querySelectorAll(H0));if(!M0(X,Z))return null;let K=Z[j];if(!K||!N0(K))return null;return K},O0=(Q)=>{let G=A1(Q);if(G){if(G.querySelector(F0))return"expression";let X=M8(Q)??Q,j=G.querySelector("mjx-math");if(!j)return"expression";let Z=Array.from(X.querySelectorAll(N8)),K=Array.from(j.querySelectorAll(H0));if(!M0(Z,K))return"expression";return K.some((W)=>N0(W))?"token":"expression"}let Y=M8(Q)??Q;return Array.from(Y.querySelectorAll(N8)).some((X)=>!U1(X))?"token":"expression"},O8=(Q)=>{let G=A0(Q),Y=A1(G);if(Y){let J=iQ(G,Y);if(J)return{type:"element",quality:"semantic-token",element:J};return{type:"element",quality:"expression",element:Y}}if(Q.type==="text-range"){if(!_0(Q.node.parentElement))return null;return{type:"text-range",quality:"semantic-token",node:Q.node,startOffset:Q.startOffset,endOffset:Q.endOffset}}if(!_0(Q.element))return null;return{type:"element",quality:Q.quality==="region-fallback"?"expression":"semantic-token",element:Q.element}},z0=O8,P0=()=>{let Q=new WeakMap;return(G)=>{let Y=A0(G),J=A1(Y);if(!Y||!J)return O8(G);if(Q.has(Y))return Q.get(Y)??null;let X=O8(G);return Q.set(Y,X),X}};var L0=(Q,G,Y,J=Q.mathAlignments,X=z0)=>{if(G.chunkSpokenStart===null||G.chunkSpokenEnd===null)return null;let j=null;for(let Z of J){let K=o6(Z.alignment,{position:G.chunkSpokenStart,length:Math.max(1,G.chunkSpokenEnd-G.chunkSpokenStart),boundaryWord:Y.word})||a6(Z.alignment,{boundaryWord:Y.word});if(!K)continue;let W=X(K);if(!W)continue;if(W.quality==="semantic-token")return W;j??=W}return j};var N1=(Q,G,Y)=>{if(!Q||typeof document>"u")return null;if(Y<=G)return null;let J=Q.get(G),X=Q.get(Math.max(G,Y-1));if(!J)return null;if(!X)X=J;try{let j=document.createRange();return j.setStart(J.node,J.offset),j.setEnd(X.node,X.offset+1),j}catch{return null}};var $0=(Q,G)=>{if(!Q.catalogAlignment||G.chunkSpokenStart===null)return null;let Y=u6(Q.catalogAlignment,G.chunkSpokenStart);if(!Y)return null;let J=N1(Q.visibleMap,Y.start,Y.end);if(!J)return null;return{type:"range",quality:Q.catalogAlignment.playbackMode==="exact-word"?"exact-word":"semantic-token",range:J}};var sQ=(Q)=>Q.regionRange?{type:"range",quality:"region",range:Q.regionRange}:Q.regionElement?{type:"element",quality:"region",element:Q.regionElement}:null,w0=(Q,G=Q.chunk.mathAlignments)=>{if(G.length!==1)return null;let Y=G[0]?.alignment.result.fallbackTarget;return Y?Q.renderedMathTargetResolver(Y):null},nQ=(Q,G)=>{if(!Q)return G.mathAlignments;return G.mathAlignments.filter(({element:Y})=>{try{if(Q.type==="range")return Q.range.intersectsNode(Y);if(Q.type==="element")return Q.element===Y||Q.element.contains(Y);return Q.node.parentElement?.contains(Y)||!1}catch{return!1}})},R0=()=>({activeTarget:null,regionTarget:null,quality:"region",confidence:0,reason:"boundary chunk id was not found"}),E0=(Q)=>Q.length===1?Q[0].element:null,rQ=(Q,G)=>G.length>0&&G.every(({element:Y})=>Q.mathCapabilityByElement.get(Y)==="token"),oQ=3,aQ=(Q,G,Y)=>{if(!G||G.type!=="range")return!1;let{startContainer:J,endContainer:X}=G.range;if(J===X&&J.nodeType===oQ)return!1;return Y.some(({element:Z})=>Q.mathCapabilityByElement.get(Z)==="token"&&Z.contains(J)&&Z.contains(X))},tQ=(Q,G)=>({chunk:Q,regionTarget:sQ(Q),renderedMathTargetResolver:P0(),mathCapabilityByElement:new Map(Q.mathAlignments.map(({element:Y})=>[Y,G?O0(Y):"expression"])),heldTokenByElement:new Map}),b0=(Q)=>{let G=Q.mathTokenHighlighting!==!1,Y=new Map(Q.chunks.map((J)=>[J.id,tQ(J,G)]));return{chunks:Q.chunks,resolveInitial(J){let X=Y.get(J);if(!X)return R0();let j=X.chunk.mathAlignments,Z=j.length===1?j[0].element:null,K=Z?X.mathCapabilityByElement.get(Z):null;if(K==="expression")return P7({semanticTarget:null,expressionTarget:w0(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:K==="token"?"initial region (sticky token mode, awaiting first token)":"initial region fallback"})},resolveBoundary(J){let X=Y.get(J.chunkId);if(!X)return R0();let{chunk:j}=X,Z=D0(j,J),K=$0(j,Z),W=nQ(K,j),B=(!K||W.length>0?L0(j,Z,J,W,X.renderedMathTargetResolver):null)||null,U=G&&B&&B.quality!=="expression"?B:null,V=B&&B.quality==="expression"?B:null;if(U){let H=E0(W);if(H)X.heldTokenByElement.set(H,U);return P7({semanticTarget:U,expressionTarget:null,regionTarget:X.regionTarget,confidence:Z.confidence,reason:Z.reason})}if(K&&(G?!aQ(X,K,W):W.length===0))return P7({semanticTarget:K,expressionTarget:null,regionTarget:X.regionTarget,confidence:Z.confidence,reason:Z.reason});if(rQ(X,W)){let H=E0(W),N=H?X.heldTokenByElement.get(H)??null:null;return P7({semanticTarget:N,expressionTarget:null,regionTarget:X.regionTarget,confidence:Z.confidence,reason:N?"hold last token (sticky token mode)":"region (sticky token mode, awaiting first token)"})}return P7({semanticTarget:null,expressionTarget:V??w0(X,W),regionTarget:X.regionTarget,confidence:Z.confidence,reason:Z.reason})}}};var eQ=(Q)=>{if(Q.alignment?.boundaryOffsetMode)return Q.alignment.boundaryOffsetMode;let G=Q.mathAlignment?.speech.boundaryOffsetSpace;if(G)return G;return"plain-spoken-text"},Q9=(Q)=>{if(Q.mathAlignments?.length)return Q.mathAlignments;if(Q.mathAlignment&&Q.sourceElement)return[{element:Q.sourceElement,alignment:Q.mathAlignment}];return[]},C0=(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((Y,J)=>({id:`tts-chunk-${J}`,speechText:Y.speechText,visibleText:Y.visibleText,sourceElement:Y.sourceElement,contentRoot:Q.contentRoot,regionElement:Y.regionElement??Y.sourceElement,regionRange:Y.regionRange,visibleMap:Y.visibleMap,catalogAlignment:Y.alignment,mathAlignments:Q9(Y),offsetSpace:eQ(Y)}))};var G9=["[data-pie-tts-region]","[data-catalog-region]","li","p","label","section","[role='group']","[role='region']","div"].join(","),M1=(Q,G)=>{let Y=Q.closest(G9);if(Y&&G.contains(Y))return Y;return Q};var Y9=(Q,G,Y)=>{let J=new Map;for(let X=G;X<Y;X++){let j=Q.get(X);if(j)J.set(X-G,j)}return J},z8=async(Q)=>{let G=O7(Q.contentRoot,Q.textProcessingOptions),Y=await H8({chunks:G.chunks,visibleText:G.visibleText,language:Q.language,mathSpeech:Q.mathSpeech,produceSsml:Q.produceSsml,resolveMathSpeech:Q.resolveMathSpeech});return{plan:{items:Y.segments.map(({segment:X,sourceChunkIndex:j})=>{let Z=G.chunks[j];if(X.kind==="prose"){let W=Z?.type==="text"?Z.sourceElement??Q.contentRoot:Q.contentRoot;return{segment:X,anchor:{sourceElement:W,regionElement:M1(W,Q.contentRoot),visibleMap:Y9(G.map,X.visibleSpan.start,X.visibleSpan.end)}}}let K=Z?.type==="math"?Z.sourceElement??null:null;return{segment:X,anchor:{sourceElement:K,regionElement:K}}}),locale:Y.locale,visibleText:Y.visibleText,plainSpeechText:Y.plainSpeechText},containsMathMarkup:G.containsMathMarkup,visibleText:G.visibleText}};var J9=(Q,G)=>{let Y=V1({speechText:Q.spokenText,visibleText:Q.spokenText});return{speechText:Q.spokenText,visibleText:Q.visibleText,sourceElement:G.sourceElement,regionElement:G.regionElement,regionRange:N1(G.visibleMap,0,Q.visibleText.length)??void 0,speechMatchesVisibleText:!0,playbackMode:Y.playbackMode,alignment:Y,visibleMap:G.visibleMap}},T0=(Q,G)=>{let Y=G.sourceElement;return{speechText:Q.spokenText,visibleText:Q.fallbackText,sourceElement:Y,regionElement:G.regionElement,speechMatchesVisibleText:Q.spokenText===Q.fallbackText,mathAlignment:Y?S7({mathElement:Y,speechText:Q.spokenText}):void 0}},X9=(Q,G,Y)=>{let J=G.sourceElement;return{speechText:Y,visibleText:Q.fallbackText,sourceElement:J,regionElement:G.regionElement,speechMatchesVisibleText:!1,mathAlignment:J?S7({mathElement:J,speechText:Y}):void 0,plainFallback:T0(Q,G)}},P8=(Q,G={})=>Q.items.map(({segment:Y,anchor:J})=>{if(Y.kind==="prose")return J9(Y,J);if(G.format==="ssml"&&Y.ssml)return X9(Y,J,Y.ssml);return T0(Y,J)});var S0="pie-tts-control-handoff";var R;(function(Q){Q.IDLE="idle",Q.LOADING="loading",Q.PLAYING="playing",Q.PAUSED="paused",Q.ERROR="error"})(R||(R={}));var y0=(Q,G)=>Q===G||Q.startContainer===G.startContainer&&Q.startOffset===G.startOffset&&Q.endContainer===G.endContainer&&Q.endOffset===G.endOffset,Z9=(Q,G)=>{if(Q===G)return!0;if(!Q||!G||Q.type!==G.type||Q.quality!==G.quality)return!1;if(Q.type==="range"&&G.type==="range")return y0(Q.range,G.range);if(Q.type==="element"&&G.type==="element")return Q.element===G.element;if(Q.type==="text-range"&&G.type==="text-range")return Q.node===G.node&&Q.startOffset===G.startOffset&&Q.endOffset===G.endOffset;return!1};class p7{currentProvider=null;provider=null;highlightCoordinator=null;highlightTargetResolverProvider=null;catalogResolver=null;state=R.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=[];currentSeekSegmentIndex=0;activeSentenceStartOffset=null;playbackStartDeferredRunId=null;pendingPlaybackStartHighlights=[];playbackStartBarrierCleanup=null;playbackRateWriteQueue=Promise.resolve();playbackRateRequestId=0;pendingPlaybackRateRequest=null;activePlaybackRate=null;activeHighlightMode="word";lastRenderedRegionTarget=null;telemetryReporter=null;generatedMathSpeechResolver=A8();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,G){if(!p7.debugEnabled)return;if(G===void 0)console.debug(Q);else console.debug(Q,G)}clearPlaybackStartBarrier(Q=this.playbackStartBarrierCleanup){if(Q?.(),this.playbackStartBarrierCleanup===Q)this.playbackStartBarrierCleanup=null}notifyPlaybackStarted(Q){if(this.playbackStartDeferredRunId!==Q||Q!==this.speakRunId)return;this.setState(R.PLAYING);let G=this.pendingPlaybackStartHighlights.splice(0);for(let Y of G)Y()}installPlaybackStartBarrier(Q,G=!1){this.clearPlaybackStartBarrier();let Y=this.provider,J=Y&&"onPlaybackStart"in Y?Y:null;if(!J&&!G)return null;let X=J?.onPlaybackStart,j=()=>{try{this.notifyPlaybackStarted(Q)}finally{X?.()}};if(J)J.onPlaybackStart=j;this.playbackStartDeferredRunId=Q;let Z=()=>{if(J?.onPlaybackStart===j)J.onPlaybackStart=X;if(this.playbackStartDeferredRunId===Q)this.playbackStartDeferredRunId=null,this.pendingPlaybackStartHighlights=[]};return this.playbackStartBarrierCleanup=Z,Z}runWhenPlaybackStarts(Q,G){if(this.playbackStartDeferredRunId===Q){this.pendingPlaybackStartHighlights.push(G);return}G()}async emitTelemetry(Q,G){try{await this.telemetryReporter?.(Q,G)}catch(Y){console.warn("[TTSService] telemetry callback failed:",Y)}}async initialize(Q,G={}){this.currentProvider=Q,this.ttsConfig={...G};let Y=G.providerOptions&&typeof G.providerOptions==="object"?G.providerOptions:{};this.telemetryReporter=typeof Y.__pieTelemetry==="function"?Y.__pieTelemetry:null;try{this.provider=await Q.initialize(G)}catch(J){if(Q.providerId.toLowerCase()==="browser")throw J;if(!this.isBrowserSpeechFallbackAvailable())throw J;if(!await this.switchProviderToBrowser(J,{operation:"tts-initialize"}))throw J}}async updateSettings(Q){if(!this.provider)throw Error("TTSService not initialized. Call initialize() first.");let G=this.provider;if(typeof G.updateSettings==="function"){let Y={...Q,...Q.providerOptions?{providerOptions:{...this.ttsConfig.providerOptions||{},...Q.providerOptions}}:{}};await G.updateSettings(Y),this.ttsConfig={...this.ttsConfig,...Y}}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,G="en-US"){if(!Q||!this.catalogResolver)return!1;return this.catalogResolver.getAlternative(Q,{type:"spoken",language:G,useFallback:!0,form:"content"})?.content!==void 0}getHighlightResolverRuntime(){let Q=null;try{Q=this.highlightTargetResolverProvider?.()??null}catch{Q=null}let G=Q?.context??{},Y=typeof HTMLElement<"u"&&this.currentContentElement instanceof HTMLElement?this.currentContentElement:null;return{context:{...G,scopeElement:G.scopeElement??Y},resolver:Q?.resolver??null}}getNodeElement(Q){if(!Q)return null;return Q.nodeType===Node.ELEMENT_NODE?Q:Q.parentElement}isElementWithinScope(Q,G){if(!G)return!0;return Q===G||G.contains(Q)}isRangeWithinScope(Q,G){let Y=this.getNodeElement(Q.startContainer),J=this.getNodeElement(Q.endContainer);if(!Y||!J)return!1;return this.isElementWithinScope(Y,G)&&this.isElementWithinScope(J,G)}resolveWordHighlightRange(Q){let{context:G,resolver:Y}=this.getHighlightResolverRuntime(),J=G.scopeElement??this.currentContentElement;try{let X=Y?.resolveWordRange?.(Q,G);if(X&&this.isRangeWithinScope(X,J))return{range:X,remapped:!y0(Q,X)}}catch{}return{range:Q,remapped:!1}}resolveSentenceHighlightTargets(Q){let{context:G,resolver:Y}=this.getHighlightResolverRuntime(),J=G.scopeElement??this.currentContentElement;try{let X=Y?.resolveSentenceRanges?.(Q,G);if(!X)return{ranges:Q,elements:[]};let j=[],Z=[];for(let K of X){if(typeof Range<"u"&&K instanceof Range){if(!this.isRangeWithinScope(K,J))return{ranges:Q,elements:[]};j.push(K);continue}if(typeof Element<"u"&&K instanceof Element){if(!this.isElementWithinScope(K,J))return{ranges:Q,elements:[]};Z.push(K);continue}return{ranges:Q,elements:[]}}return{ranges:j,elements:Z}}catch{return{ranges:Q,elements:[]}}}createTextRange(Q,G,Y){if(typeof document>"u")return null;if(typeof document.createRange!=="function")return null;try{let J=document.createRange();if(J.setStart(Q,G),J.setEnd(Q,Y),J.startContainer!==Q||J.endContainer!==Q)return null;return J}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:G,elements:Y}=this.resolveSentenceHighlightTargets(Q);if(Y.length>0&&G.length===0&&this.highlightCoordinator.highlightTTSSentenceElements){this.highlightCoordinator.highlightTTSSentenceElements(Y);return}let J=[...G];for(let X of Y){let j=document.createRange();j.selectNodeContents(X),J.push(j)}this.highlightCoordinator.highlightTTSSentence(J)}getCapabilities(){return this.currentProvider?.getCapabilities()||null}getTextProcessingOptions(Q){let Y=(this.ttsConfig.providerOptions||{}).textNormalization||{},J=Y.boundarySpacingMode,X=J==="none"||J==="alnum"||J==="segmenterPreferred"?J:void 0;return{locale:Q||(typeof Y.locale==="string"?Y.locale:void 0),boundarySpacingMode:X}}getMathSpeechOptions(){let G=(this.ttsConfig.providerOptions||{}).mathSpeech;return z7(G)}buildPositionMap(Q,G,Y){this.normalizedToDOM.clear();let{text:J,map:X}=C7(Q,this.getTextProcessingOptions(Y));if(this.normalizedToDOM=X,!p7.debugEnabled)return;this.debugLog("[TTSService] Text comparison:",{spokenLength:G.length,normalizedDomLength:J.length,match:G===J,spokenPreview:G.substring(0,150),normalizedPreview:J.substring(0,150),differAtIndex:G===J?null:(()=>{for(let j=0;j<Math.min(G.length,J.length);j++)if(G[j]!==J[j])return{index:j,spokenChar:G[j],normalizedChar:J[j],spokenContext:G.substring(Math.max(0,j-20),j+20),normalizedContext:J.substring(Math.max(0,j-20),j+20)};return null})()}),this.debugLog("[TTSService] Position map built:",{entries:this.normalizedToDOM.size,spokenTextLength:G.length,normalizedDomLength:J.length,mapLengthMatchesSpoken:this.normalizedToDOM.size===G.length,firstFewMappings:Array.from(this.normalizedToDOM.entries()).slice(0,10).map(([j,{node:Z,offset:K}])=>({pos:j,offset:K,char:Z.textContent?.[K],expected:G[j]}))})}getStructuralPauseProfile(){let G=(this.ttsConfig.providerOptions||{}).structuralPauses||{},Y=G.units||{},J=(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:J(G.baseMs,280),units:{minor:J(Y.minor,0.65),section:J(Y.section,1),major:J(Y.major,1.35)},minMs:J(G.minMs,120),maxMs:J(G.maxMs,900)}}resolvePauseMsFromUnits(Q){let G=this.getStructuralPauseProfile(),Y=Math.max(0.25,Math.min(4,Number(this.ttsConfig.rate||1))),J=G.baseMs*Math.max(0,Q)/Y;return Math.max(G.minMs,Math.min(G.maxMs,Math.round(J)))}resolveHighlightMode(){let G=(this.ttsConfig.providerOptions||{}).highlightMode;if(G==="word"||G==="sentence")return G;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 J8(Q)}getBoundaryStrength(Q){let G=Number(Q.getAttribute("data-tts-break-ms"));if(Number.isFinite(G)&&G>0)return"major";let Y=Q.tagName.toUpperCase();if(Y.match(/^H[1-6]$/))return"major";let J=(Q.getAttribute("role")||"").toLowerCase();if(J==="heading")return"major";if(J==="listitem"||J==="row"||J==="option"||J==="radio"||Y==="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,G){let Y=Q.parentElement,J=null;while(Y&&Y!==G){if(this.isElementHidden(Y))return null;let j=Number(Y.getAttribute("data-tts-break-ms"));if(Number.isFinite(j)&&j>0)return{anchor:Y,units:j/this.getStructuralPauseProfile().baseMs};let Z=(Y.getAttribute("role")||"").toLowerCase(),K=Y.tagName.toUpperCase();if(K.match(/^H[1-6]$/)||Z==="heading"||Z==="listitem"||K==="LI"){J=Y;break}if(!J){if(typeof window<"u"){let W=window.getComputedStyle(Y).display;if(W==="block"||W==="list-item"||W.startsWith("table")||W==="flex"||W==="grid")J=Y}}Y=Y.parentElement}if(!J)return null;let X=this.getBoundaryStrength(J);return{anchor:J,units:this.getStructuralPauseProfile().units[X]}}createSpeechPlan(Q,G){let Y=this.collectSpeechPlanBoundaries(Q,G);return this.createSpeechPlanSegments(G,Y)}collectSpeechPlanBoundaries(Q,G){let Y=new Map,{map:J}=C7(Q,this.getTextProcessingOptions()),X=this.createNodeStartOffsets(J),j=document.createTreeWalker(Q,NodeFilter.SHOW_TEXT),Z=j.nextNode(),K=null;while(Z){let W=Z,B=W.parentElement;if(B&&!this.isElementHidden(B)&&!B1(W)){let U=this.getBoundaryAnchor(W,Q),V=X.get(W);if(U&&V!==void 0&&U.anchor!==K&&V>0)Y.set(V,Math.max(Y.get(V)||0,U.units)),K=U.anchor}Z=j.nextNode()}return Y}createNodeStartOffsets(Q){let G=new Map;for(let[Y,J]of Q.entries())if(!G.has(J.node))G.set(J.node,Y);return G}createSpeechPlanSegments(Q,G){let Y=Array.from(G.keys()).filter((W)=>W>0&&W<Q.length).sort((W,B)=>W-B),J=[],X=0;for(let W of Y){let B=Q.substring(X,W),U=B.match(/^\s*/)?.[0].length||0,V=B.match(/\s*$/)?.[0].length||0,H=X+U,N=W-V;if(N>H){let O=Q.substring(H,N);J.push({text:O,startOffset:H,pauseMsAfter:this.resolvePauseMsFromUnits(G.get(W)||0)})}X=W}let Z=Q.substring(X).match(/^\s*/)?.[0].length||0,K=X+Z;if(K<Q.length)J.push({text:Q.substring(K).trimEnd(),startOffset:K,pauseMsAfter:0});return J.filter((W)=>W.text.trim().length>0)}segmentSentences(Q){let G=this.ttsConfig.providerOptions?.locale||void 0;return E7(Q,{locale:G})}createSeekSegmentsFromText(Q){return this.segmentSentences(Q).map((G)=>{let Y=G.text.match(/^\s*/)?.[0].length||0;return{text:G.text.trim(),startOffset:G.offset+Y,pauseMsAfter:0}}).filter((G)=>G.text.length>0)}splitSegmentsAtBoundaries(Q,G,Y){if(Q.length===0||G.length===0)return Q;let J=Array.from(new Set(G)).filter((j)=>Number.isFinite(j)&&j>0).sort((j,Z)=>j-Z);if(J.length===0)return Q;let X=[];for(let j of Q){let Z=j.startOffset,K=j.startOffset+j.text.length,W=J.filter((U)=>U>Z&&U<K);if(W.length===0){X.push(j);continue}let B=Z;for(let U of[...W,K]){let V=Y.substring(B,U),H=V.match(/^\s*/)?.[0].length||0,N=V.match(/\s*$/)?.[0].length||0,O=B+H,P=U-N;if(P>O)X.push({text:Y.substring(O,P),startOffset:O,pauseMsAfter:0});B=U}}return X}createSentenceHighlightSegments(Q){let G=this.createSeekSegmentsFromText(Q.contentToSpeak);if(!Q.shouldUsePlan||Q.playbackSegments.length===0)return G;let Y=Q.playbackSegments.map((J)=>J.startOffset).filter((J)=>J>0);return this.splitSegmentsAtBoundaries(G,Y,Q.contentToSpeak)}createSeekSegmentsFromSpeechChunks(Q){let G=0;return Q.map((Y)=>{let J=Y.plainFallback?.speechText||(this.hasExplicitBreakSemantics(Y.speechText)?Y.visibleText:Y.speechText)||Y.visibleText,X=T(J)||Y.visibleText||"",j={text:X,startOffset:G,pauseMsAfter:0};return G+=Math.max(1,X.length+1),j})}getCurrentSeekSegmentIndex(){if(this.seekSegments.length===0)return 0;let Q=0;for(let G=0;G<this.seekSegments.length;G++)if(this.seekSegments[G].startOffset<=this.currentBoundaryOffset)Q=G;else break;return Q}async speakWithPlan(Q,G,Y){if(!this.provider||Q.length===0)return;let J=Y?.highlightMode==="sentence",X=this.provider;if(!J&&typeof X.speakSegments==="function"){this.currentBoundaryOffset=0;let j=this.provider.onWordBoundary;this.provider.onWordBoundary=(Z,K,W)=>{if(j?.(Z,K,W),Number.isFinite(K))this.currentBoundaryOffset=K,this.currentSeekSegmentIndex=this.getCurrentSeekSegmentIndex()};try{await X.speakSegments(Q)}finally{if(G===this.speakRunId&&this.provider===X)this.provider.onWordBoundary=j}return}this.configureWordBoundaryHighlighting({highlightMode:Y?.highlightMode||"word",wordBoundaryOffset:this.activeWordBoundaryOffset});for(let j of Q){if(G!==this.speakRunId)return;let Z=this.seekSegments.findIndex((W)=>W.startOffset===j.startOffset);if(Z>=0)this.currentSeekSegmentIndex=Z;if(this.currentBoundaryOffset=j.startOffset,J)this.runWhenPlaybackStarts(G,()=>{this.highlightSentenceSegment(j.startOffset,j.text)});await this.provider.speak(j.text);let K=j.pauseMsAfter??0;if(K>0)await new Promise((W)=>setTimeout(W,K))}}highlightSentenceSegment(Q,G){if(!this.highlightCoordinator||typeof document>"u")return;let Y=G.trimEnd().length;if(Y<=0)return;let J=this.normalizedToDOM.get(Q),X=this.normalizedToDOM.get(Q+Y-1);if(!J||!X)return;let j=document.createRange();j.setStart(J.node,J.offset),j.setEnd(X.node,X.offset+1),this.paintTTSSentenceRanges([j]),this.activeSentenceStartOffset=Q}getSegmentIndexForOffset(Q,G){if(Q.length===0)return-1;let Y=-1;for(let J=0;J<Q.length;J++)if(Q[J].startOffset<=G)Y=J;else break;return Y}highlightSentenceForOffset(Q){let G=this.sentenceHighlightSegments;if(!this.highlightCoordinator||G.length===0)return;let Y=this.getSegmentIndexForOffset(G,Q);if(Y<0)return;let J=G[Y];if(!J)return;if(this.activeSentenceStartOffset===J.startOffset)return;this.highlightSentenceSegment(J.startOffset,J.text)}findHighlightRange(Q,G){let Y=this.normalizedToDOM.get(Q);if(!Y)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:K}])=>({pos:j,offset:Z,char:K.textContent?.[Z]}))}),null;let J=Q+G-1,X=this.normalizedToDOM.get(J);if(!X)return console.warn(`[TTSService] No mapping found for end position ${J}`,{startChar:Q,length:G,totalMappings:this.normalizedToDOM.size}),null;if(Y.node!==X.node)return console.warn("[TTSService] Word spans multiple nodes, highlighting in first node only"),{node:Y.node,start:Y.offset,end:(Y.node.textContent||"").length};return{node:Y.node,start:Y.offset,end:X.offset+1}}async speak(Q,G){if(!this.provider)throw Error("TTS service not initialized");let Y=++this.speakRunId;this.clearPlaybackStartBarrier();let J=null;try{if(await this.applyLanguageSettings(G),Y!==this.speakRunId)return;let X=await this.resolveSpeechContent(Q,G);if(Y!==this.speakRunId)return;let{contentToSpeak:j,speechText:Z,highlightText:K,normalizedText:W,usedCatalogSpoken:B,speechSource:U,speechMatchesVisibleText:V,speechChunks:H}=X;this.logResolvedSpeechContent({contentToSpeak:j,speechSource:U,catalogId:G?.catalogId}),this.initializeSpeakTracking(K,G);let N=G?.highlightModeOverride||(V?this.resolveHighlightMode():"sentence");this.activeHighlightMode=N,this.activeWordBoundaryOffset=G?.wordBoundaryOffset||0;let O=this.hasExplicitBreakSemantics(j),P=!!this.currentContentElement&&!B&&!O&&V;if(this.playbackChunks=H?.length?H:[],this.seekSegments=this.playbackChunks.length?this.createSeekSegmentsFromSpeechChunks(this.playbackChunks):O||!V?[]:P&&this.currentContentElement?this.createSpeechPlan(this.currentContentElement,W):this.createSeekSegmentsFromText(K),this.sentenceHighlightSegments=O?[]:this.createSentenceHighlightSegments({contentToSpeak:K,shouldUsePlan:P,playbackSegments:this.seekSegments}),this.setState(R.LOADING),J=this.installPlaybackStartBarrier(Y,!!this.playbackChunks[0]?.audio),this.prepareHighlightsForSpeak({contentToSpeak:K,options:G,highlightMode:N,shouldUsePlan:P,runId:Y}),V)this.configureWordBoundaryHighlighting({highlightMode:N,wordBoundaryOffset:G?.wordBoundaryOffset||0});else this.clearWordBoundaryHighlighting();if(!J)this.setState(R.PLAYING);if(this.activePlaybackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1)),await this.executeSpeakPlayback({shouldUsePlan:P,runId:Y,highlightMode:N,contentToSpeak:Z,speechChunks:H}),Y!==this.speakRunId)return;this.setState(R.IDLE),this.clearHighlightsAndTracking()}catch(X){let j=X;if(console.error("TTS error:",j),this.lastError=j instanceof Error?j.message:String(j),Y!==this.speakRunId)return;throw this.setState(R.ERROR),this.clearHighlightsAndTracking(),j}finally{this.clearPlaybackStartBarrier(J)}}async switchProviderToBrowser(Q,G){if(!this.currentProvider)return!1;let Y=new b7,J=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=G?.operation||"tts-initialize",Z=G?.contentToSpeak??"",K=Z.replace(/\s+/g," ").trim().slice(0,120),W=Z.length>0?{textLength:Z.length,textPreview:K.length<Z.length?`${K}…`:K}:{};try{return this.provider?.stop(),this.currentProvider.destroy(),this.currentProvider=Y,this.provider=await Y.initialize(X),this.ttsConfig=X,await this.emitTelemetry("pie-tool-runtime-fallback",{toolId:"textToSpeech",operation:j,fromProvider:J,toProvider:Y.providerId,reason:Q instanceof Error?Q.message:String(Q),...W}),console.warn("[TTSService] TTS provider initialization failed; switched to browser fallback",{fromProvider:J,reason:Q,...W}),!0}catch(B){return await this.emitTelemetry("pie-tool-runtime-fallback-error",{toolId:"textToSpeech",operation:j,fromProvider:J,toProvider:"browser",errorType:"TTSRuntimeFallbackError",message:B instanceof Error?B.message:String(B)}),console.error("[TTSService] Failed to switch to browser fallback provider",B),!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 G=this.ttsConfig.providerOptions||{},Y=G.textNormalization||{},J=G.segmenter||{},X={...G,locale:Q.language,textNormalization:{...Y,locale:Q.language},segmenter:{...J,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,G){let Y=T(Q);if(G?.ignoreCatalogs)return{contentToSpeak:Y,speechText:Y,visibleText:Y,highlightText:Y,usedCatalogSpoken:!1,speechSource:"dom-or-input",normalizedText:Y,containsMathMarkup:!1,speechMatchesVisibleText:!0};if(G?.catalogId&&this.catalogResolver){let j=this.catalogResolver.getAlternative(G.catalogId,{type:"spoken",language:G.language||"en-US",useFallback:!0,context:G.catalogContext,form:"content"}),Z=j?.content;if(j&&Z!==void 0){let K=G?.contentElement?O7(G.contentElement,this.getTextProcessingOptions(G.language)).visibleText||Y:Y,W=T(Z);return this.debugLog(`[TTSService] Using catalog content for "${G.catalogId}" (${j.language})`),{contentToSpeak:Z,speechText:Z,visibleText:K,highlightText:K,usedCatalogSpoken:!0,speechSource:"catalog-spoken",normalizedText:K,containsMathMarkup:!1,speechMatchesVisibleText:W===K}}this.debugLog(`[TTSService] No catalog found for "${G.catalogId}", falling back to generated TTS`)}let J=G?.contentElement?this.resolveCatalogComposedSpeechContent(G.contentElement,Y,G):null;if(J)return J;return{...G?.contentElement?await this.resolveGeneratedSpeechContent(G.contentElement,Y,G.language):{contentToSpeak:Y,speechText:Y,visibleText:Y,highlightText:Y,normalizedText:Y,containsMathMarkup:!1,speechMatchesVisibleText:!0},usedCatalogSpoken:!1,speechSource:"dom-or-input"}}resolveCatalogComposedSpeechContent(Q,G,Y){if(!this.catalogResolver)return null;let J=this.collectCatalogSpeechChunks(Q,Y);if(!J.some((Z)=>Z.sourceElement))return null;let X=T(J.map((Z)=>Z.speechText).join(" ")),j=O7(Q,this.getTextProcessingOptions(Y.language)).visibleText||G;return{contentToSpeak:X,speechText:X,visibleText:j,highlightText:j,usedCatalogSpoken:!0,speechSource:"catalog-spoken",normalizedText:j,containsMathMarkup:!1,speechMatchesVisibleText:J.every((Z)=>Z.speechMatchesVisibleText),speechChunks:J}}collectCatalogSpeechChunks(Q,G){let Y=[],J="",X=()=>{let B=T(J);if(J="",!B)return;Y.push({speechText:B,visibleText:B,sourceElement:null,speechMatchesVisibleText:!0})},j=(B)=>{let U=B.getAttribute("data-catalog-idref");if(!U)return null;let V={type:"spoken",language:G.language||"en-US",useFallback:!0,context:G.catalogContext},H=this.catalogResolver.getAlternative(U,{...V,form:"payload"}),N=H?.payload?P6({payload:H.payload})??void 0:void 0,P=this.catalogResolver.getAlternative(U,{...V,form:"content"})?.content;if(N===void 0&&P===void 0)return null;return{script:P,audio:N}},Z=(B,U)=>{let V=K(B);if(V.length!==1)return null;let H=V[0],N=O7(H,this.getTextProcessingOptions(G.language)).visibleText||T(H.textContent||""),O=(P)=>T(P).replace(/\s+/g,"");return O(N)===O(U)?H:null},K=(B)=>{let U=Array.from(B.querySelectorAll("math"));if(B.localName?.toLowerCase()==="math")return[B,...U];return U},W=(B)=>{if(V7(B,Q))return;if(B.nodeType===Node.TEXT_NODE){J+=` ${B.textContent||""}`;return}if(B.nodeType!==Node.ELEMENT_NODE)return;let U=B,V=j(U);if(V){X();let H=O7(U,this.getTextProcessingOptions(G.language)),N=H.visibleText||T(U.textContent||""),O=M1(U,Q),P=V.script!==void 0?(()=>{let $=V.script,F=V1({speechText:$,visibleText:N}),L=Z(U,N),C=L?S7({mathElement:L,speechText:$}):void 0,v=C?void 0:K(U).map((I)=>({element:I,alignment:S7({mathElement:I,speechText:$})}));return{speechText:$,visibleText:N,sourceElement:U,regionElement:O,speechMatchesVisibleText:T($)===N,playbackMode:F.playbackMode,alignment:F,mathAlignment:C,mathAlignments:v,visibleMap:H.map}})():null;if(V.audio){Y.push(P?{...P,audio:V.audio,plainFallback:P}:{speechText:N,visibleText:N,sourceElement:U,regionElement:O,speechMatchesVisibleText:!1,visibleMap:H.map,audio:V.audio});return}if(P)Y.push(P);return}for(let H of Array.from(U.childNodes))W(H)};return W(Q),X(),Y}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,G,Y){let J=this.resolveGeneratedPlaybackFormat(),{plan:X,containsMathMarkup:j,visibleText:Z}=await z8({contentRoot:Q,language:Y,mathSpeech:this.getMathSpeechOptions(),textProcessingOptions:this.getTextProcessingOptions(Y),produceSsml:J==="ssml",resolveMathSpeech:this.generatedMathSpeechResolver}),K=Z||G;if(!j)return{contentToSpeak:K,speechText:K,visibleText:K,highlightText:K,normalizedText:K,containsMathMarkup:!1,speechMatchesVisibleText:!0};let W=P8(X,{format:J}),B=X.plainSpeechText;return{contentToSpeak:B,speechText:B,visibleText:K,highlightText:K,normalizedText:K,containsMathMarkup:!0,speechMatchesVisibleText:B===K,speechChunks:W}}logResolvedSpeechContent(Q){let G=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:G})}initializeSpeakTracking(Q,G){this.currentText=Q,this.currentContentElement=G?.contentElement||null,this.lastError=null,this.currentBoundaryOffset=0,this.playbackChunks=[],this.currentSeekSegmentIndex=0,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 G=this.sentenceHighlightSegments[0]||this.seekSegments[0];this.runWhenPlaybackStarts(Q.runId,()=>{if(G)this.highlightSentenceSegment(G.startOffset,G.text),this.debugLog("[TTSService] Applied initial sentence highlighting");else try{let Y=document.createRange();Y.selectNodeContents(this.currentContentElement),this.paintTTSSentenceRanges([Y])}catch{}})}configureWordBoundaryHighlighting(Q){if(!this.provider||Q.highlightMode!=="word"||!this.highlightCoordinator||!this.currentContentElement)return;this.provider.onWordBoundary=(G,Y,J)=>{let X=J||G.length,j=Y+this.currentBoundaryOffset+Q.wordBoundaryOffset;this.highlightSentenceForOffset(j);let Z=this.findHighlightRange(j,X);if(Z&&this.highlightCoordinator){let K=Z.node.textContent?.substring(Z.start,Z.end)||"";this.debugLog(`[TTSService] Highlighting "${K}" (word: "${G}") at position ${j}`);let W=this.createTextRange(Z.node,Z.start,Z.end);if(W)this.paintTTSWordRange(this.resolveWordHighlightRange(W).range);else this.highlightCoordinator.highlightTTSWord(Z.node,Z.start,Z.end)}else console.warn(`[TTSService] Could not find highlight range for position ${j}, length ${X}`)}}clearWordBoundaryHighlighting(){if(this.provider)this.provider.onWordBoundary=void 0}highlightCatalogRegion(Q){let G=Q.regionElement||Q.sourceElement;if(!G&&!Q.regionRange||!this.highlightCoordinator)return;try{if(this.lastRenderedRegionTarget=null,Q.regionRange){this.highlightCoordinator.clearHighlights?.(u.TTS_WORD),this.paintTTSSentenceRanges([Q.regionRange]);return}if(!G)return;let Y=document.createRange();Y.selectNodeContents(G),this.highlightCoordinator.clearHighlights?.(u.TTS_WORD),this.paintTTSSentenceRanges([Y])}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&&Z9(this.lastRenderedRegionTarget,Q))return;try{let G=document.createRange();if(Q.type==="element")G.selectNodeContents(Q.element);else if(Q.type==="range"){this.paintTTSSentenceRanges([Q.range]),this.lastRenderedRegionTarget=Q;return}else G.setStart(Q.node,Q.startOffset),G.setEnd(Q.node,Q.endOffset);this.paintTTSSentenceRanges([G]),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 G=document.createRange();G.selectNodeContents(Q.element);let Y=this.resolveWordHighlightRange(G);if(Y.remapped){this.paintTTSWordRange(Y.range);return}let J=Q.element.childNodes.length===1?Q.element.firstChild:null;if(Q.quality==="semantic-token"&&J?.nodeType===Node.TEXT_NODE){this.highlightCoordinator.highlightTTSWord(J,0,J.textContent?.length||0);return}this.highlightCoordinator.highlightTTSWordElement?.(Q.element)}renderHighlightDecision(Q){this.highlightRenderableRegionTarget(Q.regionTarget),this.highlightRenderableActiveTarget(Q.activeTarget)}async speakCatalogChunk(Q,G){try{await this.speakCatalogChunkOnce(Q,G)}catch(Y){if(Q.plainFallback&&G===this.speakRunId){if(this.debugLog("[TTSService] SSML chunk speak failed; retrying plain text",{message:Y instanceof Error?Y.message:String(Y)}),this.playbackStartDeferredRunId===G&&this.provider&&!("onPlaybackStart"in this.provider))this.pendingPlaybackStartHighlights=[],this.clearPlaybackStartBarrier(),this.setState(R.PLAYING);await this.speakCatalogChunkOnce(Q.plainFallback,G);return}throw Y}}async playRecordedAudio(Q,G){if(typeof document>"u")throw Error("[tts] no document available to play recorded audio");let Y=Q.sources[0],J=document.createElement("audio");J.preload="auto",J.src=z6(Y.src,Q.fragment),J.playbackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate||1)),await new Promise((X,j)=>{let Z,K=!1,W=!1,B=()=>{if(W||K)return;K=!0,G?.()},U=()=>{if(J.removeEventListener("ended",V),J.removeEventListener("error",H),J.removeEventListener("playing",B),Z?.(),this.activeRecordedAudio?.element===J)this.activeRecordedAudio=null},V=()=>{if(W)return;W=!0,U(),X()},H=()=>{if(W)return;W=!0,U(),j(Error(`[tts] recorded audio failed to play: ${Y.src}`))};this.activeRecordedAudio={element:J,cancel:()=>{if(W)return;W=!0,U(),J.pause(),X()}},J.addEventListener("ended",V),J.addEventListener("error",H),J.addEventListener("playing",B),Z=O6(J,Q.fragment,V),Promise.resolve(J.play()).then(B).catch(H)}).finally(()=>{if(this.activeRecordedAudio?.element===J)this.activeRecordedAudio=null;J.pause(),J.removeAttribute("src")})}cancelRecordedAudio(){let Q=this.activeRecordedAudio;if(!Q)return;this.activeRecordedAudio=null,Q.cancel()}async speakCatalogChunkOnce(Q,G){if(!this.provider)return;if(this.lastRenderedRegionTarget=null,Q.audio){this.runWhenPlaybackStarts(G,()=>{this.highlightCatalogRegion(Q)}),await this.playRecordedAudio(Q.audio,()=>{this.notifyPlaybackStarted(G)});return}let Y=Q.regionElement||Q.sourceElement||this.currentContentElement,J=Y?C0({contentRoot:Y,chunks:[Q]})[0]:null,X=this.ttsConfig.mathTokenHighlighting!==!1,j=J?b0({chunks:[J],mathTokenHighlighting:X}):null;if(this.runWhenPlaybackStarts(G,()=>{if(j&&J&&Q.mathAlignment)this.renderHighlightDecision(j.resolveInitial(J.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,V=U.onWordBoundary;U.onWordBoundary=void 0;try{await U.speak(Q.speechText)}finally{if(this.provider===U&&G===this.speakRunId&&U.onWordBoundary===void 0)U.onWordBoundary=V}return}let K=this.provider,W=K.onWordBoundary,B=(U,V,H)=>{if(G!==this.speakRunId)return;if(j&&J){let N=J.offsetSpace==="unsupported"?"unknown":J.offsetSpace;this.renderHighlightDecision(j.resolveBoundary({chunkId:J.id,word:U,position:V,length:H,providerOffsetSpace:N}));return}};K.onWordBoundary=B;try{await K.speak(Q.speechText)}finally{if(this.provider===K&&G===this.speakRunId&&K.onWordBoundary===B)K.onWordBoundary=W}}async executeSpeakPlayback(Q){if(Q.speechChunks?.length&&this.provider){for(let G=0;G<Q.speechChunks.length;G++){if(Q.runId!==this.speakRunId)return;this.currentSeekSegmentIndex=G;let Y=this.seekSegments[G];if(Y)this.currentBoundaryOffset=Y.startOffset;let J=Q.speechChunks[G];await this.speakCatalogChunk(J,Q.runId)}return}if(Q.shouldUsePlan&&this.currentContentElement){let G=this.seekSegments;if(G.length>0)await this.speakWithPlan(G,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.currentSeekSegmentIndex=0,this.activeSentenceStartOffset=null}async speakRange(Q,G){if(!this.provider)throw Error("TTS service not initialized");if(B1(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 J=G?.contentRoot||null;if(!J){let U=Q.commonAncestorContainer;J=U.nodeType===Node.ELEMENT_NODE?U:U.parentElement}if(!J)return;let X=X8(Q,J),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=document.createRange();Z.selectNodeContents(J),Z.setEnd(Q.startContainer,Q.startOffset);let K=X8(Z,J).text,W=T(K),B=W.length+(/\s$/.test(K)&&W?1:0);this.debugLog("[TTSService] speakRange offset calculation:",{selectedText:j,textBeforeRange:K.substring(0,100),offset:B,rootTag:J.tagName}),await this.speak(j,{contentElement:J,ignoreCatalogs:!0,wordBoundaryOffset:B})}pause(){if(!this.provider)return;if(this.state===R.PLAYING)this.activeRecordedAudio?.element.pause(),this.provider.pause(),this.setState(R.PAUSED)}resume(){if(!this.provider)return;if(this.state===R.PAUSED){let Q=this.activeRecordedAudio?.element;if(Q)Promise.resolve(Q.play()).catch(()=>{});this.provider.resume(),this.setState(R.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 G=Math.max(0,Math.min(this.seekSegments.length-1,Q)),Y=this.playbackChunks.length?this.playbackChunks.slice(G):null;this.speakRunId+=1,this.clearPlaybackStartBarrier(),this.cancelRecordedAudio(),this.provider.onWordBoundary=void 0,this.provider.stop(),this.currentSeekSegmentIndex=G;let J=++this.speakRunId,X=this.seekSegments.slice(G);this.highlightCoordinator?.clearTTS(),this.activeSentenceStartOffset=null,this.setState(R.LOADING);let j=this.installPlaybackStartBarrier(J,!!Y?.[0]?.audio);if(!j)this.setState(R.PLAYING);this.activePlaybackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1));try{if(this.configureWordBoundaryHighlighting({highlightMode:this.activeHighlightMode,wordBoundaryOffset:this.activeWordBoundaryOffset}),Y)for(let Z=0;Z<Y.length;Z++){if(J!==this.speakRunId)return;let K=G+Z;this.currentSeekSegmentIndex=K;let W=this.seekSegments[K];if(W)this.currentBoundaryOffset=W.startOffset;await this.speakCatalogChunk(Y[Z],J)}else await this.speakWithPlan(X,J,{highlightMode:this.activeHighlightMode});if(J!==this.speakRunId)return;this.setState(R.IDLE),this.clearHighlightsAndTracking()}catch(Z){if(J!==this.speakRunId)return;throw this.lastError=Z instanceof Error?Z.message:String(Z),this.setState(R.ERROR),this.clearHighlightsAndTracking(),Z}finally{this.clearPlaybackStartBarrier(j)}}async setPlaybackRate(Q){if(!this.provider)throw Error("TTSService not initialized. Call initialize() first.");let G=this.normalizePlaybackRate(Q),Y=this.pendingPlaybackRateRequest;if(Y?.rate===G){await Y.promise;return}let J=++this.playbackRateRequestId,X=this.playbackRateWriteQueue.then(async()=>{let K=this.speakRunId;if(J!==this.playbackRateRequestId)return{didUpdate:!1,playbackRunId:K};let W=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1));if(G===W)return{didUpdate:!1,playbackRunId:K};return await this.updateSettings({rate:G}),{didUpdate:!0,playbackRunId:K}});this.playbackRateWriteQueue=X.then(()=>{return},()=>{return});let j=X.then(async(K)=>{if(J!==this.playbackRateRequestId||K.playbackRunId!==this.speakRunId)return;let W=this.activePlaybackRate!==null&&this.activePlaybackRate!==G;if(!K.didUpdate&&!W)return;if(this.state!==R.PLAYING&&this.state!==R.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:G,promise:Z},await Z}async seekBy(Q){if(!this.provider||!this.currentText)return;if(this.state!==R.PLAYING&&this.state!==R.PAUSED)return;if(this.hasExplicitBreakSemantics(this.currentText))return;if(this.seekSegments.length===0)return;let G=Number.isFinite(Q)?Math.trunc(Q):0;if(G===0)return;let Y=this.getCurrentSeekSegmentIndex(),J=Math.max(0,Math.min(this.seekSegments.length-1,Y+G));if(J===Y)return;await this.restartFromSeekIndex(J)}async seekForward(Q=1){let G=Number.isFinite(Q)?Math.max(1,Math.trunc(Q)):1;await this.seekBy(G)}async seekBackward(Q=1){let G=Number.isFinite(Q)?Math.max(1,Math.trunc(Q)):1;await this.seekBy(-G)}stop(){if(!this.provider)return;if(this.speakRunId+=1,this.clearPlaybackStartBarrier(),this.cancelRecordedAudio(),this.provider.onWordBoundary=void 0,this.provider.stop(),this.setState(R.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.currentSeekSegmentIndex=0,this.activeSentenceStartOffset=null,this.activePlaybackRate=null}requestControlHandoff(){if(typeof window>"u")return;let Q={source:"host"};window.dispatchEvent(new CustomEvent(S0,{detail:Q}))}isPlaying(){return this.state===R.PLAYING}isPaused(){return this.state===R.PAUSED}getState(){return this.state}getCurrentText(){return this.currentText}getLastError(){return this.lastError}onStateChange(Q,G){if(!this.listeners.has(Q))this.listeners.set(Q,new Set);this.listeners.get(Q).add(G)}offStateChange(Q,G){let Y=this.listeners.get(Q);if(Y){if(Y.delete(G),Y.size===0)this.listeners.delete(Q)}}setState(Q){if(this.state===Q)return;let G=this.state;this.state=Q;for(let Y of this.listeners.values())for(let J of Y)J(Q);if(this.emitTelemetry("pie-tool-playback-state-changed",{toolId:"textToSpeech",providerId:"tts",previousState:G,state:Q}),Q===R.PLAYING){let Y=G===R.PAUSED?"pie-tool-playback-resume":"pie-tool-playback-start";this.emitTelemetry(Y,{toolId:"textToSpeech",providerId:"tts",previousState:G,state:Q});return}if(Q===R.PAUSED){this.emitTelemetry("pie-tool-playback-pause",{toolId:"textToSpeech",providerId:"tts",previousState:G,state:Q});return}if(Q===R.ERROR){this.emitTelemetry("pie-tool-playback-error",{toolId:"textToSpeech",providerId:"tts",previousState:G,state:Q,message:this.lastError||void 0});return}if(Q===R.IDLE&&(G===R.PLAYING||G===R.PAUSED||G===R.LOADING))this.emitTelemetry("pie-tool-playback-stop",{toolId:"textToSpeech",providerId:"tts",previousState:G,state:Q})}}var j9=new Set(["reserved-row","expanding-row","floating-overlay","left-aligned"]),x0=(Q)=>Q&&typeof Q==="object"?Q:{},K9=(Q)=>Q==="polly"||Q==="google"||Q==="server",l=(Q,G)=>Q===void 0?G:Q,q9=(Q,G="left-aligned")=>typeof Q==="string"&&j9.has(Q)?Q:G,ZG=Object.freeze([0.8,1.25]),jG=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 KG=Object.freeze([0.8,1,1.25]);var W9=(Q)=>{let G={...Q,layoutMode:q9(Q.layoutMode)},Y=Q.backend||"browser";if(!K9(Y))return G;let J={...G,apiEndpoint:l(G.apiEndpoint,"/api/tts"),transportMode:l(G.transportMode,"pie"),endpointValidationMode:l(G.endpointValidationMode,"voices"),validateEndpoint:l(G.validateEndpoint,!0),includeAuthOnAssetFetch:l(G.includeAuthOnAssetFetch,!1),rate:l(G.rate,1),language:l(G.language,"en-US")};if(Y==="polly")return{...J,defaultVoice:l(J.defaultVoice,"Joanna"),engine:l(J.engine,"neural"),format:l(J.format,"mp3"),speechMarksMode:l(J.speechMarksMode,"word+sentence")};if(Y==="google")return{...J,defaultVoice:l(J.defaultVoice,"en-US-Wavenet-A")};return J},f0=(Q)=>{let G=x0(Q),Y=x0(G.settings);return W9({...G,...Y})},L8=(Q)=>Q.backend||"browser",U9=(Q,G)=>{if(G==="polly"||G==="google")return G;if(G==="server")return Q.serverProvider||Q.provider;return Q.serverProvider||Q.provider},B9=(Q,G)=>Q.transportMode||(G==="custom"?"custom":"pie"),k0=(Q)=>{let G=L8(Q),Y=U9(Q,G),J=B9(Q,Y),X=z7(Q.mathSpeech);return{voice:Q.defaultVoice,rate:Q.rate,pitch:Q.pitch,providerOptions:{...Q.language?{locale:Q.language}:{},...G==="polly"&&Q.engine?{engine:Q.engine}:{},...G==="polly"&&typeof Q.sampleRate==="number"?{sampleRate:Q.sampleRate}:{},...G==="polly"&&Q.format?{format:Q.format}:{},...G==="polly"?{speechMarkTypes:Q.speechMarksMode==="word+sentence"?["word","sentence"]:["word"]}:{},...J==="custom"&&typeof Q.cache==="boolean"?{cache:Q.cache}:{},...J==="custom"&&Q.speedRate?{speedRate:Q.speedRate}:{},...J==="custom"&&Q.lang_id?{lang_id:Q.lang_id}:{},...X?{mathSpeech:X}:{}},apiEndpoint:Q.apiEndpoint,provider:Y,language:Q.language,transportMode:J,endpointMode:Q.endpointMode,endpointValidationMode:Q.endpointValidationMode,includeAuthOnAssetFetch:Q.includeAuthOnAssetFetch,validateEndpoint:Q.validateEndpoint,...typeof Q.mathTokenHighlighting==="boolean"?{mathTokenHighlighting:Q.mathTokenHighlighting}:{}}};class O1{providers=new Map;configs=new Map;initialized=new Map;initializationPromises=new Map;async emitTelemetry(Q,G,Y){try{await Q.onTelemetry?.(G,Y)}catch(J){console.warn("[ToolProviderRegistry] Telemetry callback failed:",J)}}register(Q,G){if(this.providers.has(Q)){console.warn(`[ToolProviderRegistry] Provider "${Q}" already registered, skipping`);return}if(this.providers.set(Q,G.provider),this.configs.set(Q,G),this.initialized.set(Q,!1),console.log(`[ToolProviderRegistry] Registered provider "${Q}" (${G.provider.providerName})`),G.lazy===!1)this.initialize(Q).catch((Y)=>{console.error(`[ToolProviderRegistry] Failed to initialize provider "${Q}":`,Y)})}async initialize(Q){if(this.initialized.get(Q))return;let G=this.initializationPromises.get(Q);if(G)return G;let Y=this._doInitialize(Q);this.initializationPromises.set(Q,Y);try{await Y}finally{this.initializationPromises.delete(Q)}}async _doInitialize(Q){let G=this.providers.get(Q),Y=this.configs.get(Q);if(!G||!Y)throw Error(`[ToolProviderRegistry] Provider "${Q}" not registered`);let J={...Y.config},X=(Z)=>{if(!Z||typeof Z!=="object")return"unknown";let K=Z;return(typeof K.backend==="string"?K.backend:typeof K.provider==="string"?K.provider:typeof K.serverProvider==="string"?K.serverProvider:typeof K.providerId==="string"?K.providerId:"")||"unknown"},j=Date.now();if(await this.emitTelemetry(Y,"pie-tool-init-start",{toolId:Q,providerId:Q,backend:X(J),operation:"provider-initialize"}),G.requiresAuth&&Y.authFetcher){let Z=Date.now();await this.emitTelemetry(Y,"pie-tool-backend-call-start",{toolId:Q,providerId:Q,backend:X(J),operation:"auth-fetch"}),console.log(`[ToolProviderRegistry] Fetching auth for "${Q}"...`);try{let K=await Y.authFetcher();J={...J,...K},await this.emitTelemetry(Y,"pie-tool-backend-call-success",{toolId:Q,providerId:Q,backend:X(J),operation:"auth-fetch",duration:Date.now()-Z})}catch(K){throw await this.emitTelemetry(Y,"pie-tool-backend-call-error",{toolId:Q,providerId:Q,backend:X(J),operation:"auth-fetch",duration:Date.now()-Z,errorType:"ProviderAuthFetchError",message:K instanceof Error?K.message:String(K)}),console.error(`[ToolProviderRegistry] Auth fetch failed for "${Q}":`,K),Error(`Failed to fetch auth credentials for provider "${Q}"`)}}try{await G.initialize(J),this.initialized.set(Q,!0),await this.emitTelemetry(Y,"pie-tool-init-success",{toolId:Q,providerId:Q,backend:X(J),operation:"provider-initialize",duration:Date.now()-j}),console.log(`[ToolProviderRegistry] Provider "${Q}" initialized`)}catch(Z){throw await this.emitTelemetry(Y,"pie-tool-init-error",{toolId:Q,providerId:Q,backend:X(J),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,G=!0){console.log("[ToolProviderRegistry] getProvider called",{providerId:Q,autoInitialize:G,isRegistered:this.providers.has(Q),isInitialized:this.initialized.get(Q),allProviderIds:Array.from(this.providers.keys())});let Y=this.providers.get(Q);if(!Y)throw console.error("[ToolProviderRegistry] Provider not found:",{requestedId:Q,availableProviders:Array.from(this.providers.keys())}),Error(`[ToolProviderRegistry] Provider "${Q}" not registered`);if(G&&!this.initialized.get(Q))console.log("[ToolProviderRegistry] Auto-initializing provider:",Q),await this.initialize(Q);return console.log("[ToolProviderRegistry] Returning provider:",{providerId:Q,providerName:Y.providerName,isReady:Y.isReady()}),Y}getProvidersByCategory(Q){return Array.from(this.providers.entries()).filter(([G,Y])=>Y.category===Q).map(([G])=>G)}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 G=this.providers.get(Q);if(G){let Y=this.initializationPromises.get(Q);if(Y)try{await Y}catch{}G.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((G)=>this.unregister(G))),console.log("[ToolProviderRegistry] Registry destroyed")}}class $8{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,G){return this.findTarget(Q,G)!==null}request(Q){let G=this.findTarget(Q.toolId,Q.level);if(!G)return!1;try{G.open(Q.toolId,Q.params)}catch(Y){return console.error(`[ToolRequestRegistry] Target failed to open "${Q.toolId}":`,Y),!1}return!0}onTargetsChange(Q){return this.changeListeners.add(Q),()=>{this.changeListeners.delete(Q)}}findTarget(Q,G){let Y=this.findTargetAtLevel(Q,G??"section");if(Y||G!==void 0)return Y;for(let J of this.targets){if(J.level==="section")continue;if(this.hostsTool(J,Q))return J}return null}findTargetAtLevel(Q,G){for(let Y of this.targets){if(Y.level!==G)continue;if(this.hostsTool(Y,Q))return Y}return null}hostsTool(Q,G){try{return Q.hostsTool(G)===!0}catch(Y){return console.warn(`[ToolRequestRegistry] Target at level "${Q.level}" failed the host check for "${G}":`,Y),!1}}notifyChange(){for(let Q of this.changeListeners)try{Q()}catch(G){console.warn("[ToolRequestRegistry] Target change listener threw:",G)}}}var D9=(Q)=>`No assessment is bound, so no policy source could grant "${Q}"`;function w8(Q,G,Y,J){return{featureId:Q,granted:!1,action:"block",rule:G,precedence:0,sourceType:"host",reason:G==="host-blocked"?"Listed in tools.policy.blocked":`Not listed in tools.policy.allowed (${Y.join(", ")})`,required:!1,assessmentBound:J.assessmentBound}}function I0(Q,G,Y){let J=G.decisions[0],X=Array.from(G.perToolFlags.values())[0],j=J?.action==="enable",Z=J?.reason??`Feature "${Q}" not configured`;return{featureId:Q,granted:j,action:J?.action??"skip",rule:J?.rule??"pnp-support",precedence:J?.precedence??6,sourceType:J?.sourceType??"system",reason:Y.assessmentBound||j?Z:D9(Q),required:Boolean(X?.required),parameters:X?.settings,assessmentBound:Y.assessmentBound}}class z1{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,G){let Y={id:G.id,name:G.name??G.id};switch(Q){case"organization":this.provenance.sources.organization={...Y,pnpDefaults:G.config};break;case"assessment":this.provenance.sources.assessment={...Y,settings:G.config};break;case"section":this.provenance.sources.section={...Y,settings:G.config};break;case"item":this.provenance.sources.item={...Y,settings:G.config};break;case"student":this.provenance.sources.student={id:G.id,pnpProfile:G.config};break;case"host":this.provenance.sources.host={id:G.id,config:G.config};break}return this}addDecision(Q){let G={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(G);let Y=this.provenance.features.get(Q.featureId);if(!Y)Y={featureId:Q.featureId,finalState:"not-configured",allDecisions:[],explanation:""},this.provenance.features.set(Q.featureId,Y);if(Y.allDecisions.push(G),Q.action==="advisory"){if(Y.finalState==="not-configured")Y.finalState="advisory-only"}else if(Q.action!=="skip"){if(!Y.winningDecision||G.precedence<Y.winningDecision.precedence)Y.winningDecision=G,Y.finalState=G.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 G of Q){let Y=this.provenance.features.get(G);if(!Y){Y={featureId:G,finalState:"enabled",allDecisions:[],explanation:""},this.provenance.features.set(G,Y);continue}Y.finalState="enabled"}for(let G of this.provenance.features.values()){if(Q.has(G.featureId))continue;let Y=G.allDecisions.some((X)=>X.action!=="skip"&&X.action!=="advisory"),J=G.allDecisions.some((X)=>X.action==="advisory");if(Y)G.finalState="blocked";else if(J)G.finalState="advisory-only";else G.finalState="not-configured"}return this}build(){for(let Q of this.provenance.features.values())Q.explanation=_9(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 _9(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 G=Q.winningDecision,Y=G.source.name||G.source.type,J=`Feature "${Q.featureId}" is ${Q.finalState}.
|
|
215
|
+
`,document.head.appendChild(G)}highlightTTSWord(G,Q,Y){if(!this.ttsWordHighlight)return;this.applyAdaptiveTTSStyle(G.parentElement),this.clearTTSWord();let J=document.createRange();J.setStart(G,Q),J.setEnd(G,Y),this.ttsWordHighlight.add(J)}highlightTTSWordElement(G){if(!this.ttsWordHighlight)return;this.applyAdaptiveTTSStyle(G),this.clearTTSWord(),G.setAttribute("data-pie-tts-word-element","true"),this.ttsWordElementHighlights.add(G)}highlightTTSSentence(G){if(!this.ttsSentenceHighlight)return;let Q=G[0]?.startContainer,Y=Q?.nodeType===Node.ELEMENT_NODE?Q:Q?.parentElement;this.applyAdaptiveTTSStyle(Y),this.clearTTSSentence();for(let J of G)this.ttsSentenceHighlight.add(J);this.highlightTTSElementFallbacks(G)}highlightTTSSentenceElements(G){if(!this.ttsSentenceHighlight)return;this.applyAdaptiveTTSStyle(G[0]||null),this.clearTTSSentence();for(let Q of G)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(G){if(typeof Element>"u")return;this.highlightElementFallbacks(G,"data-pie-tts-sentence-element",this.ttsSentenceElementHighlights,u7.SENTENCE_FALLBACK_SELECTOR)}highlightTTSWordElementFallbacks(G){if(typeof Element>"u")return;this.highlightElementFallbacks(G,"data-pie-tts-word-element",this.ttsWordElementHighlights,u7.WORD_FALLBACK_SELECTOR)}highlightElementFallbacks(G,Q,Y,J){for(let X of G){let j=X.commonAncestorContainer.nodeType===Node.ELEMENT_NODE?X.commonAncestorContainer:X.commonAncestorContainer.parentElement;if(!j)continue;let Z=[],K=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 B of[K,W]){let U=B;while(U){if(U.matches?.(J))Z.push(U);U=U.parentElement}}if(j.matches?.(J))Z.push(j);Z.push(...Array.from(j.querySelectorAll(J)));for(let B of new Set(Z)){try{if(!X.intersectsNode(B)&&!B.contains(K)&&!B.contains(W))continue}catch{continue}B.setAttribute(Q,"true"),Y.add(B)}}}clearTTSWord(){if(!this.ttsWordHighlight)return;this.ttsWordHighlight.clear();for(let G of this.ttsWordElementHighlights)G.removeAttribute("data-pie-tts-word-element");this.ttsWordElementHighlights.clear()}clearTTSSentence(){if(!this.ttsSentenceHighlight)return;this.ttsSentenceHighlight.clear();for(let G of this.ttsSentenceElementHighlights)G.removeAttribute("data-pie-tts-sentence-element");this.ttsSentenceElementHighlights.clear()}clearTTS(){this.clearTTSWord(),this.clearTTSSentence()}addAnnotation(G,Q=_7.YELLOW){let Y=`annotation-${this.nextAnnotationId++}`,J=G.cloneRange(),X={id:Y,range:J,type:u.ANNOTATION,color:Q,timestamp:Date.now()};this.annotations.set(Y,X);let j=this.colorHighlights.get(Q);if(j)j.add(J);return Y}removeAnnotation(G){let Q=this.annotations.get(G);if(!Q){console.warn(`[HighlightCoordinator] Annotation ${G} not found`);return}console.log(`[HighlightCoordinator] Removing annotation ${G} (color: ${Q.color})`);let Y=this.colorHighlights.get(Q.color);if(Y){let J=Y.delete(Q.range);console.log("[HighlightCoordinator] Highlight.delete() returned:",J)}this.annotations.delete(G),console.log(`[HighlightCoordinator] Annotation ${G} removed from map. Remaining:`,this.annotations.size)}clearAnnotations(){for(let G of this.colorHighlights.values())G.clear();this.annotations.clear()}getAnnotations(){return Array.from(this.annotations.values())}getAnnotation(G){return this.annotations.get(G)??null}changeAnnotationColor(G,Q){let Y=this.annotations.get(G);if(!Y)return;let J=Y.color;if(J===Q)return;let X=this.colorHighlights.get(J);if(X)X.delete(Y.range);Y.color=Q;let j=this.colorHighlights.get(Q);if(j)j.add(Y.range)}exportAnnotations(G=document.body){return this.getAnnotations().map((Q)=>({...this.rangeSerializer.serialize(Q.range,G),id:Q.id,color:Q.color,timestamp:Q.timestamp}))}importAnnotations(G,Q=document.body){let Y=0;for(let J of G){let X=this.rangeSerializer.deserialize(J,Q);if(X)this.addAnnotation(X,J.color),Y++}return Y}highlightRange(G,Q,Y=_7.YELLOW){if(!this.supported)return;switch(Q){case u.TTS_WORD:case u.TTS_SENTENCE:{let J=Q===u.TTS_WORD?this.ttsWordHighlight:this.ttsSentenceHighlight;if(J){if(J.clear(),J.add(G),Q===u.TTS_WORD){for(let X of this.ttsWordElementHighlights)X.removeAttribute("data-pie-tts-word-element");this.ttsWordElementHighlights.clear(),this.highlightTTSWordElementFallbacks([G])}}break}case u.ANNOTATION:this.addAnnotation(G,Y);break}}clearHighlights(G){if(!this.supported)return;switch(G){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(G,Q){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})(G);if(!X)return;this.explicitTTSColorOverride={color:`rgb(${X.r}, ${X.g}, ${X.b})`,opacity:Math.max(0.2,Math.min(0.95,Q))},this.applyAdaptiveTTSStyle()}destroy(){if(!this.supported)return;if(this.clearTTS(),this.clearAnnotations(),typeof document<"u"){let G=document.getElementById("pie-highlight-styles");if(G)G.remove()}this.themeObserver?.disconnect(),this.themeObserver=null}}function H6(G){return(...Q)=>{console.debug(`[${G}]`,...Q)}}var a=H6("ToolCoordinator"),Z7;(function(G){G[G.BASE=0]="BASE",G[G.TOOL=1000]="TOOL",G[G.MODAL=2000]="MODAL",G[G.CONTROL=3000]="CONTROL",G[G.HIGHLIGHT=4000]="HIGHLIGHT"})(Z7||(Z7={}));class Y8{config;tools=new Map;layerCounters=new Map;listeners=new Set;visibilityState=new Map;constructor(G={}){this.config=G,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(G){return this.listeners.add(G),()=>{this.listeners.delete(G)}}notifyListeners(){this.listeners.forEach((G)=>G())}registerTool(G,Q,Y,J=Z7.MODAL){if(a("registerTool called:",{id:G,name:Q,hasElement:!!Y,layer:J}),this.tools.has(G)){a(`Tool ${G} is already registered`);return}let X=this.visibilityState.get(G)??!1;if(!Y){this.tools.set(G,{id:G,name:Q,element:null,layer:J,isVisible:X,baseZIndex:J}),a("Tool registered without element:",G);return}let j=J+this.getNextLayerOffset(J);Y.style.zIndex=String(j),Y.style.display=X?"":"none";let Z=()=>this.bringToFront(Y);if(Y.addEventListener("mousedown",Z),this.tools.set(G,{id:G,name:Q,element:Y,layer:J,isVisible:X,baseZIndex:j,mouseDownHandler:Z}),X)this.bringToFront(Y);a("Tool registered with element:",G)}unregisterTool(G){let Q=this.tools.get(G);if(!Q)return;if(Q.element&&Q.mouseDownHandler)Q.element.removeEventListener("mousedown",Q.mouseDownHandler);this.tools.delete(G)}releaseTool(G){this.unregisterTool(G),this.visibilityState.delete(G)}showTool(G){let Q=this.tools.get(G);if(!Q){a(`Tool ${G} not found`);return}if(Q.element)Q.element.style.display="",this.bringToFront(Q.element);Q.isVisible=!0,this.visibilityState.set(G,!0),this.notifyListeners()}hideTool(G){let Q=this.tools.get(G);if(!Q){a(`Tool ${G} not found`);return}if(Q.element)Q.element.style.display="none";Q.isVisible=!1,this.visibilityState.set(G,!1),this.notifyListeners()}toggleTool(G){a("toggleTool called for:",G);let Q=this.tools.get(G);if(!Q){a(`Tool ${G} not found. Registered tools:`,Array.from(this.tools.keys()));return}if(a("Tool found, current visibility:",Q.isVisible),Q.isVisible)this.hideTool(G);else this.showTool(G)}isToolVisible(G){let Q=this.tools.get(G);if(Q)return Q.isVisible;return this.visibilityState.get(G)??!1}bringToFront(G){let Q=Array.from(this.tools.values()).find((X)=>X.element===G);if(!Q)return;let Y=this.getMaxZIndexInLayer(Q.layer),J=Math.max(Y+1,Q.layer+1);G.style.zIndex=String(J),Q.baseZIndex=J}getRegisteredTools(){return Array.from(this.tools.keys())}getToolElement(G){return this.tools.get(G)?.element??null}getNextLayerOffset(G){let Q=this.layerCounters.get(G)??0;return this.layerCounters.set(G,Q+1),Q}getMaxZIndexInLayer(G){let Q=G;for(let Y of this.tools.values())if(Y.layer===G)Q=Math.max(Q,Y.baseZIndex);return Q}resetZIndices(){for(let G of this.tools.values())if(G.element)G.element.style.zIndex=String(G.baseZIndex)}updateToolElement(G,Q){let Y=this.tools.get(G);if(!Y){a(`Tool ${G} not found`);return}if(Y.element&&Y.mouseDownHandler)Y.element.removeEventListener("mousedown",Y.mouseDownHandler);let J=()=>this.bringToFront(Q);if(Q.addEventListener("mousedown",J),Y.element=Q,Y.mouseDownHandler=J,Q.style.zIndex=String(Y.baseZIndex),Y.isVisible)Q.style.display="";else Q.style.display="none"}hideAllTools(){for(let G of this.tools.keys())this.hideTool(G);this.notifyListeners()}getToolState(G){let Q=this.tools.get(G);if(!Q)return;return{id:Q.id,name:Q.name,isVisible:Q.isVisible,element:Q.element??null,layer:Q.layer}}getVisibleTools(){return Array.from(this.tools.values()).filter((G)=>G.isVisible).map((G)=>({id:G.id,name:G.name,isVisible:G.isVisible,element:G.element??null,layer:G.layer}))}}var $5=/^[a-z][a-z0-9+.-]*:/i,w5=new Set(["http:","https:","data:","blob:"]);function A6(G){return G!==void 0&&G!==1}function R5(G){if(typeof G!=="string")return!1;let Q=G.trim();if(!Q)return!1;if(Q.startsWith("//")||!$5.test(Q))return!0;let Y=Q.slice(0,Q.indexOf(":")+1).toLowerCase();return w5.has(Y)}function F6(G){if(!Array.isArray(G))return[];let Q=[];for(let Y of G){if(!Y||typeof Y!=="object")continue;let J=Y;if(!R5(J.src))continue;let X={src:J.src.trim()};if(typeof J.type==="string"&&J.type.trim())X.type=J.type.trim();if(Number.isFinite(J.width))X.width=J.width;if(Number.isFinite(J.height))X.height=J.height;if(Q.some((j)=>j.src===X.src))continue;Q.push(X)}return Q}function N6(G){if(!G||typeof G!=="object")return;let Q=G,Y=Number(Q.startSeconds);if(!Number.isFinite(Y)||Y<0)return;let J=Number(Q.endSeconds);if(!Number.isFinite(J)||J<=Y)return{startSeconds:Y};return{startSeconds:Y,endSeconds:J}}function M6(G){if(typeof G!=="string")return;return G.trim()||void 0}var E5=100,b5=1;function z6(G,Q,Y){if(!Q)return()=>{};let{startSeconds:J,endSeconds:X}=Q,j;if(J>0)if(j=()=>{if(G.currentTime<J)G.currentTime=J},G.readyState>=b5)j();else G.addEventListener("loadedmetadata",j);let Z,K;if(X!==void 0)Z=()=>{if(G.currentTime>=X)Y()},G.addEventListener("timeupdate",Z),K=setInterval(()=>{if(!G.paused)Z?.()},E5);return()=>{if(j)G.removeEventListener("loadedmetadata",j);if(Z)G.removeEventListener("timeupdate",Z);if(K!==void 0)clearInterval(K)}}function O6(G,Q){if(!Q)return G;if(G.includes("#"))return G;let Y=Q.endSeconds!==void 0?`,${Q.endSeconds}`:"";return`${G}#t=${Q.startSeconds}${Y}`}function P6(G){if(!G)return null;let Q=G.payload;if(!Q||typeof Q!=="object")return null;let Y=Q.media;if(!Y||typeof Y!=="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(A6(Y.version))return console.warn(`[spoken-audio] card's media declares version ${String(Y.version)}, which this build does not render; the card is ignored and read-aloud falls back to the script or generated speech`),null;if(Y.kind!==void 0&&Y.kind!=="audio")return console.warn(`[spoken-audio] card's media is kind "${Y.kind}", not "audio"; a spoken card carries recorded speech, so this card is ignored`),null;let J=F6(Y.sources);if(J.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:J,fragment:N6(Q.fragment),label:M6(Y.label)}}var E7=(G,Q)=>{let Y=Q?.useSentenceSegmenter!==!1;try{if(!Y)throw Error("Segmenter disabled by policy");let K=globalThis.Intl?.Segmenter;if(typeof K==="function"){let W=new K(Q?.locale,{granularity:"sentence"}),B=Array.from(W.segment(G)).map((U)=>({text:U.segment,offset:U.index})).filter((U)=>U.text.trim().length>0);if(B.length>0)return B}}catch{}let J=/[^.!?]+(?:[.!?]+|$)/g,X=G.match(J)||[G],j=[],Z=0;for(let K of X){let W=G.indexOf(K,Z);if(W===-1)continue;j.push({text:K,offset:W}),Z=W+K.length}return j.length>0?j:[{text:G,offset:0}]};var L6=5000,$6=2000,w6=(G)=>String(G||"").trim().toLowerCase(),T5=()=>{let G=typeof navigator<"u"?navigator.language||navigator.languages?.[0]:"";return w6(G||"en-US")},C5=(G,Q)=>{if(Q)return G.find((Z)=>Z.voiceURI===Q)||G.find((Z)=>Z.name===Q)||null;let Y=T5(),J=Y.split("-")[0]||"en",X=(Z)=>{let K=w6(Z.lang);return K===Y||K.startsWith(`${J}-`)},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 K=G.find(Z);if(K)return K}return G[0]||null},S5=(G)=>!G.default;class b7{providerId="browser";providerName="Browser Speech Synthesis";version="1.0.0";async initialize(G){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 R6(G)}supportsFeature(G){return!0}getCapabilities(){return{supportsPause:!0,supportsResume:!0,supportsWordBoundary:!0,supportsVoiceSelection:!0,supportsRateControl:!0,supportsPitchControl:!0,supportsSSML:!1}}destroy(){}}class R6{utterance=null;config=null;_isPlaying=!1;_isPaused=!1;speakRunId=0;settlePendingVoiceWait=null;settlePendingChunk=null;onPlaybackStart=void 0;constructor(G){this.config=G}waitForBrowserVoices(G,Q){return new Promise((Y,J)=>{let X=speechSynthesis,j=typeof X.addEventListener==="function"&&typeof X.removeEventListener==="function",Z=j?null:X.onvoiceschanged,K=!1,W=null,B=null,U=()=>{if(W!==null)clearTimeout(W),W=null;if(j)X.removeEventListener("voiceschanged",N);else if(X.onvoiceschanged===M)X.onvoiceschanged=Z;if(B&&this.settlePendingVoiceWait===B)this.settlePendingVoiceWait=null},V=(P,$)=>{if(K)return;if(K=!0,U(),$)J($);else Y(P)},H=()=>{if(G!==this.speakRunId){V(!1);return}if(X.getVoices().length>0)V(!0)},N=()=>H(),M=(P)=>{try{Z?.call(X,P)}finally{H()}};if(B=()=>V(!1),this.settlePendingVoiceWait=B,W=setTimeout(()=>V(!1,Error(`Configured browser voice "${Q}" could not be resolved because the browser did not publish its voice inventory within ${$6/1000} seconds.`)),$6),j)X.addEventListener("voiceschanged",N);else X.onvoiceschanged=M;H()})}async resolveBrowserVoice(G){let Q=typeof this.config?.voice==="string"?this.config.voice.trim():"",Y=speechSynthesis.getVoices();if(Q&&Y.length===0){if(!await this.waitForBrowserVoices(G,Q)||G!==this.speakRunId)return{shouldContinue:!1,voice:null};Y=speechSynthesis.getVoices()}if(G!==this.speakRunId)return{shouldContinue:!1,voice:null};let J=C5(Y,Q||void 0);if(Q&&!J)throw Error(`Configured browser voice "${Q}" is unavailable. Select a voice exposed by this browser using its voiceURI or name.`);return{shouldContinue:!0,voice:J}}async speak(G){if(!this.config)throw Error("TTS not initialized");this.stop();let Q=this.speakRunId,Y=await this.resolveBrowserVoice(Q);if(!Y.shouldContinue)return;let J=this.splitIntoChunks(G);for(let X of J){if(Q!==this.speakRunId)break;if(!await this.speakChunk(X.text,X.offset,Q,Y.voice))break}}async speakSegments(G){if(!this.config)throw Error("TTS not initialized");this.stop();let Q=this.speakRunId,Y=await this.resolveBrowserVoice(Q);if(!Y.shouldContinue)return;for(let J of G){if(Q!==this.speakRunId)break;let X=this.splitIntoChunks(J.text);for(let Z of X){if(Q!==this.speakRunId)break;if(!await this.speakChunk(Z.text,J.startOffset+Z.offset,Q,Y.voice))break}let j=Math.max(0,Number(J.pauseMsAfter||0));if(j>0&&Q===this.speakRunId){if(!await this.waitForPause(j,Q))break}}}async waitForPause(G,Q){return await new Promise((Y)=>setTimeout(Y,G)),Q===this.speakRunId}splitIntoChunks(G){if(G.length<=260)return[{text:G,offset:0}];let Y=this.segmentSentences(G),J=[],X="",j=0;for(let Z of Y){let K=Z.text.trim();if(!K)continue;let W=Z.text.search(/\S/),B=Z.offset+(W===-1?0:W);if(!X){X=K,j=B;continue}let U=`${X} ${K}`;if(U.length<=260)X=U;else J.push({text:X,offset:j}),X=K,j=B}if(X)J.push({text:X,offset:j});return J.length?J:[{text:G,offset:0}]}getHighlightMode(){return(this.config?.providerOptions||{}).highlightMode==="word"?"word":"sentence"}getSegmentationPolicy(){let G=this.config?.providerOptions||{},Q=G.segmenter||{},J=Q.mode!=="regexOnly",X=typeof Q.locale==="string"&&Q.locale.trim().length>0?Q.locale:typeof G.locale==="string"&&G.locale.trim().length>0?G.locale:void 0;return{useSentenceSegmenter:J,useWordSegmenter:J,locale:X}}segmentSentences(G){let Q=this.getSegmentationPolicy();return E7(G,{locale:Q.locale,useSentenceSegmenter:Q.useSentenceSegmenter})}inferWordLength(G,Q){let Y=Math.max(0,Math.min(Q,Math.max(0,G.length-1)));return G.slice(Y).match(/^\s*([^\s]+)/)?.[1]?.length||1}async speakChunk(G,Q,Y,J){return new Promise((X,j)=>{if(Y!==this.speakRunId){X(!1);return}let Z=new SpeechSynthesisUtterance(G);if(this.utterance=Z,J&&S5(J))Z.voice=J;if(this.config?.rate)Z.rate=this.config.rate;if(this.config?.pitch)Z.pitch=this.config.pitch;let K=!1,W=!1,B=null,U=null,V=()=>{if(this.utterance===Z)this.utterance=null},H=()=>{if(B!==null)clearTimeout(B),B=null},N=()=>{Z.onstart=null,Z.onend=null,Z.onerror=null,Z.onpause=null,Z.onresume=null,Z.onboundary=null},M=($,A)=>{if(W)return;if(W=!0,H(),N(),V(),U&&this.settlePendingChunk===U)this.settlePendingChunk=null;if(Y===this.speakRunId)this._isPlaying=!1,this._isPaused=!1;if(A)j(A);else X($)},P=($)=>Error($==="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 ${L6/1000} seconds. The browser speech engine may be unavailable or stuck; try another voice or restart the browser.`);U=()=>M(!1),this.settlePendingChunk=U,Z.onstart=()=>{if(Y!==this.speakRunId){M(!1);return}K=!0,H(),this._isPlaying=!0,this._isPaused=!1;try{this.onPlaybackStart?.()}catch($){console.error("Browser TTS playback-start callback failed",$)}},Z.onend=()=>{if(Y!==this.speakRunId){M(!1);return}if(!K){M(!1,P("ended"));return}M(!0)},Z.onerror=($)=>{if(Y!==this.speakRunId){M(!1);return}if($.error==="interrupted"||$.error==="canceled"){M(!1);return}M(!1,Error(`Speech synthesis error: ${$.error}`))},Z.onpause=()=>{if(Y!==this.speakRunId)return;this._isPaused=!0},Z.onresume=()=>{if(Y!==this.speakRunId)return;this._isPaused=!1},Z.onboundary=($)=>{if(Y!==this.speakRunId)return;if(console.log("[BrowserProvider] Boundary event:",$.name,"charIndex:",$.charIndex,"charLength:",$.charLength),$.name!=="word"||!this.onWordBoundary)return;if(this.getHighlightMode()==="sentence")return;let A=Math.max(0,Math.min($.charIndex,Math.max(0,G.length-1))),L=Number($.charLength||0),T=this.inferWordLength(G,A),v=Number.isFinite(L)&&L>0&&L<=80&&A+L<=G.length?L:T,I=G.substring(A,Math.min(G.length,A+v)).trim(),p=Q+A;console.log("[BrowserProvider] Calling onWordBoundary with word:",I,"at position:",p),this.onWordBoundary(I,p,v)},B=setTimeout(()=>{if(W||K||Y!==this.speakRunId)return;M(!1,P("timedOut")),speechSynthesis.cancel()},L6);try{speechSynthesis.speak(Z)}catch($){M(!1,$ instanceof Error?$: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 G=this.utterance,Q=this._isPlaying||G!==null;if(this.speakRunId+=1,this.settlePendingVoiceWait?.(),this.settlePendingChunk?.(),Q)speechSynthesis.cancel();this.utterance=null,this._isPlaying=!1,this._isPaused=!1}isPlaying(){return this._isPlaying&&!this._isPaused}isPaused(){return this._isPaused}updateSettings(G){if(!this.config)this.config={};if(G.rate!==void 0)this.config.rate=G.rate;if(G.pitch!==void 0)this.config.pitch=G.pitch;if(G.voice!==void 0)this.config.voice=G.voice;if(G.providerOptions!==void 0)this.config.providerOptions={...this.config.providerOptions||{},...G.providerOptions||{}}}onWordBoundary}var C=(G)=>G.trim().replace(/\s+/g," "),W1=()=>/[\p{L}]+|\d+(?:\.\d+)?|[±√=+\-*/()²³^×÷≤≥≠≈<>|%°'′\u2062]/gu,J8=(G)=>{if(G.hidden)return!0;if(G.tagName?.toLowerCase()==="mjx-assistive-mml")return!0;if(G.getAttribute("aria-hidden")==="true")return!0;if(G.hasAttribute("inert"))return!0;let Q=G.classList;if(Q?.contains("sr-only")||Q?.contains("pie-sr-only")||Q?.contains("visually-hidden"))return!0;if(typeof window<"u"){let Y=window.getComputedStyle(G);if(Y.display==="none"||Y.visibility==="hidden")return!0;let J=Number.parseFloat(Y.width||"0"),X=Number.parseFloat(Y.height||"0"),j=Number.isFinite(J)&&Number.isFinite(X)&&J<=1&&X<=1,Z=Y.clipPath.includes("inset(50%")||Y.clipPath.includes("inset(100%")||Y.clip.includes("rect(0px, 0px, 0px, 0px)")||Y.clip.includes("rect(0 0 0 0)");if((Y.position==="absolute"||Y.position==="fixed")&&j&&(Y.overflow==="hidden"||Z))return!0;if(Y.opacity==="0"&&j)return!0}return!1},U1=(G,Q)=>{let Y=G.nodeType===1?G:G.parentElement;while(Y){if(J8(Y))return!0;if(Q&&Y===Q)break;Y=Y.parentElement}return!1};var T6=new Set(["computer-read-aloud","all"]),E6=new Set([...T6,"screen-reader"]),b6=new Set,y5=(G)=>{let Q=G.getAttribute?.("data-tts-suppress");if(Q===null||Q===void 0)return!1;let Y=Q.trim().toLowerCase();if(T6.has(Y))return!0;if(E6.has(Y))return!1;if(!b6.has(Y))b6.add(Y),console.warn(`[tts] data-tts-suppress="${Q}" is not one of ${Array.from(E6).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},B1=(G,Q)=>{let Y=G.nodeType===1?G:G.parentElement;while(Y){if(y5(Y))return!0;if(Q&&Y===Q)break;Y=Y.parentElement}return!1},V7=(G,Q)=>U1(G,Q)||B1(G),X8=(G,Q)=>{if(typeof document>"u"||typeof document.createTreeWalker!=="function"||typeof NodeFilter>"u"||typeof G.intersectsNode!=="function")return{text:G.toString(),filtered:!1};let Y=[],J=!1,X=document.createTreeWalker(Q,NodeFilter.SHOW_TEXT),j=X.nextNode();while(j){let Z=j;if(G.intersectsNode(Z))if(V7(Z,Q))J=!0;else{let K=Z.textContent||"",W=Z===G.startContainer?G.startOffset:0,B=Z===G.endContainer?G.endOffset:K.length;Y.push(K.slice(W,B))}j=X.nextNode()}return{text:Y.join(""),filtered:J}},Z8=(G,Q,Y)=>{if(!G||!Q)return!1;if(/\s/.test(G)||/\s/.test(Q))return!1;let J=Y?.boundarySpacingMode??"segmenterPreferred";if(J==="none")return!1;if(J==="segmenterPreferred")try{let Z=globalThis.Intl?.Segmenter;if(typeof Z==="function"){let K=new Z(Y?.locale,{granularity:"word"});if(Array.from(K.segment(`${G}${Q}`)).filter((U)=>U.isWordLike!==!1&&U.segment.trim().length>0).length>=2)return!0}}catch{}let X=/[A-Za-z0-9]/.test(G),j=/[A-Za-z0-9]/.test(Q);return X&&j},T7=(G,Q)=>{let Y=new Map;if(typeof document>"u"||typeof document.createTreeWalker!=="function"||typeof NodeFilter>"u")return{text:"",map:Y};let J=[],X=0,j=!0,Z=!1,K=null,W=null,B=document.createTreeWalker(G,NodeFilter.SHOW_TEXT),U=B.nextNode();while(U){let H=U;if(H.parentElement&&!V7(H,G)){let M=H.textContent||"",P=M.match(/\S/),$=P?P[0]:null;if(!j&&!Z&&Z8(W,$,Q)){if(J.push(" "),K)Y.set(X,K);X++,Z=!0}for(let A=0;A<M.length;A++){let L=M[A],T=/\s/.test(L);if(j){if(!T)j=!1,J.push(L),Y.set(X,{node:H,offset:A}),K={node:H,offset:A},X++,Z=!1,W=L}else if(T){if(!Z)J.push(" "),Y.set(X,{node:H,offset:A}),K={node:H,offset:A},X++;Z=!0}else J.push(L),Y.set(X,{node:H,offset:A}),K={node:H,offset:A},X++,Z=!1,W=L}}U=B.nextNode()}let V=J.join("").trimEnd();while(Y.has(V.length))Y.delete(V.length);return{text:V,map:Y}};var x5=new Set(["speak","p","s","emphasis","prosody","say-as","voice","lang"]),C6=new Set(["audio","phoneme"]),y6=(G)=>G.replace(/"/g,'"').replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/ /g," ").replace(/ /g," ").replace(/&/g,"&"),D1=(G,Q,Y)=>{for(let J=0;J<Q.length;J++)G.push({char:Q[J],rawOffset:Y===null?null:Y+J})},f5=(G,Q,Y)=>{let J=Q.slice(Y).match(/^&(quot|apos|lt|gt|nbsp|amp|#160);/i);if(!J)return 0;return D1(G,y6(J[0]),Y),J[0].length},S6=(G)=>{G.push({char:" ",rawOffset:null})},k5=(G)=>{let Q=new Map,Y=[],J=!0;for(let X of G){if(/\s/.test(X.char)){if(!J&&Y.length>0){if(Y.push(" "),X.rawOffset!==null)Q.set(X.rawOffset,Y.length-1)}J=!0;continue}if(Y.push(X.char),X.rawOffset!==null)Q.set(X.rawOffset,Y.length-1);J=!1}while(Y.length>0&&Y[Y.length-1]===" ")Y.pop();for(let[X,j]of Q)if(j>=Y.length)Q.delete(X);return{text:Y.join(""),rawToSpokenOffsetMap:Q}},I5=(G)=>{return G.match(/^<\/?\s*([A-Za-z0-9:-]+)/)?.[1]?.toLowerCase()||""},v5=(G,Q)=>{let Y=new RegExp(`${Q}\\s*=\\s*("([^"]*)"|'([^']*)')`,"i"),J=G.match(Y);return y6(J?.[2]??J?.[3]??"")||null},_1=(G)=>{let Q=[],Y=!1,J=!1,X=0;while(X<G.length){let Z=G[X];if(Z!=="<"){if(Z==="&"){let H=f5(Q,G,X);if(H>0){X+=H;continue}}D1(Q,Z,X),X++;continue}let K=G.indexOf(">",X+1);if(K<0){D1(Q,Z,X),X++;continue}J=!0;let W=G.slice(X,K+1),B=I5(W),U=/^<\s*\//.test(W),V=/\/\s*>$/.test(W);if(!U&&B==="sub"){let H=v5(W,"alias");if(!H){Y=!0,X=K+1;continue}D1(Q,H,null);let N=G.toLowerCase().indexOf("</sub>",K+1);X=N>=0?N+6:K+1;continue}if(!U&&B==="break"){S6(Q),X=K+1;continue}if(!U&&C6.has(B)){if(Y=!0,V){X=K+1;continue}}if(B&&!x5.has(B)&&!C6.has(B)&&B!=="break"&&B!=="sub")Y=!0;if(!U&&(B==="p"||B==="s"))S6(Q);X=K+1}let j=k5(Q);return{spokenText:C(j.text),rawToSpokenOffsetMap:j.rawToSpokenOffsetMap,unsupportedSemantic:Y,hasMarkup:J}};var h5=W1(),v6=new Map([["zero","0"],["one","1"],["two","2"],["three","3"],["four","4"],["five","5"],["six","6"],["seven","7"],["eight","8"],["nine","9"],["ten","10"]]),m5=[{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}],j8=(G)=>{let Q=[];for(let Y of G.matchAll(h5)){let J=Y[0],X=Y.index??0;Q.push({text:J,normalized:J.toLowerCase(),start:X,end:X+J.length})}return Q},K8=(G)=>v6.get(G.normalized)||G.normalized,u5=(G,Q)=>{let Y=[];for(let J=0;J<G.length;J++){for(let X=0;X<Q.length;X++){let j=K8(G[J]),Z=K8(Q[X]);if(j===Z)Y.push({spokenStartToken:J,spokenEndToken:J+1,visibleToken:X,score:10})}for(let X of m5){let j=G.slice(J,J+X.phrase.length);if(j.length!==X.phrase.length)continue;if(!j.every((Z,K)=>Z.normalized===X.phrase[K]))continue;for(let Z=0;Z<Q.length;Z++){if(Q[Z].normalized!==X.visible)continue;Y.push({spokenStartToken:J,spokenEndToken:J+X.phrase.length,visibleToken:Z,score:X.score})}}}return Y},p5=(G,Q)=>{let Y=u5(G,Q).sort((W,B)=>G[W.spokenStartToken].start-G[B.spokenStartToken].start||Q[W.visibleToken].start-Q[B.visibleToken].start),J=Array(Y.length).fill(0),X=Array(Y.length).fill(-1);for(let W=0;W<Y.length;W++){let B=Y[W];J[W]=B.score;for(let U=0;U<W;U++){let V=Y[U];if(V.spokenEndToken<=B.spokenStartToken&&V.visibleToken<B.visibleToken){let H=B.spokenStartToken-V.spokenEndToken,N=B.visibleToken-V.visibleToken-1,M=Math.max(0,Math.abs(H-N)-2),P=J[U]+B.score-M;if(P>J[W])J[W]=P,X[W]=U}}}let j=-1;for(let W=0;W<J.length;W++)if(j<0||J[W]>J[j])j=W;if(j<0)return[];let Z=[],K=j;while(K>=0)Z.unshift(Y[K]),K=X[K];return Z.map((W)=>{let B=G[W.spokenStartToken],U=G[W.spokenEndToken-1],V=Q[W.visibleToken];return{spokenStart:B.start,spokenEnd:U.end,visibleStart:V.start,visibleEnd:V.end,score:W.score}})},g5=(G,Q,Y)=>{if(G.length===0)return 0;let J=G.length/Math.max(1,Math.min(Q.length,Y.length)),X=G.reduce((j,Z)=>j+Z.score,0)/G.length/10;return Math.min(1,J*X)},V1=(G)=>{let Q=_1(G.speechText),Y=C(G.visibleText),J=Q.spokenText,X=j8(J),j=j8(Y),Z=Q.unsupportedSemantic?[]:p5(X,j),K=g5(Z,X,j),W=J===Y&&J.length>0,B=Z.length===1&&Z[0].score===10&&X.length<=2&&j.length<=2,U=Q.unsupportedSemantic?"region-fallback":W?"exact-word":Z.length>=2||B?K>=0.12?"anchor-span":"region-fallback":"region-fallback",V=Q.unsupportedSemantic?"unsupported":Q.hasMarkup?"raw-ssml":"plain-spoken-text";return{speechText:G.speechText,spokenText:J,visibleText:Y,playbackMode:U,boundaryOffsetMode:V,anchors:Z,confidence:K,spokenTokens:X,visibleTokens:j,rawToSpokenOffsetMap:Q.rawToSpokenOffsetMap}},q8=(G,Q)=>G.find((Y)=>Y.start<=Q&&Q<Y.end)||null,h6=(G)=>{if(!G)return null;if(/^<[^>]+>$/.test(G.trim()))return null;let Q=j8(G)[0];if(!Q)return null;return v6.get(Q.normalized)||Q.normalized},x6=(G,Q,Y)=>{let J=h6(Y);if(!Q||!J)return!1;let X=q8(G.spokenTokens,Q.start);if(!X)return!1;return K8(X)===J},f6=(G,Q)=>{let Y=G.rawToSpokenOffsetMap.get(Q);if(Y!==void 0)return Y;for(let J=Q;J<G.speechText.length;J++){let X=G.rawToSpokenOffsetMap.get(J);if(X!==void 0)return X;if(G.speechText[J]===">")break}return null},k6=(G,Q,Y)=>{let J=f6(G,Q);if(J===null)return null;let X=f6(G,Math.max(Q,Q+Y-1)),j=q8(G.spokenTokens,J),Z=X!==null&&X>=J?X-J+1:j?j.end-J:Y;return{start:J,length:Math.max(1,Z)}},I6=(G,Q,Y)=>{if(Q<0||Q>=G.spokenText.length)return null;let J=q8(G.spokenTokens,Q);if(!J)return null;return{start:Q,length:Math.min(Y,J.end-Q)}},m6=(G,Q,Y=1,J)=>{if(G.boundaryOffsetMode==="unsupported"||!Number.isFinite(Q))return null;let X=Math.max(1,Number.isFinite(Y)?Y:1);if(J&&/^<[^>]+>$/.test(J.trim()))return null;if(G.boundaryOffsetMode==="raw-ssml"){let j=k6(G,Q,X),Z=I6(G,Q,X);if(J){if(x6(G,j,J))return j;if(x6(G,Z,J))return Z;if(h6(J))return null}return j||Z}return I6(G,Q,X)||k6(G,Q,X)},u6=(G,Q)=>{if(G.playbackMode==="region-fallback")return null;let Y=G.anchors.find((j)=>j.spokenStart<=Q&&Q<j.spokenEnd);if(Y)return{start:Y.visibleStart,end:Y.visibleEnd};let J=null,X=null;for(let j of G.anchors){if(j.spokenEnd<=Q){J=j;continue}if(j.spokenStart>Q){X=j;break}}if(J&&X)return{start:Math.min(J.visibleStart,X.visibleStart),end:Math.max(J.visibleEnd,X.visibleEnd)};return null};var c5=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"]]]),l5=new Map([["","function-application"],["","implicit-multiply"],["","invisible-separator"],["","invisible-plus"]]),p6=new Map([["2",["squared"]],["3",["cubed"]]]),d5=new Map([["msqrt","radical"],["mroot","radical"],["msub","subscript"],["msubsup","subsupscript"],["munder","underscript"],["mover","overscript"],["munderover","underoverscript"],["mmultiscripts","multiscript"],["menclose","enclosure"]]),i5=(G)=>G.replace(/\s+/g," ").trim(),H7=(G)=>(G.localName||G.tagName||"").toLowerCase(),s5=(G)=>G.nodeType===Node.ELEMENT_NODE,C7=(G)=>Array.from(G.childNodes).filter(s5),W8=(G)=>i5(G.textContent||""),G7=(G,Q)=>({type:"element-range",quality:Q,element:G}),n5=(G)=>{switch(G){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"}},r5=(G,Q)=>{if(Q==="operator"){if(G==="−")return"-";return G}return G.toLowerCase()},o5=(G,Q,Y)=>{if(Y==="fraction")return["over","divided by"];if(Y==="superscript")return p6.get(G)??[];if(G==="|")return["absolute value"];if(Q==="operator")return c5.get(G)||[];return[]},A7=(G)=>{let Q=G.normalized??r5(G.text,G.kind||"unknown");return{id:`math-token-${G.state.nextId++}`,kind:G.kind,role:G.role,text:G.text,normalized:Q,spokenAliases:o5(G.text,G.kind,G.role),sourceElement:G.sourceElement,path:G.path,target:G.target||G7(G.sourceElement,"element-range"),optional:G.optional}},F7=(G,Q,Y="tokens")=>{G[Y].push(Q)},g6=(G,Q,Y)=>{C7(G).forEach((J,X)=>Q7(J,Q,`${Y}/${H7(J)}[${X}]`))},a5=(G,Q,Y)=>{let J=C7(G);if(J[0])Q7(J[0],Q,`${Y}/numerator`);if(F7(Q,A7({state:Q,kind:"structure",role:"fraction",text:"/",sourceElement:G,path:Y,target:G7(G,"element-range")})),J[1])Q7(J[1],Q,`${Y}/denominator`)},t5=(G,Q,Y)=>{let J=G.getAttribute("open")||"(",X=G.getAttribute("close")||")";F7(Q,A7({state:Q,kind:"operator",role:J==="|"?"absolute-value-fence":"open-fence",text:J,sourceElement:G,path:`${Y}/open`,target:G7(G,"element-range")})),g6(G,Q,Y),F7(Q,A7({state:Q,kind:"operator",role:X==="|"?"absolute-value-fence":"close-fence",text:X,sourceElement:G,path:`${Y}/close`,target:G7(G,"element-range")}))},e5=(G,Q,Y)=>{let J=C7(G);if(J[0])Q7(J[0],Q,`${Y}/base`);let X=J[1];if(!X)return;let j=W8(X);if(p6.has(j)){F7(Q,A7({state:Q,kind:"structure",role:"superscript",text:j,normalized:j,sourceElement:X,path:`${Y}/exponent`,target:G7(G,"element-range")}));return}Q7(X,Q,`${Y}/exponent`)},GG=(G,Q,Y,J)=>{F7(Q,A7({state:Q,kind:"structure",role:J,text:W8(G)||J,normalized:`\x00${J}`,sourceElement:G,path:Y,target:G7(G,"element-range")}))},QG=(G,Q,Y)=>{let J=0;for(let X of C7(G)){if(H7(X)==="mtr"||H7(X)==="mlabeledtr")J++,F7(Q,A7({state:Q,kind:"layout",role:"table-row",text:`row-${J}`,normalized:`row-${J}`,sourceElement:X,path:`${Y}/row[${J}]`,target:G7(X,"region-fallback")}),"layoutTargets");Q7(X,Q,`${Y}/${H7(X)}[${J}]`)}},YG=(G,Q,Y)=>{let J=W8(G);if(!J)return;let X=n5(H7(G)),j=X==="operator"?l5.get(J):void 0,Z=j??(X==="operator"&&(J==="("||J===")")?"grouping-fence":X);F7(Q,A7({state:Q,kind:X,role:Z,text:J,sourceElement:G,path:Y,target:j&&G.parentElement?G7(G.parentElement,"region-fallback"):void 0,optional:Boolean(j)||Z==="grouping-fence"}))},Q7=(G,Q,Y)=>{let J=H7(G);switch(J){case"annotation":case"annotation-xml":return;case"semantics":{let X=C7(G).find((j)=>{let Z=H7(j);return Z!=="annotation"&&Z!=="annotation-xml"});if(X)Q7(X,Q,`${Y}/presentation`);return}case"mi":case"mn":case"mo":case"mtext":case"ms":case"mspace":YG(G,Q,Y);return;case"mfrac":a5(G,Q,Y);return;case"msup":e5(G,Q,Y);return;case"mfenced":t5(G,Q,Y);return;case"mtable":QG(G,Q,Y);return;case"mphantom":return;case"maction":{let X=C7(G)[0];if(X)Q7(X,Q,`${Y}/action`);return}default:{let X=d5.get(J);if(X){GG(G,Q,Y,X);return}g6(G,Q,Y)}}},c6=(G)=>{let Q={tokens:[],layoutTargets:[],nextId:0};return Q7(G,Q,"/math"),{tokens:Q.tokens,layoutTargets:Q.layoutTargets,expressionTarget:G7(G,"region-fallback")}};var l6=(G)=>{if(!G.boundary)return null;return G.alignment.segments.find((Y)=>Y.speechTokenIds.includes(G.boundary.token.id))?.target||null};var JG=(G)=>{let Q=[],Y=new Set,J=(X)=>{let j=X.toLowerCase().trim().split(/\s+/).filter(Boolean);if(j.length===0)return;let Z=j.join(" ");if(Y.has(Z))return;Y.add(Z),Q.push(j)};J(G.normalized);for(let X of G.spokenAliases)J(X);return Q},d6=(G,Q,Y)=>{let J=0;for(let X of Y){if(X.length<=J)continue;let j=!0;for(let Z=0;Z<X.length;Z++){let K=G[Q+Z];if(!K||K.normalized.toLowerCase()!==X[Z]){j=!1;break}}if(j)J=X.length}return J},XG=(G,Q)=>{let Y=[],J=0;for(let X of Q){let j=JG(X);if(X.optional){let Z=d6(G,J,j);if(Z>0)Y.push({speechTokens:G.slice(J,J+Z),math:X}),J+=Z;continue}while(J<G.length){let Z=d6(G,J,j);if(Z>0){Y.push({speechTokens:G.slice(J,J+Z),math:X}),J+=Z;break}J++}}return Y},ZG=(G,Q,Y)=>{let J=Y.filter((Z)=>!Z.optional).length,X=G.filter((Z)=>!Z.math.optional).length,j=G.reduce((Z,K)=>Z+K.speechTokens.length,0);return J>0&&X===J&&j===Q.length},jG=(G)=>G.map(({speechTokens:Q,math:Y})=>({speechTokenIds:Q.map((J)=>J.id),mathTokenIds:[Y.id],score:1,confidence:1,target:Y.target})),i6=(G)=>{let Q=G.minExactWordConfidence??0.95,Y=XG(G.speech.tokens,G.math.tokens),J=ZG(Y,G.speech.tokens,G.math.tokens)?1:0;return{segments:J>=Q?jG(Y):[],confidence:J,fallbackTarget:G.math.expressionTarget}};var s6=W1(),KG=new Map([["zero","0"],["one","1"],["two","2"],["three","3"],["four","4"],["five","5"],["six","6"],["seven","7"],["eight","8"],["nine","9"],["ten","10"]]),n6=(G)=>{let Q=G.toLowerCase();return KG.get(Q)||Q},qG=(G)=>{let Q=[];for(let Y of G.matchAll(s6)){let J=Y[0],X=Y.index??0;Q.push({id:`speech-token-${Q.length}`,text:J,normalized:n6(J),start:X,end:X+J.length,sourceStart:X,sourceEnd:X+J.length,coordinateSystem:"normalized-speech"})}return Q},N7=(G)=>{let Q=_1(G.speechText);return{speechText:G.speechText,spokenText:Q.spokenText,tokens:qG(Q.spokenText),rawToSpokenOffsetMap:Q.rawToSpokenOffsetMap,boundaryOffsetSpace:Q.unsupportedSemantic?"unsupported":Q.hasMarkup?"raw-ssml":"plain-spoken-text",unsupportedSemantic:Q.unsupportedSemantic,hasMarkup:Q.hasMarkup}},D8=(G)=>{if(!G)return null;if(/^<[^>]+>$/.test(G.trim()))return null;let Q=G.match(s6);if(!Q?.[0])return null;return n6(Q[0])},WG=(G,Q)=>G.find((Y)=>Y.start<=Q&&Q<Y.end)||null,UG=(G,Q)=>{let Y=G.rawToSpokenOffsetMap.get(Q);if(Y!==void 0)return Y;for(let J=Q;J<G.speechText.length;J++){let X=G.rawToSpokenOffsetMap.get(J);if(X!==void 0)return X;if(G.speechText[J]===">")break}return null},U8=(G,Q,Y)=>{if(Q===null)return null;let J=WG(G.tokens,Q);if(!J)return null;return{token:J,start:Q,length:Math.max(1,Math.min(Y,J.end-Q)),confidence:0.75}},B8=(G,Q)=>{let Y=D8(Q);return Boolean(G&&Y&&G.token.normalized===Y)},_8=(G)=>{if(G.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(G.position)||G.boundaryWord&&/^<[^>]+>$/.test(G.boundaryWord.trim()))return null;let Q=Math.max(1,Number.isFinite(G.length)?G.length:1),Y=U8(G.tokenization,UG(G.tokenization,G.position),Q),J=U8(G.tokenization,G.position>=0&&G.position<G.tokenization.spokenText.length?G.position:null,Q);if(B8(Y,G.boundaryWord))return{...Y,confidence:1};if(B8(J,G.boundaryWord))return{...J,confidence:1};if(G.boundaryWord&&D8(G.boundaryWord))return null;return G.tokenization.boundaryOffsetSpace==="raw-ssml"?Y||J:J||Y},r6=(G)=>{if(G.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(G.position)||G.boundaryWord&&/^<[^>]+>$/.test(G.boundaryWord.trim()))return null;let Q=Math.max(1,Number.isFinite(G.length)?G.length:1),Y=U8(G.tokenization,G.position>=0&&G.position<G.tokenization.spokenText.length?G.position:null,Q);if(B8(Y,G.boundaryWord))return{...Y,confidence:1};if(G.boundaryWord&&D8(G.boundaryWord))return null;return Y};var S7=(G)=>{let Q=N7({speechText:G.speechText}),Y=c6(G.mathElement);return{speech:Q,math:Y,result:i6({speech:Q,math:Y})}};var o6=(G,Q)=>{let Y=r6({tokenization:G.speech,position:Q.position,length:Q.length,boundaryWord:Q.boundaryWord});return l6({alignment:G.result,boundary:Y})},a6=(G,Q)=>{if(!Q.boundaryWord||/^<[^>]+>$/.test(Q.boundaryWord.trim()))return null;let Y=N7({speechText:Q.boundaryWord}).tokens[0];if(!Y)return null;let J=G.math.tokens.filter((X)=>{let j=Y.normalized.toLowerCase();return X.normalized.toLowerCase()===j||X.spokenAliases.some((Z)=>Z.toLowerCase()===j)});return J.length===1?J[0].target:null};var BG=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"]),DG=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"]),t6=(G)=>G.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),_G=(G)=>t6(G).replace(/"/g,"""),VG=(G,Q)=>{let Y=G.toLowerCase(),J=Q.trim().toLowerCase();if(Y.startsWith("on"))return!0;if(!DG.has(Y))return!0;if(J.includes("javascript:"))return!0;if(J.includes("data:text/html"))return!0;return!1},HG=(G)=>{let Q=G.localName.toLowerCase();if(!BG.has(Q))return!1;let Y=G.namespaceURI;return!Y||Y==="http://www.w3.org/1998/Math/MathML"||Y==="http://www.w3.org/1999/xhtml"},e6=(G)=>{if(G.nodeType===Node.TEXT_NODE)return t6(G.textContent||"");if(G.nodeType===Node.COMMENT_NODE)return"";if(G.nodeType!==Node.ELEMENT_NODE)return null;let Q=G;if(!HG(Q))return null;let Y=Q.localName.toLowerCase(),J=[];for(let Z of Array.from(Q.attributes)){let K=Z.name.toLowerCase();if(VG(K,Z.value))continue;if(K==="xmlns"&&Z.value!=="http://www.w3.org/1998/Math/MathML")return null;J.push(`${K}="${_G(Z.value)}"`)}if(Y==="math"&&!J.some((Z)=>Z.startsWith("xmlns=")))J.unshift('xmlns="http://www.w3.org/1998/Math/MathML"');let X=[];for(let Z of Array.from(Q.childNodes)){let K=e6(Z);if(K===null)return null;X.push(K)}let j=J.length>0?` ${J.join(" ")}`:"";return`<${Y}${j}>${X.join("")}</${Y}>`},AG=(G)=>{if(typeof DOMParser<"u")return new DOMParser().parseFromString(G,"application/xml");return null},H1=(G)=>{let Q=String(G||"").trim();if(!Q)return null;let Y=AG(Q);if(!Y)return null;if(Y.getElementsByTagName("parsererror").length>0)return null;let J=Y.documentElement;if(!J||J.localName.toLowerCase()!=="math")return null;return e6(J)};var G0=(G)=>({chars:[],map:new Map,position:0,inLeadingWhitespace:!0,lastCharWasWhitespace:!1,lastMapped:null,options:G}),Q0=(G)=>G.classList?.contains("MathJax")||G.tagName?.toLowerCase()==="mjx-container",Y0=(G)=>G.tagName?.toLowerCase()==="mjx-assistive-mml",J0=(G)=>{let Q=G.tagName?.toLowerCase();return Q==="annotation"||Q==="annotation-xml"},FG=(G)=>{let Q=G.getAttribute("data-mathml");return Q&&Q.trim()?Q:null},NG=(G)=>{return G.querySelector("mjx-assistive-mml math")?.outerHTML||null},MG=(G)=>{if(G.tagName.toLowerCase()==="math")return H1(G.outerHTML);let Q=FG(G);if(Q){let Y=H1(Q);if(Y)return Y}if(Q0(G)){let Y=NG(G);if(Y){let J=H1(Y);if(J)return J}}return null};var zG=new Set(["P","H1","H2","H3","H4","H5","H6","LI","TD","TH","DD","DT","FIGCAPTION","LABEL","BUTTON"]),OG=new Set(["heading","listitem","option","radio","row","cell","columnheader","rowheader"]),PG=(G,Q)=>{let Y=G.parentElement,J=null;while(Y&&Y!==Q){let X=(Y.getAttribute("role")||"").toLowerCase(),j=Y.tagName.toUpperCase();if(zG.has(j)||OG.has(X)){J=Y;break}Y=Y.parentElement}return J||Q},LG=(G)=>Boolean(typeof G.querySelector==="function"&&G.querySelector("math, [data-mathml], .MathJax, mjx-container, mjx-assistive-mml"))||G.tagName?.toLowerCase()==="math"||G.hasAttribute?.("data-mathml")||Q0(G),M7=(G,Q,Y)=>{if(/[.,;:!?]/.test(Q)&&G.chars.length>0&&G.chars[G.chars.length-1]===" ")G.chars.pop(),G.position--,G.map.delete(G.position);if(G.chars.push(Q),Y)G.map.set(G.position,Y),G.lastMapped=Y;else if(G.lastMapped)G.map.set(G.position,G.lastMapped);G.position++},X0=(G,Q)=>{if(G.inLeadingWhitespace||G.lastCharWasWhitespace||G.chars.length===0)return!1;let Y=G.chars[G.chars.length-1];return Z8(Y,Q,G.options)},Z0=(G,Q)=>{let Y=Q.textContent||"",J=!1;for(let X=0;X<Y.length;X++){let j=Y[X],Z=/\s/.test(j);if(G.inLeadingWhitespace){if(!Z)G.inLeadingWhitespace=!1,M7(G,j,{node:Q,offset:X}),J=!0,G.lastCharWasWhitespace=!1;continue}if(Z){if(!G.lastCharWasWhitespace)M7(G," ",{node:Q,offset:X});G.lastCharWasWhitespace=!0;continue}if(!J&&X0(G,j))M7(G," ",{node:Q,offset:X});M7(G,j,{node:Q,offset:X}),J=!0,G.lastCharWasWhitespace=!1}},$G=(G,Q)=>{for(let Y=0;Y<Q.text.length;Y++){let J=Q.text[Y],X=/\s/.test(J),j=Q.map.get(Y)||null,Z=j?.node||G.lastMapped?.node||null,K=j?.offset??G.lastMapped?.offset??0,W=j?{node:j.node,offset:j.offset}:Z?{node:Z,offset:K}:null;if(G.inLeadingWhitespace){if(X)continue;G.inLeadingWhitespace=!1}if(X){if(!G.lastCharWasWhitespace)M7(G," ",W);G.lastCharWasWhitespace=!0;continue}if(Y===0&&X0(G,J))M7(G," ",W);if(M7(G,J,W),G.lastCharWasWhitespace=!1,j)G.map.set(G.position-1,{node:j.node,offset:j.offset}),G.lastMapped={node:j.node,offset:j.offset};else if(Z)G.map.set(G.position-1,{node:Z,offset:K})}},wG=(G)=>{if(typeof DOMParser>"u")return"";let Q=new DOMParser().parseFromString(G,"application/xml");if(Q.getElementsByTagName("parsererror").length>0)return"";let Y=[],J=(X)=>{if(X.nodeType===3){let Z=X.textContent||"";if(Z.trim())Y.push(Z);return}if(X.nodeType!==1)return;let j=X;if(J0(j))return;for(let Z of Array.from(j.childNodes))J(Z)};return J(Q.documentElement),C(Y.join(" "))},RG=(G,Q,Y)=>{let J=G0(Y),X=(K)=>{if(V7(K,G))return;if(K.nodeType===3){Z0(J,K);return}if(K.nodeType!==1)return;let W=K;if(Y0(W)||J0(W))return;for(let B of Array.from(W.childNodes))X(B)};X(G),j0(J);let j=C(J.chars.join(""));if(j)return{text:j,map:J.map};let Z=wG(Q);if(!Z)return T7(G,Y);return{text:Z,map:new Map}},j0=(G)=>{while(G.chars.length>0&&/\s/.test(G.chars[G.chars.length-1]))G.chars.pop(),G.position--,G.map.delete(G.position)},EG=(G,Q)=>{let Y=G0(Q),J=[],X=0,j,Z=!1,K=()=>{let U=C(Y.chars.slice(X,Y.chars.length).join(""));if(U)J.push({type:"text",text:U,sourceElement:j});X=Y.chars.length,j=void 0},W=(U)=>{if(V7(U,G))return;if(U.nodeType===Node.TEXT_NODE){let N=PG(U,G);if(j&&N!==j)K();j=N,Z0(Y,U);return}if(U.nodeType!==Node.ELEMENT_NODE)return;let V=U;if(Y0(V))return;let H=MG(V);if(H){K();let N=RG(V,H,Q);$G(Y,N);let M=C(N.text);J.push({type:"math",mathml:H,fallbackText:M,sourceElement:V}),X=Y.chars.length,Z=!0;return}for(let N of Array.from(V.childNodes))W(N)};for(let U of Array.from(G.childNodes))W(U);j0(Y),K();let B=Y.chars.join("");while(Y.map.has(B.length))Y.map.delete(B.length);return{visibleText:B,map:Y.map,chunks:J,containsMathMarkup:Z}},z7=(G,Q)=>{if(!LG(G)){let{text:Y,map:J}=T7(G,Q);return{visibleText:Y,map:J,chunks:Y?[{type:"text",text:Y}]:[],containsMathMarkup:!1}}return EG(G,Q)};var V8=null,K0=Promise.resolve(),TG=(G)=>(G||"en").split("-")[0].toLowerCase()||"en",CG=async()=>{if(!V8)V8=import("speech-rule-engine").then((G)=>{let Q=G.default||G;if(!Q||typeof Q.toSpeech!=="function")throw Error("speech-rule-engine did not expose toSpeech");return Q});return V8},SG=(G)=>G==="en"?"clearspeak":"mathspeak",q0=(G)=>!!G&&typeof G==="object"&&!Array.isArray(G),W0=(G)=>typeof G==="string"&&G.trim()?G.trim():void 0,O7=(G)=>{if(!q0(G))return;let Q=W0(G.domain),Y=W0(G.style),J=q0(G.engineOptions)?G.engineOptions:void 0;if(!Q&&!Y&&!J)return;return{...Q?{domain:Q}:{},...Y?{style:Y}:{},...J?{engineOptions:J}:{}}},yG=async(G,Q,Y,J)=>{let X=TG(Q),j=O7(J);await G.setupEngine?.({...j?.engineOptions||{},locale:X,domain:j?.domain||SG(X),...j?.style?{style:j.style}:{},modality:"speech",markup:Y}),await G.engineReady?.()},xG=async(G)=>{let Q=K0.then(G,G);return K0=Q.then(()=>{return},()=>{return}),Q},U0=async(G,Q,Y,J,X)=>xG(async()=>{return await yG(G,Y,J,X),G.toSpeech(Q)}),fG=(G)=>G.replace(/^\s*<\?xml[^>]*\?>\s*/i,""),kG=async(G,Q,Y,J)=>{try{let X=fG(await U0(G,Q,Y,"ssml",J));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(G,Q={})=>{if(!G.some((B)=>B.type==="math"))return{speechText:C(G.map((B)=>B.type==="text"?B.text:B.fallbackText).join(" ")),usedMathSpeech:!1,usedFallback:!1};let Y=null,J=!1,X=!1,j=Q.loadSre||CG,Z=[];for(let B of G){if(B.type==="text"){Z.push(B.text);continue}try{if(!Y)Y=await j();let U=C(await U0(Y,B.mathml,Q.language,"none",Q.mathSpeech));if(U){Z.push(U),J=!0;continue}X=!0,Z.push(B.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(B.fallbackText)}}let K=C(Z.join(" ")),W;if(Q.produceSsml&&Y&&J&&G.length===1&&G[0].type==="math")W=await kG(Y,G[0].mathml,Q.language,Q.mathSpeech)??void 0;return{speechText:K,usedMathSpeech:J,usedFallback:X,ssml:W}};var IG=(G,Q)=>A1([G],Q),vG=(G)=>(G||"en").split("-")[0].toLowerCase()||"en",hG=new Set(["H1","H2","H3","H4","H5","H6","LI","LABEL","BUTTON"]),mG=new Set(["heading","listitem","option","radio"]),uG=(G)=>{if(G.type!=="text"||!G.sourceElement)return!1;let Q=G.sourceElement.tagName.toUpperCase(),Y=(G.sourceElement.getAttribute("role")||"").toLowerCase();return hG.has(Q)||mG.has(Y)},H8=async(G)=>{let Q=G.resolveMathSpeech??IG,{visibleText:Y}=G,J=[],X=0,j=(K)=>{let W=C(K),B=Y.indexOf(W,X),U=B>=0?B:X,V=U+W.length;return X=V,{start:U,end:V}},Z=[];for(let K=0;K<G.chunks.length;K++){let W=G.chunks[K];if(W.type==="text"){let N=uG(W)?[{text:W.text,offset:0}]:E7(W.text,{locale:G.language});for(let M of N){let P=C(M.text);if(!P)continue;let $=j(P);J.push({sourceChunkIndex:K,segment:{kind:"prose",spokenText:P,visibleText:P,visibleSpan:$}}),Z.push(P)}continue}let B=j(W.fallbackText),U=await Q(W,{language:G.language,produceSsml:G.produceSsml,mathSpeech:G.mathSpeech}),V=!U.speechText,H=U.speechText||W.fallbackText;J.push({sourceChunkIndex:K,segment:{kind:"math",spokenText:H,mathml:W.mathml,fallbackText:W.fallbackText,visibleSpan:B,usedFallback:V,ssml:U.ssml}}),Z.push(H)}return{segments:J,locale:vG(G.language),visibleText:Y,plainSpeechText:C(Z.join(" "))}};var pG=(G)=>(G||"en").split("-")[0].toLowerCase()||"en",gG="sre-v1",cG=256,A8=(G)=>{if(Array.isArray(G))return`array:[${G.map(A8).join(",")}]`;if(G&&typeof G==="object")return`object:{${Object.entries(G).sort(([Q],[Y])=>Q.localeCompare(Y)).map(([Q,Y])=>`${JSON.stringify(Q)}:${A8(Y)}`).join(",")}}`;if(G===null)return"null:null";if(typeof G>"u")return"undefined:";if(typeof G==="function")return`function:${G.name||"anonymous"}`;if(typeof G==="symbol")return`symbol:${String(G)}`;if(typeof G==="bigint")return`bigint:${G.toString()}`;if(typeof G==="number")return Number.isFinite(G)?`number:${G}`:`number:${String(G)}`;return`${typeof G}:${JSON.stringify(G)}`},B0=(G,Q,Y,J)=>`${gG}\x00${pG(G)}\x00${Q?"ssml":"plain"}\x00${A8(Y??null)}\x00${J}`,F8=(G={})=>{let Q=Math.max(1,G.maxEntries??cG),Y=G.resolve??((j,Z)=>A1([j],Z)),J=new Map,X=(j,Z)=>{J.delete(j),J.set(j,Z);while(J.size>Q){let K=J.keys().next().value;if(K!==void 0)J.delete(K)}};return async(j,Z)=>{let K=O7(Z.mathSpeech),W=Z.produceSsml===!0,B=B0(Z.language,W,K,j.mathml),U=J.get(B);if(U)return J.delete(B),J.set(B,U),U;let V=await Y(j,{...Z,mathSpeech:K});if(W&&V.ssml&&Q>1)X(B0(Z.language,!1,K,j.mathml),{speechText:V.speechText,usedMathSpeech:V.usedMathSpeech,usedFallback:V.usedFallback});return X(B,V),V}};var lG=(G)=>{if(!G||/^<[^>]+>$/.test(G.trim()))return null;return N7({speechText:G}).tokens[0]?.normalized||null},dG=(G,Q)=>{let Y=N7({speechText:G.speechText});if(!Number.isFinite(Q.position))return{boundary:null,spokenText:Y.spokenText};let J=_8({tokenization:Y,position:Q.position,length:Q.length,boundaryWord:Q.word});return{boundary:J?{start:J.start,length:J.length}:null,spokenText:Y.spokenText}},iG=(G,Q,Y)=>{if(!Y)return!0;return N7({speechText:G}).tokens.find((X)=>X.start<=Q&&Q<X.end)?.normalized===Y},D0=(G,Q)=>{let Y=lG(Q.word);if(G.id!==Q.chunkId)return{chunkId:Q.chunkId,normalizedWord:Y,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"boundary chunk id did not match highlight chunk"};if(Q.providerOffsetSpace==="unknown"||G.offsetSpace==="unsupported")return{chunkId:G.id,normalizedWord:Y,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"boundary offset space is unsupported"};let J,X;if(G.catalogAlignment)J=m6(G.catalogAlignment,Q.position,Q.length,Q.word),X=G.catalogAlignment.spokenText;else{let j=dG(G,Q);J=j.boundary,X=j.spokenText}if(!J)return{chunkId:G.id,normalizedWord:Y,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"could not resolve provider boundary to chunk speech"};if(!iG(X,J.start,Y))return{chunkId:G.id,normalizedWord:Y,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"could not resolve provider boundary to matching word"};return{chunkId:G.id,normalizedWord:Y,chunkSpokenStart:J.start,chunkSpokenEnd:J.start+J.length,confidence:Y?1:0.75,reason:G.catalogAlignment?"resolved through catalog alignment":"resolved through speech tokenization"}};var P7=(G)=>{if(G.semanticTarget)return{activeTarget:G.semanticTarget,regionTarget:G.regionTarget,quality:G.semanticTarget.quality==="exact-word"?"exact-word":G.semanticTarget.quality==="expression"?"expression":"semantic-token",confidence:G.confidence,reason:G.reason};if(G.expressionTarget)return{activeTarget:G.expressionTarget,regionTarget:G.regionTarget,quality:"expression",confidence:G.confidence,reason:G.reason};return{activeTarget:null,regionTarget:G.regionTarget,quality:"region",confidence:G.confidence,reason:G.reason}};var V0=new Map([["mi","mjx-mi"],["mn","mjx-mn"],["mo","mjx-mo"],["mtext","mjx-mtext"]]),N8="mi,mn,mo,mtext",H0="mjx-mi,mjx-mn,mjx-mo,mjx-mtext",A0=["mjx-mfrac","mjx-msqrt","mjx-mroot","mjx-mtable","mjx-munder","mjx-mover","mjx-munderover"].join(","),F0=(G)=>{if(G.type==="text-range")return G.node.parentElement;return G.element},F1=(G)=>{let Q=G;while(Q){if(Q.localName?.toLowerCase()==="mjx-container")return Q;Q=Q.parentElement}return null},_0=(G)=>{if(!G)return!1;if(F1(G))return!1;return!U1(G)},N0=(G)=>{let Q=G.getBoundingClientRect?.();return Boolean(Q&&Q.width>0&&Q.height>0)},M8=(G)=>{let Q=G;while(Q){if(Q.localName?.toLowerCase()==="math")return Q;Q=Q.parentElement}return null},M0=(G,Q)=>{if(G.length===0)return!1;if(G.length!==Q.length)return!1;for(let Y=0;Y<G.length;Y+=1){let J=V0.get(G[Y].localName.toLowerCase());if(!J)return!1;if(Q[Y].localName.toLowerCase()!==J)return!1}return!0},sG=(G,Q)=>{if(!G)return null;if(!V0.has(G.localName.toLowerCase()))return null;if(Q.querySelector(A0))return null;let Y=M8(G),J=Q.querySelector("mjx-math");if(!Y||!J)return null;let X=Array.from(Y.querySelectorAll(N8)),j=X.indexOf(G);if(j<0)return null;let Z=Array.from(J.querySelectorAll(H0));if(!M0(X,Z))return null;let K=Z[j];if(!K||!N0(K))return null;return K},z0=(G)=>{let Q=F1(G);if(Q){if(Q.querySelector(A0))return"expression";let X=M8(G)??G,j=Q.querySelector("mjx-math");if(!j)return"expression";let Z=Array.from(X.querySelectorAll(N8)),K=Array.from(j.querySelectorAll(H0));if(!M0(Z,K))return"expression";return K.some((W)=>N0(W))?"token":"expression"}let Y=M8(G)??G;return Array.from(Y.querySelectorAll(N8)).some((X)=>!U1(X))?"token":"expression"},z8=(G)=>{let Q=F0(G),Y=F1(Q);if(Y){let J=sG(Q,Y);if(J)return{type:"element",quality:"semantic-token",element:J};return{type:"element",quality:"expression",element:Y}}if(G.type==="text-range"){if(!_0(G.node.parentElement))return null;return{type:"text-range",quality:"semantic-token",node:G.node,startOffset:G.startOffset,endOffset:G.endOffset}}if(!_0(G.element))return null;return{type:"element",quality:G.quality==="region-fallback"?"expression":"semantic-token",element:G.element}},O0=z8,P0=()=>{let G=new WeakMap;return(Q)=>{let Y=F0(Q),J=F1(Y);if(!Y||!J)return z8(Q);if(G.has(Y))return G.get(Y)??null;let X=z8(Q);return G.set(Y,X),X}};var L0=(G,Q,Y,J=G.mathAlignments,X=O0)=>{if(Q.chunkSpokenStart===null||Q.chunkSpokenEnd===null)return null;let j=null;for(let Z of J){let K=o6(Z.alignment,{position:Q.chunkSpokenStart,length:Math.max(1,Q.chunkSpokenEnd-Q.chunkSpokenStart),boundaryWord:Y.word})||a6(Z.alignment,{boundaryWord:Y.word});if(!K)continue;let W=X(K);if(!W)continue;if(W.quality==="semantic-token")return W;j??=W}return j};var N1=(G,Q,Y)=>{if(!G||typeof document>"u")return null;if(Y<=Q)return null;let J=G.get(Q),X=G.get(Math.max(Q,Y-1));if(!J)return null;if(!X)X=J;try{let j=document.createRange();return j.setStart(J.node,J.offset),j.setEnd(X.node,X.offset+1),j}catch{return null}};var $0=(G,Q)=>{if(!G.catalogAlignment||Q.chunkSpokenStart===null)return null;let Y=u6(G.catalogAlignment,Q.chunkSpokenStart);if(!Y)return null;let J=N1(G.visibleMap,Y.start,Y.end);if(!J)return null;return{type:"range",quality:G.catalogAlignment.playbackMode==="exact-word"?"exact-word":"semantic-token",range:J}};var nG=(G)=>G.regionRange?{type:"range",quality:"region",range:G.regionRange}:G.regionElement?{type:"element",quality:"region",element:G.regionElement}:null,w0=(G,Q=G.chunk.mathAlignments)=>{if(Q.length!==1)return null;let Y=Q[0]?.alignment.result.fallbackTarget;return Y?G.renderedMathTargetResolver(Y):null},rG=(G,Q)=>{if(!G)return Q.mathAlignments;return Q.mathAlignments.filter(({element:Y})=>{try{if(G.type==="range")return G.range.intersectsNode(Y);if(G.type==="element")return G.element===Y||G.element.contains(Y);return G.node.parentElement?.contains(Y)||!1}catch{return!1}})},R0=()=>({activeTarget:null,regionTarget:null,quality:"region",confidence:0,reason:"boundary chunk id was not found"}),E0=(G)=>G.length===1?G[0].element:null,oG=(G,Q)=>Q.length>0&&Q.every(({element:Y})=>G.mathCapabilityByElement.get(Y)==="token"),aG=3,tG=(G,Q,Y)=>{if(!Q||Q.type!=="range")return!1;let{startContainer:J,endContainer:X}=Q.range;if(J===X&&J.nodeType===aG)return!1;return Y.some(({element:Z})=>G.mathCapabilityByElement.get(Z)==="token"&&Z.contains(J)&&Z.contains(X))},eG=(G,Q)=>({chunk:G,regionTarget:nG(G),renderedMathTargetResolver:P0(),mathCapabilityByElement:new Map(G.mathAlignments.map(({element:Y})=>[Y,Q?z0(Y):"expression"])),heldTokenByElement:new Map}),b0=(G)=>{let Q=G.mathTokenHighlighting!==!1,Y=new Map(G.chunks.map((J)=>[J.id,eG(J,Q)]));return{chunks:G.chunks,resolveInitial(J){let X=Y.get(J);if(!X)return R0();let j=X.chunk.mathAlignments,Z=j.length===1?j[0].element:null,K=Z?X.mathCapabilityByElement.get(Z):null;if(K==="expression")return P7({semanticTarget:null,expressionTarget:w0(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:K==="token"?"initial region (sticky token mode, awaiting first token)":"initial region fallback"})},resolveBoundary(J){let X=Y.get(J.chunkId);if(!X)return R0();let{chunk:j}=X,Z=D0(j,J),K=$0(j,Z),W=rG(K,j),B=(!K||W.length>0?L0(j,Z,J,W,X.renderedMathTargetResolver):null)||null,U=Q&&B&&B.quality!=="expression"?B:null,V=B&&B.quality==="expression"?B:null;if(U){let H=E0(W);if(H)X.heldTokenByElement.set(H,U);return P7({semanticTarget:U,expressionTarget:null,regionTarget:X.regionTarget,confidence:Z.confidence,reason:Z.reason})}if(K&&(Q?!tG(X,K,W):W.length===0))return P7({semanticTarget:K,expressionTarget:null,regionTarget:X.regionTarget,confidence:Z.confidence,reason:Z.reason});if(oG(X,W)){let H=E0(W),N=H?X.heldTokenByElement.get(H)??null:null;return P7({semanticTarget:N,expressionTarget:null,regionTarget:X.regionTarget,confidence:Z.confidence,reason:N?"hold last token (sticky token mode)":"region (sticky token mode, awaiting first token)"})}return P7({semanticTarget:null,expressionTarget:V??w0(X,W),regionTarget:X.regionTarget,confidence:Z.confidence,reason:Z.reason})}}};var GQ=(G)=>{if(G.alignment?.boundaryOffsetMode)return G.alignment.boundaryOffsetMode;let Q=G.mathAlignment?.speech.boundaryOffsetSpace;if(Q)return Q;return"plain-spoken-text"},QQ=(G)=>{if(G.mathAlignments?.length)return G.mathAlignments;if(G.mathAlignment&&G.sourceElement)return[{element:G.sourceElement,alignment:G.mathAlignment}];return[]},T0=(G)=>{return(G.chunks&&G.chunks.length?G.chunks:[{speechText:G.speechText||"",visibleText:G.visibleText||G.speechText||"",sourceElement:G.sourceElement||G.contentRoot,regionElement:G.regionElement||G.sourceElement||G.contentRoot,regionRange:G.regionRange,visibleMap:G.visibleMap}]).map((Y,J)=>({id:`tts-chunk-${J}`,speechText:Y.speechText,visibleText:Y.visibleText,sourceElement:Y.sourceElement,contentRoot:G.contentRoot,regionElement:Y.regionElement??Y.sourceElement,regionRange:Y.regionRange,visibleMap:Y.visibleMap,catalogAlignment:Y.alignment,mathAlignments:QQ(Y),offsetSpace:GQ(Y)}))};var YQ=["[data-pie-tts-region]","[data-catalog-region]","li","p","label","section","[role='group']","[role='region']","div"].join(","),M1=(G,Q)=>{let Y=G.closest(YQ);if(Y&&Q.contains(Y))return Y;return G};var JQ=(G,Q,Y)=>{let J=new Map;for(let X=Q;X<Y;X++){let j=G.get(X);if(j)J.set(X-Q,j)}return J},O8=async(G)=>{let Q=z7(G.contentRoot,G.textProcessingOptions),Y=await H8({chunks:Q.chunks,visibleText:Q.visibleText,language:G.language,mathSpeech:G.mathSpeech,produceSsml:G.produceSsml,resolveMathSpeech:G.resolveMathSpeech});return{plan:{items:Y.segments.map(({segment:X,sourceChunkIndex:j})=>{let Z=Q.chunks[j];if(X.kind==="prose"){let W=Z?.type==="text"?Z.sourceElement??G.contentRoot:G.contentRoot;return{segment:X,anchor:{sourceElement:W,regionElement:M1(W,G.contentRoot),visibleMap:JQ(Q.map,X.visibleSpan.start,X.visibleSpan.end)}}}let K=Z?.type==="math"?Z.sourceElement??null:null;return{segment:X,anchor:{sourceElement:K,regionElement:K}}}),locale:Y.locale,visibleText:Y.visibleText,plainSpeechText:Y.plainSpeechText},containsMathMarkup:Q.containsMathMarkup,visibleText:Q.visibleText}};var XQ=(G,Q)=>{let Y=V1({speechText:G.spokenText,visibleText:G.spokenText});return{speechText:G.spokenText,visibleText:G.visibleText,sourceElement:Q.sourceElement,regionElement:Q.regionElement,regionRange:N1(Q.visibleMap,0,G.visibleText.length)??void 0,speechMatchesVisibleText:!0,playbackMode:Y.playbackMode,alignment:Y,visibleMap:Q.visibleMap}},C0=(G,Q)=>{let Y=Q.sourceElement;return{speechText:G.spokenText,visibleText:G.fallbackText,sourceElement:Y,regionElement:Q.regionElement,speechMatchesVisibleText:G.spokenText===G.fallbackText,mathAlignment:Y?S7({mathElement:Y,speechText:G.spokenText}):void 0}},ZQ=(G,Q,Y)=>{let J=Q.sourceElement;return{speechText:Y,visibleText:G.fallbackText,sourceElement:J,regionElement:Q.regionElement,speechMatchesVisibleText:!1,mathAlignment:J?S7({mathElement:J,speechText:Y}):void 0,plainFallback:C0(G,Q)}},P8=(G,Q={})=>G.items.map(({segment:Y,anchor:J})=>{if(Y.kind==="prose")return XQ(Y,J);if(Q.format==="ssml"&&Y.ssml)return ZQ(Y,J,Y.ssml);return C0(Y,J)});var S0="pie-tts-control-handoff";var R;(function(G){G.IDLE="idle",G.LOADING="loading",G.PLAYING="playing",G.PAUSED="paused",G.ERROR="error"})(R||(R={}));var y0=(G,Q)=>G===Q||G.startContainer===Q.startContainer&&G.startOffset===Q.startOffset&&G.endContainer===Q.endContainer&&G.endOffset===Q.endOffset,jQ=(G,Q)=>{if(G===Q)return!0;if(!G||!Q||G.type!==Q.type||G.quality!==Q.quality)return!1;if(G.type==="range"&&Q.type==="range")return y0(G.range,Q.range);if(G.type==="element"&&Q.type==="element")return G.element===Q.element;if(G.type==="text-range"&&Q.type==="text-range")return G.node===Q.node&&G.startOffset===Q.startOffset&&G.endOffset===Q.endOffset;return!1};class p7{currentProvider=null;provider=null;highlightCoordinator=null;highlightTargetResolverProvider=null;catalogResolver=null;state=R.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=[];currentSeekSegmentIndex=0;activeSentenceStartOffset=null;playbackStartDeferredRunId=null;pendingPlaybackStartHighlights=[];playbackStartBarrierCleanup=null;playbackRateWriteQueue=Promise.resolve();playbackRateRequestId=0;pendingPlaybackRateRequest=null;activePlaybackRate=null;activeHighlightMode="word";lastRenderedRegionTarget=null;telemetryReporter=null;generatedMathSpeechResolver=F8();static debugEnabled=(()=>{try{if(typeof process<"u"&&process.env?.PIE_TTS_DEBUG==="1")return!0}catch{}return globalThis.__PIE_TTS_DEBUG__===!0})();constructor(){}debugLog(G,Q){if(!p7.debugEnabled)return;if(Q===void 0)console.debug(G);else console.debug(G,Q)}clearPlaybackStartBarrier(G=this.playbackStartBarrierCleanup){if(G?.(),this.playbackStartBarrierCleanup===G)this.playbackStartBarrierCleanup=null}notifyPlaybackStarted(G){if(this.playbackStartDeferredRunId!==G||G!==this.speakRunId)return;this.setState(R.PLAYING);let Q=this.pendingPlaybackStartHighlights.splice(0);for(let Y of Q)Y()}installPlaybackStartBarrier(G,Q=!1){this.clearPlaybackStartBarrier();let Y=this.provider,J=Y&&"onPlaybackStart"in Y?Y:null;if(!J&&!Q)return null;let X=J?.onPlaybackStart,j=()=>{try{this.notifyPlaybackStarted(G)}finally{X?.()}};if(J)J.onPlaybackStart=j;this.playbackStartDeferredRunId=G;let Z=()=>{if(J?.onPlaybackStart===j)J.onPlaybackStart=X;if(this.playbackStartDeferredRunId===G)this.playbackStartDeferredRunId=null,this.pendingPlaybackStartHighlights=[]};return this.playbackStartBarrierCleanup=Z,Z}runWhenPlaybackStarts(G,Q){if(this.playbackStartDeferredRunId===G){this.pendingPlaybackStartHighlights.push(Q);return}Q()}async emitTelemetry(G,Q){try{await this.telemetryReporter?.(G,Q)}catch(Y){console.warn("[TTSService] telemetry callback failed:",Y)}}async initialize(G,Q={}){this.currentProvider=G,this.ttsConfig={...Q};let Y=Q.providerOptions&&typeof Q.providerOptions==="object"?Q.providerOptions:{};this.telemetryReporter=typeof Y.__pieTelemetry==="function"?Y.__pieTelemetry:null;try{this.provider=await G.initialize(Q)}catch(J){if(G.providerId.toLowerCase()==="browser")throw J;if(!this.isBrowserSpeechFallbackAvailable())throw J;if(!await this.switchProviderToBrowser(J,{operation:"tts-initialize"}))throw J}}async updateSettings(G){if(!this.provider)throw Error("TTSService not initialized. Call initialize() first.");let Q=this.provider;if(typeof Q.updateSettings==="function"){let Y={...G,...G.providerOptions?{providerOptions:{...this.ttsConfig.providerOptions||{},...G.providerOptions}}:{}};await Q.updateSettings(Y),this.ttsConfig={...this.ttsConfig,...Y}}else console.warn("[TTSService] Provider does not support dynamic settings updates. Some settings may require reinitialization.")}setHighlightCoordinator(G){this.highlightCoordinator=G}setHighlightTargetResolverProvider(G){return this.highlightTargetResolverProvider=G,()=>{if(this.highlightTargetResolverProvider===G)this.highlightTargetResolverProvider=null}}setCatalogResolver(G){this.catalogResolver=G}hasSpokenAlternate(G,Q="en-US"){if(!G||!this.catalogResolver)return!1;return this.catalogResolver.getAlternative(G,{type:"spoken",language:Q,useFallback:!0,form:"content"})?.content!==void 0}getHighlightResolverRuntime(){let G=null;try{G=this.highlightTargetResolverProvider?.()??null}catch{G=null}let Q=G?.context??{},Y=typeof HTMLElement<"u"&&this.currentContentElement instanceof HTMLElement?this.currentContentElement:null;return{context:{...Q,scopeElement:Q.scopeElement??Y},resolver:G?.resolver??null}}getNodeElement(G){if(!G)return null;return G.nodeType===Node.ELEMENT_NODE?G:G.parentElement}isElementWithinScope(G,Q){if(!Q)return!0;return G===Q||Q.contains(G)}isRangeWithinScope(G,Q){let Y=this.getNodeElement(G.startContainer),J=this.getNodeElement(G.endContainer);if(!Y||!J)return!1;return this.isElementWithinScope(Y,Q)&&this.isElementWithinScope(J,Q)}resolveWordHighlightRange(G){let{context:Q,resolver:Y}=this.getHighlightResolverRuntime(),J=Q.scopeElement??this.currentContentElement;try{let X=Y?.resolveWordRange?.(G,Q);if(X&&this.isRangeWithinScope(X,J))return{range:X,remapped:!y0(G,X)}}catch{}return{range:G,remapped:!1}}resolveSentenceHighlightTargets(G){let{context:Q,resolver:Y}=this.getHighlightResolverRuntime(),J=Q.scopeElement??this.currentContentElement;try{let X=Y?.resolveSentenceRanges?.(G,Q);if(!X)return{ranges:G,elements:[]};let j=[],Z=[];for(let K of X){if(typeof Range<"u"&&K instanceof Range){if(!this.isRangeWithinScope(K,J))return{ranges:G,elements:[]};j.push(K);continue}if(typeof Element<"u"&&K instanceof Element){if(!this.isElementWithinScope(K,J))return{ranges:G,elements:[]};Z.push(K);continue}return{ranges:G,elements:[]}}return{ranges:j,elements:Z}}catch{return{ranges:G,elements:[]}}}createTextRange(G,Q,Y){if(typeof document>"u")return null;if(typeof document.createRange!=="function")return null;try{let J=document.createRange();if(J.setStart(G,Q),J.setEnd(G,Y),J.startContainer!==G||J.endContainer!==G)return null;return J}catch{return null}}paintTTSWordRange(G){if(!this.highlightCoordinator)return;try{if(G.startContainer===G.endContainer&&G.startContainer.nodeType===Node.TEXT_NODE){this.highlightCoordinator.highlightTTSWord(G.startContainer,G.startOffset,G.endOffset);return}}catch{}this.highlightCoordinator.highlightRange(G,u.TTS_WORD,_7.YELLOW)}paintTTSSentenceRanges(G){if(!this.highlightCoordinator)return;let{ranges:Q,elements:Y}=this.resolveSentenceHighlightTargets(G);if(Y.length>0&&Q.length===0&&this.highlightCoordinator.highlightTTSSentenceElements){this.highlightCoordinator.highlightTTSSentenceElements(Y);return}let J=[...Q];for(let X of Y){let j=document.createRange();j.selectNodeContents(X),J.push(j)}this.highlightCoordinator.highlightTTSSentence(J)}getCapabilities(){return this.currentProvider?.getCapabilities()||null}getTextProcessingOptions(G){let Y=(this.ttsConfig.providerOptions||{}).textNormalization||{},J=Y.boundarySpacingMode,X=J==="none"||J==="alnum"||J==="segmenterPreferred"?J:void 0;return{locale:G||(typeof Y.locale==="string"?Y.locale:void 0),boundarySpacingMode:X}}getMathSpeechOptions(){let Q=(this.ttsConfig.providerOptions||{}).mathSpeech;return O7(Q)}buildPositionMap(G,Q,Y){this.normalizedToDOM.clear();let{text:J,map:X}=T7(G,this.getTextProcessingOptions(Y));if(this.normalizedToDOM=X,!p7.debugEnabled)return;this.debugLog("[TTSService] Text comparison:",{spokenLength:Q.length,normalizedDomLength:J.length,match:Q===J,spokenPreview:Q.substring(0,150),normalizedPreview:J.substring(0,150),differAtIndex:Q===J?null:(()=>{for(let j=0;j<Math.min(Q.length,J.length);j++)if(Q[j]!==J[j])return{index:j,spokenChar:Q[j],normalizedChar:J[j],spokenContext:Q.substring(Math.max(0,j-20),j+20),normalizedContext:J.substring(Math.max(0,j-20),j+20)};return null})()}),this.debugLog("[TTSService] Position map built:",{entries:this.normalizedToDOM.size,spokenTextLength:Q.length,normalizedDomLength:J.length,mapLengthMatchesSpoken:this.normalizedToDOM.size===Q.length,firstFewMappings:Array.from(this.normalizedToDOM.entries()).slice(0,10).map(([j,{node:Z,offset:K}])=>({pos:j,offset:K,char:Z.textContent?.[K],expected:Q[j]}))})}getStructuralPauseProfile(){let Q=(this.ttsConfig.providerOptions||{}).structuralPauses||{},Y=Q.units||{},J=(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:J(Q.baseMs,280),units:{minor:J(Y.minor,0.65),section:J(Y.section,1),major:J(Y.major,1.35)},minMs:J(Q.minMs,120),maxMs:J(Q.maxMs,900)}}resolvePauseMsFromUnits(G){let Q=this.getStructuralPauseProfile(),Y=Math.max(0.25,Math.min(4,Number(this.ttsConfig.rate||1))),J=Q.baseMs*Math.max(0,G)/Y;return Math.max(Q.minMs,Math.min(Q.maxMs,Math.round(J)))}resolveHighlightMode(){let Q=(this.ttsConfig.providerOptions||{}).highlightMode;if(Q==="word"||Q==="sentence")return Q;if((this.currentProvider?.providerId||"").toLowerCase()==="browser")return"sentence";return this.currentProvider?.getCapabilities().supportsWordBoundary??!1?"word":"sentence"}hasExplicitBreakSemantics(G){if(!G.includes("<"))return!1;return/<\s*break\b|<\s*speak\b|<\s*prosody\b|<\s*p\b|<\s*s\b/i.test(G)}isElementHidden(G){return J8(G)}getBoundaryStrength(G){let Q=Number(G.getAttribute("data-tts-break-ms"));if(Number.isFinite(Q)&&Q>0)return"major";let Y=G.tagName.toUpperCase();if(Y.match(/^H[1-6]$/))return"major";let J=(G.getAttribute("role")||"").toLowerCase();if(J==="heading")return"major";if(J==="listitem"||J==="row"||J==="option"||J==="radio"||Y==="LI")return"section";if(typeof window<"u"){let X=window.getComputedStyle(G).display;if(X==="block"||X==="list-item"||X.startsWith("table")||X==="flex"||X==="grid")return"minor"}return"minor"}getBoundaryAnchor(G,Q){let Y=G.parentElement,J=null;while(Y&&Y!==Q){if(this.isElementHidden(Y))return null;let j=Number(Y.getAttribute("data-tts-break-ms"));if(Number.isFinite(j)&&j>0)return{anchor:Y,units:j/this.getStructuralPauseProfile().baseMs};let Z=(Y.getAttribute("role")||"").toLowerCase(),K=Y.tagName.toUpperCase();if(K.match(/^H[1-6]$/)||Z==="heading"||Z==="listitem"||K==="LI"){J=Y;break}if(!J){if(typeof window<"u"){let W=window.getComputedStyle(Y).display;if(W==="block"||W==="list-item"||W.startsWith("table")||W==="flex"||W==="grid")J=Y}}Y=Y.parentElement}if(!J)return null;let X=this.getBoundaryStrength(J);return{anchor:J,units:this.getStructuralPauseProfile().units[X]}}createSpeechPlan(G,Q){let Y=this.collectSpeechPlanBoundaries(G,Q);return this.createSpeechPlanSegments(Q,Y)}collectSpeechPlanBoundaries(G,Q){let Y=new Map,{map:J}=T7(G,this.getTextProcessingOptions()),X=this.createNodeStartOffsets(J),j=document.createTreeWalker(G,NodeFilter.SHOW_TEXT),Z=j.nextNode(),K=null;while(Z){let W=Z,B=W.parentElement;if(B&&!this.isElementHidden(B)&&!B1(W)){let U=this.getBoundaryAnchor(W,G),V=X.get(W);if(U&&V!==void 0&&U.anchor!==K&&V>0)Y.set(V,Math.max(Y.get(V)||0,U.units)),K=U.anchor}Z=j.nextNode()}return Y}createNodeStartOffsets(G){let Q=new Map;for(let[Y,J]of G.entries())if(!Q.has(J.node))Q.set(J.node,Y);return Q}createSpeechPlanSegments(G,Q){let Y=Array.from(Q.keys()).filter((W)=>W>0&&W<G.length).sort((W,B)=>W-B),J=[],X=0;for(let W of Y){let B=G.substring(X,W),U=B.match(/^\s*/)?.[0].length||0,V=B.match(/\s*$/)?.[0].length||0,H=X+U,N=W-V;if(N>H){let M=G.substring(H,N);J.push({text:M,startOffset:H,pauseMsAfter:this.resolvePauseMsFromUnits(Q.get(W)||0)})}X=W}let Z=G.substring(X).match(/^\s*/)?.[0].length||0,K=X+Z;if(K<G.length)J.push({text:G.substring(K).trimEnd(),startOffset:K,pauseMsAfter:0});return J.filter((W)=>W.text.trim().length>0)}segmentSentences(G){let Q=this.ttsConfig.providerOptions?.locale||void 0;return E7(G,{locale:Q})}createSeekSegmentsFromText(G){return this.segmentSentences(G).map((Q)=>{let Y=Q.text.match(/^\s*/)?.[0].length||0;return{text:Q.text.trim(),startOffset:Q.offset+Y,pauseMsAfter:0}}).filter((Q)=>Q.text.length>0)}splitSegmentsAtBoundaries(G,Q,Y){if(G.length===0||Q.length===0)return G;let J=Array.from(new Set(Q)).filter((j)=>Number.isFinite(j)&&j>0).sort((j,Z)=>j-Z);if(J.length===0)return G;let X=[];for(let j of G){let Z=j.startOffset,K=j.startOffset+j.text.length,W=J.filter((U)=>U>Z&&U<K);if(W.length===0){X.push(j);continue}let B=Z;for(let U of[...W,K]){let V=Y.substring(B,U),H=V.match(/^\s*/)?.[0].length||0,N=V.match(/\s*$/)?.[0].length||0,M=B+H,P=U-N;if(P>M)X.push({text:Y.substring(M,P),startOffset:M,pauseMsAfter:0});B=U}}return X}createSentenceHighlightSegments(G){let Q=this.createSeekSegmentsFromText(G.contentToSpeak);if(!G.shouldUsePlan||G.playbackSegments.length===0)return Q;let Y=G.playbackSegments.map((J)=>J.startOffset).filter((J)=>J>0);return this.splitSegmentsAtBoundaries(Q,Y,G.contentToSpeak)}createSeekSegmentsFromSpeechChunks(G){let Q=0;return G.map((Y)=>{let J=Y.plainFallback?.speechText||(this.hasExplicitBreakSemantics(Y.speechText)?Y.visibleText:Y.speechText)||Y.visibleText,X=C(J)||Y.visibleText||"",j={text:X,startOffset:Q,pauseMsAfter:0};return Q+=Math.max(1,X.length+1),j})}getCurrentSeekSegmentIndex(){if(this.seekSegments.length===0)return 0;let G=0;for(let Q=0;Q<this.seekSegments.length;Q++)if(this.seekSegments[Q].startOffset<=this.currentBoundaryOffset)G=Q;else break;return G}async speakWithPlan(G,Q,Y){if(!this.provider||G.length===0)return;let J=Y?.highlightMode==="sentence",X=this.provider;if(!J&&typeof X.speakSegments==="function"){this.currentBoundaryOffset=0;let j=this.provider.onWordBoundary;this.provider.onWordBoundary=(Z,K,W)=>{if(j?.(Z,K,W),Number.isFinite(K))this.currentBoundaryOffset=K,this.currentSeekSegmentIndex=this.getCurrentSeekSegmentIndex()};try{await X.speakSegments(G)}finally{if(Q===this.speakRunId&&this.provider===X)this.provider.onWordBoundary=j}return}this.configureWordBoundaryHighlighting({highlightMode:Y?.highlightMode||"word",wordBoundaryOffset:this.activeWordBoundaryOffset});for(let j of G){if(Q!==this.speakRunId)return;let Z=this.seekSegments.findIndex((W)=>W.startOffset===j.startOffset);if(Z>=0)this.currentSeekSegmentIndex=Z;if(this.currentBoundaryOffset=j.startOffset,J)this.runWhenPlaybackStarts(Q,()=>{this.highlightSentenceSegment(j.startOffset,j.text)});await this.provider.speak(j.text);let K=j.pauseMsAfter??0;if(K>0)await new Promise((W)=>setTimeout(W,K))}}highlightSentenceSegment(G,Q){if(!this.highlightCoordinator||typeof document>"u")return;let Y=Q.trimEnd().length;if(Y<=0)return;let J=this.normalizedToDOM.get(G),X=this.normalizedToDOM.get(G+Y-1);if(!J||!X)return;let j=document.createRange();j.setStart(J.node,J.offset),j.setEnd(X.node,X.offset+1),this.paintTTSSentenceRanges([j]),this.activeSentenceStartOffset=G}getSegmentIndexForOffset(G,Q){if(G.length===0)return-1;let Y=-1;for(let J=0;J<G.length;J++)if(G[J].startOffset<=Q)Y=J;else break;return Y}highlightSentenceForOffset(G){let Q=this.sentenceHighlightSegments;if(!this.highlightCoordinator||Q.length===0)return;let Y=this.getSegmentIndexForOffset(Q,G);if(Y<0)return;let J=Q[Y];if(!J)return;if(this.activeSentenceStartOffset===J.startOffset)return;this.highlightSentenceSegment(J.startOffset,J.text)}findHighlightRange(G,Q){let Y=this.normalizedToDOM.get(G);if(!Y)return console.warn(`[TTSService] No mapping found for start position ${G}`,{totalMappings:this.normalizedToDOM.size,nearbyMappings:Array.from(this.normalizedToDOM.entries()).filter(([j])=>Math.abs(j-G)<5).map(([j,{offset:Z,node:K}])=>({pos:j,offset:Z,char:K.textContent?.[Z]}))}),null;let J=G+Q-1,X=this.normalizedToDOM.get(J);if(!X)return console.warn(`[TTSService] No mapping found for end position ${J}`,{startChar:G,length:Q,totalMappings:this.normalizedToDOM.size}),null;if(Y.node!==X.node)return console.warn("[TTSService] Word spans multiple nodes, highlighting in first node only"),{node:Y.node,start:Y.offset,end:(Y.node.textContent||"").length};return{node:Y.node,start:Y.offset,end:X.offset+1}}async speak(G,Q){if(!this.provider)throw Error("TTS service not initialized");let Y=++this.speakRunId;this.clearPlaybackStartBarrier();let J=null;try{if(await this.applyLanguageSettings(Q),Y!==this.speakRunId)return;let X=await this.resolveSpeechContent(G,Q);if(Y!==this.speakRunId)return;let{contentToSpeak:j,speechText:Z,highlightText:K,normalizedText:W,usedCatalogSpoken:B,speechSource:U,speechMatchesVisibleText:V,speechChunks:H}=X;this.logResolvedSpeechContent({contentToSpeak:j,speechSource:U,catalogId:Q?.catalogId}),this.initializeSpeakTracking(K,Q);let N=Q?.highlightModeOverride||(V?this.resolveHighlightMode():"sentence");this.activeHighlightMode=N,this.activeWordBoundaryOffset=Q?.wordBoundaryOffset||0;let M=this.hasExplicitBreakSemantics(j),P=!!this.currentContentElement&&!B&&!M&&V;if(this.playbackChunks=H?.length?H:[],this.seekSegments=this.playbackChunks.length?this.createSeekSegmentsFromSpeechChunks(this.playbackChunks):M||!V?[]:P&&this.currentContentElement?this.createSpeechPlan(this.currentContentElement,W):this.createSeekSegmentsFromText(K),this.sentenceHighlightSegments=M?[]:this.createSentenceHighlightSegments({contentToSpeak:K,shouldUsePlan:P,playbackSegments:this.seekSegments}),this.setState(R.LOADING),J=this.installPlaybackStartBarrier(Y,!!this.playbackChunks[0]?.audio),this.prepareHighlightsForSpeak({contentToSpeak:K,options:Q,highlightMode:N,shouldUsePlan:P,runId:Y}),V)this.configureWordBoundaryHighlighting({highlightMode:N,wordBoundaryOffset:Q?.wordBoundaryOffset||0});else this.clearWordBoundaryHighlighting();if(!J)this.setState(R.PLAYING);if(this.activePlaybackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1)),await this.executeSpeakPlayback({shouldUsePlan:P,runId:Y,highlightMode:N,contentToSpeak:Z,speechChunks:H}),Y!==this.speakRunId)return;this.setState(R.IDLE),this.clearHighlightsAndTracking()}catch(X){let j=X;if(console.error("TTS error:",j),this.lastError=j instanceof Error?j.message:String(j),Y!==this.speakRunId)return;throw this.setState(R.ERROR),this.clearHighlightsAndTracking(),j}finally{this.clearPlaybackStartBarrier(J)}}async switchProviderToBrowser(G,Q){if(!this.currentProvider)return!1;let Y=new b7,J=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=Q?.operation||"tts-initialize",Z=Q?.contentToSpeak??"",K=Z.replace(/\s+/g," ").trim().slice(0,120),W=Z.length>0?{textLength:Z.length,textPreview:K.length<Z.length?`${K}…`:K}:{};try{return this.provider?.stop(),this.currentProvider.destroy(),this.currentProvider=Y,this.provider=await Y.initialize(X),this.ttsConfig=X,await this.emitTelemetry("pie-tool-runtime-fallback",{toolId:"textToSpeech",operation:j,fromProvider:J,toProvider:Y.providerId,reason:G instanceof Error?G.message:String(G),...W}),console.warn("[TTSService] TTS provider initialization failed; switched to browser fallback",{fromProvider:J,reason:G,...W}),!0}catch(B){return await this.emitTelemetry("pie-tool-runtime-fallback-error",{toolId:"textToSpeech",operation:j,fromProvider:J,toProvider:"browser",errorType:"TTSRuntimeFallbackError",message:B instanceof Error?B.message:String(B)}),console.error("[TTSService] Failed to switch to browser fallback provider",B),!1}}isBrowserSpeechFallbackAvailable(){if(typeof window>"u")return!1;if(!("speechSynthesis"in window))return!1;return typeof globalThis.SpeechSynthesisUtterance==="function"}async applyLanguageSettings(G){if(!G?.language||!this.provider)return;let Q=this.ttsConfig.providerOptions||{},Y=Q.textNormalization||{},J=Q.segmenter||{},X={...Q,locale:G.language,textNormalization:{...Y,locale:G.language},segmenter:{...J,locale:G.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(G,Q){let Y=C(G);if(Q?.ignoreCatalogs)return{contentToSpeak:Y,speechText:Y,visibleText:Y,highlightText:Y,usedCatalogSpoken:!1,speechSource:"dom-or-input",normalizedText:Y,containsMathMarkup:!1,speechMatchesVisibleText:!0};if(Q?.catalogId&&this.catalogResolver){let j=this.catalogResolver.getAlternative(Q.catalogId,{type:"spoken",language:Q.language||"en-US",useFallback:!0,context:Q.catalogContext,form:"content"}),Z=j?.content;if(j&&Z!==void 0){let K=Q?.contentElement?z7(Q.contentElement,this.getTextProcessingOptions(Q.language)).visibleText||Y:Y,W=C(Z);return this.debugLog(`[TTSService] Using catalog content for "${Q.catalogId}" (${j.language})`),{contentToSpeak:Z,speechText:Z,visibleText:K,highlightText:K,usedCatalogSpoken:!0,speechSource:"catalog-spoken",normalizedText:K,containsMathMarkup:!1,speechMatchesVisibleText:W===K}}this.debugLog(`[TTSService] No catalog found for "${Q.catalogId}", falling back to generated TTS`)}let J=Q?.contentElement?this.resolveCatalogComposedSpeechContent(Q.contentElement,Y,Q):null;if(J)return J;return{...Q?.contentElement?await this.resolveGeneratedSpeechContent(Q.contentElement,Y,Q.language):{contentToSpeak:Y,speechText:Y,visibleText:Y,highlightText:Y,normalizedText:Y,containsMathMarkup:!1,speechMatchesVisibleText:!0},usedCatalogSpoken:!1,speechSource:"dom-or-input"}}resolveCatalogComposedSpeechContent(G,Q,Y){if(!this.catalogResolver)return null;let J=this.collectCatalogSpeechChunks(G,Y);if(!J.some((Z)=>Z.sourceElement))return null;let X=C(J.map((Z)=>Z.speechText).join(" ")),j=z7(G,this.getTextProcessingOptions(Y.language)).visibleText||Q;return{contentToSpeak:X,speechText:X,visibleText:j,highlightText:j,usedCatalogSpoken:!0,speechSource:"catalog-spoken",normalizedText:j,containsMathMarkup:!1,speechMatchesVisibleText:J.every((Z)=>Z.speechMatchesVisibleText),speechChunks:J}}collectCatalogSpeechChunks(G,Q){let Y=[],J="",X=()=>{let B=C(J);if(J="",!B)return;Y.push({speechText:B,visibleText:B,sourceElement:null,speechMatchesVisibleText:!0})},j=(B)=>{let U=B.getAttribute("data-catalog-idref");if(!U)return null;let V={type:"spoken",language:Q.language||"en-US",useFallback:!0,context:Q.catalogContext},H=this.catalogResolver.getAlternative(U,{...V,form:"payload"}),N=H?.payload?P6({payload:H.payload})??void 0:void 0,P=this.catalogResolver.getAlternative(U,{...V,form:"content"})?.content;if(N===void 0&&P===void 0)return null;return{script:P,audio:N}},Z=(B,U)=>{let V=K(B);if(V.length!==1)return null;let H=V[0],N=z7(H,this.getTextProcessingOptions(Q.language)).visibleText||C(H.textContent||""),M=(P)=>C(P).replace(/\s+/g,"");return M(N)===M(U)?H:null},K=(B)=>{let U=Array.from(B.querySelectorAll("math"));if(B.localName?.toLowerCase()==="math")return[B,...U];return U},W=(B)=>{if(V7(B,G))return;if(B.nodeType===Node.TEXT_NODE){J+=` ${B.textContent||""}`;return}if(B.nodeType!==Node.ELEMENT_NODE)return;let U=B,V=j(U);if(V){X();let H=z7(U,this.getTextProcessingOptions(Q.language)),N=H.visibleText||C(U.textContent||""),M=M1(U,G),P=V.script!==void 0?(()=>{let $=V.script,A=V1({speechText:$,visibleText:N}),L=Z(U,N),T=L?S7({mathElement:L,speechText:$}):void 0,v=T?void 0:K(U).map((I)=>({element:I,alignment:S7({mathElement:I,speechText:$})}));return{speechText:$,visibleText:N,sourceElement:U,regionElement:M,speechMatchesVisibleText:C($)===N,playbackMode:A.playbackMode,alignment:A,mathAlignment:T,mathAlignments:v,visibleMap:H.map}})():null;if(V.audio){Y.push(P?{...P,audio:V.audio,plainFallback:P}:{speechText:N,visibleText:N,sourceElement:U,regionElement:M,speechMatchesVisibleText:!1,visibleMap:H.map,audio:V.audio});return}if(P)Y.push(P);return}for(let H of Array.from(U.childNodes))W(H)};return W(G),X(),Y}resolveGeneratedPlaybackFormat(){let G=this.currentProvider;if(!G)return"plain";if(G.providerId?.toLowerCase()==="browser")return"plain";return G.getCapabilities?.().supportsSSML?"ssml":"plain"}async resolveGeneratedSpeechContent(G,Q,Y){let J=this.resolveGeneratedPlaybackFormat(),{plan:X,containsMathMarkup:j,visibleText:Z}=await O8({contentRoot:G,language:Y,mathSpeech:this.getMathSpeechOptions(),textProcessingOptions:this.getTextProcessingOptions(Y),produceSsml:J==="ssml",resolveMathSpeech:this.generatedMathSpeechResolver}),K=Z||Q;if(!j)return{contentToSpeak:K,speechText:K,visibleText:K,highlightText:K,normalizedText:K,containsMathMarkup:!1,speechMatchesVisibleText:!0};let W=P8(X,{format:J}),B=X.plainSpeechText;return{contentToSpeak:B,speechText:B,visibleText:K,highlightText:K,normalizedText:K,containsMathMarkup:!0,speechMatchesVisibleText:B===K,speechChunks:W}}logResolvedSpeechContent(G){let Q=G.contentToSpeak.replace(/\s+/g," ").trim().slice(0,200);this.debugLog("[TTSService] Speak resolved content",{source:G.speechSource,catalogId:G.catalogId||null,length:G.contentToSpeak.length,preview:Q})}initializeSpeakTracking(G,Q){this.currentText=G,this.currentContentElement=Q?.contentElement||null,this.lastError=null,this.currentBoundaryOffset=0,this.playbackChunks=[],this.currentSeekSegmentIndex=0,this.activeSentenceStartOffset=null}prepareHighlightsForSpeak(G){if(!this.currentContentElement||!this.highlightCoordinator)return;if(this.buildPositionMap(this.currentContentElement,G.contentToSpeak,G.options?.language),G.highlightMode==="sentence"&&G.shouldUsePlan)return;let Q=this.sentenceHighlightSegments[0]||this.seekSegments[0];this.runWhenPlaybackStarts(G.runId,()=>{if(Q)this.highlightSentenceSegment(Q.startOffset,Q.text),this.debugLog("[TTSService] Applied initial sentence highlighting");else try{let Y=document.createRange();Y.selectNodeContents(this.currentContentElement),this.paintTTSSentenceRanges([Y])}catch{}})}configureWordBoundaryHighlighting(G){if(!this.provider||G.highlightMode!=="word"||!this.highlightCoordinator||!this.currentContentElement)return;this.provider.onWordBoundary=(Q,Y,J)=>{let X=J||Q.length,j=Y+this.currentBoundaryOffset+G.wordBoundaryOffset;this.highlightSentenceForOffset(j);let Z=this.findHighlightRange(j,X);if(Z&&this.highlightCoordinator){let K=Z.node.textContent?.substring(Z.start,Z.end)||"";this.debugLog(`[TTSService] Highlighting "${K}" (word: "${Q}") at position ${j}`);let W=this.createTextRange(Z.node,Z.start,Z.end);if(W)this.paintTTSWordRange(this.resolveWordHighlightRange(W).range);else this.highlightCoordinator.highlightTTSWord(Z.node,Z.start,Z.end)}else console.warn(`[TTSService] Could not find highlight range for position ${j}, length ${X}`)}}clearWordBoundaryHighlighting(){if(this.provider)this.provider.onWordBoundary=void 0}highlightCatalogRegion(G){let Q=G.regionElement||G.sourceElement;if(!Q&&!G.regionRange||!this.highlightCoordinator)return;try{if(this.lastRenderedRegionTarget=null,G.regionRange){this.highlightCoordinator.clearHighlights?.(u.TTS_WORD),this.paintTTSSentenceRanges([G.regionRange]);return}if(!Q)return;let Y=document.createRange();Y.selectNodeContents(Q),this.highlightCoordinator.clearHighlights?.(u.TTS_WORD),this.paintTTSSentenceRanges([Y])}catch{}}highlightCatalogActiveRange(G){if(!this.highlightCoordinator)return;this.paintTTSWordRange(this.resolveWordHighlightRange(G).range)}highlightRenderableRegionTarget(G){if(!this.highlightCoordinator||!G||typeof document>"u")return;if(!this.highlightTargetResolverProvider&&jQ(this.lastRenderedRegionTarget,G))return;try{let Q=document.createRange();if(G.type==="element")Q.selectNodeContents(G.element);else if(G.type==="range"){this.paintTTSSentenceRanges([G.range]),this.lastRenderedRegionTarget=G;return}else Q.setStart(G.node,G.startOffset),Q.setEnd(G.node,G.endOffset);this.paintTTSSentenceRanges([Q]),this.lastRenderedRegionTarget=G}catch{}}highlightRenderableActiveTarget(G){if(!this.highlightCoordinator||typeof document>"u")return;if(!G){this.highlightCoordinator.clearHighlights(u.TTS_WORD);return}if(G.type==="text-range"){let X=this.createTextRange(G.node,G.startOffset,G.endOffset);if(X)this.paintTTSWordRange(this.resolveWordHighlightRange(X).range);else this.highlightCoordinator.highlightTTSWord(G.node,G.startOffset,G.endOffset);return}if(G.type==="range"){this.highlightCatalogActiveRange(G.range);return}let Q=document.createRange();Q.selectNodeContents(G.element);let Y=this.resolveWordHighlightRange(Q);if(Y.remapped){this.paintTTSWordRange(Y.range);return}let J=G.element.childNodes.length===1?G.element.firstChild:null;if(G.quality==="semantic-token"&&J?.nodeType===Node.TEXT_NODE){this.highlightCoordinator.highlightTTSWord(J,0,J.textContent?.length||0);return}this.highlightCoordinator.highlightTTSWordElement?.(G.element)}renderHighlightDecision(G){this.highlightRenderableRegionTarget(G.regionTarget),this.highlightRenderableActiveTarget(G.activeTarget)}async speakCatalogChunk(G,Q){try{await this.speakCatalogChunkOnce(G,Q)}catch(Y){if(G.plainFallback&&Q===this.speakRunId){if(this.debugLog("[TTSService] SSML chunk speak failed; retrying plain text",{message:Y instanceof Error?Y.message:String(Y)}),this.playbackStartDeferredRunId===Q&&this.provider&&!("onPlaybackStart"in this.provider))this.pendingPlaybackStartHighlights=[],this.clearPlaybackStartBarrier(),this.setState(R.PLAYING);await this.speakCatalogChunkOnce(G.plainFallback,Q);return}throw Y}}async playRecordedAudio(G,Q){if(typeof document>"u")throw Error("[tts] no document available to play recorded audio");let Y=G.sources[0],J=document.createElement("audio");J.preload="auto",J.src=O6(Y.src,G.fragment),J.playbackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate||1)),await new Promise((X,j)=>{let Z,K=!1,W=!1,B=()=>{if(W||K)return;K=!0,Q?.()},U=()=>{if(J.removeEventListener("ended",V),J.removeEventListener("error",H),J.removeEventListener("playing",B),Z?.(),this.activeRecordedAudio?.element===J)this.activeRecordedAudio=null},V=()=>{if(W)return;W=!0,U(),X()},H=()=>{if(W)return;W=!0,U(),j(Error(`[tts] recorded audio failed to play: ${Y.src}`))};this.activeRecordedAudio={element:J,cancel:()=>{if(W)return;W=!0,U(),J.pause(),X()}},J.addEventListener("ended",V),J.addEventListener("error",H),J.addEventListener("playing",B),Z=z6(J,G.fragment,V),Promise.resolve(J.play()).then(B).catch(H)}).finally(()=>{if(this.activeRecordedAudio?.element===J)this.activeRecordedAudio=null;J.pause(),J.removeAttribute("src")})}cancelRecordedAudio(){let G=this.activeRecordedAudio;if(!G)return;this.activeRecordedAudio=null,G.cancel()}async speakCatalogChunkOnce(G,Q){if(!this.provider)return;if(this.lastRenderedRegionTarget=null,G.audio){this.runWhenPlaybackStarts(Q,()=>{this.highlightCatalogRegion(G)}),await this.playRecordedAudio(G.audio,()=>{this.notifyPlaybackStarted(Q)});return}let Y=G.regionElement||G.sourceElement||this.currentContentElement,J=Y?T0({contentRoot:Y,chunks:[G]})[0]:null,X=this.ttsConfig.mathTokenHighlighting!==!1,j=J?b0({chunks:[J],mathTokenHighlighting:X}):null;if(this.runWhenPlaybackStarts(Q,()=>{if(j&&J&&G.mathAlignment)this.renderHighlightDecision(j.resolveInitial(J.id));else this.highlightCatalogRegion(G)}),!(G.sourceElement&&(G.mathAlignment&&G.mathAlignment.speech.tokens.length>0||G.mathAlignments&&G.mathAlignments.length>0||G.alignment&&G.visibleMap&&(G.playbackMode==="exact-word"||G.playbackMode==="anchor-span")))){let U=this.provider,V=U.onWordBoundary;U.onWordBoundary=void 0;try{await U.speak(G.speechText)}finally{if(this.provider===U&&Q===this.speakRunId&&U.onWordBoundary===void 0)U.onWordBoundary=V}return}let K=this.provider,W=K.onWordBoundary,B=(U,V,H)=>{if(Q!==this.speakRunId)return;if(j&&J){let N=J.offsetSpace==="unsupported"?"unknown":J.offsetSpace;this.renderHighlightDecision(j.resolveBoundary({chunkId:J.id,word:U,position:V,length:H,providerOffsetSpace:N}));return}};K.onWordBoundary=B;try{await K.speak(G.speechText)}finally{if(this.provider===K&&Q===this.speakRunId&&K.onWordBoundary===B)K.onWordBoundary=W}}async executeSpeakPlayback(G){if(G.speechChunks?.length&&this.provider){for(let Q=0;Q<G.speechChunks.length;Q++){if(G.runId!==this.speakRunId)return;this.currentSeekSegmentIndex=Q;let Y=this.seekSegments[Q];if(Y)this.currentBoundaryOffset=Y.startOffset;let J=G.speechChunks[Q];await this.speakCatalogChunk(J,G.runId)}return}if(G.shouldUsePlan&&this.currentContentElement){let Q=this.seekSegments;if(Q.length>0)await this.speakWithPlan(Q,G.runId,{highlightMode:G.highlightMode});else if(this.provider)await this.provider.speak(G.contentToSpeak);return}if(this.provider)await this.provider.speak(G.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.currentSeekSegmentIndex=0,this.activeSentenceStartOffset=null}async speakRange(G,Q){if(!this.provider)throw Error("TTS service not initialized");if(B1(G.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 J=Q?.contentRoot||null;if(!J){let U=G.commonAncestorContainer;J=U.nodeType===Node.ELEMENT_NODE?U:U.parentElement}if(!J)return;let X=X8(G,J),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=document.createRange();Z.selectNodeContents(J),Z.setEnd(G.startContainer,G.startOffset);let K=X8(Z,J).text,W=C(K),B=W.length+(/\s$/.test(K)&&W?1:0);this.debugLog("[TTSService] speakRange offset calculation:",{selectedText:j,textBeforeRange:K.substring(0,100),offset:B,rootTag:J.tagName}),await this.speak(j,{contentElement:J,ignoreCatalogs:!0,wordBoundaryOffset:B})}pause(){if(!this.provider)return;if(this.state===R.PLAYING)this.activeRecordedAudio?.element.pause(),this.provider.pause(),this.setState(R.PAUSED)}resume(){if(!this.provider)return;if(this.state===R.PAUSED){let G=this.activeRecordedAudio?.element;if(G)Promise.resolve(G.play()).catch(()=>{});this.provider.resume(),this.setState(R.PLAYING)}}normalizePlaybackRate(G){if(!Number.isFinite(G))return 1;return Math.max(0.25,Math.min(4,G))}async restartFromSeekIndex(G){if(!this.provider||this.seekSegments.length===0)return;let Q=Math.max(0,Math.min(this.seekSegments.length-1,G)),Y=this.playbackChunks.length?this.playbackChunks.slice(Q):null;this.speakRunId+=1,this.clearPlaybackStartBarrier(),this.cancelRecordedAudio(),this.provider.onWordBoundary=void 0,this.provider.stop(),this.currentSeekSegmentIndex=Q;let J=++this.speakRunId,X=this.seekSegments.slice(Q);this.highlightCoordinator?.clearTTS(),this.activeSentenceStartOffset=null,this.setState(R.LOADING);let j=this.installPlaybackStartBarrier(J,!!Y?.[0]?.audio);if(!j)this.setState(R.PLAYING);this.activePlaybackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1));try{if(this.configureWordBoundaryHighlighting({highlightMode:this.activeHighlightMode,wordBoundaryOffset:this.activeWordBoundaryOffset}),Y)for(let Z=0;Z<Y.length;Z++){if(J!==this.speakRunId)return;let K=Q+Z;this.currentSeekSegmentIndex=K;let W=this.seekSegments[K];if(W)this.currentBoundaryOffset=W.startOffset;await this.speakCatalogChunk(Y[Z],J)}else await this.speakWithPlan(X,J,{highlightMode:this.activeHighlightMode});if(J!==this.speakRunId)return;this.setState(R.IDLE),this.clearHighlightsAndTracking()}catch(Z){if(J!==this.speakRunId)return;throw this.lastError=Z instanceof Error?Z.message:String(Z),this.setState(R.ERROR),this.clearHighlightsAndTracking(),Z}finally{this.clearPlaybackStartBarrier(j)}}async setPlaybackRate(G){if(!this.provider)throw Error("TTSService not initialized. Call initialize() first.");let Q=this.normalizePlaybackRate(G),Y=this.pendingPlaybackRateRequest;if(Y?.rate===Q){await Y.promise;return}let J=++this.playbackRateRequestId,X=this.playbackRateWriteQueue.then(async()=>{let K=this.speakRunId;if(J!==this.playbackRateRequestId)return{didUpdate:!1,playbackRunId:K};let W=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1));if(Q===W)return{didUpdate:!1,playbackRunId:K};return await this.updateSettings({rate:Q}),{didUpdate:!0,playbackRunId:K}});this.playbackRateWriteQueue=X.then(()=>{return},()=>{return});let j=X.then(async(K)=>{if(J!==this.playbackRateRequestId||K.playbackRunId!==this.speakRunId)return;let W=this.activePlaybackRate!==null&&this.activePlaybackRate!==Q;if(!K.didUpdate&&!W)return;if(this.state!==R.PLAYING&&this.state!==R.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:Q,promise:Z},await Z}async seekBy(G){if(!this.provider||!this.currentText)return;if(this.state!==R.PLAYING&&this.state!==R.PAUSED)return;if(this.hasExplicitBreakSemantics(this.currentText))return;if(this.seekSegments.length===0)return;let Q=Number.isFinite(G)?Math.trunc(G):0;if(Q===0)return;let Y=this.getCurrentSeekSegmentIndex(),J=Math.max(0,Math.min(this.seekSegments.length-1,Y+Q));if(J===Y)return;await this.restartFromSeekIndex(J)}async seekForward(G=1){let Q=Number.isFinite(G)?Math.max(1,Math.trunc(G)):1;await this.seekBy(Q)}async seekBackward(G=1){let Q=Number.isFinite(G)?Math.max(1,Math.trunc(G)):1;await this.seekBy(-Q)}stop(){if(!this.provider)return;if(this.speakRunId+=1,this.clearPlaybackStartBarrier(),this.cancelRecordedAudio(),this.provider.onWordBoundary=void 0,this.provider.stop(),this.setState(R.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.currentSeekSegmentIndex=0,this.activeSentenceStartOffset=null,this.activePlaybackRate=null}requestControlHandoff(){if(typeof window>"u")return;let G={source:"host"};window.dispatchEvent(new CustomEvent(S0,{detail:G}))}isPlaying(){return this.state===R.PLAYING}isPaused(){return this.state===R.PAUSED}getState(){return this.state}getCurrentText(){return this.currentText}getLastError(){return this.lastError}onStateChange(G,Q){if(!this.listeners.has(G))this.listeners.set(G,new Set);this.listeners.get(G).add(Q)}offStateChange(G,Q){let Y=this.listeners.get(G);if(Y){if(Y.delete(Q),Y.size===0)this.listeners.delete(G)}}setState(G){if(this.state===G)return;let Q=this.state;this.state=G;for(let Y of this.listeners.values())for(let J of Y)J(G);if(this.emitTelemetry("pie-tool-playback-state-changed",{toolId:"textToSpeech",providerId:"tts",previousState:Q,state:G}),G===R.PLAYING){let Y=Q===R.PAUSED?"pie-tool-playback-resume":"pie-tool-playback-start";this.emitTelemetry(Y,{toolId:"textToSpeech",providerId:"tts",previousState:Q,state:G});return}if(G===R.PAUSED){this.emitTelemetry("pie-tool-playback-pause",{toolId:"textToSpeech",providerId:"tts",previousState:Q,state:G});return}if(G===R.ERROR){this.emitTelemetry("pie-tool-playback-error",{toolId:"textToSpeech",providerId:"tts",previousState:Q,state:G,message:this.lastError||void 0});return}if(G===R.IDLE&&(Q===R.PLAYING||Q===R.PAUSED||Q===R.LOADING))this.emitTelemetry("pie-tool-playback-stop",{toolId:"textToSpeech",providerId:"tts",previousState:Q,state:G})}}var KQ=new Set(["reserved-row","expanding-row","floating-overlay","left-aligned"]),x0=(G)=>G&&typeof G==="object"?G:{},qQ=(G)=>G==="polly"||G==="google"||G==="server",l=(G,Q)=>G===void 0?Q:G,WQ=(G,Q="left-aligned")=>typeof G==="string"&&KQ.has(G)?G:Q,j2=Object.freeze([0.8,1.25]),K2=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 q2=Object.freeze([0.8,1,1.25]);var UQ=(G)=>{let Q={...G,layoutMode:WQ(G.layoutMode)},Y=G.backend||"browser";if(!qQ(Y))return Q;let J={...Q,apiEndpoint:l(Q.apiEndpoint,"/api/tts"),transportMode:l(Q.transportMode,"pie"),endpointValidationMode:l(Q.endpointValidationMode,"voices"),validateEndpoint:l(Q.validateEndpoint,!0),includeAuthOnAssetFetch:l(Q.includeAuthOnAssetFetch,!1),rate:l(Q.rate,1),language:l(Q.language,"en-US")};if(Y==="polly")return{...J,defaultVoice:l(J.defaultVoice,"Joanna"),engine:l(J.engine,"neural"),format:l(J.format,"mp3"),speechMarksMode:l(J.speechMarksMode,"word+sentence")};if(Y==="google")return{...J,defaultVoice:l(J.defaultVoice,"en-US-Wavenet-A")};return J},f0=(G)=>{let Q=x0(G),Y=x0(Q.settings);return UQ({...Q,...Y})},L8=(G)=>G.backend||"browser",BQ=(G,Q)=>{if(Q==="polly"||Q==="google")return Q;if(Q==="server")return G.serverProvider||G.provider;return G.serverProvider||G.provider},DQ=(G,Q)=>G.transportMode||(Q==="custom"?"custom":"pie"),k0=(G)=>{let Q=L8(G),Y=BQ(G,Q),J=DQ(G,Y),X=O7(G.mathSpeech);return{voice:G.defaultVoice,rate:G.rate,pitch:G.pitch,providerOptions:{...G.language?{locale:G.language}:{},...Q==="polly"&&G.engine?{engine:G.engine}:{},...Q==="polly"&&typeof G.sampleRate==="number"?{sampleRate:G.sampleRate}:{},...Q==="polly"&&G.format?{format:G.format}:{},...Q==="polly"?{speechMarkTypes:G.speechMarksMode==="word+sentence"?["word","sentence"]:["word"]}:{},...J==="custom"&&typeof G.cache==="boolean"?{cache:G.cache}:{},...J==="custom"&&G.speedRate?{speedRate:G.speedRate}:{},...J==="custom"&&G.lang_id?{lang_id:G.lang_id}:{},...X?{mathSpeech:X}:{}},apiEndpoint:G.apiEndpoint,provider:Y,language:G.language,transportMode:J,endpointMode:G.endpointMode,endpointValidationMode:G.endpointValidationMode,includeAuthOnAssetFetch:G.includeAuthOnAssetFetch,validateEndpoint:G.validateEndpoint,...typeof G.mathTokenHighlighting==="boolean"?{mathTokenHighlighting:G.mathTokenHighlighting}:{}}};class z1{providers=new Map;configs=new Map;initialized=new Map;initializationPromises=new Map;async emitTelemetry(G,Q,Y){try{await G.onTelemetry?.(Q,Y)}catch(J){console.warn("[ToolProviderRegistry] Telemetry callback failed:",J)}}register(G,Q){if(this.providers.has(G)){console.warn(`[ToolProviderRegistry] Provider "${G}" already registered, skipping`);return}if(this.providers.set(G,Q.provider),this.configs.set(G,Q),this.initialized.set(G,!1),console.log(`[ToolProviderRegistry] Registered provider "${G}" (${Q.provider.providerName})`),Q.lazy===!1)this.initialize(G).catch((Y)=>{console.error(`[ToolProviderRegistry] Failed to initialize provider "${G}":`,Y)})}async initialize(G){if(this.initialized.get(G))return;let Q=this.initializationPromises.get(G);if(Q)return Q;let Y=this._doInitialize(G);this.initializationPromises.set(G,Y);try{await Y}finally{this.initializationPromises.delete(G)}}async _doInitialize(G){let Q=this.providers.get(G),Y=this.configs.get(G);if(!Q||!Y)throw Error(`[ToolProviderRegistry] Provider "${G}" not registered`);let J={...Y.config},X=(Z)=>{if(!Z||typeof Z!=="object")return"unknown";let K=Z;return(typeof K.backend==="string"?K.backend:typeof K.provider==="string"?K.provider:typeof K.serverProvider==="string"?K.serverProvider:typeof K.providerId==="string"?K.providerId:"")||"unknown"},j=Date.now();if(await this.emitTelemetry(Y,"pie-tool-init-start",{toolId:G,providerId:G,backend:X(J),operation:"provider-initialize"}),Q.requiresAuth&&Y.authFetcher){let Z=Date.now();await this.emitTelemetry(Y,"pie-tool-backend-call-start",{toolId:G,providerId:G,backend:X(J),operation:"auth-fetch"}),console.log(`[ToolProviderRegistry] Fetching auth for "${G}"...`);try{let K=await Y.authFetcher();J={...J,...K},await this.emitTelemetry(Y,"pie-tool-backend-call-success",{toolId:G,providerId:G,backend:X(J),operation:"auth-fetch",duration:Date.now()-Z})}catch(K){throw await this.emitTelemetry(Y,"pie-tool-backend-call-error",{toolId:G,providerId:G,backend:X(J),operation:"auth-fetch",duration:Date.now()-Z,errorType:"ProviderAuthFetchError",message:K instanceof Error?K.message:String(K)}),console.error(`[ToolProviderRegistry] Auth fetch failed for "${G}":`,K),Error(`Failed to fetch auth credentials for provider "${G}"`)}}try{await Q.initialize(J),this.initialized.set(G,!0),await this.emitTelemetry(Y,"pie-tool-init-success",{toolId:G,providerId:G,backend:X(J),operation:"provider-initialize",duration:Date.now()-j}),console.log(`[ToolProviderRegistry] Provider "${G}" initialized`)}catch(Z){throw await this.emitTelemetry(Y,"pie-tool-init-error",{toolId:G,providerId:G,backend:X(J),operation:"provider-initialize",duration:Date.now()-j,errorType:"ProviderInitializationError",message:Z instanceof Error?Z.message:String(Z)}),console.error(`[ToolProviderRegistry] Initialization failed for "${G}":`,Z),Z}}async getProvider(G,Q=!0){console.log("[ToolProviderRegistry] getProvider called",{providerId:G,autoInitialize:Q,isRegistered:this.providers.has(G),isInitialized:this.initialized.get(G),allProviderIds:Array.from(this.providers.keys())});let Y=this.providers.get(G);if(!Y)throw console.error("[ToolProviderRegistry] Provider not found:",{requestedId:G,availableProviders:Array.from(this.providers.keys())}),Error(`[ToolProviderRegistry] Provider "${G}" not registered`);if(Q&&!this.initialized.get(G))console.log("[ToolProviderRegistry] Auto-initializing provider:",G),await this.initialize(G);return console.log("[ToolProviderRegistry] Returning provider:",{providerId:G,providerName:Y.providerName,isReady:Y.isReady()}),Y}getProvidersByCategory(G){return Array.from(this.providers.entries()).filter(([Q,Y])=>Y.category===G).map(([Q])=>Q)}getProviderIds(){return Array.from(this.providers.keys())}has(G){return this.providers.has(G)}isInitialized(G){return this.initialized.get(G)===!0}isInitializing(G){return this.initializationPromises.has(G)}async unregister(G){let Q=this.providers.get(G);if(Q){let Y=this.initializationPromises.get(G);if(Y)try{await Y}catch{}Q.destroy(),this.providers.delete(G),this.configs.delete(G),this.initialized.delete(G),this.initializationPromises.delete(G),console.log(`[ToolProviderRegistry] Unregistered provider "${G}"`)}}async destroy(){let G=Array.from(this.providers.keys());await Promise.all(G.map((Q)=>this.unregister(Q))),console.log("[ToolProviderRegistry] Registry destroyed")}}class $8{targets=new Set;changeListeners=new Set;registerTarget(G){return this.targets.add(G),this.notifyChange(),()=>{if(!this.targets.delete(G))return;this.notifyChange()}}canRequest(G,Q){return this.findTarget(G,Q)!==null}request(G){let Q=this.findTarget(G.toolId,G.level);if(!Q)return!1;try{Q.open(G.toolId,G.params)}catch(Y){return console.error(`[ToolRequestRegistry] Target failed to open "${G.toolId}":`,Y),!1}return!0}onTargetsChange(G){return this.changeListeners.add(G),()=>{this.changeListeners.delete(G)}}findTarget(G,Q){let Y=this.findTargetAtLevel(G,Q??"section");if(Y||Q!==void 0)return Y;for(let J of this.targets){if(J.level==="section")continue;if(this.hostsTool(J,G))return J}return null}findTargetAtLevel(G,Q){for(let Y of this.targets){if(Y.level!==Q)continue;if(this.hostsTool(Y,G))return Y}return null}hostsTool(G,Q){try{return G.hostsTool(Q)===!0}catch(Y){return console.warn(`[ToolRequestRegistry] Target at level "${G.level}" failed the host check for "${Q}":`,Y),!1}}notifyChange(){for(let G of this.changeListeners)try{G()}catch(Q){console.warn("[ToolRequestRegistry] Target change listener threw:",Q)}}}var _Q=(G)=>`No assessment is bound, so no policy source could grant "${G}"`;function w8(G,Q,Y,J){return{featureId:G,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 (${Y.join(", ")})`,required:!1,assessmentBound:J.assessmentBound}}function v0(G,Q,Y){let J=Q.decisions[0],X=Array.from(Q.perToolFlags.values())[0],j=J?.action==="enable",Z=J?.reason??`Feature "${G}" not configured`;return{featureId:G,granted:j,action:J?.action??"skip",rule:J?.rule??"pnp-support",precedence:J?.precedence??6,sourceType:J?.sourceType??"system",reason:Y.assessmentBound||j?Z:_Q(G),required:Boolean(X?.required),parameters:X?.settings,assessmentBound:Y.assessmentBound}}class O1{provenance;stepCounter=0;constructor(G){this.provenance={contextId:G,resolvedAt:new Date,sources:{},features:new Map,decisionLog:[],summary:{totalFeatures:0,enabled:0,blocked:0,notConfigured:0,bySource:{},byRule:{}}}}addSource(G,Q){let Y={id:Q.id,name:Q.name??Q.id};switch(G){case"organization":this.provenance.sources.organization={...Y,pnpDefaults:Q.config};break;case"assessment":this.provenance.sources.assessment={...Y,settings:Q.config};break;case"section":this.provenance.sources.section={...Y,settings:Q.config};break;case"item":this.provenance.sources.item={...Y,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(G){let Q={step:++this.stepCounter,precedence:G.precedence,rule:G.rule,featureId:G.featureId,action:G.action,source:{type:G.sourceType,id:G.sourceId,name:G.sourceName},reason:G.reason,value:G.value,timestamp:new Date};this.provenance.decisionLog.push(Q);let Y=this.provenance.features.get(G.featureId);if(!Y)Y={featureId:G.featureId,finalState:"not-configured",allDecisions:[],explanation:""},this.provenance.features.set(G.featureId,Y);if(Y.allDecisions.push(Q),G.action==="advisory"){if(Y.finalState==="not-configured")Y.finalState="advisory-only"}else if(G.action!=="skip"){if(!Y.winningDecision||Q.precedence<Y.winningDecision.precedence)Y.winningDecision=Q,Y.finalState=Q.action==="enable"?"enabled":"blocked"}return this.provenance.summary.bySource[G.sourceType]=(this.provenance.summary.bySource[G.sourceType]||0)+1,this.provenance.summary.byRule[G.rule]=(this.provenance.summary.byRule[G.rule]||0)+1,this}reconcileFinalStates(G){for(let Q of G){let Y=this.provenance.features.get(Q);if(!Y){Y={featureId:Q,finalState:"enabled",allDecisions:[],explanation:""},this.provenance.features.set(Q,Y);continue}Y.finalState="enabled"}for(let Q of this.provenance.features.values()){if(G.has(Q.featureId))continue;let Y=Q.allDecisions.some((X)=>X.action!=="skip"&&X.action!=="advisory"),J=Q.allDecisions.some((X)=>X.action==="advisory");if(Y)Q.finalState="blocked";else if(J)Q.finalState="advisory-only";else Q.finalState="not-configured"}return this}build(){for(let G of this.provenance.features.values())G.explanation=VQ(G);for(let G of this.provenance.features.values())if(this.provenance.summary.totalFeatures++,G.finalState==="enabled")this.provenance.summary.enabled++;else if(G.finalState==="blocked")this.provenance.summary.blocked++;else this.provenance.summary.notConfigured++;return this.provenance}}function VQ(G){if(!G.winningDecision){if(G.finalState==="advisory-only"){let j=G.allDecisions.find((Z)=>Z.action==="advisory");return j?`Feature "${G.featureId}" was kept in its host-decided state; ${j.reason}`:`Feature "${G.featureId}" carries an advisory note.`}return`Feature "${G.featureId}" was not configured at any level.`}let Q=G.winningDecision,Y=Q.source.name||Q.source.type,J=`Feature "${G.featureId}" is ${G.finalState}.
|
|
216
216
|
|
|
217
|
-
`;J+=`**Primary Reason** (${
|
|
218
|
-
`,J+=`${
|
|
219
|
-
`,J+=`Source: ${Y} (${
|
|
220
|
-
`;let X=
|
|
217
|
+
`;J+=`**Primary Reason** (${Q.rule}):
|
|
218
|
+
`,J+=`${Q.reason}
|
|
219
|
+
`,J+=`Source: ${Y} (${Q.source.type})
|
|
220
|
+
`;let X=G.allDecisions.filter((j)=>j.step!==Q.step&&j.action!=="skip"&&j.action!=="advisory"&&j.precedence>Q.precedence);if(X.length>0){J+=`
|
|
221
221
|
**Overridden Rules**:
|
|
222
222
|
`;for(let j of X)J+=`- ${j.rule}: ${j.reason}
|
|
223
|
-
`}return J}function R8(Q){let{request:G,tools:Y,pnpPolicy:J,customSources:X,contextId:j}=Q,Z=new z1(j);Z.addSource("host",{id:G.scope.scopeId,name:`${G.level}:${G.scope.scopeId}`,config:{placement:Y.placement,policy:Y.policy}});let K=L7(Y.placement[G.level]),W=L7(Y.policy.allowed),B=new Set(L7(Y.policy.blocked)),U=[];for(let F of K)U.push(F),Z.addDecision({precedence:0,rule:"placement-membership",featureId:F,action:"skip",sourceType:"host",reason:`Listed in tools.placement.${G.level}`});if(U=U.filter((F)=>{if(Y.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(B.has(F))return Z.addDecision({precedence:0,rule:"host-blocked",featureId:F,action:"block",sourceType:"host",reason:"Listed in tools.policy.blocked",value:Y.policy.blocked}),!1;return!0});let V=[],H=new Map;for(let F of U)H.set(F,["placement"]);let N=new Set(U),O=null;if(J.enforcement==="on"&&J.source&&(J.assessment||J.currentItemRef)){if(O=J.source.apply({assessment:J.assessment,currentItemRef:J.currentItemRef}),O.sources.assessment)Z.addSource("assessment",O.sources.assessment);if(O.sources.student)Z.addSource("student",O.sources.student);if(O.sources.item)Z.addSource("item",O.sources.item);for(let F of O.decisions)Z.addDecision({precedence:F.precedence,rule:F.rule,featureId:F.featureId,action:F.action,sourceType:F.sourceType,reason:F.reason,value:F.value});U=U.filter((F)=>{return!O.blockedToolIds.has(F)});for(let F of Array.from(H.keys()))if(O.blockedToolIds.has(F))H.delete(F);for(let F of O.mandatedToolIds){if(!!N.has(F))continue;let v=O.perToolFlags.get(F)?.rule??"required-tool",I=V9(F,{placement:K,allowed:W,blocked:B,providers:Y.providers}),p={rule:v,hostRule:I.hostRule,hostValue:I.hostValue};V.push({code:"tool-policy.requiredToolBlocked",level:G.level,toolId:F,message:`Profile policy mandates "${F}" (${v}) but host policy removed it from level "${G.level}" via ${I.hostRule}.`,details:p}),Z.addDecision({precedence:0,rule:"required-tool-blocked",featureId:F,action:"advisory",sourceType:"host",reason:`Host removed required tool "${F}" via ${I.hostRule}`,value:p})}for(let F of U){let L=O.perToolFlags.get(F);if(L){let C=H.get(F)??[];C.push(`pnp.${L.rule}`),H.set(F,C)}}}for(let F=0;F<X.length;F++){let L=X[F],C=U.slice(),v=L.refine({request:G,candidates:C}),I=new Set(v.refinedCandidates);for(let E of v.refinedCandidates)if(!C.includes(E))V.push({code:"tool-policy.placementMissing",level:G.level,toolId:E,message:`Custom source "${L.id}" tried to add tool "${E}" that was not in candidates; ignored.`,source:`custom.${L.id}`}),I.delete(E);U=C.filter((E)=>I.has(E));let p=new Set;if(v.decisions){for(let E of v.decisions)if(Z.addDecision({precedence:E.precedence??100+F,rule:E.rule,featureId:E.featureId,action:E.action,sourceType:E.sourceType,reason:E.reason,value:E.value}),E.action==="block")p.add(E.featureId)}for(let E of C){if(I.has(E))continue;if(p.has(E))continue;Z.addDecision({precedence:100+F,rule:"custom-source",featureId:E,action:"block",sourceType:"custom",reason:`Custom policy source "${L.id}" removed tool "${E}" from candidates without emitting a decision; auto-logged for trail completeness.`,value:{customSourceId:L.id}})}for(let E of U){let g=H.get(E)??["placement"];g.push(`custom.${L.id}`),H.set(E,g)}for(let E of C)if(!I.has(E))H.delete(E)}let P=new Set(U),$=U.map((F)=>{let L=O?.perToolFlags.get(F);return{toolId:F,required:L?.required??!1,alwaysAvailable:L?.alwaysAvailable??!1,settings:L?.settings,sources:H.get(F)??["placement"]}});return Z.reconcileFinalStates(P),{visibleTools:$,diagnostics:V,provenance:Z.build()}}function V9(Q,G){if(!G.placement.includes(Q))return{hostRule:"placement-missing",hostValue:G.placement};if(G.providers?.[Q]?.enabled===!1)return{hostRule:"provider-disabled",hostValue:!1};if(G.allowed.length>0&&!G.allowed.includes(Q))return{hostRule:"host-allowlist",hostValue:G.allowed};if(G.blocked.has(Q))return{hostRule:"host-blocked",hostValue:Array.from(G.blocked)};return{hostRule:"placement-missing",hostValue:G.placement}}function v0(Q){if(!Q)return!1;let G=Q.personalNeedsProfile;if(G){if(Array.isArray(G.supports)&&G.supports.length>0)return!0;if(Array.isArray(G.prohibitedSupports)&&G.prohibitedSupports.length>0)return!0;if(Array.isArray(G.activateAtInit)&&G.activateAtInit.length>0)return!0}let Y=Q.settings;if(Y){let J=Y.districtPolicy;if(J){if(Array.isArray(J.blockedTools)&&J.blockedTools.length>0)return!0;if(Array.isArray(J.requiredTools)&&J.requiredTools.length>0)return!0;if(J.policies&&typeof J.policies==="object"&&Object.keys(J.policies).length>0)return!0}let X=Y.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 h0(Q){let G=Q?.settings;if(!G)return!1;if(Array.isArray(G.requiredTools)&&G.requiredTools.length>0)return!0;if(Array.isArray(G.restrictedTools)&&G.restrictedTools.length>0)return!0;if(G.toolParameters&&typeof G.toolParameters==="object"&&Object.keys(G.toolParameters).length>0)return!0;return!1}function g7(Q){if(v0(Q.assessment))return"on";if(h0(Q.currentItemRef))return"on";return"off"}class P1{id="pnp";toolRegistry;constructor(Q){this.toolRegistry=Q}apply(Q){let{ctx:G,result:Y}=this.prepare(Q),{pnp:J,districtPolicy:X,itemSettings:j}=G,Z=new Set;J?.supports?.forEach((K)=>Z.add(K)),J?.prohibitedSupports?.forEach((K)=>Z.add(K)),X?.blockedTools?.forEach((K)=>Z.add(K)),X?.requiredTools?.forEach((K)=>Z.add(K)),j?.requiredTools?.forEach((K)=>Z.add(K)),j?.restrictedTools?.forEach((K)=>Z.add(K));for(let K of Z)this.resolveSupport(K,G,Y);return Y}resolveFeature(Q,G){let{ctx:Y,result:J}=this.prepare(G);return this.resolveSupport(Q,Y,J),J}prepare(Q){let{assessment:G,currentItemRef:Y}=Q,J=G?.personalNeedsProfile,X=G?.settings,j=Y?.settings,Z={blockedToolIds:new Set,mandatedToolIds:new Set,perToolFlags:new Map,decisions:[],sources:{}};if(X?.districtPolicy||X?.testAdministration)Z.sources.assessment={id:G?.id||"unknown",name:G?.name||G?.id||"Assessment",config:X};if(J)Z.sources.student={id:"student",name:"Student PNP Profile",config:J};if(Y&&j)Z.sources.item={id:Y.identifier,name:Y.identifier,config:j};return{ctx:{pnp:J,districtPolicy:X?.districtPolicy,testAdmin:X?.testAdministration,itemSettings:j,toolConfigs:X?.toolConfigs},result:Z}}resolveSupport(Q,G,Y){if(G.districtPolicy?.blockedTools?.includes(Q)){let X=this.mapSupportToToolId(Q);Y.blockedToolIds.add(X),Y.decisions.push({precedence:1,rule:"district-block",featureId:X,action:"block",sourceType:"assessment",reason:`District policy blocks "${Q}" for all assessments`,value:G.districtPolicy.blockedTools});return}if(G.testAdmin?.toolOverrides?.[Q]===!1){let X=this.mapSupportToToolId(Q);Y.blockedToolIds.add(X),Y.decisions.push({precedence:2,rule:"test-admin-override",featureId:X,action:"block",sourceType:"assessment",reason:`Test administrator disabled "${Q}" for this session`,value:G.testAdmin.toolOverrides});return}if(G.itemSettings?.restrictedTools?.includes(Q)){let X=this.mapSupportToToolId(Q);Y.blockedToolIds.add(X),Y.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:G.itemSettings.restrictedTools});return}if(G.itemSettings?.requiredTools?.includes(Q)){let X=this.mapSupportToToolId(Q);Y.mandatedToolIds.add(X),Y.perToolFlags.set(X,{required:!0,alwaysAvailable:!1,settings:this.resolveToolSettings(Q,G),rule:"item-requirement",sourceType:"item"}),Y.decisions.push({precedence:4,rule:"item-requirement",featureId:X,action:"enable",sourceType:"item",reason:`Item requires "${Q}" for this question`,value:G.itemSettings.requiredTools});return}if(G.districtPolicy?.requiredTools?.includes(Q)){let X=this.mapSupportToToolId(Q);Y.mandatedToolIds.add(X),Y.perToolFlags.set(X,{required:!0,alwaysAvailable:!1,settings:this.resolveToolSettings(Q,G),rule:"district-requirement",sourceType:"assessment"}),Y.decisions.push({precedence:5,rule:"district-requirement",featureId:X,action:"enable",sourceType:"assessment",reason:`District policy requires "${Q}" for all assessments`,value:G.districtPolicy.requiredTools});return}if(G.pnp?.prohibitedSupports?.includes(Q)){let X=this.mapSupportToToolId(Q);Y.blockedToolIds.add(X),Y.decisions.push({precedence:6,rule:"pnp-prohibited",featureId:X,action:"block",sourceType:"student",reason:`Student PNP profile prohibits "${Q}"`,value:G.pnp.prohibitedSupports});return}if(G.pnp?.supports?.includes(Q)){let X=this.mapSupportToToolId(Q);Y.perToolFlags.set(X,{required:!1,alwaysAvailable:!0,settings:this.resolveToolSettings(Q,G),rule:"pnp-support",sourceType:"student"}),Y.decisions.push({precedence:6,rule:"pnp-support",featureId:X,action:"enable",sourceType:"student",reason:`Student PNP profile requests "${Q}"`,value:G.pnp.supports});return}let J=this.mapSupportToToolId(Q);Y.decisions.push({precedence:6,rule:"pnp-support",featureId:J,action:"skip",sourceType:"system",reason:`Feature "${Q}" not configured at any level`,value:{supportId:Q}})}mapSupportToToolId(Q){let G=this.toolRegistry.getToolsByPNPSupport(Q);if(G.size===0)return Q;return Array.from(G)[0]}resolveToolSettings(Q,G){return G.itemSettings?.toolParameters?.[Q]??G.toolConfigs?.[Q]}}var m0=R7({policy:{allowed:[],blocked:[]},placement:{section:[],item:[],passage:[]},providers:{}});class L1{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 P1(this.toolRegistry),this.customSources=Q.customSources?[...Q.customSources]:[];let G=Q.inputs??{};this.tools=G.tools??m0,this.assessment=G.assessment??null,this.currentItemRef=G.currentItemRef??null,this.pnpEnforcement=G.pnpEnforcement??g7({assessment:this.assessment,currentItemRef:this.currentItemRef})}decide(Q){this.assertNotDisposed();let G=Q.scope.scopeId?`${this.contextId}:${Q.level}:${Q.scope.scopeId}`:`${this.contextId}:${Q.level}`;return R8({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:G})}decideFeature(Q){this.assertNotDisposed();let G=this.hostFeatureGate(Q);if(G)return G;return I0(Q,this.pnpPolicySource.resolveFeature(Q,{assessment:this.assessment??void 0,currentItemRef:this.currentItemRef??void 0}),{assessmentBound:this.assessment!==null})}hostFeatureGate(Q){let G={assessmentBound:this.assessment!==null},Y=L7(this.tools.policy.blocked);if(Y.includes(Q))return w8(Q,"host-blocked",Y,G);let J=L7(this.tools.policy.allowed);if(J.length>0&&!J.includes(Q))return w8(Q,"host-allowlist",J,G);return null}getVisibleToolIds(Q,G){return this.decide({level:Q,scope:{level:Q,scopeId:G}}).visibleTools.map((Y)=>Y.toolId)}updateInputs(Q){this.assertNotDisposed();let G=!1,Y=!1;if("tools"in Q){let J=Q.tools??m0;if(!Object.is(this.tools,J))this.tools=J,G=!0}if("assessment"in Q){let J=Q.assessment??null;if(!Object.is(this.assessment,J))this.assessment=J,G=!0}if("currentItemRef"in Q){let J=Q.currentItemRef??null;if(!Object.is(this.currentItemRef,J))this.currentItemRef=J,G=!0}if("pnpEnforcement"in Q&&Q.pnpEnforcement){if(this.pnpEnforcement!==Q.pnpEnforcement)this.pnpEnforcement=Q.pnpEnforcement,Y=!0}if(G||Y)this.emit({reason:Y&&!G?"pnp-enforcement":"inputs",inputs:this.snapshotInputs()})}registerPolicySource(Q){return this.assertNotDisposed(),this.customSources.push(Q),this.emit({reason:"policy-source-added",inputs:this.snapshotInputs()}),()=>{let G=this.customSources.indexOf(Q);if(G!==-1){if(this.customSources.splice(G,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 G of Array.from(this.listeners))try{G(Q)}catch{}}assertNotDisposed(){if(this.disposed)throw Error("ToolPolicyEngine has been disposed.")}}var H9=Symbol("@pie-players/tool-policy-engine");var $1=(Q)=>!!Q&&typeof Q==="object"&&!Array.isArray(Q),F9=(Q,G,Y)=>{let J={...G,...Y};if(Q==="textToSpeech"&&$1(G.settings)&&$1(Y.settings)){if(J.settings={...G.settings,...Y.settings},$1(G.settings.mathSpeech)&&$1(Y.settings.mathSpeech))J.settings.mathSpeech={...G.settings.mathSpeech,...Y.settings.mathSpeech}}return J},A9=["item-selected","item-session-data-changed","item-session-meta-changed","item-complete-changed","content-loaded","item-player-error"],N9=["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 w1{assessmentId;config;ttsService;toolCoordinator;highlightCoordinator;elementToolStateStore;catalogResolver;toolProviderRegistry;hooks;lazyInit;ttsInitialized=!1;ttsInitPromise;ttsReconfigurePromise;stateLoaded=!1;stateLoadPromise;coordinatorReadyPromise;coordinatorReadyNotified=!1;providerInitPromises=new Map;toolRegistry;toolContextResolvers=new Map;toolContextResolverChangeListeners=new Set;toolRequests=new $8;sectionControllers=new Map;sectionControllerKeys=new Map;sectionControllerInitPromises=new Map;sectionPersistenceStrategies=new Map;sectionControllerLifecycleListeners=new Set;activeSubscriptions=new Map;activeCohortMapKey=null;latestRequestedActiveCohortMapKey=null;telemetryListeners=new Set;frameworkErrorBus;ownsFrameworkErrorBus;policyEngine;pnpEnforcementOverride=null;boundAssessment=null;boundCurrentItemRef=null;reportedUnboundFeaturePolicy=!1;static resolveConfig(Q){let G=l1(Q.toolConfigStrictness),Y=Q.toolRegistry??new E8,J=Q.deferToolConfigValidation===!0?R7(Q.tools):X7(Q.tools,{strictness:G,source:"ToolkitCoordinator.init",toolRegistry:Y}).config;return{...Q,toolConfigStrictness:G,toolRegistry:Y,tools:{...J,providers:{...{textToSpeech:{enabled:!0,backend:"browser"},annotationToolbar:{enabled:!0}},...J.providers}},accessibility:{language:"en-US",...Q.accessibility??{},catalogs:Q.accessibility?.catalogs??[]}}}constructor(Q){if(!Q.assessmentId)throw Error("ToolkitCoordinator requires assessmentId in config");let G=w1.resolveConfig(Q);if(this.assessmentId=G.assessmentId,this.config=G,this.toolRegistry=G.toolRegistry??new E8,this.installToolContextResolvers(G.toolContextResolvers),this.hooks=G.hooks??{},this.lazyInit=Q.lazyInit===!0,this.pnpEnforcementOverride=this.resolveConfiguredPnpEnforcement(),this.frameworkErrorBus=Q.frameworkErrorBus??new m7,this.ownsFrameworkErrorBus=!Q.frameworkErrorBus,this.subscribeFrameworkErrorHookAdapters(),this.toolCoordinator=new Y8,this.highlightCoordinator=new u7,this.elementToolStateStore=new Q8,this.catalogResolver=new e1(G.accessibility?.catalogs||[],G.accessibility?.language||"en-US"),this.toolProviderRegistry=new O1,this._registerToolProviders(),this.ttsService=new p7,this.setupStatePersistenceHooks(),this.policyEngine=new L1({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((Y)=>{console.error("[ToolkitCoordinator] Failed eager initialization:",Y),this.handleError(Y,{phase:"coordinator-ready"})})}subscribeFrameworkErrorHookAdapters(){this.frameworkErrorBus.subscribeFrameworkErrors((Q)=>{let G=this.hooks.onFrameworkError;if(!G)return;try{G(Q)}catch(Y){console.warn("[ToolkitCoordinator] onFrameworkError hook failed:",Y)}})}async emitTelemetry(Q,G){try{await this.hooks.onTelemetry?.(Q,G)}catch(J){console.warn("[ToolkitCoordinator] telemetry hook failed:",J)}let Y=G?{...G}:void 0;for(let J of this.telemetryListeners)try{J({eventName:Q,payload:Y?{...Y}:void 0})}catch(X){console.warn("[ToolkitCoordinator] telemetry listener failed:",X)}}emitSectionControllerLifecycle(Q){for(let G of this.sectionControllerLifecycleListeners)try{G(Q)}catch(Y){console.warn("[ToolkitCoordinator] section controller lifecycle listener failed:",Y)}}handleError(Q,G){let Y=G6({error:Q,context:G});this.frameworkErrorBus.reportFrameworkError(Y)}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}})(),G=(Y)=>{let{assessmentId:J,sectionId:X,attemptId:j}=Y.key;return`pie:section-controller:v1:${J}:${X}:${j||"default"}`};return{async loadSession(Y){if(!Q)return null;let J=Q.getItem(G(Y));if(!J)return null;try{return JSON.parse(J)}catch{return null}},async saveSession(Y,J){if(!Q)return;Q.setItem(G(Y),JSON.stringify(J))},async clearSession(Y){if(!Q)return;Q.removeItem(G(Y))}}}async resolveSectionPersistence(Q){let G=this.getSectionControllerMapKey(Q.key),Y=this.sectionPersistenceStrategies.get(G);if(Y)return Y;let J={createDefaultPersistence:()=>this.createDefaultSectionPersistence()},X=await this.hooks.createSectionSessionPersistence?.(Q,J)??await J.createDefaultPersistence();return this.sectionPersistenceStrategies.set(G,X),X}setupStatePersistenceHooks(){this.elementToolStateStore.setOnStateChange((Q)=>{if(!this.hooks.saveToolState)return;Promise.resolve(this.hooks.saveToolState(Q)).catch((G)=>{this.handleError(G,{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 G=await Q();if(G&&typeof G==="object")this.elementToolStateStore.loadState(G);this.stateLoaded=!0,await this.emitTelemetry("pie-toolkit-tool-state-loaded",{hasState:Boolean(G)})}catch(G){this.handleError(G,{phase:"state-load"})}})().finally(()=>{this.stateLoadPromise=void 0}),this.stateLoadPromise}_registerToolProviders(){let Q=this.getProviderDescriptorTools();for(let G of Q)this.registerProviderFromTool(G)}getProviderDescriptorTools(){return this.toolRegistry.getAllTools().filter((Q)=>!!Q.provider)}async registerProviderFromTool(Q){let G=Q.provider;if(!G)return;let Y=this.getToolConfig(Q.toolId)||void 0;if(Y?.enabled===!1)return;let J=G.getProviderId?.(Y)??Y?.provider?.id??Q.toolId;if(this.toolProviderRegistry.has(J))return;let X=G.createProvider(Y),j=G.getInitConfig?.(Y)??Y?.provider?.init??{},Z=this.addToolTelemetryReporter({toolId:Q.toolId,providerId:J,initConfig:j}),K=this.createToolTelemetryForwarder({toolId:Q.toolId,providerId:J}),W=G.getAuthFetcher?.(Y)??Y?.provider?.runtime?.authFetcher;await this.registerProvider(J,{provider:X,config:Z,lazy:G.lazy??!0,authFetcher:W,onTelemetry:K})}createToolTelemetryForwarder(Q){return async(G,Y)=>{await this.emitTelemetry(G,{...Y||{},toolId:Q.toolId,providerId:Q.providerId})}}addToolTelemetryReporter(Q){let G=Q.initConfig&&typeof Q.initConfig==="object"?{...Q.initConfig}:{},Y=typeof G.onTelemetry==="function"?G.onTelemetry:null,J=this.createToolTelemetryForwarder({toolId:Q.toolId,providerId:Q.providerId});return G.onTelemetry=async(X,j)=>{if(Y)await Y(X,j);await J(X,j)},G}async registerProvider(Q,G){try{this.toolProviderRegistry.register(Q,G);let Y={providerId:Q,providerName:G.provider.providerName};await this.hooks.onProviderRegistered?.(Q,Y),await this.emitTelemetry("pie-toolkit-provider-registered",{providerId:Q,providerName:G.provider.providerName})}catch(Y){console.warn(`[ToolkitCoordinator] Failed to register provider "${Q}":`,Y),this.handleError(Y,{phase:"provider-register",providerId:Q})}}async ensureProviderReady(Q){let G=this.providerInitPromises.get(Q);if(G)return G;let Y=(async()=>{let J=await this.toolProviderRegistry.getProvider(Q,!1),X={providerId:Q,providerName:J.providerName};try{return await this.hooks.onProviderInitStart?.(Q,X),await this.toolProviderRegistry.initialize(Q),await this.hooks.onProviderReady?.(Q,X),await this.emitTelemetry("pie-toolkit-provider-ready",{providerId:Q}),J}catch(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,Y),Y}setHooks(Q){if(Object.assign(this.hooks,Q),this.setupStatePersistenceHooks(),Q.onCoordinatorReady&&this.isReady())Promise.resolve(Q.onCoordinatorReady(this)).catch((G)=>{this.handleError(G,{phase:"coordinator-ready"})})}subscribeTelemetry(Q){return this.telemetryListeners.add(Q),()=>{this.telemetryListeners.delete(Q)}}getSectionController(Q){let G={assessmentId:this.assessmentId,sectionId:Q.sectionId,attemptId:Q.attemptId};return this.sectionControllers.get(this.getSectionControllerMapKey(G))}subscribeSectionEvents(Q){if(this.activeCohortMapKey===null)throw Error("[ToolkitCoordinator] subscribeSectionEvents requires an active section cohort; call getOrCreateSectionController first.");let G=this.activeSubscriptions.get(Q.listener);if(G)G.unsubscribeCurrent?.(),G.unsubscribeCurrent=null;let Y={listener:Q.listener,eventTypes:Q.eventTypes,itemIds:Q.itemIds,unsubscribeCurrent:null};this.activeSubscriptions.set(Q.listener,Y);let J=this.sectionControllers.get(this.activeCohortMapKey);if(J)this.bindSubscriptionToController(Y,J);let X=!1;return()=>{if(X)return;if(X=!0,Y.unsubscribeCurrent?.(),Y.unsubscribeCurrent=null,this.activeSubscriptions.get(Q.listener)===Y)this.activeSubscriptions.delete(Q.listener)}}bindSubscriptionToController(Q,G){Q.unsubscribeCurrent?.(),Q.unsubscribeCurrent=null;let Y=G.subscribe;if(typeof Y!=="function")return;let J=this.buildSectionEventPredicate(Q);Q.unsubscribeCurrent=Y.call(G,(Z)=>{if(!J(Z))return;this.deliverSectionEventSafely(Q.listener,Z)});let X=this.buildContentLoadedReplayEvents(G);for(let Z of X)if(J(Z))this.deliverSectionEventSafely(Q.listener,Z);let j=this.buildLoadingCompleteReplayEvent(G);if(j&&J(j))this.deliverSectionEventSafely(Q.listener,j)}deliverSectionEventSafely(Q,G){try{Q(G)}catch(Y){console.warn("[ToolkitCoordinator] section-event listener failed:",Y)}}setActiveCohort(Q){if(this.activeCohortMapKey===Q)return;this.activeCohortMapKey=Q;let G=this.sectionControllers.get(Q);if(!G)return;for(let Y of Array.from(this.activeSubscriptions.values()))this.bindSubscriptionToController(Y,G)}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 G of Array.from(this.activeSubscriptions.values()))G.unsubscribeCurrent?.(),G.unsubscribeCurrent=null}clearActiveCohortIfMatches(Q){if(this.activeCohortMapKey!==Q)return;this.activeCohortMapKey=null;for(let G of Array.from(this.activeSubscriptions.values()))G.unsubscribeCurrent?.(),G.unsubscribeCurrent=null}buildSectionEventPredicate(Q){let G=Q.eventTypes?new Set(Q.eventTypes):null,Y=Q.itemIds?new Set(Q.itemIds):null;return(J)=>{if(G||Y){let X=J?.type||null;if(G&&(!X||!G.has(X)))return!1;if(Y){if(!Array.from(this.collectEventItemIds(J)).some((Z)=>Y.has(Z)))return!1}}return!0}}collectEventItemIds(Q){let G=new Set;if("itemId"in Q&&typeof Q.itemId==="string")G.add(Q.itemId);if("canonicalItemId"in Q&&typeof Q.canonicalItemId==="string")G.add(Q.canonicalItemId);if("currentItemId"in Q&&typeof Q.currentItemId==="string")G.add(Q.currentItemId);if("previousItemId"in Q&&typeof Q.previousItemId==="string")G.add(Q.previousItemId);return G}buildContentLoadedReplayEvents(Q){let G=Q.getRuntimeState?.(),Y=G?.loadedRenderables;if(!Array.isArray(Y)||Y.length===0)return[];let J=typeof G?.currentItemIndex==="number"&&Number.isFinite(G.currentItemIndex)?G.currentItemIndex:0,X=Date.now(),j=[];for(let Z of Y){if(!Z)continue;let K=Z.itemId,W=typeof Z.canonicalItemId==="string"&&Z.canonicalItemId?Z.canonicalItemId:K;if(typeof K!=="string"||!K)continue;j.push({type:"content-loaded",contentKind:Z.contentKind??"unknown",itemId:K,canonicalItemId:W,currentItemIndex:J,timestamp:X})}return j}buildLoadingCompleteReplayEvent(Q){let G=Q.getRuntimeState?.();if(G?.loadingComplete!==!0)return null;let Y=typeof G.totalRegistered==="number"&&Number.isFinite(G.totalRegistered)?Math.max(0,G.totalRegistered):0,J=typeof G.totalLoaded==="number"&&Number.isFinite(G.totalLoaded)?Math.max(0,G.totalLoaded):Y;return{type:"section-loading-complete",totalRegistered:Y,totalLoaded:J,currentItemIndex:G.currentItemIndex,timestamp:Date.now()}}subscribeItemEvents(Q){return this.subscribeSectionEvents({eventTypes:Q.eventTypes||A9,itemIds:Q.itemIds,listener:Q.listener})}subscribeSectionLifecycleEvents(Q){return this.subscribeSectionEvents({eventTypes:Q.eventTypes||N9,listener:Q.listener})}onSectionControllerLifecycle(Q){return this.sectionControllerLifecycleListeners.add(Q),()=>{this.sectionControllerLifecycleListeners.delete(Q)}}async getOrCreateSectionController(Q){let G={assessmentId:this.assessmentId,sectionId:Q.sectionId,attemptId:Q.attemptId},Y=this.getSectionControllerMapKey(G);this.latestRequestedActiveCohortMapKey=Y,this.suspendActiveCohortIfSuperseded(Y);let J=await this.resolveExistingSectionController({mapKey:Y,key:G,input:Q.input,updateExisting:Q.updateExisting});if(J)return J;let X=this.sectionControllerInitPromises.get(Y);if(X)return X;let j=this.initializeNewSectionController({args:Q,key:G,mapKey:Y}).catch((Z)=>{throw this.handleSectionControllerInitError(Z,Q),Z}).finally(()=>{this.sectionControllerInitPromises.delete(Y)});return this.sectionControllerInitPromises.set(Y,j),j}async resolveExistingSectionController(Q){let G=this.sectionControllers.get(Q.mapKey);if(!G)return;if(this.sectionControllerKeys.set(Q.mapKey,Q.key),Q.updateExisting!==!1)await G.updateInput?.(Q.input);return this.setActiveCohortIfLatestRequest(Q.mapKey),G}createSectionControllerContext(Q){return{key:Q.key,coordinator:this,input:Q.input}}async initializeNewSectionController(Q){let G=this.createSectionControllerContext({key:Q.key,input:Q.args.input}),Y=await this.resolveSectionPersistence(G),J={createDefaultController:Q.args.createDefaultController},X=await this.hooks.createSectionController?.(G,J)??await J.createDefaultController();return await X.configureSessionPersistence?.({strategy:Y,context:G}),await X.initialize?.(Q.args.input),await X.hydrate?.(),await this.finalizeSectionControllerReady({mapKey:Q.mapKey,key:Q.key,context:G,controller:X}),X}async finalizeSectionControllerReady(Q){this.sectionControllers.set(Q.mapKey,Q.controller),this.sectionControllerKeys.set(Q.mapKey,Q.key),this.setActiveCohortIfLatestRequest(Q.mapKey),this.emitSectionControllerLifecycle({type:"ready",key:Q.key,controller:Q.controller}),await this.hooks.onSectionControllerReady?.(Q.context,Q.controller),await this.emitTelemetry("pie-toolkit-section-controller-ready",{assessmentId:Q.key.assessmentId,sectionId:Q.key.sectionId,attemptId:Q.key.attemptId})}handleSectionControllerInitError(Q,G){this.handleError(Q,{phase:"section-controller-init",details:{sectionId:G.sectionId,attemptId:G.attemptId}})}async disposeSectionController(Q){let G={assessmentId:this.assessmentId,sectionId:Q.sectionId,attemptId:Q.attemptId},Y=this.getSectionControllerMapKey(G),J=this.sectionControllers.get(Y);if(!J)return;this.clearActiveCohortIfMatches(Y);let X=this.createSectionControllerContext({key:G,input:void 0});try{await this.runSectionControllerDisposePipeline({key:G,context:X,controller:J,persistBeforeDispose:Q.persistBeforeDispose})}catch(j){this.handleError(j,{phase:"section-controller-dispose",details:{sectionId:Q.sectionId,attemptId:Q.attemptId}})}finally{await this.finalizeSectionControllerDispose({mapKey:Y,key:G,context:X,clearPersistence:Q.clearPersistence})}}async runSectionControllerDisposePipeline(Q){if(Q.persistBeforeDispose!==!1)await Q.controller.persist?.();await Q.controller.dispose?.(),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(this.sectionControllers.delete(Q.mapKey),this.sectionControllerKeys.delete(Q.mapKey),this.emitSectionControllerLifecycle({type:"disposed",key:Q.key}),Q.clearPersistence)await this.sectionPersistenceStrategies.get(Q.mapKey)?.clearSession?.(Q.context);this.sectionPersistenceStrategies.delete(Q.mapKey)}async ensureTTSReady(Q){if(await this.waitForPendingTTSReconfigure(),this.ttsInitialized)return;if(this.ttsInitPromise)return this.ttsInitPromise;return this.ttsInitPromise=this._initializeTTS(Q).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 G=this.resolveTTSToolConfig(Q),Y=f0(G),J=L8(Y),X=k0(Y);if(await this.hooks.onBeforeTTSInit?.({phase:"tts-init",details:{backend:J}}),await this.emitTelemetry("pie-toolkit-tts-init-start",{backend:J}),await this.emitTelemetry("pie-tool-init-start",{toolId:"textToSpeech",operation:"tts-init",backend:J}),this.toolProviderRegistry.has("tts"))try{let K=await(await this.ensureProviderReady("tts")).createInstance();await this.initializeTTSService(K,X),await this.emitTelemetry("pie-toolkit-tts-init-success",{provider:"registry"}),await this.emitTelemetry("pie-tool-init-success",{toolId:"textToSpeech",operation:"tts-init",backend:J,provider:"registry"}),console.log("[ToolkitCoordinator] TTS initialized via ToolProviderRegistry");return}catch(Z){let K=Z instanceof Error?Z:Error(String(Z));await this.emitTelemetry("pie-tool-init-error",{toolId:"textToSpeech",providerId:"tts",operation:"tts-init",backend:J,errorType:"TTSRegistryInitError",message:K.message,recovered:!0}),await this.emitTelemetry("pie-tool-init-fallback",{toolId:"textToSpeech",providerId:"tts",operation:"tts-init",backend:J,fromProvider:"registry",toProvider:"browser",reason:K.message}),console.warn("[ToolkitCoordinator] Failed to initialize TTS via registry, falling back to browser provider:",K)}let j=new b7;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:J,provider:"browser-fallback"})}catch(Z){let K=Z instanceof Error?Z:Error(String(Z));throw this.handleError(K,{phase:"tts-init"}),await this.emitTelemetry("pie-toolkit-tts-init-error",{message:K.message}),await this.emitTelemetry("pie-tool-init-error",{toolId:"textToSpeech",operation:"tts-init",backend:J,errorType:"TTSInitError",message:K.message}),K}}resolveTTSToolConfig(Q){return Q||this.getTTSConfigFromProviders()||{}}async initializeTTSService(Q,G){let Y={...G.providerOptions||{},__pieTelemetry:async(X,j)=>{await this.emitTelemetry(X,{toolId:"textToSpeech",...j||{}})}},J={...G,providerOptions:Y};await this.ttsService.initialize(Q,J),await this.ensureBrowserVoicesReady(Q),this.ttsService.setCatalogResolver(this.catalogResolver),this.ttsInitialized=!0,await this.hooks.onTTSReady?.()}async ensureBrowserVoicesReady(Q,G=1200){if(Q.providerId!=="browser")return;if(typeof window>"u")return;if(!("speechSynthesis"in window))return;let Y=window.speechSynthesis;if(Y.getVoices().length>0)return;await new Promise((j)=>{let Z=!1,K=typeof Y.addEventListener==="function"&&typeof Y.removeEventListener==="function",W=!K&&"onvoiceschanged"in Y,B=W?Y.onvoiceschanged:null,U=!1,V=()=>{if(Z)return;if(Z=!0,window.clearTimeout(N),K)Y.removeEventListener("voiceschanged",H);else if(U&&Y.onvoiceschanged===H)Y.onvoiceschanged=B;j()},H=(O)=>{if(!K&&typeof B==="function"&&O)B.call(Y,O);V()},N=window.setTimeout(V,G);if(K)Y.addEventListener("voiceschanged",H,{once:!0});else if(W)Y.onvoiceschanged=H,U=!0});let X=Y.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.isReady())return;if(this.coordinatorReadyPromise)return this.coordinatorReadyPromise;return this.coordinatorReadyPromise=(async()=>{await this.ensureStateLoaded();let Q=this.getTTSConfigFromProviders();if(Q?.enabled!==!1)await this.ensureTTSReady(Q);if(!this.coordinatorReadyNotified)this.coordinatorReadyNotified=!0,await this.hooks.onCoordinatorReady?.(this),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 Y of this.toolProviderRegistry.getProviderIds())Q[Y]=this.toolProviderRegistry.isInitialized(Y);let G=this.getTTSConfigFromProviders();return{tts:this.ttsInitialized,stateLoaded:this.stateLoaded||!this.hooks.loadToolState,coordinator:(this.stateLoaded||!this.hooks.loadToolState)&&(this.ttsInitialized||G?.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[G,Y]of Object.entries(Q)){if(Y==null)continue;if(this.assertCanonicalToolId(G),typeof Y!=="function")throw Error(`Invalid tool context resolver for "${G}": expected a function.`);this.toolContextResolvers.set(G,Y)}}setToolContextResolvers(Q){this.toolContextResolvers.clear(),this.installToolContextResolvers(Q??void 0),this.notifyToolContextResolverChange()}notifyToolContextResolverChange(){for(let Q of this.toolContextResolverChangeListeners)try{Q()}catch(G){console.warn("[ToolkitCoordinator] Tool context resolver listener threw:",G)}}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,G){this.assertCanonicalToolId(Q);let Y=this.getToolConfig(Q)||{};if(!this.config.tools)this.config.tools=X7(void 0,{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolConfig",toolRegistry:this.toolRegistry}).config;if(!this.config.tools.providers)this.config.tools.providers={};let J={...this.config.tools.providers||{},[Q]:F9(Q,Y,G)},X=X7({...this.config.tools,providers:J},{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolConfig",toolRegistry:this.toolRegistry});this.config.tools=X.config,this.policyEngine.updateInputs({tools:this.config.tools}),this.emitTelemetry("pie-toolkit-tool-config-updated",{toolId:Q}),this._applyToolConfigChange(Q,G)}updateToolPlacement(Q,G){this.updateToolsPlacement({[Q]:[...G]})}updateToolsPlacement(Q){if(!this.config.tools)this.config.tools=X7(void 0,{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolsPlacement",toolRegistry:this.toolRegistry}).config;let G=this.config.tools?.placement??{section:[],item:[],passage:[]},Y={section:[...Q.section??G.section??[]],item:[...Q.item??G.item??[]],passage:[...Q.passage??G.passage??[]]},J=X7({...this.config.tools,placement:Y},{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolsPlacement",toolRegistry:this.toolRegistry});J.config.placement=Y,this.config.tools=J.config,this.policyEngine.updateInputs({tools:this.config.tools})}decideToolPolicy(Q){return this.policyEngine.decide(Q)}decideFeaturePolicy(Q){let G=this.policyEngine.decideFeature(Q);if(!G.assessmentBound&&!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 G}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,G){if(this.assertCanonicalToolId(Q),typeof G!=="function")throw Error(`Invalid tool context resolver for "${Q}": expected a function.`);return this.toolContextResolvers.set(Q,G),this.notifyToolContextResolverChange(),()=>{if(this.toolContextResolvers.get(Q)!==G)return;this.toolContextResolvers.delete(Q),this.notifyToolContextResolverChange()}}hasToolContextResolver(Q){return this.assertCanonicalToolId(Q),this.toolContextResolvers.has(Q)}resolveToolContext(Q){this.assertCanonicalToolId(Q.toolId);let G=this.toolContextResolvers.get(Q.toolId);if(!G)return null;let Y;try{Y=G(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(!Y)return{toolId:Q.toolId,visible:!0,params:{}};let J=Y.params&&typeof Y.params==="object"&&!Array.isArray(Y.params)?Y.params:{};return{toolId:Q.toolId,visible:Y.visible!==!1,params:J,reason:typeof Y.reason==="string"?Y.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,G){try{this.assertCanonicalToolId(Q)}catch{return!1}return this.toolRequests.canRequest(Q,G)}onToolRequestTargetsChange(Q){return this.toolRequests.onTargetsChange(Q)}resolveEffectivePnpEnforcement(){if(this.pnpEnforcementOverride!==null)return this.pnpEnforcementOverride;return g7({assessment:this.boundAssessment,currentItemRef:this.boundCurrentItemRef})}resolveConfiguredPnpEnforcement(){return this.config.tools?.pnpEnforcement??null}_applyToolConfigChange(Q,G){switch(Q){case"textToSpeech":{let Y=this._reconfigureTTSProvider();this.ttsReconfigurePromise=Y,Y.finally(()=>{if(this.ttsReconfigurePromise===Y)this.ttsReconfigurePromise=void 0}),Y.then(async()=>{let J=this.getTTSConfigFromProviders();if(!this.lazyInit&&J?.enabled!==!1)await this.ensureTTSReady(J)});break}case"answerEliminator":break}}async _reconfigureTTSProvider(){this.ttsInitialized=!1,this.ttsInitPromise=void 0;try{this.ttsService.stop()}catch{}if(this.toolProviderRegistry.has("tts"))await this.toolProviderRegistry.unregister("tts");let Q=this.getProviderDescriptorTools().find((G)=>G.toolId==="textToSpeech");if(!Q)return;await this.registerProviderFromTool(Q)}}var M9=()=>{};function u0(Q){let{ttsService:G,listenerId:Y,silence:J}=Q;if(typeof G?.onStateChange!=="function")return M9;let X=(j)=>{if(j!==R.PLAYING&&j!==R.LOADING)return;J()};return G.onStateChange(Y,X),()=>{try{G.offStateChange?.(Y,X)}catch{}}}function p0(Q){try{if(Q?.isPlaying?.())Q.pause?.()}catch{}}import{timedMediaProjectionSignature as n9}from"@pie-players/pie-players-shared/timed-media";var g0="pie-register",c0="pie-unregister",l0="pie-item-session-changed";var d0="pie-content-loaded",i0="pie-item-player-error",s0="pie-formative-action",n0="pie-media-time-source";var O9={bubbles:!0,composed:!0,cancelable:!1};function z9(Q,G,Y={}){return new CustomEvent(Q,{detail:G,...O9,...Y})}function b8(Q,G,Y,J={}){return Q.dispatchEvent(z9(G,Y,J))}function y7(){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 C8(Q,G){if(Q===G)return!0;if(!Q||!G)return!1;return Q.sectionId===G.sectionId&&Q.attemptId===G.attemptId}function P9(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 r0(Q){let G=Q.signals.sectionReady&&Q.signals.allLoadingComplete,Y=Q.mode==="strict"?G:Q.signals.interactionReady;return{phase:P9({...Q.signals,allLoadingComplete:G,interactionReady:Y}),interactionReady:Y,allLoadingComplete:G,reason:Q.reason}}function o0(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 R1(Q,G,Y,J="entered"){let X=o0(G);if(!X)return;Q.push({kind:"stage-change",stage:X,status:J,cohort:Y})}function a0(Q){let G={...y7(),phase:"booting-section",cohort:Q.cohort,effectiveRuntime:Q.effectiveRuntime,effectiveToolsConfig:Q.effectiveToolsConfig,itemCount:Q.itemCount},Y=[];return R1(Y,"booting-section",Q.cohort),{state:G,outputs:Y}}function L9(Q,G){if(Q.phase==="idle"||Q.phase==="disposed")return{state:Q,outputs:[]};let Y=r0({mode:G.mode,signals:G.signals}),J=[],X=Q.phase,j=Q.loadingCompleteEmitted;if(X==="engine-ready"&&Y.interactionReady)X="interactive",R1(J,X,Q.cohort);if(Y.allLoadingComplete&&Q.cohort&&!j)j=!0,J.push({kind:"loading-complete",cohort:Q.cohort,itemCount:G.itemCount,loadedCount:G.loadedCount});return{state:{...Q,phase:X,readinessSignals:G.signals,loadedCount:G.loadedCount,itemCount:G.itemCount,loadingCompleteEmitted:j},outputs:J}}function c7(Q,G){switch(G.kind){case"initialize":{if(Q.phase==="disposed")return{state:Q,outputs:[]};if(Q.phase!=="idle"){if(C8(Q.cohort,G.cohort))return c7(Q,{kind:"update-runtime",effectiveRuntime:G.effectiveRuntime,effectiveToolsConfig:G.effectiveToolsConfig});return c7(Q,{kind:"cohort-change",cohort:G.cohort,effectiveRuntime:G.effectiveRuntime,effectiveToolsConfig:G.effectiveToolsConfig,itemCount:G.itemCount})}return a0({state:Q,cohort:G.cohort,effectiveRuntime:G.effectiveRuntime,effectiveToolsConfig:G.effectiveToolsConfig,itemCount:G.itemCount})}case"update-runtime":{if(Q.phase==="idle"||Q.phase==="disposed")return{state:Q,outputs:[]};return{state:{...Q,effectiveRuntime:G.effectiveRuntime,effectiveToolsConfig:G.effectiveToolsConfig},outputs:[]}}case"cohort-change":{if(Q.phase==="disposed")return{state:Q,outputs:[]};if(C8(Q.cohort,G.cohort))return c7(Q,{kind:"update-runtime",effectiveRuntime:G.effectiveRuntime,effectiveToolsConfig:G.effectiveToolsConfig});let Y=[];if(Q.phase!=="idle")Y.push({kind:"stage-change",stage:"disposed",status:"entered",cohort:Q.cohort});let J=a0({state:Q,cohort:G.cohort,effectiveRuntime:G.effectiveRuntime,effectiveToolsConfig:G.effectiveToolsConfig,itemCount:G.itemCount});return{state:J.state,outputs:[...Y,...J.outputs]}}case"section-controller-resolved":{if(Q.phase!=="booting-section")return{state:{...Q,controllerResolved:!0},outputs:[]};let Y=[];return R1(Y,"engine-ready",Q.cohort),{state:{...Q,phase:"engine-ready",controllerResolved:!0},outputs:Y}}case"update-readiness-signals":return L9(Q,{signals:G.signals,mode:G.mode,loadedCount:G.loadedCount,itemCount:G.itemCount});case"framework-error":return{state:{...Q,lastFrameworkError:G.error,readinessSignals:{...Q.readinessSignals,runtimeError:G.error.recoverable===!0?Q.readinessSignals.runtimeError:!0}},outputs:[{kind:"framework-error",error:G.error}]};case"dispose":{if(Q.phase==="disposed")return{state:Q,outputs:[]};let Y=[];if(Q.phase!=="idle")R1(Y,"disposed",Q.cohort);return{state:{...Q,phase:"disposed"},outputs:Y}}default:{let Y=G;return{state:Q,outputs:[]}}}}class T8{state=y7();listeners=new Set;getState(){return this.state}dispatch(Q){let G=c7(this.state,Q);if(this.state=G.state,G.outputs.length>0)this.fanOut(G.outputs);return G.outputs}subscribe(Q){this.listeners.add(Q);let G=!0;return()=>{if(!G)return;G=!1,this.listeners.delete(Q)}}disposeListeners(){this.listeners.clear()}fanOut(Q){let G=Array.from(this.listeners),Y=Object.freeze(Q.slice());for(let J of G)try{J(Y)}catch(X){console.warn("[SectionEngineCore] listener failed:",X)}}}function t0(Q){let{coordinator:G,dispatchCoreInput:Y}=Q,J=0,X=null,j=null,Z=!1,K=G.subscribeFrameworkErrors((V)=>{try{Y({kind:"framework-error",error:V})}catch(H){console.warn("[CoordinatorBridge] framework-error dispatch failed:",H)}});function W(){if(!j)return;try{j()}catch(V){console.warn("[CoordinatorBridge] controller unsubscribe failed:",V)}j=null}async function B(V){if(Z)return;J+=1;let H=J;X=V.cohort;let N=await G.getOrCreateSectionController({sectionId:V.cohort.sectionId,attemptId:V.cohort.attemptId||void 0,input:{section:V.section,sectionId:V.cohort.sectionId,assessmentId:V.assessmentId,view:V.view},updateExisting:!0,createDefaultController:V.createDefaultController});if(H!==J||Z)return;W(),V.onControllerResolved?.(N);let O=N.getCompositionModel;if(V.onCompositionChanged?.(O?.()),typeof N.subscribe==="function")j=N.subscribe((P)=>{if(H!==J||Z)return;V.onCompositionChanged?.(O?.())});Y({kind:"section-controller-resolved"})}async function U(){if(Z)return;Z=!0,J+=1,W();try{K()}catch(H){console.warn("[CoordinatorBridge] framework-error unsubscribe failed:",H)}let V=X;if(X=null,V)try{await G.disposeSectionController({sectionId:V.sectionId,attemptId:V.attemptId||void 0})}catch(H){console.warn("[CoordinatorBridge] section-controller dispose failed:",H)}}return{resolveSectionController:B,dispose:U}}function e0(Q){let{runtimeId:G,sourceCe:Y}=Q,J=Q.host,X=Q.now??(()=>new Date().toISOString());function j(U){let V={stage:U.stage,status:U.status,runtimeId:G,sectionId:U.cohort?.sectionId,attemptId:U.cohort?.attemptId?U.cohort.attemptId:void 0,timestamp:X(),sourceCe:Y};J.dispatchEvent(new CustomEvent("pie-stage-change",{detail:V}))}function Z(U){let V={runtimeId:G,sectionId:U.cohort.sectionId,attemptId:U.cohort.attemptId?U.cohort.attemptId:void 0,itemCount:U.itemCount,loadedCount:U.loadedCount,timestamp:X(),sourceCe:Y};J.dispatchEvent(new CustomEvent("pie-loading-complete",{detail:V}))}function K(U){J.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":K(U);return;default:{let V=U;return}}}function B(U){J=U}return{dispatch:W,setHost:B}}function Q3(Q){let{bus:G}=Q;function Y(J){switch(J.kind){case"framework-error":G.reportFrameworkError(J.error);return;case"stage-change":case"loading-complete":return;default:{let X=J;return}}}return{dispatch:Y}}function G3(Q={}){let G=Q.hook;function Y(X){if(!G)return;try{G(X)}catch(j){console.warn("[InstrumentationBridge] hook failed:",j)}}function J(X){G=X}return{dispatch:Y,setHook:J}}function Y3(){let Q=new Set;function G(j){if(j.length===0)return;let Z=Array.from(Q),K=Object.freeze(j.slice());for(let W of Z)try{W(K)}catch(B){console.warn("[SubscriberFanout] listener failed:",B)}}function Y(j){Q.add(j);let Z=!0;return()=>{if(!Z)return;Z=!1,Q.delete(j)}}function J(){Q.clear()}function X(){return Q.size}return{emit:G,subscribe:Y,dispose:J,getListenerCount:X}}class S8{core;domEventBridge;frameworkErrorBridge;instrumentationBridge;subscriberFanout;coordinatorBridge;unsubscribeCore;disposed=!1;constructor(Q){this.core=Q.core??new T8,this.domEventBridge=e0({host:Q.host,runtimeId:Q.runtimeId,sourceCe:Q.sourceCe,now:Q.now}),this.frameworkErrorBridge=Q3({bus:Q.frameworkErrorBus}),this.instrumentationBridge=G3({hook:Q.instrumentationHook}),this.subscriberFanout=Y3(),this.coordinatorBridge=Q.coordinator?t0({coordinator:Q.coordinator,dispatchCoreInput:(G)=>this.dispatchInput(G)}):null,this.unsubscribeCore=this.core.subscribe((G)=>{this.routeOutputs(G)})}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 G of Q)this.routeOne(G);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 G=Q;return}}this.instrumentationBridge.dispatch(Q)}}var $9={mode:"gather",role:"student"};function E1(Q,G){return Q!==void 0?Q:G}function w9(Q){let G=Q.runtime??{};if(G.onFrameworkError!==void 0)return G.onFrameworkError;return Q.onFrameworkError}function R9(Q){let G=Q.runtime?.tools||{},Y=G.placement||{};return{...G,placement:{...Y}}}function E9(Q){let G=Q.runtime||{},Y=G.player?{...G.player}:null;return{...G,assessmentId:E1(G.assessmentId,Q.assessmentId),playerType:G.playerType??"iife",player:Y,lazyInit:G.lazyInit??!0,accessibility:G.accessibility??null,coordinator:G.coordinator??null,createSectionController:G.createSectionController,isolation:G.isolation??"inherit",env:G.env??$9,toolConfigStrictness:E1(G.toolConfigStrictness,Q.toolConfigStrictness)??"error",onFrameworkError:w9({runtime:Q.runtime,onFrameworkError:Q.onFrameworkError}),onStageChange:E1(G.onStageChange,Q.onStageChange),onLoadingComplete:E1(G.onLoadingComplete,Q.onLoadingComplete),tools:Q.effectiveToolsConfig}}function J3(Q,G){let Y=Q.assessmentId??"section-demo-direct",J=R9({runtime:Q.runtime}),X=E9({assessmentId:Y,runtime:Q.runtime,effectiveToolsConfig:J,toolConfigStrictness:Q.toolConfigStrictness,onFrameworkError:Q.onFrameworkError,onStageChange:Q.onStageChange,onLoadingComplete:Q.onLoadingComplete}),j=G.resolvePlayerRuntime({effectiveRuntime:X,playerType:String(X.playerType??"iife"),env:X.env??null});return{effectiveToolsConfig:J,effectiveRuntime:X,playerRuntime:j}}import{createPieLogger as C9,isGlobalDebugEnabled as T9}from"@pie-players/pie-players-shared";function b9(Q,G){if(Q===G)return 0;let Y=Q.compareDocumentPosition(G);if(Y&Node.DOCUMENT_POSITION_PRECEDING)return 1;if(Y&Node.DOCUMENT_POSITION_FOLLOWING)return-1;return 0}class y8{shellsByElement=new Map;register(Q){let G=this.shellsByElement.get(Q.element),Y={...Q,sortKey:Date.now()};if(G&&G.kind===Y.kind&&G.itemId===Y.itemId&&G.canonicalItemId===Y.canonicalItemId)return!1;return this.shellsByElement.set(Q.element,Y),!0}unregister(Q){return this.shellsByElement.delete(Q)}getOrderedShells(Q){let G=Array.from(this.shellsByElement.values()).filter((Y)=>!Q||Y.kind===Q);return G.sort((Y,J)=>b9(Y.element,J.element)),G}getCanonicalIdMap(){let Q={};for(let G of this.getOrderedShells("item")){if(!G.itemId)continue;Q[G.itemId]=G.canonicalItemId||G.itemId}return Q}clear(){this.shellsByElement.clear()}}function b1(Q="runtime"){return`${Q}-${Math.random().toString(16).slice(2)}-${Date.now()}`}var S9=C9("section-runtime-engine",()=>T9());class x8{registry=new y8;runtimeId=b1("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 S8({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)??y9}getState(){return this.adapter?.getState()??y7()}getEffectiveRuntime(Q,G){return J3(Q,G).effectiveRuntime}setInstrumentationHook(Q){this.adapter?.setInstrumentationHook(Q)}getRuntimeId(){return this.runtimeId}async initialize(Q){this.activeInitToken+=1;let G=this.activeInitToken;this.coordinator=Q.coordinator,this.sectionId=Q.sectionId,this.attemptId=Q.attemptId;let Y=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(G!==this.activeInitToken)return;this.unsubscribeController?.(),this.controller=Y,this.replayRegisteredShellsIntoController(Y),Q.onCompositionChanged?.(Y.getCompositionModel?.()),this.unsubscribeController=Y.subscribe?.((J)=>{try{Q.onControllerEvent?.(J)}catch(X){S9.warn("onControllerEvent handler threw",X)}Q.onCompositionChanged?.(Y.getCompositionModel?.())})||null}replayRegisteredShellsIntoController(Q){if(!Q.handleContentRegistered)return;let G=this.registry.getOrderedShells();if(G.length===0)return;for(let J of G){let X=J.canonicalItemId||J.itemId;Q.handleContentRegistered({itemId:J.itemId,canonicalItemId:X,contentKind:J.contentKind||J.kind})}let Y=Date.now();for(let J of G){let X=J.canonicalItemId||J.itemId,j=this.getLoadedKey(X,J.contentKind);if(this.loadedRenderableKeys.has(j))Q.handleContentLoaded?.({itemId:J.itemId,canonicalItemId:X,contentKind:J.contentKind||J.kind,timestamp:Y})}}getLoadedKey(Q,G){return`${G??""}:${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 G=Q.canonicalItemId||Q.itemId;this.loadedRenderableKeys.delete(this.getLoadedKey(G,Q.contentKind)),this.controller?.handleContentUnregistered?.({itemId:Q.itemId,canonicalItemId:G,contentKind:Q.contentKind||Q.kind})}handleContentLoaded(Q){let G=Q.canonicalItemId||Q.itemId;this.loadedRenderableKeys.add(this.getLoadedKey(G,Q.contentKind)),this.controller?.handleContentLoaded?.(Q)}handleItemPlayerError(Q){this.controller?.handleItemPlayerError?.(Q)}reportSectionError(Q){this.controller?.reportSectionError?.(Q)}updateItemSession(Q,G){let Y=this.getCanonicalItemId(Q);return this.controller?.updateItemSession?.(Y,G)??null}navigateToItem(Q){return this.controller?.navigateToItem?.(Q)??null}handleFormativeAction(Q){if(!Q?.itemId)return;let G=this.getCanonicalItemId(Q.itemId);if(Q.action==="retry"){this.controller?.retryFormativeItem?.({itemId:G});return}this.controller?.recordFormativeTry?.({itemId:G,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 y9=()=>{};import{ContextConsumer as x9,createContext as f9}from"@pie-players/pie-context";var X3=f9(Symbol.for("pie.sectionRuntimeEngineHostContext"));function Z3(Q,G){let Y=!1,J=new x9(Q,{context:X3,subscribe:!0,onValue:(W)=>{Y=!0,G(W)}});J.connect();let X=(W)=>{if(W.context!==X3)return;J.requestValue()};Q.addEventListener("context-provider",X);let j=0,Z=200,K=globalThis.setInterval(()=>{if(Y||j>=Z){globalThis.clearInterval(K);return}j+=1,J.requestValue()},50);return()=>{globalThis.clearInterval(K),Q.removeEventListener("context-provider",X),J.disconnect()}}var k9=(Q)=>{console.error("[pie-assessment-toolkit] onStageChange handler threw",Q)};function j3(Q,G){if(Q.isSuppressed())return!1;Q.dispatchDomEvent(G);let Y=Q.getOnStageChange();if(Y)try{Y(G)}catch(J){(Q.logHandlerError??k9)(J)}return!0}function l7(Q,G){if(typeof Q==="function")return Q;if(Q===null)return null;return typeof G==="function"?G:null}function K3(Q={}){let G=Q.frameDeadlineMs??100,Y=!1,J=null,X=null,j=null,Z=null,K=null;function W(){if(Y=!1,X!==null)Z?.(X),X=null;if(j!==null)K?.(j),j=null;Z=null,K=null}function B(H){if(!Y)return;if(H==="frame")X=null;if(H==="timer")j=null;let N=J;J=null,W(),N?.()}function U(H){if(J=H,Y)return;Y=!0;let N=globalThis,O=l7(Q.requestFrame,N.requestAnimationFrame);Z=l7(Q.cancelFrame,N.cancelAnimationFrame);let P=l7(Q.setTimer,N.setTimeout);if(K=l7(Q.clearTimer,N.clearTimeout),O){let F=O(()=>B("frame"));if(!Y)return;if(X=F,P){let L=P(()=>B("timer"),G);if(Y)j=L}return}let $=l7(Q.queueMicrotaskFn,N.queueMicrotask);if($){$(()=>B("microtask"));return}if(P){let F=P(()=>B("timer"),0);if(Y)j=F;return}B("microtask")}function V(){if(!Y)return;J=null,W()}return{schedule:U,cancel:V,isPending:()=>Y}}function q3(){return{lastSessionEventSignatureByItemId:new Map,lastMetadataSignatureByItemId:new Map}}function W3(Q){Q.lastSessionEventSignatureByItemId.clear(),Q.lastMetadataSignatureByItemId.clear()}function U3(Q){let{state:G,itemId:Y,payload:J}=Q;if(v9(J)){let Z=h9(J);if(G.lastMetadataSignatureByItemId.get(Y)===Z)return!1;G.lastMetadataSignatureByItemId.set(Y,Z)}let X=I9(J);if(G.lastSessionEventSignatureByItemId.get(Y)===X)return!1;return G.lastSessionEventSignatureByItemId.set(Y,X),!0}function I9(Q){let G={...Q};delete G.timestamp,delete G.sourceRuntimeId;try{return JSON.stringify(G)}catch{return String(G.itemId||"")}}function v9(Q){return Q.intent==="metadata-only"}function h9(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 m9=(Q,G)=>{if(customElements.get(Q))return;try{customElements.define(Q,G)}catch(Y){if(!(Y instanceof DOMException&&Y.name==="NotSupportedError"||Y&&typeof Y==="object"&&Y.name==="NotSupportedError")||!customElements.get(Q))throw Y}},r9=v8('<div class="pie-assessment-toolkit-error svelte-vpe4u2" role="alert" aria-live="assertive"><div class="pie-assessment-toolkit-error-title svelte-vpe4u2"> </div> <div class="pie-assessment-toolkit-error-message svelte-vpe4u2"> </div> <pre class="pie-assessment-toolkit-error-details svelte-vpe4u2"> </pre></div>'),o9=v8('<div class="pie-assessment-toolkit-anchor svelte-vpe4u2" aria-hidden="true"></div> <!>',1),a9={hash:"svelte-vpe4u2",code:`.pie-assessment-toolkit-anchor.svelte-vpe4u2 {display:none;}.pie-assessment-toolkit-error.svelte-vpe4u2 {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-vpe4u2 {font-weight:600;margin-bottom:0.25rem;}.pie-assessment-toolkit-error-message.svelte-vpe4u2 {margin-bottom:0.5rem;}.pie-assessment-toolkit-error-details.svelte-vpe4u2 {margin:0;white-space:pre-wrap;word-break:break-word;}`};function w3(Q,G){_3(G,!0),M3(Q,a9);let Y=b1("toolkit"),J=new x8,X=h(null),j=new m7,Z={mode:"gather",role:"student"},K={iife:"pie-item-player",esm:"pie-item-player",preloaded:"pie-item-player",custom:""},W=x(G,"assessmentId",7,""),B=x(G,"section",7,null),U=x(G,"sectionId",7,""),V=x(G,"attemptId",7,""),H=x(G,"env",23,()=>({})),N=x(G,"ndsIcons",7,!1),O=x(G,"locale",7,""),P=x(G,"lazyInit",7,!0),$=x(G,"toolConfigStrictness",7,"error"),F=x(G,"tools",23,()=>({})),L=x(G,"toolContextResolvers",7,null),C=x(G,"enabledTools",7,""),v=x(G,"toolRegistry",7,null),I=x(G,"accessibility",23,()=>({})),p=x(G,"player",7,null),E=x(G,"playerType",7,""),g=x(G,"coordinator",7,null),j7=x(G,"createSectionController",7,null),K7=x(G,"onFrameworkError",7,null),q7=x(G,"errorRenderer",7,null),$7=x(G,"onStageChange",7,null),s7=x(G,"assessment",7,null),n7=x(G,"currentItemRef",7,null),r7=x(G,"pnpEnforcement",7,null),W7=x(G,"isolation",7,"inherit"),x7=h(null),d=h(null),Y7=h(null),h8=null,f7=null,k7=null,o7=null,I7=null,a7=null,t7=h(0),y1=h(null),e7=h(null),r=h(null),x1=h("Unable to initialize assessment toolkit."),f1=h(f8([])),m8="",k1="",u8=h(""),p8=null,g8=K3(),U7=[],Q1=new Map,I1=new WeakMap,c8=q3(),i=g9({sourceCe:"pie-assessment-toolkit",sourceCeShape:"toolkit",runtimeId:Y,sectionId:m(()=>U()||void 0),attemptId:m(()=>V()||void 0),emit:(q)=>{j3({isSuppressed:()=>_(X)!==null,dispatchDomEvent:(D)=>B7("pie-stage-change",D),getOnStageChange:()=>$7()},q)}}),l8=h(f8(m(()=>`${U()}|${V()}`))),G1=h(!1),t=h(!1),v1=h(!1),h1=h(!1);function R3(){if(!_(x7))return null;let q=_(x7).getRootNode();if(q&&"host"in q)return q.host;return _(x7).parentElement}let f=n(()=>R3());function B7(q,D){if(!_(f)){U7=[...U7,{name:q,detail:D}];return}b8(_(f),q,D)}b(()=>{if(!_(f))return;if(U7.length===0)return;let q=U7;U7=[],queueMicrotask(()=>{let D=_(f);if(!D){U7=[...q,...U7];return}for(let M of q)b8(D,M.name,M.detail)})});function E3(q){if(!q7())return{title:"Unable to initialize assessment toolkit.",details:q.details.length>0?q.details:[q.message]};try{let D=q7()(q)||{};return{title:typeof D.title==="string"&&D.title.trim().length>0?D.title:"Unable to initialize assessment toolkit.",details:Array.isArray(D.details)&&D.details.length>0?D.details.map((M)=>String(M)):q.details.length>0?q.details:[q.message]}}catch(D){let M=D instanceof Error&&D.message.trim().length>0?D.message:String(D||"Unknown renderer error");return{title:"Unable to initialize assessment toolkit.",details:[...q.details,`Error renderer failed: ${M}`]}}}function v7(q){let D=K1({kind:q.kind,source:q.source,error:q.error,recoverable:q.recoverable});return j.reportFrameworkError(D),D}function b3(q){if(q?.type==="timed-media-policy-degraded"){let M=q.degradations||[];j.reportFrameworkError(j1({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 D=q.errors||[];j.reportFrameworkError(j1({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:D.map((M)=>M?.message).filter((M)=>typeof M==="string"),recoverable:!1}))}function C3(q){if(q?.type!=="timed-media-audio-started")return;if(!_(S))return;p0(_(S).getServiceBundle().ttsService)}function T3(q){return q==="coordinator-init"||q==="runtime-init"||q==="tool-config"}function d8(q){if(!K7())return;try{K7()(q),m8=`${q.kind}|${q.source}|${q.message}`}catch(D){console.error(`[pie-framework:${q.kind}:${q.source}] framework error hook failed`,D)}}b(()=>{let q=j.subscribeFrameworkErrors((D)=>{if(console.error(Y6(D),D.cause),T3(D.kind)){let M=E3(D);w(r,D,!0),w(x1,M.title,!0),w(f1,M.details,!0)}B7("framework-error",D),d8(D)});return()=>{q()}}),b(()=>{if(!_(r))return;let q=`${_(r).kind}|${_(r).source}|${_(r).message}`;if(m8===q)return;d8(_(r))});function S3(q){let D=5381;for(let M=0;M<q.length;M+=1)D=(D<<5)+D^q.charCodeAt(M);return(D>>>0).toString(36)}function s(q){return q&&typeof q==="object"?q:{}}function y3(q){let D=s(q.section),M=typeof D.identifier==="string"?D.identifier:"",z=typeof q.sectionId==="string"?q.sectionId:"";return M||z}function x3(q){return typeof q.currentItemIndex==="number"?q.currentItemIndex:-1}function f3(q){return(Array.isArray(q.renderables)?q.renderables:[]).map((M,z)=>{let A=s(M),k=s(A.entity),o=typeof k.id==="string"&&k.id||`renderable-${z}`,Z1=s(k.config),c1=typeof k.version==="string"&&k.version||(typeof k.version==="number"?String(k.version):"")||(typeof Z1.version==="string"?Z1.version:"");return{id:o,version:c1}})}function k3(q){let D=s(q.itemSessionsByItemId);return Object.keys(D).sort((M,z)=>M.localeCompare(z)).map((M)=>{let z=s(D[M]),A=typeof z.id==="string"?z.id:"",k=Array.isArray(z.data)?z.data:[],o="";try{o=S3(JSON.stringify(k))}catch{o=String(k.length)}return{itemId:M,sessionId:A,payloadSignature:o}})}function I3(q){let D=s(s(q.formative).states);return Object.entries(D).map(([M,z])=>{let A=s(z),k=s(A.lastOutcome).correctness??"";return`${M}:${A.tryCount??0}:${A.revealed===!0?1:0}:${String(k)}:${String(A.revealOverride??"")}`}).sort().join("|")}function v3(q){let D=q.timedMedia;return n9(D)}function h3(q){let D=s(q),M=f3(D).map((A)=>`${A.id}:${A.version}`).join("|"),z=k3(D).map((A)=>`${A.itemId}:${A.sessionId}:${A.payloadSignature}`).join("|");return{sectionId:y3(D),currentItemIndex:x3(D),renderableSignature:M,itemSessionSignature:z,formativeSignature:I3(D),timedMediaSignature:v3(D)}}function m3(q){let D=h3(q);return`${D.sectionId}|${D.currentItemIndex}|${D.renderableSignature}|${D.itemSessionSignature}|${D.formativeSignature}|${D.timedMediaSignature}`}function i8(q){return q==="iife"||q==="esm"||q==="preloaded"||q==="custom"}function u3(q,D){let M=q?.type,z=i8(M)?M:i8(D)?D:q?.tagName?"custom":"iife",A=q?.tagName?.trim();if(z==="custom"&&!A)return{type:"iife",tagName:K.iife,version:void 0,source:void 0,isDefault:!0};return{type:z,tagName:A||K[z],version:q?.version,source:q?.source,loaderConfig:q?.loaderConfig,loaderOptions:q?.loaderOptions,isDefault:!q&&!D}}function s8(q){let D=q||{},M=typeof D.mode==="string"&&D.mode.trim()?D.mode.trim():Z.mode,z=typeof D.role==="string"&&D.role.trim()?D.role.trim():Z.role;return{mode:M,role:z}}function p3(q){let D=s8(q);if(D.mode==="author")return"author";if(D.role==="instructor")return"scorer";return"candidate"}async function g3(){if(j7())return j7()();throw Error("pie-assessment-toolkit requires createSectionController when no coordinator hook provides one")}function n8(){let q=F()||{},D=$3(C());if(D.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:D}}}function c3(){return X7(n8(),{strictness:$(),source:"pie-assessment-toolkit.bootstrap",toolRegistry:v()}).config}function l3(){let q="",D="";try{q=JSON.stringify(n8())}catch{q="[unserializable-tools]"}try{D=JSON.stringify(Object.entries(L()??{}).map(([M,z])=>[M,typeof z]))}catch{D="[unserializable-resolvers]"}return[W()||"",String($()||"error"),q,D].join("|")}function r8(q){return q==="on"||q==="off"?q:null}function d3(q,D){let M=r8(q);if(M)return M;if(D&&typeof D==="object"){let A=D.pnpEnforcement;return r8(typeof A==="string"?A:null)}return null}function i3(q){let D=W()||B()?.identifier||`assessment-${Math.random().toString(16).slice(2)}`;return new w1({assessmentId:D,lazyInit:P(),toolConfigStrictness:$(),deferToolConfigValidation:!0,tools:q,toolRegistry:v(),toolContextResolvers:L(),accessibility:I(),frameworkErrorBus:j})}let S=n(()=>{if(W7()!=="force"&&_(Y7)?.coordinator)return _(Y7).coordinator;return g()||_(d)});b(()=>{_(f),g(),W7(),_(Y7),L(),m(()=>{if(!_(f))return;if(g()){if(_(d))w(d,null);f7=null;return}if(W7()!=="force"&&_(Y7)?.coordinator){if(_(d))w(d,null);f7=null;return}if(_(d)&&f7!==L()){try{_(d).setToolContextResolvers(L()),f7=L()}catch(q){w(e7,q,!0),v7({kind:"coordinator-init",phase:"coordinator-ready",error:q})}return}if(!_(d)){let q=l3();if(k1===q)return;try{let D=c3();w(d,i3(D),!0),f7=L(),k1="",w(r,null),w(x1,"Unable to initialize assessment toolkit."),w(f1,[],!0)}catch(D){w(e7,D,!0),w(d,null),k1=q,v7({kind:"coordinator-init",source:"pie-assessment-toolkit",error:D})}}})});let Y1=i9(),m1=h(0);b(()=>Y1.subscribe(()=>{w(m1,_(m1)+1)})),b(()=>{let q=typeof O()==="string"?O().trim():"";m(()=>{Promise.resolve(Y1.setLocale(q||s9)).catch((D)=>{v7({kind:"i18n-locale-load",source:"pie-assessment-toolkit",error:D instanceof Error?D:Error(String(D))})})})});let J7=n(()=>W()||_(S)?.assessmentId||""),e=n(()=>U()||B()?.identifier||`section-${_(J7)||"default"}`),u1=n(()=>s8(H())),s3=n(()=>p3(_(u1))),w7=n(()=>u3(p(),E())),h7=n(()=>c9({player:_(w7),component:"pie-assessment-toolkit"})),J1=n(()=>{if(!_(S))return null;let q=_(S).getServiceBundle();return{toolkitCoordinator:_(S),toolCoordinator:_(S).toolCoordinator,ttsService:q.ttsService,highlightCoordinator:q.highlightCoordinator,catalogResolver:q.catalogResolver,elementToolStateStore:q.elementToolStateStore,assessmentId:_(J7),sectionId:_(e),itemPlayer:_(w7),ndsIcons:N()===!0,locale:(_(m1),Y1.getLocale()),i18n:Y1,reportSessionChanged:(D,M)=>{let z=J.updateItemSession(D,M);t8({itemId:D,result:z,fallbackSession:M})}}}),X1=n(()=>{if(!_(S))return null;return{runtimeId:Y,coordinator:_(S)}});function n3(q){let D=m3(q);if(D===_(u8))return;w(u8,D,!0),w(t7,_(t7)+1),w(y1,q,!0),B7("composition-changed",{composition:_(y1),version:_(t7)})}function p1(q){p8=q??J.getCompositionModel(),g8.schedule(()=>{n3(p8)})}function g1(q){if(!q)return;let D=I1.get(q);if(!D)return;for(let M of D)M();I1.delete(q)}function o8(){for(let q of Q1.values())g1(q.element)}function a8(q){if(g1(q.element),!_(S))return;let D=_(S).getServiceBundle().catalogResolver;I1.set(q.element,[D.registerOwner({owner:{kind:q.kind,itemId:q.itemId,canonicalItemId:q.canonicalItemId,assessmentId:_(J7),sectionId:_(e)},entity:q.item})])}function r3(){o8();for(let q of Q1.values())a8(q)}function t8(q){let M={...q.result?.eventDetail||q.fallbackSession,itemId:q.itemId,canonicalItemId:q.canonicalItemId||q.itemId,sourceRuntimeId:Y};if(!U3({state:c8,itemId:q.itemId,payload:M}))return;B7("session-changed",M)}function o3(q){if(!(q instanceof HTMLElement))return!1;return u9(q,I8)?.runtimeId===Y}function D7(q){return q.detail??null}function a3(q,D){for(let M of D)q.addEventListener(M.name,M.handler);return()=>{for(let M of D)q.removeEventListener(M.name,M.handler)}}b(()=>{if(!_(f))return;if(W7()==="force"){w(Y7,null);return}return L3(_(f),(q)=>{if(q.runtimeId===Y)return;w(Y7,q,!0)})}),b(()=>{let q=_(f);return m(()=>{if(!q){w(X,null);return}let D=Z3(q,(M)=>{if(M.engine===_(X))return;w(X,M.engine,!0)});return()=>{D(),w(X,null)}})}),b(()=>{let q=_(S);if(!q)return;return m(()=>u0({ttsService:q.getServiceBundle().ttsService,listenerId:`timed-media-audio-handoff:${Y}`,silence:()=>J.requestMediaPauseForCompetingAudio()}))}),b(()=>{let q=W7()!=="force"&&_(Y7)?_(Y7).runtimeId:null,D=q?"inherited":"owned";if(D!==h8)h8=D,B7(D==="inherited"?"runtime-inherited":"runtime-owned",{runtimeId:Y,parentRuntimeId:q})}),b(()=>{let q=_(e),D=V()||"";W3(c8)}),b(()=>{if(!_(f)||!_(X1))return;return I7=new B3(_(f),{context:I8,initialValue:_(X1)}),I7.connect(),a7=new D3(_(f)),a7.attach(),()=>{a7?.detach(),a7=null,I7?.disconnect(),I7=null}}),b(()=>{if(!_(X1))return;I7?.setValue(_(X1))}),b(()=>{if(!_(f))return;_(f).setAttribute("data-item-player-type",_(w7).type),_(f).setAttribute("data-item-player-tag",_(w7).tagName),_(f).setAttribute("data-env-mode",String(_(u1)?.mode||"")),_(f).setAttribute("data-env-role",String(_(u1)?.role||""))}),b(()=>{if(!_(f)||!_(J1))return;return k7=new B3(_(f),{context:P3,initialValue:_(J1)}),k7.connect(),o7=new D3(_(f)),o7.attach(),()=>{o7?.detach(),o7=null,k7?.disconnect(),k7=null}}),b(()=>{if(_(J1))k7?.setValue(_(J1))}),b(()=>{return _(S),_(J7),_(e),r3(),()=>{o8()}}),b(()=>{if(!_(f))return;return p9({host:_(f),instrumentationProvider:_(h7),component:"pie-assessment-toolkit",eventMap:l9,staticAttributes:{instrumentationLayer:"toolkit",assessmentId:_(J7),sectionId:_(e),attemptId:V()||void 0}})}),b(()=>{s7(),n7(),r7(),F();let q=_(S);if(!q)return;if(q!==_(d))return;m(()=>{q.setPnpEnforcement(d3(r7(),F())),q.updateAssessment(s7()),q.updateCurrentItemRef(n7())})}),b(()=>{if(!_(S))return;return _(S).subscribeTelemetry(({eventName:q,payload:D})=>{if(!d9(_(h7)))return;if(!_(h7).isReady())return;let M=q,z=new Date().toISOString(),A={...D||{},instrumentationLayer:"toolkit",assessmentId:_(J7),sectionId:_(e),attemptId:V()||void 0,component:"pie-assessment-toolkit",sourceEventName:q,timestamp:z};_(h7).trackEvent(M,A);let k=D&&typeof D.errorType==="string"?D.errorType:void 0;if(!q.endsWith("-error")&&!k)return;let o=D&&typeof D.message==="string"?D.message:`Toolkit telemetry error: ${q}`;_(h7).trackError(Error(o),{component:"pie-assessment-toolkit",errorType:k||"ToolkitTelemetryError",...A})})}),b(()=>{if(!B()||!_(S))return;let q=!1;return J.initialize({coordinator:_(S),section:B(),sectionId:_(e),assessmentId:_(J7),attemptId:V()||void 0,view:_(s3),createDefaultController:g3,onCompositionChanged:(D)=>{if(q)return;p1(D)},onControllerEvent:(D)=>{if(q)return;C3(D),b3(D)}}).then(()=>{if(q)return;B7("toolkit-ready",{runtimeId:Y,assessmentId:_(J7),sectionId:_(e),itemPlayer:_(w7),coordinator:_(S)}),B7("section-ready",{sectionId:_(e)}),m(()=>{w(h1,!0)})}).catch((D)=>{m(()=>{if(!_(t))w(t,!0),i.enter("engine-ready","skipped");i.enter("interactive","failed")}),w(e7,D,!0),J.reportSectionError({source:"section-runtime",error:D,timestamp:Date.now()}),v7({kind:"runtime-init",source:"pie-assessment-toolkit",error:D})}),()=>{q=!0}}),b(()=>{if(!_(f))return;let q=_(f),D=(z)=>o3(z.target);return a3(q,[{name:g0,handler:(z)=>{if(!D(z))return;let A=D7(z);if(!A?.element||!A?.itemId)return;let k=J.register(A);if(Q1.set(A.element,A),a8(A),J.handleContentRegistered(A),k)p1()}},{name:c0,handler:(z)=>{if(!D(z))return;let A=D7(z);if(!A?.itemId)return;let k=A?.element?J.unregister(A.element):!1;if(g1(A.element),A.element)Q1.delete(A.element);if(J.handleContentUnregistered(A),k)p1()}},{name:l0,handler:(z)=>{if(!D(z))return;let A=D7(z);if(!A?.itemId)return;let k=J.updateItemSession(A.itemId,A.session);t8({itemId:A.itemId,canonicalItemId:J.getCanonicalItemId(A.itemId),result:k,fallbackSession:A.session})}},{name:d0,handler:(z)=>{if(!D(z))return;let A=D7(z);if(!A?.itemId)return;J.handleContentLoaded({itemId:A.itemId,canonicalItemId:A.canonicalItemId,contentKind:A.contentKind,detail:A.detail,timestamp:Date.now()})}},{name:i0,handler:(z)=>{if(!D(z))return;let A=D7(z);if(!A?.itemId)return;J.handleItemPlayerError({itemId:A.itemId,canonicalItemId:A.canonicalItemId,contentKind:A.contentKind,error:A.error,timestamp:Date.now()})}},{name:s0,handler:(z)=>{if(!D(z))return;let A=D7(z);if(!A?.itemId)return;if(A.action!=="check"&&A.action!=="retry")return;J.handleFormativeAction({itemId:A.canonicalItemId||A.itemId,action:A.action,outcomes:A.outcomes})}},{name:n0,handler:(z)=>{if(!D(z))return;let A=D7(z);if(!A?.renderableId)return;if(A.action!=="attach"&&A.action!=="detach")return;J.handleMediaTimeSource({renderableId:A.renderableId,action:A.action,source:A.source,origin:A.origin})}}])});async function t3(){if(!_(S))throw Error("Coordinator not initialized");await _(S).waitUntilReady()}function e3(){if(!_(S))throw Error("Coordinator not initialized");return _(S).getServiceBundle()}function Q5(q){if(!_(S))throw Error("Coordinator not initialized");_(S).setHooks(q)}function G5(q){return J.navigateToItem(q)}function Y5(){return J.getCompositionModel()}function J5(){return _(w7)}async function X5(){await J.persist()}async function Z5(){await J.hydrate()}b(()=>{return()=>{m(()=>{if(i.getCurrent()!==null)i.enter("disposed")})}}),b(()=>{let q=`${U()}|${V()}`;m(()=>{if(q===_(l8))return;if(i.getCurrent()!==null)i.enter("disposed");i.reset({sectionId:U()||void 0,attemptId:V()||void 0}),w(l8,q),w(G1,!1),w(t,!1),w(v1,!1),w(h1,!1)})}),b(()=>{let q=_(t)&&_(h1);m(()=>{if(!q)return;if(_(v1))return;w(v1,!0),i.enter("interactive")})}),b(()=>{let q=_(t7)>0||_(y1)!==null;m(()=>{if(!_(G1)&&q)w(G1,!0),i.enter("composed")})}),b(()=>{if(!_(S))return;if(!_(G1))return;if(_(t))return;let q=_(S),D=!1;return q.waitUntilReady().then(()=>{if(D)return;m(()=>{if(_(t))return;w(t,!0),i.enter("engine-ready")})}).catch(()=>{if(D)return;m(()=>{if(_(t))return;w(t,!0),i.enter("engine-ready","failed")})}),()=>{D=!0}}),b(()=>{return()=>{g8.cancel(),J.dispose().catch((q)=>{w(e7,q,!0),v7({kind:"runtime-dispose",source:"pie-assessment-toolkit",error:q,recoverable:!0})}).finally(()=>{j.dispose()})}});var j5={waitUntilReady:t3,getServiceBundle:e3,setHooks:Q5,navigateToItem:G5,getCompositionModel:Y5,getItemPlayerConfig:J5,persist:X5,hydrate:Z5,get assessmentId(){return W()},set assessmentId(q){W(q),y()},get section(){return B()},set section(q){B(q),y()},get sectionId(){return U()},set sectionId(q){U(q),y()},get attemptId(){return V()},set attemptId(q){V(q),y()},get env(){return H()},set env(q){H(q),y()},get ndsIcons(){return N()},set ndsIcons(q){N(q),y()},get locale(){return O()},set locale(q){O(q),y()},get lazyInit(){return P()},set lazyInit(q){P(q),y()},get toolConfigStrictness(){return $()},set toolConfigStrictness(q){$(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 I()},set accessibility(q){I(q),y()},get player(){return p()},set player(q){p(q),y()},get playerType(){return E()},set playerType(q){E(q),y()},get coordinator(){return g()},set coordinator(q){g(q),y()},get createSectionController(){return j7()},set createSectionController(q){j7(q),y()},get onFrameworkError(){return K7()},set onFrameworkError(q){K7(q),y()},get errorRenderer(){return q7()},set errorRenderer(q){q7(q),y()},get onStageChange(){return $7()},set onStageChange(q){$7(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 W7()},set isolation(q){W7(q),y()}},e8=o9(),Q6=k8(e8);O3(Q6,(q)=>w(x7,q),()=>_(x7));var K5=C1(Q6,2);{var q5=(q)=>{var D=r9(),M=i7(D),z=i7(M,!0);d7(M);var A=C1(M,2),k=i7(A,!0);d7(A);var o=C1(A,2),Z1=i7(o,!0);d7(o),d7(D),H3((c1)=>{S1(z,_(x1)),S1(k,_(r).message),S1(Z1,c1)},[()=>_(f1).join(`
|
|
225
|
-
`)]),
|
|
223
|
+
`}return J}function R8(G){let{request:Q,tools:Y,pnpPolicy:J,customSources:X,contextId:j}=G,Z=new O1(j);Z.addSource("host",{id:Q.scope.scopeId,name:`${Q.level}:${Q.scope.scopeId}`,config:{placement:Y.placement,policy:Y.policy}});let K=L7(Y.placement[Q.level]),W=L7(Y.policy.allowed),B=new Set(L7(Y.policy.blocked)),U=[];for(let A of K)U.push(A),Z.addDecision({precedence:0,rule:"placement-membership",featureId:A,action:"skip",sourceType:"host",reason:`Listed in tools.placement.${Q.level}`});if(U=U.filter((A)=>{if(Y.providers?.[A]?.enabled===!1)return Z.addDecision({precedence:0,rule:"provider-disabled",featureId:A,action:"block",sourceType:"host",reason:`tools.providers.${A}.enabled === false`,value:!1}),!1;return!0}),W.length>0){let A=new Set(W);U=U.filter((L)=>{if(!A.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((A)=>{if(B.has(A))return Z.addDecision({precedence:0,rule:"host-blocked",featureId:A,action:"block",sourceType:"host",reason:"Listed in tools.policy.blocked",value:Y.policy.blocked}),!1;return!0});let V=[],H=new Map;for(let A of U)H.set(A,["placement"]);let N=new Set(U),M=null;if(J.enforcement==="on"&&J.source&&(J.assessment||J.currentItemRef)){if(M=J.source.apply({assessment:J.assessment,currentItemRef:J.currentItemRef}),M.sources.assessment)Z.addSource("assessment",M.sources.assessment);if(M.sources.student)Z.addSource("student",M.sources.student);if(M.sources.item)Z.addSource("item",M.sources.item);for(let A of M.decisions)Z.addDecision({precedence:A.precedence,rule:A.rule,featureId:A.featureId,action:A.action,sourceType:A.sourceType,reason:A.reason,value:A.value});for(let A of M.unmappedSupportIds)V.push({code:"tool-policy.unknownSupportId",level:Q.level,toolId:A,message:`No registered tool claims PNP support id "${A}"; 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((A)=>{return!M.blockedToolIds.has(A)});for(let A of Array.from(H.keys()))if(M.blockedToolIds.has(A))H.delete(A);for(let A of M.mandatedToolIds){if(!!N.has(A))continue;let v=M.perToolFlags.get(A)?.rule??"required-tool",I=HQ(A,{placement:K,allowed:W,blocked:B,providers:Y.providers}),p={rule:v,hostRule:I.hostRule,hostValue:I.hostValue};V.push({code:"tool-policy.requiredToolBlocked",level:Q.level,toolId:A,message:`Profile policy mandates "${A}" (${v}) but host policy removed it from level "${Q.level}" via ${I.hostRule}.`,details:p}),Z.addDecision({precedence:0,rule:"required-tool-blocked",featureId:A,action:"advisory",sourceType:"host",reason:`Host removed required tool "${A}" via ${I.hostRule}`,value:p})}for(let A of U){let L=M.perToolFlags.get(A);if(L){let T=H.get(A)??[];T.push(`pnp.${L.rule}`),H.set(A,T)}}}for(let A=0;A<X.length;A++){let L=X[A],T=U.slice(),v=L.refine({request:Q,candidates:T}),I=new Set(v.refinedCandidates);for(let E of v.refinedCandidates)if(!T.includes(E))V.push({code:"tool-policy.placementMissing",level:Q.level,toolId:E,message:`Custom source "${L.id}" tried to add tool "${E}" that was not in candidates; ignored.`,source:`custom.${L.id}`}),I.delete(E);U=T.filter((E)=>I.has(E));let p=new Set;if(v.decisions){for(let E of v.decisions)if(Z.addDecision({precedence:E.precedence??100+A,rule:E.rule,featureId:E.featureId,action:E.action,sourceType:E.sourceType,reason:E.reason,value:E.value}),E.action==="block")p.add(E.featureId)}for(let E of T){if(I.has(E))continue;if(p.has(E))continue;Z.addDecision({precedence:100+A,rule:"custom-source",featureId:E,action:"block",sourceType:"custom",reason:`Custom policy source "${L.id}" removed tool "${E}" from candidates without emitting a decision; auto-logged for trail completeness.`,value:{customSourceId:L.id}})}for(let E of U){let g=H.get(E)??["placement"];g.push(`custom.${L.id}`),H.set(E,g)}for(let E of T)if(!I.has(E))H.delete(E)}let P=new Set(U),$=U.map((A)=>{let L=M?.perToolFlags.get(A);return{toolId:A,required:L?.required??!1,alwaysAvailable:L?.alwaysAvailable??!1,settings:L?.settings,sources:H.get(A)??["placement"]}});return Z.reconcileFinalStates(P),{visibleTools:$,diagnostics:V,provenance:Z.build()}}function HQ(G,Q){if(!Q.placement.includes(G))return{hostRule:"placement-missing",hostValue:Q.placement};if(Q.providers?.[G]?.enabled===!1)return{hostRule:"provider-disabled",hostValue:!1};if(Q.allowed.length>0&&!Q.allowed.includes(G))return{hostRule:"host-allowlist",hostValue:Q.allowed};if(Q.blocked.has(G))return{hostRule:"host-blocked",hostValue:Array.from(Q.blocked)};return{hostRule:"placement-missing",hostValue:Q.placement}}function h0(G){if(!G)return!1;let Q=G.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;if(Array.isArray(Q.activateAtInit)&&Q.activateAtInit.length>0)return!0}let Y=G.settings;if(Y){let J=Y.districtPolicy;if(J){if(Array.isArray(J.blockedTools)&&J.blockedTools.length>0)return!0;if(Array.isArray(J.requiredTools)&&J.requiredTools.length>0)return!0;if(J.policies&&typeof J.policies==="object"&&Object.keys(J.policies).length>0)return!0}let X=Y.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 m0(G){let Q=G?.settings;if(!Q)return!1;if(Array.isArray(Q.requiredTools)&&Q.requiredTools.length>0)return!0;if(Array.isArray(Q.restrictedTools)&&Q.restrictedTools.length>0)return!0;if(Q.toolParameters&&typeof Q.toolParameters==="object"&&Object.keys(Q.toolParameters).length>0)return!0;return!1}function g7(G){if(h0(G.assessment))return"on";if(m0(G.currentItemRef))return"on";return"off"}class P1{id="pnp";toolRegistry;constructor(G){this.toolRegistry=G}apply(G){let{ctx:Q,result:Y}=this.prepare(G),{pnp:J,districtPolicy:X,itemSettings:j}=Q,Z=new Set;J?.supports?.forEach((K)=>Z.add(K)),J?.prohibitedSupports?.forEach((K)=>Z.add(K)),X?.blockedTools?.forEach((K)=>Z.add(K)),X?.requiredTools?.forEach((K)=>Z.add(K)),j?.requiredTools?.forEach((K)=>Z.add(K)),j?.restrictedTools?.forEach((K)=>Z.add(K));for(let K of Z)this.resolveSupport(K,Q,Y);return Y}resolveFeature(G,Q){let{ctx:Y,result:J}=this.prepare(Q);return this.resolveSupport(G,Y,J),J}prepare(G){let{assessment:Q,currentItemRef:Y}=G,J=Q?.personalNeedsProfile,X=Q?.settings,j=Y?.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:Q?.id||"unknown",name:Q?.name||Q?.id||"Assessment",config:X};if(J)Z.sources.student={id:"student",name:"Student PNP Profile",config:J};if(Y&&j)Z.sources.item={id:Y.identifier,name:Y.identifier,config:j};return{ctx:{pnp:J,districtPolicy:X?.districtPolicy,testAdmin:X?.testAdministration,itemSettings:j,toolConfigs:X?.toolConfigs},result:Z}}resolveSupport(G,Q,Y){if(Q.districtPolicy?.blockedTools?.includes(G)){let X=this.mapSupportToToolId(G,Y);Y.blockedToolIds.add(X),Y.decisions.push({precedence:1,rule:"district-block",featureId:X,action:"block",sourceType:"assessment",reason:`District policy blocks "${G}" for all assessments`,value:Q.districtPolicy.blockedTools});return}if(Q.testAdmin?.toolOverrides?.[G]===!1){let X=this.mapSupportToToolId(G,Y);Y.blockedToolIds.add(X),Y.decisions.push({precedence:2,rule:"test-admin-override",featureId:X,action:"block",sourceType:"assessment",reason:`Test administrator disabled "${G}" for this session`,value:Q.testAdmin.toolOverrides});return}if(Q.itemSettings?.restrictedTools?.includes(G)){let X=this.mapSupportToToolId(G,Y);Y.blockedToolIds.add(X),Y.decisions.push({precedence:3,rule:"item-restriction",featureId:X,action:"block",sourceType:"item",reason:`Item restricts "${G}" (e.g., mental math question blocks calculator)`,value:Q.itemSettings.restrictedTools});return}if(Q.itemSettings?.requiredTools?.includes(G)){let X=this.mapSupportToToolId(G,Y);Y.mandatedToolIds.add(X),Y.perToolFlags.set(X,{required:!0,alwaysAvailable:!1,settings:this.resolveToolSettings(G,Q),rule:"item-requirement",sourceType:"item"}),Y.decisions.push({precedence:4,rule:"item-requirement",featureId:X,action:"enable",sourceType:"item",reason:`Item requires "${G}" for this question`,value:Q.itemSettings.requiredTools});return}if(Q.districtPolicy?.requiredTools?.includes(G)){let X=this.mapSupportToToolId(G,Y);Y.mandatedToolIds.add(X),Y.perToolFlags.set(X,{required:!0,alwaysAvailable:!1,settings:this.resolveToolSettings(G,Q),rule:"district-requirement",sourceType:"assessment"}),Y.decisions.push({precedence:5,rule:"district-requirement",featureId:X,action:"enable",sourceType:"assessment",reason:`District policy requires "${G}" for all assessments`,value:Q.districtPolicy.requiredTools});return}if(Q.pnp?.prohibitedSupports?.includes(G)){let X=this.mapSupportToToolId(G,Y);Y.blockedToolIds.add(X),Y.decisions.push({precedence:6,rule:"pnp-prohibited",featureId:X,action:"block",sourceType:"student",reason:`Student PNP profile prohibits "${G}"`,value:Q.pnp.prohibitedSupports});return}if(Q.pnp?.supports?.includes(G)){let X=this.mapSupportToToolId(G,Y);Y.perToolFlags.set(X,{required:!1,alwaysAvailable:!0,settings:this.resolveToolSettings(G,Q),rule:"pnp-support",sourceType:"student"}),Y.decisions.push({precedence:6,rule:"pnp-support",featureId:X,action:"enable",sourceType:"student",reason:`Student PNP profile requests "${G}"`,value:Q.pnp.supports});return}let J=this.mapSupportToToolId(G,Y);Y.decisions.push({precedence:6,rule:"pnp-support",featureId:J,action:"skip",sourceType:"system",reason:`Feature "${G}" not configured at any level`,value:{supportId:G}})}mapSupportToToolId(G,Q){let Y=this.toolRegistry.getToolsByPNPSupport(G);if(Y.size===0){if(this.toolRegistry.getAllTools().length>0)Q.unmappedSupportIds.add(G);return G}return Array.from(Y)[0]}resolveToolSettings(G,Q){return Q.itemSettings?.toolParameters?.[G]??Q.toolConfigs?.[G]}}var u0=R7({policy:{allowed:[],blocked:[]},placement:{section:[],item:[],passage:[]},providers:{}});class L1{toolRegistry;contextId;pnpPolicySource;customSources;listeners=new Set;tools;assessment;currentItemRef;pnpEnforcement;disposed=!1;constructor(G){this.toolRegistry=G.toolRegistry,this.contextId=G.contextId??"tool-policy",this.pnpPolicySource=new P1(this.toolRegistry),this.customSources=G.customSources?[...G.customSources]:[];let Q=G.inputs??{};this.tools=Q.tools??u0,this.assessment=Q.assessment??null,this.currentItemRef=Q.currentItemRef??null,this.pnpEnforcement=Q.pnpEnforcement??g7({assessment:this.assessment,currentItemRef:this.currentItemRef})}decide(G){this.assertNotDisposed();let Q=G.scope.scopeId?`${this.contextId}:${G.level}:${G.scope.scopeId}`:`${this.contextId}:${G.level}`;return R8({request:G,tools:this.tools,pnpPolicy:{source:this.pnpPolicySource,assessment:this.assessment??void 0,currentItemRef:this.currentItemRef??void 0,enforcement:this.pnpEnforcement},customSources:this.customSources,contextId:Q})}decideFeature(G){this.assertNotDisposed();let Q=this.hostFeatureGate(G);if(Q)return Q;return v0(G,this.pnpPolicySource.resolveFeature(G,{assessment:this.assessment??void 0,currentItemRef:this.currentItemRef??void 0}),{assessmentBound:this.assessment!==null})}hostFeatureGate(G){let Q={assessmentBound:this.assessment!==null},Y=L7(this.tools.policy.blocked);if(Y.includes(G))return w8(G,"host-blocked",Y,Q);let J=L7(this.tools.policy.allowed);if(J.length>0&&!J.includes(G))return w8(G,"host-allowlist",J,Q);return null}getVisibleToolIds(G,Q){return this.decide({level:G,scope:{level:G,scopeId:Q}}).visibleTools.map((Y)=>Y.toolId)}updateInputs(G){this.assertNotDisposed();let Q=!1,Y=!1;if("tools"in G){let J=G.tools??u0;if(!Object.is(this.tools,J))this.tools=J,Q=!0}if("assessment"in G){let J=G.assessment??null;if(!Object.is(this.assessment,J))this.assessment=J,Q=!0}if("currentItemRef"in G){let J=G.currentItemRef??null;if(!Object.is(this.currentItemRef,J))this.currentItemRef=J,Q=!0}if("pnpEnforcement"in G&&G.pnpEnforcement){if(this.pnpEnforcement!==G.pnpEnforcement)this.pnpEnforcement=G.pnpEnforcement,Y=!0}if(Q||Y)this.emit({reason:Y&&!Q?"pnp-enforcement":"inputs",inputs:this.snapshotInputs()})}registerPolicySource(G){return this.assertNotDisposed(),this.customSources.push(G),this.emit({reason:"policy-source-added",inputs:this.snapshotInputs()}),()=>{let Q=this.customSources.indexOf(G);if(Q!==-1){if(this.customSources.splice(Q,1),!this.disposed)this.emit({reason:"policy-source-removed",inputs:this.snapshotInputs()})}}}onPolicyChange(G){return this.listeners.add(G),()=>{this.listeners.delete(G)}}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(G){for(let Q of Array.from(this.listeners))try{Q(G)}catch{}}assertNotDisposed(){if(this.disposed)throw Error("ToolPolicyEngine has been disposed.")}}var AQ=Symbol("@pie-players/tool-policy-engine");var $1=(G)=>!!G&&typeof G==="object"&&!Array.isArray(G),FQ=(G,Q,Y)=>{let J={...Q,...Y};if(G==="textToSpeech"&&$1(Q.settings)&&$1(Y.settings)){if(J.settings={...Q.settings,...Y.settings},$1(Q.settings.mathSpeech)&&$1(Y.settings.mathSpeech))J.settings.mathSpeech={...Q.settings.mathSpeech,...Y.settings.mathSpeech}}return J},NQ=["item-selected","item-session-data-changed","item-session-meta-changed","item-complete-changed","content-loaded","item-player-error"],MQ=["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 w1{assessmentId;config;ttsService;toolCoordinator;highlightCoordinator;elementToolStateStore;catalogResolver;toolProviderRegistry;hooks;lazyInit;ttsInitialized=!1;ttsInitPromise;ttsReconfigurePromise;stateLoaded=!1;stateLoadPromise;coordinatorReadyPromise;coordinatorReadyNotified=!1;providerInitPromises=new Map;toolRegistry;toolContextResolvers=new Map;toolContextResolverChangeListeners=new Set;toolRequests=new $8;sectionControllers=new Map;sectionControllerKeys=new Map;sectionControllerInitPromises=new Map;sectionPersistenceStrategies=new Map;sectionControllerLifecycleListeners=new Set;activeSubscriptions=new Map;activeCohortMapKey=null;latestRequestedActiveCohortMapKey=null;telemetryListeners=new Set;frameworkErrorBus;ownsFrameworkErrorBus;policyEngine;pnpEnforcementOverride=null;boundAssessment=null;boundCurrentItemRef=null;reportedUnboundFeaturePolicy=!1;static resolveConfig(G){let Q=l1(G.toolConfigStrictness),Y=G.toolRegistry??new E8,J=G.deferToolConfigValidation===!0?R7(G.tools):X7(G.tools,{strictness:Q,source:"ToolkitCoordinator.init",toolRegistry:Y}).config;return{...G,toolConfigStrictness:Q,toolRegistry:Y,tools:{...J,providers:{...{textToSpeech:{enabled:!0,backend:"browser"},annotationToolbar:{enabled:!0}},...J.providers}},accessibility:{language:"en-US",...G.accessibility??{},catalogs:G.accessibility?.catalogs??[]}}}constructor(G){if(!G.assessmentId)throw Error("ToolkitCoordinator requires assessmentId in config");let Q=w1.resolveConfig(G);if(this.assessmentId=Q.assessmentId,this.config=Q,this.toolRegistry=Q.toolRegistry??new E8,this.installToolContextResolvers(Q.toolContextResolvers),this.hooks=Q.hooks??{},this.lazyInit=G.lazyInit===!0,this.pnpEnforcementOverride=this.resolveConfiguredPnpEnforcement(),this.frameworkErrorBus=G.frameworkErrorBus??new m7,this.ownsFrameworkErrorBus=!G.frameworkErrorBus,this.subscribeFrameworkErrorHookAdapters(),this.toolCoordinator=new Y8,this.highlightCoordinator=new u7,this.elementToolStateStore=new G8,this.catalogResolver=new e1(Q.accessibility?.catalogs||[],Q.accessibility?.language||"en-US"),this.toolProviderRegistry=new z1,this._registerToolProviders(),this.ttsService=new p7,this.setupStatePersistenceHooks(),this.policyEngine=new L1({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((Y)=>{console.error("[ToolkitCoordinator] Failed eager initialization:",Y),this.handleError(Y,{phase:"coordinator-ready"})})}subscribeFrameworkErrorHookAdapters(){this.frameworkErrorBus.subscribeFrameworkErrors((G)=>{let Q=this.hooks.onFrameworkError;if(!Q)return;try{Q(G)}catch(Y){console.warn("[ToolkitCoordinator] onFrameworkError hook failed:",Y)}})}async emitTelemetry(G,Q){try{await this.hooks.onTelemetry?.(G,Q)}catch(J){console.warn("[ToolkitCoordinator] telemetry hook failed:",J)}let Y=Q?{...Q}:void 0;for(let J of this.telemetryListeners)try{J({eventName:G,payload:Y?{...Y}:void 0})}catch(X){console.warn("[ToolkitCoordinator] telemetry listener failed:",X)}}emitSectionControllerLifecycle(G){for(let Q of this.sectionControllerLifecycleListeners)try{Q(G)}catch(Y){console.warn("[ToolkitCoordinator] section controller lifecycle listener failed:",Y)}}handleError(G,Q){let Y=Q6({error:G,context:Q});this.frameworkErrorBus.reportFrameworkError(Y)}subscribeFrameworkErrors(G){return this.frameworkErrorBus.subscribeFrameworkErrors(G)}reportFrameworkError(G){this.frameworkErrorBus.reportFrameworkError(G)}getSectionControllerMapKey(G){return`${G.assessmentId}::${G.sectionId}::${G.attemptId||""}`}createDefaultSectionPersistence(){let G=(()=>{try{if(typeof window>"u")return null;return window.localStorage}catch{return null}})(),Q=(Y)=>{let{assessmentId:J,sectionId:X,attemptId:j}=Y.key;return`pie:section-controller:v1:${J}:${X}:${j||"default"}`};return{async loadSession(Y){if(!G)return null;let J=G.getItem(Q(Y));if(!J)return null;try{return JSON.parse(J)}catch{return null}},async saveSession(Y,J){if(!G)return;G.setItem(Q(Y),JSON.stringify(J))},async clearSession(Y){if(!G)return;G.removeItem(Q(Y))}}}async resolveSectionPersistence(G){let Q=this.getSectionControllerMapKey(G.key),Y=this.sectionPersistenceStrategies.get(Q);if(Y)return Y;let J={createDefaultPersistence:()=>this.createDefaultSectionPersistence()},X=await this.hooks.createSectionSessionPersistence?.(G,J)??await J.createDefaultPersistence();return this.sectionPersistenceStrategies.set(Q,X),X}setupStatePersistenceHooks(){this.elementToolStateStore.setOnStateChange((G)=>{if(!this.hooks.saveToolState)return;Promise.resolve(this.hooks.saveToolState(G)).catch((Q)=>{this.handleError(Q,{phase:"state-save"})})})}async ensureStateLoaded(){if(this.stateLoaded)return;if(this.stateLoadPromise)return this.stateLoadPromise;return this.stateLoadPromise=(async()=>{let G=this.hooks.loadToolState;if(!G)return;try{let Q=await G();if(Q&&typeof Q==="object")this.elementToolStateStore.loadState(Q);this.stateLoaded=!0,await this.emitTelemetry("pie-toolkit-tool-state-loaded",{hasState:Boolean(Q)})}catch(Q){this.handleError(Q,{phase:"state-load"})}})().finally(()=>{this.stateLoadPromise=void 0}),this.stateLoadPromise}_registerToolProviders(){let G=this.getProviderDescriptorTools();for(let Q of G)this.registerProviderFromTool(Q)}getProviderDescriptorTools(){return this.toolRegistry.getAllTools().filter((G)=>!!G.provider)}async registerProviderFromTool(G){let Q=G.provider;if(!Q)return;let Y=this.getToolConfig(G.toolId)||void 0;if(Y?.enabled===!1)return;let J=Q.getProviderId?.(Y)??Y?.provider?.id??G.toolId;if(this.toolProviderRegistry.has(J))return;let X=Q.createProvider(Y),j=Q.getInitConfig?.(Y)??Y?.provider?.init??{},Z=this.addToolTelemetryReporter({toolId:G.toolId,providerId:J,initConfig:j}),K=this.createToolTelemetryForwarder({toolId:G.toolId,providerId:J}),W=Q.getAuthFetcher?.(Y)??Y?.provider?.runtime?.authFetcher;await this.registerProvider(J,{provider:X,config:Z,lazy:Q.lazy??!0,authFetcher:W,onTelemetry:K})}createToolTelemetryForwarder(G){return async(Q,Y)=>{await this.emitTelemetry(Q,{...Y||{},toolId:G.toolId,providerId:G.providerId})}}addToolTelemetryReporter(G){let Q=G.initConfig&&typeof G.initConfig==="object"?{...G.initConfig}:{},Y=typeof Q.onTelemetry==="function"?Q.onTelemetry:null,J=this.createToolTelemetryForwarder({toolId:G.toolId,providerId:G.providerId});return Q.onTelemetry=async(X,j)=>{if(Y)await Y(X,j);await J(X,j)},Q}async registerProvider(G,Q){try{this.toolProviderRegistry.register(G,Q);let Y={providerId:G,providerName:Q.provider.providerName};await this.hooks.onProviderRegistered?.(G,Y),await this.emitTelemetry("pie-toolkit-provider-registered",{providerId:G,providerName:Q.provider.providerName})}catch(Y){console.warn(`[ToolkitCoordinator] Failed to register provider "${G}":`,Y),this.handleError(Y,{phase:"provider-register",providerId:G})}}async ensureProviderReady(G){let Q=this.providerInitPromises.get(G);if(Q)return Q;let Y=(async()=>{let J=await this.toolProviderRegistry.getProvider(G,!1),X={providerId:G,providerName:J.providerName};try{return await this.hooks.onProviderInitStart?.(G,X),await this.toolProviderRegistry.initialize(G),await this.hooks.onProviderReady?.(G,X),await this.emitTelemetry("pie-toolkit-provider-ready",{providerId:G}),J}catch(j){let Z=j instanceof Error?j:Error(String(j));throw this.handleError(Z,{phase:"provider-init",providerId:G}),Z}})().finally(()=>{this.providerInitPromises.delete(G)});return this.providerInitPromises.set(G,Y),Y}setHooks(G){if(Object.assign(this.hooks,G),this.setupStatePersistenceHooks(),G.onCoordinatorReady&&this.isReady())Promise.resolve(G.onCoordinatorReady(this)).catch((Q)=>{this.handleError(Q,{phase:"coordinator-ready"})})}subscribeTelemetry(G){return this.telemetryListeners.add(G),()=>{this.telemetryListeners.delete(G)}}getSectionController(G){let Q={assessmentId:this.assessmentId,sectionId:G.sectionId,attemptId:G.attemptId};return this.sectionControllers.get(this.getSectionControllerMapKey(Q))}subscribeSectionEvents(G){if(this.activeCohortMapKey===null)throw Error("[ToolkitCoordinator] subscribeSectionEvents requires an active section cohort; call getOrCreateSectionController first.");let Q=this.activeSubscriptions.get(G.listener);if(Q)Q.unsubscribeCurrent?.(),Q.unsubscribeCurrent=null;let Y={listener:G.listener,eventTypes:G.eventTypes,itemIds:G.itemIds,unsubscribeCurrent:null};this.activeSubscriptions.set(G.listener,Y);let J=this.sectionControllers.get(this.activeCohortMapKey);if(J)this.bindSubscriptionToController(Y,J);let X=!1;return()=>{if(X)return;if(X=!0,Y.unsubscribeCurrent?.(),Y.unsubscribeCurrent=null,this.activeSubscriptions.get(G.listener)===Y)this.activeSubscriptions.delete(G.listener)}}bindSubscriptionToController(G,Q){G.unsubscribeCurrent?.(),G.unsubscribeCurrent=null;let Y=Q.subscribe;if(typeof Y!=="function")return;let J=this.buildSectionEventPredicate(G);G.unsubscribeCurrent=Y.call(Q,(Z)=>{if(!J(Z))return;this.deliverSectionEventSafely(G.listener,Z)});let X=this.buildContentLoadedReplayEvents(Q);for(let Z of X)if(J(Z))this.deliverSectionEventSafely(G.listener,Z);let j=this.buildLoadingCompleteReplayEvent(Q);if(j&&J(j))this.deliverSectionEventSafely(G.listener,j)}deliverSectionEventSafely(G,Q){try{G(Q)}catch(Y){console.warn("[ToolkitCoordinator] section-event listener failed:",Y)}}setActiveCohort(G){if(this.activeCohortMapKey===G)return;this.activeCohortMapKey=G;let Q=this.sectionControllers.get(G);if(!Q)return;for(let Y of Array.from(this.activeSubscriptions.values()))this.bindSubscriptionToController(Y,Q)}setActiveCohortIfLatestRequest(G){if(this.latestRequestedActiveCohortMapKey!==G)return;this.setActiveCohort(G)}suspendActiveCohortIfSuperseded(G){if(this.activeCohortMapKey===null)return;if(this.activeCohortMapKey===G)return;this.activeCohortMapKey=null;for(let Q of Array.from(this.activeSubscriptions.values()))Q.unsubscribeCurrent?.(),Q.unsubscribeCurrent=null}clearActiveCohortIfMatches(G){if(this.activeCohortMapKey!==G)return;this.activeCohortMapKey=null;for(let Q of Array.from(this.activeSubscriptions.values()))Q.unsubscribeCurrent?.(),Q.unsubscribeCurrent=null}buildSectionEventPredicate(G){let Q=G.eventTypes?new Set(G.eventTypes):null,Y=G.itemIds?new Set(G.itemIds):null;return(J)=>{if(Q||Y){let X=J?.type||null;if(Q&&(!X||!Q.has(X)))return!1;if(Y){if(!Array.from(this.collectEventItemIds(J)).some((Z)=>Y.has(Z)))return!1}}return!0}}collectEventItemIds(G){let Q=new Set;if("itemId"in G&&typeof G.itemId==="string")Q.add(G.itemId);if("canonicalItemId"in G&&typeof G.canonicalItemId==="string")Q.add(G.canonicalItemId);if("currentItemId"in G&&typeof G.currentItemId==="string")Q.add(G.currentItemId);if("previousItemId"in G&&typeof G.previousItemId==="string")Q.add(G.previousItemId);return Q}buildContentLoadedReplayEvents(G){let Q=G.getRuntimeState?.(),Y=Q?.loadedRenderables;if(!Array.isArray(Y)||Y.length===0)return[];let J=typeof Q?.currentItemIndex==="number"&&Number.isFinite(Q.currentItemIndex)?Q.currentItemIndex:0,X=Date.now(),j=[];for(let Z of Y){if(!Z)continue;let K=Z.itemId,W=typeof Z.canonicalItemId==="string"&&Z.canonicalItemId?Z.canonicalItemId:K;if(typeof K!=="string"||!K)continue;j.push({type:"content-loaded",contentKind:Z.contentKind??"unknown",itemId:K,canonicalItemId:W,currentItemIndex:J,timestamp:X})}return j}buildLoadingCompleteReplayEvent(G){let Q=G.getRuntimeState?.();if(Q?.loadingComplete!==!0)return null;let Y=typeof Q.totalRegistered==="number"&&Number.isFinite(Q.totalRegistered)?Math.max(0,Q.totalRegistered):0,J=typeof Q.totalLoaded==="number"&&Number.isFinite(Q.totalLoaded)?Math.max(0,Q.totalLoaded):Y;return{type:"section-loading-complete",totalRegistered:Y,totalLoaded:J,currentItemIndex:Q.currentItemIndex,timestamp:Date.now()}}subscribeItemEvents(G){return this.subscribeSectionEvents({eventTypes:G.eventTypes||NQ,itemIds:G.itemIds,listener:G.listener})}subscribeSectionLifecycleEvents(G){return this.subscribeSectionEvents({eventTypes:G.eventTypes||MQ,listener:G.listener})}onSectionControllerLifecycle(G){return this.sectionControllerLifecycleListeners.add(G),()=>{this.sectionControllerLifecycleListeners.delete(G)}}async getOrCreateSectionController(G){let Q={assessmentId:this.assessmentId,sectionId:G.sectionId,attemptId:G.attemptId},Y=this.getSectionControllerMapKey(Q);this.latestRequestedActiveCohortMapKey=Y,this.suspendActiveCohortIfSuperseded(Y);let J=await this.resolveExistingSectionController({mapKey:Y,key:Q,input:G.input,updateExisting:G.updateExisting});if(J)return J;let X=this.sectionControllerInitPromises.get(Y);if(X)return X;let j=this.initializeNewSectionController({args:G,key:Q,mapKey:Y}).catch((Z)=>{throw this.handleSectionControllerInitError(Z,G),Z}).finally(()=>{this.sectionControllerInitPromises.delete(Y)});return this.sectionControllerInitPromises.set(Y,j),j}async resolveExistingSectionController(G){let Q=this.sectionControllers.get(G.mapKey);if(!Q)return;if(this.sectionControllerKeys.set(G.mapKey,G.key),G.updateExisting!==!1)await Q.updateInput?.(G.input);return this.setActiveCohortIfLatestRequest(G.mapKey),Q}createSectionControllerContext(G){return{key:G.key,coordinator:this,input:G.input}}async initializeNewSectionController(G){let Q=this.createSectionControllerContext({key:G.key,input:G.args.input}),Y=await this.resolveSectionPersistence(Q),J={createDefaultController:G.args.createDefaultController},X=await this.hooks.createSectionController?.(Q,J)??await J.createDefaultController();return await X.configureSessionPersistence?.({strategy:Y,context:Q}),await X.initialize?.(G.args.input),await X.hydrate?.(),await this.finalizeSectionControllerReady({mapKey:G.mapKey,key:G.key,context:Q,controller:X}),X}async finalizeSectionControllerReady(G){this.sectionControllers.set(G.mapKey,G.controller),this.sectionControllerKeys.set(G.mapKey,G.key),this.setActiveCohortIfLatestRequest(G.mapKey),this.emitSectionControllerLifecycle({type:"ready",key:G.key,controller:G.controller}),await this.hooks.onSectionControllerReady?.(G.context,G.controller),await this.emitTelemetry("pie-toolkit-section-controller-ready",{assessmentId:G.key.assessmentId,sectionId:G.key.sectionId,attemptId:G.key.attemptId})}handleSectionControllerInitError(G,Q){this.handleError(G,{phase:"section-controller-init",details:{sectionId:Q.sectionId,attemptId:Q.attemptId}})}async disposeSectionController(G){let Q={assessmentId:this.assessmentId,sectionId:G.sectionId,attemptId:G.attemptId},Y=this.getSectionControllerMapKey(Q),J=this.sectionControllers.get(Y);if(!J)return;this.clearActiveCohortIfMatches(Y);let X=this.createSectionControllerContext({key:Q,input:void 0});try{await this.runSectionControllerDisposePipeline({key:Q,context:X,controller:J,persistBeforeDispose:G.persistBeforeDispose})}catch(j){this.handleError(j,{phase:"section-controller-dispose",details:{sectionId:G.sectionId,attemptId:G.attemptId}})}finally{await this.finalizeSectionControllerDispose({mapKey:Y,key:Q,context:X,clearPersistence:G.clearPersistence})}}async runSectionControllerDisposePipeline(G){if(G.persistBeforeDispose!==!1)await G.controller.persist?.();await G.controller.dispose?.(),await this.hooks.onSectionControllerDispose?.(G.context,G.controller),await this.emitTelemetry("pie-toolkit-section-controller-disposed",{assessmentId:G.key.assessmentId,sectionId:G.key.sectionId,attemptId:G.key.attemptId})}async finalizeSectionControllerDispose(G){if(this.sectionControllers.delete(G.mapKey),this.sectionControllerKeys.delete(G.mapKey),this.emitSectionControllerLifecycle({type:"disposed",key:G.key}),G.clearPersistence)await this.sectionPersistenceStrategies.get(G.mapKey)?.clearSession?.(G.context);this.sectionPersistenceStrategies.delete(G.mapKey)}async ensureTTSReady(G){if(await this.waitForPendingTTSReconfigure(),this.ttsInitialized)return;if(this.ttsInitPromise)return this.ttsInitPromise;return this.ttsInitPromise=this._initializeTTS(G).finally(()=>{this.ttsInitPromise=void 0}),this.ttsInitPromise}async waitForPendingTTSReconfigure(){let G=this.ttsReconfigurePromise;while(G)await G,G=this.ttsReconfigurePromise}async _initializeTTS(G){if(this.ttsInitialized)return;let Q=this.resolveTTSToolConfig(G),Y=f0(Q),J=L8(Y),X=k0(Y);if(await this.hooks.onBeforeTTSInit?.({phase:"tts-init",details:{backend:J}}),await this.emitTelemetry("pie-toolkit-tts-init-start",{backend:J}),await this.emitTelemetry("pie-tool-init-start",{toolId:"textToSpeech",operation:"tts-init",backend:J}),this.toolProviderRegistry.has("tts"))try{let K=await(await this.ensureProviderReady("tts")).createInstance();await this.initializeTTSService(K,X),await this.emitTelemetry("pie-toolkit-tts-init-success",{provider:"registry"}),await this.emitTelemetry("pie-tool-init-success",{toolId:"textToSpeech",operation:"tts-init",backend:J,provider:"registry"}),console.log("[ToolkitCoordinator] TTS initialized via ToolProviderRegistry");return}catch(Z){let K=Z instanceof Error?Z:Error(String(Z));await this.emitTelemetry("pie-tool-init-error",{toolId:"textToSpeech",providerId:"tts",operation:"tts-init",backend:J,errorType:"TTSRegistryInitError",message:K.message,recovered:!0}),await this.emitTelemetry("pie-tool-init-fallback",{toolId:"textToSpeech",providerId:"tts",operation:"tts-init",backend:J,fromProvider:"registry",toProvider:"browser",reason:K.message}),console.warn("[ToolkitCoordinator] Failed to initialize TTS via registry, falling back to browser provider:",K)}let j=new b7;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:J,provider:"browser-fallback"})}catch(Z){let K=Z instanceof Error?Z:Error(String(Z));throw this.handleError(K,{phase:"tts-init"}),await this.emitTelemetry("pie-toolkit-tts-init-error",{message:K.message}),await this.emitTelemetry("pie-tool-init-error",{toolId:"textToSpeech",operation:"tts-init",backend:J,errorType:"TTSInitError",message:K.message}),K}}resolveTTSToolConfig(G){return G||this.getTTSConfigFromProviders()||{}}async initializeTTSService(G,Q){let Y={...Q.providerOptions||{},__pieTelemetry:async(X,j)=>{await this.emitTelemetry(X,{toolId:"textToSpeech",...j||{}})}},J={...Q,providerOptions:Y};await this.ttsService.initialize(G,J),await this.ensureBrowserVoicesReady(G),this.ttsService.setCatalogResolver(this.catalogResolver),this.ttsInitialized=!0,await this.hooks.onTTSReady?.()}async ensureBrowserVoicesReady(G,Q=1200){if(G.providerId!=="browser")return;if(typeof window>"u")return;if(!("speechSynthesis"in window))return;let Y=window.speechSynthesis;if(Y.getVoices().length>0)return;await new Promise((j)=>{let Z=!1,K=typeof Y.addEventListener==="function"&&typeof Y.removeEventListener==="function",W=!K&&"onvoiceschanged"in Y,B=W?Y.onvoiceschanged:null,U=!1,V=()=>{if(Z)return;if(Z=!0,window.clearTimeout(N),K)Y.removeEventListener("voiceschanged",H);else if(U&&Y.onvoiceschanged===H)Y.onvoiceschanged=B;j()},H=(M)=>{if(!K&&typeof B==="function"&&M)B.call(Y,M);V()},N=window.setTimeout(V,Q);if(K)Y.addEventListener("voiceschanged",H,{once:!0});else if(W)Y.onvoiceschanged=H,U=!0});let X=Y.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(G){return this.ensureProviderReady(G)}async waitUntilReady(){if(this.isReady())return;if(this.coordinatorReadyPromise)return this.coordinatorReadyPromise;return this.coordinatorReadyPromise=(async()=>{await this.ensureStateLoaded();let G=this.getTTSConfigFromProviders();if(G?.enabled!==!1)await this.ensureTTSReady(G);if(!this.coordinatorReadyNotified)this.coordinatorReadyNotified=!0,await this.hooks.onCoordinatorReady?.(this),await this.emitTelemetry("pie-toolkit-coordinator-ready",{assessmentId:this.assessmentId})})().finally(()=>{this.coordinatorReadyPromise=void 0}),this.coordinatorReadyPromise}isReady(){return this.getInitStatus().coordinator}getInitStatus(){let G={};for(let Y of this.toolProviderRegistry.getProviderIds())G[Y]=this.toolProviderRegistry.isInitialized(Y);let Q=this.getTTSConfigFromProviders();return{tts:this.ttsInitialized,stateLoaded:this.stateLoaded||!this.hooks.loadToolState,coordinator:(this.stateLoaded||!this.hooks.loadToolState)&&(this.ttsInitialized||Q?.enabled===!1),providers:G}}getTTSConfigFromProviders(){return(this.config.tools?.providers||{}).textToSpeech}assertCanonicalToolId(G){if(typeof G!=="string"||G.trim().length===0)throw Error("Tool id must be a non-empty string.");if(G==="tts")throw Error('Tool id "tts" is no longer supported. Use "textToSpeech".');if(this.toolRegistry.getAllToolIds().length===0)return;if(!this.toolRegistry.get(G))throw Error(`Unknown tool id "${G}".`)}installToolContextResolvers(G){if(!G)return;for(let[Q,Y]of Object.entries(G)){if(Y==null)continue;if(this.assertCanonicalToolId(Q),typeof Y!=="function")throw Error(`Invalid tool context resolver for "${Q}": expected a function.`);this.toolContextResolvers.set(Q,Y)}}setToolContextResolvers(G){this.toolContextResolvers.clear(),this.installToolContextResolvers(G??void 0),this.notifyToolContextResolverChange()}notifyToolContextResolverChange(){for(let G of this.toolContextResolverChangeListeners)try{G()}catch(Q){console.warn("[ToolkitCoordinator] Tool context resolver listener threw:",Q)}}isToolEnabled(G){return this.assertCanonicalToolId(G),this.config.tools?.providers?.[G]?.enabled!==!1}getToolConfig(G){return this.assertCanonicalToolId(G),this.config.tools?.providers?.[G]||null}updateToolConfig(G,Q){this.assertCanonicalToolId(G);let Y=this.getToolConfig(G)||{};if(!this.config.tools)this.config.tools=X7(void 0,{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolConfig",toolRegistry:this.toolRegistry}).config;if(!this.config.tools.providers)this.config.tools.providers={};let J={...this.config.tools.providers||{},[G]:FQ(G,Y,Q)},X=X7({...this.config.tools,providers:J},{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolConfig",toolRegistry:this.toolRegistry});this.config.tools=X.config,this.policyEngine.updateInputs({tools:this.config.tools}),this.emitTelemetry("pie-toolkit-tool-config-updated",{toolId:G}),this._applyToolConfigChange(G,Q)}updateToolPlacement(G,Q){this.updateToolsPlacement({[G]:[...Q]})}updateToolsPlacement(G){if(!this.config.tools)this.config.tools=X7(void 0,{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolsPlacement",toolRegistry:this.toolRegistry}).config;let Q=this.config.tools?.placement??{section:[],item:[],passage:[]},Y={section:[...G.section??Q.section??[]],item:[...G.item??Q.item??[]],passage:[...G.passage??Q.passage??[]]},J=X7({...this.config.tools,placement:Y},{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolsPlacement",toolRegistry:this.toolRegistry});J.config.placement=Y,this.config.tools=J.config,this.policyEngine.updateInputs({tools:this.config.tools})}decideToolPolicy(G){return this.policyEngine.decide(G)}decideFeaturePolicy(G){let Q=this.policyEngine.decideFeature(G);if(!Q.assessmentBound&&!this.reportedUnboundFeaturePolicy)this.reportedUnboundFeaturePolicy=!0,console.warn(`[ToolkitCoordinator] Feature policy was asked about "${G}" 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 Q}onPolicyChange(G){return this.policyEngine.onPolicyChange(G)}onCatalogsChange(G){return this.catalogResolver.onCatalogsChange(G)}updateAssessment(G){this.boundAssessment=G,this.policyEngine.updateInputs({assessment:G,pnpEnforcement:this.resolveEffectivePnpEnforcement()})}updateCurrentItemRef(G){this.boundCurrentItemRef=G,this.policyEngine.updateInputs({currentItemRef:G,pnpEnforcement:this.resolveEffectivePnpEnforcement()})}setPnpEnforcement(G){this.pnpEnforcementOverride=G,this.policyEngine.updateInputs({pnpEnforcement:this.resolveEffectivePnpEnforcement()})}getPolicyInputs(){return this.policyEngine.getInputs()}registerPolicySource(G){return this.policyEngine.registerPolicySource(G)}registerToolContextResolver(G,Q){if(this.assertCanonicalToolId(G),typeof Q!=="function")throw Error(`Invalid tool context resolver for "${G}": expected a function.`);return this.toolContextResolvers.set(G,Q),this.notifyToolContextResolverChange(),()=>{if(this.toolContextResolvers.get(G)!==Q)return;this.toolContextResolvers.delete(G),this.notifyToolContextResolverChange()}}hasToolContextResolver(G){return this.assertCanonicalToolId(G),this.toolContextResolvers.has(G)}resolveToolContext(G){this.assertCanonicalToolId(G.toolId);let Q=this.toolContextResolvers.get(G.toolId);if(!Q)return null;let Y;try{Y=Q(G)}catch(X){return console.error(`[ToolkitCoordinator] Tool context resolver for "${G.toolId}" threw:`,X),{toolId:G.toolId,visible:!1,params:{},reason:"Tool context resolver threw."}}if(!Y)return{toolId:G.toolId,visible:!0,params:{}};let J=Y.params&&typeof Y.params==="object"&&!Array.isArray(Y.params)?Y.params:{};return{toolId:G.toolId,visible:Y.visible!==!1,params:J,reason:typeof Y.reason==="string"?Y.reason:void 0}}onToolContextResolverChange(G){return this.toolContextResolverChangeListeners.add(G),()=>{this.toolContextResolverChangeListeners.delete(G)}}registerToolRequestTarget(G){return this.toolRequests.registerTarget(G)}requestTool(G){return this.assertCanonicalToolId(G.toolId),this.toolRequests.request(G)}canRequestTool(G,Q){try{this.assertCanonicalToolId(G)}catch{return!1}return this.toolRequests.canRequest(G,Q)}onToolRequestTargetsChange(G){return this.toolRequests.onTargetsChange(G)}resolveEffectivePnpEnforcement(){if(this.pnpEnforcementOverride!==null)return this.pnpEnforcementOverride;return g7({assessment:this.boundAssessment,currentItemRef:this.boundCurrentItemRef})}resolveConfiguredPnpEnforcement(){return this.config.tools?.pnpEnforcement??null}_applyToolConfigChange(G,Q){switch(G){case"textToSpeech":{let Y=this._reconfigureTTSProvider();this.ttsReconfigurePromise=Y,Y.finally(()=>{if(this.ttsReconfigurePromise===Y)this.ttsReconfigurePromise=void 0}),Y.then(async()=>{let J=this.getTTSConfigFromProviders();if(!this.lazyInit&&J?.enabled!==!1)await this.ensureTTSReady(J)});break}case"answerEliminator":break}}async _reconfigureTTSProvider(){this.ttsInitialized=!1,this.ttsInitPromise=void 0;try{this.ttsService.stop()}catch{}if(this.toolProviderRegistry.has("tts"))await this.toolProviderRegistry.unregister("tts");let G=this.getProviderDescriptorTools().find((Q)=>Q.toolId==="textToSpeech");if(!G)return;await this.registerProviderFromTool(G)}}var zQ=()=>{};function p0(G){let{ttsService:Q,listenerId:Y,silence:J}=G;if(typeof Q?.onStateChange!=="function")return zQ;let X=(j)=>{if(j!==R.PLAYING&&j!==R.LOADING)return;J()};return Q.onStateChange(Y,X),()=>{try{Q.offStateChange?.(Y,X)}catch{}}}function g0(G){try{if(G?.isPlaying?.())G.pause?.()}catch{}}import{timedMediaProjectionSignature as rQ}from"@pie-players/pie-players-shared/timed-media";var c0="pie-register",l0="pie-unregister",d0="pie-item-session-changed";var i0="pie-content-loaded",s0="pie-item-player-error",n0="pie-formative-action",r0="pie-media-time-source";var OQ={bubbles:!0,composed:!0,cancelable:!1};function PQ(G,Q,Y={}){return new CustomEvent(G,{detail:Q,...OQ,...Y})}function b8(G,Q,Y,J={}){return G.dispatchEvent(PQ(Q,Y,J))}function y7(){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 T8(G,Q){if(G===Q)return!0;if(!G||!Q)return!1;return G.sectionId===Q.sectionId&&G.attemptId===Q.attemptId}function LQ(G){if(G.runtimeError)return"error";if(G.allLoadingComplete)return"ready";if(G.interactionReady)return"interaction-ready";if(G.sectionReady)return"loading";return"bootstrapping"}function o0(G){let Q=G.signals.sectionReady&&G.signals.allLoadingComplete,Y=G.mode==="strict"?Q:G.signals.interactionReady;return{phase:LQ({...G.signals,allLoadingComplete:Q,interactionReady:Y}),interactionReady:Y,allLoadingComplete:Q,reason:G.reason}}function a0(G){switch(G){case"idle":return null;case"booting-section":return"composed";case"engine-ready":return"engine-ready";case"interactive":return"interactive";case"disposed":return"disposed"}}function R1(G,Q,Y,J="entered"){let X=a0(Q);if(!X)return;G.push({kind:"stage-change",stage:X,status:J,cohort:Y})}function t0(G){let Q={...y7(),phase:"booting-section",cohort:G.cohort,effectiveRuntime:G.effectiveRuntime,effectiveToolsConfig:G.effectiveToolsConfig,itemCount:G.itemCount},Y=[];return R1(Y,"booting-section",G.cohort),{state:Q,outputs:Y}}function $Q(G,Q){if(G.phase==="idle"||G.phase==="disposed")return{state:G,outputs:[]};let Y=o0({mode:Q.mode,signals:Q.signals}),J=[],X=G.phase,j=G.loadingCompleteEmitted;if(X==="engine-ready"&&Y.interactionReady)X="interactive",R1(J,X,G.cohort);if(Y.allLoadingComplete&&G.cohort&&!j)j=!0,J.push({kind:"loading-complete",cohort:G.cohort,itemCount:Q.itemCount,loadedCount:Q.loadedCount});return{state:{...G,phase:X,readinessSignals:Q.signals,loadedCount:Q.loadedCount,itemCount:Q.itemCount,loadingCompleteEmitted:j},outputs:J}}function c7(G,Q){switch(Q.kind){case"initialize":{if(G.phase==="disposed")return{state:G,outputs:[]};if(G.phase!=="idle"){if(T8(G.cohort,Q.cohort))return c7(G,{kind:"update-runtime",effectiveRuntime:Q.effectiveRuntime,effectiveToolsConfig:Q.effectiveToolsConfig});return c7(G,{kind:"cohort-change",cohort:Q.cohort,effectiveRuntime:Q.effectiveRuntime,effectiveToolsConfig:Q.effectiveToolsConfig,itemCount:Q.itemCount})}return t0({state:G,cohort:Q.cohort,effectiveRuntime:Q.effectiveRuntime,effectiveToolsConfig:Q.effectiveToolsConfig,itemCount:Q.itemCount})}case"update-runtime":{if(G.phase==="idle"||G.phase==="disposed")return{state:G,outputs:[]};return{state:{...G,effectiveRuntime:Q.effectiveRuntime,effectiveToolsConfig:Q.effectiveToolsConfig},outputs:[]}}case"cohort-change":{if(G.phase==="disposed")return{state:G,outputs:[]};if(T8(G.cohort,Q.cohort))return c7(G,{kind:"update-runtime",effectiveRuntime:Q.effectiveRuntime,effectiveToolsConfig:Q.effectiveToolsConfig});let Y=[];if(G.phase!=="idle")Y.push({kind:"stage-change",stage:"disposed",status:"entered",cohort:G.cohort});let J=t0({state:G,cohort:Q.cohort,effectiveRuntime:Q.effectiveRuntime,effectiveToolsConfig:Q.effectiveToolsConfig,itemCount:Q.itemCount});return{state:J.state,outputs:[...Y,...J.outputs]}}case"section-controller-resolved":{if(G.phase!=="booting-section")return{state:{...G,controllerResolved:!0},outputs:[]};let Y=[];return R1(Y,"engine-ready",G.cohort),{state:{...G,phase:"engine-ready",controllerResolved:!0},outputs:Y}}case"update-readiness-signals":return $Q(G,{signals:Q.signals,mode:Q.mode,loadedCount:Q.loadedCount,itemCount:Q.itemCount});case"framework-error":return{state:{...G,lastFrameworkError:Q.error,readinessSignals:{...G.readinessSignals,runtimeError:Q.error.recoverable===!0?G.readinessSignals.runtimeError:!0}},outputs:[{kind:"framework-error",error:Q.error}]};case"dispose":{if(G.phase==="disposed")return{state:G,outputs:[]};let Y=[];if(G.phase!=="idle")R1(Y,"disposed",G.cohort);return{state:{...G,phase:"disposed"},outputs:Y}}default:{let Y=Q;return{state:G,outputs:[]}}}}class C8{state=y7();listeners=new Set;getState(){return this.state}dispatch(G){let Q=c7(this.state,G);if(this.state=Q.state,Q.outputs.length>0)this.fanOut(Q.outputs);return Q.outputs}subscribe(G){this.listeners.add(G);let Q=!0;return()=>{if(!Q)return;Q=!1,this.listeners.delete(G)}}disposeListeners(){this.listeners.clear()}fanOut(G){let Q=Array.from(this.listeners),Y=Object.freeze(G.slice());for(let J of Q)try{J(Y)}catch(X){console.warn("[SectionEngineCore] listener failed:",X)}}}function e0(G){let{coordinator:Q,dispatchCoreInput:Y}=G,J=0,X=null,j=null,Z=!1,K=Q.subscribeFrameworkErrors((V)=>{try{Y({kind:"framework-error",error:V})}catch(H){console.warn("[CoordinatorBridge] framework-error dispatch failed:",H)}});function W(){if(!j)return;try{j()}catch(V){console.warn("[CoordinatorBridge] controller unsubscribe failed:",V)}j=null}async function B(V){if(Z)return;J+=1;let H=J;X=V.cohort;let N=await Q.getOrCreateSectionController({sectionId:V.cohort.sectionId,attemptId:V.cohort.attemptId||void 0,input:{section:V.section,sectionId:V.cohort.sectionId,assessmentId:V.assessmentId,view:V.view},updateExisting:!0,createDefaultController:V.createDefaultController});if(H!==J||Z)return;W(),V.onControllerResolved?.(N);let M=N.getCompositionModel;if(V.onCompositionChanged?.(M?.()),typeof N.subscribe==="function")j=N.subscribe((P)=>{if(H!==J||Z)return;V.onCompositionChanged?.(M?.())});Y({kind:"section-controller-resolved"})}async function U(){if(Z)return;Z=!0,J+=1,W();try{K()}catch(H){console.warn("[CoordinatorBridge] framework-error unsubscribe failed:",H)}let V=X;if(X=null,V)try{await Q.disposeSectionController({sectionId:V.sectionId,attemptId:V.attemptId||void 0})}catch(H){console.warn("[CoordinatorBridge] section-controller dispose failed:",H)}}return{resolveSectionController:B,dispose:U}}function G3(G){let{runtimeId:Q,sourceCe:Y}=G,J=G.host,X=G.now??(()=>new Date().toISOString());function j(U){let V={stage:U.stage,status:U.status,runtimeId:Q,sectionId:U.cohort?.sectionId,attemptId:U.cohort?.attemptId?U.cohort.attemptId:void 0,timestamp:X(),sourceCe:Y};J.dispatchEvent(new CustomEvent("pie-stage-change",{detail:V}))}function Z(U){let V={runtimeId:Q,sectionId:U.cohort.sectionId,attemptId:U.cohort.attemptId?U.cohort.attemptId:void 0,itemCount:U.itemCount,loadedCount:U.loadedCount,timestamp:X(),sourceCe:Y};J.dispatchEvent(new CustomEvent("pie-loading-complete",{detail:V}))}function K(U){J.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":K(U);return;default:{let V=U;return}}}function B(U){J=U}return{dispatch:W,setHost:B}}function Q3(G){let{bus:Q}=G;function Y(J){switch(J.kind){case"framework-error":Q.reportFrameworkError(J.error);return;case"stage-change":case"loading-complete":return;default:{let X=J;return}}}return{dispatch:Y}}function Y3(G={}){let Q=G.hook;function Y(X){if(!Q)return;try{Q(X)}catch(j){console.warn("[InstrumentationBridge] hook failed:",j)}}function J(X){Q=X}return{dispatch:Y,setHook:J}}function J3(){let G=new Set;function Q(j){if(j.length===0)return;let Z=Array.from(G),K=Object.freeze(j.slice());for(let W of Z)try{W(K)}catch(B){console.warn("[SubscriberFanout] listener failed:",B)}}function Y(j){G.add(j);let Z=!0;return()=>{if(!Z)return;Z=!1,G.delete(j)}}function J(){G.clear()}function X(){return G.size}return{emit:Q,subscribe:Y,dispose:J,getListenerCount:X}}class S8{core;domEventBridge;frameworkErrorBridge;instrumentationBridge;subscriberFanout;coordinatorBridge;unsubscribeCore;disposed=!1;constructor(G){this.core=G.core??new C8,this.domEventBridge=G3({host:G.host,runtimeId:G.runtimeId,sourceCe:G.sourceCe,now:G.now}),this.frameworkErrorBridge=Q3({bus:G.frameworkErrorBus}),this.instrumentationBridge=Y3({hook:G.instrumentationHook}),this.subscriberFanout=J3(),this.coordinatorBridge=G.coordinator?e0({coordinator:G.coordinator,dispatchCoreInput:(Q)=>this.dispatchInput(Q)}):null,this.unsubscribeCore=this.core.subscribe((Q)=>{this.routeOutputs(Q)})}getState(){return this.core.getState()}dispatchInput(G){if(this.disposed)return[];return this.core.dispatch(G)}subscribe(G){return this.subscriberFanout.subscribe(G)}setHost(G){this.domEventBridge.setHost(G)}setInstrumentationHook(G){this.instrumentationBridge.setHook(G)}resolveSectionController(G){if(!this.coordinatorBridge)throw Error("[SectionEngineAdapter] resolveSectionController called without a coordinator.");return this.coordinatorBridge.resolveSectionController(G)}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(G){for(let Q of G)this.routeOne(Q);this.subscriberFanout.emit(G)}routeOne(G){switch(G.kind){case"stage-change":case"loading-complete":this.domEventBridge.dispatch(G);break;case"framework-error":this.domEventBridge.dispatch(G),this.frameworkErrorBridge.dispatch(G);break;default:{let Q=G;return}}this.instrumentationBridge.dispatch(G)}}var wQ={mode:"gather",role:"student"};function E1(G,Q){return G!==void 0?G:Q}function RQ(G){let Q=G.runtime??{};if(Q.onFrameworkError!==void 0)return Q.onFrameworkError;return G.onFrameworkError}function EQ(G){let Q=G.runtime?.tools||{},Y=Q.placement||{};return{...Q,placement:{...Y}}}function bQ(G){let Q=G.runtime||{},Y=Q.player?{...Q.player}:null;return{...Q,assessmentId:E1(Q.assessmentId,G.assessmentId),playerType:Q.playerType??"iife",player:Y,lazyInit:Q.lazyInit??!0,accessibility:Q.accessibility??null,coordinator:Q.coordinator??null,createSectionController:Q.createSectionController,isolation:Q.isolation??"inherit",env:Q.env??wQ,toolConfigStrictness:E1(Q.toolConfigStrictness,G.toolConfigStrictness)??"error",onFrameworkError:RQ({runtime:G.runtime,onFrameworkError:G.onFrameworkError}),onStageChange:E1(Q.onStageChange,G.onStageChange),onLoadingComplete:E1(Q.onLoadingComplete,G.onLoadingComplete),tools:G.effectiveToolsConfig}}function X3(G,Q){let Y=G.assessmentId??"section-demo-direct",J=EQ({runtime:G.runtime}),X=bQ({assessmentId:Y,runtime:G.runtime,effectiveToolsConfig:J,toolConfigStrictness:G.toolConfigStrictness,onFrameworkError:G.onFrameworkError,onStageChange:G.onStageChange,onLoadingComplete:G.onLoadingComplete}),j=Q.resolvePlayerRuntime({effectiveRuntime:X,playerType:String(X.playerType??"iife"),env:X.env??null});return{effectiveToolsConfig:J,effectiveRuntime:X,playerRuntime:j}}import{createPieLogger as CQ,isGlobalDebugEnabled as SQ}from"@pie-players/pie-players-shared";function TQ(G,Q){if(G===Q)return 0;let Y=G.compareDocumentPosition(Q);if(Y&Node.DOCUMENT_POSITION_PRECEDING)return 1;if(Y&Node.DOCUMENT_POSITION_FOLLOWING)return-1;return 0}class y8{shellsByElement=new Map;register(G){let Q=this.shellsByElement.get(G.element),Y={...G,sortKey:Date.now()};if(Q&&Q.kind===Y.kind&&Q.itemId===Y.itemId&&Q.canonicalItemId===Y.canonicalItemId)return!1;return this.shellsByElement.set(G.element,Y),!0}unregister(G){return this.shellsByElement.delete(G)}getOrderedShells(G){let Q=Array.from(this.shellsByElement.values()).filter((Y)=>!G||Y.kind===G);return Q.sort((Y,J)=>TQ(Y.element,J.element)),Q}getCanonicalIdMap(){let G={};for(let Q of this.getOrderedShells("item")){if(!Q.itemId)continue;G[Q.itemId]=Q.canonicalItemId||Q.itemId}return G}clear(){this.shellsByElement.clear()}}function b1(G="runtime"){return`${G}-${Math.random().toString(16).slice(2)}-${Date.now()}`}var yQ=CQ("section-runtime-engine",()=>SQ());class x8{registry=new y8;runtimeId=b1("section-engine");adapter=null;controller=null;coordinator=null;sectionId="";attemptId;unsubscribeController=null;activeInitToken=0;loadedRenderableKeys=new Set;attachHost(G){if(this.adapter){if(this.adapter.setHost(G.host),G.instrumentationHook!==void 0)this.adapter.setInstrumentationHook(G.instrumentationHook);return}this.adapter=new S8({host:G.host,runtimeId:this.runtimeId,sourceCe:G.sourceCe,frameworkErrorBus:G.frameworkErrorBus,coordinator:G.coordinator,instrumentationHook:G.instrumentationHook,now:G.now})}dispatchInput(G){return this.adapter?.dispatchInput(G)??[]}subscribe(G){return this.adapter?.subscribe(G)??xQ}getState(){return this.adapter?.getState()??y7()}getEffectiveRuntime(G,Q){return X3(G,Q).effectiveRuntime}setInstrumentationHook(G){this.adapter?.setInstrumentationHook(G)}getRuntimeId(){return this.runtimeId}async initialize(G){this.activeInitToken+=1;let Q=this.activeInitToken;this.coordinator=G.coordinator,this.sectionId=G.sectionId,this.attemptId=G.attemptId;let Y=await G.coordinator.getOrCreateSectionController({sectionId:G.sectionId,attemptId:G.attemptId,input:{section:G.section,sectionId:G.sectionId,assessmentId:G.assessmentId,view:G.view},updateExisting:!0,createDefaultController:G.createDefaultController});if(Q!==this.activeInitToken)return;this.unsubscribeController?.(),this.controller=Y,this.replayRegisteredShellsIntoController(Y),G.onCompositionChanged?.(Y.getCompositionModel?.()),this.unsubscribeController=Y.subscribe?.((J)=>{try{G.onControllerEvent?.(J)}catch(X){yQ.warn("onControllerEvent handler threw",X)}G.onCompositionChanged?.(Y.getCompositionModel?.())})||null}replayRegisteredShellsIntoController(G){if(!G.handleContentRegistered)return;let Q=this.registry.getOrderedShells();if(Q.length===0)return;for(let J of Q){let X=J.canonicalItemId||J.itemId;G.handleContentRegistered({itemId:J.itemId,canonicalItemId:X,contentKind:J.contentKind||J.kind})}let Y=Date.now();for(let J of Q){let X=J.canonicalItemId||J.itemId,j=this.getLoadedKey(X,J.contentKind);if(this.loadedRenderableKeys.has(j))G.handleContentLoaded?.({itemId:J.itemId,canonicalItemId:X,contentKind:J.contentKind||J.kind,timestamp:Y})}}getLoadedKey(G,Q){return`${Q??""}:${G}`}register(G){return this.registry.register(G)}unregister(G){return this.registry.unregister(G)}getCompositionModel(){return this.controller?.getCompositionModel?.()??null}getCanonicalItemId(G){return this.registry.getCanonicalIdMap()[G]||this.controller?.getCanonicalItemId?.(G)||G}handleContentRegistered(G){this.controller?.handleContentRegistered?.({itemId:G.itemId,canonicalItemId:G.canonicalItemId||G.itemId,contentKind:G.contentKind||G.kind})}handleContentUnregistered(G){let Q=G.canonicalItemId||G.itemId;this.loadedRenderableKeys.delete(this.getLoadedKey(Q,G.contentKind)),this.controller?.handleContentUnregistered?.({itemId:G.itemId,canonicalItemId:Q,contentKind:G.contentKind||G.kind})}handleContentLoaded(G){let Q=G.canonicalItemId||G.itemId;this.loadedRenderableKeys.add(this.getLoadedKey(Q,G.contentKind)),this.controller?.handleContentLoaded?.(G)}handleItemPlayerError(G){this.controller?.handleItemPlayerError?.(G)}reportSectionError(G){this.controller?.reportSectionError?.(G)}updateItemSession(G,Q){let Y=this.getCanonicalItemId(G);return this.controller?.updateItemSession?.(Y,Q)??null}navigateToItem(G){return this.controller?.navigateToItem?.(G)??null}handleFormativeAction(G){if(!G?.itemId)return;let Q=this.getCanonicalItemId(G.itemId);if(G.action==="retry"){this.controller?.retryFormativeItem?.({itemId:Q});return}this.controller?.recordFormativeTry?.({itemId:Q,outcomes:G.outcomes})}handleMediaTimeSource(G){if(G?.action==="detach"){this.controller?.detachMediaTimeSource?.({origin:G.origin??"host"});return}if(!G?.source)return;this.controller?.attachMediaTimeSource?.(G.source,{origin:G.origin??"host",renderableId:G.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 G=this.adapter;this.adapter=null,await G.dispose()}}}var xQ=()=>{};import{ContextConsumer as fQ,createContext as kQ}from"@pie-players/pie-context";var Z3=kQ(Symbol.for("pie.sectionRuntimeEngineHostContext"));function j3(G,Q){let Y=!1,J=new fQ(G,{context:Z3,subscribe:!0,onValue:(W)=>{Y=!0,Q(W)}});J.connect();let X=(W)=>{if(W.context!==Z3)return;J.requestValue()};G.addEventListener("context-provider",X);let j=0,Z=200,K=globalThis.setInterval(()=>{if(Y||j>=Z){globalThis.clearInterval(K);return}j+=1,J.requestValue()},50);return()=>{globalThis.clearInterval(K),G.removeEventListener("context-provider",X),J.disconnect()}}var IQ=(G)=>{console.error("[pie-assessment-toolkit] onStageChange handler threw",G)};function K3(G,Q){if(G.isSuppressed())return!1;G.dispatchDomEvent(Q);let Y=G.getOnStageChange();if(Y)try{Y(Q)}catch(J){(G.logHandlerError??IQ)(J)}return!0}function l7(G,Q){if(typeof G==="function")return G;if(G===null)return null;return typeof Q==="function"?Q:null}function q3(G={}){let Q=G.frameDeadlineMs??100,Y=!1,J=null,X=null,j=null,Z=null,K=null;function W(){if(Y=!1,X!==null)Z?.(X),X=null;if(j!==null)K?.(j),j=null;Z=null,K=null}function B(H){if(!Y)return;if(H==="frame")X=null;if(H==="timer")j=null;let N=J;J=null,W(),N?.()}function U(H){if(J=H,Y)return;Y=!0;let N=globalThis,M=l7(G.requestFrame,N.requestAnimationFrame);Z=l7(G.cancelFrame,N.cancelAnimationFrame);let P=l7(G.setTimer,N.setTimeout);if(K=l7(G.clearTimer,N.clearTimeout),M){let A=M(()=>B("frame"));if(!Y)return;if(X=A,P){let L=P(()=>B("timer"),Q);if(Y)j=L}return}let $=l7(G.queueMicrotaskFn,N.queueMicrotask);if($){$(()=>B("microtask"));return}if(P){let A=P(()=>B("timer"),0);if(Y)j=A;return}B("microtask")}function V(){if(!Y)return;J=null,W()}return{schedule:U,cancel:V,isPending:()=>Y}}function W3(){return{lastSessionEventSignatureByItemId:new Map,lastMetadataSignatureByItemId:new Map}}function U3(G){G.lastSessionEventSignatureByItemId.clear(),G.lastMetadataSignatureByItemId.clear()}function B3(G){let{state:Q,itemId:Y,payload:J}=G;if(hQ(J)){let Z=mQ(J);if(Q.lastMetadataSignatureByItemId.get(Y)===Z)return!1;Q.lastMetadataSignatureByItemId.set(Y,Z)}let X=vQ(J);if(Q.lastSessionEventSignatureByItemId.get(Y)===X)return!1;return Q.lastSessionEventSignatureByItemId.set(Y,X),!0}function vQ(G){let Q={...G};delete Q.timestamp,delete Q.sourceRuntimeId;try{return JSON.stringify(Q)}catch{return String(Q.itemId||"")}}function hQ(G){return G.intent==="metadata-only"}function mQ(G){try{return JSON.stringify({itemId:G.itemId,canonicalItemId:G.canonicalItemId,intent:G.intent,complete:G.complete??null,component:G.component??null})}catch{return String(G.itemId||"")}}var uQ=(G,Q)=>{if(customElements.get(G))return;try{customElements.define(G,Q)}catch(Y){if(!(Y instanceof DOMException&&Y.name==="NotSupportedError"||Y&&typeof Y==="object"&&Y.name==="NotSupportedError")||!customElements.get(G))throw Y}},oQ=v8('<div class="pie-assessment-toolkit-error svelte-vpe4u2" role="alert" aria-live="assertive"><div class="pie-assessment-toolkit-error-title svelte-vpe4u2"> </div> <div class="pie-assessment-toolkit-error-message svelte-vpe4u2"> </div> <pre class="pie-assessment-toolkit-error-details svelte-vpe4u2"> </pre></div>'),aQ=v8('<div class="pie-assessment-toolkit-anchor svelte-vpe4u2" aria-hidden="true"></div> <!>',1),tQ={hash:"svelte-vpe4u2",code:`.pie-assessment-toolkit-anchor.svelte-vpe4u2 {display:none;}.pie-assessment-toolkit-error.svelte-vpe4u2 {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-vpe4u2 {font-weight:600;margin-bottom:0.25rem;}.pie-assessment-toolkit-error-message.svelte-vpe4u2 {margin-bottom:0.5rem;}.pie-assessment-toolkit-error-details.svelte-vpe4u2 {margin:0;white-space:pre-wrap;word-break:break-word;}`};function R3(G,Q){V3(Q,!0),z3(G,tQ);let Y=b1("toolkit"),J=new x8,X=h(null),j=new m7,Z={mode:"gather",role:"student"},K={iife:"pie-item-player",esm:"pie-item-player",preloaded:"pie-item-player",custom:""},W=x(Q,"assessmentId",7,""),B=x(Q,"section",7,null),U=x(Q,"sectionId",7,""),V=x(Q,"attemptId",7,""),H=x(Q,"env",23,()=>({})),N=x(Q,"ndsIcons",7,!1),M=x(Q,"locale",7,""),P=x(Q,"lazyInit",7,!0),$=x(Q,"toolConfigStrictness",7,"error"),A=x(Q,"tools",23,()=>({})),L=x(Q,"toolContextResolvers",7,null),T=x(Q,"enabledTools",7,""),v=x(Q,"toolRegistry",7,null),I=x(Q,"accessibility",23,()=>({})),p=x(Q,"player",7,null),E=x(Q,"playerType",7,""),g=x(Q,"coordinator",7,null),j7=x(Q,"createSectionController",7,null),K7=x(Q,"onFrameworkError",7,null),q7=x(Q,"errorRenderer",7,null),$7=x(Q,"onStageChange",7,null),s7=x(Q,"assessment",7,null),n7=x(Q,"currentItemRef",7,null),r7=x(Q,"pnpEnforcement",7,null),W7=x(Q,"isolation",7,"inherit"),x7=h(null),d=h(null),Y7=h(null),h8=null,f7=null,k7=null,o7=null,I7=null,a7=null,t7=h(0),y1=h(null),e7=h(null),r=h(null),x1=h("Unable to initialize assessment toolkit."),f1=h(f8([])),m8="",k1="",u8=h(""),p8=null,g8=q3(),U7=[],G1=new Map,I1=new WeakMap,c8=W3(),i=cQ({sourceCe:"pie-assessment-toolkit",sourceCeShape:"toolkit",runtimeId:Y,sectionId:m(()=>U()||void 0),attemptId:m(()=>V()||void 0),emit:(q)=>{K3({isSuppressed:()=>_(X)!==null,dispatchDomEvent:(D)=>B7("pie-stage-change",D),getOnStageChange:()=>$7()},q)}}),l8=h(f8(m(()=>`${U()}|${V()}`))),Q1=h(!1),t=h(!1),v1=h(!1),h1=h(!1);function E3(){if(!_(x7))return null;let q=_(x7).getRootNode();if(q&&"host"in q)return q.host;return _(x7).parentElement}let f=n(()=>E3());function B7(q,D){if(!_(f)){U7=[...U7,{name:q,detail:D}];return}b8(_(f),q,D)}b(()=>{if(!_(f))return;if(U7.length===0)return;let q=U7;U7=[],queueMicrotask(()=>{let D=_(f);if(!D){U7=[...q,...U7];return}for(let z of q)b8(D,z.name,z.detail)})});function b3(q){if(!q7())return{title:"Unable to initialize assessment toolkit.",details:q.details.length>0?q.details:[q.message]};try{let D=q7()(q)||{};return{title:typeof D.title==="string"&&D.title.trim().length>0?D.title:"Unable to initialize assessment toolkit.",details:Array.isArray(D.details)&&D.details.length>0?D.details.map((z)=>String(z)):q.details.length>0?q.details:[q.message]}}catch(D){let z=D instanceof Error&&D.message.trim().length>0?D.message:String(D||"Unknown renderer error");return{title:"Unable to initialize assessment toolkit.",details:[...q.details,`Error renderer failed: ${z}`]}}}function v7(q){let D=K1({kind:q.kind,source:q.source,error:q.error,recoverable:q.recoverable});return j.reportFrameworkError(D),D}function T3(q){if(q?.type==="timed-media-policy-degraded"){let z=q.degradations||[];j.reportFrameworkError(j1({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:z.map((O)=>O?.message).filter((O)=>typeof O==="string"),recoverable:!0}));return}if(q?.type!=="timed-media-invalid")return;let D=q.errors||[];j.reportFrameworkError(j1({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:D.map((z)=>z?.message).filter((z)=>typeof z==="string"),recoverable:!1}))}function C3(q){if(q?.type!=="timed-media-audio-started")return;if(!_(S))return;g0(_(S).getServiceBundle().ttsService)}function S3(q){return q==="coordinator-init"||q==="runtime-init"||q==="tool-config"}function d8(q){if(!K7())return;try{K7()(q),m8=`${q.kind}|${q.source}|${q.message}`}catch(D){console.error(`[pie-framework:${q.kind}:${q.source}] framework error hook failed`,D)}}b(()=>{let q=j.subscribeFrameworkErrors((D)=>{if(console.error(Y6(D),D.cause),S3(D.kind)){let z=b3(D);w(r,D,!0),w(x1,z.title,!0),w(f1,z.details,!0)}B7("framework-error",D),d8(D)});return()=>{q()}}),b(()=>{if(!_(r))return;let q=`${_(r).kind}|${_(r).source}|${_(r).message}`;if(m8===q)return;d8(_(r))});function y3(q){let D=5381;for(let z=0;z<q.length;z+=1)D=(D<<5)+D^q.charCodeAt(z);return(D>>>0).toString(36)}function s(q){return q&&typeof q==="object"?q:{}}function x3(q){let D=s(q.section),z=typeof D.identifier==="string"?D.identifier:"",O=typeof q.sectionId==="string"?q.sectionId:"";return z||O}function f3(q){return typeof q.currentItemIndex==="number"?q.currentItemIndex:-1}function k3(q){return(Array.isArray(q.renderables)?q.renderables:[]).map((z,O)=>{let F=s(z),k=s(F.entity),o=typeof k.id==="string"&&k.id||`renderable-${O}`,Z1=s(k.config),c1=typeof k.version==="string"&&k.version||(typeof k.version==="number"?String(k.version):"")||(typeof Z1.version==="string"?Z1.version:"");return{id:o,version:c1}})}function I3(q){let D=s(q.itemSessionsByItemId);return Object.keys(D).sort((z,O)=>z.localeCompare(O)).map((z)=>{let O=s(D[z]),F=typeof O.id==="string"?O.id:"",k=Array.isArray(O.data)?O.data:[],o="";try{o=y3(JSON.stringify(k))}catch{o=String(k.length)}return{itemId:z,sessionId:F,payloadSignature:o}})}function v3(q){let D=s(s(q.formative).states);return Object.entries(D).map(([z,O])=>{let F=s(O),k=s(F.lastOutcome).correctness??"";return`${z}:${F.tryCount??0}:${F.revealed===!0?1:0}:${String(k)}:${String(F.revealOverride??"")}`}).sort().join("|")}function h3(q){let D=q.timedMedia;return rQ(D)}function m3(q){let D=s(q),z=k3(D).map((F)=>`${F.id}:${F.version}`).join("|"),O=I3(D).map((F)=>`${F.itemId}:${F.sessionId}:${F.payloadSignature}`).join("|");return{sectionId:x3(D),currentItemIndex:f3(D),renderableSignature:z,itemSessionSignature:O,formativeSignature:v3(D),timedMediaSignature:h3(D)}}function u3(q){let D=m3(q);return`${D.sectionId}|${D.currentItemIndex}|${D.renderableSignature}|${D.itemSessionSignature}|${D.formativeSignature}|${D.timedMediaSignature}`}function i8(q){return q==="iife"||q==="esm"||q==="preloaded"||q==="custom"}function p3(q,D){let z=q?.type,O=i8(z)?z:i8(D)?D:q?.tagName?"custom":"iife",F=q?.tagName?.trim();if(O==="custom"&&!F)return{type:"iife",tagName:K.iife,version:void 0,source:void 0,isDefault:!0};return{type:O,tagName:F||K[O],version:q?.version,source:q?.source,loaderConfig:q?.loaderConfig,loaderOptions:q?.loaderOptions,isDefault:!q&&!D}}function s8(q){let D=q||{},z=typeof D.mode==="string"&&D.mode.trim()?D.mode.trim():Z.mode,O=typeof D.role==="string"&&D.role.trim()?D.role.trim():Z.role;return{mode:z,role:O}}function g3(q){let D=s8(q);if(D.mode==="author")return"author";if(D.role==="instructor")return"scorer";return"candidate"}async function c3(){if(j7())return j7()();throw Error("pie-assessment-toolkit requires createSectionController when no coordinator hook provides one")}function n8(){let q=A()||{},D=w3(T());if(D.length===0)return q;let z=q.placement||{},O=Array.isArray(z.section)?z.section:null;if(O&&O.length>0)return q;return{...q,placement:{...z,section:D}}}function l3(){return X7(n8(),{strictness:$(),source:"pie-assessment-toolkit.bootstrap",toolRegistry:v()}).config}function d3(){let q="",D="";try{q=JSON.stringify(n8())}catch{q="[unserializable-tools]"}try{D=JSON.stringify(Object.entries(L()??{}).map(([z,O])=>[z,typeof O]))}catch{D="[unserializable-resolvers]"}return[W()||"",String($()||"error"),q,D].join("|")}function r8(q){return q==="on"||q==="off"?q:null}function i3(q,D){let z=r8(q);if(z)return z;if(D&&typeof D==="object"){let F=D.pnpEnforcement;return r8(typeof F==="string"?F:null)}return null}function s3(q){let D=W()||B()?.identifier||`assessment-${Math.random().toString(16).slice(2)}`;return new w1({assessmentId:D,lazyInit:P(),toolConfigStrictness:$(),deferToolConfigValidation:!0,tools:q,toolRegistry:v(),toolContextResolvers:L(),accessibility:I(),frameworkErrorBus:j})}let S=n(()=>{if(W7()!=="force"&&_(Y7)?.coordinator)return _(Y7).coordinator;return g()||_(d)});b(()=>{_(f),g(),W7(),_(Y7),L(),m(()=>{if(!_(f))return;if(g()){if(_(d))w(d,null);f7=null;return}if(W7()!=="force"&&_(Y7)?.coordinator){if(_(d))w(d,null);f7=null;return}if(_(d)&&f7!==L()){try{_(d).setToolContextResolvers(L()),f7=L()}catch(q){w(e7,q,!0),v7({kind:"coordinator-init",phase:"coordinator-ready",error:q})}return}if(!_(d)){let q=d3();if(k1===q)return;try{let D=l3();w(d,s3(D),!0),f7=L(),k1="",w(r,null),w(x1,"Unable to initialize assessment toolkit."),w(f1,[],!0)}catch(D){w(e7,D,!0),w(d,null),k1=q,v7({kind:"coordinator-init",source:"pie-assessment-toolkit",error:D})}}})});let Y1=sQ(),m1=h(0);b(()=>Y1.subscribe(()=>{w(m1,_(m1)+1)})),b(()=>{let q=typeof M()==="string"?M().trim():"";m(()=>{Promise.resolve(Y1.setLocale(q||nQ)).catch((D)=>{v7({kind:"i18n-locale-load",source:"pie-assessment-toolkit",error:D instanceof Error?D:Error(String(D))})})})});let J7=n(()=>W()||_(S)?.assessmentId||""),e=n(()=>U()||B()?.identifier||`section-${_(J7)||"default"}`),u1=n(()=>s8(H())),n3=n(()=>g3(_(u1))),w7=n(()=>p3(p(),E())),h7=n(()=>lQ({player:_(w7),component:"pie-assessment-toolkit"})),J1=n(()=>{if(!_(S))return null;let q=_(S).getServiceBundle();return{toolkitCoordinator:_(S),toolCoordinator:_(S).toolCoordinator,ttsService:q.ttsService,highlightCoordinator:q.highlightCoordinator,catalogResolver:q.catalogResolver,elementToolStateStore:q.elementToolStateStore,assessmentId:_(J7),sectionId:_(e),itemPlayer:_(w7),ndsIcons:N()===!0,locale:(_(m1),Y1.getLocale()),i18n:Y1,reportSessionChanged:(D,z)=>{let O=J.updateItemSession(D,z);t8({itemId:D,result:O,fallbackSession:z})}}}),X1=n(()=>{if(!_(S))return null;return{runtimeId:Y,coordinator:_(S)}});function r3(q){let D=u3(q);if(D===_(u8))return;w(u8,D,!0),w(t7,_(t7)+1),w(y1,q,!0),B7("composition-changed",{composition:_(y1),version:_(t7)})}function p1(q){p8=q??J.getCompositionModel(),g8.schedule(()=>{r3(p8)})}function g1(q){if(!q)return;let D=I1.get(q);if(!D)return;for(let z of D)z();I1.delete(q)}function o8(){for(let q of G1.values())g1(q.element)}function a8(q){if(g1(q.element),!_(S))return;let D=_(S).getServiceBundle().catalogResolver;I1.set(q.element,[D.registerOwner({owner:{kind:q.kind,itemId:q.itemId,canonicalItemId:q.canonicalItemId,assessmentId:_(J7),sectionId:_(e)},entity:q.item})])}function o3(){o8();for(let q of G1.values())a8(q)}function t8(q){let z={...q.result?.eventDetail||q.fallbackSession,itemId:q.itemId,canonicalItemId:q.canonicalItemId||q.itemId,sourceRuntimeId:Y};if(!B3({state:c8,itemId:q.itemId,payload:z}))return;B7("session-changed",z)}function a3(q){if(!(q instanceof HTMLElement))return!1;return pQ(q,I8)?.runtimeId===Y}function D7(q){return q.detail??null}function t3(q,D){for(let z of D)q.addEventListener(z.name,z.handler);return()=>{for(let z of D)q.removeEventListener(z.name,z.handler)}}b(()=>{if(!_(f))return;if(W7()==="force"){w(Y7,null);return}return $3(_(f),(q)=>{if(q.runtimeId===Y)return;w(Y7,q,!0)})}),b(()=>{let q=_(f);return m(()=>{if(!q){w(X,null);return}let D=j3(q,(z)=>{if(z.engine===_(X))return;w(X,z.engine,!0)});return()=>{D(),w(X,null)}})}),b(()=>{let q=_(S);if(!q)return;return m(()=>p0({ttsService:q.getServiceBundle().ttsService,listenerId:`timed-media-audio-handoff:${Y}`,silence:()=>J.requestMediaPauseForCompetingAudio()}))}),b(()=>{let q=W7()!=="force"&&_(Y7)?_(Y7).runtimeId:null,D=q?"inherited":"owned";if(D!==h8)h8=D,B7(D==="inherited"?"runtime-inherited":"runtime-owned",{runtimeId:Y,parentRuntimeId:q})}),b(()=>{let q=_(e),D=V()||"";U3(c8)}),b(()=>{if(!_(f)||!_(X1))return;return I7=new D3(_(f),{context:I8,initialValue:_(X1)}),I7.connect(),a7=new _3(_(f)),a7.attach(),()=>{a7?.detach(),a7=null,I7?.disconnect(),I7=null}}),b(()=>{if(!_(X1))return;I7?.setValue(_(X1))}),b(()=>{if(!_(f))return;_(f).setAttribute("data-item-player-type",_(w7).type),_(f).setAttribute("data-item-player-tag",_(w7).tagName),_(f).setAttribute("data-env-mode",String(_(u1)?.mode||"")),_(f).setAttribute("data-env-role",String(_(u1)?.role||""))}),b(()=>{if(!_(f)||!_(J1))return;return k7=new D3(_(f),{context:L3,initialValue:_(J1)}),k7.connect(),o7=new _3(_(f)),o7.attach(),()=>{o7?.detach(),o7=null,k7?.disconnect(),k7=null}}),b(()=>{if(_(J1))k7?.setValue(_(J1))}),b(()=>{return _(S),_(J7),_(e),o3(),()=>{o8()}}),b(()=>{if(!_(f))return;return gQ({host:_(f),instrumentationProvider:_(h7),component:"pie-assessment-toolkit",eventMap:dQ,staticAttributes:{instrumentationLayer:"toolkit",assessmentId:_(J7),sectionId:_(e),attemptId:V()||void 0}})}),b(()=>{s7(),n7(),r7(),A();let q=_(S);if(!q)return;if(q!==_(d))return;m(()=>{q.setPnpEnforcement(i3(r7(),A())),q.updateAssessment(s7()),q.updateCurrentItemRef(n7())})}),b(()=>{if(!_(S))return;return _(S).subscribeTelemetry(({eventName:q,payload:D})=>{if(!iQ(_(h7)))return;if(!_(h7).isReady())return;let z=q,O=new Date().toISOString(),F={...D||{},instrumentationLayer:"toolkit",assessmentId:_(J7),sectionId:_(e),attemptId:V()||void 0,component:"pie-assessment-toolkit",sourceEventName:q,timestamp:O};_(h7).trackEvent(z,F);let k=D&&typeof D.errorType==="string"?D.errorType:void 0;if(!q.endsWith("-error")&&!k)return;let o=D&&typeof D.message==="string"?D.message:`Toolkit telemetry error: ${q}`;_(h7).trackError(Error(o),{component:"pie-assessment-toolkit",errorType:k||"ToolkitTelemetryError",...F})})}),b(()=>{if(!B()||!_(S))return;let q=!1;return J.initialize({coordinator:_(S),section:B(),sectionId:_(e),assessmentId:_(J7),attemptId:V()||void 0,view:_(n3),createDefaultController:c3,onCompositionChanged:(D)=>{if(q)return;p1(D)},onControllerEvent:(D)=>{if(q)return;C3(D),T3(D)}}).then(()=>{if(q)return;B7("toolkit-ready",{runtimeId:Y,assessmentId:_(J7),sectionId:_(e),itemPlayer:_(w7),coordinator:_(S)}),B7("section-ready",{sectionId:_(e)}),m(()=>{w(h1,!0)})}).catch((D)=>{m(()=>{if(!_(t))w(t,!0),i.enter("engine-ready","skipped");i.enter("interactive","failed")}),w(e7,D,!0),J.reportSectionError({source:"section-runtime",error:D,timestamp:Date.now()}),v7({kind:"runtime-init",source:"pie-assessment-toolkit",error:D})}),()=>{q=!0}}),b(()=>{if(!_(f))return;let q=_(f),D=(O)=>a3(O.target);return t3(q,[{name:c0,handler:(O)=>{if(!D(O))return;let F=D7(O);if(!F?.element||!F?.itemId)return;let k=J.register(F);if(G1.set(F.element,F),a8(F),J.handleContentRegistered(F),k)p1()}},{name:l0,handler:(O)=>{if(!D(O))return;let F=D7(O);if(!F?.itemId)return;let k=F?.element?J.unregister(F.element):!1;if(g1(F.element),F.element)G1.delete(F.element);if(J.handleContentUnregistered(F),k)p1()}},{name:d0,handler:(O)=>{if(!D(O))return;let F=D7(O);if(!F?.itemId)return;let k=J.updateItemSession(F.itemId,F.session);t8({itemId:F.itemId,canonicalItemId:J.getCanonicalItemId(F.itemId),result:k,fallbackSession:F.session})}},{name:i0,handler:(O)=>{if(!D(O))return;let F=D7(O);if(!F?.itemId)return;J.handleContentLoaded({itemId:F.itemId,canonicalItemId:F.canonicalItemId,contentKind:F.contentKind,detail:F.detail,timestamp:Date.now()})}},{name:s0,handler:(O)=>{if(!D(O))return;let F=D7(O);if(!F?.itemId)return;J.handleItemPlayerError({itemId:F.itemId,canonicalItemId:F.canonicalItemId,contentKind:F.contentKind,error:F.error,timestamp:Date.now()})}},{name:n0,handler:(O)=>{if(!D(O))return;let F=D7(O);if(!F?.itemId)return;if(F.action!=="check"&&F.action!=="retry")return;J.handleFormativeAction({itemId:F.canonicalItemId||F.itemId,action:F.action,outcomes:F.outcomes})}},{name:r0,handler:(O)=>{if(!D(O))return;let F=D7(O);if(!F?.renderableId)return;if(F.action!=="attach"&&F.action!=="detach")return;J.handleMediaTimeSource({renderableId:F.renderableId,action:F.action,source:F.source,origin:F.origin})}}])});async function e3(){if(!_(S))throw Error("Coordinator not initialized");await _(S).waitUntilReady()}function G5(){if(!_(S))throw Error("Coordinator not initialized");return _(S).getServiceBundle()}function Q5(q){if(!_(S))throw Error("Coordinator not initialized");_(S).setHooks(q)}function Y5(q){return J.navigateToItem(q)}function J5(){return J.getCompositionModel()}function X5(){return _(w7)}async function Z5(){await J.persist()}async function j5(){await J.hydrate()}b(()=>{return()=>{m(()=>{if(i.getCurrent()!==null)i.enter("disposed")})}}),b(()=>{let q=`${U()}|${V()}`;m(()=>{if(q===_(l8))return;if(i.getCurrent()!==null)i.enter("disposed");i.reset({sectionId:U()||void 0,attemptId:V()||void 0}),w(l8,q),w(Q1,!1),w(t,!1),w(v1,!1),w(h1,!1)})}),b(()=>{let q=_(t)&&_(h1);m(()=>{if(!q)return;if(_(v1))return;w(v1,!0),i.enter("interactive")})}),b(()=>{let q=_(t7)>0||_(y1)!==null;m(()=>{if(!_(Q1)&&q)w(Q1,!0),i.enter("composed")})}),b(()=>{if(!_(S))return;if(!_(Q1))return;if(_(t))return;let q=_(S),D=!1;return q.waitUntilReady().then(()=>{if(D)return;m(()=>{if(_(t))return;w(t,!0),i.enter("engine-ready")})}).catch(()=>{if(D)return;m(()=>{if(_(t))return;w(t,!0),i.enter("engine-ready","failed")})}),()=>{D=!0}}),b(()=>{return()=>{g8.cancel(),J.dispose().catch((q)=>{w(e7,q,!0),v7({kind:"runtime-dispose",source:"pie-assessment-toolkit",error:q,recoverable:!0})}).finally(()=>{j.dispose()})}});var K5={waitUntilReady:e3,getServiceBundle:G5,setHooks:Q5,navigateToItem:Y5,getCompositionModel:J5,getItemPlayerConfig:X5,persist:Z5,hydrate:j5,get assessmentId(){return W()},set assessmentId(q){W(q),y()},get section(){return B()},set section(q){B(q),y()},get sectionId(){return U()},set sectionId(q){U(q),y()},get attemptId(){return V()},set attemptId(q){V(q),y()},get env(){return H()},set env(q){H(q),y()},get ndsIcons(){return N()},set ndsIcons(q){N(q),y()},get locale(){return M()},set locale(q){M(q),y()},get lazyInit(){return P()},set lazyInit(q){P(q),y()},get toolConfigStrictness(){return $()},set toolConfigStrictness(q){$(q),y()},get tools(){return A()},set tools(q){A(q),y()},get toolContextResolvers(){return L()},set toolContextResolvers(q){L(q),y()},get enabledTools(){return T()},set enabledTools(q){T(q),y()},get toolRegistry(){return v()},set toolRegistry(q){v(q),y()},get accessibility(){return I()},set accessibility(q){I(q),y()},get player(){return p()},set player(q){p(q),y()},get playerType(){return E()},set playerType(q){E(q),y()},get coordinator(){return g()},set coordinator(q){g(q),y()},get createSectionController(){return j7()},set createSectionController(q){j7(q),y()},get onFrameworkError(){return K7()},set onFrameworkError(q){K7(q),y()},get errorRenderer(){return q7()},set errorRenderer(q){q7(q),y()},get onStageChange(){return $7()},set onStageChange(q){$7(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 W7()},set isolation(q){W7(q),y()}},e8=aQ(),G6=k8(e8);O3(G6,(q)=>w(x7,q),()=>_(x7));var q5=T1(G6,2);{var W5=(q)=>{var D=oQ(),z=i7(D),O=i7(z,!0);d7(z);var F=T1(z,2),k=i7(F,!0);d7(F);var o=T1(F,2),Z1=i7(o,!0);d7(o),d7(D),A3((c1)=>{S1(O,_(x1)),S1(k,_(r).message),S1(Z1,c1)},[()=>_(f1).join(`
|
|
225
|
+
`)]),C1(q,D)},U5=(q)=>{var D=F3(),z=k8(D);M3(z,Q,"default",{},null),C1(q,D)};N3(q5,(q)=>{if(_(r)&&!_(r).recoverable)q(W5);else q(U5,-1)})}return C1(G,e8),H3(K5)}uQ("pie-assessment-toolkit",P3(R3,{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"},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"},onStageChange:{type:"Object"},assessment:{type:"Object"},currentItemRef:{type:"Object"},pnpEnforcement:{attribute:"pnp-enforcement",type:"String"},isolation:{type:"Object"}},["default"],["waitUntilReady","getServiceBundle","setHooks","navigateToItem","getCompositionModel","getItemPlayerConfig","persist","hydrate"],{mode:"open"}));export{R3 as default};
|