@qualified-salesforce/web 0.0.1-oidc-bootstrap

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 (560) hide show
  1. package/41842993ec71d6628e4949e9a22b146b.svg +3 -0
  2. package/7271f3433ed82fc7f56adcd9e30275f4.svg +17 -0
  3. package/LICENSE.txt +82 -0
  4. package/components/helpers/entriesStringValidations.js +69 -0
  5. package/components/helpers/languages.js +32 -0
  6. package/components/shared/assertUnreachable.js +5 -0
  7. package/components/shared/controls/imageCropperHelpers.js +43 -0
  8. package/components/shared/meetingLoadingProgressSpec.js +116 -0
  9. package/constants.generated.js +9883 -0
  10. package/css/widget/multimodal_v2/host.split-css.css +162 -0
  11. package/css/widget/multimodal_v2/index.split-css.panda.css +5240 -0
  12. package/css/widget/widget.split-css.css +100 -0
  13. package/fonts/inter/Inter-Black.woff +0 -0
  14. package/fonts/inter/Inter-Black.woff2 +0 -0
  15. package/fonts/inter/Inter-BlackItalic.woff +0 -0
  16. package/fonts/inter/Inter-BlackItalic.woff2 +0 -0
  17. package/fonts/inter/Inter-Bold.woff +0 -0
  18. package/fonts/inter/Inter-Bold.woff2 +0 -0
  19. package/fonts/inter/Inter-BoldItalic.woff +0 -0
  20. package/fonts/inter/Inter-BoldItalic.woff2 +0 -0
  21. package/fonts/inter/Inter-ExtraBold.woff +0 -0
  22. package/fonts/inter/Inter-ExtraBold.woff2 +0 -0
  23. package/fonts/inter/Inter-ExtraBoldItalic.woff +0 -0
  24. package/fonts/inter/Inter-ExtraBoldItalic.woff2 +0 -0
  25. package/fonts/inter/Inter-ExtraLight.woff +0 -0
  26. package/fonts/inter/Inter-ExtraLight.woff2 +0 -0
  27. package/fonts/inter/Inter-ExtraLightItalic.woff +0 -0
  28. package/fonts/inter/Inter-ExtraLightItalic.woff2 +0 -0
  29. package/fonts/inter/Inter-Italic.woff +0 -0
  30. package/fonts/inter/Inter-Italic.woff2 +0 -0
  31. package/fonts/inter/Inter-Light.woff +0 -0
  32. package/fonts/inter/Inter-Light.woff2 +0 -0
  33. package/fonts/inter/Inter-LightItalic.woff +0 -0
  34. package/fonts/inter/Inter-LightItalic.woff2 +0 -0
  35. package/fonts/inter/Inter-Medium.woff +0 -0
  36. package/fonts/inter/Inter-Medium.woff2 +0 -0
  37. package/fonts/inter/Inter-MediumItalic.woff +0 -0
  38. package/fonts/inter/Inter-MediumItalic.woff2 +0 -0
  39. package/fonts/inter/Inter-Regular.woff +0 -0
  40. package/fonts/inter/Inter-Regular.woff2 +0 -0
  41. package/fonts/inter/Inter-SemiBold.woff +0 -0
  42. package/fonts/inter/Inter-SemiBold.woff2 +0 -0
  43. package/fonts/inter/Inter-SemiBoldItalic.woff +0 -0
  44. package/fonts/inter/Inter-SemiBoldItalic.woff2 +0 -0
  45. package/fonts/inter/Inter-Thin.woff +0 -0
  46. package/fonts/inter/Inter-Thin.woff2 +0 -0
  47. package/fonts/inter/Inter-ThinItalic.woff +0 -0
  48. package/fonts/inter/Inter-ThinItalic.woff2 +0 -0
  49. package/fonts/inter/Inter-italic.var.woff2 +0 -0
  50. package/fonts/inter/Inter-roman.var.woff2 +0 -0
  51. package/images/close.js +63 -0
  52. package/images/logo.js +22 -0
  53. package/js/4101.js +19721 -0
  54. package/js/daily-esm.js +9948 -0
  55. package/js/date-fns.js +427 -0
  56. package/js/multimodal_v2.js +1653 -0
  57. package/js/runtime.js +109 -0
  58. package/media/Inter-Black.796be8d8bf.woff2 +0 -0
  59. package/media/Inter-Black.b254104c56.woff +0 -0
  60. package/media/Inter-BlackItalic.70306b0eae.woff +0 -0
  61. package/media/Inter-BlackItalic.752f1e0aaa.woff2 +0 -0
  62. package/media/Inter-Bold.579e0f95ca.woff2 +0 -0
  63. package/media/Inter-Bold.b1234477a5.woff +0 -0
  64. package/media/Inter-BoldItalic.3d0d804323.woff +0 -0
  65. package/media/Inter-BoldItalic.828a494e04.woff2 +0 -0
  66. package/media/Inter-ExtraBold.208a9e6c99.woff +0 -0
  67. package/media/Inter-ExtraBold.d65f028165.woff2 +0 -0
  68. package/media/Inter-ExtraBoldItalic.30429962ec.woff +0 -0
  69. package/media/Inter-ExtraBoldItalic.8c7eac5ce3.woff2 +0 -0
  70. package/media/Inter-ExtraLight.15c082a57d.woff +0 -0
  71. package/media/Inter-ExtraLight.6824177d1e.woff2 +0 -0
  72. package/media/Inter-ExtraLightItalic.05138dddf3.woff2 +0 -0
  73. package/media/Inter-ExtraLightItalic.3beee54f59.woff +0 -0
  74. package/media/Inter-Italic.9beab78452.woff +0 -0
  75. package/media/Inter-Italic.d593a8df79.woff2 +0 -0
  76. package/media/Inter-Light.27083fa637.woff2 +0 -0
  77. package/media/Inter-Light.91dfddd842.woff +0 -0
  78. package/media/Inter-LightItalic.0a783b89b3.woff2 +0 -0
  79. package/media/Inter-LightItalic.f8ccf2813f.woff +0 -0
  80. package/media/Inter-Medium.dc792b508e.woff2 +0 -0
  81. package/media/Inter-Medium.ec7dd2d9d8.woff +0 -0
  82. package/media/Inter-MediumItalic.17301e5b40.woff +0 -0
  83. package/media/Inter-MediumItalic.84d3493a9f.woff2 +0 -0
  84. package/media/Inter-Regular.f1f0c35b32.woff2 +0 -0
  85. package/media/Inter-Regular.f356e84aa0.woff +0 -0
  86. package/media/Inter-SemiBold.55027e4724.woff +0 -0
  87. package/media/Inter-SemiBold.fcb100c760.woff2 +0 -0
  88. package/media/Inter-SemiBoldItalic.ab9105ed3b.woff +0 -0
  89. package/media/Inter-SemiBoldItalic.d90f295d0c.woff2 +0 -0
  90. package/media/Inter-Thin.16325d9b0f.woff +0 -0
  91. package/media/Inter-Thin.dafaa44d99.woff2 +0 -0
  92. package/media/Inter-ThinItalic.4fc662b3cf.woff2 +0 -0
  93. package/media/Inter-ThinItalic.d3d8994788.woff +0 -0
  94. package/media/Inter-italic.var.958a0b9742.woff2 +0 -0
  95. package/media/Inter-roman.var.b2129c009c.woff2 +0 -0
  96. package/package.json +20 -0
  97. package/packs/widget/api/docking/docking_host.js +97 -0
  98. package/packs/widget/api/docking/index.js +294 -0
  99. package/packs/widget/api/docking/shared.js +164 -0
  100. package/packs/widget/api/docking/viewport_lock.js +488 -0
  101. package/packs/widget/api/docking/viewport_resize.js +1203 -0
  102. package/packs/widget/esm/fonts/Inter-Black.796be8d8bf.woff2 +0 -0
  103. package/packs/widget/esm/fonts/Inter-Black.b254104c56.woff +0 -0
  104. package/packs/widget/esm/fonts/Inter-BlackItalic.70306b0eae.woff +0 -0
  105. package/packs/widget/esm/fonts/Inter-BlackItalic.752f1e0aaa.woff2 +0 -0
  106. package/packs/widget/esm/fonts/Inter-Bold.579e0f95ca.woff2 +0 -0
  107. package/packs/widget/esm/fonts/Inter-Bold.b1234477a5.woff +0 -0
  108. package/packs/widget/esm/fonts/Inter-BoldItalic.3d0d804323.woff +0 -0
  109. package/packs/widget/esm/fonts/Inter-BoldItalic.828a494e04.woff2 +0 -0
  110. package/packs/widget/esm/fonts/Inter-ExtraBold.208a9e6c99.woff +0 -0
  111. package/packs/widget/esm/fonts/Inter-ExtraBold.d65f028165.woff2 +0 -0
  112. package/packs/widget/esm/fonts/Inter-ExtraBoldItalic.30429962ec.woff +0 -0
  113. package/packs/widget/esm/fonts/Inter-ExtraBoldItalic.8c7eac5ce3.woff2 +0 -0
  114. package/packs/widget/esm/fonts/Inter-ExtraLight.15c082a57d.woff +0 -0
  115. package/packs/widget/esm/fonts/Inter-ExtraLight.6824177d1e.woff2 +0 -0
  116. package/packs/widget/esm/fonts/Inter-ExtraLightItalic.05138dddf3.woff2 +0 -0
  117. package/packs/widget/esm/fonts/Inter-ExtraLightItalic.3beee54f59.woff +0 -0
  118. package/packs/widget/esm/fonts/Inter-Italic.9beab78452.woff +0 -0
  119. package/packs/widget/esm/fonts/Inter-Italic.d593a8df79.woff2 +0 -0
  120. package/packs/widget/esm/fonts/Inter-Light.27083fa637.woff2 +0 -0
  121. package/packs/widget/esm/fonts/Inter-Light.91dfddd842.woff +0 -0
  122. package/packs/widget/esm/fonts/Inter-LightItalic.0a783b89b3.woff2 +0 -0
  123. package/packs/widget/esm/fonts/Inter-LightItalic.f8ccf2813f.woff +0 -0
  124. package/packs/widget/esm/fonts/Inter-Medium.dc792b508e.woff2 +0 -0
  125. package/packs/widget/esm/fonts/Inter-Medium.ec7dd2d9d8.woff +0 -0
  126. package/packs/widget/esm/fonts/Inter-MediumItalic.17301e5b40.woff +0 -0
  127. package/packs/widget/esm/fonts/Inter-MediumItalic.84d3493a9f.woff2 +0 -0
  128. package/packs/widget/esm/fonts/Inter-Regular.f1f0c35b32.woff2 +0 -0
  129. package/packs/widget/esm/fonts/Inter-Regular.f356e84aa0.woff +0 -0
  130. package/packs/widget/esm/fonts/Inter-SemiBold.55027e4724.woff +0 -0
  131. package/packs/widget/esm/fonts/Inter-SemiBold.fcb100c760.woff2 +0 -0
  132. package/packs/widget/esm/fonts/Inter-SemiBoldItalic.ab9105ed3b.woff +0 -0
  133. package/packs/widget/esm/fonts/Inter-SemiBoldItalic.d90f295d0c.woff2 +0 -0
  134. package/packs/widget/esm/fonts/Inter-Thin.16325d9b0f.woff +0 -0
  135. package/packs/widget/esm/fonts/Inter-Thin.dafaa44d99.woff2 +0 -0
  136. package/packs/widget/esm/fonts/Inter-ThinItalic.4fc662b3cf.woff2 +0 -0
  137. package/packs/widget/esm/fonts/Inter-ThinItalic.d3d8994788.woff +0 -0
  138. package/packs/widget/esm/fonts/Inter-italic.var.958a0b9742.woff2 +0 -0
  139. package/packs/widget/esm/fonts/Inter-roman.var.b2129c009c.woff2 +0 -0
  140. package/packs/widget/esm/index.js +183 -0
  141. package/packs/widget/esm/qualified.css +5502 -0
  142. package/routes/app/offers/scripts/OfferMainScript.js +154 -0
  143. package/routes/app/offers/scripts/constants.js +71 -0
  144. package/routes/app/offers/scripts/main/ButtonManager.js +65 -0
  145. package/routes/app/offers/scripts/main/FormManager.js +325 -0
  146. package/routes/app/offers/scripts/main/MainContext.js +19 -0
  147. package/routes/app/offers/scripts/main/OfferManager.js +91 -0
  148. package/routes/app/offers/scripts/main/TriggerManager.js +125 -0
  149. package/routes/app/offers/scripts/rendering/ContentManager.js +53 -0
  150. package/routes/app/offers/scripts/rendering/LocationManager.js +83 -0
  151. package/routes/app/offers/scripts/rendering/RenderedOffer.js +188 -0
  152. package/routes/app/offers/scripts/rendering/Renderer.js +69 -0
  153. package/routes/app/offers/scripts/rendering/RenderingInitializer.js +62 -0
  154. package/routes/app/offers/scripts/rendering/animations/AnimationManager.js +31 -0
  155. package/routes/app/offers/scripts/rendering/animations/AnimationManagerFooter.js +81 -0
  156. package/routes/app/offers/scripts/rendering/animations/AnimationManagerHeader.js +81 -0
  157. package/routes/app/offers/scripts/rendering/animations/AnimationManagerModal.js +117 -0
  158. package/routes/app/offers/scripts/rendering/animations/AnimationManagerSidebar.js +75 -0
  159. package/routes/app/offers/scripts/rendering/animations/AnimationResult.js +43 -0
  160. package/routes/app/offers/scripts/rendering/animations/Animator.js +78 -0
  161. package/routes/app/offers/scripts/rendering/animations/BaseAnimationManager.js +25 -0
  162. package/routes/app/offers/scripts/rendering/lib/BaseComponent.js +106 -0
  163. package/routes/app/offers/scripts/rendering/lib/FormComponent.js +134 -0
  164. package/routes/app/offers/scripts/rendering/lib/OfferComponent.js +144 -0
  165. package/routes/app/offers/scripts/rendering/lib/ScrollbarWidth.js +27 -0
  166. package/routes/app/offers/scripts/rendering/lib/decorators.js +20 -0
  167. package/routes/app/offers/scripts/rendering/locations/CSSVarsManager.js +66 -0
  168. package/routes/app/offers/scripts/rendering/locations/ElementResizeObserver.js +49 -0
  169. package/routes/app/offers/scripts/rendering/locations/footer.js +53 -0
  170. package/routes/app/offers/scripts/rendering/locations/header/AsyncBatchProcessor.js +70 -0
  171. package/routes/app/offers/scripts/rendering/locations/header/CSSTransitionObserver.js +182 -0
  172. package/routes/app/offers/scripts/rendering/locations/header/ElementStyleChangeObserver.js +138 -0
  173. package/routes/app/offers/scripts/rendering/locations/header/ExternalStyleManager.js +110 -0
  174. package/routes/app/offers/scripts/rendering/locations/header/Header.js +353 -0
  175. package/routes/app/offers/scripts/rendering/locations/header/InlineStyleManager.js +105 -0
  176. package/routes/app/offers/scripts/rendering/locations/header/MatchingElementsObserver.js +107 -0
  177. package/routes/app/offers/scripts/rendering/locations/header/NewElementsObserver.js +129 -0
  178. package/routes/app/offers/scripts/rendering/locations/header/RuleWrapper.js +46 -0
  179. package/routes/app/offers/scripts/rendering/locations/header/SelectorObservable.js +23 -0
  180. package/routes/app/offers/scripts/rendering/locations/header/SelectorObserver.js +61 -0
  181. package/routes/app/offers/scripts/rendering/locations/header/ShiftedElementsManager.js +45 -0
  182. package/routes/app/offers/scripts/rendering/locations/header/StyleElementManager.js +37 -0
  183. package/routes/app/offers/scripts/rendering/locations/header/StyleElementWrapper.js +62 -0
  184. package/routes/app/offers/scripts/rendering/locations/header/StyleSelectorObserver/ObservedSelectorValue.js +45 -0
  185. package/routes/app/offers/scripts/rendering/locations/header/StyleSelectorObserver/ObservedSelectors.js +62 -0
  186. package/routes/app/offers/scripts/rendering/locations/header/StyleSelectorObserver/StyleSelectorObserver.js +294 -0
  187. package/routes/app/offers/scripts/rendering/locations/header/StyleSelectorObserver/constants.js +21 -0
  188. package/routes/app/offers/scripts/rendering/locations/header/WindowResizeObserver.js +43 -0
  189. package/routes/app/offers/scripts/rendering/locations/header/utils.js +25 -0
  190. package/routes/app/offers/scripts/rendering/locations/popup.js +66 -0
  191. package/routes/app/offers/scripts/rendering/locations/sidebar.js +21 -0
  192. package/routes/app/offers/scripts/rendering/variations/ButtonBanner.js +105 -0
  193. package/routes/app/offers/scripts/rendering/variations/ButtonModal.js +114 -0
  194. package/routes/app/offers/scripts/rendering/variations/FormBanner.js +214 -0
  195. package/routes/app/offers/scripts/rendering/variations/FormModal.js +325 -0
  196. package/routes/app/offers/scripts/rendering/variations/LinkBanner.js +105 -0
  197. package/routes/app/offers/scripts/rendering/variations/components/Body.js +29 -0
  198. package/routes/app/offers/scripts/rendering/variations/components/Button.js +128 -0
  199. package/routes/app/offers/scripts/rendering/variations/components/DismissButton.js +39 -0
  200. package/routes/app/offers/scripts/rendering/variations/components/ForegroundImageBanner.js +110 -0
  201. package/routes/app/offers/scripts/rendering/variations/components/ForegroundImageModal.js +128 -0
  202. package/routes/app/offers/scripts/rendering/variations/components/Headline.js +94 -0
  203. package/routes/app/offers/scripts/rendering/variations/components/MultiFieldForm.js +302 -0
  204. package/routes/app/offers/scripts/rendering/variations/components/Tooltip.js +74 -0
  205. package/routes/app/offers/scripts/rendering/variations/icons.js +15 -0
  206. package/routes/app/offers/scripts/utils.js +115 -0
  207. package/routes/app/offers/utils/HTMLUtils.js +10 -0
  208. package/routes/app/offers/utils/createTypeGuard.js +32 -0
  209. package/routes/app/offers/utils/promise-utils.js +22 -0
  210. package/routes/app/websiteBuilder/stores/storeHelpers.js +18 -0
  211. package/sounds/message-initial.mp3 +0 -0
  212. package/sounds/message-received.mp3 +0 -0
  213. package/sounds/message-sent.mp3 +0 -0
  214. package/src/arrays.js +15 -0
  215. package/src/audio.js +106 -0
  216. package/src/bounded-set.js +16 -0
  217. package/src/bounding_box_observer.js +129 -0
  218. package/src/decorators.js +29 -0
  219. package/src/dom.js +128 -0
  220. package/src/dom_roots.js +26 -0
  221. package/src/embedded_forms/EmbeddedForm.js +638 -0
  222. package/src/embedded_forms/QualifiedEmbeddedForm.js +51 -0
  223. package/src/embedded_forms/QualifiedFormField.js +137 -0
  224. package/src/embedded_forms/utils.js +17 -0
  225. package/src/graphql-types.js +1686 -0
  226. package/src/iframes.js +86 -0
  227. package/src/localstorage.js +43 -0
  228. package/src/mirror/Shipper.js +133 -0
  229. package/src/mirror/constants.generated.js +13 -0
  230. package/src/mirror/constants.js +238 -0
  231. package/src/mirror/shipper/ChangeQueue.js +155 -0
  232. package/src/mirror/shipper/DOMSerializer.js +392 -0
  233. package/src/mirror/shipper/observers.js +441 -0
  234. package/src/mirror/shipper/utils.js +98 -0
  235. package/src/mixins/disposable.js +125 -0
  236. package/src/mixins/injectable.js +37 -0
  237. package/src/personalizations/personalization-manager.js +110 -0
  238. package/src/personalizations/strategies/node-freezing-strategy.js +174 -0
  239. package/src/personalizations/utils.js +187 -0
  240. package/src/promises.js +107 -0
  241. package/src/proxy.js +144 -0
  242. package/src/qualified_root.js +35 -0
  243. package/src/query_params.js +55 -0
  244. package/src/shadow-dom-helper.js +63 -0
  245. package/src/singleton_host.js +39 -0
  246. package/src/smart_website/trigger.js +49 -0
  247. package/src/smart_website/utils.js +149 -0
  248. package/src/string.js +53 -0
  249. package/src/timezone.js +57 -0
  250. package/src/timing.js +49 -0
  251. package/src/type-utils.js +76 -0
  252. package/src/url-utils.js +102 -0
  253. package/src/url.js +50 -0
  254. package/src/utils.js +72 -0
  255. package/src/validation.js.js +29 -0
  256. package/src/validation_ts.js +6 -0
  257. package/vendor/actioncable/adapters.js +6 -0
  258. package/vendor/actioncable/connection.js +204 -0
  259. package/vendor/actioncable/connection_monitor.js +129 -0
  260. package/vendor/actioncable/consumer.js +91 -0
  261. package/vendor/actioncable/index.js +34 -0
  262. package/vendor/actioncable/internal.js +22 -0
  263. package/vendor/actioncable/logger.js +28 -0
  264. package/vendor/actioncable/subscription.js +93 -0
  265. package/vendor/actioncable/subscriptions.js +89 -0
  266. package/vendor/open-telemetry-idgenerator.js +43 -0
  267. package/widget/analytics/facebook_tracker.js +8 -0
  268. package/widget/analytics/google_analytics_tracker.js +83 -0
  269. package/widget/analytics/google_tag_manager_tracker.js +22 -0
  270. package/widget/analytics.js +58 -0
  271. package/widget/api_handler/api_handler.js +730 -0
  272. package/widget/api_handler/base_api_handler.js +249 -0
  273. package/widget/booker_intent_tracker.js +391 -0
  274. package/widget/booker_outcome_tracker.js +329 -0
  275. package/widget/capture_widget_exceptions.js +150 -0
  276. package/widget/channel.js +282 -0
  277. package/widget/composite_experience_adapter.js +101 -0
  278. package/widget/constants.generated.js +350 -0
  279. package/widget/constants.js +21 -0
  280. package/widget/container.js +193 -0
  281. package/widget/content_activity_emitter.js +36 -0
  282. package/widget/data360_visitor.js +67 -0
  283. package/widget/date_provider.js +11 -0
  284. package/widget/debug_mode_state.js +175 -0
  285. package/widget/dummy_module.js +9 -0
  286. package/widget/eloqua_visitor.js +17 -0
  287. package/widget/form_cta_booker_intent.js +246 -0
  288. package/widget/hubspot_visitor.js +39 -0
  289. package/widget/inline_meeting_booker_page.js +90 -0
  290. package/widget/local_state/abstract_local_state.js +38 -0
  291. package/widget/local_state/debug_state/abstract_debug_flow.js +29 -0
  292. package/widget/local_state/debug_state/custom_form_flow.js +14 -0
  293. package/widget/local_state/debug_state/hubspot_form_flow.js +19 -0
  294. package/widget/local_state/debug_state/hubspot_v4_form_flow.js +19 -0
  295. package/widget/local_state/debug_state/marketo_form_flow.js +20 -0
  296. package/widget/local_state/debug_state/pardot_form_flow.js +18 -0
  297. package/widget/local_state/debug_state.js +362 -0
  298. package/widget/local_state/trace_state.js +20 -0
  299. package/widget/location_provider.js +9 -0
  300. package/widget/marketo_visitor.js +39 -0
  301. package/widget/meetings/tracing/buttons_forms_triggering_tracer.js +124 -0
  302. package/widget/meetings/tracing/spans/button_spans.js +18 -0
  303. package/widget/meetings/tracing/spans/form_spans.js +11 -0
  304. package/widget/multimodal_v2/assets_preloader.js +97 -0
  305. package/widget/multimodal_v2/components/AppLayout.js +93 -0
  306. package/widget/multimodal_v2/components/CursorOverlay.js +93 -0
  307. package/widget/multimodal_v2/components/PointerRectOverlay.js +74 -0
  308. package/widget/multimodal_v2/components/app/Artifact.js +109 -0
  309. package/widget/multimodal_v2/components/app/Background.js +27 -0
  310. package/widget/multimodal_v2/components/app/CalendarLoadingContent.js +255 -0
  311. package/widget/multimodal_v2/components/app/Chat.js +39 -0
  312. package/widget/multimodal_v2/components/app/CookieConsentModal.js +149 -0
  313. package/widget/multimodal_v2/components/app/Foreground.js +48 -0
  314. package/widget/multimodal_v2/components/app/HiddenInput.js +41 -0
  315. package/widget/multimodal_v2/components/app/Input.js +72 -0
  316. package/widget/multimodal_v2/components/app/LightboxExperience.js +769 -0
  317. package/widget/multimodal_v2/components/app/LoadingOverlay.js +97 -0
  318. package/widget/multimodal_v2/components/app/Main.js +985 -0
  319. package/widget/multimodal_v2/components/app/MessengerButton.js +160 -0
  320. package/widget/multimodal_v2/components/app/Multimodal.js +17 -0
  321. package/widget/multimodal_v2/components/app/OverlayControls.js +79 -0
  322. package/widget/multimodal_v2/components/app/Preview.js +32 -0
  323. package/widget/multimodal_v2/components/app/PrivacyDisclosure.js +57 -0
  324. package/widget/multimodal_v2/components/app/RotateDeviceOverlay.js +70 -0
  325. package/widget/multimodal_v2/components/app/Toolbar.js +156 -0
  326. package/widget/multimodal_v2/components/chat/ChatComposer.js +129 -0
  327. package/widget/multimodal_v2/components/chat/ChatInputForm.js +398 -0
  328. package/widget/multimodal_v2/components/chat/ColdStartQuestions.js +354 -0
  329. package/widget/multimodal_v2/components/chat/ComposerErrorBanner.js +62 -0
  330. package/widget/multimodal_v2/components/chat/PostCallSurvey.js +359 -0
  331. package/widget/multimodal_v2/components/chat/preview/FieldRequestRenderer.js +41 -0
  332. package/widget/multimodal_v2/components/chat/preview/PreviewMessageRenderer.js +60 -0
  333. package/widget/multimodal_v2/components/chat/preview/SharedOfferRenderer.js +143 -0
  334. package/widget/multimodal_v2/components/chat/preview/TextRenderer.js +27 -0
  335. package/widget/multimodal_v2/components/chat/preview/TimelinePreview.js +254 -0
  336. package/widget/multimodal_v2/components/chat/timeline/CalendarEventOfferRenderer.js +103 -0
  337. package/widget/multimodal_v2/components/chat/timeline/CalendarEventPickRenderer.js +148 -0
  338. package/widget/multimodal_v2/components/chat/timeline/FieldEntryRenderer.js +84 -0
  339. package/widget/multimodal_v2/components/chat/timeline/FieldRequestRenderer.js +56 -0
  340. package/widget/multimodal_v2/components/chat/timeline/InlinePrivacyDisclosure.js +66 -0
  341. package/widget/multimodal_v2/components/chat/timeline/LinkPreviewCard.js +70 -0
  342. package/widget/multimodal_v2/components/chat/timeline/MessageEntry.js +88 -0
  343. package/widget/multimodal_v2/components/chat/timeline/PresentContentRenderer.js +30 -0
  344. package/widget/multimodal_v2/components/chat/timeline/PresentDeckRenderer.js +279 -0
  345. package/widget/multimodal_v2/components/chat/timeline/PresentVideoRenderer.js +131 -0
  346. package/widget/multimodal_v2/components/chat/timeline/ShareContentRenderer.js +59 -0
  347. package/widget/multimodal_v2/components/chat/timeline/SharedOfferRenderer.js +131 -0
  348. package/widget/multimodal_v2/components/chat/timeline/SystemRenderer.js +82 -0
  349. package/widget/multimodal_v2/components/chat/timeline/TextRenderer.js +66 -0
  350. package/widget/multimodal_v2/components/chat/timeline/Timeline.js +158 -0
  351. package/widget/multimodal_v2/components/debug/DebugMultimodalPanel.js +327 -0
  352. package/widget/multimodal_v2/components/decks/index.js +160 -0
  353. package/widget/multimodal_v2/components/field_request/BooleanField.js +77 -0
  354. package/widget/multimodal_v2/components/field_request/FieldComponents.js +69 -0
  355. package/widget/multimodal_v2/components/field_request/Form.js +87 -0
  356. package/widget/multimodal_v2/components/field_request/MultiPicklistField.js +240 -0
  357. package/widget/multimodal_v2/components/field_request/PicklistField.js +166 -0
  358. package/widget/multimodal_v2/components/field_request/SingleLineInputField.js +69 -0
  359. package/widget/multimodal_v2/components/field_request/TextField.js +37 -0
  360. package/widget/multimodal_v2/components/field_request/index.js +170 -0
  361. package/widget/multimodal_v2/components/helpers/AutoScroll.js +37 -0
  362. package/widget/multimodal_v2/components/helpers/ErrorBoundary.js +53 -0
  363. package/widget/multimodal_v2/components/helpers/FocusTrapDialog.js +26 -0
  364. package/widget/multimodal_v2/components/helpers/ImpressionTracker.js +94 -0
  365. package/widget/multimodal_v2/components/helpers/ListRenderer.js +37 -0
  366. package/widget/multimodal_v2/components/helpers/Localization.js +76 -0
  367. package/widget/multimodal_v2/components/helpers/Persisted.js +166 -0
  368. package/widget/multimodal_v2/components/helpers/RichText.js +358 -0
  369. package/widget/multimodal_v2/components/helpers/ScreenReaderHeading.js +17 -0
  370. package/widget/multimodal_v2/components/helpers/Thumbnail.js +190 -0
  371. package/widget/multimodal_v2/components/helpers/VisuallyHidden.js +41 -0
  372. package/widget/multimodal_v2/components/helpers/content_click_payloads.js +58 -0
  373. package/widget/multimodal_v2/components/helpers/useDraggable.js +103 -0
  374. package/widget/multimodal_v2/components/helpers/useTextOverflow.js +44 -0
  375. package/widget/multimodal_v2/components/lightbox_gather/index.js +741 -0
  376. package/widget/multimodal_v2/components/meetings/ArtifactEntryPoint.js +252 -0
  377. package/widget/multimodal_v2/components/meetings/MeetingAdditionalAttendees.js +325 -0
  378. package/widget/multimodal_v2/components/meetings/MeetingBookerEntry.js +100 -0
  379. package/widget/multimodal_v2/components/meetings/MeetingDetailsCard.js +99 -0
  380. package/widget/multimodal_v2/components/meetings/MeetingErrorBanner.js +62 -0
  381. package/widget/multimodal_v2/components/meetings/MeetingOfferEmailStep.js +239 -0
  382. package/widget/multimodal_v2/components/meetings/MeetingOfferFooter.js +104 -0
  383. package/widget/multimodal_v2/components/meetings/MeetingOfferSelectionStep.js +60 -0
  384. package/widget/multimodal_v2/components/meetings/MeetingRepHeader.js +222 -0
  385. package/widget/multimodal_v2/components/meetings/MeetingStepShell.js +92 -0
  386. package/widget/multimodal_v2/components/meetings/MeetingSummaryRail.js +515 -0
  387. package/widget/multimodal_v2/components/meetings/MeetingTimeSelector.js +603 -0
  388. package/widget/multimodal_v2/components/meetings/MonthDatePicker.js +422 -0
  389. package/widget/multimodal_v2/components/meetings/NavigationButtons.js +76 -0
  390. package/widget/multimodal_v2/components/meetings/TimeSlotHeader.js +357 -0
  391. package/widget/multimodal_v2/components/meetings/WeekViewHeader.js +20 -0
  392. package/widget/multimodal_v2/components/meetings/constants.js +7 -0
  393. package/widget/multimodal_v2/components/meetings/index.js +47 -0
  394. package/widget/multimodal_v2/components/meetings/utils.js +328 -0
  395. package/widget/multimodal_v2/components/multimodal/Audio.js +28 -0
  396. package/widget/multimodal_v2/components/multimodal/Controls.js +188 -0
  397. package/widget/multimodal_v2/components/multimodal/LiveVideo.js +63 -0
  398. package/widget/multimodal_v2/components/multimodal/MultiModalComponent.js +424 -0
  399. package/widget/multimodal_v2/components/multimodal/MultimodalAvatar.js +36 -0
  400. package/widget/multimodal_v2/components/multimodal/OrbAvatar.js +326 -0
  401. package/widget/multimodal_v2/components/multimodal/Status.js +220 -0
  402. package/widget/multimodal_v2/components/multimodal/VideoAvatar.js +24 -0
  403. package/widget/multimodal_v2/components/multimodal/VideoPreview.js +114 -0
  404. package/widget/multimodal_v2/components/multimodal/useAudioLevelMonitoring.js +96 -0
  405. package/widget/multimodal_v2/components/multimodal/useMultimodal.js +434 -0
  406. package/widget/multimodal_v2/components/presentations/index.js +372 -0
  407. package/widget/multimodal_v2/components/shared/Avatar.js +92 -0
  408. package/widget/multimodal_v2/components/shared/AvatarGroup.js +135 -0
  409. package/widget/multimodal_v2/components/shared/Button.js +245 -0
  410. package/widget/multimodal_v2/components/shared/ButtonGroup.js +133 -0
  411. package/widget/multimodal_v2/components/shared/ComposerForm.js +98 -0
  412. package/widget/multimodal_v2/components/shared/SpeakingIndicator.js +239 -0
  413. package/widget/multimodal_v2/components/shared/ThinkingAnimation.js +165 -0
  414. package/widget/multimodal_v2/components/shared/Tooltip.js +266 -0
  415. package/widget/multimodal_v2/components/shared/controls/Dropdown.js +79 -0
  416. package/widget/multimodal_v2/components/shared/controls/PillToggle.js +142 -0
  417. package/widget/multimodal_v2/components/shared/controls/TextArea.js +114 -0
  418. package/widget/multimodal_v2/components/shared/toolCallLabels.js +12 -0
  419. package/widget/multimodal_v2/components/slides/SlidesThumbnail.js +47 -0
  420. package/widget/multimodal_v2/components/slides/index.js +61 -0
  421. package/widget/multimodal_v2/constants.js +88 -0
  422. package/widget/multimodal_v2/host.split-css.js +2 -0
  423. package/widget/multimodal_v2/host.string.js +96 -0
  424. package/widget/multimodal_v2/images/icons.js +582 -0
  425. package/widget/multimodal_v2/images/posters/piper_low_res.jpg +0 -0
  426. package/widget/multimodal_v2/index.js +23 -0
  427. package/widget/multimodal_v2/index.panda.js +28 -0
  428. package/widget/multimodal_v2/index.split-css.panda.js +2 -0
  429. package/widget/multimodal_v2/inline_meeting_booker.js +182 -0
  430. package/widget/multimodal_v2/locales/cs.js +196 -0
  431. package/widget/multimodal_v2/locales/da.js +196 -0
  432. package/widget/multimodal_v2/locales/de.js +196 -0
  433. package/widget/multimodal_v2/locales/en.js +196 -0
  434. package/widget/multimodal_v2/locales/en_AU.js +197 -0
  435. package/widget/multimodal_v2/locales/en_GB.js +197 -0
  436. package/widget/multimodal_v2/locales/es.js +197 -0
  437. package/widget/multimodal_v2/locales/es_LA.js +196 -0
  438. package/widget/multimodal_v2/locales/fi.js +196 -0
  439. package/widget/multimodal_v2/locales/fr.js +197 -0
  440. package/widget/multimodal_v2/locales/fr_CA.js +196 -0
  441. package/widget/multimodal_v2/locales/id.js +196 -0
  442. package/widget/multimodal_v2/locales/index.js +48 -0
  443. package/widget/multimodal_v2/locales/it.js +196 -0
  444. package/widget/multimodal_v2/locales/ja.js +196 -0
  445. package/widget/multimodal_v2/locales/ko.js +196 -0
  446. package/widget/multimodal_v2/locales/nb.js +196 -0
  447. package/widget/multimodal_v2/locales/nl.js +196 -0
  448. package/widget/multimodal_v2/locales/pl.js +196 -0
  449. package/widget/multimodal_v2/locales/pt_BR.js +196 -0
  450. package/widget/multimodal_v2/locales/ru.js +196 -0
  451. package/widget/multimodal_v2/locales/sv.js +196 -0
  452. package/widget/multimodal_v2/locales/th.js +196 -0
  453. package/widget/multimodal_v2/locales/tr.js +196 -0
  454. package/widget/multimodal_v2/locales/vi.js +196 -0
  455. package/widget/multimodal_v2/locales/zh_CN.js +196 -0
  456. package/widget/multimodal_v2/locales/zh_TW.js +196 -0
  457. package/widget/multimodal_v2/multimodal.js +633 -0
  458. package/widget/multimodal_v2/multimodal_channel.js +195 -0
  459. package/widget/multimodal_v2/signals/active_conversation_signal.js +33 -0
  460. package/widget/multimodal_v2/signals/allowed_conversation_mode_signal.js +38 -0
  461. package/widget/multimodal_v2/signals/artifact_signal.js +22 -0
  462. package/widget/multimodal_v2/signals/layout_signal.js +98 -0
  463. package/widget/multimodal_v2/signals/messages_signal.js +207 -0
  464. package/widget/multimodal_v2/signals/ui_state_signal.js +128 -0
  465. package/widget/multimodal_v2/stable_bundle_src.js +44 -0
  466. package/widget/multimodal_v2/stores/ai_conversation_store.js +221 -0
  467. package/widget/multimodal_v2/stores/artifact_store.js +205 -0
  468. package/widget/multimodal_v2/stores/base_store.js +16 -0
  469. package/widget/multimodal_v2/stores/call_store.js +770 -0
  470. package/widget/multimodal_v2/stores/call_ui_adapter.js +225 -0
  471. package/widget/multimodal_v2/stores/debug_multimodal_scenario_store.js +471 -0
  472. package/widget/multimodal_v2/stores/decks_store.js +285 -0
  473. package/widget/multimodal_v2/stores/device_store.js +63 -0
  474. package/widget/multimodal_v2/stores/docking_store.js +62 -0
  475. package/widget/multimodal_v2/stores/field_request_store.js +326 -0
  476. package/widget/multimodal_v2/stores/meeting_store.js +477 -0
  477. package/widget/multimodal_v2/stores/participant_store.js +73 -0
  478. package/widget/multimodal_v2/stores/post_call_survey_store.js +160 -0
  479. package/widget/multimodal_v2/stores/pounce_tracking_store.js +163 -0
  480. package/widget/multimodal_v2/stores/pounce_tracking_store_v2.js +511 -0
  481. package/widget/multimodal_v2/stores/presentations_store.js +111 -0
  482. package/widget/multimodal_v2/stores/root_store.js +1919 -0
  483. package/widget/multimodal_v2/stores/screen_share_store.js +217 -0
  484. package/widget/multimodal_v2/stores/slides_store.js +21 -0
  485. package/widget/multimodal_v2/stores/translation_store.js +185 -0
  486. package/widget/multimodal_v2/stores/ui_store.js +496 -0
  487. package/widget/multimodal_v2/stores/waiting_store.js +159 -0
  488. package/widget/multimodal_v2/stores/website_navigation_store.js +767 -0
  489. package/widget/multimodal_v2/styled-system/css/conditions.js +34 -0
  490. package/widget/multimodal_v2/styled-system/css/css.js +48 -0
  491. package/widget/multimodal_v2/styled-system/css/cva.js +96 -0
  492. package/widget/multimodal_v2/styled-system/css/cx.js +13 -0
  493. package/widget/multimodal_v2/styled-system/css/index.js +15 -0
  494. package/widget/multimodal_v2/styled-system/css/sva.js +69 -0
  495. package/widget/multimodal_v2/styled-system/helpers.js +384 -0
  496. package/widget/multimodal_v2/styled-system/jsx/create-style-context.js +96 -0
  497. package/widget/multimodal_v2/styled-system/jsx/factory-helper.js +19 -0
  498. package/widget/multimodal_v2/styled-system/jsx/factory.js +111 -0
  499. package/widget/multimodal_v2/styled-system/jsx/index.js +12 -0
  500. package/widget/multimodal_v2/styled-system/jsx/is-valid-prop.js +22 -0
  501. package/widget/multimodal_v2/types.js +105 -0
  502. package/widget/multimodal_v2/utils/auto_scroller.js +157 -0
  503. package/widget/multimodal_v2/utils/flip_animation.js +124 -0
  504. package/widget/multimodal_v2/utils/focus_gate.js +237 -0
  505. package/widget/multimodal_v2/utils/locale.js +16 -0
  506. package/widget/multimodal_v2/utils/media_queries.js +30 -0
  507. package/widget/multimodal_v2/utils/multimodal_cache.js +19 -0
  508. package/widget/multimodal_v2/utils/mutation_effect.js +14 -0
  509. package/widget/multimodal_v2/utils/navigation_interceptor.js +205 -0
  510. package/widget/multimodal_v2/utils/navigation_strategies/dom_swap.js +393 -0
  511. package/widget/multimodal_v2/utils/navigation_strategies/index.js +12 -0
  512. package/widget/multimodal_v2/utils/navigation_strategies/lwr.js +61 -0
  513. package/widget/multimodal_v2/utils/navigation_strategies/navigation_utils.js +46 -0
  514. package/widget/multimodal_v2/utils/navigation_strategies/next_js.js +24 -0
  515. package/widget/multimodal_v2/utils/navigation_strategies/wouter_v3.js +15 -0
  516. package/widget/multimodal_v2/utils/objects_map.js +38 -0
  517. package/widget/multimodal_v2/utils/perceived_voice_turn_tracker.js +345 -0
  518. package/widget/multimodal_v2/utils/sanitize_html.js +132 -0
  519. package/widget/multimodal_v2/utils/signals.js +97 -0
  520. package/widget/multimodal_v2/utils/slide_zoom.js +114 -0
  521. package/widget/multimodal_v2/utils/theme_styles.js +137 -0
  522. package/widget/multimodal_v2/utils/url_observer.js +52 -0
  523. package/widget/multimodal_v2/utils/voice_onset_detector.js +127 -0
  524. package/widget/page_mirror.js +89 -0
  525. package/widget/page_view_activity_emitter.js +71 -0
  526. package/widget/pardot_visitor.js +137 -0
  527. package/widget/personalization_observer.js +96 -0
  528. package/widget/personalizations_config.js +160 -0
  529. package/widget/qualified_form/constants.js +23 -0
  530. package/widget/qualified_form/phone_utils.js +38 -0
  531. package/widget/qualified_form/qualified_form_action.js +91 -0
  532. package/widget/qualified_form/qualified_form_action_orchestrator.js +21 -0
  533. package/widget/qualified_form/qualified_form_api.js +471 -0
  534. package/widget/scroll_disabler.js +109 -0
  535. package/widget/server-logger.js +156 -0
  536. package/widget/smart_website_config.js +112 -0
  537. package/widget/telemetry/context.js +75 -0
  538. package/widget/telemetry/index.js +16 -0
  539. package/widget/telemetry/messenger_uptime.js +80 -0
  540. package/widget/telemetry/metrics.js +120 -0
  541. package/widget/telemetry/span.js +82 -0
  542. package/widget/telemetry/telemetry.js +180 -0
  543. package/widget/telemetry/tracer.js +41 -0
  544. package/widget/telemetry/tracing_store.js +310 -0
  545. package/widget/tracker.js +916 -0
  546. package/widget/utils/native_globals.js +129 -0
  547. package/widget/v1_adapter.js +50 -0
  548. package/widget/v2_adapter.js +368 -0
  549. package/widget/visitor/base_visitor_state.js +11 -0
  550. package/widget/visitor/cookie_visitor_state.js +128 -0
  551. package/widget/visitor/in_memory_visitor_state.js +29 -0
  552. package/widget/visitor/visitor_state.js +384 -0
  553. package/widget/visitor.js +356 -0
  554. package/widget/widget/linked_widget_v2.js +227 -0
  555. package/widget/widget/page_mirror_factory.js +22 -0
  556. package/widget/widget/sentry.js +130 -0
  557. package/widget/widget/widget.js +1698 -0
  558. package/widget/widget.split-css.js +2 -0
  559. package/widget/widget_bootstrap.js +97 -0
  560. package/widget/widget_object.js +73 -0
@@ -0,0 +1,767 @@
1
+ import { __webpack_require__ } from "../../../js/runtime.js";
2
+ import { signals_core_module_d } from "../../../js/multimodal_v2.js";
3
+ import { normalizeToBaseUrl } from "../../../src/url-utils.js";
4
+ import { MULTIMODAL_HOST_ID } from "../constants.js";
5
+ import { isMobile } from "../utils/media_queries.js";
6
+ import { NavigationInterceptor } from "../utils/navigation_interceptor.js";
7
+ import "../utils/navigation_strategies/index.js";
8
+ import { unzoomRect, slideZoomPoint, zoomScaleForBox, slideZoomFocus } from "../utils/slide_zoom.js";
9
+ import { DisplayMode as types_DisplayMode } from "../types.js";
10
+ import "../../utils/native_globals.js";
11
+ import { hexToRgba } from "../utils/theme_styles.js";
12
+ import { isSameOrigin, findElementWithText } from "../utils/navigation_strategies/navigation_utils.js";
13
+ import { wouterV3Strategy as wouter_v3 } from "../utils/navigation_strategies/wouter_v3.js";
14
+ import { lwrStrategy as lwr } from "../utils/navigation_strategies/lwr.js";
15
+ import { nextJsStrategy as next_js } from "../utils/navigation_strategies/next_js.js";
16
+ import { default as dom_swap } from "../utils/navigation_strategies/dom_swap.js";
17
+
18
+ /* provided dependency */ var website_navigation_store_setTimeout = __webpack_require__(68034).pS;
19
+ /* provided dependency */ var website_navigation_store_clearTimeout = __webpack_require__(68034).Kj;
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+ // Layout constants
30
+ const CURSOR_OFFSET_PX = 14;
31
+ const CURSOR_ELEMENT_OFFSET_PX = 15;
32
+ // Animation timing constants (in milliseconds)
33
+ const HIGHLIGHT_DELAY_MS = 3000;
34
+ // Upper bound for waiting on the smooth scroll to settle. Smooth scrolls
35
+ // can run ~800-1500ms on long pages, and we then need several consecutive
36
+ // stable samples on top of that, so this needs headroom over the raw scroll
37
+ // duration. The cap keeps us from hanging if the page keeps animating
38
+ // (carousels, sticky headers re-laying out, etc.).
39
+ const SCROLL_STABILITY_TIMEOUT_MS = 3500;
40
+ const RECT_STABILITY_POLL_INTERVAL_MS = 100;
41
+ // Five consecutive identical samples (~500ms of stillness) is enough to
42
+ // declare a smooth scroll done without being so eager that mid-scroll
43
+ // pauses get mistaken for the final position.
44
+ const RECT_STABILITY_REQUIRED_SAMPLES = 5;
45
+ const CURSOR_POSITION_DELAY_MS = 500;
46
+ const CURSOR_HIDE_DELAY_MS = 1500;
47
+ // How long the cursor's glide to the target takes — must match the CursorContainer CSS transition
48
+ // (transform 0.8s) so we wait for the cursor to actually arrive before zooming the video in, and so
49
+ // each traced side is drawn in lockstep with the cursor. Kept unhurried so the trace reads calmly.
50
+ const CURSOR_MOVE_DURATION_MS = 800;
51
+ // Per-side duration while the cursor traces (draws) the bounding box — 40% faster than the glide so
52
+ // the box draws snappily. Drives both the cursor's per-leg glide and the border reveal, kept in sync.
53
+ const RECT_TRACE_LEG_MS = Math.round(CURSOR_MOVE_DURATION_MS * 0.6);
54
+ // How long the video stays zoomed in on the target before zooming back out. Comfortably longer than
55
+ // the full trace (5 glides x CURSOR_MOVE_DURATION_MS) so the finished box rests a beat before closing.
56
+ const SLIDE_ZOOM_HOLD_MS = 6500;
57
+ // Padding (viewport px) added around the model's bounding box so the drawn rectangle frames the
58
+ // element with a little breathing room instead of hugging its exact edges.
59
+ const RECT_PADDING_PX = 12;
60
+ // How far off the bottom-right corner the cursor rests once the box is drawn, so it sits beside the
61
+ // finished rectangle rather than on the corner.
62
+ const RECT_REST_OFFSET_PX = 12;
63
+ // Brief pause after showing the cursor at its start position so the browser paints that frame before
64
+ // we move it — otherwise the CSS transform transition has nothing to animate from and it just pops in.
65
+ const CURSOR_GLIDE_START_DELAY_MS = 60;
66
+ const TRANSITION_DURATION_MS = 300;
67
+ // Highlight styling
68
+ const HIGHLIGHT_OPACITY = 0.2;
69
+ const DARK_SURFACE_HIGHLIGHT_OPACITY = 0.25;
70
+ const DARK_SURFACE_LUMINANCE_THRESHOLD = 0.4;
71
+ const DEFAULT_PRIMARY_COLOR = "#1e79ff";
72
+ // Text search retry config
73
+ const FIND_TEXT_MAX_ATTEMPTS = 3;
74
+ const FIND_TEXT_DELAY_MS = 500;
75
+ class WebsiteNavigationStore {
76
+ /**
77
+ * Navigate to a URL and optionally highlight a text snippet.
78
+ * Switches to docked mode to push content left for co-browsing.
79
+ */ async navigateToContent(message) {
80
+ const wasNavigationInterceptorInitialized = this.navigationInterceptor.initialized;
81
+ try {
82
+ this.navigationInterceptor.dispose();
83
+ if (this.rootStore.displayMode.peek() !== types_DisplayMode.CLOSED) {
84
+ this.rootStore.setDisplayMode(isMobile.value ? types_DisplayMode.CLOSED : types_DisplayMode.DOCKED);
85
+ }
86
+ // Minimize video if maximized so user can see the navigated content,
87
+ // this will also clear the slide if it is maximized with an artifact
88
+ this.rootStore.clearMaximizedState();
89
+ const promises = [];
90
+ // Perform soft navigation if URL is provided
91
+ if (message.url) {
92
+ const postNavigate = await this.navigate(message.url);
93
+ promises.push(postNavigate());
94
+ }
95
+ // Highlight text snippet if provided
96
+ if (message.textSnippet) {
97
+ promises.push(this.highlightText(message.textSnippet));
98
+ }
99
+ await Promise.all(promises);
100
+ } finally{
101
+ if (wasNavigationInterceptorInitialized) {
102
+ this.navigationInterceptor.init();
103
+ }
104
+ }
105
+ }
106
+ /**
107
+ * Highlight a text snippet on the page with a cursor animation.
108
+ * Shows cursor at center, moves to element, then highlights it.
109
+ */ async highlightText(text) {
110
+ // Give the user a few seconds before highlighting the text snippet
111
+ await this.delay(HIGHLIGHT_DELAY_MS);
112
+ // Show initial cursor in center of the page content (accounting for sidebar)
113
+ this.setCursorPosition({
114
+ x: window.innerWidth / 2 - CURSOR_OFFSET_PX,
115
+ y: window.innerHeight / 2 - CURSOR_OFFSET_PX,
116
+ visible: true
117
+ });
118
+ const foundElement = await findElementWithText(text, {
119
+ maxAttempts: FIND_TEXT_MAX_ATTEMPTS,
120
+ delayMs: FIND_TEXT_DELAY_MS
121
+ });
122
+ if (!foundElement) {
123
+ this.setCursorPosition({
124
+ x: 0,
125
+ y: 0,
126
+ visible: false
127
+ });
128
+ return;
129
+ }
130
+ await this.pointCursorAtElement(foundElement);
131
+ }
132
+ /**
133
+ * Point Piper's cursor at a specific element on the live page (and highlight it), identified by
134
+ * its co-browse node-id. Driven by the point_at_page tool / PointCursor message. Resolves the
135
+ * node-id to the live host element via the Shipper reverse lookup (falls back to text search).
136
+ * Reuses the same cursor + highlight as the share_website flow.
137
+ */ async pointAtNode(nodeId, text) {
138
+ // A previous point gesture may still have a hide timer pending; cancel it so it can't
139
+ // yank the cursor back to the old spot mid-gesture.
140
+ this.cancelCursorSequenceTimers();
141
+ let element = this.elementForNodeId(nodeId);
142
+ if (!element && text) {
143
+ element = await findElementWithText(text, {
144
+ maxAttempts: FIND_TEXT_MAX_ATTEMPTS,
145
+ delayMs: FIND_TEXT_DELAY_MS
146
+ });
147
+ }
148
+ if (!element) {
149
+ this.setCursorPosition({
150
+ x: 0,
151
+ y: 0,
152
+ visible: false
153
+ });
154
+ return;
155
+ }
156
+ // Show the cursor near center first so it visibly glides to the target.
157
+ this.setCursorPosition({
158
+ x: window.innerWidth / 2 - CURSOR_OFFSET_PX,
159
+ y: window.innerHeight / 2 - CURSOR_OFFSET_PX,
160
+ visible: true
161
+ });
162
+ // Let the browser paint that start frame before moving. A resolved node-id needs no lookup, so
163
+ // without this pause both positions land in one task and the cursor pops onto the target instead
164
+ // of gliding. Routed through the cursor-sequence set so a newer gesture drops this continuation.
165
+ await this.cursorSequenceDelay(CURSOR_GLIDE_START_DELAY_MS);
166
+ // Don't scroll the visitor's page: marks are only placed on elements already in view, so the
167
+ // target is on-screen and yanking the page would be jarring mid-call.
168
+ await this.pointCursorAtElement(element, {
169
+ scroll: false
170
+ });
171
+ }
172
+ /**
173
+ * Point Piper's cursor at a spot on the slide image she's currently showing. A slide is an image
174
+ * with no DOM to anchor to, so the model gives normalized [0,1] coordinates and we map them onto
175
+ * the on-screen slide image's rect. Reuses the same cursor overlay as the page/share_website flow.
176
+ */ async pointAtSlide(normalizedX, normalizedY, box) {
177
+ if (box === void 0) box = null;
178
+ // Cancel any pending hide (and glide continuation) from a previous point gesture: its
179
+ // callback captured the *old* x/y, so letting it fire would jump the cursor back there
180
+ // and hide it while this gesture is still showing.
181
+ this.cancelCursorSequenceTimers();
182
+ const nx = Math.min(1, Math.max(0, normalizedX));
183
+ const ny = Math.min(1, Math.max(0, normalizedY));
184
+ const slide = this.currentSlideElement();
185
+ const measured = slide == null ? void 0 : slide.getBoundingClientRect();
186
+ if (!slide || !measured || measured.width < 1 || measured.height < 1) {
187
+ this.slideZoom.value = null;
188
+ this.pointerTrace.value = null;
189
+ this.setCursorPosition({
190
+ x: 0,
191
+ y: 0,
192
+ visible: false
193
+ });
194
+ return;
195
+ }
196
+ // A previous gesture's zoom may still be applied to the media — its hold hasn't elapsed, or its
197
+ // unzoom transition is still animating — so getBoundingClientRect reports the *zoomed* geometry.
198
+ // Recover the natural rect by inverting that known zoom before mapping the model's fraction onto
199
+ // it (measuring through the live transform would land the point in the wrong place).
200
+ const activeZoom = this.slideZoom.peek();
201
+ const rect = activeZoom ? unzoomRect(measured, activeZoom) : measured;
202
+ // The model's coordinates are fractions of the FRAME it perceives, which is the raw
203
+ // slide/video content (no letterbox). The element renders that content with object-fit:
204
+ // contain, so when the element box isn't the content's aspect ratio the picture is
205
+ // letterboxed inside it. Map onto the actual displayed content box (not the padded element
206
+ // rect) so the cursor lands where the model means — otherwise a non-matching aspect (common
207
+ // for videos) offsets the pointer.
208
+ const content = contentBox(slide, rect);
209
+ const x = content.left + nx * content.width;
210
+ const y = content.top + ny * content.height;
211
+ // Make the cursor glide to the spot rather than pop in. The CSS transform transition only
212
+ // animates if the cursor is already on-screen at a prior position, so if it's hidden we first
213
+ // show it at the viewport center, let the browser paint that frame, then move it to the target.
214
+ if (!this.cursorPosition.peek().visible) {
215
+ this.setCursorPosition({
216
+ x: window.innerWidth / 2 - CURSOR_OFFSET_PX,
217
+ y: window.innerHeight / 2 - CURSOR_OFFSET_PX,
218
+ visible: true
219
+ });
220
+ // Routed through the cursor-sequence set: if another point gesture starts during the
221
+ // glide pause, the promise is dropped and this gesture's continuation never runs.
222
+ await this.cursorSequenceDelay(CURSOR_GLIDE_START_DELAY_MS);
223
+ }
224
+ // Phase 1: glide the cursor to the (un-zoomed) target spot, with no zoom yet.
225
+ this.slideZoom.value = null;
226
+ this.setCursorPosition({
227
+ x,
228
+ y,
229
+ visible: true
230
+ });
231
+ // Size the magnification to the target box: a small box zooms in hard, a wide/tall one stays
232
+ // gentle so it isn't cropped by the zoom window. With no box, fall back to the default scale.
233
+ const scale = box ? zoomScaleForBox(box) : (/* inlined export .SLIDE_ZOOM_SCALE */1.3);
234
+ // Phase 2: once the cursor has reached the spot, zoom the media (slide image OR demo video) in
235
+ // toward it. Both apply slideZoomStyle from `slideZoom` (see components/decks + presentations).
236
+ // Routed through the cursor-sequence delay so a new point gesture starting mid-move drops this.
237
+ await this.cursorSequenceDelay(CURSOR_MOVE_DURATION_MS);
238
+ this.slideZoom.value = {
239
+ x: nx,
240
+ y: ny,
241
+ scale
242
+ };
243
+ // Phase 3: hold the zoom for SLIDE_ZOOM_HOLD_MS, then zoom back out (the cursor returns to the
244
+ // un-zoomed spot as the media unzooms) and hide the cursor + box. Scheduled from zoom-in time,
245
+ // independent of the trace below, so the zoom always lasts the full hold.
246
+ this.scheduleCursorSequenceTimer(()=>{
247
+ this.slideZoom.value = null;
248
+ this.pointerTrace.value = null;
249
+ this.setCursorPosition({
250
+ x,
251
+ y,
252
+ visible: false
253
+ });
254
+ }, SLIDE_ZOOM_HOLD_MS);
255
+ if (box) {
256
+ // Trace the bounding box with the cursor, drawing the border as it goes.
257
+ await this.traceRect(box, {
258
+ x: nx,
259
+ y: ny
260
+ }, content, scale);
261
+ } else {
262
+ // No box: the magnification pans the point toward center, so move the cursor to where it lands
263
+ // (slideZoomFocus) so it stays glued to the target as the media zooms.
264
+ const focus = slideZoomFocus({
265
+ x: nx,
266
+ y: ny
267
+ }, scale);
268
+ this.setCursorPosition({
269
+ x: content.left + focus.x * content.width,
270
+ y: content.top + focus.y * content.height,
271
+ visible: true
272
+ });
273
+ }
274
+ }
275
+ /**
276
+ * Trace the target's bounding box with the cursor on the zoomed video, drawing the border in the
277
+ * cursor's color as it goes. Each corner is mapped through the same zoom the media applies (so the
278
+ * box frames the zoomed content) and padded outward a little so the box sits just outside the
279
+ * element rather than hugging it. The cursor starts at the bottom-right corner and glides clockwise
280
+ * (BR -> BL -> TL -> TR -> BR) while PointerRectOverlay reveals the border for each side over the
281
+ * same per-side duration, so the line follows the cursor; it then rests just off the bottom-right
282
+ * corner. Every step is a cursor-sequence delay, so a new point gesture cancels the trace cleanly.
283
+ */ async traceRect(box, focal, content, scale) {
284
+ // Map a normalized content point through the zoom, then to viewport pixels — clamped to the
285
+ // content box so a box larger than the zoom window still traces along the media's edges.
286
+ const toScreen = (px, py)=>{
287
+ const z = slideZoomPoint(focal, {
288
+ x: px,
289
+ y: py
290
+ }, scale);
291
+ return {
292
+ x: content.left + Math.min(1, Math.max(0, z.x)) * content.width,
293
+ y: content.top + Math.min(1, Math.max(0, z.y)) * content.height
294
+ };
295
+ };
296
+ const tlPoint = toScreen(box.x1, box.y1);
297
+ const brPoint = toScreen(box.x2, box.y2);
298
+ // Pad the box outward so the drawn rectangle frames the element with a little breathing room
299
+ // instead of hugging its exact edges (the model's box is very tight).
300
+ const left = tlPoint.x - RECT_PADDING_PX;
301
+ const top = tlPoint.y - RECT_PADDING_PX;
302
+ const width = Math.max(0, brPoint.x - tlPoint.x) + 2 * RECT_PADDING_PX;
303
+ const height = Math.max(0, brPoint.y - tlPoint.y) + 2 * RECT_PADDING_PX;
304
+ // Padded corners the cursor visits.
305
+ const br = {
306
+ x: left + width,
307
+ y: top + height
308
+ };
309
+ const bl = {
310
+ x: left,
311
+ y: top + height
312
+ };
313
+ const tl = {
314
+ x: left,
315
+ y: top
316
+ };
317
+ const tr = {
318
+ x: left + width,
319
+ y: top
320
+ };
321
+ const perimeter = 2 * (width + height) || 1;
322
+ // Cumulative perimeter fraction revealed after each side is drawn, clockwise from the bottom-right:
323
+ // bottom (BR->BL), left (BL->TL), top (TL->TR), right (TR->BR).
324
+ const legs = [
325
+ {
326
+ corner: bl,
327
+ reveal: width / perimeter
328
+ },
329
+ {
330
+ corner: tl,
331
+ reveal: (width + height) / perimeter
332
+ },
333
+ {
334
+ corner: tr,
335
+ reveal: (2 * width + height) / perimeter
336
+ },
337
+ {
338
+ corner: br,
339
+ reveal: 1
340
+ }
341
+ ];
342
+ // Show the (undrawn) box and glide the cursor to the bottom-right corner to start the trace.
343
+ this.pointerTrace.value = {
344
+ left,
345
+ top,
346
+ width,
347
+ height,
348
+ reveal: 0,
349
+ transitionMs: 0
350
+ };
351
+ this.setCursorPosition({
352
+ x: br.x,
353
+ y: br.y,
354
+ visible: true
355
+ });
356
+ await this.cursorSequenceDelay(CURSOR_MOVE_DURATION_MS);
357
+ for (const leg of legs){
358
+ this.pointerTrace.value = {
359
+ left,
360
+ top,
361
+ width,
362
+ height,
363
+ reveal: leg.reveal,
364
+ transitionMs: RECT_TRACE_LEG_MS
365
+ };
366
+ // Speed the cursor's glide to match the faster border reveal so the two stay in lockstep.
367
+ this.setCursorPosition({
368
+ x: leg.corner.x,
369
+ y: leg.corner.y,
370
+ visible: true,
371
+ transitionMs: RECT_TRACE_LEG_MS
372
+ });
373
+ // Sequential by design: each side is drawn only after the cursor finishes the previous one.
374
+ // eslint-disable-next-line no-await-in-loop
375
+ await this.cursorSequenceDelay(RECT_TRACE_LEG_MS);
376
+ }
377
+ // Rest the cursor just off the bottom-right corner so it sits beside the finished box, not on it.
378
+ this.setCursorPosition({
379
+ x: br.x + RECT_REST_OFFSET_PX,
380
+ y: br.y + RECT_REST_OFFSET_PX,
381
+ visible: true
382
+ });
383
+ }
384
+ /**
385
+ * The on-screen element the agent is pointing at — a slide image (deck or single slide) or the
386
+ * demo video currently playing — looked up inside the multimodal widget's shadow root. Its
387
+ * viewport rect is what we map the normalized [0,1] point coordinates onto. Only one of these is
388
+ * ever mounted at a time (the artifact overlay shows a single thing), so first-match is correct.
389
+ */ currentSlideElement() {
390
+ const host = document.getElementById(MULTIMODAL_HOST_ID);
391
+ const root = host == null ? void 0 : host.shadowRoot;
392
+ if (!root) return null;
393
+ // Slides are plain styled elements, so we match their data-component-name. The demo video is a
394
+ // <Persisted> element, which applies attributes as JS properties (not DOM attributes) — so
395
+ // data-component-name isn't queryable on it. Its id ("presentation-video") IS a reflected DOM
396
+ // attribute, so we target the video by id instead.
397
+ return root.querySelector('[data-component-name="Deck.SlideImage"], [data-component-name="Slide.SlideImage"], #presentation-video');
398
+ }
399
+ /**
400
+ * Resolve a co-browse node-id to the live host-page element. The Shipper (running because a call
401
+ * with page perception is active) exposes the reverse lookup on the host window. Returns null when
402
+ * unavailable or when the node isn't an element.
403
+ */ elementForNodeId(nodeId) {
404
+ var _ref;
405
+ if (nodeId == null) return null;
406
+ const lookup = window.__qlfdNodeForId;
407
+ const node = (_ref = lookup == null ? void 0 : lookup(nodeId)) != null ? _ref : null;
408
+ if (!node) return null;
409
+ const el = node.nodeType === Node.ELEMENT_NODE ? node : node.parentElement;
410
+ return el != null ? el : null;
411
+ }
412
+ /**
413
+ * Scroll an element into view, land the cursor on it, and highlight it. Shared by the
414
+ * share_website text flow (highlightText) and the point_at_page node-id flow (pointAtNode).
415
+ */ async pointCursorAtElement(element, param) {
416
+ let { scroll = true } = param === void 0 ? {} : param;
417
+ // Cancel any highlight/hide cascade still pending from a previous point gesture so its
418
+ // stale hide (captured at the old coordinates) can't fire during this one.
419
+ this.cancelCursorSequenceTimers();
420
+ // Detect surface darkness up front so the cursor can pick a contrasting color before it lands.
421
+ const onDarkSurface = this.isOnDarkSurface(element);
422
+ let rect;
423
+ if (scroll) {
424
+ element.scrollIntoView({
425
+ behavior: "smooth",
426
+ block: "center",
427
+ inline: "nearest"
428
+ });
429
+ // Wait for the smooth scroll to settle before measuring, so the cursor lands accurately.
430
+ rect = await this.waitForStableRect(element);
431
+ } else {
432
+ // No scroll: the element is already in view, so measure it where it is.
433
+ rect = element.getBoundingClientRect();
434
+ }
435
+ // Move cursor to bottom right of the element.
436
+ this.setCursorPosition({
437
+ x: rect.right - CURSOR_ELEMENT_OFFSET_PX,
438
+ y: rect.bottom - CURSOR_ELEMENT_OFFSET_PX,
439
+ visible: true,
440
+ onDarkSurface
441
+ });
442
+ // After cursor arrives, highlight the element, then hide the cursor shortly after.
443
+ this.scheduleCursorSequenceTimer(()=>{
444
+ this.applyHighlight(element);
445
+ this.scheduleCursorSequenceTimer(()=>{
446
+ this.setCursorPosition({
447
+ x: rect.right - CURSOR_ELEMENT_OFFSET_PX,
448
+ y: rect.bottom - CURSOR_ELEMENT_OFFSET_PX,
449
+ visible: false,
450
+ onDarkSurface
451
+ });
452
+ }, CURSOR_HIDE_DELAY_MS);
453
+ }, CURSOR_POSITION_DELAY_MS);
454
+ }
455
+ /**
456
+ * Set the cursor position for the co-browsing overlay.
457
+ */ setCursorPosition(position) {
458
+ this.cursorPosition.value = position;
459
+ }
460
+ /**
461
+ * Initialize navigation interception to handle user-initiated link clicks.
462
+ * Uses the Navigation API on Chromium browsers, falls back to click capture
463
+ * on Firefox/Safari until they implement the Navigation API.
464
+ *
465
+ * Should be called when entering voice/video mode.
466
+ */ initNavigationInterceptor() {
467
+ const strategy = this.navigationStrategies.find((s)=>s.isApplicable());
468
+ if (!strategy || strategy.needsInterceptor) {
469
+ this.navigationInterceptor.init();
470
+ }
471
+ }
472
+ /**
473
+ * Dispose of the navigation interceptor and remove event listeners.
474
+ * Should be called when leaving voice/video mode.
475
+ */ disposeNavigationInterceptor() {
476
+ this.navigationInterceptor.dispose();
477
+ }
478
+ /**
479
+ * Dispose of the store by clearing all active timers and removing event listeners.
480
+ * Should be called when the store is no longer needed.
481
+ */ dispose() {
482
+ this.clearAllTimers();
483
+ this.slideZoom.value = null;
484
+ this.pointerTrace.value = null;
485
+ this.navigationInterceptor.dispose();
486
+ }
487
+ /**
488
+ * Navigate to a URL using the best available strategy.
489
+ * @returns Post-navigation callback if any cleanup is needed (e.g., run scripts)
490
+ * @throws If no strategy can handle it (e.g., cross-origin URL)
491
+ */ async navigate(url) {
492
+ const target = new URL(url, window.location.origin);
493
+ const strategy = this.navigationStrategies.find((s)=>s.isApplicable());
494
+ if (!strategy || !isSameOrigin(target)) {
495
+ throw new Error("No navigation strategy can handle URL: " + url);
496
+ }
497
+ const postNavigate = await strategy.navigate(target);
498
+ return async ()=>{
499
+ await (postNavigate == null ? void 0 : postNavigate());
500
+ this.rootStore.dockingStore.reEvaluate();
501
+ };
502
+ }
503
+ /**
504
+ * Schedule a timer and track it for cleanup.
505
+ */ scheduleTimer(callback, delay) {
506
+ const timerId = website_navigation_store_setTimeout(callback, delay);
507
+ this.activeTimerIds.add(timerId);
508
+ return timerId;
509
+ }
510
+ /**
511
+ * Schedule a timer belonging to the current cursor point/highlight/hide gesture.
512
+ * Cancelled wholesale by `cancelCursorSequenceTimers()` when a new gesture starts,
513
+ * and by `clearAllTimers()` on dispose.
514
+ */ scheduleCursorSequenceTimer(callback, delay) {
515
+ const timerId = this.scheduleTimer(()=>{
516
+ this.activeTimerIds.delete(timerId);
517
+ this.cursorSequenceTimerIds.delete(timerId);
518
+ callback();
519
+ }, delay);
520
+ this.cursorSequenceTimerIds.add(timerId);
521
+ }
522
+ /**
523
+ * Like `delay()`, but the timer is part of the current cursor gesture: if a new
524
+ * gesture starts (or the store is disposed) before it elapses, the promise is left
525
+ * unresolved and the awaiting continuation is dropped along with the stale gesture.
526
+ */ cursorSequenceDelay(ms) {
527
+ return new Promise((resolve)=>{
528
+ this.scheduleCursorSequenceTimer(resolve, ms);
529
+ });
530
+ }
531
+ /**
532
+ * Cancel all timers belonging to the previous cursor gesture (see
533
+ * `cursorSequenceTimerIds`).
534
+ */ cancelCursorSequenceTimers() {
535
+ for (const timerId of this.cursorSequenceTimerIds){
536
+ website_navigation_store_clearTimeout(timerId);
537
+ this.activeTimerIds.delete(timerId);
538
+ }
539
+ this.cursorSequenceTimerIds.clear();
540
+ }
541
+ /**
542
+ * Clear all active timers.
543
+ */ clearAllTimers() {
544
+ for (const timerId of this.activeTimerIds){
545
+ website_navigation_store_clearTimeout(timerId);
546
+ }
547
+ this.activeTimerIds.clear();
548
+ }
549
+ /**
550
+ * Create a delay promise that can be used with async/await.
551
+ */ delay(ms) {
552
+ return new Promise((resolve)=>{
553
+ const timerId = this.scheduleTimer(()=>{
554
+ this.activeTimerIds.delete(timerId);
555
+ resolve();
556
+ }, ms);
557
+ });
558
+ }
559
+ applyHighlight(element) {
560
+ const isDark = this.isOnDarkSurface(element);
561
+ const baseColor = isDark ? this.getThemeVar("--q-lighter-primary-color") : this.getThemeVar("--q-primary-color");
562
+ const alpha = isDark ? DARK_SURFACE_HIGHLIGHT_OPACITY : HIGHLIGHT_OPACITY;
563
+ element.style.backgroundColor = hexToRgba(baseColor, alpha);
564
+ element.style.transition = "background-color " + TRANSITION_DURATION_MS + "ms ease-in-out";
565
+ }
566
+ getThemeVar(name, fallback) {
567
+ if (fallback === void 0) fallback = DEFAULT_PRIMARY_COLOR;
568
+ const host = document.getElementById(MULTIMODAL_HOST_ID);
569
+ return ((host == null ? void 0 : host.style.getPropertyValue(name)) || getComputedStyle(host || document.documentElement).getPropertyValue(name) || fallback).trim();
570
+ }
571
+ // Light text (high luminance) implies a dark background.
572
+ isOnDarkSurface(element) {
573
+ const textColor = this.extractTextColor(element);
574
+ if (textColor) return this.relativeLuminance(textColor) > 1 - DARK_SURFACE_LUMINANCE_THRESHOLD;
575
+ return false;
576
+ }
577
+ extractTextColor(element) {
578
+ const { color } = getComputedStyle(element);
579
+ if (!color) return null;
580
+ const match = color.match(/rgba?\(\s*(\d+),\s*(\d+),\s*(\d+)/);
581
+ if (!match) return null;
582
+ return [
583
+ parseInt(match[1], 10),
584
+ parseInt(match[2], 10),
585
+ parseInt(match[3], 10)
586
+ ];
587
+ }
588
+ relativeLuminance(param) {
589
+ let [r, g, b] = param;
590
+ const toLinear = (c)=>{
591
+ const s = c / 255;
592
+ return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
593
+ };
594
+ return 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);
595
+ }
596
+ /**
597
+ * Perform soft navigation to a URL.
598
+ * Updates history, fetches the page, and swaps the DOM.
599
+ * This is passed to NavigationInterceptor for user-initiated navigation.
600
+ */ async navigateSoftly(url, options) {
601
+ if (options === void 0) options = {};
602
+ const { history = "push", scroll = "top" } = options;
603
+ try {
604
+ const postNavigate = await this.navigate(url);
605
+ // Update history if needed (for fallback mode where we manage history ourselves)
606
+ if (history === "push") {
607
+ window.history.pushState({
608
+ __live: true
609
+ }, "", url);
610
+ } else if (history === "replace") {
611
+ window.history.replaceState({
612
+ __live: true
613
+ }, "", url);
614
+ }
615
+ // Run post-navigation
616
+ await postNavigate();
617
+ // Notify the backend so the multimodal agent knows the visitor navigated.
618
+ // Use window.location.href (not the original url) to capture the final URL after any redirects.
619
+ this.notifyPageNavigation(window.location.href);
620
+ // Scroll to top if requested
621
+ if (scroll === "top") {
622
+ window.scrollTo(0, 0);
623
+ }
624
+ } catch (unused) {
625
+ // If soft navigation fails, fall back to hard navigation
626
+ window.location.href = url;
627
+ }
628
+ }
629
+ /**
630
+ * Notify the backend that the visitor navigated to a new page.
631
+ * Deduplicates by comparing against the last notified URL.
632
+ */ notifyPageNavigation(url) {
633
+ const normalizedUrl = normalizeToBaseUrl(url);
634
+ // Skip if this URL was already reported
635
+ if (normalizedUrl === this.lastNotifiedUrl) return;
636
+ this.lastNotifiedUrl = normalizedUrl;
637
+ this.rootStore.channel.perform("notify_page_navigation", {
638
+ url: normalizedUrl
639
+ });
640
+ }
641
+ /**
642
+ * Resolve once the element's rect has been unchanged for ~500ms,
643
+ * or with the latest rect after `timeoutMs` so callers never hang.
644
+ *
645
+ * The polling timers are routed through `scheduleTimer` so `dispose()` /
646
+ * `clearAllTimers()` can cancel them. If the store is disposed before the
647
+ * watcher settles, no further DOM reads happen and the promise is left
648
+ * unresolved (matching `delay()`'s existing semantics) — the awaiting
649
+ * caller's continuation is dropped along with the rest of the store.
650
+ */ waitForStableRect(element, timeoutMs) {
651
+ if (timeoutMs === void 0) timeoutMs = SCROLL_STABILITY_TIMEOUT_MS;
652
+ return new Promise((resolve)=>{
653
+ const startTime = performance.now();
654
+ let stableCount = 0;
655
+ let prevRect = element.getBoundingClientRect();
656
+ const scheduleTick = ()=>{
657
+ const timerId = this.scheduleTimer(()=>{
658
+ this.activeTimerIds.delete(timerId);
659
+ tick();
660
+ }, RECT_STABILITY_POLL_INTERVAL_MS);
661
+ };
662
+ const tick = ()=>{
663
+ const newRect = element.getBoundingClientRect();
664
+ const isStable = newRect.top === prevRect.top && newRect.left === prevRect.left && newRect.right === prevRect.right && newRect.bottom === prevRect.bottom;
665
+ if (isStable) {
666
+ stableCount += 1;
667
+ if (stableCount >= RECT_STABILITY_REQUIRED_SAMPLES) {
668
+ resolve(newRect);
669
+ return;
670
+ }
671
+ } else {
672
+ // A single moving sample resets the streak so we only resolve on
673
+ // truly consecutive stable frames (smooth scrolls can briefly
674
+ // pause mid-motion and we don't want to call those "settled").
675
+ stableCount = 0;
676
+ }
677
+ if (performance.now() - startTime >= timeoutMs) {
678
+ // Timed out — fall through with the latest rect rather than hang
679
+ // forever on a page that never stops animating.
680
+ resolve(newRect);
681
+ return;
682
+ }
683
+ prevRect = newRect;
684
+ scheduleTick();
685
+ };
686
+ scheduleTick();
687
+ });
688
+ }
689
+ // eslint-disable-next-line no-useless-constructor
690
+ constructor(rootStore){
691
+ this.rootStore = rootStore;
692
+ this.cursorPosition = signals_core_module_d({
693
+ x: 0,
694
+ y: 0,
695
+ visible: false
696
+ });
697
+ // Focal point (normalized [0,1] within the media element) the on-screen slide/video should zoom
698
+ // toward while the cursor points, or null for no zoom, plus the magnification to apply (chosen from
699
+ // the target box so a small target zooms in hard and a wide one stays gentle — see zoomScaleForBox).
700
+ // The media components read this and apply slideZoomStyle so the media zooms in place.
701
+ this.slideZoom = signals_core_module_d(null);
702
+ // Bounding box (viewport pixels) the cursor is tracing on the zoomed video, or null when not
703
+ // tracing. `reveal` is the fraction of the perimeter drawn so far and `transitionMs` how long to
704
+ // animate to it; the PointerRectOverlay draws the border in sync with the cursor's glide. See
705
+ // pointAtSlide -> traceRect.
706
+ this.pointerTrace = signals_core_module_d(null);
707
+ // Navigation interceptor for handling user-initiated link clicks
708
+ this.navigationInterceptor = new NavigationInterceptor(this.navigateSoftly.bind(this));
709
+ // Tracks the last URL sent to the backend to avoid duplicate notifications
710
+ this.lastNotifiedUrl = null;
711
+ // Order matters - first match wins. SPA-router strategies come before
712
+ // dom_swap since dom_swap is a brute-force fallback that re-executes the
713
+ // page's bootstrap scripts and breaks on frameworks that freeze globals.
714
+ this.navigationStrategies = [
715
+ wouter_v3,
716
+ lwr,
717
+ next_js,
718
+ // Always last as a fallback
719
+ dom_swap
720
+ ];
721
+ this.activeTimerIds = new Set();
722
+ /**
723
+ * Timers driving the *current* point/highlight/hide cursor gesture (a subset of
724
+ * `activeTimerIds`). Each new point gesture cancels these so a stale hide timer —
725
+ * whose callback captured the previous gesture's coordinates — can't jump the
726
+ * cursor back and hide it mid-gesture.
727
+ */ this.cursorSequenceTimerIds = new Set();
728
+ }
729
+ }
730
+
731
+ /**
732
+ * The rect of the actual displayed content inside an element that renders intrinsic media with
733
+ * `object-fit: contain` — accounting for letterbox bars when the element box and the content have
734
+ * different aspect ratios (e.g. a 16:9 video in a taller box). Falls back to the full element rect
735
+ * when the intrinsic size is unknown (metadata not loaded yet) or the element isn't a video/image,
736
+ * so a slide image that fills its box is unaffected.
737
+ */ function contentBox(el, rect) {
738
+ let intrinsicW = 0;
739
+ let intrinsicH = 0;
740
+ if (el instanceof HTMLVideoElement) {
741
+ intrinsicW = el.videoWidth;
742
+ intrinsicH = el.videoHeight;
743
+ } else if (el instanceof HTMLImageElement) {
744
+ intrinsicW = el.naturalWidth;
745
+ intrinsicH = el.naturalHeight;
746
+ }
747
+ if (intrinsicW < 1 || intrinsicH < 1) {
748
+ return {
749
+ left: rect.left,
750
+ top: rect.top,
751
+ width: rect.width,
752
+ height: rect.height
753
+ };
754
+ }
755
+ const scale = Math.min(rect.width / intrinsicW, rect.height / intrinsicH);
756
+ const width = intrinsicW * scale;
757
+ const height = intrinsicH * scale;
758
+ return {
759
+ left: rect.left + (rect.width - width) / 2,
760
+ top: rect.top + (rect.height - height) / 2,
761
+ width,
762
+ height
763
+ };
764
+ }
765
+
766
+ export { CURSOR_MOVE_DURATION_MS, RECT_TRACE_LEG_MS, SLIDE_ZOOM_HOLD_MS };
767
+ export default WebsiteNavigationStore;