@pie-players/pie-assessment-toolkit 0.3.65 → 0.3.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +36 -16
  2. package/dist/components/ItemToolBar.custom-element.js +1 -1
  3. package/dist/components/PieAssessmentToolkit.custom-element.js +9 -8
  4. package/dist/components/SectionToolBar.custom-element.js +1 -1
  5. package/dist/components/chunks/{ItemToolBar-cckwpz6c.js → ItemToolBar-8jgdz50p.js} +9 -9
  6. package/dist/components/chunks/ItemToolBar-cvs646j3.js +36 -0
  7. package/dist/index.d.ts +4 -3
  8. package/dist/index.js +2 -1
  9. package/dist/policy/core/PolicySource.d.ts +2 -2
  10. package/dist/policy/core/PolicySource.js +2 -2
  11. package/dist/policy/core/ToolPolicyEngine.d.ts +19 -3
  12. package/dist/policy/core/ToolPolicyEngine.js +39 -5
  13. package/dist/policy/core/compose-decision.d.ts +3 -2
  14. package/dist/policy/core/compose-decision.js +3 -2
  15. package/dist/policy/core/decision-types.d.ts +2 -2
  16. package/dist/policy/core/decision-types.js +2 -2
  17. package/dist/policy/core/feature-decision.d.ts +56 -3
  18. package/dist/policy/core/feature-decision.js +60 -3
  19. package/dist/policy/core/pnp-policy-inputs.d.ts +2 -2
  20. package/dist/policy/core/pnp-policy-inputs.js +2 -2
  21. package/dist/policy/core/provenance.d.ts +4 -1
  22. package/dist/policy/core/provenance.js +4 -1
  23. package/dist/policy/engine.d.ts +1 -1
  24. package/dist/policy/engine.js +1 -0
  25. package/dist/policy/sources/PnpPolicySource.d.ts +2 -1
  26. package/dist/policy/sources/PnpPolicySource.js +2 -1
  27. package/dist/runtime/core/engine-transition.js +3 -1
  28. package/dist/services/AccessibilityCatalogResolver.d.ts +49 -10
  29. package/dist/services/AccessibilityCatalogResolver.js +180 -11
  30. package/dist/services/TTSService.d.ts +11 -0
  31. package/dist/services/TTSService.js +220 -32
  32. package/dist/services/ToolRegistry.d.ts +55 -14
  33. package/dist/services/ToolRegistry.js +57 -3
  34. package/dist/services/ToolkitCoordinator.d.ts +18 -1
  35. package/dist/services/ToolkitCoordinator.js +24 -2
  36. package/dist/services/catalog-owner.d.ts +71 -0
  37. package/dist/services/catalog-owner.js +64 -0
  38. package/dist/services/framework-error.d.ts +1 -1
  39. package/dist/services/interfaces.d.ts +15 -3
  40. package/dist/services/tts/browser-provider.js +189 -23
  41. package/dist/tools/content-capability-resolution.d.ts +106 -0
  42. package/dist/tools/content-capability-resolution.js +136 -0
  43. package/dist/tools/internal.d.ts +3 -0
  44. package/dist/tools/internal.js +1 -0
  45. package/package.json +13 -9
  46. package/dist/components/chunks/ItemToolBar-pryf0rtz.js +0 -22
  47. package/dist/runtime/catalog-registration.d.ts +0 -67
  48. package/dist/runtime/catalog-registration.js +0 -86
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Whether a content capability has anything to show, for one entity and one
3
+ * profile.
4
+ *
5
+ * Two independent halves, and a capability is in play only when both answer yes:
6
+ * policy granted one of its support ids, and its own `requiresAuthoredContent`
7
+ * found the resource in this entity's catalogs. Neither implies the other — a
8
+ * learner with an accommodation still sees nothing on an item carrying no
9
+ * resource, and an item carrying one shows nothing to a learner without the
10
+ * grant.
11
+ *
12
+ * Policy answers in three states rather than two, because a host gate is not the
13
+ * absence of a grant: `resolvesWithoutGrant` lets a capability answer from the
14
+ * content when nobody was granted anything, and a host that switched the
15
+ * capability off must not be read as nobody having spoken. Resolution order is
16
+ * denial, then grant, then the content exception.
17
+ *
18
+ * It lives here, data-only and DOM-free, because two renderers ask it. The
19
+ * section player asks continuously: policy and catalogs both change under a
20
+ * mounted card, and it re-resolves to reconcile what is on screen. Print asks
21
+ * once — one learner, one profile, decided before the page exists, with nothing
22
+ * to toggle. A second implementation for the one-shot case would be two
23
+ * renderers disagreeing about the same card, which is the failure this exists to
24
+ * prevent.
25
+ *
26
+ * Capability-neutral, and gated as such: nothing here names a support id, a
27
+ * catalog type, or a surface. The caller passes the registrations and the slot,
28
+ * a capability interprets its own cards, and the resolution owns only the
29
+ * two-halves rule and its one documented exception.
30
+ */
31
+ import type { ToolRegistration } from "../services/ToolRegistry.js";
32
+ import type { CatalogOwnerSnapshot } from "../services/AccessibilityCatalogResolver.js";
33
+ /** What policy answered about one feature id. */
34
+ export type ContentCapabilityPolicy = {
35
+ outcome: "granted";
36
+ /** The support id that was granted — a capability may declare several. */
37
+ featureId: string;
38
+ /** Feature parameters carried by the decision, if any. */
39
+ parameters?: unknown;
40
+ }
41
+ /**
42
+ * No source granted it and none denied it. A capability declaring
43
+ * {@link ToolRegistration.resolvesWithoutGrant} may still answer from the
44
+ * content: silence is what an authored-presentation alternate looks like,
45
+ * since no profile speaks for one either way.
46
+ */
47
+ | {
48
+ outcome: "silent";
49
+ }
50
+ /**
51
+ * A host gate denied it — the off switch, not the absence of a grant. It
52
+ * outranks `resolvesWithoutGrant`, because a host saying a capability has no
53
+ * place in this delivery is a statement authored content cannot overrule.
54
+ */
55
+ | {
56
+ outcome: "denied";
57
+ };
58
+ /** Which half of a capability's resolution failed. */
59
+ export type ContentCapabilityPhase = "policy" | "content";
60
+ /** A capability that is in play, and everything its renderer needs to mount it. */
61
+ export interface ResolvedContentCapability {
62
+ registration: ToolRegistration;
63
+ /**
64
+ * The granted support id, or `""` when the capability resolved without a
65
+ * grant. Passed through to the render context unchanged, so a capability that
66
+ * serves both an authored-presentation case and an accommodation can still
67
+ * tell them apart at render time.
68
+ */
69
+ featureId: string;
70
+ parameters?: unknown;
71
+ /** Whatever the capability's own `resolve` returned; never inspected here. */
72
+ content: unknown;
73
+ }
74
+ export interface ResolveContentCapabilitiesArgs {
75
+ /**
76
+ * The capabilities to consider. A caller with a registry passes
77
+ * `getToolsBySurface(surface)`, which is what keeps a renderer from naming
78
+ * one.
79
+ */
80
+ registrations: readonly ToolRegistration[];
81
+ /** The entity's cards, or `null` when no resolver is available. */
82
+ catalogs: CatalogOwnerSnapshot | null;
83
+ /**
84
+ * Policy's answer about one feature id, in three states.
85
+ *
86
+ * Granting requires a documented need, so an unconfigured feature is
87
+ * `"silent"`, never granted. What the third state buys is the distinction
88
+ * `"silent"` cannot carry: a host that switched the capability off said
89
+ * something, and a capability allowed to answer from content alone must not
90
+ * treat that as nobody having spoken.
91
+ */
92
+ policyFor: (featureId: string) => ContentCapabilityPolicy;
93
+ /**
94
+ * Report a capability that threw. It is dropped either way; this is how a
95
+ * caller surfaces it as its own recoverable warning rather than letting one
96
+ * capability's defect reach the learner's content.
97
+ */
98
+ onError?: (registration: ToolRegistration, phase: ContentCapabilityPhase, error: unknown) => void;
99
+ }
100
+ /**
101
+ * The capabilities in play, in the order the caller offered them.
102
+ *
103
+ * Registry order is preserved so a renderer's slot ordering stays a property of
104
+ * the registry rather than of resolution timing.
105
+ */
106
+ export declare function resolveContentCapabilities(args: ResolveContentCapabilitiesArgs): ResolvedContentCapability[];
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Whether a content capability has anything to show, for one entity and one
3
+ * profile.
4
+ *
5
+ * Two independent halves, and a capability is in play only when both answer yes:
6
+ * policy granted one of its support ids, and its own `requiresAuthoredContent`
7
+ * found the resource in this entity's catalogs. Neither implies the other — a
8
+ * learner with an accommodation still sees nothing on an item carrying no
9
+ * resource, and an item carrying one shows nothing to a learner without the
10
+ * grant.
11
+ *
12
+ * Policy answers in three states rather than two, because a host gate is not the
13
+ * absence of a grant: `resolvesWithoutGrant` lets a capability answer from the
14
+ * content when nobody was granted anything, and a host that switched the
15
+ * capability off must not be read as nobody having spoken. Resolution order is
16
+ * denial, then grant, then the content exception.
17
+ *
18
+ * It lives here, data-only and DOM-free, because two renderers ask it. The
19
+ * section player asks continuously: policy and catalogs both change under a
20
+ * mounted card, and it re-resolves to reconcile what is on screen. Print asks
21
+ * once — one learner, one profile, decided before the page exists, with nothing
22
+ * to toggle. A second implementation for the one-shot case would be two
23
+ * renderers disagreeing about the same card, which is the failure this exists to
24
+ * prevent.
25
+ *
26
+ * Capability-neutral, and gated as such: nothing here names a support id, a
27
+ * catalog type, or a surface. The caller passes the registrations and the slot,
28
+ * a capability interprets its own cards, and the resolution owns only the
29
+ * two-halves rule and its one documented exception.
30
+ */
31
+ /** The support ids a capability answers to, defaulting to its own id. */
32
+ const supportIdsOf = (registration) => registration.pnpSupportIds?.length
33
+ ? registration.pnpSupportIds
34
+ : [registration.toolId];
35
+ /**
36
+ * Everything policy has to say about one capability: a grant, an off switch, or
37
+ * nothing.
38
+ *
39
+ * Denial is checked ahead of a grant on each id rather than after the scan,
40
+ * because the two can only disagree when a host blocked one of a capability's ids
41
+ * while a profile granted another, and there the off switch is the later, more
42
+ * specific statement about this delivery.
43
+ *
44
+ * A host gate names *capabilities*, so the tool id is probed too when it is not
45
+ * already a declared support id — otherwise a capability whose id differs from
46
+ * its support ids would slip a host block. That probe is gate-only: a grant on
47
+ * the tool id is ignored, or blocking would double as a second way to switch a
48
+ * capability on.
49
+ */
50
+ function policyForCapability(registration, args) {
51
+ const supportIds = supportIdsOf(registration);
52
+ for (const supportId of supportIds) {
53
+ const answer = args.policyFor(supportId);
54
+ if (answer.outcome === "denied")
55
+ return { grant: null, denied: true };
56
+ if (answer.outcome === "granted")
57
+ return { grant: answer, denied: false };
58
+ }
59
+ if (supportIds.includes(registration.toolId)) {
60
+ return { grant: null, denied: false };
61
+ }
62
+ return {
63
+ grant: null,
64
+ denied: args.policyFor(registration.toolId).outcome === "denied",
65
+ };
66
+ }
67
+ function resolveOne(registration, args) {
68
+ let grant = null;
69
+ try {
70
+ const answer = policyForCapability(registration, args);
71
+ // Nothing reopens a host denial — not a grant it outranked, and not the
72
+ // content exception below.
73
+ if (answer.denied)
74
+ return null;
75
+ grant = answer.grant;
76
+ }
77
+ catch (error) {
78
+ args.onError?.(registration, "policy", error);
79
+ return null;
80
+ }
81
+ // The exception, and the only one: a capability whose content can declare
82
+ // itself authored presentation is consulted even when policy granted nothing,
83
+ // because an item family designed to be delivered with its alternate on screen
84
+ // is not an accommodation and no profile grants or revokes it. The capability
85
+ // still decides — `granted` is how it tells the two cases apart.
86
+ if (!grant && !registration.resolvesWithoutGrant)
87
+ return null;
88
+ if (!registration.requiresAuthoredContent) {
89
+ // Nothing to look for in the content, so the grant is the whole answer. A
90
+ // capability reaching here without one has no second half to supply it.
91
+ if (!grant)
92
+ return null;
93
+ return {
94
+ registration,
95
+ featureId: grant.featureId,
96
+ parameters: grant.parameters,
97
+ content: null,
98
+ };
99
+ }
100
+ const context = {
101
+ featureId: grant?.featureId ?? "",
102
+ parameters: grant?.parameters,
103
+ catalogs: args.catalogs,
104
+ granted: Boolean(grant),
105
+ };
106
+ let content;
107
+ try {
108
+ content = registration.requiresAuthoredContent.resolve(context);
109
+ }
110
+ catch (error) {
111
+ args.onError?.(registration, "content", error);
112
+ return null;
113
+ }
114
+ // Absent content is the honest answer to "is there anything to show", not a
115
+ // failure: the item carries no resource for this capability.
116
+ if (content === null || content === undefined)
117
+ return null;
118
+ return {
119
+ registration,
120
+ featureId: context.featureId,
121
+ parameters: context.parameters,
122
+ content,
123
+ };
124
+ }
125
+ /**
126
+ * The capabilities in play, in the order the caller offered them.
127
+ *
128
+ * Registry order is preserved so a renderer's slot ordering stays a property of
129
+ * the registry rather than of resolution timing.
130
+ */
131
+ export function resolveContentCapabilities(args) {
132
+ return args.registrations.flatMap((registration) => {
133
+ const resolved = resolveOne(registration, args);
134
+ return resolved ? [resolved] : [];
135
+ });
136
+ }
@@ -20,6 +20,9 @@
20
20
  */
21
21
  export type { HostedToolContext, HostedToolSize, ResolvedToolContext, ToolActivation, ToolContentDependency, ToolContentDependencyContext, ToolModuleLoader, ToolProviderDescriptor, ToolRegistration, ToolRenderElement, ToolSingletonScope, ToolSurfaceRenderContext, ToolSurfaceRenderResult, ToolSurfaceServices, ToolToolbarButtonDefinition, ToolToolbarRenderResult, ToolWindowShellConfig, ToolbarContext, } from "../services/ToolRegistry.js";
22
22
  export { ToolRegistry } from "../services/ToolRegistry.js";
23
+ export type { CatalogOwnerCard, CatalogOwnerSnapshot, } from "../services/AccessibilityCatalogResolver.js";
24
+ export type { ContentCapabilityPhase, ContentCapabilityPolicy, ResolveContentCapabilitiesArgs, ResolvedContentCapability, } from "./content-capability-resolution.js";
25
+ export { resolveContentCapabilities } from "./content-capability-resolution.js";
23
26
  export type { ToolContext, ToolLevel } from "../services/tool-context.js";
24
27
  export { hasChoiceInteraction, hasMathContent, hasReadableText, hasScienceContent, } from "../services/tool-context.js";
25
28
  export { createScopedToolId } from "../services/tool-instance-id.js";
@@ -19,6 +19,7 @@
19
19
  * point — the mechanism is the same one our own registrations use.
20
20
  */
21
21
  export { ToolRegistry } from "../services/ToolRegistry.js";
22
+ export { resolveContentCapabilities } from "./content-capability-resolution.js";
22
23
  export { hasChoiceInteraction, hasMathContent, hasReadableText, hasScienceContent, } from "../services/tool-context.js";
23
24
  // Scoped tool instance ids, so two placements of one tool do not share state.
24
25
  export { createScopedToolId } from "../services/tool-instance-id.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pie-players/pie-assessment-toolkit",
3
- "version": "0.3.65",
3
+ "version": "0.3.67",
4
4
  "type": "module",
5
5
  "description": "PIE assessment toolkit: composable services + reference implementation for assessment players and tool coordination",
6
6
  "license": "MIT",
@@ -41,6 +41,10 @@
41
41
  "types": "./dist/components/section-toolbar-element.d.ts",
42
42
  "import": "./dist/components/section-toolbar-element.js"
43
43
  },
44
+ "./services/AccessibilityCatalogResolver": {
45
+ "types": "./dist/services/AccessibilityCatalogResolver.d.ts",
46
+ "import": "./dist/services/AccessibilityCatalogResolver.js"
47
+ },
44
48
  "./services/pnp-standard-features": {
45
49
  "types": "./dist/services/pnp-standard-features.d.ts",
46
50
  "import": "./dist/services/pnp-standard-features.js"
@@ -79,15 +83,15 @@
79
83
  "test": "bun test"
80
84
  },
81
85
  "dependencies": {
82
- "@pie-players/pie-calculator": "0.3.65",
83
- "@pie-players/pie-context": "0.3.65",
84
- "@pie-players/pie-players-shared": "0.3.65",
85
- "@pie-players/pie-tts": "0.3.65",
86
+ "@pie-players/pie-calculator": "0.3.67",
87
+ "@pie-players/pie-context": "0.3.67",
88
+ "@pie-players/pie-players-shared": "0.3.67",
89
+ "@pie-players/pie-tts": "0.3.67",
86
90
  "speech-rule-engine": "^5.0.0-rc.4"
87
91
  },
88
92
  "peerDependencies": {
89
- "@pie-players/pie-calculator-desmos": "0.3.65",
90
- "@pie-players/tts-client-server": "0.3.65"
93
+ "@pie-players/pie-calculator-desmos": "0.3.67",
94
+ "@pie-players/tts-client-server": "0.3.67"
91
95
  },
92
96
  "peerDependenciesMeta": {
93
97
  "@pie-players/pie-calculator-desmos": {
@@ -100,8 +104,8 @@
100
104
  "devDependencies": {
101
105
  "@biomejs/biome": "^2.5.7",
102
106
  "@happy-dom/global-registrator": "^20.11.1",
103
- "@pie-players/pie-calculator-desmos": "0.3.65",
104
- "@pie-players/tts-client-server": "0.3.65",
107
+ "@pie-players/pie-calculator-desmos": "0.3.67",
108
+ "@pie-players/tts-client-server": "0.3.67",
105
109
  "svelte": "^5.56.8",
106
110
  "typescript": "^5.9.3"
107
111
  },
@@ -1,22 +0,0 @@
1
- import{A as j0,C as bj,D as fL,E as CL,F as _j,G as ZL,H as yL,I as Ej,J as d,K as vj,N as gj,P as $j,R as mj,T as hj,c as PL,d as Ij,e as Cj,f as N,g as a,h as HL,i as RL,j as yj,k as hL,l as KL,m as P0,n as VL,o as UL,p as L,r as R0,s as pj,t as ML,u as QL,v as F,x as DL,y as M0,z as L0}from"./ItemToolBar-cckwpz6c.js";function g0(z){return typeof z.href==="string"}function zj(z){if(!z||typeof z!=="object"||Array.isArray(z))return!1;let P=z;if(typeof P.id!=="string"||P.id.trim().length===0)return!1;if(typeof P.label!=="string"||P.label.trim().length===0)return!1;if(P.ariaLabel!==void 0&&typeof P.ariaLabel!=="string")return!1;if(P.icon!==void 0&&typeof P.icon!=="string")return!1;if(P.tooltip!==void 0&&typeof P.tooltip!=="string")return!1;if(P.active!==void 0&&typeof P.active!=="boolean")return!1;if(P.disabled!==void 0&&typeof P.disabled!=="boolean")return!1;let A=typeof P.href==="string",YL=typeof P.onClick==="function";if(A===YL)return!1;if(A)return!0;return YL}function $0(z){return typeof z==="string"&&z.trimStart().startsWith("<svg")}function m0(z){return typeof z==="string"&&z.trimStart().startsWith("http")}import{sanitizeSvgIcon as Y0}from"@pie-players/pie-players-shared/security";import{approximateZoomFromWidths as WJ,computeZoomCompensation as wJ,ICON_BUTTON_ZOOM_OPTIONS as fj}from"@pie-players/pie-players-shared/ui/zoom-compensation";import{createFocusTrap as zJ,FOCUSABLE_SELECTOR as xj,isProgrammaticFocusTarget as Tj}from"@pie-players/pie-players-shared";var qJ=["assessment","section","item","passage","rubric"],FJ=new Set(qJ);function Hj(z){return FJ.has(z)}function h0(z,P,A){let YL=z.trim(),xL=A.trim();if(!YL||!xL)throw Error("Tool instance ids require non-empty tool and scope ids");if(!Hj(P))throw Error(`Unknown tool scope level '${P}'. Register custom levels with registerToolScopeLevel().`);return`${YL}:${P}:${xL}`}function u0(z){let P=z.split(":");if(P.length!==3)return null;let[A,YL,xL]=P;if(!A||!xL)return null;if(!Hj(YL))return null;return{baseToolId:A,scopeLevel:YL,scopeId:xL}}import"@pie-players/pie-players-shared/nds-icon-button";var kJ=(z,P)=>{if(customElements.get(z))return;try{customElements.define(z,P)}catch(A){if(!(A instanceof DOMException&&A.name==="NotSupportedError"||A&&typeof A==="object"&&A.name==="NotSupportedError")||!customElements.get(z))throw A}},N0=ML('<span class="item-toolbar__element-host svelte-rnx3ie"></span>'),HJ=ML('<span class="item-toolbar__nds-button-zoom svelte-rnx3ie"><nds-icon-button></nds-icon-button></span>',2),G0=ML('<span aria-hidden="true"></span>'),Bj=ML('<img class="item-toolbar__icon-image svelte-rnx3ie" alt=""/>'),Sj=ML('<i aria-hidden="true"></i>'),fJ=ML("<a><!></a>"),xJ=ML('<button type="button"><!></button>'),Aj=ML('<span class="item-toolbar__controls-host svelte-rnx3ie"></span>'),TJ=ML("<div></div>"),BJ=ML('<div><div class="item-toolbar__tools-row svelte-rnx3ie"><!> <!> <!></div> <!></div>'),SJ={hash:"svelte-rnx3ie",code:`.item-toolbar.svelte-rnx3ie {display:flex;flex-direction:column;align-items:flex-end;gap:0;--pie-toolbar-tools-row-height: 2rem;--pie-tts-controls-row-height: 2.875rem;}.item-toolbar__tools-row.svelte-rnx3ie {display:flex;align-items:center;justify-content:flex-end;flex-wrap:nowrap;
2
- /* Cap the gap between toolbar items (e.g. TTS play ↔ calculator) at its
3
- 200%-zoom size with the same factor the buttons use, so the spacing
4
- doesn't keep growing past 200% while the buttons themselves freeze. */gap:calc(0.5rem * var(--pie-toolbar-zoom-comp, 1));min-height:var(--pie-toolbar-tools-row-height);}.item-toolbar__controls-row.svelte-rnx3ie {display:flex;align-items:center;justify-content:flex-end;width:100%;min-height:0;height:auto;}.item-toolbar__controls-row--reserve.svelte-rnx3ie {min-height:var(--pie-tts-controls-row-height);height:var(--pie-tts-controls-row-height);}.item-toolbar__controls-row--active.svelte-rnx3ie {min-height:var(--pie-tts-controls-row-height);height:var(--pie-tts-controls-row-height);}.item-toolbar__controls-row--align-start.svelte-rnx3ie {justify-content:flex-start;}.item-toolbar__controls-host.svelte-rnx3ie {display:inline-flex;align-items:center;justify-content:flex-end;width:100%;}.item-toolbar--top.svelte-rnx3ie,
5
- .item-toolbar--bottom.svelte-rnx3ie {align-items:flex-end;}.item-toolbar--left.svelte-rnx3ie,
6
- .item-toolbar--right.svelte-rnx3ie {align-items:stretch;}.item-toolbar--left.svelte-rnx3ie .item-toolbar__tools-row:where(.svelte-rnx3ie),
7
- .item-toolbar--right.svelte-rnx3ie .item-toolbar__tools-row:where(.svelte-rnx3ie) {flex-direction:column;align-items:center;justify-content:flex-start;flex-wrap:nowrap;}.item-toolbar--left.svelte-rnx3ie .item-toolbar__controls-row:where(.svelte-rnx3ie),
8
- .item-toolbar--right.svelte-rnx3ie .item-toolbar__controls-row:where(.svelte-rnx3ie) {justify-content:flex-start;width:auto;min-height:0;height:auto;}.item-toolbar__button.svelte-rnx3ie {display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0.25rem;border:1px solid var(--pie-button-border, var(--pie-border, #ccc));border-radius:0.25rem;background-color:var(--pie-button-bg, var(--pie-background, white));color:var(--pie-button-color, var(--pie-text, #333));cursor:pointer;transition:all 0.15s ease;text-decoration:none;}
9
-
10
- /* Drive the vendored NDS icon button's outer size via its own \`--height-32\`
11
- custom property so its light-DOM inner button matches the toolbar's
12
- md/sm/lg dimensions (32 / 44 / 40 px) without a layout shift. The glyph
13
- keeps the NDS-native icon size (we render size="small"), so it isn't
14
- oversized. */
15
- /* Freeze the calculator's header open/close button at its 200%-zoom size
16
- (factor is 1 at zoom <= 200%). Zoom on this wrapper, not the host. */.item-toolbar__nds-button-zoom.svelte-rnx3ie {display:inline-flex;zoom:var(--pie-toolbar-zoom-comp, 1);}.item-toolbar.svelte-rnx3ie nds-icon-button:where(.svelte-rnx3ie) {
17
- /* Host-settable button size per toolbar size (drives the NDS outer button
18
- via its own --height-32). */--height-32: var(--pie-calculator-button-size, 2rem);
19
- /* Host-settable accent for the calculator button: the NDS tertiary glyph
20
- colour derives from --color-interactive-blue, remapped here to a
21
- themeable variable. */--color-interactive-blue: var(--pie-calculator-button-color, #146eb3);}.item-toolbar--sm.svelte-rnx3ie nds-icon-button:where(.svelte-rnx3ie) {--height-32: var(--pie-calculator-button-size-sm, 2.75rem);}.item-toolbar--lg.svelte-rnx3ie nds-icon-button:where(.svelte-rnx3ie) {--height-32: var(--pie-calculator-button-size-lg, 2.5rem);}.item-toolbar__element-host.svelte-rnx3ie {display:contents;}.item-toolbar--sm.svelte-rnx3ie .item-toolbar__button:where(.svelte-rnx3ie) {width:2.75rem;height:2.75rem;}.item-toolbar--sm.svelte-rnx3ie {--pie-toolbar-tools-row-height: 2.75rem;--pie-tts-controls-row-height: 3.625rem;}.item-toolbar--lg.svelte-rnx3ie .item-toolbar__button:where(.svelte-rnx3ie) {width:2.5rem;height:2.5rem;}.item-toolbar--lg.svelte-rnx3ie {--pie-toolbar-tools-row-height: 2.5rem;--pie-tts-controls-row-height: 3.375rem;}.item-toolbar__button.svelte-rnx3ie:hover:not(:disabled) {background-color:var(--pie-button-hover-bg, var(--pie-secondary-background, #f5f5f5));border-color:var(--pie-button-hover-border, var(--pie-button-border, var(--pie-border, #ccc)));color:var(--pie-button-hover-color, var(--pie-button-color, var(--pie-text, #333)));transform:translateY(-1px);box-shadow:0 2px 4px color-mix(in srgb, var(--pie-black, #000) 10%, transparent);}.item-toolbar__button.svelte-rnx3ie:active:not(:disabled) {transform:translateY(0);box-shadow:none;}.item-toolbar__button--active.svelte-rnx3ie {background-color:var(--pie-primary, #1976d2);color:var(--pie-white, #fff);border-color:var(--pie-primary, #1976d2);}.item-toolbar__button--active.svelte-rnx3ie:hover:not(:disabled) {background-color:var(--pie-primary-dark, #1565c0);}.item-toolbar__button.svelte-rnx3ie:focus-visible {outline:2px solid var(--pie-button-focus-outline, var(--pie-primary, #1976d2));outline-offset:2px;}.item-toolbar__button.svelte-rnx3ie:disabled {opacity:0.5;cursor:not-allowed;}.item-toolbar__button.svelte-rnx3ie svg {width:100%;height:100%;}.item-toolbar__icon-image.svelte-rnx3ie {width:100%;height:100%;object-fit:contain;}`};function uj(z,P){Ij(P,!0),bj(z,SJ);let A=typeof window<"u",YL=["/_fa-pro/fontawesome.min.css","/_fa-pro/light.min.css"],xL="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.5.2/css/all.min.css",cj="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap",c0=/font.?awesome|fa-?pro/i,s0=!1,q0=()=>{if(!A||s0)return;if(s0=!0,!document.querySelector('link[href*="Roboto"]')){let K=document.createElement("link");K.rel="stylesheet",K.href=cj,document.head.appendChild(K)}if(Array.from(document.querySelectorAll('link[rel="stylesheet"][href]')).some((K)=>c0.test(K.href)))return;if(!document.querySelector(`link[href="${xL}"]`)){let K=document.createElement("link");K.rel="stylesheet",K.href=xL,document.head.appendChild(K)}for(let K of YL){if(document.querySelector(`link[href="${K}"]`))continue;let J=document.createElement("link");J.rel="stylesheet",J.href=K,document.head.appendChild(J)}},i0="__pieFaToolbarShadowInstalled",sj=(j)=>{let K=j.getRootNode();if(!(K instanceof ShadowRoot))return;let J=K;if(J[i0])return;J[i0]=!0;let U=new Set,X=(H)=>{if(!H||U.has(H))return;U.add(H);let i=document.createElement("link");i.rel="stylesheet",i.href=H,K.appendChild(i)},V=Array.from(document.querySelectorAll('link[rel="stylesheet"][href]')).filter((H)=>c0.test(H.href));for(let H of V)X(H.href)},ij=(j)=>{return q0(),sj(j),{}},aj=(j,K)=>{let J=K,U=()=>{let V=j.querySelector("button");if(V)V.setAttribute("aria-pressed",J?"true":"false")};U();let X=new MutationObserver(U);return X.observe(j,{childList:!0,subtree:!0}),{update(V){J=V,U()},destroy(){X.disconnect()}}},dj={calculator:"calculator"},rj=(j)=>dj[j.id]??null,lj=new hj,pL=HL(yj({})),EL=d(P,"level",7,"item"),J0=d(P,"scopeId",7,""),F0=d(P,"itemId",7,""),k0=d(P,"sectionId",7,""),W0=d(P,"catalogId",7,""),w0=d(P,"tools",7,"calculator,textToSpeech,answerEliminator"),z0=d(P,"contentKind",7,"assessment-item"),TL=d(P,"position",7,"bottom"),uL=d(P,"scopeElement",7,null),H0=d(P,"toolRegistry",7,null),f0=d(P,"item",7,null),Z0=d(P,"hostButtons",23,()=>[]),x0=d(P,"class",7,""),cL=d(P,"size",7,"md"),K0=d(P,"language",7,"en-US"),qL=HL(null);function a0(){if(typeof window>"u")return 1;return wJ(WJ(window.outerWidth,window.innerWidth),fj.maxZoom,fj.minCompensation)}let d0=HL(1);VL(()=>{if(typeof window>"u")return;let j=()=>{RL(d0,a0(),!0)};return j(),window.addEventListener("resize",j),()=>window.removeEventListener("resize",j)});let $=HL(null),sL=N(()=>L($)?.ndsIcons===!0),bL=HL(null),iL=HL(0),U0=HL(0),T0=HL(0);VL(()=>{if(!L(qL))return;return gj(L(qL),(j)=>{RL($,j,!0)})}),VL(()=>{if(!L(qL))return;return $j(L(qL),(j)=>{RL(bL,j,!0)})}),VL(()=>{let j=L($)?.toolkitCoordinator;if(!j||typeof j.onPolicyChange!=="function")return;let K=j.onPolicyChange(()=>{RL(U0,L(U0)+1)});return()=>{try{K?.()}catch{}}}),VL(()=>{let j=L($)?.toolkitCoordinator;if(!j||typeof j.onToolContextResolverChange!=="function")return;let K=j.onToolContextResolverChange(()=>{RL(T0,L(T0)+1)});return()=>{try{K?.()}catch{}}});let y=N(()=>L($)?.toolCoordinator),r0=N(()=>L($)?.ttsService),vL=N(()=>L($)?.elementToolStateStore),Q0=N(()=>L($)?.assessmentId??""),aL=N(()=>F0()||L(bL)?.itemId||""),r=N(()=>L(bL)?.canonicalItemId||L(aL)),BL=N(()=>k0()||L($)?.sectionId||""),gL=N(()=>z0()||L(bL)?.contentKind||(EL()==="section"?"section":"assessment-item")),p=N(()=>{if(EL()&&EL()!=="item")return EL();if(L(gL)==="rubric-block-stimulus")return"passage";return"item"}),SL=N(()=>{if(J0())return J0();if(L(p)==="section")return L(BL)||L($)?.sectionId||"default-section";if(L(p)==="assessment")return L($)?.assessmentId||"default-assessment";return L(r)||L(aL)||"default-item"}),l0=N(()=>W0()||L(SL)),WL=N(()=>f0()||L(bL)?.item||null),XL=N(()=>H0()||lj),oj=N(()=>mj(w0())),nj=N(()=>L(XL).normalizeToolIds(L(oj)).filter(Boolean)),tj=N(()=>{if(L(p)==="section")return"section";if(L(p)==="passage"||L(gL)==="rubric-block-stimulus")return"passage";return"item"}),o0=N(()=>{L(U0);let j=L($)?.toolkitCoordinator;if(!j||typeof j.decideToolPolicy!=="function")return null;return j.decideToolPolicy({level:L(tj),scope:{level:L(p),scopeId:L(SL),assessmentId:L($)?.assessmentId,sectionId:L(BL)||void 0,itemId:L(aL)||void 0,canonicalItemId:L(r)||void 0,contentKind:L(gL)}})}),n0=N(()=>{let j=(K)=>Array.from(new Set(K));if(L(o0))return j(L(XL).normalizeToolIds(L(o0).visibleTools.map((K)=>K.toolId)).filter(Boolean));return j(L(nj))}),B0=N(()=>{if(L(p)==="section"||L(p)==="assessment")return!0;let j=L(WL)?.config;return!!(L(WL)&&j&&typeof j==="object")}),t0=N(()=>{L(U0);let j=L($)?.toolkitCoordinator;if(!j||typeof j.getPolicyInputs!=="function")return null;return j.getPolicyInputs()}),$L=N(()=>L(t0)?.assessment??null),D0=N(()=>L(t0)?.currentItemRef??null),dL=N(()=>{if(L(p)==="section")return{level:"section",assessment:L($L)||{},section:{}};if(L(p)==="assessment")return{level:"assessment",assessment:L($L)||{}};if(!L(B0)||!L(WL))return null;if(L(p)==="passage")return{level:"passage",assessment:L($L)||{},itemRef:L(D0)||{id:L(r)},passage:L(WL)};return{level:"item",assessment:L($L)||{},itemRef:L(D0)||{id:L(r)},item:L(WL)}}),e0=N(()=>{if(L(dL))return L(dL);return{level:"item",assessment:L($L)||{},itemRef:L(D0)||{id:L(r)},item:L(WL)||{id:L(r),config:{}}}}),Lj=N(()=>{if(L(p)!=="item"&&L(p)!=="passage")return[];if(!L(B0)||!L(WL))return[];let j=L(WL)?.config?.models;return(Array.isArray(j)?j:j&&typeof j==="object"?Object.values(j):[]).filter((J)=>J&&typeof J==="object"&&typeof J.id==="string").map((J)=>({level:"element",assessment:L($L)||{},itemRef:L(D0)||{id:L(r)},item:L(WL),elementId:J.id}))}),ej=N(()=>{let j=L($)?.toolkitCoordinator||null,K=(J)=>u0(J)?J:h0(J,L(p),L(SL));return{scope:{level:L(p),scopeId:L(SL),assessmentId:L($)?.assessmentId,sectionId:L(BL),itemId:L(aL),canonicalItemId:L(r),contentKind:L(gL)},itemId:L(SL),catalogId:L(l0),language:K0(),ui:{size:cL()},getScopeElement:()=>uL()||L(bL)?.scopeElement||null,getGlobalElementId:()=>{if(!L(vL)||!L(Q0)||!L(BL)||!L(r))return null;return L(vL).getGlobalElementId(L(Q0),L(BL),L(r),L(r))},toolCoordinator:L(y)||null,toolkitCoordinator:j,ttsService:L(r0)||null,elementToolStateStore:L(vL)||null,toggleTool:(J)=>{if(!L(y))return;let U=K(J);if(!L(y).getToolState(U))L(y).registerTool(U,J);L(y).toggleTool(U)},isToolVisible:(J)=>{if(!L(y))return!1;return L(y).isToolVisible(K(J))},subscribeVisibility:L(y)?(J)=>L(y).subscribe(J):null}}),S0=N(()=>{L(T0);let j=L($)?.toolkitCoordinator;if(!j||typeof j.hasToolContextResolver!=="function"||typeof j.resolveToolContext!=="function")return{};let K={};for(let J of L(n0)){if(!L(XL).get(J)?.supportedLevels.includes(L(p)))continue;if(!j.hasToolContextResolver(J))continue;let X=j.resolveToolContext({toolId:J,context:L(e0),toolbarContext:L(ej)});if(X)K[J]=X}return K}),LJ=N(()=>{let j=L(n0).filter((V)=>{let H=L(XL).get(V);return H?H.supportedLevels.includes(L(p)):!1}),K=Object.values(L(S0)),J=new Set(K.map((V)=>V.toolId)),U=new Set(K.filter((V)=>V.visible).map((V)=>V.toolId)),X=j.filter((V)=>!J.has(V));if(L(p)==="section")return X.forEach((V)=>U.add(V)),Array.from(U);if(!L(B0))return X.forEach((V)=>U.add(V)),Array.from(U);if(!L(dL)&&L(Lj).length===0)return X.forEach((V)=>U.add(V)),Array.from(U);if(L(dL))L(XL).filterVisibleInContext(X,L(dL)).forEach((V)=>U.add(V.toolId));for(let V of L(Lj))L(XL).filterVisibleInContext(X,V).forEach((H)=>U.add(H.toolId));return Array.from(U)}),A0=N(()=>L(XL).filterToolIdsByActivation(L(LJ),"toolbar-toggle"));VL(()=>{if(!A)return;let j=!1;return L(XL).ensureToolModulesLoaded(L(A0)).then(()=>{if(!j)RL(iL,L(iL)+1)}).catch((K)=>{console.error("[ItemToolBar] Failed to load one or more tool modules:",K)}),()=>{j=!0}});function jJ(){if(uL())return uL();return L(bL)?.scopeElement||null}function JJ(){if(!L(vL)||!L(Q0)||!L(BL)||!L(r))return null;return L(vL).getGlobalElementId(L(Q0),L(BL),L(r),L(r))}let _L=N(()=>{let j=L($)?.toolkitCoordinator||null,K=(J)=>{return u0(J)?J:h0(J,L(p),L(SL))};return{scope:{level:L(p),scopeId:L(SL),assessmentId:L($)?.assessmentId,sectionId:L(BL),itemId:L(aL),canonicalItemId:L(r),contentKind:L(gL)},itemId:L(SL),catalogId:L(l0),language:K0(),ui:{size:cL()},getScopeElement:jJ,getGlobalElementId:JJ,toolCoordinator:L(y)||null,toolkitCoordinator:j,ttsService:L(r0)||null,elementToolStateStore:L(vL)||null,toggleTool:(J)=>{if(!L(y))return;let U=K(J);if(!L(y).getToolState(U))L(y).registerTool(U,J);L(y).toggleTool(U)},isToolVisible:(J)=>{if(!L(y))return!1;return L(y).isToolVisible(K(J))},subscribeVisibility:L(y)?(J)=>L(y).subscribe(J):null,getResolvedToolContext:(J)=>L(S0)[J]??null,getToolRenderParams:(J)=>L(S0)[J]?.params??null}}),wL=N(()=>{if(!A)return[];L(iL);let j=[];for(let K of L(A0)){let J=L(XL).renderForToolbar(K,L(e0),L(_L));if(J)j.push(J)}return j}),ZJ=N(()=>{if(!Array.isArray(Z0()))return[];let j=[];return Z0().forEach((K,J)=>{if(zj(K)){j.push(K);return}console.warn(`[ItemToolBar] Ignoring invalid host button at index ${J}. Expected { id, label, href | onClick } with valid types.`)}),j}),KJ=N(()=>L(wL).filter((j)=>!!j.button).map((j)=>{let K=j.button;return{id:j.toolId,label:K.label,ariaLabel:K.ariaLabel||K.label,icon:K.icon,tooltip:K.tooltip||K.label,disabled:K.disabled,active:L(pL)[j.toolId]??K.active??!1,onClick:()=>{K.onClick(),lL()}}})),jj=N(()=>[...L(KJ),...L(ZJ)]),rL=N(()=>{let j={};for(let K of L(wL))j[K.toolId]=L(pL)[K.toolId]??K.button?.active??!1;return j}),UJ=N(()=>L(wL).flatMap((j)=>(j.elements||[]).filter((K)=>K.mount==="before-buttons").filter((K)=>Boolean(K.element)).map((K,J)=>({key:`before-${j.toolId}-${J}`,toolId:j.toolId,entry:K})))),QJ=N(()=>L(wL).flatMap((j)=>(j.elements||[]).filter((K)=>K.mount==="after-buttons").filter((K)=>Boolean(K.element)).map((K,J)=>({key:`after-${j.toolId}-${J}`,toolId:j.toolId,entry:K})))),Jj=N(()=>L(wL).flatMap((j)=>(j.elements||[]).filter((K)=>K.mount==="controls-row").filter((K)=>Boolean(K.element)).map((K,J)=>({key:`controls-row-${j.toolId}-${J}`,toolId:j.toolId,entry:K})))),Zj=N(()=>L(wL).flatMap((j)=>(j.elements||[]).map((K)=>({toolId:j.toolId,hint:K.layoutHints?.controlsRow})).filter((K)=>Boolean(K.hint)))),Kj=N(()=>L(wL).flatMap((j)=>(j.elements||[]).map((K)=>({toolId:j.toolId,hint:K.layoutHints?.headerOverlay})).filter((K)=>Boolean(K.hint)))),Uj=N(()=>L(Zj).some((j)=>j.hint?.reserveSpace===!0)),Qj=N(()=>L(Zj).some((j)=>j.hint?.showWhenToolActive===!0&&(L(rL)[j.toolId]??!1))),DJ=N(()=>TL()==="left"||TL()==="right"),Dj=N(()=>L(Kj).some((j)=>j.hint?.showWhenToolActive===!0&&(L(rL)[j.toolId]??!1))),XJ=N(()=>L(Jj).length>0||L(Uj)||L(Qj));function OJ(){if(!L(qL))return null;let j=L(qL).getRootNode();if(j instanceof ShadowRoot)return j.host;return null}VL(()=>{let j=OJ();if(!j)return;let K=L(Kj).length>0,J=L(Dj);return j.setAttribute("data-pie-header-overlay",K?"true":"false"),j.setAttribute("data-pie-header-overlay-active",J?"true":"false"),()=>{j.removeAttribute("data-pie-header-overlay"),j.removeAttribute("data-pie-header-overlay-active")}}),VL(()=>{if(!A)return;if(L(jj).some((j)=>j.icon==="calculator"))q0()});function X0(j){if(j.id in L(pL))return L(pL)[j.id]===!0;return j.active===!0}function Xj(j){return{calculator:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 2h10a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2Zm0 2v4h10V4H7Zm0 6v2h2v-2H7Zm4 0v2h2v-2h-2Zm4 0v2h2v-2h-2Zm-8 4v2h2v-2H7Zm4 0v2h2v-2h-2Zm4 0v2h2v-2h-2Zm-8 4v2h2v-2H7Zm4 0v2h2v-2h-2Zm4 0v2h2v-2h-2Z" fill="currentColor"/></svg>',"volume-up":'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 3.23v2.06A7.002 7.002 0 0 1 19 12a7 7 0 0 1-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77Zm-2 17.75V3L7 8H3v8h4l5 5Zm4.5-9a4.5 4.5 0 0 0-2.5-4.03v8.05A4.5 4.5 0 0 0 16.5 12Z" fill="currentColor"/></svg>',swatch:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 3a9 9 0 1 0 9 9c0-.55-.45-1-1-1h-2.5a1.5 1.5 0 0 1 0-3H20a1 1 0 0 0 1-1 8.99 8.99 0 0 0-9-4Zm-5.5 9A1.5 1.5 0 1 1 8 13.5 1.5 1.5 0 0 1 6.5 12Zm3-4A1.5 1.5 0 1 1 11 9.5 1.5 1.5 0 0 1 9.5 8Zm5 0A1.5 1.5 0 1 1 16 9.5 1.5 1.5 0 0 1 14.5 8Z" fill="currentColor"/></svg>',"chart-bar":'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4.75 5a.76.76 0 0 1 .75.75v11c0 .438.313.75.75.75h13a.76.76 0 0 1 .696 1.039.74.74 0 0 1-.696.461h-13C5 19 4 18 4 16.75v-11A.74.74 0 0 1 4.75 5ZM8 8.25a.74.74 0 0 1 .75-.75h6.5a.76.76 0 0 1 .696 1.039.74.74 0 0 1-.696.461h-6.5A.722.722 0 0 1 8 8.25Zm.75 2.25h4.5a.76.76 0 0 1 .696 1.039.74.74 0 0 1-.696.461h-4.5a.723.723 0 0 1-.75-.75.74.74 0 0 1 .75-.75Zm0 3h8.5a.76.76 0 0 1 .696 1.039.74.74 0 0 1-.696.461h-8.5a.723.723 0 0 1-.75-.75.74.74 0 0 1 .75-.75Z" fill="currentColor"/></svg>',beaker:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5 21c-.85 0-1.454-.38-1.813-1.137-.358-.759-.27-1.463.263-2.113L9 11V5H8a.968.968 0 0 1-.713-.287A.968.968 0 0 1 7 4c0-.283.096-.52.287-.712A.968.968 0 0 1 8 3h8c.283 0 .52.096.712.288.192.191.288.429.288.712s-.096.52-.288.713A.968.968 0 0 1 16 5h-1v6l5.55 6.75c.533.65.62 1.354.262 2.113C20.454 20.62 19.85 21 19 21H5Zm2-3h10l-3.4-4h-3.2L7 18Zm-2 1h14l-6-7.3V5h-2v6.7L5 19Z" fill="currentColor"/></svg>',protractor:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m6.75 21-.25-2.2 2.85-7.85a3.95 3.95 0 0 0 1.75.95l-2.75 7.55L6.75 21Zm10.5 0-1.6-1.55-2.75-7.55a3.948 3.948 0 0 0 1.75-.95l2.85 7.85-.25 2.2ZM12 11a2.893 2.893 0 0 1-2.125-.875A2.893 2.893 0 0 1 9 8c0-.65.188-1.23.563-1.737A2.935 2.935 0 0 1 11 5.2V3h2v2.2c.583.2 1.063.554 1.438 1.063C14.812 6.77 15 7.35 15 8c0 .833-.292 1.542-.875 2.125A2.893 2.893 0 0 1 12 11Zm0-2c.283 0 .52-.096.713-.287A.967.967 0 0 0 13 8a.967.967 0 0 0-.287-.713A.968.968 0 0 0 12 7a.968.968 0 0 0-.713.287A.967.967 0 0 0 11 8c0 .283.096.52.287.713.192.191.43.287.713.287Z" fill="currentColor"/></svg>',"bars-3":'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6.85 15c.517 0 .98-.15 1.388-.45.408-.3.695-.692.862-1.175l.375-1.15c.267-.8.2-1.537-.2-2.213C8.875 9.337 8.3 9 7.55 9H4.025l.475 3.925c.083.583.346 1.075.787 1.475.442.4.963.6 1.563.6Zm10.3 0c.6 0 1.12-.2 1.563-.6.441-.4.704-.892.787-1.475L19.975 9h-3.5c-.75 0-1.325.342-1.725 1.025-.4.683-.467 1.425-.2 2.225l.35 1.125c.167.483.454.875.862 1.175.409.3.871.45 1.388.45Zm-10.3 2c-1.1 0-2.063-.363-2.887-1.088a4.198 4.198 0 0 1-1.438-2.737L2 9H1V7h6.55c.733 0 1.404.18 2.013.537A3.906 3.906 0 0 1 11 9h2.025c.35-.617.83-1.104 1.438-1.463A3.892 3.892 0 0 1 16.474 7H23v2h-1l-.525 4.175a4.198 4.198 0 0 1-1.438 2.737A4.238 4.238 0 0 1 17.15 17c-.95 0-1.804-.27-2.562-.813A4.234 4.234 0 0 1 13 14.026l-.375-1.125a21.35 21.35 0 0 1-.1-.363 4.926 4.926 0 0 1-.1-.537h-.85c-.033.2-.067.363-.1.488a21.35 21.35 0 0 1-.1.362L11 14a4.3 4.3 0 0 1-1.588 2.175A4.258 4.258 0 0 1 6.85 17Z" fill="currentColor"/></svg>',ruler:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m8.8 10.95 2.15-2.175-1.4-1.425-1.1 1.1-1.4-1.4 1.075-1.1L7 4.825 4.825 7 8.8 10.95Zm8.2 8.225L19.175 17l-1.125-1.125-1.1 1.075-1.4-1.4 1.075-1.1-1.425-1.4-2.15 2.15L17 19.175ZM7.25 21H3v-4.25l4.375-4.375L2 7l5-5 5.4 5.4 3.775-3.8c.2-.2.425-.35.675-.45a2.068 2.068 0 0 1 1.55 0c.25.1.475.25.675.45L20.4 4.95c.2.2.35.425.45.675.1.25.15.508.15.775a1.975 1.975 0 0 1-.6 1.425l-3.775 3.8L22 17l-5 5-5.375-5.375L7.25 21ZM5 19h1.4l9.8-9.775L14.775 7.8 5 17.6V19Z" fill="currentColor"/></svg>'}[j]||null}function lL(){let j={};for(let K of L(wL))if(K.sync?.(),K.button)j[K.toolId]=K.button.active??!1;RL(pL,j,!0)}VL(()=>{let j=[];lL();for(let K of L(wL))if(K.subscribeActive){let J=!1,U=K.subscribeActive((X)=>{queueMicrotask(()=>{if(J)return;RL(pL,{...L(pL),[K.toolId]:X},!0),K.sync?.()})});j.push(()=>{J=!0,U()})}return()=>{j.forEach((K)=>K())}}),VL(()=>{if(!L(_L).subscribeVisibility)return;let j=!1,K=L(_L).subscribeVisibility(()=>{queueMicrotask(()=>{if(j)return;lL()})});return()=>{j=!0,K?.()}}),VL(()=>{let j=L(_L).toolkitCoordinator;if(typeof j?.subscribeTelemetry!=="function")return;let K=!1,J=j.subscribeTelemetry(({eventName:U,payload:X})=>{if(U!=="pie-toolkit-tool-config-updated")return;if(X?.toolId&&!L(A0).includes(X.toolId))return;queueMicrotask(()=>{if(K)return;RL(iL,L(iL)+1),lL()})});return()=>{K=!0,J?.()}});function I0(j,K){let J=null,U=(V)=>{if(!V)return;let H=V.__pieToolElementUnmount;if(typeof H==="function")H()},X=(V)=>{if(J===V)return;if(J){if(U(J),J.parentNode===j)j.removeChild(J)}if(J=V,J){if(J.parentNode&&J.parentNode!==j)J.parentNode.removeChild(J);j.appendChild(J)}};return X(K),{update(V){X(V)},destroy(){X(null)}}}function C0(j,K){let J=K,U=null,X=null,V=null,H=null,i=null,FL=null,c=null,Y=null,l=null,o=!1,s=!1,k=null,B=null,b=null,LL=0,m=0,I=0,f=0,q=0,T=0,n=0,NL=0,C=null,GL=[],_=0,E=0,v=J.mounted.entry.shell?.initialWidth??720,g=J.mounted.entry.shell?.initialHeight??560,kL=null,jL=null,x=!1,S=(Z)=>{if(!Z)return;let D=Z.__pieToolElementUnmount;if(typeof D==="function")D()},zL=()=>{let Z=J.mounted.entry.shell;if(!Z)return null;return{toolId:J.mounted.toolId,toolbarContext:L(_L),shellConfig:Z}},oL=(Z)=>{let D=L(XL).get(J.mounted.toolId),R=zL();if(!D?.onHostedMount||!R)return;D.onHostedMount(Z,R)},AL=()=>{let Z=L(XL).get(J.mounted.toolId),D=zL();if(!Z?.onHostedResize||!D)return;Z.onHostedResize({width:v,height:g},J.mounted.entry.element,D)},nL=()=>{let Z=L(XL).get(J.mounted.toolId),D=zL();if(!Z?.onHostedUnmount||!D)return;Z.onHostedUnmount(J.mounted.entry.element,D)},w=(Z,D,R)=>Math.max(D,Math.min(Z,R)),t=()=>{let Z=J.mounted.entry.shell,D=Z?.minWidth??320,R=Z?.minHeight??240,O=Z?.maxWidth??window.innerWidth,G=Z?.maxHeight??window.innerHeight;return{minWidth:D,minHeight:R,maxWidth:O,maxHeight:G}},y0=()=>{let Z=J.mounted.entry.shell?.minWidth,D=typeof Z==="number"&&Z>0&&v<Z,R=D?`${Z}px`:"";if(k)k.style.minWidth=R;if(X)X.style.minWidth=R;if(V)V.style.minWidth=R;if(U)U.style.overflowX=D?"auto":"visible",U.style.overflowY="visible"},Vj=()=>J.mounted.entry.shell?.content?.overflowY==="auto"?"auto":"hidden",GJ=()=>{if(!X)return 0;let Z=X.getBoundingClientRect().height;if(Z>0)return Z;return X.offsetHeight||0},p0=()=>{if(!V)return;let Z=J.mounted.entry.shell;if(V.style.overflowX="hidden",V.style.overflowY=Vj(),!k)return;if(Z?.content?.preserveMinHeight===!0){let D=GJ(),R=Z.minHeight??240,O=Math.max(0,R-D),G=Math.max(0,g-D),Q=Math.max(G,O);k.style.height=`${Q}px`,k.style.minHeight="0",k.style.flex=`0 0 ${Q}px`;return}k.style.height="100%",k.style.minHeight="0",k.style.flex="1 1 auto"},O0=()=>{let{minWidth:Z,minHeight:D,maxWidth:R,maxHeight:O}=t(),G=Math.min(Z,window.innerWidth),Q=Math.min(D,window.innerHeight);v=w(v,G,Math.max(G,Math.min(R,window.innerWidth))),g=w(g,Q,Math.max(Q,Math.min(O,window.innerHeight))),_=w(_,0,Math.max(0,window.innerWidth-v)),E=w(E,0,Math.max(0,window.innerHeight-g)),tL(),y0(),p0(),AL()},IL=(Z,D)=>{_+=Z,E+=D,O0()},V0=(Z,D)=>{v+=Z,g+=D,O0()},Yj=(Z,D,R,O="fa-regular")=>{let G=document.createElement("nds-icon-button");if(G.setAttribute("variant","tertiary"),G.setAttribute("size","small"),G.setAttribute("type","circle"),G.setAttribute("icon-name",D),G.setAttribute("button-aria-label",Z),G.title=Z,G.addEventListener("click",(Q)=>{Q.stopPropagation(),R(),mL()}),O!=="fa-light"){let Q=(M)=>{M.classList.remove("fa-light"),M.classList.add(O)},W=G.querySelector("i.fa-light");if(W)Q(W);else{let M=new MutationObserver(()=>{let h=G.querySelector("i.fa-light");if(h)Q(h),M.disconnect()});M.observe(G,{childList:!0,subtree:!0})}}return G},Nj=(Z,D,R)=>{let O=document.createElement("button");return O.type="button",O.className="pie-tool-shell__control",O.setAttribute("aria-label",Z),O.title=Z,O.textContent=D,O.style.border="1px solid transparent",O.style.background="color-mix(in srgb, var(--pie-white, #fff) 10%, transparent)",O.style.color="inherit",O.style.cursor="pointer",O.style.display="inline-flex",O.style.alignItems="center",O.style.justifyContent="center",O.style.width="28px",O.style.height="28px",O.style.padding="0",O.style.fontSize="14px",O.style.fontWeight="700",O.style.borderRadius="8px",O.style.lineHeight="1",O.onclick=(G)=>{G.stopPropagation(),R(),mL()},O.onfocus=()=>{O.style.outline="2px solid var(--pie-button-focus-outline, var(--pie-primary, #4A90E2))",O.style.outlineOffset="2px"},O.onblur=()=>{O.style.outline="none",O.style.outlineOffset="0"},O},tL=()=>{if(!U)return;U.style.left=`${_}px`,U.style.top=`${E}px`,U.style.width=`${v}px`,U.style.height=`${g}px`,U.style.display=J.active?"flex":"none",U.style.setProperty("--pie-tool-shell-zoom-comp",String(a0()))},Gj=()=>{if(!V)return;let Z=J.mounted.entry.element;if(Z.style.display="block",Z.style.width="100%",Z.style.height="100%",Z.style.flex="1 1 auto",Z.style.minHeight="0",k&&k!==Z){if(k.parentNode===V)S(k),V.removeChild(k);k=null}if(Z.parentNode&&Z.parentNode!==V)Z.parentNode.removeChild(Z);if(Z.parentNode!==V)V.appendChild(Z);k=Z,y0(),p0(),oL(Z)},mL=()=>{if(L(y)&&U)L(y).bringToFront(U)},b0=()=>{let{innerWidth:Z,innerHeight:D}=window,R=J.mounted.entry.shell,O=R?.initialAlign??"center",G=R?.initialMargin??16,Q=G+60;switch(O){case"top-left":_=G,E=Q;break;case"top-right":_=Math.max(0,Z-v-G),E=Q;break;case"bottom-left":_=G,E=Math.max(0,D-g-Q);break;case"bottom-right":_=Math.max(0,Z-v-G),E=Math.max(0,D-g-Q);break;default:_=Math.max(0,Math.round((Z-v)/2)),E=Math.max(0,Math.round((D-g)/2))}O0()},PJ=()=>{let Z=jL;if(!Z)return;queueMicrotask(()=>{if(!Z.isConnected)return;try{Z.focus()}catch{}})},Pj=()=>{if(typeof document>"u")return null;let Z=document.activeElement;while(Z){let D=Z.shadowRoot;if(D&&D.activeElement&&D.activeElement!==Z)Z=D.activeElement;else break}return Z??null},Rj=()=>{if(!U||kL)return;let Z=Pj();if(!jL&&Z&&!U.contains(Z))jL=Z;let D=J.mounted.toolId==="calculator";if(D&&!s)document.addEventListener("keydown",E0,!0),s=!0;kL=zJ(U,{initialFocus:FL,onEscape:()=>{v0()},wrap:!D,onTabExit:D?(R,O)=>{if(R==="backward"){if(jL?.isConnected){O.preventDefault();try{jL.focus()}catch{}}return}let G=_0();if(G){O.preventDefault();try{G.focus()}catch{}}}:void 0})},_0=()=>{let Z=L(_L).getScopeElement?.()??null;if(!Z)return null;let D=(O)=>{if(L(qL)&&L(qL).contains(O))return!0;if(U&&U.contains(O))return!0;return!1},R=(O)=>{if(O instanceof HTMLElement){if(D(O))return null;if(O.matches?.(xj)&&Tj(O))return O}let G=O.shadowRoot;if(G)for(let Q=0;Q<G.children.length;Q++){let W=R(G.children[Q]);if(W)return W}for(let Q=0;Q<O.children.length;Q++){let W=R(O.children[Q]);if(W)return W}return null};return R(Z)},RJ=()=>{if(!U)return[];return Array.from(U.querySelectorAll(xj)).filter((Z)=>Z!==Y&&Z!==l).filter(Tj)},E0=(Z)=>{if(Z.key!=="Tab")return;if(!U||!J.active)return;let D=Pj();if(!D)return;if(U.contains(D))return;let R=RJ();if(R.length===0)return;if(Z.shiftKey){let O=_0();if(D!==O)return;Z.preventDefault();try{R[R.length-1].focus()}catch{}return}if(D!==jL)return;Z.preventDefault();try{R[0].focus()}catch{}},Mj=()=>{if(s)document.removeEventListener("keydown",E0,!0),s=!1;if(!kL)return;let Z=kL;kL=null;try{Z()}catch{}PJ()},v0=()=>{L(_L).toggleTool(J.mounted.toolId),lL()},qj=(Z)=>{if(!J.mounted.entry.shell?.draggable)return;if(Z.target.closest("button")||!U)return;Z.preventDefault(),B=Z.pointerId,LL=Z.clientX-_,m=Z.clientY-E,U.setPointerCapture(Z.pointerId),mL()},MJ=(Z)=>(D)=>{if(!U||!J.mounted.entry.shell?.resizable)return;D.preventDefault(),D.stopPropagation(),b=D.pointerId,C=Z,I=v,f=g,q=D.clientX,T=D.clientY,n=_,NL=E,U.setPointerCapture(D.pointerId),mL()},Fj=(Z)=>{if(!U)return;if(B===Z.pointerId){Z.preventDefault();let D=Math.max(0,window.innerWidth-v),R=Math.max(0,window.innerHeight-g);_=w(Z.clientX-LL,0,D),E=w(Z.clientY-m,0,R),tL();return}if(b===Z.pointerId){Z.preventDefault();let D=J.mounted.entry.shell,R=D?.minWidth??320,O=D?.minHeight??240,G=Math.min(R,window.innerWidth),Q=Math.min(O,window.innerHeight),W=D?.maxWidth??window.innerWidth,M=D?.maxHeight??window.innerHeight,h=Z.clientX-q,e=Z.clientY-T;if(C==="se")v=w(I+h,G,Math.max(G,Math.min(W,window.innerWidth-_))),g=w(f+e,Q,Math.max(Q,Math.min(M,window.innerHeight-E)));else if(C==="sw"){let JL=n+I,OL=w(I-h,G,Math.min(W,JL));_=JL-OL,v=OL,g=w(f+e,Q,Math.max(Q,Math.min(M,window.innerHeight-E)))}else if(C==="ne"){let JL=NL+f;v=w(I+h,G,Math.max(G,Math.min(W,window.innerWidth-_)));let OL=w(f-e,Q,Math.min(M,JL));E=JL-OL,g=OL}else if(C==="nw"){let JL=n+I,OL=NL+f,eL=w(I-h,G,Math.min(W,JL));_=JL-eL,v=eL;let u=w(f-e,Q,Math.min(M,OL));E=OL-u,g=u}tL(),y0(),p0(),AL()}},kj=(Z)=>{if(!U)return;if(B===Z.pointerId)B=null,U.releasePointerCapture(Z.pointerId);if(b===Z.pointerId)b=null,U.releasePointerCapture(Z.pointerId)},Wj=()=>{O0()};if(A&&J.mounted.entry.shell){let Z=J.mounted.toolId==="calculator",D=Z&&L(sL);if(D)q0();if(U=document.createElement("div"),U.className="pie-tool-shell",U.setAttribute("data-pie-tool-shell",J.mounted.toolId),U.style.position="fixed",U.style.zIndex="2000",U.style.background="var(--pie-background, #fff)",U.style.border="1px solid var(--pie-border-light, #d1d5db)",U.style.borderRadius="12px",U.style.boxShadow="0 10px 40px color-mix(in srgb, var(--pie-black, #000) 25%, transparent)",U.style.overflow="visible",U.style.display=J.active?"flex":"none",U.style.flexDirection="column",U.style.userSelect="none",U.style.webkitUserSelect="none",U.style.touchAction="none",U.setAttribute("draggable","false"),U.addEventListener("dragstart",(Q)=>Q.preventDefault()),X=document.createElement("div"),X.className="pie-tool-shell__header",X.style.display="flex",X.style.alignItems="center",X.style.justifyContent="space-between",X.style.gap="6px",X.style.padding=Z?"12px 12px 12px 28px":"10px 12px",Z)X.style.minHeight="48px";if(Z)X.style.background="var(--pie-section-player-card-header-background, #f3f4f6)",X.style.color="var(--pie-text, #111827)",X.style.borderBottom="1px solid var(--pie-border-light, #e5e7eb)";else X.style.background="var(--pie-primary-dark, #2c3e50)",X.style.color="var(--pie-white, #fff)";X.style.cursor=J.mounted.entry.shell.draggable===!1?"default":"move",X.style.flex="0 0 auto",X.style.borderRadius="12px 12px 0 0",X.style.overflow="hidden",X.style.userSelect="none",X.style.webkitUserSelect="none",X.style.touchAction="none",X.setAttribute("draggable","false"),X.addEventListener("dragstart",(Q)=>Q.preventDefault()),H=document.createElement("span"),H.className="pie-tool-shell__title",H.textContent=J.mounted.entry.shell.title||J.mounted.toolId,X.appendChild(H),i=document.createElement("div"),i.className="pie-tool-shell__controls",i.style.display="inline-flex",i.style.alignItems="center",i.style.gap=Z?"6px":"4px";let R=J.mounted.entry.shell,O=(Q,W,M,h,e="fa-regular")=>{if(!i)return;i.appendChild(D?Yj(Q,M,h,e):Nj(Q,W,h))};if(R?.draggable!==!1)O("Move tool left","←","chevron-left",()=>IL(-24,0)),O("Move tool right","→","chevron-right",()=>IL(24,0)),O("Move tool up","↑","chevron-up",()=>IL(0,-24)),O("Move tool down","↓","chevron-down",()=>IL(0,24));if(R?.resizable!==!1)O("Shrink tool window","−","magnifying-glass-minus",()=>V0(-40,-40)),O("Grow tool window","+","magnifying-glass-plus",()=>V0(40,40));if(!Z)i.appendChild(Nj("Center tool window","◎",b0));let G=null;if(Z)G=document.createElement("div"),G.className="pie-tool-shell__header-right",G.style.display="inline-flex",G.style.alignItems="center",G.style.gap="6px",G.style.setProperty("zoom","var(--pie-tool-shell-zoom-comp, 1)"),G.appendChild(i),X.appendChild(G);else X.appendChild(i);if(D)FL=Yj("Close tool","xmark",v0,"fa-regular"),FL.style.display=J.mounted.entry.shell.closeable===!1?"none":"inline-block";else{let Q=document.createElement("button");Q.type="button",Q.className="pie-tool-shell__close",Q.setAttribute("aria-label","Close tool");let W="http://www.w3.org/2000/svg",M=document.createElementNS(W,"svg");M.setAttribute("xmlns",W),M.setAttribute("viewBox","0 0 16 16"),M.setAttribute("aria-hidden","true");let h=document.createElementNS(W,"path");h.setAttribute("d","M3.5 3.5L12.5 12.5M12.5 3.5L3.5 12.5"),h.setAttribute("stroke","currentColor"),h.setAttribute("stroke-width","1.8"),h.setAttribute("stroke-linecap","round"),M.appendChild(h),Q.appendChild(M);let e=M.style;e.width="16px",e.height="16px",e.display="block",e.flexShrink="0",e.pointerEvents="none";let JL="color-mix(in srgb, var(--pie-white, #fff) 8%, transparent)",OL="color-mix(in srgb, var(--pie-white, #fff) 18%, transparent)";Q.style.border="1px solid transparent",Q.style.background=JL,Q.style.color="inherit",Q.style.cursor="pointer",Q.style.display="inline-flex",Q.style.alignItems="center",Q.style.justifyItems="center",Q.style.width="28px",Q.style.height="28px",Q.style.padding="0",Q.style.borderRadius="8px",Q.style.lineHeight="0",Q.style.transition="background-color 0.15s ease, border-color 0.15s ease",Q.style.display=J.mounted.entry.shell.closeable===!1?"none":"inline-flex",Q.onmouseenter=()=>{Q.style.background=OL},Q.onmouseleave=()=>{Q.style.background=JL},Q.onfocus=()=>{Q.style.outline="2px solid var(--pie-button-focus-outline, var(--pie-primary, #4A90E2))",Q.style.outlineOffset="2px"},Q.onblur=()=>{Q.style.outline="none",Q.style.outlineOffset="0"},Q.onclick=v0,FL=Q}if(G)G.appendChild(FL);else X.appendChild(FL);if(X.tabIndex=0,X.onkeydown=(Q)=>{if(Q.key==="Home"){Q.preventDefault(),b0();return}let W=J.mounted.entry.shell;if(Q.shiftKey&&W?.resizable!==!1){if(Q.key==="ArrowRight"||Q.key==="ArrowDown"){Q.preventDefault(),V0(40,40);return}if(Q.key==="ArrowLeft"||Q.key==="ArrowUp"){Q.preventDefault(),V0(-40,-40);return}}if(W?.draggable!==!1){if(Q.key==="ArrowLeft")Q.preventDefault(),IL(-24,0);else if(Q.key==="ArrowRight")Q.preventDefault(),IL(24,0);else if(Q.key==="ArrowUp")Q.preventDefault(),IL(0,-24);else if(Q.key==="ArrowDown")Q.preventDefault(),IL(0,24)}},V=document.createElement("div"),V.className="pie-tool-shell__content",V.style.position="relative",V.style.width="100%",V.style.flex="1 1 auto",V.style.minHeight="0",V.style.overflowX="hidden",V.style.overflowY=Vj(),V.style.borderRadius="0 0 12px 12px",Z){let Q=(W)=>{let M=document.createElement("div");return M.tabIndex=0,M.setAttribute("aria-hidden","true"),M.setAttribute("data-pie-tool-shell-focus-guard",W),M.style.position="absolute",M.style.width="1px",M.style.height="1px",M.style.padding="0",M.style.margin="-1px",M.style.overflow="hidden",M.style.clipPath="inset(50%)",M.style.whiteSpace="nowrap",M.style.border="0",M};Y=Q("start"),l=Q("end"),Y.addEventListener("focus",(W)=>{if(o)return;o=!0;try{if(W.stopPropagation(),jL?.isConnected)try{jL.focus()}catch{}}finally{queueMicrotask(()=>{o=!1})}}),l.addEventListener("focus",(W)=>{if(o)return;o=!0;try{W.stopPropagation();let M=_0();if(M)try{M.focus()}catch{}}finally{queueMicrotask(()=>{o=!1})}}),U.appendChild(Y)}if(U.appendChild(X),U.appendChild(V),Z&&l)U.appendChild(l);if(J.mounted.entry.shell.resizable!==!1){let Q=(W,M,h,e,JL,OL,eL)=>{let u=document.createElement("div");if(u.className="pie-tool-shell__resize",u.style.position="absolute",u.style.width="24px",u.style.height="24px",u.style.cursor=OL,u.style.zIndex="10",u.style.touchAction="none",u.setAttribute("draggable","false"),M!==null)u.style.top=M;if(h!==null)u.style.right=h;if(e!==null)u.style.bottom=e;if(JL!==null)u.style.left=JL;if(eL!==null)u.style.background=`linear-gradient(${eL}, transparent 0%, transparent 40%, rgba(0,0,0,0.35) 40%, rgba(0,0,0,0.35) 60%, transparent 60%, transparent 100%)`;let wj=MJ(W);u.addEventListener("pointerdown",wj),U.appendChild(u),GL.push({el:u,handler:wj})};Q("se",null,"0","0",null,"nwse-resize",null),Q("nw","0",null,null,"0","nwse-resize","135deg"),Q("ne","0","0",null,null,"nesw-resize",null),Q("sw",null,null,"0","0","nesw-resize",null)}if(X.addEventListener("pointerdown",qj),U.addEventListener("pointermove",Fj),U.addEventListener("pointerup",kj),U.addEventListener("pointerdown",mL),window.addEventListener("resize",Wj),document.body.appendChild(U),b0(),tL(),Gj(),AL(),J.active)Rj();x=J.active}return{update(Z){if(J=Z,!U||!V||!H||!FL)return;H.textContent=J.mounted.entry.shell?.title||J.mounted.toolId;let D=J.mounted.toolId==="calculator"?"inline-block":"inline-flex";if(FL.style.display=J.mounted.entry.shell?.closeable===!1?"none":D,tL(),Gj(),AL(),!x&&J.active)Rj();else if(x&&!J.active)Mj(),jL=null;x=J.active},destroy(){if(nL(),kL)Mj();if(s)document.removeEventListener("keydown",E0,!0),s=!1;for(let{el:Z,handler:D}of GL)Z.removeEventListener("pointerdown",D);if(jL=null,GL.length=0,X)X.removeEventListener("pointerdown",qj),X.onkeydown=null;if(U)U.removeEventListener("pointermove",Fj),U.removeEventListener("pointerup",kj),U.removeEventListener("pointerdown",mL);if(window.removeEventListener("resize",Wj),k&&V&&k.parentNode===V)S(k),V.removeChild(k);if(k=null,U&&U.parentElement)U.remove()}}}var VJ={get level(){return EL()},set level(j){EL(j),a()},get scopeId(){return J0()},set scopeId(j){J0(j),a()},get itemId(){return F0()},set itemId(j){F0(j),a()},get sectionId(){return k0()},set sectionId(j){k0(j),a()},get catalogId(){return W0()},set catalogId(j){W0(j),a()},get tools(){return w0()},set tools(j){w0(j),a()},get contentKind(){return z0()},set contentKind(j){z0(j),a()},get position(){return TL()},set position(j){TL(j),a()},get scopeElement(){return uL()},set scopeElement(j){uL(j),a()},get toolRegistry(){return H0()},set toolRegistry(j){H0(j),a()},get item(){return f0()},set item(j){f0(j),a()},get hostButtons(){return Z0()},set hostButtons(j){Z0(j),a()},get class(){return x0()},set class(j){x0(j),a()},get size(){return cL()},set size(j){cL(j),a()},get language(){return K0()},set language(j){K0(j),a()}},Oj=QL(),YJ=KL(Oj);{var NJ=(j)=>{var K=BJ();let J;var U=hL(K),X=hL(U);L0(X,17,()=>L(UJ),(c)=>c.key,(c,Y)=>{var l=QL(),o=KL(l);{var s=(B)=>{var b=QL(),LL=KL(b);M0(LL,()=>L(sL),(m)=>{var I=N0();fL(I,(f,q)=>C0?.(f,q),()=>({mounted:L(Y),active:L(rL)[L(Y).toolId]??!1})),F(m,I)}),F(B,b)},k=(B)=>{var b=N0();fL(b,(LL,m)=>I0?.(LL,m),()=>L(Y).entry.element),F(B,b)};DL(o,(B)=>{if(L(Y).entry.shell)B(s);else B(k,-1)})}F(c,l)});var V=P0(X,2);L0(V,17,()=>L(jj),(c)=>c.id,(c,Y,l,o)=>{let s=N(()=>L(sL)&&!g0(L(Y))?rj(L(Y)):null);var k=QL(),B=KL(k);{var b=(f)=>{var q=HJ(),T=hL(q);CL(T,1,"item-toolbar__nds-button svelte-rnx3ie"),yL(T,"type","circle"),yL(T,"size","small"),yL(T,"variant","tertiary"),UL(()=>yL(T,"icon-name",L(s))),UL(()=>yL(T,"button-aria-label",L(Y).ariaLabel||L(Y).label)),UL(()=>yL(T,"title",L(Y).tooltip||L(Y).label)),UL(()=>yL(T,"disabled",L(Y).disabled)),fL(T,(n)=>ij?.(n)),fL(T,(n,NL)=>aj?.(n,NL),()=>X0(L(Y))),PL(q),R0("click",T,function(...n){L(Y).onClick?.apply(this,n)}),F(f,q)},LL=(f)=>{var q=fJ();let T;var n=hL(q);{var NL=(C)=>{var GL=QL(),_=KL(GL);{var E=(x)=>{var S=G0();j0(S,()=>Y0(L(Y).icon),!0),PL(S),F(x,S)},v=N(()=>$0(L(Y).icon)),g=(x)=>{var S=Bj();UL(()=>ZL(S,"src",L(Y).icon)),F(x,S)},kL=N(()=>m0(L(Y).icon)),jL=(x)=>{let S=N(()=>Xj(L(Y).icon));var zL=QL(),oL=KL(zL);{var AL=(w)=>{var t=G0();j0(t,()=>Y0(L(S)),!0),PL(t),F(w,t)},nL=(w)=>{var t=Sj();UL(()=>CL(t,1,`icon icon-${L(Y).icon}`,"svelte-rnx3ie")),F(w,t)};DL(oL,(w)=>{if(L(S))w(AL);else w(nL,-1)})}F(x,zL)};DL(_,(x)=>{if(L(v))x(E);else if(L(kL))x(g,1);else x(jL,-1)})}F(C,GL)};DL(n,(C)=>{if(L(Y).icon)C(NL)})}PL(q),UL((C)=>{T=CL(q,1,"item-toolbar__button svelte-rnx3ie",null,T,C),ZL(q,"href",L(Y).disabled?void 0:L(Y).href),ZL(q,"target",L(Y).target),ZL(q,"rel",L(Y).rel),ZL(q,"aria-label",L(Y).ariaLabel||L(Y).label),ZL(q,"title",L(Y).tooltip||L(Y).label),ZL(q,"aria-disabled",L(Y).disabled?"true":void 0)},[()=>({"item-toolbar__button--active":X0(L(Y))})]),R0("click",q,(C)=>{if(L(Y).disabled)C.preventDefault()}),F(f,q)},m=N(()=>g0(L(Y))),I=(f)=>{var q=xJ();let T;var n=hL(q);{var NL=(C)=>{var GL=QL(),_=KL(GL);{var E=(x)=>{var S=G0();j0(S,()=>Y0(L(Y).icon),!0),PL(S),F(x,S)},v=N(()=>$0(L(Y).icon)),g=(x)=>{var S=Bj();UL(()=>ZL(S,"src",L(Y).icon)),F(x,S)},kL=N(()=>m0(L(Y).icon)),jL=(x)=>{let S=N(()=>Xj(L(Y).icon));var zL=QL(),oL=KL(zL);{var AL=(w)=>{var t=G0();j0(t,()=>Y0(L(S)),!0),PL(t),F(w,t)},nL=(w)=>{var t=Sj();UL(()=>CL(t,1,`icon icon-${L(Y).icon}`,"svelte-rnx3ie")),F(w,t)};DL(oL,(w)=>{if(L(S))w(AL);else w(nL,-1)})}F(x,zL)};DL(_,(x)=>{if(L(v))x(E);else if(L(kL))x(g,1);else x(jL,-1)})}F(C,GL)};DL(n,(C)=>{if(L(Y).icon)C(NL)})}PL(q),UL((C,GL)=>{T=CL(q,1,"item-toolbar__button svelte-rnx3ie",null,T,C),ZL(q,"aria-label",L(Y).ariaLabel||L(Y).label),ZL(q,"aria-pressed",GL),ZL(q,"title",L(Y).tooltip||L(Y).label),q.disabled=L(Y).disabled},[()=>({"item-toolbar__button--active":X0(L(Y))}),()=>X0(L(Y))]),R0("click",q,function(...C){L(Y).onClick?.apply(this,C)}),F(f,q)};DL(B,(f)=>{if(L(s))f(b);else if(L(m))f(LL,1);else f(I,-1)})}F(c,k)});var H=P0(V,2);L0(H,17,()=>L(QJ),(c)=>c.key,(c,Y)=>{var l=QL(),o=KL(l);{var s=(B)=>{var b=QL(),LL=KL(b);M0(LL,()=>L(sL),(m)=>{var I=N0();fL(I,(f,q)=>C0?.(f,q),()=>({mounted:L(Y),active:L(rL)[L(Y).toolId]??!1})),F(m,I)}),F(B,b)},k=(B)=>{var b=N0();fL(b,(LL,m)=>I0?.(LL,m),()=>L(Y).entry.element),F(B,b)};DL(o,(B)=>{if(L(Y).entry.shell)B(s);else B(k,-1)})}F(c,l)}),PL(U);var i=P0(U,2);{var FL=(c)=>{var Y=TJ();let l;L0(Y,21,()=>L(Jj),(o)=>o.key,(o,s)=>{var k=QL(),B=KL(k);{var b=(m)=>{var I=QL(),f=KL(I);M0(f,()=>L(sL),(q)=>{var T=Aj();fL(T,(n,NL)=>C0?.(n,NL),()=>({mounted:L(s),active:L(rL)[L(s).toolId]??!1})),F(q,T)}),F(m,I)},LL=(m)=>{var I=Aj();fL(I,(f,q)=>I0?.(f,q),()=>L(s).entry.element),F(m,I)};DL(B,(m)=>{if(L(s).entry.shell)m(b);else m(LL,-1)})}F(o,k)}),PL(Y),UL(()=>l=CL(Y,1,"item-toolbar__controls-row svelte-rnx3ie",null,l,{"item-toolbar__controls-row--reserve":L(Uj),"item-toolbar__controls-row--active":L(Qj),"item-toolbar__controls-row--align-start":L(DJ)})),F(c,Y)};DL(i,(c)=>{if(L(XJ))c(FL)})}PL(K),Ej(K,(c)=>RL(qL,c),()=>L(qL)),UL(()=>{J=CL(K,1,`item-toolbar ${x0()??""} item-toolbar--${cL()??""}`,"svelte-rnx3ie",J,{"item-toolbar--top":TL()==="top","item-toolbar--right":TL()==="right","item-toolbar--bottom":TL()==="bottom","item-toolbar--left":TL()==="left","item-toolbar--header-overlay-active":L(Dj)}),ZL(K,"data-content-kind",L(gL)),ZL(K,"data-level",L(p)),_j(K,`--pie-toolbar-zoom-comp: ${L(d0)};`)}),F(j,K)};DL(YJ,(j)=>{if(A)j(NJ)})}return F(z,Oj),Cj(VJ)}pj(["click"]);kJ("pie-item-toolbar",vj(uj,{level:{attribute:"level",type:"String"},scopeId:{attribute:"scope-id",type:"String"},itemId:{attribute:"item-id",type:"String"},sectionId:{attribute:"section-id",type:"String"},catalogId:{attribute:"catalog-id",type:"String"},tools:{attribute:"tools",type:"String"},contentKind:{attribute:"content-kind",type:"String"},position:{attribute:"position",type:"String"},size:{attribute:"size",type:"String"},language:{attribute:"language",type:"String"},scopeElement:{type:"Object"},toolRegistry:{type:"Object"},item:{type:"Object"},hostButtons:{type:"Object"},class:{}},[],[],{mode:"open"}));
22
- export{uj as a};
@@ -1,67 +0,0 @@
1
- /**
2
- * Where accessibility catalogs live on a rendered entity, and which owner scope
3
- * each one belongs to.
4
- *
5
- * Catalogs are placed dynamically: a shell registers what its entity carries
6
- * when it mounts, and readers (TTS, the item card's media region) resolve by
7
- * identifier within an owner scope. Both sides therefore have to agree on two
8
- * facts — the three places catalogs can hang off an entity, and the owner
9
- * context each one is filed under. This module is the only place either is
10
- * decided, so a reader cannot look up a scope registration never wrote.
11
- *
12
- * Part of PIE Assessment Toolkit.
13
- */
14
- import type { AccessibilityCatalog } from "@pie-players/pie-players-shared/types";
15
- import type { CatalogOwnerContext } from "../services/AccessibilityCatalogResolver.js";
16
- import type { RuntimeRegistrationDetail, RuntimeRegistrationKind } from "./registration-events.js";
17
- export interface CatalogRegistrationRuntimeContext {
18
- assessmentId?: string;
19
- sectionId?: string;
20
- }
21
- export interface CatalogRegistration {
22
- context: CatalogOwnerContext;
23
- catalogs: AccessibilityCatalog[];
24
- }
25
- /** The entity shape catalogs hang off: an item, or a passage. */
26
- export interface CatalogSourceEntity {
27
- accessibilityCatalogs?: AccessibilityCatalog[];
28
- config?: {
29
- extractedCatalogs?: AccessibilityCatalog[];
30
- models?: Array<{
31
- id?: string;
32
- accessibilityCatalogs?: AccessibilityCatalog[];
33
- }>;
34
- };
35
- }
36
- /** Who is rendering the entity — everything owner scoping is derived from. */
37
- export interface CatalogOwnerIdentity {
38
- kind: RuntimeRegistrationKind;
39
- /** The rendered instance id. */
40
- itemId: string;
41
- canonicalItemId?: string;
42
- assessmentId?: string;
43
- sectionId?: string;
44
- }
45
- /**
46
- * The owner context an entity's catalogs are registered under, and therefore the
47
- * one a reader must look them up with.
48
- *
49
- * Exported because readers construct the lookup context themselves: the
50
- * resolver matches contexts field by field, so a reader that hand-assembled its
51
- * own would silently resolve nothing the day either side gained a field.
52
- */
53
- export declare function catalogOwnerContextFor(owner: CatalogOwnerIdentity): CatalogOwnerContext;
54
- /**
55
- * Every catalog an entity carries, paired with the owner scope it belongs in.
56
- *
57
- * Three places carry catalogs, and the distinction matters to resolution rather
58
- * than only to bookkeeping: entity-level `accessibilityCatalogs` and
59
- * extractor-generated `config.extractedCatalogs` are filed against the entity,
60
- * while a model's own catalogs are filed against that model, so two models on
61
- * one item can use the same catalog identifier without colliding.
62
- *
63
- * Passages have no models, so the walk stops after the entity-level pair.
64
- */
65
- export declare function collectEntityCatalogRegistrations(entity: CatalogSourceEntity | null | undefined, owner: CatalogOwnerIdentity): CatalogRegistration[];
66
- /** Adapter for the runtime registration event a shell dispatches on mount. */
67
- export declare function collectCatalogRegistrations(detail: RuntimeRegistrationDetail, runtime?: CatalogRegistrationRuntimeContext): CatalogRegistration[];
@@ -1,86 +0,0 @@
1
- /**
2
- * Where accessibility catalogs live on a rendered entity, and which owner scope
3
- * each one belongs to.
4
- *
5
- * Catalogs are placed dynamically: a shell registers what its entity carries
6
- * when it mounts, and readers (TTS, the item card's media region) resolve by
7
- * identifier within an owner scope. Both sides therefore have to agree on two
8
- * facts — the three places catalogs can hang off an entity, and the owner
9
- * context each one is filed under. This module is the only place either is
10
- * decided, so a reader cannot look up a scope registration never wrote.
11
- *
12
- * Part of PIE Assessment Toolkit.
13
- */
14
- const hasCatalogs = (catalogs) => Array.isArray(catalogs) && catalogs.length > 0;
15
- /**
16
- * The owner context an entity's catalogs are registered under, and therefore the
17
- * one a reader must look them up with.
18
- *
19
- * Exported because readers construct the lookup context themselves: the
20
- * resolver matches contexts field by field, so a reader that hand-assembled its
21
- * own would silently resolve nothing the day either side gained a field.
22
- */
23
- export function catalogOwnerContextFor(owner) {
24
- if (owner.kind === "passage") {
25
- return {
26
- ownerKind: "passage",
27
- assessmentId: owner.assessmentId,
28
- sectionId: owner.sectionId,
29
- passageId: owner.canonicalItemId || owner.itemId,
30
- };
31
- }
32
- return {
33
- ownerKind: "itemModel",
34
- assessmentId: owner.assessmentId,
35
- sectionId: owner.sectionId,
36
- itemId: owner.itemId,
37
- canonicalItemId: owner.canonicalItemId || owner.itemId,
38
- };
39
- }
40
- /**
41
- * Every catalog an entity carries, paired with the owner scope it belongs in.
42
- *
43
- * Three places carry catalogs, and the distinction matters to resolution rather
44
- * than only to bookkeeping: entity-level `accessibilityCatalogs` and
45
- * extractor-generated `config.extractedCatalogs` are filed against the entity,
46
- * while a model's own catalogs are filed against that model, so two models on
47
- * one item can use the same catalog identifier without colliding.
48
- *
49
- * Passages have no models, so the walk stops after the entity-level pair.
50
- */
51
- export function collectEntityCatalogRegistrations(entity, owner) {
52
- if (!entity)
53
- return [];
54
- const context = catalogOwnerContextFor(owner);
55
- const registrations = [];
56
- if (hasCatalogs(entity.accessibilityCatalogs)) {
57
- registrations.push({ context, catalogs: entity.accessibilityCatalogs });
58
- }
59
- if (hasCatalogs(entity.config?.extractedCatalogs)) {
60
- registrations.push({
61
- context,
62
- catalogs: entity.config.extractedCatalogs,
63
- });
64
- }
65
- if (owner.kind === "passage")
66
- return registrations;
67
- for (const model of entity.config?.models ?? []) {
68
- if (!hasCatalogs(model.accessibilityCatalogs))
69
- continue;
70
- registrations.push({
71
- context: { ...context, modelId: model.id },
72
- catalogs: model.accessibilityCatalogs,
73
- });
74
- }
75
- return registrations;
76
- }
77
- /** Adapter for the runtime registration event a shell dispatches on mount. */
78
- export function collectCatalogRegistrations(detail, runtime = {}) {
79
- return collectEntityCatalogRegistrations(detail.item, {
80
- kind: detail.kind,
81
- itemId: detail.itemId,
82
- canonicalItemId: detail.canonicalItemId,
83
- assessmentId: runtime.assessmentId,
84
- sectionId: runtime.sectionId,
85
- });
86
- }