@pie-players/pie-section-player 0.3.29 → 0.3.31

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 (50) hide show
  1. package/README.md +261 -21
  2. package/dist/chunks/dist-24a90544.js +193 -138
  3. package/dist/chunks/{dist-Bud4G4lv-b2620662.js → dist-DIBQdekL-ec6db34a.js} +120 -66
  4. package/dist/chunks/dist-c4148994.js +14 -2
  5. package/dist/chunks/{dist-DwP27yIs-cfd207a3.js → dist-rF11IR1B-adc4857f.js} +13 -1
  6. package/dist/chunks/module-c1d68911.js +1819 -1835
  7. package/dist/chunks/tool-annotation-toolbar-db5bfbec.js +1642 -1473
  8. package/dist/components/section-player-tabbed-element.d.ts +2 -0
  9. package/dist/components/section-player-tabbed-element.d.ts.map +1 -0
  10. package/dist/components/shared/player-preload.d.ts +88 -71
  11. package/dist/components/shared/player-preload.d.ts.map +1 -1
  12. package/dist/components/shared/section-player-host-runtime.d.ts +72 -0
  13. package/dist/components/shared/section-player-host-runtime.d.ts.map +1 -0
  14. package/dist/components/shared/section-player-runtime-callbacks.d.ts +33 -0
  15. package/dist/components/shared/section-player-runtime-callbacks.d.ts.map +1 -0
  16. package/dist/components/shared/section-player-view-state.d.ts.map +1 -1
  17. package/dist/contracts/host-hooks.d.ts +20 -0
  18. package/dist/contracts/host-hooks.d.ts.map +1 -1
  19. package/dist/contracts/layout-contract.d.ts +3 -3
  20. package/dist/contracts/layout-contract.d.ts.map +1 -1
  21. package/dist/contracts/layout-parity-metadata.d.ts +1 -0
  22. package/dist/contracts/layout-parity-metadata.d.ts.map +1 -1
  23. package/dist/contracts/public-events.d.ts +86 -10
  24. package/dist/contracts/public-events.d.ts.map +1 -1
  25. package/dist/contracts/runtime-host-contract.d.ts +13 -0
  26. package/dist/contracts/runtime-host-contract.d.ts.map +1 -1
  27. package/dist/contracts/stages.d.ts +11 -0
  28. package/dist/contracts/stages.d.ts.map +1 -0
  29. package/dist/controllers/SectionController.d.ts.map +1 -1
  30. package/dist/controllers/SectionItemNavigationService.d.ts +0 -1
  31. package/dist/controllers/SectionItemNavigationService.d.ts.map +1 -1
  32. package/dist/controllers/types.d.ts +16 -0
  33. package/dist/controllers/types.d.ts.map +1 -1
  34. package/dist/pie-section-player.d.ts +4 -4
  35. package/dist/pie-section-player.d.ts.map +1 -1
  36. package/dist/pie-section-player.js +19513 -6465
  37. package/dist/policies/index.d.ts +26 -1
  38. package/dist/policies/index.d.ts.map +1 -1
  39. package/dist/policies/types.d.ts +18 -1
  40. package/dist/policies/types.d.ts.map +1 -1
  41. package/package.json +21 -19
  42. package/dist/chunks/player-preload-79b07366.js +0 -7066
  43. package/dist/components/shared/section-player-readiness.d.ts +0 -14
  44. package/dist/components/shared/section-player-readiness.d.ts.map +0 -1
  45. package/dist/components/shared/section-player-runtime.d.ts +0 -154
  46. package/dist/components/shared/section-player-runtime.d.ts.map +0 -1
  47. package/dist/utils/player-preload.d.ts +0 -2
  48. package/dist/utils/player-preload.d.ts.map +0 -1
  49. package/dist/utils/player-preload.js +0 -8
  50. /package/dist/chunks/{defineProperty-318b8855.js → defineProperty-aab5a8e0.js} +0 -0
@@ -1,56 +1,91 @@
1
1
  import { t as d } from "./defineProperty-CyepwRr5-3800a70a.js";
2
- var b = (e) => {
2
+ function w(e, t) {
3
+ if (typeof e != "string" || e.length === 0) return null;
4
+ try {
5
+ const i = typeof t.apiEndpoint == "string" && /^https?:\/\//i.test(t.apiEndpoint) ? t.apiEndpoint : void 0, r = i ? new URL(e, i) : new URL(e);
6
+ return r.protocol !== "http:" && r.protocol !== "https:" ? null : r;
7
+ } catch {
8
+ return null;
9
+ }
10
+ }
11
+ function k(e, t) {
12
+ const i = Array.isArray(t.assetOrigins) ? t.assetOrigins.filter((r) => typeof r == "string" && r.length > 0).map((r) => {
13
+ try {
14
+ return new URL(r).origin;
15
+ } catch {
16
+ return r;
17
+ }
18
+ }) : [];
19
+ if (i.length === 0) {
20
+ if (typeof t.apiEndpoint == "string" && /^https?:\/\//i.test(t.apiEndpoint)) try {
21
+ return new URL(t.apiEndpoint).origin === e.origin;
22
+ } catch {
23
+ return !1;
24
+ }
25
+ return typeof window < "u" && typeof window.location?.origin == "string" && window.location.origin === e.origin;
26
+ }
27
+ return i.includes(e.origin);
28
+ }
29
+ function A(e) {
30
+ const t = {};
31
+ for (const [i, r] of Object.entries(e)) {
32
+ const o = i.toLowerCase();
33
+ o === "authorization" || o === "proxy-authorization" || o === "cookie" || o.startsWith("x-auth-") || (t[i] = r);
34
+ }
35
+ return t;
36
+ }
37
+ var R = (e) => {
3
38
  const t = (e.providerOptions && typeof e.providerOptions == "object" ? e.providerOptions : {}).__pieTelemetry;
4
39
  return typeof t == "function" ? t : void 0;
5
- }, S = {
40
+ }, E = {
6
41
  pie: 3e3,
7
42
  custom: 3e3
8
- }, v = (e) => e.replace(/\/+$/, ""), k = (e) => {
9
- const t = v(e.apiEndpoint), i = (e.provider || "").toLowerCase();
43
+ }, T = (e) => e.replace(/\/+$/, ""), M = (e) => {
44
+ const t = T(e.apiEndpoint), i = (e.provider || "").toLowerCase();
10
45
  return i === "polly" || i === "google" ? `${t}/${i}/voices` : `${t}/voices`;
11
- }, w = (e) => e.transportMode === "custom" ? "custom" : e.transportMode === "pie" ? "pie" : e.provider === "custom" ? "custom" : "pie", T = (e, t) => e.endpointMode ? e.endpointMode : t === "custom" ? "rootPost" : "synthesizePath", A = (e, t) => e.endpointValidationMode ? e.endpointValidationMode : t === "custom" ? "none" : "voices", R = (e) => {
46
+ }, b = (e) => e.transportMode === "custom" ? "custom" : e.transportMode === "pie" ? "pie" : e.provider === "custom" ? "custom" : "pie", S = (e, t) => e.endpointMode ? e.endpointMode : t === "custom" ? "rootPost" : "synthesizePath", U = (e, t) => e.endpointValidationMode ? e.endpointValidationMode : t === "custom" ? "none" : "voices", P = (e) => {
12
47
  const t = e.providerOptions || {};
13
48
  if (typeof t.speedRate == "string") return t.speedRate;
14
49
  const i = Number(e.rate ?? 1);
15
50
  return !Number.isFinite(i) || i <= 0.95 ? "slow" : i >= 1.5 ? "fast" : "medium";
16
- }, I = (e) => {
51
+ }, z = (e) => {
17
52
  const t = [];
18
53
  let i = 0;
19
54
  const r = e.split(`
20
55
  `).map((o) => o.trim()).filter(Boolean);
21
56
  for (const o of r) try {
22
- const s = JSON.parse(o), a = typeof s.type == "string" ? s.type : "word", h = typeof s.time == "number" && Number.isFinite(s.time) ? s.time : 0, n = typeof s.value == "string" ? s.value : "", l = typeof s.start == "number" && Number.isFinite(s.start) ? s.start : null, u = typeof s.end == "number" && Number.isFinite(s.end) ? s.end : null, m = l ?? i, c = u ?? m + Math.max(1, n.length || String(s.value || "").length);
23
- i = Math.max(c + 1, i), t.push({
57
+ const s = JSON.parse(o), a = typeof s.type == "string" ? s.type : "word", h = typeof s.time == "number" && Number.isFinite(s.time) ? s.time : 0, n = typeof s.value == "string" ? s.value : "", c = typeof s.start == "number" && Number.isFinite(s.start) ? s.start : null, u = typeof s.end == "number" && Number.isFinite(s.end) ? s.end : null, p = c ?? i, l = u ?? p + Math.max(1, n.length || String(s.value || "").length);
58
+ i = Math.max(l + 1, i), t.push({
24
59
  time: h,
25
60
  type: a,
26
- start: m,
27
- end: c,
61
+ start: p,
62
+ end: l,
28
63
  value: n
29
64
  });
30
65
  } catch {
31
66
  }
32
67
  return t;
33
- }, M = (e) => {
68
+ }, C = (e) => {
34
69
  if (!Array.isArray(e)) return [];
35
70
  const t = [];
36
71
  let i = 0;
37
72
  for (const r of e) {
38
73
  if (!r || typeof r != "object") continue;
39
- const o = typeof r.type == "string" ? r.type : "word", s = typeof r.time == "number" && Number.isFinite(r.time) ? r.time : 0, a = typeof r.value == "string" ? r.value : "", h = typeof r.start == "number" && Number.isFinite(r.start) ? r.start : null, n = typeof r.end == "number" && Number.isFinite(r.end) ? r.end : null, l = h ?? i, u = n ?? l + Math.max(1, a.length || 1);
74
+ const o = typeof r.type == "string" ? r.type : "word", s = typeof r.time == "number" && Number.isFinite(r.time) ? r.time : 0, a = typeof r.value == "string" ? r.value : "", h = typeof r.start == "number" && Number.isFinite(r.start) ? r.start : null, n = typeof r.end == "number" && Number.isFinite(r.end) ? r.end : null, c = h ?? i, u = n ?? c + Math.max(1, a.length || 1);
40
75
  i = Math.max(i, u + 1), t.push({
41
76
  time: s,
42
77
  type: o,
43
- start: l,
78
+ start: c,
44
79
  end: u,
45
80
  value: a
46
81
  });
47
82
  }
48
83
  return t.sort((r, o) => r.time !== o.time ? r.time - o.time : r.start !== o.start ? r.start - o.start : r.end - o.end);
49
- }, P = {
84
+ }, O = {
50
85
  pie: {
51
86
  id: "pie",
52
87
  resolveSynthesisUrl: (e) => {
53
- const t = T(e, "pie"), i = v(e.apiEndpoint);
88
+ const t = S(e, "pie"), i = T(e.apiEndpoint);
54
89
  return t === "rootPost" ? i : `${i}/synthesize`;
55
90
  },
56
91
  buildRequestBody: (e, t) => {
@@ -83,43 +118,49 @@ var b = (e) => {
83
118
  custom: {
84
119
  id: "custom",
85
120
  resolveSynthesisUrl: (e) => {
86
- const t = T(e, "custom"), i = v(e.apiEndpoint);
121
+ const t = S(e, "custom"), i = T(e.apiEndpoint);
87
122
  return t === "synthesizePath" ? `${i}/synthesize` : i;
88
123
  },
89
124
  buildRequestBody: (e, t) => {
90
125
  const i = t.providerOptions || {}, r = typeof i.lang_id == "string" ? i.lang_id : t.language || "en-US", o = typeof i.cache == "boolean" ? i.cache : !0;
91
126
  return {
92
127
  text: e,
93
- speedRate: R(t),
128
+ speedRate: P(t),
94
129
  lang_id: r,
95
130
  cache: o
96
131
  };
97
132
  },
98
133
  parseResponse: async (e, t, i, r) => {
99
134
  const o = await e.json(), s = {};
100
- if (t.includeAuthOnAssetFetch) for (const [n, l] of Object.entries(i)) n.toLowerCase() === "authorization" && (s[n] = l);
135
+ if (t.includeAuthOnAssetFetch) for (const [c, u] of Object.entries(i)) c.toLowerCase() === "authorization" && (s[c] = u);
101
136
  let a = [];
102
- const h = M(o.speechMarks);
137
+ const h = C(o.speechMarks);
103
138
  if (h.length > 0) a = h;
104
139
  else if (typeof o.word == "string" && o.word.length > 0) {
105
- const n = await fetch(o.word, {
106
- headers: s,
107
- signal: r
108
- });
109
- n.ok && (a = I(await n.text()));
140
+ const c = w(o.word, t);
141
+ if (c !== null) {
142
+ const u = k(c, t) ? s : A(s), p = await fetch(c.toString(), {
143
+ headers: u,
144
+ signal: r,
145
+ redirect: "error"
146
+ });
147
+ p.ok && (a = z(await p.text()));
148
+ }
110
149
  }
150
+ const n = w(o.audioContent, t);
151
+ if (n === null) throw new Error("TTS server returned an invalid audio URL");
111
152
  return {
112
153
  audio: {
113
154
  kind: "url",
114
- url: o.audioContent
155
+ url: n.toString()
115
156
  },
116
157
  speechMarks: a
117
158
  };
118
159
  }
119
160
  }
120
- }, E = class {
161
+ }, L = class {
121
162
  constructor(e, t) {
122
- d(this, "config", void 0), d(this, "adapter", void 0), d(this, "currentAudio", null), d(this, "pausedState", !1), d(this, "wordTimings", []), d(this, "highlightInterval", null), d(this, "intentionallyStopped", !1), d(this, "activeSynthesisController", null), d(this, "synthesisRunId", 0), d(this, "telemetryReporter", void 0), d(this, "onWordBoundary", void 0), this.config = e, this.adapter = t, this.telemetryReporter = b(e);
163
+ d(this, "config", void 0), d(this, "adapter", void 0), d(this, "currentAudio", null), d(this, "pausedState", !1), d(this, "wordTimings", []), d(this, "highlightInterval", null), d(this, "intentionallyStopped", !1), d(this, "activeSynthesisController", null), d(this, "synthesisRunId", 0), d(this, "telemetryReporter", void 0), d(this, "onWordBoundary", void 0), this.config = e, this.adapter = t, this.telemetryReporter = R(e);
123
164
  }
124
165
  async emitTelemetry(e, t) {
125
166
  try {
@@ -147,7 +188,7 @@ var b = (e) => {
147
188
  this.pausedState = !1, this.onWordBoundary && this.wordTimings.length > 0 && this.startWordHighlighting();
148
189
  }, n.onended = () => {
149
190
  this.stopWordHighlighting(), URL.revokeObjectURL(r), this.currentAudio = null, this.wordTimings = [], a();
150
- }, n.onerror = (l) => {
191
+ }, n.onerror = (c) => {
151
192
  this.stopWordHighlighting(), URL.revokeObjectURL(r), this.currentAudio = null, this.wordTimings = [], this.intentionallyStopped ? a() : h(/* @__PURE__ */ new Error("Failed to play audio from server"));
152
193
  }, n.onpause = () => {
153
194
  this.stopWordHighlighting(), this.pausedState = !0;
@@ -174,19 +215,19 @@ var b = (e) => {
174
215
  body: JSON.stringify(a),
175
216
  signal: t
176
217
  });
177
- } catch (c) {
218
+ } catch (l) {
178
219
  throw await this.emitTelemetry("pie-tool-backend-call-error", {
179
220
  toolId: "tts",
180
221
  backend: this.config.provider || "server",
181
222
  operation: "synthesize-speech",
182
223
  duration: Date.now() - r,
183
224
  errorType: "TTSBackendNetworkError",
184
- message: c instanceof Error ? c.message : String(c)
185
- }), c;
225
+ message: l instanceof Error ? l.message : String(l)
226
+ }), l;
186
227
  }
187
228
  })();
188
229
  if (!h.ok) {
189
- const c = await h.json().catch(() => ({})), p = c.message || c.error?.message || `Server returned ${h.status}`;
230
+ const l = await h.json().catch(() => ({})), g = l.message || l.error?.message || `Server returned ${h.status}`;
190
231
  throw await this.emitTelemetry("pie-tool-backend-call-error", {
191
232
  toolId: "tts",
192
233
  backend: this.config.provider || "server",
@@ -194,15 +235,15 @@ var b = (e) => {
194
235
  duration: Date.now() - r,
195
236
  statusCode: h.status,
196
237
  errorType: "TTSBackendRequestError",
197
- message: p
198
- }), new Error(p);
238
+ message: g
239
+ }), new Error(g);
199
240
  }
200
241
  const n = await this.adapter.parseResponse(h, this.config, o, t);
201
242
  if (i !== this.synthesisRunId || t.aborted) throw new Error("Synthesis superseded by a newer request");
202
- let l;
203
- if (n.audio.kind === "base64") l = this.base64ToBlob(n.audio.data, n.audio.contentType);
243
+ let c;
244
+ if (n.audio.kind === "base64") c = this.base64ToBlob(n.audio.data, n.audio.contentType);
204
245
  else {
205
- const c = n.audio.url, p = Date.now();
246
+ const l = n.audio.url, g = Date.now();
206
247
  await this.emitTelemetry("pie-tool-backend-call-start", {
207
248
  toolId: "tts",
208
249
  backend: this.config.provider || "server",
@@ -210,40 +251,50 @@ var b = (e) => {
210
251
  });
211
252
  const f = {};
212
253
  this.config.includeAuthOnAssetFetch && this.config.authToken && (f.Authorization = `Bearer ${this.config.authToken}`);
213
- const g = await (async () => {
254
+ const v = w(l, this.config);
255
+ if (v === null) throw await this.emitTelemetry("pie-tool-backend-call-error", {
256
+ toolId: "tts",
257
+ backend: this.config.provider || "server",
258
+ operation: "fetch-synthesized-audio-asset",
259
+ duration: Date.now() - g,
260
+ errorType: "TTSAssetInvalidUrl",
261
+ message: "TTS asset URL rejected (non-http(s) or malformed)"
262
+ }), /* @__PURE__ */ new Error("TTS asset URL rejected (non-http(s) or malformed)");
263
+ const I = k(v, this.config) ? f : A(f), y = await (async () => {
214
264
  try {
215
- return await fetch(c, {
216
- headers: f,
217
- signal: t
265
+ return await fetch(v.toString(), {
266
+ headers: I,
267
+ signal: t,
268
+ redirect: "error"
218
269
  });
219
- } catch (y) {
270
+ } catch (m) {
220
271
  throw await this.emitTelemetry("pie-tool-backend-call-error", {
221
272
  toolId: "tts",
222
273
  backend: this.config.provider || "server",
223
274
  operation: "fetch-synthesized-audio-asset",
224
- duration: Date.now() - p,
275
+ duration: Date.now() - g,
225
276
  errorType: "TTSAssetNetworkError",
226
- message: y instanceof Error ? y.message : String(y)
227
- }), y;
277
+ message: m instanceof Error ? m.message : String(m)
278
+ }), m;
228
279
  }
229
280
  })();
230
- if (!g.ok) throw await this.emitTelemetry("pie-tool-backend-call-error", {
281
+ if (!y.ok) throw await this.emitTelemetry("pie-tool-backend-call-error", {
231
282
  toolId: "tts",
232
283
  backend: this.config.provider || "server",
233
284
  operation: "fetch-synthesized-audio-asset",
234
- duration: Date.now() - p,
235
- statusCode: g.status,
285
+ duration: Date.now() - g,
286
+ statusCode: y.status,
236
287
  errorType: "TTSAssetFetchError",
237
- message: `Failed to download synthesized audio (${g.status})`
238
- }), /* @__PURE__ */ new Error(`Failed to download synthesized audio (${g.status})`);
239
- l = await g.blob(), await this.emitTelemetry("pie-tool-backend-call-success", {
288
+ message: `Failed to download synthesized audio (${y.status})`
289
+ }), /* @__PURE__ */ new Error(`Failed to download synthesized audio (${y.status})`);
290
+ c = await y.blob(), await this.emitTelemetry("pie-tool-backend-call-success", {
240
291
  toolId: "tts",
241
292
  backend: this.config.provider || "server",
242
293
  operation: "fetch-synthesized-audio-asset",
243
- duration: Date.now() - p
294
+ duration: Date.now() - g
244
295
  });
245
296
  }
246
- const u = URL.createObjectURL(l), m = this.parseSpeechMarks(n.speechMarks);
297
+ const u = URL.createObjectURL(c), p = this.parseSpeechMarks(n.speechMarks);
247
298
  return await this.emitTelemetry("pie-tool-backend-call-success", {
248
299
  toolId: "tts",
249
300
  backend: this.config.provider || "server",
@@ -251,13 +302,14 @@ var b = (e) => {
251
302
  duration: Date.now() - r
252
303
  }), {
253
304
  audioUrl: u,
254
- wordTimings: m
305
+ wordTimings: p
255
306
  };
256
307
  }
257
308
  base64ToBlob(e, t) {
258
309
  const i = atob(e), r = new Array(i.length);
259
- for (let o = 0; o < i.length; o++) r[o] = i.charCodeAt(o);
260
- return new Blob([new Uint8Array(r)], { type: t });
310
+ for (let s = 0; s < i.length; s++) r[s] = i.charCodeAt(s);
311
+ const o = new Uint8Array(r);
312
+ return new Blob([o], { type: t });
261
313
  }
262
314
  parseSpeechMarks(e) {
263
315
  return e.filter((t) => t.type === "word").map((t, i) => ({
@@ -314,7 +366,7 @@ var b = (e) => {
314
366
  updateSettings(e) {
315
367
  e.rate !== void 0 && (this.config.rate = e.rate, this.currentAudio && (this.currentAudio.playbackRate = Math.max(0.25, Math.min(4, e.rate)))), e.pitch !== void 0 && (this.config.pitch = e.pitch), e.voice !== void 0 && (this.config.voice = e.voice);
316
368
  }
317
- }, C = class {
369
+ }, B = class {
318
370
  constructor() {
319
371
  d(this, "providerId", "server-tts"), d(this, "providerName", "Server TTS"), d(this, "version", "1.0.0"), d(this, "config", null), d(this, "adapter", null), d(this, "telemetryReporter", void 0);
320
372
  }
@@ -328,8 +380,10 @@ var b = (e) => {
328
380
  async initialize(e) {
329
381
  const t = e;
330
382
  if (!t.apiEndpoint) throw new Error("apiEndpoint is required for ServerTTSProvider");
331
- if (this.config = t, this.telemetryReporter = b(t), this.adapter = P[w(t)], t.validateEndpoint) {
332
- const i = Date.now();
383
+ this.config = t, this.telemetryReporter = R(t);
384
+ const i = b(t);
385
+ if (this.adapter = O[i], t.validateEndpoint) {
386
+ const r = Date.now();
333
387
  if (await this.emitTelemetry("pie-tool-backend-call-start", {
334
388
  toolId: "tts",
335
389
  backend: t.provider || "server",
@@ -338,7 +392,7 @@ var b = (e) => {
338
392
  toolId: "tts",
339
393
  backend: t.provider || "server",
340
394
  operation: "validate-endpoint",
341
- duration: Date.now() - i,
395
+ duration: Date.now() - r,
342
396
  errorType: "TTSEndpointValidationError",
343
397
  message: `Server TTS API not available at ${t.apiEndpoint}`
344
398
  }), /* @__PURE__ */ new Error(`Server TTS API not available at ${t.apiEndpoint}`);
@@ -346,19 +400,19 @@ var b = (e) => {
346
400
  toolId: "tts",
347
401
  backend: t.provider || "server",
348
402
  operation: "validate-endpoint",
349
- duration: Date.now() - i
403
+ duration: Date.now() - r
350
404
  });
351
405
  }
352
- return new E(t, this.adapter);
406
+ return new L(t, this.adapter);
353
407
  }
354
408
  async testAPIAvailability() {
355
409
  if (!this.config || !this.adapter) return !1;
356
410
  try {
357
411
  const e = { ...this.config.headers };
358
412
  this.config.authToken && (e.Authorization = `Bearer ${this.config.authToken}`);
359
- const t = new AbortController(), i = setTimeout(() => t.abort(), 5e3), r = A(this.config, this.adapter.id);
413
+ const t = new AbortController(), i = setTimeout(() => t.abort(), 5e3), r = U(this.config, this.adapter.id);
360
414
  if (r === "none") return clearTimeout(i), !0;
361
- const o = r === "voices" ? k(this.config) : this.adapter.resolveSynthesisUrl(this.config), s = r === "voices" ? "GET" : "OPTIONS";
415
+ const o = r === "voices" ? M(this.config) : this.adapter.resolveSynthesisUrl(this.config), s = r === "voices" ? "GET" : "OPTIONS";
362
416
  try {
363
417
  const a = await fetch(o, {
364
418
  method: s,
@@ -395,7 +449,7 @@ var b = (e) => {
395
449
  supportsVoiceSelection: !0,
396
450
  supportsRateControl: !0,
397
451
  supportsPitchControl: !1,
398
- maxTextLength: S[this.config ? w(this.config) : "pie"]
452
+ maxTextLength: E[this.config ? b(this.config) : "pie"]
399
453
  };
400
454
  }
401
455
  destroy() {
@@ -403,5 +457,5 @@ var b = (e) => {
403
457
  }
404
458
  };
405
459
  export {
406
- C as ServerTTSProvider
460
+ B as ServerTTSProvider
407
461
  };
@@ -1,4 +1,4 @@
1
- import { t as s } from "./defineProperty-318b8855.js";
1
+ import { t as s } from "./defineProperty-aab5a8e0.js";
2
2
  var n = class {
3
3
  constructor() {
4
4
  s(this, "providerId", "desmos"), s(this, "providerName", "Desmos"), s(this, "supportedTypes", [
@@ -41,7 +41,8 @@ var n = class {
41
41
  try {
42
42
  const t = await fetch(e.proxyEndpoint);
43
43
  if (!t.ok) throw new Error(`Proxy endpoint returned ${t.status}`);
44
- this.apiKey = (await t.json()).apiKey, await this.emitTelemetry("pie-tool-backend-call-success", {
44
+ const r = await t.json();
45
+ this.apiKey = r.apiKey, await this.emitTelemetry("pie-tool-backend-call-success", {
45
46
  toolId: "calculator",
46
47
  backend: "desmos",
47
48
  operation: "proxy-auth-fetch",
@@ -179,6 +180,17 @@ Recommended: Use proxyEndpoint for production, apiKey for development only.`);
179
180
  resize() {
180
181
  this.calculator.resize && this.calculator.resize();
181
182
  }
183
+ focus() {
184
+ try {
185
+ if (this.type === "graphing" && typeof this.calculator?.focusFirstExpression == "function") {
186
+ this.calculator.focusFirstExpression();
187
+ return;
188
+ }
189
+ this.container.querySelector('.dcg-mq-editable-field[tabindex="0"], textarea, [contenteditable="true"], [tabindex]:not([tabindex="-1"])')?.focus();
190
+ } catch (e) {
191
+ console.warn("[DesmosCalculator] focus() failed:", e);
192
+ }
193
+ }
182
194
  exportState() {
183
195
  let e = {};
184
196
  return this.type === "graphing" && this.calculator.getState && (e = this.calculator.getState()), {
@@ -41,7 +41,8 @@ var n = class {
41
41
  try {
42
42
  const e = await fetch(t.proxyEndpoint);
43
43
  if (!e.ok) throw new Error(`Proxy endpoint returned ${e.status}`);
44
- this.apiKey = (await e.json()).apiKey, await this.emitTelemetry("pie-tool-backend-call-success", {
44
+ const i = await e.json();
45
+ this.apiKey = i.apiKey, await this.emitTelemetry("pie-tool-backend-call-success", {
45
46
  toolId: "calculator",
46
47
  backend: "desmos",
47
48
  operation: "proxy-auth-fetch",
@@ -179,6 +180,17 @@ Recommended: Use proxyEndpoint for production, apiKey for development only.`);
179
180
  resize() {
180
181
  this.calculator.resize && this.calculator.resize();
181
182
  }
183
+ focus() {
184
+ try {
185
+ if (this.type === "graphing" && typeof this.calculator?.focusFirstExpression == "function") {
186
+ this.calculator.focusFirstExpression();
187
+ return;
188
+ }
189
+ this.container.querySelector('.dcg-mq-editable-field[tabindex="0"], textarea, [contenteditable="true"], [tabindex]:not([tabindex="-1"])')?.focus();
190
+ } catch (t) {
191
+ console.warn("[DesmosCalculator] focus() failed:", t);
192
+ }
193
+ }
182
194
  exportState() {
183
195
  let t = {};
184
196
  return this.type === "graphing" && this.calculator.getState && (t = this.calculator.getState()), {