1!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._posthogChunkIds=e._posthogChunkIds||{},e._posthogChunkIds[n]="01a0804f-8530-70d2-8e8e-acee8a012ed6")}catch(e){}}();(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,843727,e=>{"use strict";var t=e.i(651034);function n(e){return e.replace(/<\/(script)/gi,"<\\/$1").replace(/<!--/g,"<\\!--").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")}e.s(["buildWidgetCode",0,function(e,t,r,a,i){let o=n(JSON.stringify(t)),s=n(JSON.stringify(r)),l=n(JSON.stringify(a)),d=n(JSON.stringify(i));return` 2// Widget data injection 3window.__WIDGET_DATA__ = ${o}; 4window.__WIDGET_COLLAPSED__ = ${s}; 5window.__PARENT_ORIGIN__ = ${l}; 6 7// Widget component code 8${e} 9 10// Render the widget 11(function(widgetSessionToken) { 12 var rootEl = document.getElementById('root'); 13 if (!rootEl) { 14 console.error('Widget root element not found'); 15 return; 16 } 17 18 if (typeof Widget !== 'function') { 19 console.error( 20 'Widget function not defined. The widget code must export a function named "Widget".' 21 ); 22 window.parent.postMessage( 23 { 24 type: 'sdk-error', 25 error: { 26 message: 27 'Widget function not defined. The widget code must export a function named "Widget".', 28 } 29 }, 30 window.__PARENT_ORIGIN__ 31 ); 32 return; 33 } 34 35 try { 36 function updateCollapsedStateAttribute() { 37 document.body.setAttribute( 38 'data-widget-collapsed', 39 window.__WIDGET_COLLAPSED__ ? 'true' : 'false' 40 ); 41 } 42 updateCollapsedStateAttribute(); 43 44 var root = ReactDOM.createRoot(rootEl); 45 root.render( 46 React.createElement(Widget, { 47 data: window.__WIDGET_DATA__, 48 isCollapsed: window.__WIDGET_COLLAPSED__ 49 }) 50 ); 51 52 // Prevent margin collapsing through #root so contentRect.height is accurate 53 rootEl.style.overflow = 'hidden'; 54 55 function getContentWidth() { 56 var children = rootEl.children; 57 var maxChildWidth = 0; 58 var minChildLeft = Infinity; 59 var maxChildRight = -Infinity; 60 for (var childIndex = 0; childIndex < children.length; childIndex += 1) { 61 var child = children[childIndex]; 62 if (child && typeof child.getBoundingClientRect === 'function') { 63 var rect = child.getBoundingClientRect(); 64 var childWidth = Math.ceil(rect.width); 65 if (Number.isFinite(childWidth) && childWidth > maxChildWidth) { 66 maxChildWidth = childWidth; 67 } 68 if ( 69 Number.isFinite(rect.left) && 70 Number.isFinite(rect.right) && 71 rect.right > rect.left 72 ) { 73 if (rect.left < minChildLeft) { 74 minChildLeft = rect.left; 75 } 76 if (rect.right > maxChildRight) { 77 maxChildRight = rect.right; 78 } 79 } 80 } 81 } 82 83 var combinedChildrenWidth = 0; 84 if ( 85 Number.isFinite(minChildLeft) && 86 Number.isFinite(maxChildRight) && 87 maxChildRight > minChildLeft 88 ) { 89 combinedChildrenWidth = Math.ceil(maxChildRight - minChildLeft); 90 } 91 var measuredChildrenWidth = Math.max(maxChildWidth, combinedChildrenWidth); 92 if (Number.isFinite(measuredChildrenWidth) && measuredChildrenWidth > 0) { 93 return measuredChildrenWidth; 94 } 95 96 var clientWidth = Math.ceil(rootEl.clientWidth || 0); 97 var scrollWidth = Math.ceil(rootEl.scrollWidth || 0); 98 var offsetWidth = Math.ceil(rootEl.offsetWidth || 0); 99 var fallbackWidth = Math.max(scrollWidth, offsetWidth); 100 if ( 101 Number.isFinite(fallbackWidth) && 102 fallbackWidth > 0 && 103 (clientWidth <= 0 || fallbackWidth > clientWidth + 2) 104 ) { 105 return fallbackWidth; 106 } 107 108 return 0; 109 } 110 111 // Set up ResizeObserver to notify parent of content size changes 112 var __MIN_HEIGHT = 80; 113 var lastHeight = 0; 114 var lastWidth = 0; 115 var pendingHeight = 0; 116 var hasPendingHeight = false;
117 var resizeScheduleHandle = null; 118 function postResize(height, width) { 119 var resizePayload = { type: 'resize', height: height }; 120 if (width > 0) { 121 resizePayload.width = width; 122 } 123 window.parent.postMessage(resizePayload, window.__PARENT_ORIGIN__); 124 } 125 126 function flushScheduledResize() { 127 resizeScheduleHandle = null; 128 function getOverlayBottom() { 129 // Widgets run inside iframes. Many UI overlays (Popover/Select/DropdownMenu) 130 // are rendered in Radix portals and positioned fixed, so they: 131 // - don't affect rootEl scrollHeight 132 // - don't trigger the rootEl ResizeObserver 133 // This can lead to clipped overlays when they extend past the iframe bounds. 134 // 135 // We detect common Radix popper wrappers and expand the measured iframe 136 // height to include the furthest visible overlay. 137 if (typeof document === "undefined") return 0; 138 139 var nodes = document.querySelectorAll( 140 "[data-radix-popper-content-wrapper]" 141 ); 142 if (!nodes || nodes.length === 0) return 0; 143 144 var scrollY = 145 window.scrollY || document.documentElement.scrollTop || 0; 146 var maxBottom = 0; 147 for (var nodeIndex = 0; nodeIndex < nodes.length; nodeIndex += 1) { 148 var node = nodes[nodeIndex]; 149 if (!node || typeof node.getBoundingClientRect !== "function") continue; 150 151 var rect = node.getBoundingClientRect(); 152 if (!rect) continue; 153 154 var rectHeight = rect.bottom - rect.top; 155 var rectWidth = rect.right - rect.left; 156 if (!Number.isFinite(rectHeight) || rectHeight <= 0) continue; 157 if (!Number.isFinite(rectWidth) || rectWidth <= 0) continue; 158 159 var bottom = rect.bottom + scrollY; 160 if (Number.isFinite(bottom) && bottom > maxBottom) { 161 maxBottom = bottom; 162 } 163 } 164 165 // Small padding so shadows/rounded corners aren't clipped at the edge. 166 return maxBottom > 0 ? Math.ceil(maxBottom + 8) : 0; 167 } 168 169 var measuredHeightBase = hasPendingHeight 170 ? pendingHeight 171 : Math.ceil(rootEl.scrollHeight || rootEl.offsetHeight || 0); 172 hasPendingHeight = false; 173 if (measuredHeightBase <= 0) { 174 measuredHeightBase = __MIN_HEIGHT; 175 } 176 var overlayBottom = getOverlayBottom(); 177 var measuredHeight = Math.max(measuredHeightBase, overlayBottom); 178 var measuredWidth = getContentWidth(); 179 if ( 180 Math.abs(measuredHeight - lastHeight) > 2 || 181 Math.abs(measuredWidth - lastWidth) > 2 182 ) { 183 lastHeight = measuredHeight; 184 lastWidth = measuredWidth; 185 postResize(measuredHeight, measuredWidth); 186 } 187 } 188 189 function scheduleResize(heightHint) { 190 if ( 191 typeof heightHint === 'number' && 192 Number.isFinite(heightHint) && 193 heightHint > 0 194 ) { 195 pendingHeight = Math.ceil(heightHint); 196 hasPendingHeight = true; 197 } 198 if (resizeScheduleHandle !== null) { 199 return; 200 } 201 if (typeof requestAnimationFrame === 'function') { 202 resizeScheduleHandle = requestAnimationFrame(flushScheduledResize); 203 return; 204 } 205 resizeScheduleHandle = setTimeout(flushScheduledResize, 16); 206 } 207 208 // Content may have changed while the host ignored resize messages (it 209 // suppresses them during overlay promotion); dropping the dedupe memory 210 // guarantees one fresh report. 211 function forceFreshResizeReport() { 212 lastHeight = 0; 213 lastWidth = 0; 214 scheduleResize(); 215 } 216 217 var resizeObserver = new ResizeObserver(function(entries) { 218 for (var entry of entries) { 219 scheduleResize(entry.contentRect.height); 220 } 221 }); 222 resizeObserver.observe(rootEl); 223 224 // Popper overlays (Popover/Select/DropdownMenu) mount in portals outside 225 // #root and won't trigger rootEl's ResizeObserver; observe body mutations 226 // and re-measure so the iframe grows to fit them. This observer is 227 // resize-only: overlay escalation is intent-driven via the viewport 228 // bridge, never DOM-detected. 229 if (typeof MutationObserver === 'function') { 230 var mutationObserver = new MutationObserver(function() { 231 scheduleResize(); 232 // Some overlays compute position after mount; re-check shortly after. 233 setTimeout(scheduleResize, 60); 234 }); 235 mutationObserver.observe(document.body, { childList: true, subtree: true }); 236 } 237 238 // Send initial size on the next frame to ensure layout is computed
239 var __didSendInitial = false; 240 var sendInitialSize = function() { 241 if (__didSendInitial) return; 242 __didSendInitial = true; 243 var height = rootEl.scrollHeight || rootEl.offsetHeight || 0; 244 if (height <= 0) { 245 height = __MIN_HEIGHT; 246 } 247 var width = getContentWidth(); 248 lastHeight = height; 249 lastWidth = width; 250 postResize(height, width); 251 // Signal ready to parent after the first size post 252 // Use 'app-ready' for consistency with createIframeHost which widgets use for SDK access 253 window.parent.postMessage({ type: 'app-ready' }, window.__PARENT_ORIGIN__); 254 255 // React render can commit after the first size post in some environments. 256 // Re-check shortly after mount to converge width/height even without an observer tick. 257 setTimeout(function() { 258 var followupHeight = rootEl.scrollHeight || rootEl.offsetHeight || 0; 259 if (followupHeight <= 0) { 260 followupHeight = __MIN_HEIGHT; 261 } 262 var followupWidth = getContentWidth(); 263 if ( 264 Math.abs(followupHeight - lastHeight) > 2 || 265 Math.abs(followupWidth - lastWidth) > 2 266 ) { 267 lastHeight = followupHeight; 268 lastWidth = followupWidth; 269 postResize(followupHeight, followupWidth); 270 } 271 }, 180); 272 }; 273 274 if (typeof requestAnimationFrame === 'function') { 275 requestAnimationFrame(sendInitialSize); 276 } 277 // Fallback: ensure ready even if rAF is throttled in hidden/zero-sized iframes 278 setTimeout(sendInitialSize, 50); 279 280 281 // ---- Modal overlay escalation ---- 282 // A modal overlay (dialog, alert dialog, drawer, sheet) cannot render 283 // usefully inside the widget box: position:fixed resolves against the 284 // iframe viewport. When one opens, the host promotes this iframe to the 285 // browser top layer so the overlay owns the real page; #root gets pinned 286 // at the widget's slot rect so the card appears to never move. 287 // 288 // The geometry handoff is expressed as viewport-conditional CSS injected 289 // BEFORE the host resizes the iframe (widget-promote-pending carries the 290 // slot rect and the target viewport). The pin and the transparent body 291 // key off a media query that only matches the promoted viewport, so the 292 // browser applies them atomically in the same layout pass as the resize: 293 // the card never paints unpinned. The overlay reveal is deliberately NOT 294 // media-keyed: it waits for the class release after the promoted 295 // viewport settles, so the host's slot clip (stale-frame guard) is 296 // already lifted when the enter starts. 297 // Everything an in-flight overlay paints (popups AND backdrops), hidden 298 // while a promotion handshake is running so nothing renders squeezed in 299 // the slot-sized iframe. 300 var OVERLAY_HIDE_SELECTOR = [ 301 '[data-slot="dialog-content"]', 302 '[data-slot="dialog-overlay"]', 303 '[data-slot="alert-dialog-content"]', 304 '[data-slot="alert-dialog-overlay"]', 305 '[data-slot="drawer-popup"]', 306 '[data-slot="drawer-overlay"]', 307 '[data-slot="sheet-content"]', 308 '[data-slot="sheet-overlay"]' 309 ].map(function (selector) { 310 return 'html.snow-overlay-promoting ' + selector; 311 }).join(', '); 312 // Hidden overlays are also held at their enter start state with the 313 // enter animation suppressed: the enter clock starts at mount, so a slow 314 // handshake would consume it invisibly and the overlay would pop in 315 // mid-flight or already at rest. Every hold is class-gated and releases 316 // at the class removal in completeOverlayHandshake (deferred past the 317 // viewport settle plus a few frames), so the enter always plays in full 318 // and only after the host dropped its slot clip. Two enter mechanisms 319 // survive that release identically: 320 // - The drawer enters via a TRANSITION (Base UI starting-style), which 321 // only fires when the held state has painted a frame first; the 322 // deferred release guarantees that paint. 323 // - The others enter via CSS ANIMATIONS, which restart from scratch 324 // whenever animation: none is dropped, no prior paint needed. 325 var DRAWER_ENTER_HOLD_RULES = 326 'html.snow-overlay-promoting [data-slot="drawer-popup"] { transform: translate3d(0, 100%, 0) !important; transition: none !important; } ' + 327 'html.snow-overlay-promoting [data-slot="drawer-overlay"] { opacity: 0 !important; transition: none !important; }'; 328 var ANIMATED_ENTER_HOLD_RULES = [ 329 '[data-slot="dialog-content"]', 330 '[data-slot="dialog-overlay"]', 331 '[data-slot="alert-dialog-content"]', 332 '[data-slot="alert-dialog-overlay"]', 333 '[data-slot="sheet-content"]', 334 '[data-slot="sheet-overlay"]' 335 ].map(function (selector) { 336 return 'html.snow-overlay-promoting ' + selector; 337 }).join(', ') + ' { animation: none !important; }'; 338 var UNCONDITIONAL_GUARD_RULES = 339 OVERLAY_HIDE_SELECTOR + ' { visibility: hidden !important; transition: none !important; } ' +
340 DRAWER_ENTER_HOLD_RULES + ' ' + ANIMATED_ENTER_HOLD_RULES; 341 // Two style elements with one owner each. The guard element carries the 342 // class-gated hide/enter-hold rules; the pin element carries the #root 343 // pin geometry. Separate on purpose: an overlay that opens while a close 344 // handshake is still in flight needs fresh hide rules while the 345 // demote-settle pin is still filling the stale texture, and one shared 346 // element cannot hold both without one write clobbering the other. 347 var escalationGuardStyleEl = document.createElement('style'); 348 var escalationPinStyleEl = document.createElement('style'); 349 (document.head || document.documentElement).appendChild(escalationGuardStyleEl); 350 (document.head || document.documentElement).appendChild(escalationPinStyleEl); 351 var overlayEscalationOpen = false; 352 var overlayPromotingTimeout = null; 353 var promotionTarget = null; 354 var promotionCondition = null; 355 var promotionRect = null; 356 var promotionRadius = 24; 357 var promotionAttemptId = null; 358 // Intent reconciliation pauses between posting a state transition and the 359 // host's ack: the handshake hides overlays, and double-posting mid-flight 360 // would desync the promote/demote handshake. 361 var overlayHandshakePending = false; 362 // Promotion requires a prior user gesture inside the widget. Without it 363 // (an overlay opened on mount), the overlay stays contained: a widget 364 // must not seize the full viewport before the user ever touched it. 365 var hasUserEngagement = false; 366 document.addEventListener('pointerdown', function () { 367 hasUserEngagement = true; 368 }, true); 369 document.addEventListener('keydown', function () { 370 hasUserEngagement = true; 371 }, true); 372 373 // In-iframe Escape collapses a pure api expansion, mirroring the host 374 // window's Escape. Bubble phase + defaultPrevented leave overlays their 375 // say (Base UI prevents the Escape it consumes), and open overlay 376 // tokens skip it entirely: a modal-held promotion exits through the 377 // modal's own close. 378 window.addEventListener('keydown', function (event) { 379 if (event.key !== 'Escape' || event.defaultPrevented) return; 380 if (!viewportPromoted || !apiDesiredExpanded) return; 381 if (openOverlayTokenCount() > 0) return; 382 apiDesiredExpanded = false; 383 apiAuthorizationGrantId = null; 384 pendingCollapseReason = 'host'; 385 scheduleEscalationReconcile(); 386 }); 387 388 // ---- Viewport intent bridge ---- 389 // Escalation is intent-driven, never DOM-detected: the runtime's modal 390 // components announce their lifecycle through registerOverlay tokens 391 // (mount = actually open, both controlled and uncontrolled; release = 392 // exit finished or removed while open), and sdk.viewport drives the 393 // api side. See docs/decisions/sdk-viewport-areas.md. 394 var overlayTokens = []; 395 var overlayClosingReported = false; 396 var apiDesiredExpanded = false; 397 // Stage the api expansion asked for ('card' | 'plane' | 'page'); always 398 // explicit - expand() without an area rejects. Phones collapse every 399 // stage to the full screen host-side. 400 var apiDesiredArea = null; 401 var apiAuthorizationGrantId = null; 402 // Stage the host granted in widget-promoted. 403 var promotedArea = null; 404 // Stage ordering for the promoted-state resolve/reject decision. 405 var AREA_RANK = { card: 1, plane: 2, page: 3 }; 406 var apiPendingIntent = null; 407 var apiAuthorizationRequestId = 0; 408 var viewportPromoted = false; 409 var overlayEscalationSource = null; 410 var viewportChangeHandlers = []; 411 var pendingCollapseReason = null; 412 var escalationReconcileQueued = false; 413 414 function postEscalationMessage(message) { 415 message.sessionToken = widgetSessionToken; 416 window.parent.postMessage(message, window.__PARENT_ORIGIN__); 417 } 418 419 function openOverlayTokenCount() { 420 var count = 0; 421 for (var tokenIndex = 0; tokenIndex < overlayTokens.length; tokenIndex += 1) { 422 if (overlayTokens[tokenIndex].open) count += 1; 423 } 424 return count; 425 } 426 427 function wantEscalation() { 428 return openOverlayTokenCount() > 0 || apiDesiredExpanded; 429 } 430 431 function wantedEscalationSource() { 432 if (openOverlayTokenCount() > 0) return 'overlay'; 433 if (apiDesiredExpanded) return 'api'; 434 return null; 435 } 436 437 // Advisory for the host's dismiss pill: fades with the exit of the LAST 438 // open overlay layer. All-tokens-gone keeps the last report: the demote 439 // is imminent, and a closing:false then would resurface the faded pill. 440 function syncOverlayClosingAdvisory() { 441 if (!overlayEscalationOpen) { 442 overlayClosingReported = false;
443 return; 444 } 445 var anyClosing = false; 446 var anyOpenSettled = false; 447 for (var advisoryIndex = 0; advisoryIndex < overlayTokens.length; advisoryIndex += 1) { 448 var advisoryToken = overlayTokens[advisoryIndex]; 449 if (!advisoryToken.open) continue; 450 if (advisoryToken.closing) anyClosing = true; 451 else anyOpenSettled = true; 452 } 453 if (!anyClosing && !anyOpenSettled) return; 454 var closing = anyClosing && !anyOpenSettled; 455 if (closing === overlayClosingReported) return; 456 overlayClosingReported = closing; 457 postEscalationMessage({ 458 type: 'widget-overlay-closing', 459 closing: closing 460 }); 461 } 462 463 function emitViewportChange(state, reason) { 464 var handlers = viewportChangeHandlers.slice(); 465 for (var handlerIndex = 0; handlerIndex < handlers.length; handlerIndex += 1) { 466 try { 467 handlers[handlerIndex]({ state: state, reason: reason }); 468 } catch (handlerError) { 469 console.error('viewport change handler failed:', handlerError); 470 } 471 } 472 } 473 474 function isValidOverlayRect(rect) { 475 return !!rect && 476 Number.isFinite(rect.left) && Number.isFinite(rect.top) && 477 Number.isFinite(rect.width) && Number.isFinite(rect.height) && 478 rect.width > 0 && rect.height > 0; 479 } 480 481 // While a promotion handshake is in flight, the mounting overlay must 482 // not paint squeezed into the slot; the class-gated guard holds it until 483 // completeOverlayHandshake releases after the promoted viewport settles. 484 var promotingGuardGeneration = 0; 485 486 function beginPromotingGuard() { 487 // A new handshake owns the pin lifecycle from here; a deferred 488 // post-demote clear firing later would wipe its pin CSS. 489 cancelPendingDemoteCleanup(); 490 promotingGuardGeneration += 1; 491 document.documentElement.classList.add('snow-overlay-promoting'); 492 escalationGuardStyleEl.textContent = UNCONDITIONAL_GUARD_RULES; 493 if (overlayPromotingTimeout !== null) clearTimeout(overlayPromotingTimeout); 494 // Safety: a host that never completes the handshake must not leave the 495 // overlay invisible. Every guard rule is class-gated, so dropping the 496 // class reveals it contained (pre-promotion behavior); pin CSS that 497 // widget-promote-pending installed stays for a promotion that may 498 // still land after a jank-stretched handshake. 499 overlayPromotingTimeout = setTimeout(function () { 500 overlayPromotingTimeout = null; 501 endPromotingGuard(); 502 overlayHandshakePending = false; 503 // Intent may have moved while the handshake hung; re-derive it. 504 scheduleEscalationReconcile(); 505 }, 600); 506 } 507 508 function endPromotingGuard() { 509 if (overlayPromotingTimeout !== null) { 510 clearTimeout(overlayPromotingTimeout); 511 overlayPromotingTimeout = null; 512 } 513 document.documentElement.classList.remove('snow-overlay-promoting'); 514 } 515 516 // The drawer's enter transition only fires if its held start state has 517 // painted first (transitions need a rendered before-state; a same-frame 518 // release snaps instead). Release the guard class one painted frame 519 // after the handshake resolves, unless a newer handshake started. 520 // After a PROMOTION the release must additionally wait for the promoted 521 // viewport to actually reach this document: the host's iframe resize 522 // propagates asynchronously (out-of-process frames, busy main threads), 523 // and rAF here keeps ticking against the OLD layout - releasing then 524 // paints the overlay squeezed at the slot geometry for a frame or two 525 // (the "flicker in the corner"). Mirror of the demote side's 526 // runDemoteCleanupWhenViewportSettles. 527 function releasePromotingGuardAfterPaint(awaitPromotedViewport) { 528 if (overlayPromotingTimeout !== null) { 529 clearTimeout(overlayPromotingTimeout); 530 overlayPromotingTimeout = null; 531 } 532 var generation = promotingGuardGeneration; 533 var release = function () { 534 if (generation !== promotingGuardGeneration) return; 535 document.documentElement.classList.remove('snow-overlay-promoting'); 536 }; 537 // The promoted viewport reached this document (or we are giving up 538 // waiting): the host can drop its slot clip, which guards the flip 539 // against stale compositor frames of this document showing at the 540 // container origin. Posted BEFORE the class release so the clip is 541 // gone by the time the overlay's enter starts painting. 542 var ackPromotedPaint = function () { 543 if (awaitPromotedViewport !== true) return; 544 postEscalationMessage({ 545 type: 'widget-promoted-painted', 546 attemptId: promotionAttemptId 547 }); 548 }; 549 var deferPastPaint = function () { 550 // A later promotion owns the host clip now. A stale resize/fallback 551 // must not acknowledge paint for the newer handshake. 552 if (generation !== promotingGuardGeneration) return; 553 ackPromotedPaint(); 554 // Promote path defers 4 frames, not 2: the ack above needs a 555 // postMessage roundtrip before the host lifts its slot clip, and an 556 // enter that starts sooner paints clipped to the slot. Frame-based 557 // so the margin stretches with jank alongside everything else. 558 var frames = awaitPromotedViewport === true ? 4 : 2; 559 if (typeof requestAnimationFrame === 'function') { 560 var step = function () { 561 frames -= 1; 562 if (frames <= 0) release(); 563 else requestAnimationFrame(step); 564 }; 565 requestAnimationFrame(step); 566 } else { 567 setTimeout(release, frames * 16); 568 } 569 }; 570 var condition = promotionCondition; 571 if ( 572 awaitPromotedViewport !== true || 573 condition === null || 574 window.matchMedia(condition).matches 575 ) { 576 deferPastPaint(); 577 return; 578 } 579 var settled = false;
580 var cleanup = function () { 581 settled = true; 582 window.removeEventListener('resize', onResize); 583 clearTimeout(fallback); 584 }; 585 var onResize = function () { 586 if (settled) return; 587 if (generation !== promotingGuardGeneration) { 588 cleanup(); 589 return; 590 } 591 if (!window.matchMedia(condition).matches) return; 592 cleanup(); 593 deferPastPaint(); 594 }; 595 // A resize that never lands (host died mid-handshake) must not leave 596 // the overlay hidden; the capped fallback reveals it regardless. 597 var fallback = setTimeout(function () { 598 if (settled) return; 599 cleanup(); 600 deferPastPaint(); 601 }, 600); 602 window.addEventListener('resize', onResize); 603 } 604 605 // Slot-state iframe dimensions, captured when the handshake starts. 606 // Mid-promotion rewrites (window resize) must still discriminate against 607 // the SLOT size, not the current (promoted) window size. 608 var promotionSlotDims = null; 609 610 // The media condition that is true only in the promoted viewport: any 611 // dimension where the target exceeds the slot discriminates the states. 612 // Thresholds sit 1px below the target: the host measures the parent 613 // window, and page zoom or fractional dvh can make this iframe's own 614 // viewport land fractionally short of that, which under exact equality 615 // would leave the promoted state unpinned. Safe because discrimination 616 // already requires target > slot + 1 per used dimension. 617 function promotionMediaCondition(target, slotDims) { 618 var parts = []; 619 if (target.width > slotDims.width + 1) { 620 parts.push('(min-width: ' + (target.width - 1) + 'px)'); 621 } 622 if (target.height > slotDims.height + 1) { 623 parts.push('(min-height: ' + (target.height - 1) + 'px)'); 624 } 625 if (parts.length === 0) return null; 626 return parts.join(' and '); 627 } 628 629 function writePromotionStyles(rect, radius, target) { 630 var resolvedRadius = 631 typeof radius === 'number' && Number.isFinite(radius) && radius >= 0 632 ? radius 633 : 24; 634 promotionRect = rect; 635 promotionRadius = resolvedRadius; 636 // height carries !important: iframe-base.css has 637 // body.widget-mode #root { height: auto } at higher specificity, which 638 // would otherwise let a content-height card (e.g. one the host clamped 639 // at its max iframe height) outgrow the pinned slot rect. 640 var pinBlock = 641 ' #root { position: fixed; left: ' + rect.left + 'px; top: ' + 642 rect.top + 'px; width: ' + rect.width + 'px; height: ' + rect.height + 643 'px !important; background: var(--background); border-radius: ' + resolvedRadius + 644 'px; } ' + 645 'body { background: transparent !important; } '; 646 var slotDims = promotionSlotDims || { 647 width: window.innerWidth, 648 height: window.innerHeight 649 }; 650 var condition = promotionMediaCondition(target, slotDims); 651 promotionCondition = condition; 652 // The guard stays fully class-gated for EVERY overlay kind: the 653 // reveal moment is the class release (viewport settle + a few frames, 654 // acked to the host so its slot clip lifts first), never the media 655 // flip itself. A media-keyed reveal starts the enter in the same pass 656 // as the resize - before the host can possibly lift the clip - and 657 // paints the first enter frames clipped to the slot. 658 escalationGuardStyleEl.textContent = UNCONDITIONAL_GUARD_RULES; 659 if (condition === null) { 660 // Pathological case (slot already as large as the viewport in both 661 // dimensions): no discriminating query exists, so pin immediately. 662 // The card is clipped for the handoff frames; promoted geometry is 663 // near-identical to the slot here, so the artifact is minimal. 664 escalationPinStyleEl.textContent = pinBlock; 665 return; 666 } 667 escalationPinStyleEl.textContent = 668 '@media ' + condition + ' {' + pinBlock + '}'; 669 } 670 671 function clearPromotionStyles() { 672 // Pin only: guard rules are class-gated (inert once the class drops) 673 // and may at this moment be guarding a NEWER handshake that began 674 // while this demote settled. 675 escalationPinStyleEl.textContent = ''; 676 promotionTarget = null; 677 promotionSlotDims = null; 678 promotionCondition = null; 679 promotionRect = null; 680 promotionRadius = 24; 681 } 682 683 // Post-demote style teardown. On iOS Safari the widget-demoted message 684 // can reach a separate-process iframe before the host's resize does, and 685 // the host paints the shrunk widget box with this document's last 686 // committed frame until the resize lands here. That stale frame must 687 // already look like the demoted card: clearing the styles immediately 688 // lays the card out unpinned at the stale wide viewport (content shifts 689 // right), while leaving the promoted pin shows the empty top-left of the 690 // full-viewport frame (the widget blinks blank). So the demote repins 691 // the card at the origin at slot width - identical to the final demoted 692 // layout - and the full clear waits for the viewport to actually leave 693 // the promoted state. 694 // 695 // The repin WAITS for the host's widget-demote-committed ack (sent two 696 // host frames after the demote styles, when the shrunk box is on 697 // screen): applied any earlier, an out-of-process iframe can commit the 698 // origin-pinned card at the still-promoted viewport while the 699 // fullscreen box is still visible - the card flashes in the page's 700 // top-left corner. A local rAF defer cannot replace the ack: this 701 // iframe's frame clock says nothing about the host compositor (a 2-rAF 702 // version lost the race in live testing). A 250ms fallback keeps the 703 // iOS crop filler alive if the ack is ever lost. 704 var pendingDemoteCleanup = null; 705 706 function cancelPendingDemoteCleanup() { 707 if (pendingDemoteCleanup === null) return; 708 clearTimeout(pendingDemoteCleanup.timer); 709 clearTimeout(pendingDemoteCleanup.repinTimer); 710 window.removeEventListener('resize', pendingDemoteCleanup.onResize); 711 pendingDemoteCleanup = null; 712 } 713 714 function runDemoteCleanup() { 715 cancelPendingDemoteCleanup(); 716 clearPromotionStyles(); 717 forceFreshResizeReport(); 718 } 719 720 function runDemoteCleanupWhenViewportSettles() { 721 if (pendingDemoteCleanup !== null) return; 722 if ( 723 promotionCondition === null || 724 promotionRect === null || 725 !window.matchMedia(promotionCondition).matches 726 ) { 727 runDemoteCleanup(); 728 return; 729 } 730 // Origin-anchored slot-width pin: what the demoted card looks like. 731 // Until the ack, the promoted pin keeps the last committed frame 732 // looking exactly like the pre-demote screen, which is the correct 733 // picture while the fullscreen box is still visible. 734 var repinWidth = promotionRect.width; 735 var repinHeight = promotionRect.height; 736 var repinRadius = promotionRadius; 737 var applyOriginRepin = function () { 738 // A cancel (reopen, settle) while waiting wins; apply only once. 739 if (pendingDemoteCleanup === null || pendingDemoteCleanup.applyRepin === null) return; 740 pendingDemoteCleanup.applyRepin = null; 741 clearTimeout(pendingDemoteCleanup.repinTimer); 742 escalationPinStyleEl.textContent = 743 '#root { position: fixed; left: 0; top: 0; width: ' + 744 repinWidth + 'px; height: ' + repinHeight + 745 'px !important; background: var(--background); border-radius: ' + 746 repinRadius + 'px; } ' + 747 'body { background: transparent !important; }'; 748 }; 749 var onResize = function () { 750 if ( 751 promotionCondition !== null && 752 window.matchMedia(promotionCondition).matches 753 ) { 754 return; 755 } 756 runDemoteCleanup(); 757 }; 758 pendingDemoteCleanup = { 759 onResize: onResize, 760 timer: setTimeout(runDemoteCleanup, 500), 761 applyRepin: applyOriginRepin, 762 repinTimer: setTimeout(applyOriginRepin, 250) 763 }; 764 window.addEventListener('resize', onResize); 765 } 766 767 var overlayCloseAckTimeout = null; 768 769 function postOverlayTransition(open) { 770 overlayEscalationOpen = open; 771 overlayEscalationSource = open ? wantedEscalationSource() : null; 772 overlayHandshakePending = true; 773 if (overlayCloseAckTimeout !== null) { 774 clearTimeout(overlayCloseAckTimeout); 775 overlayCloseAckTimeout = null; 776 } 777 if (open) { 778 beginPromotingGuard(); 779 } else { 780 // Safety mirror of the open-side guard timeout: a host that never 781 // acks a close must not leave the handshake pending forever, which 782 // would silently disable all future escalation for this iframe. 783 overlayCloseAckTimeout = setTimeout(function () { 784 overlayCloseAckTimeout = null; 785 if (!overlayHandshakePending) return; 786 overlayHandshakePending = false;
787 reconcileEscalation(); 788 }, 600); 789 } 790 var stateMessage = { type: 'widget-overlay-state', open: open }; 791 if (open) { 792 // Modal overlays always own the full page; only a pure api 793 // expansion carries the app's requested stage. API permission is 794 // authorized through its own request before it can reach this state. 795 stateMessage.area = 796 openOverlayTokenCount() > 0 ? 'page' : apiDesiredArea || 'page'; 797 stateMessage.source = overlayEscalationSource; 798 if (overlayEscalationSource === 'api') { 799 stateMessage.authorizationGrantId = apiAuthorizationGrantId; 800 } 801 } 802 postEscalationMessage(stateMessage); 803 } 804 805 function reconcileEscalation() { 806 syncOverlayClosingAdvisory(); 807 if (overlayHandshakePending) return; 808 var wanted = wantEscalation(); 809 var wantedSource = wantedEscalationSource(); 810 // A pill dismissal that closes only one layer must not label a later, 811 // unrelated demotion. Keep the reason only while the dismissal is 812 // actually taking the viewport inline. 813 if (pendingCollapseReason === 'dismissed' && wanted && overlayEscalationOpen) { 814 pendingCollapseReason = null; 815 } 816 if ( 817 wanted === overlayEscalationOpen && 818 (!wanted || wantedSource === overlayEscalationSource) 819 ) return; 820 if (wanted) { 821 if (!hasUserEngagement) return; 822 postOverlayTransition(true); 823 return; 824 } 825 postOverlayTransition(false); 826 } 827 828 // The close side is coalesced past the current commit: the responsive 829 // variant swap releases the drawer token and opens the dialog token in 830 // one React commit, and reacting to the transient zero would demote and 831 // re-promote mid-open. A microtask+frame is enough (the old detection 832 // needed 120ms because it could only see the DOM). 833 function scheduleEscalationReconcile() { 834 if (escalationReconcileQueued) return; 835 escalationReconcileQueued = true; 836 var runReconcile = function () { 837 escalationReconcileQueued = false; 838 reconcileEscalation(); 839 }; 840 var afterFrame = function () { 841 if (typeof requestAnimationFrame === 'function') { 842 requestAnimationFrame(runReconcile); 843 } else { 844 setTimeout(runReconcile, 16); 845 } 846 }; 847 if (typeof queueMicrotask === 'function') { 848 queueMicrotask(afterFrame); 849 } else { 850 afterFrame(); 851 } 852 } 853 854 // The open side runs synchronously on purpose: overlayOpened arrives 855 // from a layout effect before first paint, and beginPromotingGuard 856 // (inside postOverlayTransition) must hide the mounting overlay in that 857 // same pass or it flashes squeezed in the slot-sized iframe. 858 function escalateForOverlayOpen() { 859 syncOverlayClosingAdvisory(); 860 if (overlayHandshakePending) { 861 // An overlay opening while a CLOSE handshake is still in flight must 862 // not paint squeezed between the demote resize and the re-promotion. 863 // Hold it hidden now; the post-ack reconcile posts the new open. An 864 // OPEN handshake in flight already holds the guard, and re-beginning 865 // it here would wipe pin CSS mid-handshake. 866 if (!overlayEscalationOpen && hasUserEngagement) beginPromotingGuard(); 867 return; 868 } 869 if (overlayEscalationOpen) return; 870 if (!hasUserEngagement) return; 871 postOverlayTransition(true); 872 } 873 874 function completeOverlayHandshake(promoted) { 875 overlayHandshakePending = false; 876 if (overlayCloseAckTimeout !== null) { 877 clearTimeout(overlayCloseAckTimeout); 878 overlayCloseAckTimeout = null; 879 } 880 releasePromotingGuardAfterPaint(promoted === true); 881 // Intent may have changed while the handshake was in flight. 882 if (typeof requestAnimationFrame === 'function') { 883 requestAnimationFrame(reconcileEscalation); 884 } else { 885 setTimeout(reconcileEscalation, 16); 886 } 887 } 888 889 function settleApiIntent(settled) { 890 if (apiPendingIntent === null) return; 891 var intent = apiPendingIntent; 892 apiPendingIntent = null; 893 clearTimeout(intent.timer); 894 if (settled === 'resolve') intent.resolve(); 895 else intent.reject(new Error(intent.failureMessage)); 896 } 897 898 window.__snowViewportBridge__ = { 899 registerOverlay: function (requestClose) { 900 var token = { 901 open: false, 902 closing: false, 903 requestClose: typeof requestClose === 'function' ? requestClose : null 904 }; 905 overlayTokens.push(token); 906 return { 907 notifyOpen: function () { 908 if (token.open && !token.closing) return; 909 token.open = true; 910 token.closing = false;
911 escalateForOverlayOpen(); 912 }, 913 setClosing: function (closing) { 914 closing = closing === true; 915 if (!token.open || token.closing === closing) return; 916 token.closing = closing; 917 syncOverlayClosingAdvisory(); 918 }, 919 release: function () { 920 var tokenIdx = overlayTokens.indexOf(token); 921 if (tokenIdx !== -1) overlayTokens.splice(tokenIdx, 1); 922 token.open = false; 923 scheduleEscalationReconcile(); 924 } 925 }; 926 }, 927 expand: function (options) { 928 if ( 929 options === null || 930 typeof options !== 'object' || 931 options.area === undefined 932 ) { 933 return Promise.reject( 934 new Error("viewport.expand requires an area: pass { area: 'card' | 'plane' | 'page' }") 935 ); 936 } 937 if ( 938 options.area !== 'card' && 939 options.area !== 'plane' && 940 options.area !== 'page' 941 ) { 942 return Promise.reject( 943 new Error("viewport.expand: area must be 'card', 'plane', or 'page'") 944 ); 945 } 946 var requestedArea = options.area; 947 if (apiPendingIntent !== null) { 948 if (apiPendingIntent.kind === 'expand') { 949 // The same request coalesces; a different area must not silently 950 // resolve with the other request's geometry. 951 if (apiPendingIntent.area === requestedArea) { 952 return apiPendingIntent.promise; 953 } 954 return Promise.reject( 955 new Error( 956 "viewport.expand({ area: '" + apiPendingIntent.area + 957 "' }) is already in flight; await it before requesting '" + 958 requestedArea + "'" 959 ) 960 ); 961 } 962 return Promise.reject( 963 new Error('viewport.expand called while a collapse is in flight') 964 ); 965 } 966 if (!hasUserEngagement) { 967 return Promise.reject( 968 new Error('viewport.expand requires a user interaction inside the widget first') 969 ); 970 } 971 if (viewportPromoted) { 972 if (AREA_RANK[requestedArea] > AREA_RANK[promotedArea || 'page']) { 973 // Live area renegotiation is unsupported by design: the safe 974 // path IS a fresh handshake, which the app gets by collapsing. 975 return Promise.reject( 976 new Error( 977 'viewport.expand: already expanded at ' + promotedArea + 978 " size; call collapse() first, then expand({ area: '" + 979 requestedArea + "' })" 980 ) 981 ); 982 } 983 if (apiDesiredExpanded) return Promise.resolve(); 984 } 985 apiAuthorizationRequestId += 1; 986 var expandIntent = { 987 kind: 'expand', 988 area: requestedArea, 989 authorizationRequestId: apiAuthorizationRequestId, 990 failureMessage: 'viewport.expand was denied or interrupted by the host' 991 }; 992 expandIntent.promise = new Promise(function (resolve, reject) { 993 expandIntent.resolve = resolve; 994 expandIntent.reject = reject; 995 }); 996 expandIntent.timer = setTimeout(function () { 997 if (apiPendingIntent !== expandIntent) return; 998 apiPendingIntent = null; 999 apiDesiredExpanded = false; 1000 apiAuthorizationGrantId = null; 1001 expandIntent.reject(new Error('viewport.expand timed out waiting for the host')); 1002 scheduleEscalationReconcile(); 1003 }, 2000); 1004 apiPendingIntent = expandIntent; 1005 postEscalationMessage({ 1006 type: 'widget-viewport-expand-request', 1007 area: requestedArea, 1008 requestId: expandIntent.authorizationRequestId 1009 }); 1010 return expandIntent.promise; 1011 }, 1012 collapse: function () { 1013 if (apiPendingIntent !== null) { 1014 if (apiPendingIntent.kind === 'collapse') return apiPendingIntent.promise; 1015 return Promise.reject( 1016 new Error('viewport.collapse called while an expand is in flight') 1017 ); 1018 } 1019 apiDesiredExpanded = false;
1020 apiAuthorizationGrantId = null; 1021 if (!viewportPromoted || wantEscalation()) { 1022 // Already inline, or modal overlays still hold the promotion. 1023 return Promise.resolve(); 1024 } 1025 pendingCollapseReason = 'collapsed'; 1026 var collapseIntent = { kind: 'collapse', failureMessage: 'viewport.collapse timed out waiting for the host' }; 1027 collapseIntent.promise = new Promise(function (resolve, reject) { 1028 collapseIntent.resolve = resolve; 1029 collapseIntent.reject = reject; 1030 }); 1031 collapseIntent.timer = setTimeout(function () { 1032 if (apiPendingIntent !== collapseIntent) return; 1033 apiPendingIntent = null; 1034 // A stale reason would mislabel a later unrelated demote. 1035 if (pendingCollapseReason === 'collapsed') pendingCollapseReason = null; 1036 collapseIntent.reject(new Error('viewport.collapse timed out waiting for the host')); 1037 }, 2000); 1038 apiPendingIntent = collapseIntent; 1039 reconcileEscalation(); 1040 return collapseIntent.promise; 1041 }, 1042 getState: function () { 1043 return viewportPromoted ? 'expanded' : 'inline'; 1044 }, 1045 onChange: function (handler) { 1046 if (typeof handler !== 'function') return function () {}; 1047 viewportChangeHandlers.push(handler); 1048 return function () { 1049 var handlerIdx = viewportChangeHandlers.indexOf(handler); 1050 if (handlerIdx !== -1) viewportChangeHandlers.splice(handlerIdx, 1); 1051 }; 1052 } 1053 }; 1054 1055 // Host messages that drive the promotion lifecycle; called from the main 1056 // message listener after origin and shape validation. 1057 function handleEscalationMessage(data) { 1058 // The iframe keeps the same WindowProxy if widget code navigates itself. 1059 // Origin alone therefore cannot distinguish the current document from a 1060 // stale or navigated one; every acting lifecycle message is per-load. 1061 if (data.sessionToken !== widgetSessionToken) return; 1062 1063 if (data.type === 'widget-promote-pending') { 1064 var pendingViewport = data.viewport; 1065 if ( 1066 Number.isSafeInteger(data.attemptId) && 1067 data.attemptId > 0 && 1068 isValidOverlayRect(data.rect) && 1069 pendingViewport && 1070 Number.isFinite(pendingViewport.width) && 1071 Number.isFinite(pendingViewport.height) && 1072 pendingViewport.width > 0 && 1073 pendingViewport.height > 0 1074 ) { 1075 promotionTarget = { 1076 width: pendingViewport.width, 1077 height: pendingViewport.height 1078 }; 1079 promotionAttemptId = data.attemptId; 1080 promotionSlotDims = { 1081 width: window.innerWidth, 1082 height: window.innerHeight 1083 }; 1084 writePromotionStyles(data.rect, data.radius, promotionTarget); 1085 postEscalationMessage({ 1086 type: 'widget-pin-ready', 1087 attemptId: promotionAttemptId 1088 }); 1089 } 1090 } 1091 1092 if (data.type === 'widget-viewport-expand-authorized') { 1093 if ( 1094 apiPendingIntent === null || 1095 apiPendingIntent.kind !== 'expand' || 1096 !Number.isSafeInteger(data.requestId) || 1097 data.requestId !== apiPendingIntent.authorizationRequestId 1098 ) return; 1099 if (data.allowed !== true) { 1100 settleApiIntent('reject'); 1101 return; 1102 } 1103 if (typeof data.grantId !== 'string' || data.grantId.length < 16) { 1104 settleApiIntent('reject'); 1105 return; 1106 } 1107 apiDesiredExpanded = true; 1108 apiDesiredArea = apiPendingIntent.area; 1109 apiAuthorizationGrantId = data.grantId; 1110 if (viewportPromoted) { 1111 settleApiIntent('resolve'); 1112 return; 1113 } 1114 reconcileEscalation(); 1115 } 1116 1117 if (data.type === 'widget-promoted') { 1118 if ( 1119 !Number.isSafeInteger(data.attemptId) || 1120 data.attemptId !== promotionAttemptId 1121 ) return; 1122 var becamePromoted = !viewportPromoted; 1123 viewportPromoted = true; 1124 promotedArea = AREA_RANK[data.area] !== undefined ? data.area : 'page'; 1125 if (apiPendingIntent !== null && apiPendingIntent.kind === 'expand') { 1126 settleApiIntent('resolve'); 1127 } 1128 if (becamePromoted) emitViewportChange('expanded', 'expanded'); 1129 completeOverlayHandshake(true); 1130 } 1131 1132 if (data.type === 'widget-slot-rect') { 1133 var slotViewport = data.viewport || promotionTarget; 1134 if ( 1135 overlayEscalationOpen && 1136 isValidOverlayRect(data.rect) && 1137 slotViewport 1138 ) { 1139 promotionTarget = slotViewport; 1140 writePromotionStyles(data.rect, data.radius, slotViewport); 1141 } 1142 } 1143 1144 if (data.type === 'widget-dismiss-overlay') {
1145 // Host dismiss pill. Modal overlays close through their own 1146 // registered dismissal path (component filters and controlled 1147 // owners keep their say; a refusing overlay is covered by the 1148 // host's force-demote timeout). Only when no overlay holds the 1149 // promotion does the pill collapse an api expansion. 1150 pendingCollapseReason = 'dismissed'; 1151 var topmostOpenToken = null; 1152 for (var dismissIdx = overlayTokens.length - 1; dismissIdx >= 0; dismissIdx -= 1) { 1153 if (!overlayTokens[dismissIdx].open) continue; 1154 topmostOpenToken = overlayTokens[dismissIdx]; 1155 break; 1156 } 1157 if (topmostOpenToken !== null && topmostOpenToken.requestClose !== null) { 1158 try { 1159 topmostOpenToken.requestClose(); 1160 } catch (dismissError) { 1161 console.error('overlay requestClose failed:', dismissError); 1162 } 1163 } 1164 if (topmostOpenToken === null && apiDesiredExpanded) { 1165 apiDesiredExpanded = false; 1166 apiAuthorizationGrantId = null; 1167 scheduleEscalationReconcile(); 1168 } 1169 } 1170 1171 if (data.type === 'widget-demote-committed') { 1172 // The host's shrunk box is on screen: the crop filler is safe now. 1173 if (pendingDemoteCleanup !== null && pendingDemoteCleanup.applyRepin !== null) { 1174 pendingDemoteCleanup.applyRepin(); 1175 } 1176 } 1177 1178 if (data.type === 'widget-demoted') { 1179 runDemoteCleanupWhenViewportSettles(); 1180 var wasPromoted = viewportPromoted; 1181 viewportPromoted = false; 1182 promotedArea = null; 1183 apiDesiredArea = null; 1184 apiAuthorizationGrantId = null; 1185 if (apiPendingIntent !== null) { 1186 // Host nack, engagement gate, or pending-abort all surface here: 1187 // a pending expand is rejected, a pending collapse is fulfilled. 1188 settleApiIntent( 1189 apiPendingIntent.kind === 'expand' ? 'reject' : 'resolve' 1190 ); 1191 } 1192 if (apiDesiredExpanded) { 1193 // Host-forced exit (Escape, pill fallback): the expansion no 1194 // longer holds; the app re-expands with a fresh call if it wants. 1195 apiDesiredExpanded = false; 1196 if (pendingCollapseReason === null) pendingCollapseReason = 'host'; 1197 } 1198 if (wasPromoted) { 1199 emitViewportChange('inline', pendingCollapseReason || 'host'); 1200 } 1201 pendingCollapseReason = null; 1202 // overlayEscalationOpen intentionally NOT reset while overlay tokens 1203 // are open: on a host-forced demote the overlay is still up, and 1204 // resetting would make the next reconcile immediately re-promote it. 1205 // Without any open intent, though, the demote IS the settled state; 1206 // aligning here avoids posting a redundant close. 1207 if (!wantEscalation()) { 1208 overlayEscalationOpen = false; 1209 overlayEscalationSource = null; 1210 } 1211 completeOverlayHandshake(); 1212 } 1213 } 1214 1215 // Listen for clicks to expand collapsed widget (iframe clicks don't bubble to parent) 1216 function isNonInteractiveTarget(target) { 1217 if (!(target instanceof Element)) { 1218 return true; 1219 } 1220 return !target.closest('a, button, input, select, textarea'); 1221 } 1222 1223 var __collapsedPressActive = false; 1224 function startCollapsedPress() { 1225 if (__collapsedPressActive) return; 1226 __collapsedPressActive = true; 1227 window.parent.postMessage({ type: 'widget-press-start' }, window.__PARENT_ORIGIN__); 1228 } 1229 1230 function endCollapsedPress() { 1231 if (!__collapsedPressActive) return; 1232 __collapsedPressActive = false; 1233 window.parent.postMessage({ type: 'widget-press-end' }, window.__PARENT_ORIGIN__); 1234 } 1235 1236 document.addEventListener('pointerdown', function(e) { 1237 if (!window.__WIDGET_COLLAPSED__) return; 1238 if (isNonInteractiveTarget(e.target)) { 1239 startCollapsedPress(); 1240 } 1241 }); 1242 1243 document.addEventListener('pointerup', function() { 1244 endCollapsedPress(); 1245 }); 1246 1247 document.addEventListener('pointercancel', function() { 1248 endCollapsedPress(); 1249 }); 1250 1251 document.addEventListener('pointerleave', function() { 1252 endCollapsedPress(); 1253 }); 1254 1255 document.addEventListener('click', function(e) { 1256 if (!window.__WIDGET_COLLAPSED__) return; 1257 if (isNonInteractiveTarget(e.target)) { 1258 endCollapsedPress(); 1259 window.parent.postMessage({ type: 'widget-expand' }, window.__PARENT_ORIGIN__); 1260 } 1261 }); 1262 1263 window.addEventListener('blur', function() { 1264 endCollapsedPress(); 1265 }); 1266 1267 document.addEventListener('visibilitychange', function() { 1268 if (document.visibilityState !== 'visible') { 1269 endCollapsedPress(); 1270 } 1271 }); 1272 1273 // Set pointer cursor when collapsed 1274 function updateCollapsedCursor() { 1275 document.body.style.cursor = window.__WIDGET_COLLAPSED__ ? 'pointer' : ''; 1276 } 1277 updateCollapsedCursor(); 1278 1279 // Listen for messages from parent to update state without full reload 1280 // Validate message origin for defense-in-depth (CSP is primary protection) 1281 window.addEventListener('message', function(event) { 1282 // Validate sender origin matches parent 1283 if (event.origin !== window.__PARENT_ORIGIN__) { 1284 return; 1285 } 1286 if (!event.data || typeof event.data.type !== 'string') return; 1287 1288 if (event.data.type === 'set-collapsed') { 1289 window.__WIDGET_COLLAPSED__ = event.data.isCollapsed; 1290 updateCollapsedStateAttribute(); 1291 if (!window.__WIDGET_COLLAPSED__) { 1292 endCollapsedPress(); 1293 } 1294 root.render( 1295 React.createElement(Widget, { 1296 data: window.__WIDGET_DATA__, 1297 isCollapsed: window.__WIDGET_COLLAPSED__ 1298 }) 1299 ); 1300 updateCollapsedCursor(); 1301 } 1302 1303 if (event.data.type === 'set-data') { 1304 window.__WIDGET_DATA__ = event.data.data; 1305 root.render( 1306 React.createElement(Widget, { 1307 data: window.__WIDGET_DATA__, 1308 isCollapsed: window.__WIDGET_COLLAPSED__ 1309 }) 1310 ); 1311 } 1312 1313 if (event.data.type === 'set-dark-mode') { 1314 if (event.data.darkMode) { 1315 document.documentElement.classList.add('dark'); 1316 } else { 1317 document.documentElement.classList.remove('dark'); 1318 } 1319 } 1320 1321 if (event.data.type === 'request-ready') { 1322 window.parent.postMessage({ type: 'app-ready' }, window.__PARENT_ORIGIN__); 1323 } 1324 1325 handleEscalationMessage(event.data); 1326 }); 1327 } catch (err) { 1328 console.error('Widget render error:', err); 1329 var errorMessage = 'Widget render failed'; 1330 if (err instanceof Error && typeof err.message === 'string' && err.message.length > 0) { 1331 errorMessage = err.message; 1332 } else if (typeof err === 'string' && err.length > 0) { 1333 errorMessage = err; 1334 } else if ( 1335 err && 1336 typeof err === 'object' && 1337 'message' in err && 1338 typeof err.message === 'string' && 1339 err.message.length > 0 1340 ) { 1341 errorMessage = err.message; 1342 } else if (err !== undefined && err !== null) { 1343 errorMessage = String(err); 1344 } 1345 window.parent.postMessage({ 1346 type: 'sdk-error', 1347 error: { message: errorMessage } 1348 }, window.__PARENT_ORIGIN__); 1349 } 1350})(${d}); 1351`},"computeWidgetBundles",0,function(e){let n=new Set;if(!e?.packages)return[];for(let[r,a]of Object.entries(e.packages)){let e=(0,t.resolvePackageName)(r)??r;if("ui"===e)for(let e of a){let r=(0,t.getUiComponentBundle)(e.source);r&&"ui-base.js"!==r&&n.add(r)}else if("lucide"===e)a.length>0&&n.add("lucide.js");else{let r=t.PACKAGE_TO_BUNDLE[e];r&&n.add(r)}}return Array.from(n)}],843727)},150799,e=>{"use strict";var t=e.i(943306),n=e.i(297068),r=e.i(176300),a=e.i(809382),i=e.i(839221);e.s(["ViewportDismissPill",0,function({closing:e=!1,onDismiss:o,anchorRect:s=null}){let l=(0,n.useRef)(null);return(0,n.useEffect)(()=>{let e=l.current;if(e&&"showPopover"in e){if(e.isConnected&&!e.matches(":popover-open"))try{e.showPopover()}catch(e){if(!(e instanceof DOMException)||"InvalidStateError"!==e.name)throw e}return()=>{e.isConnected&&e.matches(":popover-open")&&e.hidePopover()}}},[]),(0,t.jsx)("div",{ref:l,popover:"manual",className:(0,i.cn)("fixed bottom-auto left-auto m-0 border-0 bg-transparent p-0","animate-in transition-opacity duration-200 fade-in-0",e?"pointer-events-none opacity-0":"opacity-100"),style:s?{top:`${s.top+10}px`,right:`calc(100% - ${s.left+s.width}px + 10px)`}:{top:"calc(env(safe-area-inset-top, 0px) + 10px)",right:"10px"},children:(0,t.jsx)(a.Button,{variant:"secondary",size:"icon-lg",className:"rounded-full shadow-lg","aria-label":"Close",onClick:o,children:(0,t.jsx)(r.X,{})})})}])},661831,e=>{"use strict";var t=e.i(943306),n=e.i(297068),r=e.i(848317),a=e.i(174410),i=e.i(542095),o=e.i(134549),s=e.i(27464),l=e.i(843727),d=e.i(861211),u=e.i(542279),c=e.i(779786),p=e.i(150799),h=e.i(997632),m=e.i(381674),f=e.i(251545),g=e.i(9946),w=e.i(225703),v=e.i(734500),y=e.i(873914),k=e.i(156419),x=e.i(809382),E=e.i(537701),b=e.i(287098),I=e.i(372642);let C=(e,t)=>e===t||!!e&&!!t&&e.length===t.length&&e.every((e,n)=>e===t[n]),R=(e,t)=>{let n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;let a=[...n].sort(),i=[...r].sort();return!!a.every((e,t)=>e===i[t])&&a.every(n=>e[n]===t[n])};var _=e.i(744636),A=e.i(489841);let P=new Set,T=new Map,M=null;function S(){let e=[...P].filter(e=>e.island.isConnected),t=e.map(e=>e.island),n=new Set;for(let r of function(e){let t=new Set;for(let n of e){if("page"===n.area){t.add(document.body);continue}if("plane"===n.area){let e=document.getElementById(_.SHELL_CONTENT_ROW_ID);e&&t.add(e);let n=document.getElementById(_.SHELL_LOWER_RAIL_ID);n&&t.add(n);continue}let e=document.getElementById(_.SHELL_MAIN_CARD_ID);e&&t.add(e)}return t}(e))!function e(t,n,r){let a=n.filter(e=>e===t||t.contains(e));if(0===a.length)return void r.add(t);if(!a.includes(t))for(let n of t.children){let t=a.filter(e=>e===n||n.contains(e));if(0===t.length){!function e(t,n){if(t instanceof HTMLElement)return void n.add(t);for(let r of t.children)e(r,n)}(n,r);continue}!t.some(e=>e===n)&&n instanceof HTMLElement&&e(n,t,r)}}(r,t,n);for(let[e,t]of T)!n.has(e)&&(t?e.setAttribute("inert",""):e.removeAttribute("inert"),T.delete(e));for(let e of n)T.has(e)||T.set(e,e.hasAttribute("inert")),e.setAttribute("inert","")}function O(e){let t=document.getElementById(e);if(!t)return null;let n=t.getBoundingClientRect();return n.width<200||n.height<200?null:{left:n.left,top:n.top,width:n.width,height:n.height}}function D(e){if("page"===e||window.matchMedia(A.BELOW_DESKTOP_MEDIA_QUERY).matches)return{area:"page",rect:null};if("card"===e){let e=O(_.SHELL_MAIN_CARD_ID);if(e)return{area:"card",rect:e}}let t=O(_.SHELL_CONTENT_ROW_ID);return t?{area:"plane",rect:function(e){let t=document.querySelector('[data-shell-chrome="rail"]');if(!(t instanceof HTMLElement))return e;let n=t.getBoundingClientRect(),r=e.left+e.width;return 0===n.width||n.right<=r?e:{...e,width:n.right-e.left}}(t)}:{area:"page",rect:null}}let N={position:"fixed",inset:"0",width:"100vw",height:"100dvh",margin:"0",padding:"0",border:"0",borderRadius:"0",background:"transparent",overflow:"visible"},W={count:0};function H(){W.count=Math.max(0,W.count-1),0===W.count&&(document.documentElement.style.overflow="",document.body.style.paddingRight="")}function L(e){return e.closest(".widget-container")??e}function z(e,t,n){Object.assign(e.style,N),"page"!==n.area&&n.rect&&Object.assign(e.style,{inset:"auto",left:`${n.rect.left}px`,top:`${n.rect.top}px`,width:`${n.rect.width}px`,height:`${n.rect.height}px`,borderRadius:"16px",overflow:"hidden"}),e.hasAttribute("popover")||(e.setAttribute("popover","manual"),e.showPopover()),t.style.height="100%"}function q(e,t){return"page"!==t.area&&t.rect?{left:e.left-t.rect.left,top:e.top-t.rect.top,width:e.width,height:e.height}:e}function j(e){return"page"!==e.area&&e.rect?{width:e.rect.width,height:e.rect.height}:{width:window.innerWidth,height:window.innerHeight}}function G(e){e.element.style.height=e.previousHeight,H()}function F(e){if(document.activeElement===e)return!0;try{return e.matches(":hover")}catch{return!1}}function V(e){if(!e)return null;let t=L(e).getBoundingClientRect();return{left:t.left,top:t.top,width:t.width,height:t.height}}function B(e,t){return null===e||null===t?e===t:e.left===t.left&&e.top===t.top&&e.width===t.width&&e.height===t.height}function U(e){return!e?.isConnected||null!==e.closest('[inert], [aria-hidden="true"], [hidden]')}var $=e.i(798307);let K=n.default.memo(function({widgetMeta:e,data:_,initialIsCollapsed:A=!0,prefixToWidget:T,reserveSpaceOnLoad:O=!1}){let N=(0,n.useRef)(null),K=(0,n.useRef)(null),Y=(0,n.useRef)(null),Q=(0,n.useRef)(null),J=(0,n.useRef)(null),X=(0,n.useRef)(null),Z=(0,n.useRef)(null),ee=(0,n.useRef)(!1),et=(0,n.useRef)(!1),[en]=(0,n.use
1351State)(()=>(0,E.generateUUID)()),[er,ea]=(0,n.useState)(A),[ei,eo]=(0,n.useState)(!1),[es,el]=(0,n.useState)(0),[ed,eu]=(0,n.useState)(0),[ec,ep]=(0,n.useState)(!1),eh=(0,n.useMemo)(()=>"string"!=typeof e.component||0===e.component.length?null:{...e,component:e.component},[e]),em=null!==eh,[ef,eg]=(0,n.useState)(eh),[ew,ev]=(0,n.useState)(0),ey=(0,n.useRef)(!1),ek=(0,n.useRef)(0),ex=(0,y.useOptionalShellActions)(),{isOverlayPromoted:eE,isOverlayPromotedRef:eb,promotedGeometry:eI,handleOverlayStateMessage:eC,handlePinReady:eR,handlePromotionPainted:e_,requestOverlayDismiss:eA,teardownPromotion:eP}=function({containerRef:e,promotionIslandRef:t,iframeRef:r,iframeHeightRef:a,sessionTokenRef:i,claimPromotion:o,releasePromotion:s}){let[l,d]=(0,n.useState)(!1),u=(0,n.useRef)(!1),c=(0,n.useRef)(null),p=(0,n.useRef)(null),h=(0,n.useRef)(null),m=(0,n.useRef)(0),f=(0,n.useRef)(null),g=(0,n.useRef)(null),w=(0,n.useRef)(null),v=(0,n.useRef)(null),y=(0,n.useRef)(null),k=(0,n.useRef)(!1),x=(0,n.useRef)("page"),E=(0,n.useRef)(null),b=(0,n.useRef)(null),I=(0,n.useRef)(null),[C,R]=(0,n.useState)(null),_=(0,n.useCallback)((e,t)=>{let n=i.current;null!==n&&e.postMessage({...t,sessionToken:n},"*")},[i]),A=(0,n.useCallback)(()=>{k.current&&(k.current=!1,s())},[s]),T=(0,n.useCallback)(()=>{let t=V(e.current);if(!t)return;let n=b.current??E.current??{area:"page",rect:null},a=r.current?.contentWindow;a&&_(a,{type:"widget-slot-rect",rect:q(t,n),radius:24,viewport:j(n)})},[e,r,_]),O=(0,n.useCallback)(()=>{null!==h.current&&(window.clearTimeout(h.current),h.current=null);let e=p.current;e&&(G(e),p.current=null),w.current=null,f.current=null,A()},[A]),N=(0,n.useCallback)(()=>{null===h.current&&(h.current=window.setTimeout(()=>{if(h.current=null,!p.current)return;O();let e=r.current?.contentWindow;e&&_(e,{type:"widget-demoted"})},400))},[O,r,_]),$=(0,n.useCallback)(n=>{let a=e.current,i=r.current;if(!a||!i?.contentWindow)return;if(U(t.current)||!("showPopover"in HTMLElement.prototype)||!F(i))return void _(i.contentWindow,{type:"widget-demoted"});if(u.current)return void _(i.contentWindow,{type:"widget-promoted",area:b.current?.area??"page",attemptId:g.current});if(p.current)return;x.current=n;let s=D(n);if(!o(s.area))return void _(i.contentWindow,{type:"widget-demoted"});k.current=!0,E.current=s;let l=m.current+1;m.current=l,f.current=l;let{rect:d,freeze:c}=function(e){let t=L(e);if(0===W.count){let e=window.innerWidth-document.documentElement.clientWidth;document.documentElement.style.overflow="hidden",e>0&&(document.body.style.paddingRight=`${e}px`)}W.count+=1;let n=t.getBoundingClientRect(),r={left:n.left,top:n.top,width:n.width,height:n.height},a={element:t,previousHeight:t.style.height};return t.style.height=`${r.height}px`,{rect:r,freeze:a}}(a);p.current=c,w.current=d,_(i.contentWindow,{type:"widget-promote-pending",rect:q(d,s),radius:24,viewport:j(s),attemptId:l}),N()},[N,o,e,r,_]),K=(0,n.useCallback)(()=>{null!==v.current&&(window.clearTimeout(v.current),v.current=null);let t=e.current;t&&(t.style.clipPath="")},[e]),Y=(0,n.useCallback)(e=>{u.current&&e===g.current&&K()},[K]),Q=(0,n.useCallback)(n=>{var a;let i=e.current,s=r.current,l=p.current;if(!i||!s?.contentWindow||!l||n!==f.current)return;if(U(t.current)){O(),_(s.contentWindow,{type:"widget-demoted"});return}let y=D(x.current),k=V(i);if(k&&(a=E.current,!(a?.area===y.area&&B(a.rect,y.rect))||!B(w.current,k))){if(E.current?.area!==y.area&&!o(y.area)){O(),_(s.contentWindow,{type:"widget-demoted"});return}E.current=y,w.current=k;let e=m.current+1;m.current=e,f.current=e,_(s.contentWindow,{type:"widget-promote-pending",rect:q(k,y),radius:24,viewport:j(y),attemptId:e});return}null!==h.current&&(window.clearTimeout(h.current),h.current=null),p.current=null,f.current=null,c.current=l;let C=E.current??{area:"page",rect:null};E.current=null,z(i,s,C);let A=t.current;if(A){let e,t;I.current?.release(),e={area:C.area,island:A},P.add(e),!M&&document.body&&(M=new MutationObserver(S)).observe(document.body,{childList:!0,subtree:!0}),S(),t=!1,I.current={updateArea(n){t||e.area===n||(e.area=n,S())},release(){!t&&(t=!0,P.delete(e),S(),P.size>0||(M?.disconnect(),M=null))}}}let T=w.current;if(w.current=null,T){let t,n,r,a,o,s,l;t="page"!==C.area&&C.rect?C.rect.left:0,n="page"!==C.area&&C.rect?C.rect.top:0,r=j(C),a=Math.max(0,T.left-t),o=Math.max(0,T.top-n),s=Math.max(0,r.width-(a+T.width)),l=Math.max(0,r.height-(o+T.height)),i.style.clipPath=`inset(${o}px ${s}px ${l}px ${a}px round 24px)`,v.current=window.setTimeout(()=>{v.current=null;let t=e.current;t&&(t.style.clipPath="")},600)}b.current=C,R(C),u.current=!0,g.current=n,d(!0),_(s.contentWindow,{type:"widget-promoted",area:C.area,attemptId:n})},[O,o,e,r,_,t]),J=(0,n.useCallback)(()=>
1351{if(O(),E.current=null,f.current=null,null!==y.current&&(window.clearTimeout(y.current),y.current=null),u.current){var t,n,i,o;K(),t=e.current,n=c.current,i=r.current,o=a.current,t&&(t.matches(":popover-open")&&t.hidePopover(),t.removeAttribute("popover"),t.removeAttribute("style")),n&&(n.element.style.height=n.previousHeight),H(),i&&(i.style.height=`${o}px`),I.current?.release(),I.current=null,c.current=null,u.current=!1,d(!1),window.requestAnimationFrame(()=>{window.requestAnimationFrame(()=>{let e=r.current?.contentWindow;e&&_(e,{type:"widget-demote-committed"})})})}b.current=null,g.current=null,R(null);let s=r.current?.contentWindow;s&&_(s,{type:"widget-demoted"})},[O,K,e,a,r,_]),X=(0,n.useCallback)((e,t)=>{e?$("card"===t||"plane"===t||"page"===t?t:"page"):J()},[J,$]),Z=(0,n.useCallback)(()=>{let t=e.current,n=r.current;if(!t||!n||!u.current)return;let a=D(x.current),i=b.current;(i?.area===a.area||o(a.area))&&(i&&i.area===a.area&&i.rect?.left===a.rect?.left&&i.rect?.top===a.rect?.top&&i.rect?.width===a.rect?.width&&i.rect?.height===a.rect?.height||(z(t,n,a),I.current?.updateArea(a.area),b.current=a,R(a)),T())},[o,e,r,T]),ee=(0,n.useCallback)(()=>{let e=r.current;e?.contentWindow&&u.current&&(_(e.contentWindow,{type:"widget-dismiss-overlay"}),null===y.current&&(y.current=window.setTimeout(()=>{y.current=null,u.current&&J()},1500)))},[J,r,_]),et=(0,n.useCallback)(()=>{(u.current||p.current||k.current)&&J()},[J]);return(0,n.useEffect)(()=>{let e=()=>{(u.current||null!==p.current||k.current)&&U(t.current)&&J()},n=new MutationObserver(e),r=t.current;for(;r;)n.observe(r,{attributes:!0,attributeFilter:["aria-hidden","hidden","inert"]}),r=r.parentElement;return e(),()=>{n.disconnect()}},[J,t]),(0,n.useEffect)(()=>{if(!l)return;let e=e=>{e.isTrusted&&"Escape"===e.key&&J()};return window.addEventListener("resize",Z),window.addEventListener("scroll",T,!0),window.addEventListener("keydown",e,!0),()=>{window.removeEventListener("resize",Z),window.removeEventListener("scroll",T,!0),window.removeEventListener("keydown",e,!0)}},[J,l,Z,T]),(0,n.useEffect)(()=>()=>{null!==h.current&&(window.clearTimeout(h.current),h.current=null),null!==y.current&&(window.clearTimeout(y.current),y.current=null),null!==v.current&&(window.clearTimeout(v.current),v.current=null);let e=p.current;e&&(G(e),p.current=null),u.current&&(H(),u.current=!1),I.current?.release(),I.current=null,A()},[A]),{isOverlayPromoted:l,isOverlayPromotedRef:u,promotedGeometry:C,handleOverlayStateMessage:X,handlePinReady:Q,handlePromotionPainted:Y,requestOverlayDismiss:ee,teardownPromotion:et}}({containerRef:Y,promotionIslandRef:K,iframeRef:Q,iframeHeightRef:ek,sessionTokenRef:J,claimPromotion:(0,n.useCallback)(e=>ex?.claimViewport({ownerId:en,surface:"widget",stage:e})??!0,[ex,en]),releasePromotion:(0,n.useCallback)(()=>{X.current=null,ex?.releaseViewport(en)},[ex,en])}),[eT,eM]=(0,n.useState)(!1),{resolvedTheme:eS}=(0,r.useTheme)(),eO="dark"===eS||void 0===eS&&"u">typeof document&&document.documentElement.classList.contains("dark"),eD=ef??eh,eN=eD?.hasCollapsedView??e.hasCollapsedView,eW=er&&eN,eH=(0,n.useMemo)(()=>{if(eD?.sdkContext)return eD.sdkContext;let t=eD?.appId??e.appId,n=eD?.actionName?`Widget: ${eD.actionName}`:`App ${t}`;return{appId:t,appName:n,userId:"",userName:"",effectivePolicy:(0,v.createDefaultEffectivePolicy)()}},[eD,e.appId]),{requestPermission:eL}=(0,g.useAppPermissionPrompt)(),{requestIntegrationPrompt:ez}=(0,f.useAppIntegrationPrompt)();(0,n.useEffect)(()=>{ey.current=eW},[eW]);let{status:eq,error:ej,reloadApp:eG,iframeKey:eF,startHandler:eV,setStatus:eB,setError:eU}=(0,m.useAppIframeHandler)({appId:eH.appId,appName:eH.appName,userId:eH.userId,userName:eH.userName,effectivePolicy:eH.effectivePolicy,source:"chat-widget",ownerDataAliases:eH.ownerDataAliases},{onPermissionPrompt:eL,onIntegrationPrompt:ez}),e$=eD?.deps??e.deps;(0,n.useEffect)(()=>{em?eg(e=>{var t,n,r,a,i,o;return e&&eh&&(e===eh||e.actionId===eh.actionId&&e.appId===eh.appId&&e.actionName===eh.actionName&&e.component===eh.component&&e.hasCollapsedView===eh.hasCollapsedView&&((e,t)=>{if(e===t)return!0;
1351if(!e||!t)return!1;let n=e.packages??{},r=t.packages??{},a=Object.keys(n),i=Object.keys(r);if(a.length!==i.length)return!1;for(let e of a){let t=n[e]??[],a=r[e]??[];if(t.length!==a.length)return!1;for(let e=0;e<t.length;e+=1)if(t[e]?.source!==a[e]?.source||t[e]?.local!==a[e]?.local)return!1}return!0})(e.deps,eh.deps)&&(t=e.sdkContext,t===(n=eh.sdkContext)||t&&n&&t.appId===n.appId&&t.appName===n.appName&&t.userId===n.userId&&t.userName===n.userName&&((r=t.effectivePolicy)===(a=n.effectivePolicy)||r&&a&&r.manifestVersion===a.manifestVersion&&r.manifestFingerprint===a.manifestFingerprint&&r.staleGrant===a.staleGrant&&r.networkHttpAllowAllDomains===a.networkHttpAllowAllDomains&&C(r.deniedDomains,a.deniedDomains)&&C(r.effectiveDomains,a.effectiveDomains)&&C(r.manifestRequestedDomains,a.manifestRequestedDomains)&&R(r.effectivePermissions,a.effectivePermissions)&&R(r.manifestRequestedPermissions,a.manifestRequestedPermissions))&&((i=t.ownerDataAliases)===(o=n.ownerDataAliases)||i&&o&&i.length===o.length&&i.every((e,t)=>e===o[t]))))?e:eh}):eg(e=>e?null:e)},[em,eh]),(0,n.useEffect)(()=>{if(em)return;let t=!0;return(async()=>{eB("loading");try{var n,r;let a=encodeURIComponent(e.actionId),i=new URL(`/api/apps/manage/actions/${a}/widget`,window.location.origin);i.searchParams.set("appId",e.appId),i.searchParams.set("actionName",e.actionName);let o=await (0,k.workspaceFetch)(`${i.pathname}${i.search}`);if(!o.ok){let e=await o.json().catch(()=>null),t=(0,c.isObjectRecord)(e)&&"string"==typeof e.error?e.error:"Failed to load widget";throw Error(t)}let s=await o.json();if(!(0,c.isObjectRecord)(s)||(n=s.widget,!((0,c.isObjectRecord)(n)&&"string"==typeof n.actionId&&"string"==typeof n.appId&&"string"==typeof n.actionName&&"string"==typeof n.component&&"boolean"==typeof n.hasCollapsedView&&(void 0===n.deps||(0,d.isAppDeps)(n.deps))&&(void 0===n.sdkContext||(r=n.sdkContext,(0,c.isObjectRecord)(r)&&"string"==typeof r.appId&&"string"==typeof r.appName&&"string"==typeof r.userId&&"string"==typeof r.userName&&(0,u.isEffectiveAppPolicy)(r.effectivePolicy)&&(void 0===r.ownerDataAliases||Array.isArray(r.ownerDataAliases)&&r.ownerDataAliases.every(e=>"string"==typeof e)))))))throw Error("Widget not found");let l=s.widget;if(!t)return;eg(l)}catch(e){if(!t)return;eU(e instanceof Error?e.message:"Failed to load widget")}})(),()=>{t=!1}},[ew,eU,eB,e.actionId,e.actionName,e.appId,em]),(0,n.useEffect)(()=>{function e(e){var t;if(e.data&&"string"==typeof e.data.type&&(!Q.current||e.source===Q.current.contentWindow)&&("widget-overlay-state"!==(t=e.data.type)&&"widget-overlay-closing"!==t&&"widget-viewport-expand-request"!==t&&"widget-pin-ready"!==t&&"widget-promoted-painted"!==t||null!==J.current&&e.data.sessionToken===J.current))switch(e.data.type){case"resize":if(eb.current)break;"number"==typeof e.data.height&&Number.isFinite(e.data.height)&&e.data.height>0&&el(Math.min(Math.ceil(e.data.height),2400)),"number"==typeof e.data.width&&Number.isFinite(e.data.width)&&e.data.width>0&&eu(Math.ceil(e.data.width));break;case"widget-press-start":eW&&eo(!0);break;case"widget-press-end":eo(!1);break;case"widget-expand":eW&&ea(!1);break;case"widget-overlay-state":if("boolean"==typeof e.data.open){let t="card"===e.data.area||"plane"===e.data.area||"page"===e.data.area?e.data.area:void 0;if(e.data.open){if("api"===e.data.source){let n=X.current;if(void 0===t||null===n||n.area!==t||n.grantId!==e.data.authorizationGrantId){X.current=null,ee.current=!1,null!==Z.current&&(window.clearTimeout(Z.current),Z.current=null),et.current=!1,eM(!1),eC(!1);break}X.current=null}}else X.current=null;e.data.open?(ee.current||(null!==Z.current&&(window.clearTimeout(Z.current),Z.current=null),et.current=!1),ee.current=!0):(ee.current=!1,null!==Z.current&&(window.clearTimeout(Z.current),Z.current=null)),eM(!1),eC(e.data.open,t)}break;case"widget-viewport-expand-request":if(Number.isSafeInteger(e.data.requestId)&&("card"===e.data.area||"plane"===e.data.area||"page"===e.data.area)){let t=J.current,n=Q.current;if(null===t||!n?.contentWindow)break;let r=(0,v.canInvokeSdkMethod)(eH.effectivePolicy,"viewport.expand")&&F(n),a=r?(0,E.generateUUID)():null;X.current=null===a?null:{grantId:a,area:e.data.area},n.contentWindow.postMessage({type:"widget-viewport-expand-authorized",requestId:e.data.requestId,allowed:r,...null===a?{}:{grantId:a},sessionToken:t},"*")}break;case"widget-overlay-closing":"boolean"==typeof e.data.closing&&(e.data.closing?ee.current&&!et.current&&(eM(!0),null===Z.current&&(Z.current=window.setTimeout(()=>{Z.current=null,et.current=!0,eM(!1)},1500))):eM(!1));break;case"widget-pin-ready":Number.isSafeInteger(e.data.attemptId)&&eR(e.data.attemptId);break;case"widget-promoted-painted":Number.isSafeInteger(e.data.attemptId)&&e_(e.data.attemptId)}}return window.addEventListener("message",e),()=>{window.removeEventListener("message",e),null!==Z.current&&(window.clearTimeout(Z.current),Z.current=null),ee.current=!1,et.current=!1}},[eW,eC,eR,e_,eb,eH.effectivePolicy]),(0,n.useEffect)(()=>{let e,t=Y.current;if(!t||!eD)return;let n=null;eu(0),(n=document.createElement("iframe")).sandbox.add("allow-scripts","allow-forms","allow-downloads"),n.className="block w-full border-0",n.style.height=`${es}px`,n.title=`Widget: ${eD.actionName}`;let r=(0,l.computeWidgetBundles)(e$),a=(0,h.getHashedBundleNames)(r),i=(0,h.getRequiredHashedFilenames)(),o=(0,w.buildIframeRuntimeConfig)({baseUrl:window.location.origin,darkMode:eO,hashedFilenames:i}),{bundleUrls:s,bundleNames:d}=(0,w.buildBundleUrls)(o.runtimeBaseUrl,a);(0,h.prefetchBundles)(r).catch(()=>null),n.src=`${o.runtimeBaseUrl}/iframe.html#dark=${+!!eO}`,t.replaceChildren(n),Q.current=n;let u=(0,E.generateUUID)();J.current=u,X.current=null,e=eV(n,{sessionToken:u});let c=!1,p=()=>{(()=>{if(c)return;c=!0;
1351let e=(0,l.buildWidgetCode)(eD.component,_,ey.current,o.parentOrigin,u),t=(0,w.generatePackageDeclarations)(e$?.packages),r={type:"initialize-app",runtime:o,context:{appId:eH.appId,appName:eH.appName,userId:eH.userId,userName:eH.userName},code:e,packageDeclarations:t,hasPrefetch:!1,renderMode:"widget",bundleUrls:s,bundleNames:d,sessionToken:u};n.contentWindow?.postMessage(r,"*")})()};return n.addEventListener("load",p),()=>{e?.(),J.current===u&&(J.current=null,X.current=null),n.removeEventListener("load",p),n&&n.remove(),Q.current=null,eP()}},[eD,eF,eV,eH,eP]);let eK=(0,n.useRef)(null);(0,n.useEffect)(()=>{"ready"!==eq&&"error"!==eq||eK.current!==_&&(eK.current=_,Q.current?.contentWindow?.postMessage({type:"set-data",data:_},"*"))},[_,eq]),(0,n.useEffect)(()=>{if("ready"!==eq&&"error"!==eq)return;let e=Q.current;e&&e.contentWindow?.postMessage({type:"set-dark-mode",darkMode:eO},"*")},[eO,eq]),(0,n.useEffect)(()=>{if("ready"!==eq&&"error"!==eq)return;let e=Q.current;e&&e.contentWindow?.postMessage({type:"set-collapsed",isCollapsed:eW},"*")},[eW,eq]),(0,n.useEffect)(()=>{eW||eo(!1)},[eW]),(0,n.useEffect)(()=>{ek.current=es,!eE&&Q.current&&(Q.current.style.height=`${es}px`)},[es,eE]);let eY=(0,n.useCallback)(()=>{eB("loading"),eG(),em||(eg(null),ev(e=>e+1))},[em,eG,eB]),eQ=(0,n.useCallback)(()=>{ea(e=>!e)},[]),eJ=(0,n.useCallback)(async e=>{try{await navigator.clipboard.writeText(e),ep(!0)}catch{}},[]);if((0,n.useEffect)(()=>{if(!ec)return;let e=window.setTimeout(()=>{ep(!1)},2e3);return()=>window.clearTimeout(e)},[ec]),"error"===eq&&ej){let e=(0,m.formatAppIframeError)(ej);return(0,t.jsx)("div",{ref:N,className:"w-full",children:(0,t.jsxs)("div",{className:"relative flex flex-col items-center rounded-2xl border border-error-outline bg-error-soft p-4 text-center shadow-sm",children:[(0,t.jsx)(x.Button,{type:"button",variant:"ghost",size:"icon-sm","aria-label":ec?"Error copied":"Copy error",title:ec?"Error copied":"Copy error",className:"absolute top-3 right-3 bg-error-soft text-error hover:bg-error-soft-hover hover:text-error",onClick:()=>{eJ(e)},children:ec?(0,t.jsx)(i.Check,{className:"size-3.5"}):(0,t.jsx)(o.Copy,{className:"size-3.5"})}),(0,t.jsxs)("div",{className:"flex items-center gap-2 text-error",children:[(0,t.jsx)(a.AlertCircle,{className:"size-4 shrink-0"}),(0,t.jsx)("div",{className:"text-sm font-semibold",children:"Widget error"})]}),(0,t.jsx)("p",{className:"mt-2 max-w-sm text-xs leading-5 text-error-muted",children:"This widget hit a rendering problem. You can retry loading it."}),(0,t.jsx)("pre",{className:"mt-4 w-full max-w-md overflow-auto rounded-xl border border-error-outline bg-card/70 p-3 text-left text-xs wrap-break-word whitespace-pre-wrap text-error",children:e}),(0,t.jsxs)(x.Button,{type:"button",variant:"destructive",size:"sm",className:"mt-4",onClick:eY,children:[(0,t.jsx)(s.RefreshCw,{className:"size-3"}),"Retry"]})]})})}let eX=!!eD,eZ=(!!T||!!eN)&&(O||eX);if(!eX&&!O)return(0,t.jsx)("div",{ref:N,className:"w-full"});let e0="ready"===eq||"error"===eq,e1=es>0,e2=O&&(!e0||!e1||!eX);return(0,t.jsxs)("div",{ref:N,className:"w-full",children:[eZ&&(0,t.jsx)(I.DynamicWidgetHeader,{prefix:T,isCollapsed:eW,hasCollapsedView:!!eN,setIsCollapsed:eQ,isButtonPressed:ei,setIsButtonPressed:eo}),(0,t.jsxs)("div",{ref:K,className:"relative w-full",children:[e2&&(0,t.jsx)("div",{className:"w-full",style:{minHeight:b.WIDGET_PLACEHOLDER_MIN_HEIGHT_PX}}),(0,t.jsx)("div",{className:`widget-container ${e2?"absolute inset-0":"relative"} w-full transform overflow-hidden transition-[transform,scale,opacity,border-radius] duration-200 ${eW?$.WIDGET_COLLAPSED_SHELL_CLASS:"scale-100"}`,style:{width:"100%",maxWidth:ed>0?`${Math.ceil(ed)}px`:void 0,transform:(0,$.getWidgetPressTransform)(ei,eW),backgroundColor:eW?"transparent":void 0,borderRadius:eW?void 0:"24px",visibility:e0&&eX&&e1?"visible":"hidden",minHeight:O&&!e1?b.WIDGET_PLACEHOLDER_MIN_HEIGHT_PX:void 0},children:(0,t.jsx)("div",{ref:Y,className:"w-full"})}),eE&&(0,t.jsx)(p.ViewportDismissPill,{closing:eT,onDismiss:eA,anchorRect:eI&&"page"!==eI.area?eI.rect:null})]})]})});e.s(["UserAppWidget",0,K],661831)},287098,372642,798307,e=>{"use strict";e.s(["WIDGET_PLACEHOLDER_MIN_HEIGHT_PX",0,80],287098);var t=e.i(943306),n=e.i(302309),r=e.i(800636),a=e.i(809382);e.s(["DynamicWidgetHeader",0,function({prefix:e,isCollapsed:i,hasCollapsedView:o,setIsCollapsed:s,setIsButtonPressed:l}){return(0,t.jsx)("div",{className:"flex max-w-full min-w-0 items-center",children:o?(0,t.jsxs)("div",{className:"flex w-full min-w-0 cursor-pointer items-center gap-1",onClick:e=>{e.stopPropagation(),s()},onMouseDown:()=>l(!0),onMouseUp:()=>l(!1),onMouseLeave:()=>l(!1),children:[(0,t.jsx)("div",{className:"markdown-widget min-w-0 text-xl font-medium wrap-break-word text-foreground",children:e}),(0,t.jsx)(a.Button,{variant:"ghost",size:"icon-sm",className:"ml-auto shrink-0","aria-hidden":"true",tabIndex:-1,
1351children:i?(0,t.jsx)(r.ChevronUp,{className:"size-5"}):(0,t.jsx)(n.ChevronDown,{className:"size-5"})})]}):(0,t.jsx)("div",{className:"markdown-widget max-w-full min-w-0 text-xl font-medium wrap-break-word text-foreground",children:e})})}],372642),e.s(["WIDGET_COLLAPSED_SHELL_CLASS",0,"scale-[0.99] cursor-pointer hover:opacity-80 [&:hover_a]:opacity-100 [&:hover_button]:opacity-100 [&:hover_input]:opacity-100 [&:hover_select]:opacity-100 [&:hover_textarea]:opacity-100","getWidgetPressTransform",0,(e,t)=>e?t?"scale(0.98)":"scale(0.985)":void 0],798307)},254581,e=>{"use strict";var t=e.i(352255);async function n(e){if(!(0,t.isPushSupported)())return{supported:!1,permission:"default",subscribed:!1};let n=Notification.permission,r=!1;try{let n=e?await (0,t.getExistingSubscription)({appId:e}):await (0,t.getExistingSubscription)();r=null!==n}catch{r=!1}return{supported:!0,permission:n,subscribed:r}}e.s(["getPushStatus",0,n])},857821,e=>{"use strict";var t=e.i(943306);e.s(["ActionIcon",0,function({className:e}){return(0,t.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",className:e,children:(0,t.jsx)("path",{d:"M8.628 12.674H8.17c-1.484 0-2.226 0-2.542-.49-.316-.489-.015-1.17.587-2.533l1.812-4.098c.548-1.24.822-1.859 1.353-2.206C9.911 3 10.586 3 11.935 3h2.09c1.638 0 2.458 0 2.767.535.309.536-.098 1.251-.91 2.681l-1.073 1.886c-.404.711-.606 1.067-.603 1.358.004.378.205.726.53.917.25.147.657.147 1.472.147 1.03 0 1.545 0 1.813.178.349.232.531.646.467 1.061-.049.32-.395.702-1.088 1.469l-5.535 6.12c-1.087 1.203-1.631 1.804-1.996 1.614-.365-.19-.19-.983.16-2.569l.687-3.107c.267-1.207.4-1.811.08-2.213-.322-.403-.937-.403-2.168-.403Z"})})}])},208406,e=>{"use strict";let t=(0,e.i(820750).default)("arrow-up-right",[["path",{d:"M7 7h10v10",key:"1tivn9"}],["path",{d:"M7 17 17 7",key:"1vkiza"}]]);e.s(["default",0,t])},767904,e=>{"use strict";let t=(0,e.i(820750).default)("bell-off",[["path",{d:"M10.268 21a2 2 0 0 0 3.464 0",key:"vwvbt9"}],["path",{d:"M17 17H4a1 1 0 0 1-.74-1.673C4.59 13.956 6 12.499 6 8a6 6 0 0 1 .258-1.742",key:"178tsu"}],["path",{d:"m2 2 20 20",key:"1ooewy"}],["path",{d:"M8.668 3.01A6 6 0 0 1 18 8c0 2.687.77 4.653 1.707 6.05",key:"1hqiys"}]]);e.s(["default",0,t])},449449,e=>{"use strict";let t=(0,e.i(820750).default)("bell",[["path",{d:"M10.268 21a2 2 0 0 0 3.464 0",key:"vwvbt9"}],["path",{d:"M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326",key:"11g9vi"}]]);e.s(["default",0,t])},170914,e=>{"use strict";let t=(0,e.i(820750).default)("blocks",[["path",{d:"M10 22V7a1 1 0 0 0-1-1H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-5a1 1 0 0 0-1-1H2",key:"1ah6g2"}],["rect",{x:"14",y:"2",width:"8",height:"8",rx:"1",key:"88lufb"}]]);e.s(["default",0,t])},312238,e=>{"use strict";let t=(0,e.i(820750).default)("calendar",[["path",{d:"M8 2v4",key:"1cmpym"}],["path",{d:"M16 2v4",key:"4m81vk"}],["rect",{width:"18",height:"18",x:"3",y:"4",rx:"2",key:"1hopcy"}],["path",{d:"M3 10h18",key:"8toen8"}]]);e.s(["default",0,t])},161930,e=>{"use strict";let t=(0,e.i(820750).default)("chevron-up",[["path",{d:"m18 15-6-6-6 6",key:"153udz"}]]);e.s(["default",0,t])},800636,e=>{"use strict";var t=e.i(161930);e.s(["ChevronUp",()=>t.default])},228904,e=>{"use strict";let t=(0,e.i(820750).default)("chevrons-up-down",[["path",{d:"m7 15 5 5 5-5",key:"1hf1tw"}],["path",{d:"m7 9 5-5 5 5",key:"sgt6xg"}]]);e.s(["default",0,t])},208781,e=>{"use strict";let t=(0,e.i(820750).default)("circle-dashed",[["path",{d:"M10.1 2.182a10 10 0 0 1 3.8 0",key:"5ilxe3"}],["path",{d:"M13.9 21.818a10 10 0 0 1-3.8 0",key:"11zvb9"}],["path",{d:"M17.609 3.721a10 10 0 0 1 2.69 2.7",key:"1iw5b2"}],["path",{d:"M2.182 13.9a10 10 0 0 1 0-3.8",key:"c0bmvh"}],["path",{d:"M20.279 17.609a10 10 0 0 1-2.7 2.69",key:"1ruxm7"}],["path",{d:"M21.818 10.1a10 10 0 0 1 0 3.8",key:"qkgqxc"}],["path",{d:"M3.721 6.391a10 10 0 0 1 2.7-2.69",key:"1mcia2"}],["path",{d:"M6.391 20.279a10 10 0 0 1-2.69-2.7",key:"1fvljs"}]]);e.s(["default",0,t])},992322,584506,979991,e=>{"use strict";var t=e.i(820750);let n=(0,t.default)("circle-plus",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M8 12h8",key:"1wcyev"}],["path",{d:"M12 8v8",key:"napkw2"}]]);e.s(["default",0,n],992322);let r=(0,t.default)("square-minus",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M8 12h8",key:"1wcyev"}]]);e.s(["default",0,r],584506);let a=(0,t.default)("square-plus",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M8 12h8",key:"1wcyev"}],["path",{d:"M12 8v8",key:"napkw2"}]]);e.s(["default",0,a],979991)},488884,137107,790045,e=>{"use strict";var t=e.i(820750);
1351let n=(0,t.default)("clipboard-check",[["rect",{width:"8",height:"4",x:"8",y:"2",rx:"1",ry:"1",key:"tgr4d6"}],["path",{d:"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2",key:"116196"}],["path",{d:"m9 14 2 2 4-4",key:"df797q"}]]);e.s(["default",0,n],488884);let r=(0,t.default)("clipboard-clock",[["path",{d:"M16 14v2.2l1.6 1",key:"fo4ql5"}],["path",{d:"M16 4h2a2 2 0 0 1 2 2v.832",key:"1ujtp2"}],["path",{d:"M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h2",key:"qvpao1"}],["circle",{cx:"16",cy:"16",r:"6",key:"qoo3c4"}],["rect",{x:"8",y:"2",width:"8",height:"4",rx:"1",key:"ublpy"}]]);e.s(["default",0,r],137107);let a=(0,t.default)("clipboard-x",[["rect",{width:"8",height:"4",x:"8",y:"2",rx:"1",ry:"1",key:"tgr4d6"}],["path",{d:"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2",key:"116196"}],["path",{d:"m15 11-6 6",key:"1toa9n"}],["path",{d:"m9 11 6 6",key:"wlibny"}]]);e.s(["default",0,a],790045)},717345,e=>{"use strict";let t=(0,e.i(820750).default)("coins",[["path",{d:"M13.744 17.736a6 6 0 1 1-7.48-7.48",key:"bq4yh3"}],["path",{d:"M15 6h1v4",key:"11y1tn"}],["path",{d:"m6.134 14.768.866-.5 2 3.464",key:"17snzx"}],["circle",{cx:"16",cy:"8",r:"6",key:"14bfc9"}]]);e.s(["default",0,t])},761475,e=>{"use strict";let t=(0,e.i(820750).default)("credit-card",[["rect",{width:"20",height:"14",x:"2",y:"5",rx:"2",key:"ynyp8z"}],["line",{x1:"2",x2:"22",y1:"10",y2:"10",key:"1b3vmo"}]]);e.s(["default",0,t])},962266,e=>{"use strict";let t=(0,e.i(820750).default)("crown",[["path",{d:"M11.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294z",key:"1vdc57"}],["path",{d:"M5 21h14",key:"11awu3"}]]);e.s(["default",0,t])},479505,e=>{"use strict";let t=(0,e.i(820750).default)("ellipsis",[["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["circle",{cx:"19",cy:"12",r:"1",key:"1wjl8i"}],["circle",{cx:"5",cy:"12",r:"1",key:"1pcz8c"}]]);e.s(["default",0,t])},161815,e=>{"use strict";let t=(0,e.i(820750).default)("gauge",[["path",{d:"m12 14 4-4",key:"9kzdfg"}],["path",{d:"M3.34 19a10 10 0 1 1 17.32 0",key:"19p75a"}]]);e.s(["default",0,t])},665931,e=>{"use strict";let t=(0,e.i(820750).default)("hammer",[["path",{d:"m15 12-9.373 9.373a1 1 0 0 1-3.001-3L12 9",key:"1hayfq"}],["path",{d:"m18 15 4-4",key:"16gjal"}],["path",{d:"m21.5 11.5-1.914-1.914A2 2 0 0 1 19 8.172v-.344a2 2 0 0 0-.586-1.414l-1.657-1.657A6 6 0 0 0 12.516 3H9l1.243 1.243A6 6 0 0 1 12 8.485V10l2 2h1.172a2 2 0 0 1 1.414.586L18.5 14.5",key:"15ts47"}]]);e.s(["default",0,t])},668120,e=>{"use strict";let t=(0,e.i(820750).default)("image-up",[["path",{d:"M10.3 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v10l-3.1-3.1a2 2 0 0 0-2.814.014L6 21",key:"9csbqa"}],["path",{d:"m14 19.5 3-3 3 3",key:"9vmjn0"}],["path",{d:"M17 22v-5.5",key:"1aa6fl"}],["circle",{cx:"9",cy:"9",r:"2",key:"af1f0g"}]]);e.s(["default",0,t])},667730,e=>{"use strict";let t=(0,e.i(820750).default)("image",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",ry:"2",key:"1m3agn"}],["circle",{cx:"9",cy:"9",r:"2",key:"af1f0g"}],["path",{d:"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21",key:"1xmnt7"}]]);e.s(["default",0,t])},660355,e=>{"use strict";let t=(0,e.i(820750).default)("import",[["path",{d:"M12 3v12",key:"1x0j5s"}],["path",{d:"m8 11 4 4 4-4",key:"1dohi6"}],["path",{d:"M8 5H4a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-4",key:"1ywtjm"}]]);e.s(["default",0,t])},77185,e=>{"use strict";let t=(0,e.i(820750).default)("infinity",[["path",{d:"M6 16c5 0 7-8 12-8a4 4 0 0 1 0 8c-5 0-7-8-12-8a4 4 0 1 0 0 8",key:"18ogeb"}]]);e.s(["default",0,t])},792793,e=>{"use strict";let t=(0,e.i(820750).default)("key-round",[["path",{d:"M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z",key:"1s6t7t"}],["circle",{cx:"16.5",cy:"7.5",r:".5",fill:"currentColor",key:"w0ekpg"}]]);e.s(["default",0,t])},945447,e=>{"use strict";let t=(0,e.i(820750).default)("layers",[["path",{d:"M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z",key:"zw3jo"}],["path",{d:"M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12",key:"1wduqc"}],["path",{d:"M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17",key:"kqbvx6"}]]);e.s(["default",0,t])},206209,e=>{"use strict";let t=(0,e.i(820750).default)("link-2",[["path",{d:"M9 17H7A5 5 0 0 1 7 7h2",ke
1351y:"8i5ue5"}],["path",{d:"M15 7h2a5 5 0 1 1 0 10h-2",key:"1b9ql8"}],["line",{x1:"8",x2:"16",y1:"12",y2:"12",key:"1jonct"}]]);e.s(["default",0,t])},130701,e=>{"use strict";let t=(0,e.i(820750).default)("message-circle-plus",[["path",{d:"M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719",key:"1sd12s"}],["path",{d:"M8 12h8",key:"1wcyev"}],["path",{d:"M12 8v8",key:"napkw2"}]]);e.s(["default",0,t])},26610,e=>{"use strict";let t=(0,e.i(820750).default)("message-square",[["path",{d:"M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z",key:"18887p"}]]);e.s(["default",0,t])},989974,e=>{"use strict";let t=(0,e.i(820750).default)("monitor-smartphone",[["path",{d:"M18 8V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h8",key:"10dyio"}],["path",{d:"M10 19v-3.96 3.15",key:"1irgej"}],["path",{d:"M7 19h5",key:"qswx4l"}],["rect",{width:"6",height:"10",x:"16",y:"12",rx:"2",key:"1egngj"}]]);e.s(["default",0,t])},959372,e=>{"use strict";let t=(0,e.i(820750).default)("moon-star",[["path",{d:"M18 5h4",key:"1lhgn2"}],["path",{d:"M20 3v4",key:"1olli1"}],["path",{d:"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401",key:"kfwtm"}]]);e.s(["default",0,t])},676172,e=>{"use strict";let t=(0,e.i(820750).default)("pen-line",[["path",{d:"M13 21h8",key:"1jsn5i"}],["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}]]);e.s(["default",0,t])},444678,e=>{"use strict";let t=(0,e.i(820750).default)("refresh-cw",[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]]);e.s(["default",0,t])},27464,e=>{"use strict";var t=e.i(444678);e.s(["RefreshCw",()=>t.default])},788679,e=>{"use strict";let t=(0,e.i(820750).default)("rocket",[["path",{d:"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5",key:"qeys4"}],["path",{d:"M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09",key:"u4xsad"}],["path",{d:"M9 12a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.4 22.4 0 0 1-4 2z",key:"676m9"}],["path",{d:"M9 12H4s.55-3.03 2-4c1.62-1.08 5 .05 5 .05",key:"92ym6u"}]]);e.s(["default",0,t])},391485,e=>{"use strict";let t=(0,e.i(820750).default)("shield-check",[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]]);e.s(["default",0,t])},825395,e=>{"use strict";let t=(0,e.i(820750).default)("sliders-horizontal",[["path",{d:"M10 5H3",key:"1qgfaw"}],["path",{d:"M12 19H3",key:"yhmn1j"}],["path",{d:"M14 3v4",key:"1sua03"}],["path",{d:"M16 17v4",key:"1q0r14"}],["path",{d:"M21 12h-9",key:"1o4lsq"}],["path",{d:"M21 19h-5",key:"1rlt1p"}],["path",{d:"M21 5h-7",key:"1oszz2"}],["path",{d:"M8 10v4",key:"tgpxqk"}],["path",{d:"M8 12H3",key:"a7s4jb"}]]);e.s(["default",0,t])},176349,e=>{"use strict";let t=(0,e.i(820750).default)("smartphone",[["rect",{width:"14",height:"20",x:"5",y:"2",rx:"2",ry:"2",key:"1yt0o3"}],["path",{d:"M12 18h.01",key:"mhygvu"}]]);e.s(["default",0,t])},705323,e=>{"use strict";let t=(0,e.i(820750).default)("star",[["path",{d:"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z",key:"r04s7s"}]]);e.s(["default",0,t])},946608,e=>{"use strict";let t=(0,e.i(820750).default)("store",[["path",{d:"M15 21v-5a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v5",key:"slp6dd"}],["path",{d:"M17.774 10.31a1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.451 0 1.12 1.12 0 0 0-1.548 0 2.5 2.5 0 0 1-3.452 0 1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.77-3.248l2.889-4.184A2 2 0 0 1 7 2h10a2 2 0 0 1 1.653.873l2.895 4.192a2.5 2.5 0 0 1-3.774 3.244",key:"o0xfot"}],["path",{d:"M4 10.95V19a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8.05",key:"wn3emo"}]]);e.s(["default",0,t])},43416,e=>{"use strict";let t=(0,e.i(820750).default)("user-round",[["circle",{cx:"12",cy:"8",r:"5",key:"1hypcn"}
1351],["path",{d:"M20 21a8 8 0 0 0-16 0",key:"rfgkzh"}]]);e.s(["default",0,t])},917225,e=>{"use strict";let t=(0,e.i(820750).default)("webhook",[["path",{d:"M18 16.98h-5.99c-1.1 0-1.95.94-2.48 1.9A4 4 0 0 1 2 17c.01-.7.2-1.4.57-2",key:"q3hayz"}],["path",{d:"m6 17 3.13-5.78c.53-.97.1-2.18-.5-3.1a4 4 0 1 1 6.89-4.06",key:"1go1hn"}],["path",{d:"m12 6 3.13 5.73C15.66 12.7 16.9 13 18 13a4 4 0 0 1 0 8",key:"qlwsc0"}]]);e.s(["default",0,t])},169900,e=>{"use strict";let t=(0,e.i(820750).default)("zap",[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]]);e.s(["default",0,t])}]); 1352 1353//# chunkId=01a0804f-8530-70d2-8e8e-acee8a012ed6
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.