(trigger, receipt) => { const PENDING_KEY = "__labs3daiFallbackPending"; const ALLOWED_PARENTS = __LABS_EMBED_PARENTS__; const ticket = receipt && typeof receipt === "object" ? receipt.ticket : null; const parentOrigin = new URLSearchParams(location.search).get("__labs_parent"); const ack = extra => Object.assign({ticket: ticket}, extra); const skip = reason => [ack({no_fallback: true, reason: reason}), receipt]; if (window.parent === window) return skip("no_parent_frame"); if (!ALLOWED_PARENTS.includes(parentOrigin)) return skip("parent_not_allowed"); if (typeof ticket !== "string" || !ticket || ticket.length > 4096) return skip("no_ticket"); const pending = (window[PENDING_KEY] = window[PENDING_KEY] || new Map()); if (pending.has(ticket)) return pending.get(ticket); const requestId = typeof crypto.randomUUID === "function" ? crypto.randomUUID() : `${Date.now().toString(16)}-${Math.random().toString(16).slice(2)}`; const imageInput = document.querySelector('input[type="file"]'); const promise = new Promise(resolve => { let settled = false; const settle = ackValue => { if (settled) return; settled = true; clearTimeout(timer); window.removeEventListener("message", receive); window.removeEventListener("pagehide", cancel); imageInput?.removeEventListener("change", cancel); document.removeEventListener("click", onClear, true); pending.delete(ticket); resolve([ackValue, receipt]); }; const cancel = () => settle(ack({cancelled: true})); const onClear = event => { if (event.target.closest?.('button[aria-label="Remove Image"], button[aria-label="Clear"], table[role="grid"] tbody tr')) cancel(); }; const receive = event => { if (event.source !== window.parent || event.origin !== parentOrigin) return; const data = event.data; if (!data || data.type !== "labs:3dai-result" || data.requestId !== requestId) return; if (data.cancelled) return cancel(); if (data.error) return settle(ack({error: String(data.error)})); if (data.ready === true) return settle(ack({ready: true})); }; const timer = setTimeout(cancel, 120000); window.addEventListener("message", receive); window.addEventListener("pagehide", cancel, {once: true}); imageInput?.addEventListener("change", cancel, {once: true}); document.addEventListener("click", onClear, true); window.parent.postMessage({type: "labs:3dai-fallback", requestId, ticket}, parentOrigin); }); pending.set(ticket, promise); return promise; }