@pie-players/pie-players-shared 1.0.0-beta.0 → 1.0.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +18 -17
  3. package/dist/THIRD-PARTY-LICENSES.txt +51 -0
  4. package/dist/components/vendor/nds/README.md +43 -5
  5. package/dist/components/vendor/nds/nds-icon-button.d.ts +2 -2
  6. package/dist/components/vendor/nds/nds-icon-button.js +2 -2
  7. package/dist/i18n/catalogs.d.ts +25 -13
  8. package/dist/i18n/catalogs.js +30 -22
  9. package/dist/i18n/content-language.d.ts +77 -0
  10. package/dist/i18n/content-language.js +129 -0
  11. package/dist/i18n/index.d.ts +7 -2
  12. package/dist/i18n/index.js +5 -2
  13. package/dist/i18n/language-tags.d.ts +3 -55
  14. package/dist/i18n/language-tags.js +3 -90
  15. package/dist/i18n/locale-load-error.d.ts +35 -0
  16. package/dist/i18n/locale-load-error.js +30 -0
  17. package/dist/i18n/messages/en-US.d.ts +151 -7
  18. package/dist/i18n/messages/en-US.js +168 -7
  19. package/dist/i18n/provider.d.ts +122 -18
  20. package/dist/i18n/provider.js +315 -133
  21. package/dist/i18n/pseudo.d.ts +34 -0
  22. package/dist/i18n/pseudo.js +106 -0
  23. package/dist/i18n/types.d.ts +19 -3
  24. package/dist/index.d.ts +16 -20
  25. package/dist/index.js +19 -19
  26. package/dist/instrumentation/providers/CompositeInstrumentationProvider.js +2 -1
  27. package/dist/item-session-control/index.d.ts +16 -0
  28. package/dist/item-session-control/index.js +5 -0
  29. package/dist/{formative → item-session-control}/mastery.d.ts +5 -5
  30. package/dist/{formative → item-session-control}/mastery.js +3 -3
  31. package/dist/{formative → item-session-control}/outcome.d.ts +3 -3
  32. package/dist/{formative → item-session-control}/outcome.js +2 -2
  33. package/dist/{formative → item-session-control}/policy.d.ts +11 -11
  34. package/dist/{formative → item-session-control}/policy.js +12 -12
  35. package/dist/item-session-control/session.d.ts +19 -0
  36. package/dist/{formative → item-session-control}/session.js +12 -12
  37. package/dist/{formative → item-session-control}/state.d.ts +26 -26
  38. package/dist/{formative → item-session-control}/state.js +13 -13
  39. package/dist/{formative → item-session-control}/types.d.ts +38 -40
  40. package/dist/{formative → item-session-control}/types.js +2 -2
  41. package/dist/loaders/ElementLoader.d.ts +1 -1
  42. package/dist/loaders/element-loader.d.ts +4 -1
  43. package/dist/loaders/element-loader.js +74 -21
  44. package/dist/loaders/element-package-spec.d.ts +16 -0
  45. package/dist/loaders/element-package-spec.js +30 -0
  46. package/dist/loaders/esm-adapter.d.ts +12 -1
  47. package/dist/loaders/esm-adapter.js +113 -19
  48. package/dist/loaders/iife-adapter.d.ts +7 -0
  49. package/dist/loaders/iife-adapter.js +1 -1
  50. package/dist/loaders/index.d.ts +2 -1
  51. package/dist/loaders/index.js +2 -1
  52. package/dist/loaders/preloaded-registration.d.ts +18 -6
  53. package/dist/loaders/preloaded-registration.js +44 -9
  54. package/dist/object/index.d.ts +4 -1
  55. package/dist/object/index.js +8 -1
  56. package/dist/pie/config.d.ts +8 -0
  57. package/dist/pie/config.js +32 -1
  58. package/dist/pie/index.d.ts +2 -0
  59. package/dist/pie/index.js +1 -0
  60. package/dist/pie/math-rendering.d.ts +13 -1
  61. package/dist/pie/math-rendering.js +54 -1
  62. package/dist/pie/updates.d.ts +4 -1
  63. package/dist/pie/updates.js +21 -5
  64. package/dist/pie/versioned-tag.d.ts +10 -0
  65. package/dist/pie/versioned-tag.js +27 -0
  66. package/dist/promise/index.d.ts +10 -0
  67. package/dist/promise/index.js +16 -0
  68. package/dist/security/overwide-regions.js +65 -0
  69. package/dist/security/private-hosts.d.ts +27 -0
  70. package/dist/security/private-hosts.js +85 -0
  71. package/dist/security/validate-style-url.js +2 -2
  72. package/dist/security/wrap-overwide-images.d.ts +6 -2
  73. package/dist/security/wrap-overwide-images.js +5 -2
  74. package/dist/security/wrap-overwide-tables.d.ts +6 -2
  75. package/dist/security/wrap-overwide-tables.js +5 -2
  76. package/dist/security/wrap-overwide.d.ts +13 -0
  77. package/dist/security/wrap-overwide.js +68 -3
  78. package/dist/timed-media/index.d.ts +1 -1
  79. package/dist/timed-media/index.js +1 -1
  80. package/dist/timed-media/policy.d.ts +2 -2
  81. package/dist/timed-media/policy.js +2 -2
  82. package/dist/timed-media/session.d.ts +1 -1
  83. package/dist/timed-media/session.js +1 -1
  84. package/dist/timed-media/types.d.ts +11 -11
  85. package/dist/tools/term-lookup.d.ts +15 -0
  86. package/dist/tools/term-lookup.js +16 -0
  87. package/dist/types/index.d.ts +127 -47
  88. package/dist/types/interchange.d.ts +116 -0
  89. package/dist/types/interchange.js +1 -0
  90. package/dist/ui/content-styles-entry.d.ts +1 -0
  91. package/dist/ui/content-styles-entry.js +2 -0
  92. package/dist/ui/content-styles.d.ts +24 -3
  93. package/dist/ui/content-styles.js +114 -3
  94. package/dist/ui/focus-trap.d.ts +12 -0
  95. package/dist/ui/focus-trap.js +41 -1
  96. package/dist/ui/fontawesome.d.ts +51 -0
  97. package/dist/ui/fontawesome.js +122 -0
  98. package/dist/ui/ime.d.ts +6 -0
  99. package/dist/ui/ime.js +10 -0
  100. package/dist/ui/overlay-containment.d.ts +13 -0
  101. package/dist/ui/overlay-containment.js +23 -0
  102. package/dist/ui/overlay-placement.d.ts +28 -0
  103. package/dist/ui/overlay-placement.js +17 -2
  104. package/package.json +72 -36
  105. package/dist/formative/index.d.ts +0 -16
  106. package/dist/formative/index.js +0 -5
  107. package/dist/formative/session.d.ts +0 -19
  108. package/dist/i18n/messages/nl-NL.d.ts +0 -529
  109. package/dist/i18n/messages/nl-NL.js +0 -529
  110. package/dist/instrumentation/new-relic-agent.d.ts +0 -20
  111. package/dist/loaders/module-shim.d.ts +0 -12
  112. package/dist/pie/authoring-tag.d.ts +0 -6
  113. package/dist/pie/configure-initialization.d.ts +0 -21
  114. package/dist/pie/correct-response-env.d.ts +0 -3
  115. package/dist/pie/element-announcements.d.ts +0 -39
  116. package/dist/pie/elements-rendered.d.ts +0 -23
  117. package/dist/pie/initialize-element.d.ts +0 -26
  118. package/dist/pie/markup-math.d.ts +0 -20
  119. package/dist/pie/resource-monitor.d.ts +0 -217
  120. package/dist/security/sanitize-forbidden-lists.d.ts +0 -8
  121. package/dist/ui/pointer-rotate.d.ts +0 -29
  122. package/dist/ui/safe-storage.d.ts +0 -2
@@ -57,6 +57,8 @@ const enUS = {
57
57
  apply: "Apply",
58
58
  enabled: "Enabled",
59
59
  disabled: "Disabled",
60
+ lookUp: "Look up",
61
+ wordOrPhrase: "Word or phrase",
60
62
  closeA11y: "Close",
61
63
  settingsA11y: "Open settings menu",
62
64
  },
@@ -89,6 +91,14 @@ const enUS = {
89
91
  resizeMediaRegion: "Resize media region",
90
92
  resizeQuestionAndMediaA11y: "Resize question and media panels",
91
93
  resizePassageAndMediaA11y: "Resize passage and media panels",
94
+ resizePassageAndQuestionA11y: "Resize passage and question panels",
95
+ passageWidthA11y: "{percent}% passage width",
96
+ /**
97
+ * The section player's navigation live region, announced when the active
98
+ * item changes; `{label}` is the item's own label when it has one.
99
+ */
100
+ questionPositionA11y: "Question {position} of {total}",
101
+ questionPositionLabeledA11y: "{label}, question {position} of {total}",
92
102
  /**
93
103
  * The assessment player's own section-to-section navigation. Its Back and
94
104
  * Next controls take `common.back` / `common.next`.
@@ -99,16 +109,16 @@ const enUS = {
99
109
  loadFailed: "The assessment could not be loaded. Try again.",
100
110
  restoreFailed: "Your saved answers for this section could not be restored. Try again.",
101
111
  },
102
- /** Formative delivery: check-answer control and its outcome announcements. */
103
- formative: {
104
- checkAnswer: "Check answer",
112
+ /** Item session control: check-answer control and its outcome announcements. */
113
+ check: {
114
+ answer: "Check answer",
105
115
  tryAgain: "Try again",
106
116
  answerRecorded: "Answer recorded.",
107
117
  correct: "Correct.",
108
118
  partlyCorrect: "Partly correct.",
109
119
  notCorrect: "Not correct.",
110
120
  notAutoScored: "Answer recorded. This question is not scored automatically.",
111
- checkFailed: "This question could not be checked. Try again.",
121
+ failed: "This question could not be checked. Try again.",
112
122
  /**
113
123
  * Appended after the outcome, so the announcement reads
114
124
  * "Not correct. 2 tries left." Kept a separate plural group rather than
@@ -139,6 +149,29 @@ const enUS = {
139
149
  playbackAdvisory: "Answer question {position} before continuing with the media.",
140
150
  playbackReleased: "Answer accepted. Continue playing the media.",
141
151
  },
152
+ /**
153
+ * `<pie-item-summary>`: an item described as a list row, without loading its
154
+ * elements. The correct marker's glyph is hidden from assistive technology,
155
+ * which reads `correctA11y` instead.
156
+ */
157
+ summary: {
158
+ correctA11y: "Correct answer",
159
+ answer: "Answer",
160
+ manualScoring: "Scored by a teacher",
161
+ audio: "Audio",
162
+ video: "Video",
163
+ },
164
+ /** `<pie-item-list>`. */
165
+ list: {
166
+ /** The row toggle, a disclosure button whose `aria-expanded` carries the state, so its label stays the same either way. */
167
+ expandA11y: "Show the full item",
168
+ /** Names the block of an entry's search matches below its summary. */
169
+ highlights: "Search matches",
170
+ /** The row toggle's tooltip while the row is expanded: collapsing returns it to the summary. */
171
+ collapse: "Show the summary",
172
+ /** Shown in an expanded row whose player failed to load; the summary keeps showing above it. */
173
+ playerError: "The full item could not be loaded.",
174
+ },
142
175
  },
143
176
  /** Toolbar and tool-shell chrome owned by the assessment toolkit. */
144
177
  toolkit: {
@@ -159,17 +192,20 @@ const enUS = {
159
192
  moveRightA11y: "Move tool right",
160
193
  moveUpA11y: "Move tool up",
161
194
  moveDownA11y: "Move tool down",
162
- shrinkA11y: "Shrink tool window",
163
- growA11y: "Grow tool window",
195
+ narrowerA11y: "Make tool window narrower",
196
+ widerA11y: "Make tool window wider",
197
+ shorterA11y: "Make tool window shorter",
198
+ tallerA11y: "Make tool window taller",
164
199
  centerA11y: "Center tool window",
165
200
  closeA11y: "Close tool",
166
201
  },
167
202
  /**
168
- * The tap controls that move and turn the ruler and protractor without a
203
+ * The tap controls that move, turn and resize a placed tool without a
169
204
  * drag. The move buttons reuse the `window` labels above.
170
205
  */
171
206
  placement: {
172
207
  controlsA11y: "Move and rotate",
208
+ moveAndResizeA11y: "Move and resize",
173
209
  rotateClockwiseA11y: "Rotate {degrees}° clockwise",
174
210
  rotateCounterclockwiseA11y: "Rotate {degrees}° counterclockwise",
175
211
  },
@@ -214,6 +250,7 @@ const enUS = {
214
250
  toolA11y: "Calculator tool",
215
251
  loading: "Loading calculator…",
216
252
  providerUnavailable: "The calculator is unavailable.",
253
+ initFailed: "Calculator failed to initialize.",
217
254
  },
218
255
  graph: {
219
256
  name: "Graph",
@@ -269,6 +306,12 @@ const enUS = {
269
306
  lanthanide: "Lanthanide",
270
307
  actinide: "Actinide",
271
308
  },
309
+ /** Standard-state phase, keyed by the data file's lowercased `phase` value. */
310
+ phaseValue: {
311
+ solid: "Solid",
312
+ liquid: "Liquid",
313
+ gas: "Gas",
314
+ },
272
315
  },
273
316
  ruler: {
274
317
  name: "Ruler",
@@ -313,6 +356,21 @@ const enUS = {
313
356
  buttonA11y: "Dictionary, look up word definitions",
314
357
  tooltip: "Dictionary",
315
358
  toolA11y: "Dictionary",
359
+ // The lookup panel's notices are authored whole: the term interpolates
360
+ // into the sentence, never around it.
361
+ notConfigured: "No dictionary service is configured for this assessment.",
362
+ idleHint: "Type a word to look it up.",
363
+ lookingUp: "Looking up “{term}”…",
364
+ noEntryFor: "No entry for “{term}”.",
365
+ // The polite live-region status after a lookup: the count summary and
366
+ // the no-entry announcement, phrased without the quotation marks the
367
+ // visible notices carry. The count calls plural(), never a `=== 1`
368
+ // branch.
369
+ entriesCount: {
370
+ one: "{count} entry",
371
+ other: "{count} entries",
372
+ },
373
+ noEntryStatusFor: "No dictionary entry for {term}.",
316
374
  },
317
375
  pictureDictionary: {
318
376
  name: "Picture Dictionary",
@@ -320,6 +378,15 @@ const enUS = {
320
378
  buttonA11y: "Picture Dictionary, look up pictures for words",
321
379
  tooltip: "Picture Dictionary",
322
380
  toolA11y: "Picture Dictionary",
381
+ notConfigured: "No picture dictionary service is configured for this assessment.",
382
+ idleHint: "Type a word to see a picture of it.",
383
+ lookingUp: "Looking up “{term}”…",
384
+ noEntryFor: "No picture for “{term}”.",
385
+ entriesCount: {
386
+ one: "{count} picture",
387
+ other: "{count} pictures",
388
+ },
389
+ noEntryStatusFor: "No picture for {term}.",
323
390
  },
324
391
  /**
325
392
  * The Spanish variants. Named in the interface locale like every other tool label —
@@ -352,15 +419,47 @@ const enUS = {
352
419
  windowHeightAnnounce: "Reading window height {pixels} pixels",
353
420
  frameHeightAnnounce: "Frame height {pixels} pixels",
354
421
  widthAnnounce: "Width {pixels} pixels",
422
+ shorterWindowA11y: "Make the reading window shorter",
423
+ tallerWindowA11y: "Make the reading window taller",
424
+ shorterFrameA11y: "Make the frame shorter",
425
+ tallerFrameA11y: "Make the frame taller",
426
+ narrowerA11y: "Make the line reader narrower",
427
+ widerA11y: "Make the line reader wider",
355
428
  applicationA11y: "Line Reader tool. A clear reading window inside an obscuring frame. Use arrow keys to move, +/- to resize the reading window, Escape to close. Reading window height: {paneHeight} pixels, Frame height: {frameHeight} pixels",
356
429
  resizeWindowFullA11y: "Resize the reading window. Drag, or use the up and down arrow keys to change its height. Current height {paneHeight} pixels",
357
430
  resizeFrameFullA11y: "Resize the frame. Drag, or use the up and down arrow keys to change the frame height and the left and right arrow keys to change the width. Current frame height {frameHeight} pixels, width {width} pixels",
358
431
  },
432
+ magnification: {
433
+ name: "Magnifier",
434
+ description: "Magnify the content under a movable lens",
435
+ buttonA11y: "Magnifier, enlarge the content under a lens",
436
+ tooltip: "Magnifier",
437
+ roleA11y: "Draggable and resizable magnifying lens",
438
+ applicationA11y: "Magnifier at {zoom} times. Use the arrow keys to move the lens, + and - to change the zoom, and Escape to close.",
439
+ zoomIn: "Zoom in",
440
+ zoomOut: "Zoom out",
441
+ zoomLevel: "{zoom}×",
442
+ zoomAnnounce: "Zoom {zoom} times",
443
+ close: "Close magnifier",
444
+ resizeA11y: "Drag to resize the magnifier",
445
+ resizeFullA11y: "Resize the magnifier. Drag, or use the arrow keys. Current size {width} by {height} pixels",
446
+ sizeAnnounce: "Magnifier {width} by {height} pixels",
447
+ narrowerA11y: "Make the magnifier narrower",
448
+ widerA11y: "Make the magnifier wider",
449
+ shorterA11y: "Make the magnifier shorter",
450
+ tallerA11y: "Make the magnifier taller",
451
+ },
359
452
  answerEliminator: {
360
453
  name: "Answer Eliminator",
361
454
  description: "Strike through answer choices",
362
455
  buttonA11y: "Strike Through, eliminate answer choices",
363
456
  tooltip: "Strike Through",
457
+ /** A choice's toggle; `{choice}` is the choice's own accessible name. */
458
+ toggleA11y: "Toggle elimination for {choice}",
459
+ /** Appended to an eliminated choice's label for assistive technology. */
460
+ eliminatedA11y: "(eliminated)",
461
+ /** Stands in for `{choice}` when a choice has no text of its own. */
462
+ unlabeledChoice: "Unlabeled choice",
364
463
  },
365
464
  highlighter: {
366
465
  name: "Highlighter",
@@ -389,6 +488,19 @@ const enUS = {
389
488
  highlightPinkA11y: "Pink highlight",
390
489
  highlightBlueA11y: "Blue highlight",
391
490
  highlightGreenA11y: "Green highlight",
491
+ // Announced in the strip's live region. A colour is authored per phrase:
492
+ // a colour adjective agrees with its noun in some languages.
493
+ selectionAvailableA11y: "Annotation toolbar available for “{text}”. Press Shift+F10 for annotation tools.",
494
+ highlightedYellowA11y: "“{text}” highlighted in yellow",
495
+ highlightedPinkA11y: "“{text}” highlighted in pink",
496
+ highlightedBlueA11y: "“{text}” highlighted in blue",
497
+ highlightedGreenA11y: "“{text}” highlighted in green",
498
+ underlinedA11y: "“{text}” underlined",
499
+ removedA11y: "Removed annotation from “{text}”",
500
+ clearedA11y: {
501
+ one: "{count} annotation cleared",
502
+ other: "{count} annotations cleared",
503
+ },
392
504
  },
393
505
  theme: {
394
506
  name: "Theme",
@@ -512,6 +624,39 @@ const enUS = {
512
624
  toggleEventPanelA11y: "Toggle event broadcast panel",
513
625
  toggleDatabasePanelA11y: "Toggle database state panel",
514
626
  toggleInstrumentationPanelA11y: "Toggle instrumentation panel",
627
+ // Panel actions and status. "clear"/"pause"/"resume" stay lowercase in
628
+ // English to match the dev panels' chrome; locales render their own
629
+ // register.
630
+ clear: "clear",
631
+ pause: "pause",
632
+ resume: "resume",
633
+ controllerUnavailable: "controller unavailable",
634
+ noMatchingEvents: "No matching events yet. Interact with an item to capture controller events.",
635
+ noSectionSessionYet: "No section session data yet. Interact with the questions to see updates.",
636
+ eventLevelItem: "item",
637
+ eventLevelSection: "section",
638
+ // Instrumentation record-kind identifiers. They name the emitted
639
+ // records, so every locale carries them verbatim; a locale that
640
+ // prefers translated labels can override per key.
641
+ instrumentationKindAll: "all",
642
+ instrumentationKindEvent: "event",
643
+ instrumentationKindError: "error",
644
+ instrumentationKindMetric: "metric",
645
+ instrumentationKindUserContext: "user-context",
646
+ instrumentationKindGlobalAttributes: "global-attributes",
647
+ // Instrumentation detail-field labels.
648
+ instrumentationFieldName: "name:",
649
+ instrumentationFieldKind: "kind:",
650
+ instrumentationFieldProvider: "provider:",
651
+ instrumentationFieldTimestamp: "timestamp:",
652
+ instrumentationFieldValue: "value:",
653
+ instrumentationFieldError: "error:",
654
+ // Session-db payload field names — identifiers, verbatim across
655
+ // locales like the record kinds above.
656
+ sessionDbAssessmentId: "assessmentId:",
657
+ sessionDbSectionId: "sectionId:",
658
+ sessionDbAttemptId: "attemptId:",
659
+ sessionDbMode: "mode:",
515
660
  /** PNP debugger. */
516
661
  pnp: {
517
662
  title: "PNP Profile",
@@ -531,6 +676,12 @@ const enUS = {
531
676
  perToolDecisions: "Per-Tool Decisions",
532
677
  policyDiagnostics: "Policy Diagnostics",
533
678
  profileReadOnly: "PNP Profile (read-only)",
679
+ on: "On",
680
+ effective: "Effective:",
681
+ needs: "needs",
682
+ hostSurfaceNotPlaced: "host surface (not placed)",
683
+ support: "support",
684
+ prohibit: "prohibit",
534
685
  },
535
686
  /** TTS settings panel. */
536
687
  tts: {
@@ -628,6 +779,16 @@ const enUS = {
628
779
  previewHintGoogleSsml: "SSML preserved. Tracking disabled.",
629
780
  previewHintCustom: "Tracking enabled when provider returns speech marks.",
630
781
  previewHintTracking: "Tracking enabled while preview plays.",
782
+ formatMp3: "MP3",
783
+ formatOgg: "OGG",
784
+ formatPcm: "PCM",
785
+ sampleRate8000: "8000 Hz",
786
+ sampleRate16000: "16000 Hz",
787
+ sampleRate22050: "22050 Hz",
788
+ sampleRate24000: "24000 Hz",
789
+ apiEndpointPlaceholder: "/api/tts",
790
+ languagePlaceholder: "en-US",
791
+ ssml: "SSML",
631
792
  },
632
793
  },
633
794
  };
@@ -51,12 +51,20 @@ export declare function detectBrowserLocale(): string;
51
51
  export declare class SimpleI18n implements I18nServiceApi {
52
52
  /** Shared across instances and views: `Intl.PluralRules` is not cheap. */
53
53
  private static readonly pluralRules;
54
- private locale;
54
+ /** The latest request, canonical; what `getRequestedLocale` names. */
55
+ private requested;
56
+ /** The request whose strings are served; moves once its catalog is resident. */
57
+ private active;
58
+ /** The catalog serving `active`, resolved against catalogs alone. */
59
+ private activeCatalog;
55
60
  private readonly fallbackLocale;
56
61
  /** Shared by reference with every `withLocale` view. */
57
62
  private catalogs;
63
+ /** Keyed by normalized tag, so `ES`, `es_ES` and `es-es` reach one set. */
58
64
  private customMessages;
59
65
  private loading;
66
+ /** Counts `setLocale` calls, so a slow load cannot overwrite a later request. */
67
+ private requests;
60
68
  private readonly listeners;
61
69
  private config;
62
70
  constructor(config?: I18nConfig);
@@ -68,14 +76,30 @@ export declare class SimpleI18n implements I18nServiceApi {
68
76
  * {@link detectBrowserLocale}.
69
77
  */
70
78
  initialize(config: I18nConfig): Promise<void>;
79
+ /**
80
+ * The locale the strings are served in: the resolved catalog locale once
81
+ * resident, else the most specific host-message tag on the request's
82
+ * truncation chain, canonical, else the fallback. A request nothing serves
83
+ * names the fallback, so a chrome root stamped from it never names a
84
+ * language its text is not in.
85
+ */
71
86
  getLocale(): string;
87
+ /**
88
+ * The latest `setLocale` request (or the configured `locale`), canonical, as
89
+ * soon as it is made and whatever its load does. `getLocale` names what is
90
+ * served instead, so the two differ while a catalog loads, after a load
91
+ * fails, and for a tag nothing ships.
92
+ */
93
+ getRequestedLocale(): string;
72
94
  /**
73
95
  * Switch locale.
74
96
  *
75
97
  * Resolves the request against the catalogs this provider can serve, loads
76
98
  * the winner if it is not resident, then notifies subscribers — in that
77
99
  * order, so a component's reactive read re-runs against a catalog that is
78
- * already in place rather than against the previous locale.
100
+ * already in place rather than against the previous locale. The last call
101
+ * wins: a call whose load finishes after a later call's leaves the locale
102
+ * to that later call.
79
103
  */
80
104
  setLocale(locale: LocaleCode): Promise<void>;
81
105
  t(key: MessageKeyInput, values?: InterpolationValues): string;
@@ -84,8 +108,12 @@ export declare class SimpleI18n implements I18nServiceApi {
84
108
  *
85
109
  * The category comes from `Intl.PluralRules` for the active locale, so a
86
110
  * locale with more than two forms resolves correctly: Arabic selects among
87
- * zero/one/two/few/many/other, Polish among one/few/many/other. A category the
88
- * catalog does not carry resolves to `other`.
111
+ * zero/one/two/few/many/other, Polish among one/few/many/other.
112
+ *
113
+ * Each form resolves on its own, tier by tier (`resolveMessage`): a host
114
+ * overriding one category leaves the others to the catalog, and a locale's
115
+ * own `other` wins over the fallback's `one`. A group no source completes is
116
+ * a miss and returns the key.
89
117
  */
90
118
  plural(key: MessageKeyInput, options: PluralOptions): string;
91
119
  getDirection(): TextDirection;
@@ -101,9 +129,11 @@ export declare class SimpleI18n implements I18nServiceApi {
101
129
  * Add or override messages for one locale.
102
130
  *
103
131
  * Deep-merged, so a deployment can override a single label without restating
104
- * a catalog.
132
+ * a catalog, and keyed by normalized tag, so `es-mx` and `es-MX` are one
133
+ * locale's messages.
105
134
  */
106
135
  addCustomMessages(locale: string, messages: MessageCatalog): void;
136
+ private mergeCustomMessages;
107
137
  /**
108
138
  * A view of this provider fixed to another locale.
109
139
  *
@@ -118,21 +148,30 @@ export declare class SimpleI18n implements I18nServiceApi {
118
148
  /** The resolved catalog for a locale, for a host that wants to inspect it. */
119
149
  getBundle(locale?: LocaleCode): TranslationBundle | undefined;
120
150
  /**
121
- * Which shipped catalog serves a requested tag.
122
- *
123
- * RFC 4647 lookup first, so `nl-BE` reaches `nl-NL` through `nl`; then
124
- * primary-subtag widening, so a bare `nl` reaches the regional `nl-NL`
125
- * catalog we actually ship. POSIX `nl_NL` normalizes on the way in, which is
126
- * the form the Learnosity transform emits.
151
+ * Which catalog serves a requested tag, under `findClosestLanguageMatch`
152
+ * over the resident catalogs and the loader's declared tags. Host messages
153
+ * take no part: they resolve separately (`hostMessageLocale`), so a host
154
+ * override for `es-MX` cannot hide a shipped `es`.
127
155
  */
128
- private resolveLocaleTag;
156
+ private resolveCatalogLocale;
157
+ /** The most specific host-message tag on a request's truncation chain, normalized. */
158
+ private hostMessageLocale;
129
159
  private loadCatalog;
130
160
  /**
131
- * Resolution order for one key. Host overrides for the active locale win, so
132
- * a deployment can rename one label without forking a catalog.
161
+ * Two tiers in lookup order: host messages along the active request's
162
+ * truncation chain (`es-MX`, then `es`) and the active catalog, then host
163
+ * messages and the catalog for the fallback locale. Host overrides win, so a
164
+ * deployment can rename one label without forking a catalog.
133
165
  */
134
- private lookupNode;
135
- private lookup;
166
+ private sourceTiers;
167
+ /**
168
+ * The text for `key`. The first source that has it decides its shape: a
169
+ * string is the text, and a plural group resolves `category`, else `other`,
170
+ * within the first tier that has a group, so a locale's own `other` wins
171
+ * over the fallback's `one`. A namespace (`t("common")`) is a miss:
172
+ * returning the object would put one where the caller expects a string.
173
+ */
174
+ private resolveMessage;
136
175
  private selectPluralCategory;
137
176
  private notify;
138
177
  }
@@ -143,7 +182,7 @@ export declare class SimpleI18n implements I18nServiceApi {
143
182
  * present, and this is that state. A tool mounted bare — in `print-player` or
144
183
  * an authoring harness — resolves this and renders English rather than
145
184
  * leaking raw message keys onto the screen. It carries no locale loader, so it
146
- * pulls no catalog beyond the 5 KB English one already in the bundle.
185
+ * pulls no catalog beyond the English one already in the bundle.
147
186
  */
148
187
  export declare function getDefaultI18n(): I18nServiceApi;
149
188
  /**
@@ -169,6 +208,71 @@ export declare function getDefaultI18n(): I18nServiceApi;
169
208
  * default rather than nothing, which is the graceful default the pull pattern
170
209
  * requires.
171
210
  */
211
+ /** The rendering surface `resolveInterfaceI18n` promises. */
212
+ export interface ResolvedInterfaceI18n extends I18nProvider {
213
+ /** Locale-aware number formatting, at the resolved locale. */
214
+ formatNumber(value: number, options?: Intl.NumberFormatOptions): string;
215
+ /** Locale-aware date formatting, at the resolved locale. */
216
+ formatDate(date: Date, options?: Intl.DateTimeFormatOptions): string;
217
+ }
172
218
  export declare function resolveInterfaceI18n(source: {
173
219
  i18n?: I18nProvider;
174
- } | null | undefined): I18nProvider;
220
+ } | null | undefined): ResolvedInterfaceI18n;
221
+ /**
222
+ * Stamp the interface locale's `lang` and `dir` on a chrome element.
223
+ *
224
+ * The imperative form of the `lang={…} dir={…}` pair a template puts on its
225
+ * root, for the elements a template cannot reach: a shadow host whose chrome
226
+ * is slotted light DOM, a shell built with `document.createElement`, a vanilla
227
+ * element stamping itself. Call it from whatever already re-runs on a locale
228
+ * change and on a catalog load: `getLocale()` moves only once the requested
229
+ * catalog is resident, so a stamp taken at setup alone names the locale that
230
+ * rendered before the load.
231
+ */
232
+ export declare function stampInterfaceLocale(target: Element, provider: Pick<I18nProvider, "getLocale" | "getDirection">): void;
233
+ /**
234
+ * Whether `provider` was already asked for `locale`. An element handed its
235
+ * owner's provider together with the owner's `locale` skips asking again, so a
236
+ * catalog that fails to load is fetched and reported once, by the owner, and
237
+ * not again by every row and player under it.
238
+ */
239
+ export declare function isLocaleRequested(provider: Pick<I18nProvider, "getRequestedLocale">, locale: string): boolean;
240
+ /**
241
+ * Whether a host chose a player's interface locale: it set the player's
242
+ * `locale`, or supplied a provider that was asked for a locale other than
243
+ * `en-US`.
244
+ *
245
+ * A player answers `interfaceLocaleContext` from the first time this holds,
246
+ * and never before it. An element left unanswered labels its chrome in the
247
+ * language its item declares, which is how an item declaring Spanish keeps
248
+ * Spanish labels under a host that sets no locale; a default `en-US` answer
249
+ * would override that declaration. A supplied provider asked for `en-US` is
250
+ * not a choice, because hosts supply one to add catalogs or messages; a host
251
+ * that wants `en-US` chrome over the item's language sets `locale="en-US"`.
252
+ * Once answering, a player keeps answering, so clearing `locale` republishes
253
+ * `en-US` to the elements that subscribed.
254
+ *
255
+ * The toolkit and the item player both decide through this rule. An item
256
+ * player a section mounts receives the toolkit's provider, so it answers only
257
+ * when the toolkit above it would. Callers re-evaluate it on the provider's
258
+ * change signal, since a supplied provider's locale moves without a property
259
+ * change.
260
+ */
261
+ export declare function hostChoseInterfaceLocale(player: {
262
+ locale?: unknown;
263
+ i18n?: Pick<I18nProvider, "getLocale" | "getRequestedLocale"> | null;
264
+ }): boolean;
265
+ /**
266
+ * The tag a player answers `interfaceLocaleContext` with: its `locale`,
267
+ * canonical, from the moment it is set, else its provider's requested tag.
268
+ *
269
+ * The request rather than the players' own catalog match, because elements
270
+ * resolve the tag against their own catalogs: a host asking for `en-GB` or
271
+ * `fr-CA` reaches the elements' catalogs and host messages for that tag
272
+ * whatever the players ship, and neither a players' catalog still loading nor
273
+ * one that failed holds the elements on the previous locale.
274
+ */
275
+ export declare function requestedInterfaceLocale(player: {
276
+ locale?: unknown;
277
+ i18n: Pick<I18nProvider, "getLocale" | "getRequestedLocale">;
278
+ }): string;