@pie-players/pie-assessment-toolkit 0.3.52 → 0.3.54

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.
@@ -10996,7 +10996,11 @@ var calculatorToolRegistration = {
10996
10996
  minWidth: 380,
10997
10997
  minHeight: 420,
10998
10998
  initialAlign: "bottom-right",
10999
- initialMargin: 16
10999
+ initialMargin: 16,
11000
+ content: {
11001
+ overflowY: "auto",
11002
+ preserveMinHeight: true
11003
+ }
11000
11004
  }
11001
11005
  }
11002
11006
  ],
@@ -11054,12 +11058,16 @@ var isServerBackend = (backend) => backend === "polly" || backend === "google" |
11054
11058
  var withDefault = (value, fallback2) => value === undefined ? fallback2 : value;
11055
11059
  var normalizeTTSLayoutMode = (value, fallback2 = "left-aligned") => typeof value === "string" && VALID_TTS_LAYOUT_MODES.has(value) ? value : fallback2;
11056
11060
  var DEFAULT_TTS_SPEED_OPTIONS = Object.freeze([0.8, 1.25]);
11057
- var normalizeSpeedRate = (entry) => {
11061
+ var DEFAULT_TTS_SPEED_CONTROL_OPTIONS = Object.freeze([
11062
+ { rate: 0.8, label: "Slow", ariaLabel: "Slow speed" },
11063
+ { rate: 1, label: "Normal", ariaLabel: "Normal speed", default: true },
11064
+ { rate: 1.25, label: "Fast", ariaLabel: "Fast speed" }
11065
+ ]);
11066
+ var normalizeControlSpeedRate = (entry) => {
11058
11067
  if (typeof entry !== "number" || !Number.isFinite(entry) || entry <= 0) {
11059
11068
  return;
11060
11069
  }
11061
- const rounded = Math.round(entry * 100) / 100;
11062
- return rounded === 1 ? undefined : rounded;
11070
+ return Math.round(entry * 100) / 100;
11063
11071
  };
11064
11072
  var trimOptionalText = (value) => {
11065
11073
  if (typeof value !== "string")
@@ -11068,7 +11076,7 @@ var trimOptionalText = (value) => {
11068
11076
  return trimmed.length ? trimmed : undefined;
11069
11077
  };
11070
11078
  var formatSpeedLabel = (rate) => `${rate}x`;
11071
- var formatSpeedAriaLabel = (label, usedDefaultLabel) => usedDefaultLabel ? `Speed ${label}` : `${label} speed`;
11079
+ var formatSpeedAriaLabel = (label, usedDefaultLabel) => label.toLowerCase() === "normal" ? "Normal speed" : usedDefaultLabel ? `Speed ${label}` : `${label} speed`;
11072
11080
  var normalizeSpeedAriaLabel = (label, ariaLabel, usedDefaultLabel) => {
11073
11081
  if (!ariaLabel)
11074
11082
  return formatSpeedAriaLabel(label, usedDefaultLabel);
@@ -11076,59 +11084,55 @@ var normalizeSpeedAriaLabel = (label, ariaLabel, usedDefaultLabel) => {
11076
11084
  return ariaLabel;
11077
11085
  return `${label} ${ariaLabel}`;
11078
11086
  };
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) => {
11097
- if (!Array.isArray(value))
11098
- return [...DEFAULT_TTS_SPEED_OPTIONS];
11099
- if (value.length === 0)
11087
+ var normalizeTTSSpeedControlOptions = (value) => {
11088
+ const input = Array.isArray(value) ? value : [...DEFAULT_TTS_SPEED_CONTROL_OPTIONS];
11089
+ if (input.length === 0)
11100
11090
  return [];
11101
11091
  const dedupedRates = new Set;
11102
11092
  const normalized = [];
11103
- for (const entry of value) {
11104
- const option = normalizeTTSSpeedOptionConfig(entry);
11105
- if (option === undefined)
11106
- continue;
11107
- const rate = typeof option === "number" ? option : option.rate;
11108
- if (dedupedRates.has(rate))
11093
+ for (const entry of input) {
11094
+ const record = toRecord(entry);
11095
+ const rate = typeof entry === "number" ? normalizeControlSpeedRate(entry) : normalizeControlSpeedRate(record.rate);
11096
+ if (rate === undefined || dedupedRates.has(rate))
11109
11097
  continue;
11110
11098
  dedupedRates.add(rate);
11111
- normalized.push(option);
11099
+ const defaultLabel = rate === 1 ? "Normal" : typeof entry === "number" ? formatSpeedLabel(rate) : formatSpeedLabel(rate);
11100
+ const label = typeof entry === "number" ? defaultLabel : trimOptionalText(record.label) || defaultLabel;
11101
+ const ariaLabel = typeof entry === "number" ? rate === 1 ? "Normal speed" : formatSpeedAriaLabel(label, true) : normalizeSpeedAriaLabel(label, trimOptionalText(record.ariaLabel), label === defaultLabel);
11102
+ normalized.push({
11103
+ rate,
11104
+ label,
11105
+ ariaLabel,
11106
+ isDefault: false,
11107
+ requestedDefault: record.default === true || record.isDefault === true
11108
+ });
11112
11109
  }
11113
- return normalized.length ? normalized : [...DEFAULT_TTS_SPEED_OPTIONS];
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)
11110
+ if (!normalized.length) {
11111
+ return normalizeTTSSpeedControlOptions(DEFAULT_TTS_SPEED_CONTROL_OPTIONS);
11112
+ }
11113
+ if (!dedupedRates.has(1)) {
11114
+ const normalOption = {
11115
+ rate: 1,
11116
+ label: "Normal",
11117
+ ariaLabel: "Normal speed",
11118
+ isDefault: false,
11119
+ requestedDefault: false
11122
11120
  };
11121
+ const firstFasterIndex = normalized.findIndex((option) => option.rate > 1);
11122
+ if (firstFasterIndex >= 0) {
11123
+ normalized.splice(firstFasterIndex, 0, normalOption);
11124
+ } else {
11125
+ normalized.push(normalOption);
11126
+ }
11123
11127
  }
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
- });
11128
+ const requestedDefaultIndex = normalized.findIndex((option) => option.requestedDefault);
11129
+ const defaultIndex = requestedDefaultIndex >= 0 ? requestedDefaultIndex : normalized.findIndex((option) => option.rate === 1);
11130
+ return normalized.map(({ requestedDefault: _requestedDefault, ...option }, index2) => ({
11131
+ ...option,
11132
+ isDefault: index2 === defaultIndex
11133
+ }));
11134
+ };
11135
+ var DEFAULT_TTS_SPEED_CONTROL_RATES = Object.freeze([0.8, 1, 1.25]);
11132
11136
  var applyRuntimeDefaults = (config) => {
11133
11137
  const withLayoutDefaults = {
11134
11138
  ...config,
@@ -11283,7 +11287,7 @@ var ttsToolRegistration = {
11283
11287
  settings.layoutMode = normalizeTTSLayoutMode(settings.layoutMode);
11284
11288
  }
11285
11289
  if (settings && "speedOptions" in settings) {
11286
- settings.speedOptions = normalizeTTSSpeedOptionConfigs(settings.speedOptions);
11290
+ settings.speedOptions = normalizeTTSSpeedControlOptions(settings.speedOptions);
11287
11291
  }
11288
11292
  const normalizedConfig = {
11289
11293
  ...config
@@ -11292,7 +11296,7 @@ var ttsToolRegistration = {
11292
11296
  normalizedConfig.layoutMode = normalizeTTSLayoutMode(normalizedConfig.layoutMode);
11293
11297
  }
11294
11298
  if ("speedOptions" in normalizedConfig) {
11295
- normalizedConfig.speedOptions = normalizeTTSSpeedOptionConfigs(normalizedConfig.speedOptions);
11299
+ normalizedConfig.speedOptions = normalizeTTSSpeedControlOptions(normalizedConfig.speedOptions);
11296
11300
  }
11297
11301
  if (settings) {
11298
11302
  normalizedConfig.settings = settings;
@@ -11345,6 +11349,7 @@ var ttsToolRegistration = {
11345
11349
  element2.setAttribute("size", resolveControlSize());
11346
11350
  element2.setAttribute("layout-mode", resolveLayoutMode());
11347
11351
  element2.speedOptions = resolveElementSpeedOptions();
11352
+ element2.showSingleSpeedOption = resolveRuntimeSettings().showSingleSpeedOption === true;
11348
11353
  return element2;
11349
11354
  };
11350
11355
  const hostLayout = resolveHostLayout();
@@ -11382,6 +11387,7 @@ var ttsToolRegistration = {
11382
11387
  element2.setAttribute("size", resolveControlSize());
11383
11388
  element2.setAttribute("layout-mode", resolveLayoutMode());
11384
11389
  element2.speedOptions = resolveElementSpeedOptions();
11390
+ element2.showSingleSpeedOption = resolveRuntimeSettings().showSingleSpeedOption === true;
11385
11391
  }
11386
11392
  };
11387
11393
  }
@@ -13576,6 +13582,38 @@ function ItemToolBar($$anchor, $$props) {
13576
13582
  shellEl.style.overflowY = "visible";
13577
13583
  }
13578
13584
  };
13585
+ const getContentOverflowY = () => currentArgs.mounted.entry.shell?.content?.overflowY === "auto" ? "auto" : "hidden";
13586
+ const getHeaderHeight = () => {
13587
+ if (!headerEl)
13588
+ return 0;
13589
+ const rectHeight = headerEl.getBoundingClientRect().height;
13590
+ if (rectHeight > 0)
13591
+ return rectHeight;
13592
+ return headerEl.offsetHeight || 0;
13593
+ };
13594
+ const applyContentLayout = () => {
13595
+ if (!contentEl)
13596
+ return;
13597
+ const shellConfig = currentArgs.mounted.entry.shell;
13598
+ contentEl.style.overflowX = "hidden";
13599
+ contentEl.style.overflowY = getContentOverflowY();
13600
+ if (!mountedContentElement)
13601
+ return;
13602
+ if (shellConfig?.content?.preserveMinHeight === true) {
13603
+ const headerHeight = getHeaderHeight();
13604
+ const shellMinHeight = shellConfig.minHeight ?? 240;
13605
+ const contentMinHeight = Math.max(0, shellMinHeight - headerHeight);
13606
+ const availableHeight = Math.max(0, height - headerHeight);
13607
+ const elementHeight = Math.max(availableHeight, contentMinHeight);
13608
+ mountedContentElement.style.height = `${elementHeight}px`;
13609
+ mountedContentElement.style.minHeight = "0";
13610
+ mountedContentElement.style.flex = `0 0 ${elementHeight}px`;
13611
+ return;
13612
+ }
13613
+ mountedContentElement.style.height = "100%";
13614
+ mountedContentElement.style.minHeight = "0";
13615
+ mountedContentElement.style.flex = "1 1 auto";
13616
+ };
13579
13617
  const applyPositionAndSize = () => {
13580
13618
  const { minWidth, minHeight, maxWidth, maxHeight } = getShellBounds();
13581
13619
  const effectiveMinWidth = Math.min(minWidth, window.innerWidth);
@@ -13586,6 +13624,7 @@ function ItemToolBar($$anchor, $$props) {
13586
13624
  y2 = clamp(y2, 0, Math.max(0, window.innerHeight - height));
13587
13625
  applyShellStyle();
13588
13626
  applyContentMinWidth();
13627
+ applyContentLayout();
13589
13628
  notifyHostedResize();
13590
13629
  };
13591
13630
  const moveBy = (dx, dy) => {
@@ -13686,7 +13725,6 @@ function ItemToolBar($$anchor, $$props) {
13686
13725
  element2.style.height = "100%";
13687
13726
  element2.style.flex = "1 1 auto";
13688
13727
  element2.style.minHeight = "0";
13689
- applyContentMinWidth();
13690
13728
  if (mountedContentElement && mountedContentElement !== element2) {
13691
13729
  if (mountedContentElement.parentNode === contentEl) {
13692
13730
  invokeElementUnmount(mountedContentElement);
@@ -13701,6 +13739,8 @@ function ItemToolBar($$anchor, $$props) {
13701
13739
  contentEl.appendChild(element2);
13702
13740
  }
13703
13741
  mountedContentElement = element2;
13742
+ applyContentMinWidth();
13743
+ applyContentLayout();
13704
13744
  notifyHostedMount(element2);
13705
13745
  };
13706
13746
  const bringToFront = () => {
@@ -13970,6 +14010,7 @@ function ItemToolBar($$anchor, $$props) {
13970
14010
  }
13971
14011
  applyShellStyle();
13972
14012
  applyContentMinWidth();
14013
+ applyContentLayout();
13973
14014
  notifyHostedResize();
13974
14015
  }
13975
14016
  };
@@ -14182,7 +14223,8 @@ function ItemToolBar($$anchor, $$props) {
14182
14223
  contentEl.style.width = "100%";
14183
14224
  contentEl.style.flex = "1 1 auto";
14184
14225
  contentEl.style.minHeight = "0";
14185
- contentEl.style.overflow = "hidden";
14226
+ contentEl.style.overflowX = "hidden";
14227
+ contentEl.style.overflowY = getContentOverflowY();
14186
14228
  contentEl.style.borderRadius = "0 0 12px 12px";
14187
14229
  if (isCalculatorShell) {
14188
14230
  const makeFocusGuard = (label) => {
@@ -14300,8 +14342,8 @@ function ItemToolBar($$anchor, $$props) {
14300
14342
  titleEl.textContent = currentArgs.mounted.entry.shell?.title || currentArgs.mounted.toolId;
14301
14343
  const closeButtonOpenDisplay = currentArgs.mounted.toolId === "calculator" ? "inline-block" : "inline-flex";
14302
14344
  closeButtonEl.style.display = currentArgs.mounted.entry.shell?.closeable === false ? "none" : closeButtonOpenDisplay;
14303
- mountContent();
14304
14345
  applyShellStyle();
14346
+ mountContent();
14305
14347
  notifyHostedResize();
14306
14348
  if (!previousActive && currentArgs.active) {
14307
14349
  installFocusTrap();
package/dist/index.d.ts CHANGED
@@ -23,7 +23,7 @@ export type { SerializedRange } from "./services/RangeSerializer.js";
23
23
  export { RangeSerializer } from "./services/RangeSerializer.js";
24
24
  export type { I18nConfig, PluralTranslation, TranslationBundle, } from "./services/I18nService.js";
25
25
  export { I18nService } from "./services/I18nService.js";
26
- export type { ResolvedToolContext, ToolbarContext, ToolContextResolver, ToolContextResolverContext, ToolContextResolverMap, ToolContextResolverResult, ToolModuleLoader, ToolToolbarButtonDefinition, ToolToolbarRenderResult, ToolRegistration, } from "./services/ToolRegistry.js";
26
+ export type { ResolvedToolContext, ToolbarContext, ToolContextResolver, ToolContextResolverContext, ToolContextResolverMap, ToolContextResolverResult, ToolModuleLoader, ToolToolbarButtonDefinition, ToolToolbarRenderResult, ToolWindowShellAction, ToolWindowShellAlign, ToolWindowShellConfig, ToolWindowShellContentConfig, ToolRegistration, } from "./services/ToolRegistry.js";
27
27
  export { ToolRegistry } from "./services/ToolRegistry.js";
28
28
  export type { AssessmentToolContext, BaseToolContext, ElementToolContext, ItemToolContext, PassageToolContext, RubricToolContext, SectionToolContext, ToolContext, ToolLevel, } from "./services/tool-context.js";
29
29
  export { extractTextContent, hasChoiceInteraction, hasMathContent, hasReadableText, isAssessmentContext, isElementContext, isItemContext, isPassageContext, isRubricContext, isSectionContext, } from "./services/tool-context.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 type {\n\tTTSHighlightContext,\n\tTTSHighlightTargetResolver,\n\tTTSHighlightTargetResolverProvider,\n\tTTSHighlightTargetResolverRuntime,\n} from \"./services/tts/highlight-target-resolver.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\tSECTION_PLAYER_PREFERRED_TOOL_PLACEMENT,\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"]}
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 type {\n\tTTSHighlightContext,\n\tTTSHighlightTargetResolver,\n\tTTSHighlightTargetResolverProvider,\n\tTTSHighlightTargetResolverRuntime,\n} from \"./services/tts/highlight-target-resolver.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\tToolWindowShellAction,\n\tToolWindowShellAlign,\n\tToolWindowShellConfig,\n\tToolWindowShellContentConfig,\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\tSECTION_PLAYER_PREFERRED_TOOL_PLACEMENT,\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"]}
@@ -63,6 +63,7 @@ export declare class TTSService {
63
63
  private currentBoundaryOffset;
64
64
  private activeWordBoundaryOffset;
65
65
  private seekSegments;
66
+ private playbackChunks;
66
67
  private sentenceHighlightSegments;
67
68
  private currentSeekSegmentIndex;
68
69
  private activeSentenceStartOffset;
@@ -142,6 +143,7 @@ export declare class TTSService {
142
143
  private createSeekSegmentsFromText;
143
144
  private splitSegmentsAtBoundaries;
144
145
  private createSentenceHighlightSegments;
146
+ private createSeekSegmentsFromSpeechChunks;
145
147
  private getCurrentSeekSegmentIndex;
146
148
  private speakWithPlan;
147
149
  private highlightSentenceSegment;
@@ -87,6 +87,7 @@ export class TTSService {
87
87
  currentBoundaryOffset = 0;
88
88
  activeWordBoundaryOffset = 0;
89
89
  seekSegments = [];
90
+ playbackChunks = [];
90
91
  sentenceHighlightSegments = [];
91
92
  currentSeekSegmentIndex = 0;
92
93
  activeSentenceStartOffset = null;
@@ -705,6 +706,24 @@ export class TTSService {
705
706
  .filter((offset) => offset > 0);
706
707
  return this.splitSegmentsAtBoundaries(grammaticalSegments, structuralBoundaries, args.contentToSpeak);
707
708
  }
709
+ createSeekSegmentsFromSpeechChunks(chunks) {
710
+ let offset = 0;
711
+ return chunks.map((chunk) => {
712
+ const speechText = chunk.plainFallback?.speechText ||
713
+ (this.hasExplicitBreakSemantics(chunk.speechText)
714
+ ? chunk.visibleText
715
+ : chunk.speechText) ||
716
+ chunk.visibleText;
717
+ const text = normalizeTextForSpeech(speechText) || chunk.visibleText || "";
718
+ const segment = {
719
+ text,
720
+ startOffset: offset,
721
+ pauseMsAfter: 0,
722
+ };
723
+ offset += Math.max(1, text.length + 1);
724
+ return segment;
725
+ });
726
+ }
708
727
  getCurrentSeekSegmentIndex() {
709
728
  if (this.seekSegments.length === 0)
710
729
  return 0;
@@ -894,8 +913,10 @@ export class TTSService {
894
913
  !usedCatalogSpoken &&
895
914
  !hasExplicitBreaks &&
896
915
  speechMatchesVisibleText;
897
- this.seekSegments =
898
- hasExplicitBreaks || !speechMatchesVisibleText
916
+ this.playbackChunks = speechChunks?.length ? speechChunks : [];
917
+ this.seekSegments = this.playbackChunks.length
918
+ ? this.createSeekSegmentsFromSpeechChunks(this.playbackChunks)
919
+ : hasExplicitBreaks || !speechMatchesVisibleText
899
920
  ? []
900
921
  : shouldUsePlan && this.currentContentElement
901
922
  ? this.createSpeechPlan(this.currentContentElement, normalizedText)
@@ -1306,6 +1327,7 @@ export class TTSService {
1306
1327
  this.currentContentElement = options?.contentElement || null;
1307
1328
  this.lastError = null;
1308
1329
  this.currentBoundaryOffset = 0;
1330
+ this.playbackChunks = [];
1309
1331
  this.currentSeekSegmentIndex = 0;
1310
1332
  this.activeSentenceStartOffset = null;
1311
1333
  }
@@ -1579,9 +1601,15 @@ export class TTSService {
1579
1601
  }
1580
1602
  async executeSpeakPlayback(args) {
1581
1603
  if (args.speechChunks?.length && this.provider) {
1582
- for (const chunk of args.speechChunks) {
1604
+ for (let index = 0; index < args.speechChunks.length; index++) {
1583
1605
  if (args.runId !== this.speakRunId)
1584
1606
  return;
1607
+ this.currentSeekSegmentIndex = index;
1608
+ const segment = this.seekSegments[index];
1609
+ if (segment) {
1610
+ this.currentBoundaryOffset = segment.startOffset;
1611
+ }
1612
+ const chunk = args.speechChunks[index];
1585
1613
  await this.speakCatalogChunk(chunk, args.runId);
1586
1614
  }
1587
1615
  return;
@@ -1612,6 +1640,7 @@ export class TTSService {
1612
1640
  this.currentBoundaryOffset = 0;
1613
1641
  this.activeWordBoundaryOffset = 0;
1614
1642
  this.seekSegments = [];
1643
+ this.playbackChunks = [];
1615
1644
  this.sentenceHighlightSegments = [];
1616
1645
  this.currentSeekSegmentIndex = 0;
1617
1646
  this.activeSentenceStartOffset = null;
@@ -1696,6 +1725,9 @@ export class TTSService {
1696
1725
  if (!this.provider || this.seekSegments.length === 0)
1697
1726
  return;
1698
1727
  const safeTargetIndex = Math.max(0, Math.min(this.seekSegments.length - 1, targetIndex));
1728
+ const restartChunks = this.playbackChunks.length
1729
+ ? this.playbackChunks.slice(safeTargetIndex)
1730
+ : null;
1699
1731
  this.speakRunId += 1;
1700
1732
  this.provider.onWordBoundary = undefined;
1701
1733
  this.provider.stop();
@@ -1708,9 +1740,24 @@ export class TTSService {
1708
1740
  highlightMode: this.activeHighlightMode,
1709
1741
  wordBoundaryOffset: this.activeWordBoundaryOffset,
1710
1742
  });
1711
- await this.speakWithPlan(restartSegments, runId, {
1712
- highlightMode: this.activeHighlightMode,
1713
- });
1743
+ if (restartChunks) {
1744
+ for (let index = 0; index < restartChunks.length; index++) {
1745
+ if (runId !== this.speakRunId)
1746
+ return;
1747
+ const absoluteIndex = safeTargetIndex + index;
1748
+ this.currentSeekSegmentIndex = absoluteIndex;
1749
+ const segment = this.seekSegments[absoluteIndex];
1750
+ if (segment) {
1751
+ this.currentBoundaryOffset = segment.startOffset;
1752
+ }
1753
+ await this.speakCatalogChunk(restartChunks[index], runId);
1754
+ }
1755
+ }
1756
+ else {
1757
+ await this.speakWithPlan(restartSegments, runId, {
1758
+ highlightMode: this.activeHighlightMode,
1759
+ });
1760
+ }
1714
1761
  if (runId !== this.speakRunId)
1715
1762
  return;
1716
1763
  this.setState(PlaybackState.IDLE);
@@ -1789,6 +1836,7 @@ export class TTSService {
1789
1836
  this.currentBoundaryOffset = 0;
1790
1837
  this.activeWordBoundaryOffset = 0;
1791
1838
  this.seekSegments = [];
1839
+ this.playbackChunks = [];
1792
1840
  this.sentenceHighlightSegments = [];
1793
1841
  this.currentSeekSegmentIndex = 0;
1794
1842
  this.activeSentenceStartOffset = null;