@pie-players/pie-assessment-toolkit 0.3.49 → 0.3.51

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.
@@ -11054,22 +11054,81 @@ var isServerBackend = (backend) => backend === "polly" || backend === "google" |
11054
11054
  var withDefault = (value, fallback2) => value === undefined ? fallback2 : value;
11055
11055
  var normalizeTTSLayoutMode = (value, fallback2 = "left-aligned") => typeof value === "string" && VALID_TTS_LAYOUT_MODES.has(value) ? value : fallback2;
11056
11056
  var DEFAULT_TTS_SPEED_OPTIONS = Object.freeze([0.8, 1.25]);
11057
- var normalizeTTSSpeedOptions = (value) => {
11057
+ var normalizeSpeedRate = (entry) => {
11058
+ if (typeof entry !== "number" || !Number.isFinite(entry) || entry <= 0) {
11059
+ return;
11060
+ }
11061
+ const rounded = Math.round(entry * 100) / 100;
11062
+ return rounded === 1 ? undefined : rounded;
11063
+ };
11064
+ var trimOptionalText = (value) => {
11065
+ if (typeof value !== "string")
11066
+ return;
11067
+ const trimmed = value.trim();
11068
+ return trimmed.length ? trimmed : undefined;
11069
+ };
11070
+ var formatSpeedLabel = (rate) => `${rate}x`;
11071
+ var formatSpeedAriaLabel = (label, usedDefaultLabel) => usedDefaultLabel ? `Speed ${label}` : `${label} speed`;
11072
+ var normalizeSpeedAriaLabel = (label, ariaLabel, usedDefaultLabel) => {
11073
+ if (!ariaLabel)
11074
+ return formatSpeedAriaLabel(label, usedDefaultLabel);
11075
+ if (ariaLabel.toLowerCase().includes(label.toLowerCase()))
11076
+ return ariaLabel;
11077
+ return `${label} ${ariaLabel}`;
11078
+ };
11079
+ var normalizeTTSSpeedOptionConfig = (entry) => {
11080
+ if (typeof entry === "number")
11081
+ return normalizeSpeedRate(entry);
11082
+ if (!entry || typeof entry !== "object" || Array.isArray(entry))
11083
+ return;
11084
+ const record = entry;
11085
+ const rate = normalizeSpeedRate(record.rate);
11086
+ if (rate === undefined)
11087
+ return;
11088
+ const label = trimOptionalText(record.label);
11089
+ const ariaLabel = trimOptionalText(record.ariaLabel);
11090
+ return {
11091
+ rate,
11092
+ ...label ? { label } : {},
11093
+ ...ariaLabel ? { ariaLabel } : {}
11094
+ };
11095
+ };
11096
+ var normalizeTTSSpeedOptionConfigs = (value) => {
11058
11097
  if (!Array.isArray(value))
11059
11098
  return [...DEFAULT_TTS_SPEED_OPTIONS];
11060
11099
  if (value.length === 0)
11061
11100
  return [];
11062
- const deduped = new Set;
11101
+ const dedupedRates = new Set;
11102
+ const normalized = [];
11063
11103
  for (const entry of value) {
11064
- if (typeof entry !== "number" || !Number.isFinite(entry) || entry <= 0)
11104
+ const option = normalizeTTSSpeedOptionConfig(entry);
11105
+ if (option === undefined)
11065
11106
  continue;
11066
- const rounded = Math.round(entry * 100) / 100;
11067
- if (rounded === 1)
11107
+ const rate = typeof option === "number" ? option : option.rate;
11108
+ if (dedupedRates.has(rate))
11068
11109
  continue;
11069
- deduped.add(rounded);
11110
+ dedupedRates.add(rate);
11111
+ normalized.push(option);
11070
11112
  }
11071
- return deduped.size ? Array.from(deduped) : [...DEFAULT_TTS_SPEED_OPTIONS];
11113
+ return normalized.length ? normalized : [...DEFAULT_TTS_SPEED_OPTIONS];
11072
11114
  };
11115
+ var normalizeTTSSpeedControlOptions = (value) => normalizeTTSSpeedOptionConfigs(value).map((option) => {
11116
+ if (typeof option === "number") {
11117
+ const label2 = formatSpeedLabel(option);
11118
+ return {
11119
+ rate: option,
11120
+ label: label2,
11121
+ ariaLabel: formatSpeedAriaLabel(label2, true)
11122
+ };
11123
+ }
11124
+ const defaultLabel = formatSpeedLabel(option.rate);
11125
+ const label = option.label || defaultLabel;
11126
+ return {
11127
+ rate: option.rate,
11128
+ label,
11129
+ ariaLabel: normalizeSpeedAriaLabel(label, option.ariaLabel, label === defaultLabel)
11130
+ };
11131
+ });
11073
11132
  var applyRuntimeDefaults = (config) => {
11074
11133
  const withLayoutDefaults = {
11075
11134
  ...config,
@@ -11224,7 +11283,7 @@ var ttsToolRegistration = {
11224
11283
  settings.layoutMode = normalizeTTSLayoutMode(settings.layoutMode);
11225
11284
  }
11226
11285
  if (settings && "speedOptions" in settings) {
11227
- settings.speedOptions = normalizeTTSSpeedOptions(settings.speedOptions);
11286
+ settings.speedOptions = normalizeTTSSpeedOptionConfigs(settings.speedOptions);
11228
11287
  }
11229
11288
  const normalizedConfig = {
11230
11289
  ...config
@@ -11233,7 +11292,7 @@ var ttsToolRegistration = {
11233
11292
  normalizedConfig.layoutMode = normalizeTTSLayoutMode(normalizedConfig.layoutMode);
11234
11293
  }
11235
11294
  if ("speedOptions" in normalizedConfig) {
11236
- normalizedConfig.speedOptions = normalizeTTSSpeedOptions(normalizedConfig.speedOptions);
11295
+ normalizedConfig.speedOptions = normalizeTTSSpeedOptionConfigs(normalizedConfig.speedOptions);
11237
11296
  }
11238
11297
  if (settings) {
11239
11298
  normalizedConfig.settings = settings;
@@ -11256,7 +11315,7 @@ var ttsToolRegistration = {
11256
11315
  const resolveRuntimeSettings = () => resolveTTSRuntimeSettings(toolbarContext.toolkitCoordinator?.getToolConfig(this.toolId) || undefined);
11257
11316
  const resolveElementSpeedOptions = () => {
11258
11317
  const runtimeSettings = resolveRuntimeSettings();
11259
- return normalizeTTSSpeedOptions(runtimeSettings.speedOptions);
11318
+ return normalizeTTSSpeedControlOptions(runtimeSettings.speedOptions);
11260
11319
  };
11261
11320
  const resolveLayoutMode = () => resolveTTSLayoutMode(resolveRuntimeSettings());
11262
11321
  const resolveHostLayout = () => resolveTTSHostToolbarLayout(resolveRuntimeSettings());
@@ -11886,19 +11945,6 @@ function createPackagedToolRegistry(options = {}) {
11886
11945
  includePackagedTools: true
11887
11946
  });
11888
11947
  }
11889
- var loadSideEffectModule = (load) => load().then(() => {
11890
- return;
11891
- });
11892
- function loadCalculatorModule() {
11893
- if (typeof globalThis !== "undefined" && "customElements" in globalThis && globalThis.customElements?.get("pie-tool-calculator")) {
11894
- return Promise.resolve();
11895
- }
11896
- return loadSideEffectModule(() => import("@pie-players/pie-tool-calculator-desmos"));
11897
- }
11898
- var DEFAULT_TOOL_MODULE_LOADERS = {
11899
- calculator: loadCalculatorModule,
11900
- textToSpeech: () => loadSideEffectModule(() => import("@pie-players/pie-tool-tts-inline"))
11901
- };
11902
11948
  var H = globalThis;
11903
11949
  var D = H.ShadowRoot && (H.ShadyCSS === undefined || H.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype;
11904
11950
  var tt = Symbol();
@@ -12870,7 +12916,7 @@ function ItemToolBar($$anchor, $$props) {
12870
12916
  installFaInToolbarShadow(node);
12871
12917
  return {};
12872
12918
  };
12873
- const fallbackToolRegistry = createPackagedToolRegistry({ toolModuleLoaders: DEFAULT_TOOL_MODULE_LOADERS });
12919
+ const fallbackToolRegistry = createPackagedToolRegistry();
12874
12920
  let activeToolState = state2(proxy2({}));
12875
12921
  let level = prop2($$props, "level", 7, "item"), scopeId = prop2($$props, "scopeId", 7, ""), itemId = prop2($$props, "itemId", 7, ""), sectionId = prop2($$props, "sectionId", 7, ""), catalogId = prop2($$props, "catalogId", 7, ""), tools = prop2($$props, "tools", 7, "calculator,textToSpeech,answerEliminator"), contentKind = prop2($$props, "contentKind", 7, "assessment-item"), position = prop2($$props, "position", 7, "bottom"), scopeElement = prop2($$props, "scopeElement", 7, null), toolRegistry = prop2($$props, "toolRegistry", 7, null), item = prop2($$props, "item", 7, null), hostButtons = prop2($$props, "hostButtons", 23, () => []), className = prop2($$props, "class", 7, ""), size = prop2($$props, "size", 7, "md"), language = prop2($$props, "language", 7, "en-US");
12876
12922
  let toolbarRootElement = state2(null);
@@ -13512,13 +13558,34 @@ function ItemToolBar($$anchor, $$props) {
13512
13558
  const maxHeight = shellConfig?.maxHeight ?? window.innerHeight;
13513
13559
  return { minWidth, minHeight, maxWidth, maxHeight };
13514
13560
  };
13561
+ const applyContentMinWidth = () => {
13562
+ const configuredMinWidth = currentArgs.mounted.entry.shell?.minWidth;
13563
+ const shouldScroll = typeof configuredMinWidth === "number" && configuredMinWidth > 0 && width < configuredMinWidth;
13564
+ const minWidthValue = shouldScroll ? `${configuredMinWidth}px` : "";
13565
+ if (mountedContentElement) {
13566
+ mountedContentElement.style.minWidth = minWidthValue;
13567
+ }
13568
+ if (headerEl) {
13569
+ headerEl.style.minWidth = minWidthValue;
13570
+ }
13571
+ if (contentEl) {
13572
+ contentEl.style.minWidth = minWidthValue;
13573
+ }
13574
+ if (shellEl) {
13575
+ shellEl.style.overflowX = shouldScroll ? "auto" : "visible";
13576
+ shellEl.style.overflowY = "visible";
13577
+ }
13578
+ };
13515
13579
  const applyPositionAndSize = () => {
13516
13580
  const { minWidth, minHeight, maxWidth, maxHeight } = getShellBounds();
13517
- width = clamp(width, minWidth, Math.max(minWidth, Math.min(maxWidth, window.innerWidth)));
13518
- height = clamp(height, minHeight, Math.max(minHeight, Math.min(maxHeight, window.innerHeight)));
13581
+ const effectiveMinWidth = Math.min(minWidth, window.innerWidth);
13582
+ const effectiveMinHeight = Math.min(minHeight, window.innerHeight);
13583
+ width = clamp(width, effectiveMinWidth, Math.max(effectiveMinWidth, Math.min(maxWidth, window.innerWidth)));
13584
+ height = clamp(height, effectiveMinHeight, Math.max(effectiveMinHeight, Math.min(maxHeight, window.innerHeight)));
13519
13585
  x2 = clamp(x2, 0, Math.max(0, window.innerWidth - width));
13520
13586
  y2 = clamp(y2, 0, Math.max(0, window.innerHeight - height));
13521
13587
  applyShellStyle();
13588
+ applyContentMinWidth();
13522
13589
  notifyHostedResize();
13523
13590
  };
13524
13591
  const moveBy = (dx, dy) => {
@@ -13619,6 +13686,7 @@ function ItemToolBar($$anchor, $$props) {
13619
13686
  element2.style.height = "100%";
13620
13687
  element2.style.flex = "1 1 auto";
13621
13688
  element2.style.minHeight = "0";
13689
+ applyContentMinWidth();
13622
13690
  if (mountedContentElement && mountedContentElement !== element2) {
13623
13691
  if (mountedContentElement.parentNode === contentEl) {
13624
13692
  invokeElementUnmount(mountedContentElement);
@@ -13867,8 +13935,10 @@ function ItemToolBar($$anchor, $$props) {
13867
13935
  if (resizePointerId === event2.pointerId) {
13868
13936
  event2.preventDefault();
13869
13937
  const shellConfig = currentArgs.mounted.entry.shell;
13870
- const minWidth = shellConfig?.minWidth ?? 320;
13871
- const minHeight = shellConfig?.minHeight ?? 240;
13938
+ const configuredMinWidth = shellConfig?.minWidth ?? 320;
13939
+ const configuredMinHeight = shellConfig?.minHeight ?? 240;
13940
+ const minWidth = Math.min(configuredMinWidth, window.innerWidth);
13941
+ const minHeight = Math.min(configuredMinHeight, window.innerHeight);
13872
13942
  const maxWidth = shellConfig?.maxWidth ?? window.innerWidth;
13873
13943
  const maxHeight = shellConfig?.maxHeight ?? window.innerHeight;
13874
13944
  const dx = event2.clientX - resizeStartX;
@@ -13899,6 +13969,7 @@ function ItemToolBar($$anchor, $$props) {
13899
13969
  height = newHeight;
13900
13970
  }
13901
13971
  applyShellStyle();
13972
+ applyContentMinWidth();
13902
13973
  notifyHostedResize();
13903
13974
  }
13904
13975
  };
package/dist/index.d.ts CHANGED
@@ -56,8 +56,8 @@ export { PlaybackState, TTSService } from "./services/TTSService.js";
56
56
  export { PIE_TTS_CONTROL_HANDOFF_EVENT, type TTSControlHandoffDetail, } from "./services/tts-control-events.js";
57
57
  export { BrowserTTSProvider } from "./services/tts/browser-provider.js";
58
58
  export type { SREMathSpeechOptions } from "./services/tts/math-speech.js";
59
- export type { TTSHostToolbarLayout, TTSLayoutMode, TTSRuntimeSettings, } from "./services/tts-runtime-config.js";
60
- export { DEFAULT_TTS_SPEED_OPTIONS, formatTTSSpeedOptionsAsText, normalizeTTSLayoutMode, normalizeTTSSpeedOptions, parseTTSSpeedOptionsFromText, resolveTTSHostToolbarLayout, resolveTTSLayoutMode, resolveTTSRuntimeSettings, } from "./services/tts-runtime-config.js";
59
+ export type { NormalizedTTSSpeedOption, TTSHostToolbarLayout, TTSLayoutMode, TTSRuntimeSettings, TTSSpeedOption, TTSSpeedOptionConfig, } from "./services/tts-runtime-config.js";
60
+ export { DEFAULT_TTS_SPEED_OPTIONS, formatTTSSpeedOptionsAsText, normalizeTTSLayoutMode, normalizeTTSSpeedControlOptions, normalizeTTSSpeedOptionConfigs, normalizeTTSSpeedOptions, parseTTSSpeedOptionsFromText, resolveTTSHostToolbarLayout, resolveTTSLayoutMode, resolveTTSRuntimeSettings, } from "./services/tts-runtime-config.js";
61
61
  export type { ITTSProvider, ITTSProviderImplementation, TTSSpeechSegment, TTSFeature, TTSProviderCapabilities, } from "@pie-players/pie-tts";
62
62
  export type { CreateLoadItemOptions, LoadItem, LoadItemOptions, } from "./item-loader.js";
63
63
  export { createFetchItemLoader, createLoadItem, ItemLoadError, } from "./item-loader.js";
package/dist/index.js CHANGED
@@ -39,7 +39,7 @@ export { createScopedToolId, parseScopedToolId, toOverlayToolId, } from "./servi
39
39
  export { PlaybackState, TTSService } from "./services/TTSService.js";
40
40
  export { PIE_TTS_CONTROL_HANDOFF_EVENT, } from "./services/tts-control-events.js";
41
41
  export { BrowserTTSProvider } from "./services/tts/browser-provider.js";
42
- export { DEFAULT_TTS_SPEED_OPTIONS, formatTTSSpeedOptionsAsText, normalizeTTSLayoutMode, normalizeTTSSpeedOptions, parseTTSSpeedOptionsFromText, resolveTTSHostToolbarLayout, resolveTTSLayoutMode, resolveTTSRuntimeSettings, } from "./services/tts-runtime-config.js";
42
+ export { DEFAULT_TTS_SPEED_OPTIONS, formatTTSSpeedOptionsAsText, normalizeTTSLayoutMode, normalizeTTSSpeedControlOptions, normalizeTTSSpeedOptionConfigs, normalizeTTSSpeedOptions, parseTTSSpeedOptionsFromText, resolveTTSHostToolbarLayout, resolveTTSLayoutMode, resolveTTSRuntimeSettings, } from "./services/tts-runtime-config.js";
43
43
  export { createFetchItemLoader, createLoadItem, ItemLoadError, } from "./item-loader.js";
44
44
  export { createMemoryStorage, createTestAttemptSessionIdentifier, createNewTestAttemptSession, getBrowserLocalStorage, getOrCreateAnonymousDeviceId, getTestAttemptSessionStorageKey, loadTestAttemptSession, saveTestAttemptSession, setCurrentPosition, upsertItemSessionFromPieSessionChange, upsertVisitedItem, } from "./attempt/TestSession.js";
45
45
  export { createNewAssessmentSession, getAssessmentSessionStorageKey, loadAssessmentSession, saveAssessmentSession, setCurrentSectionPosition, upsertSectionSession, } from "./attempt/AssessmentSession.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * PIE Assessment Toolkit\n *\n * Independent, composable services for coordinating tools, accommodations,\n * and item players in assessment applications.\n *\n * @packageDocumentation\n */\n\n// ============================================================================\n// Core Infrastructure\n// ============================================================================\n\nexport type {\n\tAssessmentToolkitHostRuntimeContext,\n\tAssessmentToolkitRegionScopeContext,\n\tAssessmentToolkitRuntimeContext,\n\tAssessmentToolkitShellContext,\n\tItemPlayerConfig,\n\tItemPlayerType,\n\tShellContextKind,\n} from \"./context/assessment-toolkit-context.js\";\nexport {\n\tassessmentToolkitHostRuntimeContext,\n\tassessmentToolkitRegionScopeContext,\n\tassessmentToolkitRuntimeContext,\n\tassessmentToolkitShellContext,\n} from \"./context/assessment-toolkit-context.js\";\nexport {\n\tconnectAssessmentToolkitHostRuntimeContext,\n\tconnectAssessmentToolkitRegionScopeContext,\n\tconnectAssessmentToolkitRuntimeContext,\n\tconnectAssessmentToolkitShellContext,\n} from \"./context/runtime-context-consumer.js\";\nexport {\n\tPIE_INTERNAL_CONTENT_LOADED_EVENT,\n\tPIE_INTERNAL_ITEM_SESSION_CHANGED_EVENT,\n\tPIE_INTERNAL_ITEM_PLAYER_ERROR_EVENT,\n\tPIE_ITEM_SESSION_CHANGED_EVENT,\n\tPIE_REGISTER_EVENT,\n\tPIE_UNREGISTER_EVENT,\n\ttype InternalContentLoadedDetail,\n\ttype InternalItemSessionChangedDetail,\n\ttype InternalItemPlayerErrorDetail,\n\ttype ItemSessionChangedDetail,\n\ttype RuntimeRegistrationDetail,\n\ttype RuntimeRegistrationKind,\n} from \"./runtime/registration-events.js\";\nexport {\n\tconnectToolRegionScopeContext,\n\tconnectToolRuntimeContext,\n\tconnectToolShellContext,\n\tcreateCrossBoundaryEvent,\n\tdispatchCrossBoundaryEvent,\n\tisContextValueDefined,\n} from \"./runtime/tool-host-contract.js\";\n\n// ============================================================================\n// Service Interfaces\n// ============================================================================\n\nexport type {\n\tAccessibilityCatalogResolverApi,\n\tElementToolStateStoreApi,\n\tHighlightCoordinatorApi,\n\tI18nServiceApi,\n\tThemeProviderApi,\n\tToolCoordinatorApi,\n\tToolkitCoordinatorApi,\n\tTtsServiceApi,\n\tToolState,\n} from \"./services/interfaces.js\";\n\n// ============================================================================\n// Toolkit Services\n// ============================================================================\n\n// Accessibility Catalog Resolver (QTI 3.0 Accessibility Catalogs)\nexport type {\n\tCatalogLookupContext,\n\tCatalogLookupOptions,\n\tCatalogOwnerContext,\n\tCatalogOwnerKind,\n\tCatalogStatistics,\n\tCatalogType,\n\tResolvedCatalog,\n} from \"./services/AccessibilityCatalogResolver.js\";\nexport { AccessibilityCatalogResolver } from \"./services/AccessibilityCatalogResolver.js\";\n// Context Variable Store (QTI 3.0 Context Declarations)\nexport { ContextVariableStore } from \"./services/ContextVariableStore.js\";\n// Element Tool State Store (Element-level ephemeral tool state)\nexport { ElementToolStateStore } from \"./services/ElementToolStateStore.js\";\n// Highlight Coordinator\nexport type { Annotation } from \"./services/HighlightCoordinator.js\";\nexport {\n\tHighlightColor,\n\tHighlightCoordinator,\n\tHighlightType,\n} from \"./services/HighlightCoordinator.js\";\n// Range Serializer (for annotation persistence)\nexport type { SerializedRange } from \"./services/RangeSerializer.js\";\nexport { RangeSerializer } from \"./services/RangeSerializer.js\";\n// I18n Service\nexport type {\n\tI18nConfig,\n\tPluralTranslation,\n\tTranslationBundle,\n} from \"./services/I18nService.js\";\nexport { I18nService } from \"./services/I18nService.js\";\n// Tool Registry (Registry-based tool system)\nexport type {\n\tResolvedToolContext,\n\tToolbarContext,\n\tToolContextResolver,\n\tToolContextResolverContext,\n\tToolContextResolverMap,\n\tToolContextResolverResult,\n\tToolModuleLoader,\n\tToolToolbarButtonDefinition,\n\tToolToolbarRenderResult,\n\tToolRegistration,\n} from \"./services/ToolRegistry.js\";\nexport { ToolRegistry } from \"./services/ToolRegistry.js\";\nexport type {\n\tAssessmentToolContext,\n\tBaseToolContext,\n\tElementToolContext,\n\tItemToolContext,\n\tPassageToolContext,\n\tRubricToolContext,\n\tSectionToolContext,\n\tToolContext,\n\tToolLevel,\n} from \"./services/tool-context.js\";\nexport {\n\textractTextContent,\n\thasChoiceInteraction,\n\thasMathContent,\n\thasReadableText,\n\tisAssessmentContext,\n\tisElementContext,\n\tisItemContext,\n\tisPassageContext,\n\tisRubricContext,\n\tisSectionContext,\n} from \"./services/tool-context.js\";\nexport {\n\tDEFAULT_TOOL_PLACEMENT,\n\tDEFAULT_TOOL_ORDER,\n\tcreatePackagedToolRegistry,\n\tPACKAGED_TOOL_PLACEMENT,\n\tregisterPackagedTools,\n} from \"./services/createDefaultToolRegistry.js\";\nexport type { CreateToolsConfigArgs } from \"./services/create-tools-config.js\";\nexport { createToolsConfig } from \"./services/create-tools-config.js\";\nexport {\n\tDEFAULT_PERSONAL_NEEDS_PROFILE,\n\tcreateDefaultPersonalNeedsProfile,\n} from \"./services/defaultPersonalNeedsProfile.js\";\nexport type {\n\tToolComponentFactory,\n\tToolComponentFactoryMap,\n\tToolComponentOverrides,\n\tToolTagMap,\n} from \"./tools/tool-tag-map.js\";\nexport {\n\tcreateToolElement,\n\tDEFAULT_TOOL_TAG_MAP,\n\tresolveToolTag,\n\ttoToolIdFromTag,\n} from \"./tools/tool-tag-map.js\";\n// QTI 3.0 Standard Access Features\nexport {\n\tALL_STANDARD_ACCESS_FEATURES,\n\tEXAMPLE_PNP_CONFIGURATIONS,\n\tgetFeatureCategory,\n\tgetFeaturesInCategory,\n\tisStandardAccessFeature,\n\tQTI_STANDARD_ACCESS_FEATURES,\n} from \"./services/pnp-standard-features.js\";\n// SSML Extractor (Auto-generates catalogs from embedded SSML)\nexport type { ExtractionResult } from \"./services/SSMLExtractor.js\";\nexport { SSMLExtractor } from \"./services/SSMLExtractor.js\";\n// Theme Provider\nexport type { FontSize, ThemeConfig } from \"./services/ThemeProvider.js\";\nexport { ThemeProvider } from \"./services/ThemeProvider.js\";\n// Tool Coordinator\nexport { ToolCoordinator, ZIndexLayer } from \"./services/ToolCoordinator.js\";\n// Toolkit Coordinator (Centralized service management)\nexport type {\n\tAnswerEliminatorToolConfig,\n\tProviderLifecycleContext,\n\tSectionControllerContext,\n\tSectionControllerEvent,\n\tSectionControllerEventType,\n\tSectionItemEvent,\n\tSectionItemEventType,\n\tSectionControllerFactoryDefaults,\n\tSectionControllerHandle,\n\tSectionControllerKey,\n\tSectionScopedEvent,\n\tSectionScopedEventType,\n\tSectionSessionPersistenceConfig,\n\tSectionItemEventSubscriptionArgs,\n\tSectionScopedEventSubscriptionArgs,\n\tSectionEventSubscriptionArgs,\n\tSectionSessionPersistenceStrategy,\n\tSectionControllerLoadedRenderable,\n\tSectionControllerRuntimeState,\n\tSectionControllerSessionState,\n\tSectionPersistenceFactoryDefaults,\n\tToolConfig,\n\tToolkitCoordinatorConfig,\n\tToolkitCoordinatorHooks,\n\tToolkitErrorContext,\n\tToolkitInitStatus,\n\tToolkitServiceBundle,\n\tToolkitToolsConfig,\n\tTTSToolConfig,\n} from \"./services/ToolkitCoordinator.js\";\nexport { ToolkitCoordinator } from \"./services/ToolkitCoordinator.js\";\nexport type {\n\tCanonicalToolsConfig,\n\tToolPlacementConfig,\n\tToolPlacementLevel,\n\tToolPolicyConfig,\n\tToolProvidersConfig,\n} from \"./services/tools-config-normalizer.js\";\nexport type {\n\tFrameworkErrorKind,\n\tFrameworkErrorModel,\n\tFrameworkErrorSeverity,\n} from \"./services/framework-error.js\";\nexport {\n\tformatFrameworkErrorForConsole,\n\tframeworkErrorFromToolConfigDiagnostics,\n\tframeworkErrorFromUnknown,\n\ttoFrameworkErrorModel,\n} from \"./services/framework-error.js\";\nexport type { FrameworkErrorListener } from \"./services/framework-error-bus.js\";\nexport type {\n\tToolConfigDiagnostic,\n\tToolConfigDiagnosticSeverity,\n\tToolConfigStrictness,\n\tToolConfigValidationOptions,\n\tToolConfigValidationResult,\n} from \"./services/tool-config-validation.js\";\nexport type {\n\tToolbarButtonItem,\n\tToolbarItem,\n\tToolbarItemBase,\n\tToolbarLinkItem,\n} from \"./services/toolbar-items.js\";\nexport {\n\tisExternalIconUrl,\n\tisInlineSvgIcon,\n\tisToolbarLinkItem,\n\tisValidToolbarItemShape,\n} from \"./services/toolbar-items.js\";\nexport {\n\tnormalizeToolsConfig,\n\tnormalizeToolAlias,\n\tnormalizeToolList,\n\tparseToolList,\n} from \"./services/tools-config-normalizer.js\";\nexport {\n\tframeworkErrorFromToolConfigValidation,\n\tnormalizeAndValidateToolsConfig,\n} from \"./services/tool-config-validation.js\";\nexport type {\n\tParsedToolInstanceId,\n\tToolScopeLevel,\n} from \"./services/tool-instance-id.js\";\nexport {\n\tcreateScopedToolId,\n\tparseScopedToolId,\n\ttoOverlayToolId,\n} from \"./services/tool-instance-id.js\";\n// Text-to-Speech Service\nexport type { TTSConfig } from \"./services/TTSService.js\";\nexport { PlaybackState, TTSService } from \"./services/TTSService.js\";\nexport {\n\tPIE_TTS_CONTROL_HANDOFF_EVENT,\n\ttype TTSControlHandoffDetail,\n} from \"./services/tts-control-events.js\";\nexport { BrowserTTSProvider } from \"./services/tts/browser-provider.js\";\nexport type { SREMathSpeechOptions } from \"./services/tts/math-speech.js\";\nexport type {\n\tTTSHostToolbarLayout,\n\tTTSLayoutMode,\n\tTTSRuntimeSettings,\n} from \"./services/tts-runtime-config.js\";\nexport {\n\tDEFAULT_TTS_SPEED_OPTIONS,\n\tformatTTSSpeedOptionsAsText,\n\tnormalizeTTSLayoutMode,\n\tnormalizeTTSSpeedOptions,\n\tparseTTSSpeedOptionsFromText,\n\tresolveTTSHostToolbarLayout,\n\tresolveTTSLayoutMode,\n\tresolveTTSRuntimeSettings,\n} from \"./services/tts-runtime-config.js\";\n// TTS Provider System\nexport type {\n\tITTSProvider,\n\tITTSProviderImplementation,\n\tTTSSpeechSegment,\n\tTTSFeature,\n\tTTSProviderCapabilities,\n} from \"@pie-players/pie-tts\";\n\n// ============================================================================\n// Item loading (client-resolvable default; optional backend hook)\n// ============================================================================\n\nexport type {\n\tCreateLoadItemOptions,\n\tLoadItem,\n\tLoadItemOptions,\n} from \"./item-loader.js\";\nexport {\n\tcreateFetchItemLoader,\n\tcreateLoadItem,\n\tItemLoadError,\n} from \"./item-loader.js\";\n\n// ============================================================================\n// Attempt Session\n// ============================================================================\n\nexport type {\n\tStorageLike,\n\tTestAttemptItemSession,\n\tTestAttemptSession,\n\tTestAttemptSessionNavigationState,\n\tTestAttemptSessionRealization,\n} from \"./attempt/TestSession.js\";\nexport {\n\tcreateMemoryStorage,\n\tcreateTestAttemptSessionIdentifier,\n\tcreateNewTestAttemptSession,\n\tgetBrowserLocalStorage,\n\tgetOrCreateAnonymousDeviceId,\n\tgetTestAttemptSessionStorageKey,\n\tloadTestAttemptSession,\n\tsaveTestAttemptSession,\n\tsetCurrentPosition,\n\tupsertItemSessionFromPieSessionChange,\n\tupsertVisitedItem,\n} from \"./attempt/TestSession.js\";\nexport type {\n\tAssessmentSession,\n\tAssessmentSectionSessionState,\n\tAssessmentSessionNavigationState,\n\tAssessmentSessionRealization,\n} from \"./attempt/AssessmentSession.js\";\nexport {\n\tcreateNewAssessmentSession,\n\tgetAssessmentSessionStorageKey,\n\tloadAssessmentSession,\n\tsaveAssessmentSession,\n\tsetCurrentSectionPosition,\n\tupsertSectionSession,\n} from \"./attempt/AssessmentSession.js\";\nexport type {\n\tActivitySessionPatchPayload,\n\tMapActivityToTestAttemptSessionArgs,\n\tPieBackendActivityDefinition,\n\tPieBackendActivityItemRef,\n\tPieBackendActivitySession,\n} from \"./attempt/adapters/activity-to-test-attempt-session.js\";\nexport {\n\tbuildActivitySessionItemUpdate,\n\tbuildActivitySessionPatchFromTestAttemptSession,\n\tmapActivityToTestAttemptSession,\n\ttoItemSessionsRecord,\n} from \"./attempt/adapters/activity-to-test-attempt-session.js\";\n\n// Section Player - Use @pie-players/pie-section-player web component\n\n// ============================================================================\n// Shared Components\n// ============================================================================\n\n// ItemToolBar custom element registration helper is exported via package.json exports field\n// Import using: import '@pie-players/pie-assessment-toolkit/components/item-toolbar-element';\n// PieAssessmentToolkit custom element registration helper is exported via package.json exports field\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * PIE Assessment Toolkit\n *\n * Independent, composable services for coordinating tools, accommodations,\n * and item players in assessment applications.\n *\n * @packageDocumentation\n */\n\n// ============================================================================\n// Core Infrastructure\n// ============================================================================\n\nexport type {\n\tAssessmentToolkitHostRuntimeContext,\n\tAssessmentToolkitRegionScopeContext,\n\tAssessmentToolkitRuntimeContext,\n\tAssessmentToolkitShellContext,\n\tItemPlayerConfig,\n\tItemPlayerType,\n\tShellContextKind,\n} from \"./context/assessment-toolkit-context.js\";\nexport {\n\tassessmentToolkitHostRuntimeContext,\n\tassessmentToolkitRegionScopeContext,\n\tassessmentToolkitRuntimeContext,\n\tassessmentToolkitShellContext,\n} from \"./context/assessment-toolkit-context.js\";\nexport {\n\tconnectAssessmentToolkitHostRuntimeContext,\n\tconnectAssessmentToolkitRegionScopeContext,\n\tconnectAssessmentToolkitRuntimeContext,\n\tconnectAssessmentToolkitShellContext,\n} from \"./context/runtime-context-consumer.js\";\nexport {\n\tPIE_INTERNAL_CONTENT_LOADED_EVENT,\n\tPIE_INTERNAL_ITEM_SESSION_CHANGED_EVENT,\n\tPIE_INTERNAL_ITEM_PLAYER_ERROR_EVENT,\n\tPIE_ITEM_SESSION_CHANGED_EVENT,\n\tPIE_REGISTER_EVENT,\n\tPIE_UNREGISTER_EVENT,\n\ttype InternalContentLoadedDetail,\n\ttype InternalItemSessionChangedDetail,\n\ttype InternalItemPlayerErrorDetail,\n\ttype ItemSessionChangedDetail,\n\ttype RuntimeRegistrationDetail,\n\ttype RuntimeRegistrationKind,\n} from \"./runtime/registration-events.js\";\nexport {\n\tconnectToolRegionScopeContext,\n\tconnectToolRuntimeContext,\n\tconnectToolShellContext,\n\tcreateCrossBoundaryEvent,\n\tdispatchCrossBoundaryEvent,\n\tisContextValueDefined,\n} from \"./runtime/tool-host-contract.js\";\n\n// ============================================================================\n// Service Interfaces\n// ============================================================================\n\nexport type {\n\tAccessibilityCatalogResolverApi,\n\tElementToolStateStoreApi,\n\tHighlightCoordinatorApi,\n\tI18nServiceApi,\n\tThemeProviderApi,\n\tToolCoordinatorApi,\n\tToolkitCoordinatorApi,\n\tTtsServiceApi,\n\tToolState,\n} from \"./services/interfaces.js\";\n\n// ============================================================================\n// Toolkit Services\n// ============================================================================\n\n// Accessibility Catalog Resolver (QTI 3.0 Accessibility Catalogs)\nexport type {\n\tCatalogLookupContext,\n\tCatalogLookupOptions,\n\tCatalogOwnerContext,\n\tCatalogOwnerKind,\n\tCatalogStatistics,\n\tCatalogType,\n\tResolvedCatalog,\n} from \"./services/AccessibilityCatalogResolver.js\";\nexport { AccessibilityCatalogResolver } from \"./services/AccessibilityCatalogResolver.js\";\n// Context Variable Store (QTI 3.0 Context Declarations)\nexport { ContextVariableStore } from \"./services/ContextVariableStore.js\";\n// Element Tool State Store (Element-level ephemeral tool state)\nexport { ElementToolStateStore } from \"./services/ElementToolStateStore.js\";\n// Highlight Coordinator\nexport type { Annotation } from \"./services/HighlightCoordinator.js\";\nexport {\n\tHighlightColor,\n\tHighlightCoordinator,\n\tHighlightType,\n} from \"./services/HighlightCoordinator.js\";\n// Range Serializer (for annotation persistence)\nexport type { SerializedRange } from \"./services/RangeSerializer.js\";\nexport { RangeSerializer } from \"./services/RangeSerializer.js\";\n// I18n Service\nexport type {\n\tI18nConfig,\n\tPluralTranslation,\n\tTranslationBundle,\n} from \"./services/I18nService.js\";\nexport { I18nService } from \"./services/I18nService.js\";\n// Tool Registry (Registry-based tool system)\nexport type {\n\tResolvedToolContext,\n\tToolbarContext,\n\tToolContextResolver,\n\tToolContextResolverContext,\n\tToolContextResolverMap,\n\tToolContextResolverResult,\n\tToolModuleLoader,\n\tToolToolbarButtonDefinition,\n\tToolToolbarRenderResult,\n\tToolRegistration,\n} from \"./services/ToolRegistry.js\";\nexport { ToolRegistry } from \"./services/ToolRegistry.js\";\nexport type {\n\tAssessmentToolContext,\n\tBaseToolContext,\n\tElementToolContext,\n\tItemToolContext,\n\tPassageToolContext,\n\tRubricToolContext,\n\tSectionToolContext,\n\tToolContext,\n\tToolLevel,\n} from \"./services/tool-context.js\";\nexport {\n\textractTextContent,\n\thasChoiceInteraction,\n\thasMathContent,\n\thasReadableText,\n\tisAssessmentContext,\n\tisElementContext,\n\tisItemContext,\n\tisPassageContext,\n\tisRubricContext,\n\tisSectionContext,\n} from \"./services/tool-context.js\";\nexport {\n\tDEFAULT_TOOL_PLACEMENT,\n\tDEFAULT_TOOL_ORDER,\n\tcreatePackagedToolRegistry,\n\tPACKAGED_TOOL_PLACEMENT,\n\tregisterPackagedTools,\n} from \"./services/createDefaultToolRegistry.js\";\nexport type { CreateToolsConfigArgs } from \"./services/create-tools-config.js\";\nexport { createToolsConfig } from \"./services/create-tools-config.js\";\nexport {\n\tDEFAULT_PERSONAL_NEEDS_PROFILE,\n\tcreateDefaultPersonalNeedsProfile,\n} from \"./services/defaultPersonalNeedsProfile.js\";\nexport type {\n\tToolComponentFactory,\n\tToolComponentFactoryMap,\n\tToolComponentOverrides,\n\tToolTagMap,\n} from \"./tools/tool-tag-map.js\";\nexport {\n\tcreateToolElement,\n\tDEFAULT_TOOL_TAG_MAP,\n\tresolveToolTag,\n\ttoToolIdFromTag,\n} from \"./tools/tool-tag-map.js\";\n// QTI 3.0 Standard Access Features\nexport {\n\tALL_STANDARD_ACCESS_FEATURES,\n\tEXAMPLE_PNP_CONFIGURATIONS,\n\tgetFeatureCategory,\n\tgetFeaturesInCategory,\n\tisStandardAccessFeature,\n\tQTI_STANDARD_ACCESS_FEATURES,\n} from \"./services/pnp-standard-features.js\";\n// SSML Extractor (Auto-generates catalogs from embedded SSML)\nexport type { ExtractionResult } from \"./services/SSMLExtractor.js\";\nexport { SSMLExtractor } from \"./services/SSMLExtractor.js\";\n// Theme Provider\nexport type { FontSize, ThemeConfig } from \"./services/ThemeProvider.js\";\nexport { ThemeProvider } from \"./services/ThemeProvider.js\";\n// Tool Coordinator\nexport { ToolCoordinator, ZIndexLayer } from \"./services/ToolCoordinator.js\";\n// Toolkit Coordinator (Centralized service management)\nexport type {\n\tAnswerEliminatorToolConfig,\n\tProviderLifecycleContext,\n\tSectionControllerContext,\n\tSectionControllerEvent,\n\tSectionControllerEventType,\n\tSectionItemEvent,\n\tSectionItemEventType,\n\tSectionControllerFactoryDefaults,\n\tSectionControllerHandle,\n\tSectionControllerKey,\n\tSectionScopedEvent,\n\tSectionScopedEventType,\n\tSectionSessionPersistenceConfig,\n\tSectionItemEventSubscriptionArgs,\n\tSectionScopedEventSubscriptionArgs,\n\tSectionEventSubscriptionArgs,\n\tSectionSessionPersistenceStrategy,\n\tSectionControllerLoadedRenderable,\n\tSectionControllerRuntimeState,\n\tSectionControllerSessionState,\n\tSectionPersistenceFactoryDefaults,\n\tToolConfig,\n\tToolkitCoordinatorConfig,\n\tToolkitCoordinatorHooks,\n\tToolkitErrorContext,\n\tToolkitInitStatus,\n\tToolkitServiceBundle,\n\tToolkitToolsConfig,\n\tTTSToolConfig,\n} from \"./services/ToolkitCoordinator.js\";\nexport { ToolkitCoordinator } from \"./services/ToolkitCoordinator.js\";\nexport type {\n\tCanonicalToolsConfig,\n\tToolPlacementConfig,\n\tToolPlacementLevel,\n\tToolPolicyConfig,\n\tToolProvidersConfig,\n} from \"./services/tools-config-normalizer.js\";\nexport type {\n\tFrameworkErrorKind,\n\tFrameworkErrorModel,\n\tFrameworkErrorSeverity,\n} from \"./services/framework-error.js\";\nexport {\n\tformatFrameworkErrorForConsole,\n\tframeworkErrorFromToolConfigDiagnostics,\n\tframeworkErrorFromUnknown,\n\ttoFrameworkErrorModel,\n} from \"./services/framework-error.js\";\nexport type { FrameworkErrorListener } from \"./services/framework-error-bus.js\";\nexport type {\n\tToolConfigDiagnostic,\n\tToolConfigDiagnosticSeverity,\n\tToolConfigStrictness,\n\tToolConfigValidationOptions,\n\tToolConfigValidationResult,\n} from \"./services/tool-config-validation.js\";\nexport type {\n\tToolbarButtonItem,\n\tToolbarItem,\n\tToolbarItemBase,\n\tToolbarLinkItem,\n} from \"./services/toolbar-items.js\";\nexport {\n\tisExternalIconUrl,\n\tisInlineSvgIcon,\n\tisToolbarLinkItem,\n\tisValidToolbarItemShape,\n} from \"./services/toolbar-items.js\";\nexport {\n\tnormalizeToolsConfig,\n\tnormalizeToolAlias,\n\tnormalizeToolList,\n\tparseToolList,\n} from \"./services/tools-config-normalizer.js\";\nexport {\n\tframeworkErrorFromToolConfigValidation,\n\tnormalizeAndValidateToolsConfig,\n} from \"./services/tool-config-validation.js\";\nexport type {\n\tParsedToolInstanceId,\n\tToolScopeLevel,\n} from \"./services/tool-instance-id.js\";\nexport {\n\tcreateScopedToolId,\n\tparseScopedToolId,\n\ttoOverlayToolId,\n} from \"./services/tool-instance-id.js\";\n// Text-to-Speech Service\nexport type { TTSConfig } from \"./services/TTSService.js\";\nexport { PlaybackState, TTSService } from \"./services/TTSService.js\";\nexport {\n\tPIE_TTS_CONTROL_HANDOFF_EVENT,\n\ttype TTSControlHandoffDetail,\n} from \"./services/tts-control-events.js\";\nexport { BrowserTTSProvider } from \"./services/tts/browser-provider.js\";\nexport type { SREMathSpeechOptions } from \"./services/tts/math-speech.js\";\nexport type {\n\tNormalizedTTSSpeedOption,\n\tTTSHostToolbarLayout,\n\tTTSLayoutMode,\n\tTTSRuntimeSettings,\n\tTTSSpeedOption,\n\tTTSSpeedOptionConfig,\n} from \"./services/tts-runtime-config.js\";\nexport {\n\tDEFAULT_TTS_SPEED_OPTIONS,\n\tformatTTSSpeedOptionsAsText,\n\tnormalizeTTSLayoutMode,\n\tnormalizeTTSSpeedControlOptions,\n\tnormalizeTTSSpeedOptionConfigs,\n\tnormalizeTTSSpeedOptions,\n\tparseTTSSpeedOptionsFromText,\n\tresolveTTSHostToolbarLayout,\n\tresolveTTSLayoutMode,\n\tresolveTTSRuntimeSettings,\n} from \"./services/tts-runtime-config.js\";\n// TTS Provider System\nexport type {\n\tITTSProvider,\n\tITTSProviderImplementation,\n\tTTSSpeechSegment,\n\tTTSFeature,\n\tTTSProviderCapabilities,\n} from \"@pie-players/pie-tts\";\n\n// ============================================================================\n// Item loading (client-resolvable default; optional backend hook)\n// ============================================================================\n\nexport type {\n\tCreateLoadItemOptions,\n\tLoadItem,\n\tLoadItemOptions,\n} from \"./item-loader.js\";\nexport {\n\tcreateFetchItemLoader,\n\tcreateLoadItem,\n\tItemLoadError,\n} from \"./item-loader.js\";\n\n// ============================================================================\n// Attempt Session\n// ============================================================================\n\nexport type {\n\tStorageLike,\n\tTestAttemptItemSession,\n\tTestAttemptSession,\n\tTestAttemptSessionNavigationState,\n\tTestAttemptSessionRealization,\n} from \"./attempt/TestSession.js\";\nexport {\n\tcreateMemoryStorage,\n\tcreateTestAttemptSessionIdentifier,\n\tcreateNewTestAttemptSession,\n\tgetBrowserLocalStorage,\n\tgetOrCreateAnonymousDeviceId,\n\tgetTestAttemptSessionStorageKey,\n\tloadTestAttemptSession,\n\tsaveTestAttemptSession,\n\tsetCurrentPosition,\n\tupsertItemSessionFromPieSessionChange,\n\tupsertVisitedItem,\n} from \"./attempt/TestSession.js\";\nexport type {\n\tAssessmentSession,\n\tAssessmentSectionSessionState,\n\tAssessmentSessionNavigationState,\n\tAssessmentSessionRealization,\n} from \"./attempt/AssessmentSession.js\";\nexport {\n\tcreateNewAssessmentSession,\n\tgetAssessmentSessionStorageKey,\n\tloadAssessmentSession,\n\tsaveAssessmentSession,\n\tsetCurrentSectionPosition,\n\tupsertSectionSession,\n} from \"./attempt/AssessmentSession.js\";\nexport type {\n\tActivitySessionPatchPayload,\n\tMapActivityToTestAttemptSessionArgs,\n\tPieBackendActivityDefinition,\n\tPieBackendActivityItemRef,\n\tPieBackendActivitySession,\n} from \"./attempt/adapters/activity-to-test-attempt-session.js\";\nexport {\n\tbuildActivitySessionItemUpdate,\n\tbuildActivitySessionPatchFromTestAttemptSession,\n\tmapActivityToTestAttemptSession,\n\ttoItemSessionsRecord,\n} from \"./attempt/adapters/activity-to-test-attempt-session.js\";\n\n// Section Player - Use @pie-players/pie-section-player web component\n\n// ============================================================================\n// Shared Components\n// ============================================================================\n\n// ItemToolBar custom element registration helper is exported via package.json exports field\n// Import using: import '@pie-players/pie-assessment-toolkit/components/item-toolbar-element';\n// PieAssessmentToolkit custom element registration helper is exported via package.json exports field\n"]}
@@ -59,6 +59,7 @@ export declare class TTSService {
59
59
  private lastError;
60
60
  private speakRunId;
61
61
  private currentBoundaryOffset;
62
+ private activeWordBoundaryOffset;
62
63
  private seekSegments;
63
64
  private sentenceHighlightSegments;
64
65
  private currentSeekSegmentIndex;
@@ -197,6 +198,9 @@ export declare class TTSService {
197
198
  * Resume playback
198
199
  */
199
200
  resume(): void;
201
+ private normalizePlaybackRate;
202
+ private restartFromSeekIndex;
203
+ setPlaybackRate(rate: number): Promise<void>;
200
204
  private seekBy;
201
205
  seekForward(units?: number): Promise<void>;
202
206
  seekBackward(units?: number): Promise<void>;
@@ -84,6 +84,7 @@ export class TTSService {
84
84
  lastError = null;
85
85
  speakRunId = 0;
86
86
  currentBoundaryOffset = 0;
87
+ activeWordBoundaryOffset = 0;
87
88
  seekSegments = [];
88
89
  sentenceHighlightSegments = [];
89
90
  currentSeekSegmentIndex = 0;
@@ -577,11 +578,11 @@ export class TTSService {
577
578
  this.currentBoundaryOffset = 0;
578
579
  const originalOnWordBoundary = this.provider.onWordBoundary;
579
580
  this.provider.onWordBoundary = (word, position, length) => {
581
+ originalOnWordBoundary?.(word, position, length);
580
582
  if (Number.isFinite(position)) {
581
583
  this.currentBoundaryOffset = position;
582
584
  this.currentSeekSegmentIndex = this.getCurrentSeekSegmentIndex();
583
585
  }
584
- originalOnWordBoundary?.(word, position, length);
585
586
  };
586
587
  try {
587
588
  await providerWithPlan.speakSegments(segments);
@@ -593,6 +594,10 @@ export class TTSService {
593
594
  }
594
595
  return;
595
596
  }
597
+ this.configureWordBoundaryHighlighting({
598
+ highlightMode: options?.highlightMode || "word",
599
+ wordBoundaryOffset: this.activeWordBoundaryOffset,
600
+ });
596
601
  for (const segment of segments) {
597
602
  if (runId !== this.speakRunId)
598
603
  return;
@@ -732,6 +737,7 @@ export class TTSService {
732
737
  const highlightMode = options?.highlightModeOverride ||
733
738
  (speechMatchesVisibleText ? this.resolveHighlightMode() : "sentence");
734
739
  this.activeHighlightMode = highlightMode;
740
+ this.activeWordBoundaryOffset = options?.wordBoundaryOffset || 0;
735
741
  const hasExplicitBreaks = this.hasExplicitBreakSemantics(contentToSpeak);
736
742
  const shouldUsePlan = !!this.currentContentElement &&
737
743
  !usedCatalogSpoken &&
@@ -1438,6 +1444,7 @@ export class TTSService {
1438
1444
  this.currentContentElement = null;
1439
1445
  this.normalizedToDOM.clear();
1440
1446
  this.currentBoundaryOffset = 0;
1447
+ this.activeWordBoundaryOffset = 0;
1441
1448
  this.seekSegments = [];
1442
1449
  this.sentenceHighlightSegments = [];
1443
1450
  this.currentSeekSegmentIndex = 0;
@@ -1514,32 +1521,27 @@ export class TTSService {
1514
1521
  this.setState(PlaybackState.PLAYING);
1515
1522
  }
1516
1523
  }
1517
- async seekBy(units) {
1518
- if (!this.provider || !this.currentText)
1519
- return;
1520
- if (this.state !== PlaybackState.PLAYING &&
1521
- this.state !== PlaybackState.PAUSED) {
1522
- return;
1523
- }
1524
- if (this.hasExplicitBreakSemantics(this.currentText))
1525
- return;
1526
- if (this.seekSegments.length === 0)
1527
- return;
1528
- const delta = Number.isFinite(units) ? Math.trunc(units) : 0;
1529
- if (delta === 0)
1530
- return;
1531
- const currentIndex = this.getCurrentSeekSegmentIndex();
1532
- const targetIndex = Math.max(0, Math.min(this.seekSegments.length - 1, currentIndex + delta));
1533
- if (targetIndex === currentIndex)
1524
+ normalizePlaybackRate(rate) {
1525
+ if (!Number.isFinite(rate))
1526
+ return 1;
1527
+ return Math.max(0.25, Math.min(4, rate));
1528
+ }
1529
+ async restartFromSeekIndex(targetIndex) {
1530
+ if (!this.provider || this.seekSegments.length === 0)
1534
1531
  return;
1532
+ const safeTargetIndex = Math.max(0, Math.min(this.seekSegments.length - 1, targetIndex));
1535
1533
  this.speakRunId += 1;
1536
1534
  this.provider.onWordBoundary = undefined;
1537
1535
  this.provider.stop();
1538
- this.currentSeekSegmentIndex = targetIndex;
1536
+ this.currentSeekSegmentIndex = safeTargetIndex;
1539
1537
  const runId = ++this.speakRunId;
1540
- const restartSegments = this.seekSegments.slice(targetIndex);
1538
+ const restartSegments = this.seekSegments.slice(safeTargetIndex);
1541
1539
  this.setState(PlaybackState.PLAYING);
1542
1540
  try {
1541
+ this.configureWordBoundaryHighlighting({
1542
+ highlightMode: this.activeHighlightMode,
1543
+ wordBoundaryOffset: this.activeWordBoundaryOffset,
1544
+ });
1543
1545
  await this.speakWithPlan(restartSegments, runId, {
1544
1546
  highlightMode: this.activeHighlightMode,
1545
1547
  });
@@ -1557,6 +1559,37 @@ export class TTSService {
1557
1559
  throw error;
1558
1560
  }
1559
1561
  }
1562
+ async setPlaybackRate(rate) {
1563
+ const nextRate = this.normalizePlaybackRate(rate);
1564
+ await this.updateSettings({ rate: nextRate });
1565
+ if (this.state !== PlaybackState.PLAYING ||
1566
+ !this.currentText ||
1567
+ this.seekSegments.length === 0 ||
1568
+ this.hasExplicitBreakSemantics(this.currentText)) {
1569
+ return;
1570
+ }
1571
+ await this.restartFromSeekIndex(this.getCurrentSeekSegmentIndex());
1572
+ }
1573
+ async seekBy(units) {
1574
+ if (!this.provider || !this.currentText)
1575
+ return;
1576
+ if (this.state !== PlaybackState.PLAYING &&
1577
+ this.state !== PlaybackState.PAUSED) {
1578
+ return;
1579
+ }
1580
+ if (this.hasExplicitBreakSemantics(this.currentText))
1581
+ return;
1582
+ if (this.seekSegments.length === 0)
1583
+ return;
1584
+ const delta = Number.isFinite(units) ? Math.trunc(units) : 0;
1585
+ if (delta === 0)
1586
+ return;
1587
+ const currentIndex = this.getCurrentSeekSegmentIndex();
1588
+ const targetIndex = Math.max(0, Math.min(this.seekSegments.length - 1, currentIndex + delta));
1589
+ if (targetIndex === currentIndex)
1590
+ return;
1591
+ await this.restartFromSeekIndex(targetIndex);
1592
+ }
1560
1593
  async seekForward(units = 1) {
1561
1594
  const step = Number.isFinite(units) ? Math.max(1, Math.trunc(units)) : 1;
1562
1595
  await this.seekBy(step);
@@ -1585,6 +1618,7 @@ export class TTSService {
1585
1618
  this.currentContentElement = null;
1586
1619
  this.normalizedToDOM.clear();
1587
1620
  this.currentBoundaryOffset = 0;
1621
+ this.activeWordBoundaryOffset = 0;
1588
1622
  this.seekSegments = [];
1589
1623
  this.sentenceHighlightSegments = [];
1590
1624
  this.currentSeekSegmentIndex = 0;