@neurodyn/core-ar 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- (()=>{"use strict";let e,t,i;function r(e,t){let i;try{i=new URL(e)}catch{throw TypeError(`${t} must be an absolute HTTP(S) URL`)}if("http:"!==i.protocol&&"https:"!==i.protocol)throw TypeError(`${t} must be an absolute HTTP(S) URL`);return i.origin}function o(){if(!e)throw Error("Core AR widget runtime is not configured");return e}function n(){return"u"<typeof navigator?"":navigator.userAgent||navigator.vendor||""}function a(){if("u"<typeof window||"u"<typeof navigator)return!1;let e="MacIntel"===navigator.platform&&navigator.maxTouchPoints>1;return(/iPad|iPhone|iPod/.test(n())||e)&&!("MSStream"in window)}function s(){if("u"<typeof window||"u"<typeof navigator)return!1;let e=navigator.maxTouchPoints>1,t=window.matchMedia?.("(pointer: coarse)").matches??!1,i=/Android|iPhone|iPad|iPod|webOS|BlackBerry|Windows Phone|Opera Mini|IEMobile|Mobile/i.test(n());return e&&t&&(i||a())}function l(){let e=n();return[[/edg/i,"Microsoft Edge"],[/trident/i,"Microsoft Internet Explorer"],[/firefox|fxios/i,"Mozilla Firefox"],[/opr\//i,"Opera"],[/ucbrowser/i,"UC Browser"],[/samsungbrowser/i,"Samsung Browser"],[/chrome|chromium|crios/i,"Google Chrome"],[/safari/i,"Apple Safari"]].find(([t])=>t.test(e))?.[1]??"Other"}function c(){let e=function(){let e=n(),t=e.match(/\bOS (\d+)/)?.[1]??e.match(/Version\/(\d+)/)?.[1];if(!t)return null;let i=Number.parseInt(t,10);return Number.isNaN(i)?null:i}();return null!==e&&e>=17}function d(e){let t;try{t=new URL(e)}catch{throw TypeError("Native AR asset URL must be absolute HTTP(S)")}if("http:"!==t.protocol&&"https:"!==t.protocol)throw TypeError("Native AR asset URL must be absolute HTTP(S)");return t.href}function u(e,t){let i=d(e.glbUrl),r=d(e.usdzUrl),o=encodeURIComponent(i),n=`intent://arvr.google.com/scene-viewer/1.0?file=${o}&resizable=false${"wall"===t||"ceiling"===t?"&enable_vertical_placement=true":""}&mode=ar_preferred#Intent;scheme=https;package=com.google.android.googlequicksearchbox;action=android.intent.action.VIEW;end;`,s=`${r}#allowsContentScaling=0`;return a()?s:n}function g(e,t=0){let i=document.createElement("a"),r=document.createElement("img");i.rel="ar",i.href=e,i.hidden=!0,r.alt="",r.hidden=!0,i.appendChild(r),document.body.appendChild(i),window.setTimeout(()=>{i.click(),i.remove()},t)}function h(e,t){let i=function(e,t){let{brand:i}=t??o();if(a()){let t=new URL("https://appclip.apple.com/id");return t.searchParams.set("p","com.us.vizbl.Clip"),t.searchParams.set("tinuuid",e),t.searchParams.set("region","arizo"===i?"ru":"en"),t.toString()}return`intent:/${window.location.pathname}#Intent;scheme=open;package=com.us.vizbl;end`}(e,t);window.self===window.top||l().toLowerCase().includes("edge")?window.location.assign(i):window.open(i,"_top")}function p(e,t,i=!1,r){let{viewerOrigin:n}=r??o(),a=new URL("/ar/index.html",n);return a.searchParams.set("tinuuid",e),t&&a.searchParams.set("hid",t),i&&a.searchParams.set("appview","true"),a.toString()}function m(){let e=new WeakMap;return function(t){let i=e.get(t);i?.cleanup?.();let r={revision:(i?.revision??0)+1};return e.set(t,r),{isCurrent:()=>e.get(t)===r,register(i){let o=!1,n=()=>{o||(o=!0,i())};return e.get(t)!==r?(n(),n):(r.cleanup=n,()=>{e.get(t)===r&&e.delete(t),n()})}}}}let f=0;function w(){return window.QRCode}async function v(e,r="vizblQrModal",n,a){let s,l=++f;i?.(),document.querySelectorAll("[data-vizbl-qr-modal]").forEach(e=>e.remove());let c=function(e){let{brand:t,viewerOrigin:i}=e??o(),r="arizo"===t,n=document.createElement("div");n.dataset.vizblQrModal="",n.setAttribute("aria-label","View object in augmented reality"),n.setAttribute("aria-modal","true"),n.setAttribute("role","dialog"),Object.assign(n.style,{alignItems:"center",backgroundColor:"rgba(0,0,0,0.25)",display:"none",height:"100%",justifyContent:"center",left:"0",position:"fixed",top:"0",width:"100%",zIndex:"9999"});let a=document.createElement("div");Object.assign(a.style,{backgroundColor:"#fff",borderRadius:"12px",boxSizing:"border-box",color:"#000",fontFamily:"Inter, sans-serif",minHeight:"372px",padding:"48px 52px 40px",position:"relative",width:"min(460px, calc(100vw - 32px))"});let s=document.createElement("button");s.type="button",s.dataset.vizblQrClose="",s.setAttribute("aria-label","Close QR code"),s.textContent="\xd7",Object.assign(s.style,{background:"none",border:"none",color:"#AEB1B7",cursor:"pointer",fontSize:"24px",position:"absolute",right:"20px",top:"20px"});let l=document.createElement("div");l.dataset.vizblQrCode="",l.style.margin="0 auto",l.style.width="fit-content";let c=document.createElement("p");c.textContent="Scan this QR code with your phone camera to view the object in Augmented Reality",Object.assign(c.style,{fontSize:"16px",fontWeight:"500",lineHeight:"24px",margin:"24px 0 0",textAlign:"center"});let d=document.createElement("p");d.textContent=r?"*Требуется устройство и браузер с поддержкой AR. Рекомендуем iOS 12 или новее с Safari либо Android 7.0 или новее с Chrome.":"*Requires an AR-compatible device and browser. We recommend iOS 12 or later with Safari, or Android 7.0 or later with Chrome.",Object.assign(d.style,{color:"#93979F",fontSize:"12px",lineHeight:"16px",margin:"12px 0 0",textAlign:"center"});let u=document.createElement("p");u.textContent=`Powered by ${r?"Arizo":"Vizbl"}`,Object.assign(u.style,{color:"#93979F",fontSize:"11px",letterSpacing:"1.5px",margin:"24px 0 4px",textAlign:"center",textTransform:"uppercase"});let g=document.createElement("a");g.href=r?"https://arizo.ru":"https://vizbl.com",g.style.display="block",g.style.textAlign="center";let h=document.createElement("img");return h.alt=`${r?"Arizo":"Vizbl"} logo`,h.src=`${i}/${r?"logoArizo.svg":"logo.svg"}`,h.height=20,h.width=r?76:60,g.appendChild(h),a.append(s,l,c,d,u,g),n.appendChild(a),n}(a);c.id=r;let d=c.querySelector("[data-vizbl-qr-close]"),u=Array.from(c.querySelectorAll("button, a[href]")),g=!1,h=e=>{if("Escape"===e.key){e.preventDefault(),s();return}if("Tab"!==e.key||0===u.length)return;let t=u[0],i=u.at(-1)??t;e.shiftKey&&(document.activeElement===t||!c.contains(document.activeElement))?(e.preventDefault(),i.focus()):e.shiftKey||document.activeElement!==i||(e.preventDefault(),t.focus())};i=s=()=>{g||(g=!0,document.removeEventListener("keydown",h),c.remove(),i===s&&(i=void 0),n?.focus({preventScroll:!0}))},d?.addEventListener("click",s),c.addEventListener("click",e=>{e.target===c&&s()}),document.body.appendChild(c),document.addEventListener("keydown",h),function(){let e="https://fonts.googleapis.com/css2?family=Inter&display=swap";if(Array.from(document.querySelectorAll('link[rel="stylesheet"]')).some(t=>t.href===e||t.getAttribute("href")===e))return;let t=document.createElement("link");t.rel="stylesheet",t.href=e,document.head.appendChild(t)}();try{let i=await function(e){let i=w();if(i)return Promise.resolve(i);if(t)return t;let{qrCodeScriptUrl:r}=e??o();return t=new Promise((e,i)=>{let o,n=document.createElement("script"),a=()=>{o();let r=w();r?e(r):(n.remove(),t=void 0,i(Error("QR code runtime did not expose QRCode")))},s=()=>{o(),n.remove(),t=void 0,i(Error("Failed to load QR code runtime"))};o=()=>{n.removeEventListener("load",a),n.removeEventListener("error",s)},n.addEventListener("load",a,{once:!0}),n.addEventListener("error",s,{once:!0}),n.src=r,n.async=!0,n.dataset.vizblQrScript="true",document.head.appendChild(n)})}(a);if(l!==f||!c.isConnected)return s(),s;let r=c.querySelector("[data-vizbl-qr-code]");return r&&new i(r,{correctLevel:i.CorrectLevel.L,height:148,text:e,width:148}),c.style.display="flex",d?.focus({preventScroll:!0}),s}catch(e){throw s(),e}}class b extends Error{code;constructor(e){super(e),this.code=e,this.name="WidgetRuntimeError"}}function y(e){return e.runtimeConfig??o()}async function E(e,t,i){try{return await (i.fetchImpl??i.runtimeConfig?.fetchImpl??o().fetchImpl)(e,{...t,signal:i.signal})}catch(e){if(e instanceof DOMException&&"AbortError"===e.name)throw e;throw new b("NETWORK_ERROR")}}async function A(e){try{let t=await e.json();return[t.code,t.error,t.message].flatMap(e=>Array.isArray(e)?e:[e]).filter(e=>"string"==typeof e).join(" ").toLowerCase()}catch{return""}}async function C(e,t){let i=await A(e);return new b(429===e.status?"RATE_LIMITED":e.status>=500?"API_UNAVAILABLE":404===e.status&&"object"===t?"OBJECT_NOT_FOUND":i.includes("domain")||i.includes("origin")?"DOMAIN_NOT_ALLOWED":i.includes("revoked")?"KEY_REVOKED":i.includes("expired")?"activation"===t?"KEY_EXPIRED":"SESSION_EXPIRED":i.includes("policy")||i.includes("not available for this object")?"POLICY_DENIED":401===e.status||403===e.status?"activation"===t?"INVALID_KEY":"SESSION_EXPIRED":"REQUEST_FAILED")}async function I(e){try{return await e.json()}catch{throw new b("INVALID_RESPONSE")}}function S(e){if(!e||"object"!=typeof e||"string"!=typeof e.token||!e.token.trim()||"string"!=typeof e.sid||!e.sid.trim()||"number"!=typeof e.expiresIn||!Number.isFinite(e.expiresIn)||e.expiresIn<=0)throw new b("INVALID_RESPONSE");return e}async function x(e,t={}){let{apiOrigin:i}=y(t),r=await E(`${i}/public/widget/activate-core`,{cache:"no-store",headers:{"x-api-key":e},method:"POST"},t);if(!r.ok)throw await C(r,"activation");let o=await I(r);if("string"!=typeof o.productType)throw new b("INVALID_RESPONSE");return{...S(o.widgetSession),productType:o.productType}}async function T(e,t,i={}){let{apiOrigin:r}=y(i),o=await E(`${r}/public/widget/token`,{body:JSON.stringify({token:t}),cache:"no-store",headers:{"Content-Type":"application/json","x-api-key":e},method:"POST"},i);if(!o.ok)throw await C(o,"token");return S(await I(o))}async function k(e,t,i={}){let{apiOrigin:r}=y(i),o=await E(`${r}/public/objects/by-tinuuid/${encodeURIComponent(e)}`,{cache:"no-store",headers:{"x-widget-session-token":t},method:"GET"},i);if(!o.ok)throw await C(o,"object");let n=await I(o);if(!n||"object"!=typeof n||Array.isArray(n))throw new b("INVALID_RESPONSE");return n}async function L(e,t,i,r={}){let{apiOrigin:o}=y(r),n=await E(`${o}/public/widget/events`,{body:JSON.stringify({event:e,...i?{objectId:i}:{},timestamp:new Date().toISOString()}),cache:"no-store",headers:{"Content-Type":"application/json","x-widget-session-token":t},method:"POST"},r);if(!n.ok)throw await C(n,"event");let a=await I(n);if(!a||"object"!=typeof a||Array.isArray(a)||"boolean"!=typeof a.ok)throw new b("INVALID_RESPONSE")}async function O(e,t,i){let r=i??o(),{fetchImpl:n,legacyApiOrigin:a}=r,s=await E(`${a}/obj/Fetch`,{body:JSON.stringify({tinuuid:e}),headers:{"Content-Type":"application/json"},method:"POST"},{fetchImpl:n,runtimeConfig:r,signal:t});if(!s.ok)throw await C(s,"object");let l=await I(s);if(!l||"object"!=typeof l||Array.isArray(l))throw new b("INVALID_RESPONSE");return l}async function z(e,t){let{fetchImpl:i,legacyApiOrigin:r}=t??o();await i(`${r}/obj/IncrViews`,{body:JSON.stringify({tinuuid:e}),headers:{"Content-Type":"application/json"},method:"POST"})}function R(e){try{let t=e?.();t instanceof Promise&&t.catch(()=>void 0)}catch{}}let N=m();function P(e){if(e?.aborted)throw new DOMException("Aborted","AbortError")}async function D(e,t={}){let i,r,o=N(e),n=e.getAttribute("data-native-link"),d=e.dataset.objectTinuuid?.trim(),m=e.dataset.objectHid?.trim()||void 0;if(!d)throw Error("Object ID is required");P(t.signal);let f=t.loadObject??((e,i)=>O(e,i,t.runtimeConfig)),w=t.object??await f(d,t.signal);if(P(t.signal),!o.isCurrent())return()=>void 0;let b=m?w.materials.find(e=>e.hid===m):w.materials[0];if(!b?.native?.glbUrl||!b.native.usdzUrl)throw Error("Native AR assets are unavailable");let y=u(b.native,w.type),E=s(),A=!1,C=0;e.querySelector("img")||((i=document.createElement("img")).alt="",i.hidden=!0,e.appendChild(i));let I=()=>t.trackView?t.trackView():z(d,t.runtimeConfig),S=i=>{i.preventDefault(),R(()=>t.onAction?.("widget_opened"));let n=++C;r?.(),r=void 0,v(p(d,m,!0,t.runtimeConfig),`vizbl-${d}`,e,t.runtimeConfig).then(e=>{n===C&&o.isCurrent()?r=e:e()}).catch(()=>void 0)},x=async e=>{let i;if(i=l().toLowerCase(),["firefox","edge","opera"].some(e=>i.includes(e))){if(e.preventDefault(),A)return;A=!0,R(()=>t.onAction?.("ar_launched"));try{await Promise.resolve(I()).catch(()=>void 0)}finally{A=!1,a()&&c()?h(d,t.runtimeConfig):g(y)}return}R(()=>t.onAction?.("ar_launched")),R(I),a()&&c()?(e.preventDefault(),h(d,t.runtimeConfig)):g(y)};return E?(e.dataset.nativeLink=y,e.addEventListener("click",x)):e.addEventListener("click",S),o.register(()=>{C+=1,e.removeEventListener("click",S),e.removeEventListener("click",x),r?.(),i?.remove(),null===n?e.removeAttribute("data-native-link"):e.setAttribute("data-native-link",n)})}var j=!1;if("u">typeof window){var _={get passive(){j=!0;return}};window.addEventListener("testPassive",null,_),window.removeEventListener("testPassive",null,_)}var M="u">typeof window&&window.navigator&&window.navigator.platform&&(/iP(ad|hone|od)/.test(window.navigator.platform)||"MacIntel"===window.navigator.platform&&window.navigator.maxTouchPoints>1),U=[],$=!1,V=-1,B=void 0,q=void 0,H=void 0,W=function(e){return U.some(function(t){return!!(t.options.allowTouchMove&&t.options.allowTouchMove(e))})},F=function(e){var t=e||window.event;return!!W(t.target)||t.touches.length>1||(t.preventDefault&&t.preventDefault(),!1)},Q=function(e){if(void 0===H){var t=!!e&&!0===e.reserveScrollBarGap,i=window.innerWidth-document.documentElement.clientWidth;if(t&&i>0){var r=parseInt(window.getComputedStyle(document.body).getPropertyValue("padding-right"),10);H=document.body.style.paddingRight,document.body.style.paddingRight=r+i+"px"}}void 0===B&&(B=document.body.style.overflow,document.body.style.overflow="hidden")},Y=function(){void 0!==H&&(document.body.style.paddingRight=H,H=void 0),void 0!==B&&(document.body.style.overflow=B,B=void 0)},K=function(){if(void 0!==q){var e=-parseInt(document.body.style.top,10),t=-parseInt(document.body.style.left,10);document.body.style.position=q.position,document.body.style.top=q.top,document.body.style.left=q.left,window.scrollTo(t,e),q=void 0}},X=function(e,t){var i=e.targetTouches[0].clientY-V;return!W(e.target)&&(t&&0===t.scrollTop&&i>0?F(e):t&&t.scrollHeight-t.scrollTop<=t.clientHeight&&i<0?F(e):(e.stopPropagation(),!0))},J=function(e,t){e?!U.some(function(t){return t.targetElement===e})&&(U=[].concat(function(e){if(!Array.isArray(e))return Array.from(e);for(var t=0,i=Array(e.length);t<e.length;t++)i[t]=e[t];return i}(U),[{targetElement:e,options:t||{}}]),M?window.requestAnimationFrame(function(){if(void 0===q){q={position:document.body.style.position,top:document.body.style.top,left:document.body.style.left};var e=window,t=e.scrollY,i=e.scrollX,r=e.innerHeight;document.body.style.position="fixed",document.body.style.top=-t,document.body.style.left=-i,setTimeout(function(){return window.requestAnimationFrame(function(){var e=r-window.innerHeight;e&&t>=r&&(document.body.style.top=-(t+e))})},300)}}):Q(t),M&&(e.ontouchstart=function(e){1===e.targetTouches.length&&(V=e.targetTouches[0].clientY)},e.ontouchmove=function(t){1===t.targetTouches.length&&X(t,e)},$||(document.addEventListener("touchmove",F,j?{passive:!1}:void 0),$=!0))):console.error("disableBodyScroll unsuccessful - targetElement must be provided when calling disableBodyScroll on IOS devices.")},G=function(e){e?(U=U.filter(function(t){return t.targetElement!==e}),M&&(e.ontouchstart=null,e.ontouchmove=null,$&&0===U.length&&(document.removeEventListener("touchmove",F,j?{passive:!1}:void 0),$=!1)),M?K():Y()):console.error("enableBodyScroll unsuccessful - targetElement must be provided when calling enableBodyScroll on IOS devices.")};let Z=["cm","inch"],ee="vizbl_viewer",et=m(),ei=m();function er(e){if(e?.aborted)throw new DOMException("Aborted","AbortError")}async function eo(e,t={}){let i,r,o=ei(e),n=e.getAttribute("href"),a=e.getAttribute("rel"),l=e.dataset.objectTinuuid?.trim(),c=e.dataset.objectHid?.trim()||void 0;if(!l)throw Error("Object ID is required");er(t.signal);let d=t.loadObject??((e,i)=>O(e,i,t.runtimeConfig)),g=t.object??await d(l,t.signal);if(er(t.signal),!o.isCurrent())return()=>void 0;let h=c?g.materials.find(e=>e.hid===c):g.materials[0];if(!h?.native?.glbUrl||!h.native.usdzUrl)throw Error("Native AR assets are unavailable");let m=u(h.native,g.type),f=s(),w=0;e.rel="ar",e.querySelector("img")||((i=document.createElement("img")).alt="",i.hidden=!0,e.appendChild(i));let b=i=>{i.preventDefault(),R(()=>t.onAction?.("widget_opened"));let n=++w;r?.(),r=void 0,v(p(l,c,!1,t.runtimeConfig),`vizbl-${l}`,e,t.runtimeConfig).then(e=>{n===w&&o.isCurrent()?r=e:e()}).catch(()=>void 0)},y=()=>{R(t.trackView??(()=>z(l,t.runtimeConfig))),R(()=>t.onAction?.("ar_launched"))};return f?(e.href=m,e.addEventListener("click",y)):(e.href="#",e.addEventListener("click",b)),o.register(()=>{w+=1,e.removeEventListener("click",b),e.removeEventListener("click",y),r?.(),i?.remove(),null===n?e.removeAttribute("href"):e.setAttribute("href",n),null===a?e.removeAttribute("rel"):e.setAttribute("rel",a)})}let en=["advanced-ar","ar-one-click","ar-viewer"],ea={arizo:"arizo-core",vizbl:"vizbl-core"},es=new Set(["core-ar","core-ar-shopify"]),el={"advanced-ar":"View in advanced AR","ar-one-click":"View in AR","ar-viewer":"View in 3D & AR"},ec=["api-key","dev","object-id","size-type","trigger-class","type","variant-id"],ed=new Set(["API_UNAVAILABLE","INVALID_RESPONSE","NETWORK_ERROR","REQUEST_FAILED","SESSION_EXPIRED"]),eu="core-ar-widget-styles";class eg extends Error{code;constructor(e){super(e),this.code=e,this.name="CoreArWidgetComponentError"}}function eh(e){return en.includes(e)}let ep="u"<typeof HTMLElement?class{}:HTMLElement;class em extends ep{static get observedAttributes(){return[...ec]}get triggerClass(){return this.getAttribute("trigger-class")??""}set triggerClass(e){let t="string"==typeof e?e.trim():"";t?this.setAttribute("trigger-class",t):this.removeAttribute("trigger-class")}get unstyled(){return this.hasAttribute("unstyled")}set unstyled(e){this.toggleAttribute("unstyled",!!e)}abortController;actionResetTimer;cleanup;customLabelNodes=null;initializationRevision=0;object;queued=!1;session;trigger;connectedCallback(){!function(){if(document.getElementById(eu))return;let e=document.createElement("style");e.id=eu,e.textContent=`
1
+ (()=>{"use strict";let e,t,i;function r(e,t){let i;try{i=new URL(e)}catch{throw TypeError(`${t} must be an absolute HTTP(S) URL`)}if("http:"!==i.protocol&&"https:"!==i.protocol)throw TypeError(`${t} must be an absolute HTTP(S) URL`);return i.origin}function n(){if(!e)throw Error("Core AR widget runtime is not configured");return e}function o(){return"u"<typeof navigator?"":navigator.userAgent||navigator.vendor||""}function a(){if("u"<typeof window||"u"<typeof navigator)return!1;let e="MacIntel"===navigator.platform&&navigator.maxTouchPoints>1;return(/iPad|iPhone|iPod/.test(o())||e)&&!("MSStream"in window)}function s(){if("u"<typeof window||"u"<typeof navigator)return!1;let e=navigator.maxTouchPoints>1,t=window.matchMedia?.("(pointer: coarse)").matches??!1,i=/Android|iPhone|iPad|iPod|webOS|BlackBerry|Windows Phone|Opera Mini|IEMobile|Mobile/i.test(o());return e&&t&&(i||a())}function l(){let e=o();return[[/edg/i,"Microsoft Edge"],[/trident/i,"Microsoft Internet Explorer"],[/firefox|fxios/i,"Mozilla Firefox"],[/opr\//i,"Opera"],[/ucbrowser/i,"UC Browser"],[/samsungbrowser/i,"Samsung Browser"],[/chrome|chromium|crios/i,"Google Chrome"],[/safari/i,"Apple Safari"]].find(([t])=>t.test(e))?.[1]??"Other"}function d(){let e=function(){let e=o(),t=e.match(/\bOS (\d+)/)?.[1]??e.match(/Version\/(\d+)/)?.[1];if(!t)return null;let i=Number.parseInt(t,10);return Number.isNaN(i)?null:i}();return null!==e&&e>=17}function c(e){let t;try{t=new URL(e)}catch{throw TypeError("Native AR asset URL must be absolute HTTP(S)")}if("http:"!==t.protocol&&"https:"!==t.protocol)throw TypeError("Native AR asset URL must be absolute HTTP(S)");return t.href}function u(e,t){let i=c(e.glbUrl),r=c(e.usdzUrl),n=encodeURIComponent(i),o=`intent://arvr.google.com/scene-viewer/1.0?file=${n}&resizable=false${"wall"===t||"ceiling"===t?"&enable_vertical_placement=true":""}&mode=ar_preferred#Intent;scheme=https;package=com.google.android.googlequicksearchbox;action=android.intent.action.VIEW;end;`,s=`${r}#allowsContentScaling=0`;return a()?s:o}function g(e,t=0){let i=document.createElement("a"),r=document.createElement("img");i.rel="ar",i.href=e,i.hidden=!0,r.alt="",r.hidden=!0,i.appendChild(r),document.body.appendChild(i),window.setTimeout(()=>{i.click(),i.remove()},t)}function h(e,t,i){let r=function(e,t,i){let{brand:r}=i??n();if(a()){let i=new URL("https://appclip.apple.com/id");return i.searchParams.set("p","com.us.vizbl.Clip"),i.searchParams.set("tinuuid",e),t&&i.searchParams.set("hid",t),i.searchParams.set("region","arizo"===r?"ru":"en"),i.toString()}return`intent:/${window.location.pathname}#Intent;scheme=open;package=com.us.vizbl;end`}(e,t,i);window.self===window.top||l().toLowerCase().includes("edge")?window.location.assign(r):window.open(r,"_top")}function m(e,t,i=!1,r){let{viewerOrigin:o}=r??n(),a=new URL("/ar/index.html",o);return a.searchParams.set("tinuuid",e),t&&a.searchParams.set("hid",t),i&&a.searchParams.set("appview","true"),a.toString()}function p(){let e=new WeakMap;return function(t){let i=e.get(t);i?.cleanup?.();let r={revision:(i?.revision??0)+1};return e.set(t,r),{isCurrent:()=>e.get(t)===r,register(i){let n=!1,o=()=>{n||(n=!0,i())};return e.get(t)!==r?(o(),o):(r.cleanup=o,()=>{e.get(t)===r&&e.delete(t),o()})}}}}let f=0,v={arizo:{conjunction:"и",privacyLabel:"Политика конфиденциальности",privacyUrl:"https://arizo.ru/privacy-policy/",termsLabel:"Условия использования",termsUrl:"https://arizo.ru/terms-of-use/"},vizbl:{conjunction:"and",privacyLabel:"Privacy Policy",privacyUrl:"https://vizbl.com/legal/privacy-policy",termsLabel:"Terms of Use",termsUrl:"https://vizbl.com/legal/terms-of-use"}};function w(){return window.QRCode}function b(e,t,i){let r=document.createElement("a");return r.dataset.vizblLegalLink=e,r.href=t,r.rel="noopener noreferrer",r.target="_blank",r.textContent=i,Object.assign(r.style,{color:"inherit",textDecoration:"underline",textUnderlineOffset:"2px",whiteSpace:"nowrap"}),r}async function y(e,r="vizblQrModal",o,a){let s,l=++f;i?.(),document.querySelectorAll("[data-vizbl-qr-modal]").forEach(e=>e.remove());let d=function(e){let{brand:t,viewerOrigin:i}=e??n(),r="arizo"===t,o=document.createElement("div");o.dataset.vizblQrModal="",o.setAttribute("aria-label","View object in augmented reality"),o.setAttribute("aria-modal","true"),o.setAttribute("role","dialog"),Object.assign(o.style,{alignItems:"center",backgroundColor:"rgba(0,0,0,0.25)",display:"none",height:"100%",justifyContent:"center",left:"0",position:"fixed",top:"0",width:"100%",zIndex:"9999"});let a=document.createElement("div");Object.assign(a.style,{backgroundColor:"#fff",borderRadius:"12px",boxSizing:"border-box",color:"#000",fontFamily:"Inter, sans-serif",minHeight:"372px",padding:"48px 52px 40px",position:"relative",width:"min(460px, calc(100vw - 32px))"});let s=document.createElement("button");s.type="button",s.dataset.vizblQrClose="",s.setAttribute("aria-label","Close QR code"),s.textContent="\xd7",Object.assign(s.style,{background:"none",border:"none",color:"#AEB1B7",cursor:"pointer",fontSize:"24px",position:"absolute",right:"20px",top:"20px"});let l=document.createElement("div");l.dataset.vizblQrCode="",l.style.margin="0 auto",l.style.width="fit-content";let d=document.createElement("p");d.textContent=r?"Отсканируйте этот QR-код камерой телефона, чтобы примерить объект в интерьере":"Scan this QR code with your phone camera to view the object in Augmented Reality",Object.assign(d.style,{fontSize:"16px",fontWeight:"500",lineHeight:"24px",margin:"24px 0 0",textAlign:"center"});let c=document.createElement("p");Object.assign(c.style,{color:"#93979F",fontSize:"12px",lineHeight:"16px",margin:"12px 0 0",textAlign:"center"});let u=v[t],g=b("terms",u.termsUrl,u.termsLabel),h=b("privacy",u.privacyUrl,u.privacyLabel);c.append(r?"*Требуется устройство и браузер с поддержкой AR. Рекомендуем iOS 12 или новее с Safari либо Android 7.0 или новее с Chrome.":"*Requires an AR-compatible device and browser. We recommend iOS 12 or later with Safari, or Android 7.0 or later with Chrome.",document.createElement("br"),g,` ${u.conjunction} `,h);let m=document.createElement("p");m.textContent=`Powered by ${r?"Arizo":"Vizbl"}`,Object.assign(m.style,{color:"#93979F",fontSize:"11px",letterSpacing:"1.5px",margin:"24px 0 4px",textAlign:"center",textTransform:"uppercase"});let p=document.createElement("a");p.dataset.vizblBrandLink="",p.href=r?"https://arizo.ru":"https://vizbl.com",p.style.display="block",p.style.textAlign="center";let f=document.createElement("img");return f.alt=`${r?"Arizo":"Vizbl"} logo`,f.src=`${i}/${r?"logoArizo.svg":"logo.svg"}`,f.height=20,f.width=r?76:60,p.appendChild(f),a.append(s,l,d,c,m,p),o.appendChild(a),o}(a);d.id=r;let c=d.querySelector("[data-vizbl-qr-close]"),u=Array.from(d.querySelectorAll("button, a[href]")),g=!1,h=e=>{if("Escape"===e.key){e.preventDefault(),s();return}if("Tab"!==e.key||0===u.length)return;let t=u[0],i=u.at(-1)??t;e.shiftKey&&(document.activeElement===t||!d.contains(document.activeElement))?(e.preventDefault(),i.focus()):e.shiftKey||document.activeElement!==i||(e.preventDefault(),t.focus())};i=s=()=>{g||(g=!0,document.removeEventListener("keydown",h),d.remove(),i===s&&(i=void 0),o?.focus({preventScroll:!0}))},c?.addEventListener("click",s),d.addEventListener("click",e=>{e.target===d&&s()}),document.body.appendChild(d),document.addEventListener("keydown",h),function(){let e="https://fonts.googleapis.com/css2?family=Inter&display=swap";if(Array.from(document.querySelectorAll('link[rel="stylesheet"]')).some(t=>t.href===e||t.getAttribute("href")===e))return;let t=document.createElement("link");t.rel="stylesheet",t.href=e,document.head.appendChild(t)}();try{let i=await function(e){let i=w();if(i)return Promise.resolve(i);if(t)return t;let{qrCodeScriptUrl:r}=e??n();return t=new Promise((e,i)=>{let n,o=document.createElement("script"),a=()=>{n();let r=w();r?e(r):(o.remove(),t=void 0,i(Error("QR code runtime did not expose QRCode")))},s=()=>{n(),o.remove(),t=void 0,i(Error("Failed to load QR code runtime"))};n=()=>{o.removeEventListener("load",a),o.removeEventListener("error",s)},o.addEventListener("load",a,{once:!0}),o.addEventListener("error",s,{once:!0}),o.src=r,o.async=!0,o.dataset.vizblQrScript="true",document.head.appendChild(o)})}(a);if(l!==f||!d.isConnected)return s(),s;let r=d.querySelector("[data-vizbl-qr-code]");return r&&new i(r,{correctLevel:i.CorrectLevel.L,height:148,text:e,width:148}),d.style.display="flex",c?.focus({preventScroll:!0}),s}catch(e){throw s(),e}}class E extends Error{code;constructor(e){super(e),this.code=e,this.name="WidgetRuntimeError"}}function A(e){return e.runtimeConfig??n()}function I(e,t,i={}){let r=new URL(t,e);for(let[e,t]of Object.entries(i))t&&r.searchParams.set(e,t);return r.toString()}async function C(e,t,i){try{return await (i.fetchImpl??i.runtimeConfig?.fetchImpl??n().fetchImpl)(e,{...t,signal:i.signal})}catch(e){if(e instanceof DOMException&&"AbortError"===e.name)throw e;throw new E("NETWORK_ERROR")}}async function S(e){try{let t=await e.json();return[t.code,t.error,t.message].flatMap(e=>Array.isArray(e)?e:[e]).filter(e=>"string"==typeof e).join(" ").toLowerCase()}catch{return""}}async function k(e,t){let i=await S(e);return new E(429===e.status?"RATE_LIMITED":e.status>=500?"API_UNAVAILABLE":404===e.status&&"object"===t?"OBJECT_NOT_FOUND":i.includes("domain")||i.includes("origin")?"DOMAIN_NOT_ALLOWED":i.includes("revoked")?"KEY_REVOKED":i.includes("expired")?"activation"===t?"KEY_EXPIRED":"SESSION_EXPIRED":i.includes("policy")||i.includes("not available for this object")?"POLICY_DENIED":401===e.status||403===e.status?"activation"===t?"INVALID_KEY":"SESSION_EXPIRED":"REQUEST_FAILED")}async function T(e){try{return await e.json()}catch{throw new E("INVALID_RESPONSE")}}function L(e){if(!e||"object"!=typeof e||"string"!=typeof e.token||!e.token.trim()||"string"!=typeof e.sid||!e.sid.trim()||"number"!=typeof e.expiresIn||!Number.isFinite(e.expiresIn)||e.expiresIn<=0)throw new E("INVALID_RESPONSE");return e}async function x(e,t={}){let{apiOrigin:i}=A(t),r=await C(I(i,"/public/widget/activate-core",{mode:t.mode}),{cache:"no-store",headers:{"x-api-key":e},method:"POST"},t);if(!r.ok)throw await k(r,"activation");let n=await T(r);if("string"!=typeof n.productType)throw new E("INVALID_RESPONSE");return{...L(n.widgetSession),productType:n.productType}}async function z(e,t,i={}){let{apiOrigin:r}=A(i),n=await C(`${r}/public/widget/token`,{body:JSON.stringify({token:t,...i.mode?{mode:i.mode}:{}}),cache:"no-store",headers:{"Content-Type":"application/json","x-api-key":e},method:"POST"},i);if(!n.ok)throw await k(n,"token");return L(await T(n))}async function O(e,t,i={}){let{apiOrigin:r}=A(i),n=await C(I(r,`/public/objects/by-tinuuid/${encodeURIComponent(e)}`,{variantId:i.variantId}),{cache:"no-store",headers:{"x-widget-session-token":t},method:"GET"},i);if(!n.ok)throw await k(n,"object");let o=await T(n);if(!o||"object"!=typeof o||Array.isArray(o))throw new E("INVALID_RESPONSE");return o}async function R(e,t,i,r={}){let{apiOrigin:n}=A(r),o=await C(`${n}/public/widget/events`,{body:JSON.stringify({event:e,...i?{objectId:i}:{},...r.variantId?{variantId:r.variantId}:{},timestamp:new Date().toISOString()}),cache:"no-store",headers:{"Content-Type":"application/json","x-widget-session-token":t},keepalive:!0,method:"POST"},r);if(!o.ok)throw await k(o,"event");let a=await T(o);if(!a||"object"!=typeof a||Array.isArray(a)||"boolean"!=typeof a.ok)throw new E("INVALID_RESPONSE")}async function N(e,t,i){let r=i??n(),{fetchImpl:o,legacyApiOrigin:a}=r,s=await C(`${a}/obj/Fetch`,{body:JSON.stringify({tinuuid:e}),headers:{"Content-Type":"application/json"},method:"POST"},{fetchImpl:o,runtimeConfig:r,signal:t});if(!s.ok)throw await k(s,"object");let l=await T(s);if(!l||"object"!=typeof l||Array.isArray(l))throw new E("INVALID_RESPONSE");return l}async function D(e,t){let{fetchImpl:i,legacyApiOrigin:r}=t??n();await i(`${r}/obj/IncrViews`,{body:JSON.stringify({tinuuid:e}),headers:{"Content-Type":"application/json"},method:"POST"})}function P(e){try{let t=e?.();t instanceof Promise&&t.catch(()=>void 0)}catch{}}let j=p();function _(e){if(e?.aborted)throw new DOMException("Aborted","AbortError")}async function U(e,t={}){let i,r,n=j(e),o=e.getAttribute("data-native-link"),c=e.dataset.objectTinuuid?.trim(),p=e.dataset.objectHid?.trim()||void 0;if(!c)throw Error("Object ID is required");_(t.signal);let f=t.loadObject??((e,i)=>N(e,i,t.runtimeConfig)),v=t.object??await f(c,t.signal);if(_(t.signal),!n.isCurrent())return()=>void 0;let w=p?v.materials.find(e=>e.hid===p):v.materials[0];if(!w?.native?.glbUrl||!w.native.usdzUrl)throw Error("Native AR assets are unavailable");let b=u(w.native,v.type),E=s(),A=!1,I=0;e.querySelector("img")||((i=document.createElement("img")).alt="",i.hidden=!0,e.appendChild(i));let C=()=>t.trackView?t.trackView():D(c,t.runtimeConfig),S=i=>{i.preventDefault();let o=++I;r?.(),r=void 0,Promise.resolve(t.getDesktopQrUrl?.()??m(c,p,!0,t.runtimeConfig)).then(i=>{if(o===I&&n.isCurrent())return P(()=>t.onAction?.("interacted")),y(i,`vizbl-${c}`,e,t.runtimeConfig)}).then(e=>{if(e){if(o!==I||!n.isCurrent())return void e();r=e}}).catch(()=>void 0)},k=async e=>{let i;if(i=l().toLowerCase(),["firefox","edge","opera"].some(e=>i.includes(e))){if(e.preventDefault(),A)return;A=!0,P(()=>t.onAction?.("ar_launched"));try{await Promise.resolve(C()).catch(()=>void 0)}finally{A=!1,a()&&d()?h(c,p,t.runtimeConfig):g(b)}return}P(()=>t.onAction?.("ar_launched")),P(C),a()&&d()?(e.preventDefault(),h(c,p,t.runtimeConfig)):g(b)};return E?(e.dataset.nativeLink=b,e.addEventListener("click",k)):e.addEventListener("click",S),n.register(()=>{I+=1,e.removeEventListener("click",S),e.removeEventListener("click",k),r?.(),i?.remove(),null===o?e.removeAttribute("data-native-link"):e.setAttribute("data-native-link",o)})}var V=!1;if("u">typeof window){var M={get passive(){V=!0;return}};window.addEventListener("testPassive",null,M),window.removeEventListener("testPassive",null,M)}var $="u">typeof window&&window.navigator&&window.navigator.platform&&(/iP(ad|hone|od)/.test(window.navigator.platform)||"MacIntel"===window.navigator.platform&&window.navigator.maxTouchPoints>1),B=[],q=!1,H=-1,W=void 0,F=void 0,K=void 0,Q=function(e){return B.some(function(t){return!!(t.options.allowTouchMove&&t.options.allowTouchMove(e))})},Y=function(e){var t=e||window.event;return!!Q(t.target)||t.touches.length>1||(t.preventDefault&&t.preventDefault(),!1)},X=function(e){if(void 0===K){var t=!!e&&!0===e.reserveScrollBarGap,i=window.innerWidth-document.documentElement.clientWidth;if(t&&i>0){var r=parseInt(window.getComputedStyle(document.body).getPropertyValue("padding-right"),10);K=document.body.style.paddingRight,document.body.style.paddingRight=r+i+"px"}}void 0===W&&(W=document.body.style.overflow,document.body.style.overflow="hidden")},J=function(){void 0!==K&&(document.body.style.paddingRight=K,K=void 0),void 0!==W&&(document.body.style.overflow=W,W=void 0)},Z=function(){if(void 0!==F){var e=-parseInt(document.body.style.top,10),t=-parseInt(document.body.style.left,10);document.body.style.position=F.position,document.body.style.top=F.top,document.body.style.left=F.left,window.scrollTo(t,e),F=void 0}},G=function(e,t){var i=e.targetTouches[0].clientY-H;return!Q(e.target)&&(t&&0===t.scrollTop&&i>0?Y(e):t&&t.scrollHeight-t.scrollTop<=t.clientHeight&&i<0?Y(e):(e.stopPropagation(),!0))},ee=function(e,t){e?!B.some(function(t){return t.targetElement===e})&&(B=[].concat(function(e){if(!Array.isArray(e))return Array.from(e);for(var t=0,i=Array(e.length);t<e.length;t++)i[t]=e[t];return i}(B),[{targetElement:e,options:t||{}}]),$?window.requestAnimationFrame(function(){if(void 0===F){F={position:document.body.style.position,top:document.body.style.top,left:document.body.style.left};var e=window,t=e.scrollY,i=e.scrollX,r=e.innerHeight;document.body.style.position="fixed",document.body.style.top=-t,document.body.style.left=-i,setTimeout(function(){return window.requestAnimationFrame(function(){var e=r-window.innerHeight;e&&t>=r&&(document.body.style.top=-(t+e))})},300)}}):X(t),$&&(e.ontouchstart=function(e){1===e.targetTouches.length&&(H=e.targetTouches[0].clientY)},e.ontouchmove=function(t){1===t.targetTouches.length&&G(t,e)},q||(document.addEventListener("touchmove",Y,V?{passive:!1}:void 0),q=!0))):console.error("disableBodyScroll unsuccessful - targetElement must be provided when calling disableBodyScroll on IOS devices.")},et=function(e){e?(B=B.filter(function(t){return t.targetElement!==e}),$&&(e.ontouchstart=null,e.ontouchmove=null,q&&0===B.length&&(document.removeEventListener("touchmove",Y,V?{passive:!1}:void 0),q=!1)),$?Z():J()):console.error("enableBodyScroll unsuccessful - targetElement must be provided when calling enableBodyScroll on IOS devices.")};let ei=["cm","inch"],er="vizbl_viewer",en=p();function eo(e){return e&&ei.includes(e)?e:"inch"}function ea(e){let t=new URL("/model-viewer",e.modelViewerOrigin??n().modelViewerOrigin);t.searchParams.set("tinuuid",e.tinuuid),e.hid&&t.searchParams.set("hid",e.hid),t.searchParams.set("size-type",e.sizeType);let i=new URLSearchParams;return e.apiKey&&i.set("api-key",e.apiKey),e.mode&&i.set("mode",e.mode),e.widgetSessionToken&&i.set("widget-session-token",e.widgetSessionToken),t.hash=i.toString(),t.toString()}let es=p();function el(e){if(e?.aborted)throw new DOMException("Aborted","AbortError")}async function ed(e,t={}){let i,r,n=es(e),o=e.getAttribute("href"),a=e.getAttribute("rel"),l=e.dataset.objectTinuuid?.trim(),d=e.dataset.objectHid?.trim()||void 0;if(!l)throw Error("Object ID is required");el(t.signal);let c=t.loadObject??((e,i)=>N(e,i,t.runtimeConfig)),g=t.object??await c(l,t.signal);if(el(t.signal),!n.isCurrent())return()=>void 0;let h=d?g.materials.find(e=>e.hid===d):g.materials[0];if(!h?.native?.glbUrl||!h.native.usdzUrl)throw Error("Native AR assets are unavailable");let p=u(h.native,g.type),f=s(),v=0;e.rel="ar",e.querySelector("img")||((i=document.createElement("img")).alt="",i.hidden=!0,e.appendChild(i));let w=i=>{i.preventDefault();let o=++v;r?.(),r=void 0,Promise.resolve(t.getDesktopQrUrl?.()??m(l,d,!1,t.runtimeConfig)).then(i=>{if(o===v&&n.isCurrent())return P(()=>t.onAction?.("interacted")),y(i,`vizbl-${l}`,e,t.runtimeConfig)}).then(e=>{if(e){if(o!==v||!n.isCurrent())return void e();r=e}}).catch(()=>void 0)},b=()=>{P(t.trackView??(()=>D(l,t.runtimeConfig))),P(()=>t.onAction?.("ar_launched"))};return f?(e.href=p,e.addEventListener("click",b)):(e.href="#",e.addEventListener("click",w)),n.register(()=>{v+=1,e.removeEventListener("click",w),e.removeEventListener("click",b),r?.(),i?.remove(),null===o?e.removeAttribute("href"):e.setAttribute("href",o),null===a?e.removeAttribute("rel"):e.setAttribute("rel",a)})}let ec=["advanced-ar","ar-one-click","ar-viewer"],eu={arizo:"arizo-core",vizbl:"vizbl-core"},eg=new Set(["core-ar","core-ar-shopify"]),eh={"advanced-ar":"View in advanced AR","ar-one-click":"View in AR","ar-viewer":"View in 3D & AR"},em={"advanced-ar":"advanced-ar-view","ar-one-click":"ar-view","ar-viewer":"ar-viewer"},ep=["api-key","dev","object-id","size-type","trigger-class","type","variant-id"],ef=new Set(["API_UNAVAILABLE","INVALID_RESPONSE","NETWORK_ERROR","REQUEST_FAILED","SESSION_EXPIRED"]),ev="core-ar-widget-styles";class ew extends Error{code;constructor(e){super(e),this.code=e,this.name="CoreArWidgetComponentError"}}function eb(e){return ec.includes(e)}function ey(e,t){let i=Array.isArray(e.materials)?e.materials:[],r=t?i.find(e=>e.hid===t):i[0];if(!r)throw new ew(t?"VARIANT_NOT_FOUND":"MODEL_UNAVAILABLE");return r}function eE(e,t){let i=t.policy;if(!("ar-one-click"===e?i?.instantArView!==!1:i?.appClip!==!1))throw new ew("POLICY_DENIED")}let eA="u"<typeof HTMLElement?class{}:HTMLElement;class eI extends eA{static get observedAttributes(){return[...ep]}get triggerClass(){return this.getAttribute("trigger-class")??""}set triggerClass(e){let t="string"==typeof e?e.trim():"";t?this.setAttribute("trigger-class",t):this.removeAttribute("trigger-class")}get unstyled(){return this.hasAttribute("unstyled")}set unstyled(e){this.toggleAttribute("unstyled",!!e)}abortController;actionResetTimer;cleanup;customLabelNodes=null;initializationRevision=0;object;queued=!1;session;trigger;variantId;widgetMode;connectedCallback(){!function(){if(document.getElementById(ev))return;let e=document.createElement("style");e.id=ev,e.textContent=`
2
2
  :where(vizbl-core, arizo-core) {
3
3
  display: inline-block;
4
4
  --core-ar-widget-background: #3556f0;
@@ -65,4 +65,4 @@
65
65
  :where(vizbl-core, arizo-core)[data-state="error"] [data-core-ar-widget-trigger] {
66
66
  cursor: not-allowed;
67
67
  }
68
- `,document.head.appendChild(e)}(),this.captureCustomLabel(),this.queueInitialization()}disconnectedCallback(){this.initializationRevision+=1,this.abortController?.abort(),this.abortController=void 0,this.cleanup?.(),this.cleanup=void 0,this.clearActionResetTimer()}attributeChangedCallback(e,t,i){if(t!==i){if("trigger-class"===e)return void this.applyTriggerClass();("api-key"===e||"dev"===e)&&(this.session=void 0),this.isConnected&&(this.abortController?.abort(),this.cleanup?.(),this.cleanup=void 0,this.setState("loading"),this.queueInitialization())}}captureCustomLabel(){if(null!==this.customLabelNodes)return;let e=Array.from(this.childNodes),t=e.some(e=>e.nodeType!==Node.TEXT_NODE||!!e.textContent?.trim());this.customLabelNodes=t?e:[]}queueInitialization(){this.queued||(this.queued=!0,queueMicrotask(()=>{this.queued=!1,this.isConnected&&this.initialize()}))}async initialize(){let e=++this.initializationRevision;this.abortController?.abort(),this.cleanup?.(),this.cleanup=void 0,this.clearActionResetTimer();let t=new AbortController;this.abortController=t;let i=this.getAttribute("type")?.trim()??"",r=eh(i)?i:"ar-viewer",o=this.getAttribute("object-id")?.trim()??"",n=this.getAttribute("variant-id")?.trim()||void 0,a=this.getAttribute("api-key")?.trim()??"",s=this.getAttribute("size-type")?.trim()||void 0;this.removeAttribute("data-error-code"),this.setState("loading"),this.renderTrigger(r);try{let r=this.resolveRuntimeConfig();if(!a)throw new eg("MISSING_API_KEY");if(!o)throw new eg("MISSING_OBJECT_ID");if(!eh(i))throw new eg("INVALID_TYPE");if("ar-viewer"===i&&s&&"cm"!==s&&"inch"!==s)throw new eg("INVALID_SIZE_TYPE");let l=await this.ensureSession(a,r,t.signal);this.assertCurrent(e,t.signal);let c=await this.fetchObjectWithSession(o,a,l,r,t.signal);this.assertCurrent(e,t.signal);let d=function(e,t){let i=Array.isArray(e.materials)?e.materials:[],r=t?i.find(e=>e.hid===t):i[0];if(!r)throw new eg(t?"VARIANT_NOT_FOUND":"MODEL_UNAVAILABLE");return r}(c,n),u=c.policy;if(!("ar-viewer"===i?u?.ignViewerModal!==!1:"ar-one-click"===i?u?.instantArView!==!1:u?.appClip!==!1))throw new eg("POLICY_DENIED");if("ar-viewer"!==i&&(!d.native?.glbUrl||!d.native.usdzUrl))throw new eg("MODEL_UNAVAILABLE");this.object=c,this.applyIntegrationData(o,n,s);let g=await this.initializeTrigger(i,c,r,t.signal);try{this.assertCurrent(e,t.signal)}catch(e){throw g(),e}this.cleanup=g,this.setState("ready"),this.dispatchWidgetEvent("core-ar-ready",{objectId:o,type:i})}catch(n){if(e!==this.initializationRevision||t.signal.aborted||n instanceof DOMException&&"AbortError"===n.name)return;let r=n instanceof eg||n instanceof b?n.code:"INITIALIZATION_FAILED";this.setAttribute("data-error-code",r),this.setState("error"),this.dispatchWidgetEvent("core-ar-error",{code:r,objectId:o,type:i})}}async ensureSession(e,t,i,r=!1){let o=`${t.apiOrigin}|${t.viewerOrigin}`,n=this.session?.publicKey===e&&this.session.runtimeKey===o?this.session:void 0;if(n&&!r&&n.expiresAt-Date.now()>3e4)return n;if(n)try{let r=await T(e,n.token,{runtimeConfig:t,signal:i}),o={...n,...r,expiresAt:Date.now()+1e3*r.expiresIn};return this.session=o,o}catch(e){if(!(e instanceof b)||!ed.has(e.code))throw e;this.session=void 0}let a=await x(e,{runtimeConfig:t,signal:i});if(!es.has(a.productType))throw new eg("POLICY_DENIED");let s={expiresAt:Date.now()+1e3*a.expiresIn,productType:a.productType,publicKey:e,runtimeKey:o,sid:a.sid,token:a.token};return this.session=s,s}async fetchObjectWithSession(e,t,i,r,o){try{return await k(e,i.token,{runtimeConfig:r,signal:o})}catch(i){if(!(i instanceof b)||"SESSION_EXPIRED"!==i.code)throw i;return k(e,(await this.ensureSession(t,r,o,!0)).token,{runtimeConfig:r,signal:o})}}assertCurrent(e,t){if(e!==this.initializationRevision||t.aborted)throw new DOMException("Aborted","AbortError")}renderTrigger(e){let t="ar-one-click"===e?document.createElement("a"):document.createElement("button");if(t.dataset.coreArWidgetTrigger="",t.setAttribute("part","trigger"),t.addEventListener("click",e=>{"ready"!==this.dataset.state&&(e.preventDefault(),e.stopImmediatePropagation())}),t instanceof HTMLButtonElement&&(t.type="button"),t instanceof HTMLAnchorElement&&(t.href="#",t.rel="ar"),"ar-viewer"===e&&t.setAttribute("aria-haspopup","dialog"),"ar-viewer"!==e){let e=document.createElement("img");e.alt="",e.hidden=!0,t.appendChild(e)}let i=document.createElement("span");i.dataset.coreArWidgetLabel="",this.customLabelNodes?.length?i.append(...this.customLabelNodes):i.textContent=el[e],t.appendChild(i),this.trigger=t,this.applyTriggerClass(),this.replaceChildren(t),this.updateTriggerAccessibility(this.dataset.state)}applyTriggerClass(){if(!this.trigger)return;let e=this.triggerClass.trim();e?this.trigger.className=e:this.trigger.removeAttribute("class")}applyIntegrationData(e,t,i){this.trigger&&(this.trigger.dataset.objectTinuuid=e,t?this.trigger.dataset.objectHid=t:delete this.trigger.dataset.objectHid,i?this.trigger.dataset.sizeType=i:delete this.trigger.dataset.sizeType)}async initializeTrigger(e,t,i,r){if(!this.trigger)throw new eg("INITIALIZATION_FAILED");if("ar-viewer"===e)return function(e,t={}){let i,r=et(e),n=()=>{var r;if(i)return;let n=e.dataset.objectTinuuid?.trim();if(!n)return;let a=function(e){var t,i,r,n;let a,s,l,c,d;if(document.getElementById(ee))return null;let u=document.createElement("div"),g=document.createElement("div"),h=document.createElement("div"),p=e.containerClassName?document.getElementsByClassName(e.containerClassName)[0]:null,m=!!p,f=m?g:u,w=!1,v=e=>{"Escape"===e.key&&a()};a=()=>{w||(w=!0,document.removeEventListener("keydown",v),G(f),(m?g:u).remove(),e.onClose?.(),e.restoreFocusTo?.focus({preventScroll:!0}))},u.id=ee,Object.assign(u.style,{inset:"0",overflow:"auto",position:"fixed",zIndex:"11111"}),u.style.webkitOverflowScrolling="touch",g.setAttribute("role","dialog"),g.setAttribute("aria-modal","true"),g.setAttribute("aria-label","3D model viewer"),Object.assign(h.style,{animation:"vex-fadein 0.5s",background:"#fff",inset:"0",position:"fixed",zIndex:"11111"}),h.addEventListener("click",a),(e.width||e.height)&&(h.style.background="rgba(0, 0, 0, 0.8)",Object.assign(g.style,{borderRadius:"12px",height:e.height??"100%",left:"50%",overflow:"hidden",position:"absolute",top:"50%",transform:"translate(-50%, -50%)",width:e.width??"100%",zIndex:"11112"}));let b=(t=e.crossClassName,i=a,(s=document.createElement("button")).type="button",s.setAttribute("aria-label","Close 3D model viewer"),t&&(s.className=t),Object.assign(s.style,{alignItems:"center",background:"#fff",border:"1px solid #E3E7E7",borderRadius:"4px",boxSizing:"border-box",cursor:"pointer",display:"flex",height:"40px",inset:"24px 24px auto auto",justifyContent:"center",padding:"8px 16px",position:"absolute",width:"56px",zIndex:"11113"}),s.innerHTML='<svg aria-hidden="true" style="flex-shrink:0" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12L19 6.41Z" fill="#484D50"/></svg>',s.addEventListener("click",i),s);return g.append((l=e.viewerOrigin??o().viewerOrigin,(c=new URL(e.hid?`${encodeURIComponent(e.tinuuid)}/${encodeURIComponent(e.hid)}`:encodeURIComponent(e.tinuuid),`${l.replace(/\/$/,"")}/`)).searchParams.set("hide-title",e.hideTitle??""),c.searchParams.set("hide-preview",e.hidePreview??""),c.searchParams.set("button-bg-color",e.buttonBgColor??""),c.searchParams.set("button-border-color",e.buttonBorderColor??""),c.searchParams.set("button-text-color",e.buttonTextColor??""),c.searchParams.set("background-color",e.backgroundColor??""),c.searchParams.set("size_type",e.sizeType),r=c.toString(),n=e.backgroundColor,(d=document.createElement("iframe")).src=r,d.title="3D model viewer",d.allow="fullscreen; xr-spatial-tracking",Object.assign(d.style,{backgroundColor:n??"white",border:"none",height:"100%",inset:"0",position:"absolute",width:"100%",zIndex:"11112"}),d),b),p?(g.id=ee,p.appendChild(g)):(u.append(h,g),document.body.appendChild(u)),document.addEventListener("keydown",v),J(f),b.focus({preventScroll:!0}),a}({backgroundColor:e.dataset.background,buttonBgColor:e.dataset.buttonBgColor,buttonBorderColor:e.dataset.buttonBorderColor,buttonTextColor:e.dataset.buttonTextColor,containerClassName:e.dataset.container,crossClassName:e.dataset.crossClassName,height:e.dataset.height?.trim(),hid:e.dataset.objectHid,hidePreview:e.dataset.hidePreview,hideTitle:e.dataset.hideTitle,onClose:()=>{i=void 0,t.onClose?.()},restoreFocusTo:e,sizeType:(r=e.dataset.sizeType)&&Z.includes(r)?r:"inch",tinuuid:n,viewerOrigin:t.viewerOrigin,width:e.dataset.width?.trim()});a&&(i=a,t.onOpen?.(),R(()=>t.onAction?.("widget_opened")))};return e.addEventListener("click",n),r.register(()=>{e.removeEventListener("click",n),i?.(),i=void 0})}(this.trigger,{onAction:e=>this.handleAction(e,i),onClose:()=>{this.isConnected&&this.setState("ready")},onOpen:()=>this.setState("opening"),viewerOrigin:i.viewerOrigin});let n={object:t,onAction:e=>this.handleAction(e,i),runtimeConfig:i,signal:r,trackView:()=>this.trackEvent("ar_launched",i)};if("ar-one-click"===e){if(!(this.trigger instanceof HTMLAnchorElement))throw new eg("INITIALIZATION_FAILED");return eo(this.trigger,n)}return D(this.trigger,n)}handleAction(e,t){this.setState("opening"),"widget_opened"===e&&this.trackEvent(e,t),"ar-viewer"!==this.getAttribute("type")&&(this.clearActionResetTimer(),this.actionResetTimer=window.setTimeout(()=>{this.isConnected&&this.setState("ready")},300))}async trackEvent(e,t){let i=this.getAttribute("api-key")?.trim();if(i&&this.isConnected)try{let r=await this.ensureSession(i,t);await L(e,r.token,this.object?.uuid,{runtimeConfig:t})}catch{}}clearActionResetTimer(){void 0!==this.actionResetTimer&&(window.clearTimeout(this.actionResetTimer),this.actionResetTimer=void 0)}setState(e){this.dataset.state=e,this.updateTriggerAccessibility(e)}updateTriggerAccessibility(e){if(!this.trigger)return;let t="ready"===e;this.trigger.setAttribute("aria-busy",String("loading"===e)),this.trigger.setAttribute("aria-disabled",String(!t)),this.trigger.tabIndex=t?0:-1,this.trigger instanceof HTMLButtonElement&&(this.trigger.disabled=!t)}dispatchWidgetEvent(e,t){this.dispatchEvent(new CustomEvent(e,{bubbles:!0,composed:!0,detail:t}))}}function ef(e){if("u"<typeof customElements)return;let t=ea[e],i=customElements.get(t);if(i)return i;class o extends em{resolveRuntimeConfig(){return function(e,t="prod"){var i,o;let n,a,s,l,c,d="arizo"===e?"arizo.ru":"vizbl.com",u="dev"===t?"-dev":"";return n=r((i={apiOrigin:`https://api${u}.${d}`,viewerOrigin:`https://viewer${u}.${d}`}).apiOrigin,"apiOrigin"),a=r(i.viewerOrigin,"viewerOrigin"),c=i.legacyApiOrigin?(s=r(o=i.legacyApiOrigin,"legacyApiOrigin"),(l=new URL(o).pathname.replace(/\/+$/,""))?`${s}${l}`:s):`${n}/v1`,{apiOrigin:n,brand:new URL(a).hostname.endsWith("arizo.ru")?"arizo":"vizbl",fetchImpl:i.fetchImpl??fetch,legacyApiOrigin:c,qrCodeScriptUrl:i.qrCodeScriptUrl??`${a}/vendor/qrcode.min.js`,viewerOrigin:a}}(e,this.hasAttribute("dev")?"dev":"prod")}}return customElements.define(t,o),o}ef("arizo"),ef("vizbl")})();
68
+ `,document.head.appendChild(e)}(),this.captureCustomLabel(),this.queueInitialization()}disconnectedCallback(){this.initializationRevision+=1,this.abortController?.abort(),this.abortController=void 0,this.cleanup?.(),this.cleanup=void 0,this.clearActionResetTimer()}attributeChangedCallback(e,t,i){if(t!==i){if("trigger-class"===e)return void this.applyTriggerClass();("api-key"===e||"dev"===e)&&(this.session=void 0),this.isConnected&&(this.abortController?.abort(),this.cleanup?.(),this.cleanup=void 0,this.setState("loading"),this.queueInitialization())}}captureCustomLabel(){if(null!==this.customLabelNodes)return;let e=Array.from(this.childNodes),t=e.some(e=>e.nodeType!==Node.TEXT_NODE||!!e.textContent?.trim());this.customLabelNodes=t?e:[]}queueInitialization(){this.queued||(this.queued=!0,queueMicrotask(()=>{this.queued=!1,this.isConnected&&this.initialize()}))}async initialize(){let e=++this.initializationRevision;this.abortController?.abort(),this.cleanup?.(),this.cleanup=void 0,this.object=void 0,this.variantId=void 0,this.widgetMode=void 0,this.clearActionResetTimer();let t=new AbortController;this.abortController=t;let i=this.getAttribute("type")?.trim()??"",r=eb(i)?i:"ar-viewer",n=this.getAttribute("object-id")?.trim()??"",o=this.getAttribute("variant-id")?.trim()||void 0,a=this.getAttribute("api-key")?.trim()??"",l=this.getAttribute("size-type")?.trim()||void 0;this.removeAttribute("data-error-code"),this.setState("loading"),this.renderTrigger(r);try{let r,d=this.resolveRuntimeConfig();if(!a)throw new ew("MISSING_API_KEY");if(!n)throw new ew("MISSING_OBJECT_ID");if(!eb(i))throw new ew("INVALID_TYPE");if("ar-viewer"===i&&l&&"cm"!==l&&"inch"!==l)throw new ew("INVALID_SIZE_TYPE");let c=em[i],u=await this.ensureSession(a,d,c,t.signal);if(this.assertCurrent(e,t.signal),this.variantId=o,this.widgetMode=c,this.applyIntegrationData(n,o,l),"ar-viewer"===i)r=await N(n,t.signal,d),this.assertCurrent(e,t.signal),ey(r,o),eE(i,r),this.object=r;else{r=s()?await this.fetchObjectWithSession(n,a,u,d,t.signal,o):await N(n,t.signal,d),this.assertCurrent(e,t.signal);let l=ey(r,o);if(eE(i,r),!l.native?.glbUrl||!l.native.usdzUrl)throw new ew("MODEL_UNAVAILABLE");this.object=r}let g=await this.initializeTrigger(i,r,d,t.signal,a,u);try{this.assertCurrent(e,t.signal)}catch(e){throw g(),e}this.cleanup=g,this.setState("ready"),this.dispatchWidgetEvent("core-ar-ready",{objectId:n,type:i})}catch(o){if(e!==this.initializationRevision||t.signal.aborted||o instanceof DOMException&&"AbortError"===o.name)return;let r=o instanceof ew||o instanceof E?o.code:"INITIALIZATION_FAILED";this.setAttribute("data-error-code",r),this.setState("error"),this.dispatchWidgetEvent("core-ar-error",{code:r,objectId:n,type:i})}}async ensureSession(e,t,i,r,n=!1){let o=`${t.apiOrigin}|${t.viewerOrigin}|${t.modelViewerOrigin}|${i}`,a=this.session?.publicKey===e&&this.session.runtimeKey===o?this.session:void 0;if(a&&!n&&a.expiresAt-Date.now()>3e4)return a;if(a)try{let i=await z(e,a.token,{mode:a.mode,runtimeConfig:t,signal:r}),n={...a,...i,expiresAt:Date.now()+1e3*i.expiresIn};return this.session=n,n}catch(e){if(!(e instanceof E)||!ef.has(e.code))throw e;this.session=void 0}let s=await x(e,{mode:i,runtimeConfig:t,signal:r});if(!eg.has(s.productType))throw new ew("POLICY_DENIED");let l={expiresAt:Date.now()+1e3*s.expiresIn,mode:i,productType:s.productType,publicKey:e,runtimeKey:o,sid:s.sid,token:s.token};return this.session=l,l}async fetchObjectWithSession(e,t,i,r,n,o){try{return await O(e,i.token,{runtimeConfig:r,signal:n,variantId:o})}catch(a){if(!(a instanceof E)||"SESSION_EXPIRED"!==a.code)throw a;return O(e,(await this.ensureSession(t,r,i.mode,n,!0)).token,{runtimeConfig:r,signal:n,variantId:o})}}assertCurrent(e,t){if(e!==this.initializationRevision||t.aborted)throw new DOMException("Aborted","AbortError")}renderTrigger(e){let t="ar-one-click"===e?document.createElement("a"):document.createElement("button");if(t.dataset.coreArWidgetTrigger="",t.setAttribute("part","trigger"),t.addEventListener("click",e=>{"ready"!==this.dataset.state&&(e.preventDefault(),e.stopImmediatePropagation())}),t instanceof HTMLButtonElement&&(t.type="button"),t instanceof HTMLAnchorElement&&(t.href="#",t.rel="ar"),"ar-viewer"===e&&t.setAttribute("aria-haspopup","dialog"),"ar-viewer"!==e){let e=document.createElement("img");e.alt="",e.hidden=!0,t.appendChild(e)}let i=document.createElement("span");i.dataset.coreArWidgetLabel="",this.customLabelNodes?.length?i.append(...this.customLabelNodes):i.textContent=eh[e],t.appendChild(i),this.trigger=t,this.applyTriggerClass(),this.replaceChildren(t),this.updateTriggerAccessibility(this.dataset.state)}applyTriggerClass(){if(!this.trigger)return;let e=this.triggerClass.trim();e?this.trigger.className=e:this.trigger.removeAttribute("class")}applyIntegrationData(e,t,i){this.trigger&&(this.trigger.dataset.objectTinuuid=e,t?this.trigger.dataset.objectHid=t:delete this.trigger.dataset.objectHid,i?this.trigger.dataset.sizeType=i:delete this.trigger.dataset.sizeType)}async initializeTrigger(e,t,i,r,n,o){if(!this.trigger)throw new ew("INITIALIZATION_FAILED");if("ar-viewer"===e)return function(e,t={}){let i,r=en(e),n=!1,o=async()=>{if(i||n)return;let o=e.dataset.objectTinuuid?.trim();if(!o)return;n=!0;let a=t.widgetSessionToken;try{t.getWidgetSessionToken&&(a=await t.getWidgetSessionToken())}catch{n=!1;return}if(n=!1,i||!r.isCurrent())return;let s=function(e){var t,i,r,n;let o,a,s;if(document.getElementById(er))return null;let l=document.createElement("div"),d=document.createElement("div"),c=document.createElement("div"),u=e.containerClassName?document.getElementsByClassName(e.containerClassName)[0]:null,g=!!u,h=g?d:l,m=!1,p=e=>{"Escape"===e.key&&o()};o=()=>{m||(m=!0,document.removeEventListener("keydown",p),et(h),(g?d:l).remove(),e.onClose?.(),e.restoreFocusTo?.focus({preventScroll:!0}))},l.id=er,Object.assign(l.style,{inset:"0",overflow:"auto",position:"fixed",zIndex:"11111"}),l.style.webkitOverflowScrolling="touch",d.setAttribute("role","dialog"),d.setAttribute("aria-modal","true"),d.setAttribute("aria-label","3D model viewer"),Object.assign(c.style,{animation:"vex-fadein 0.5s",background:"#fff",inset:"0",position:"fixed",zIndex:"11111"}),c.addEventListener("click",o),(e.width||e.height)&&(c.style.background="rgba(0, 0, 0, 0.8)",Object.assign(d.style,{borderRadius:"12px",height:e.height??"100%",left:"50%",overflow:"hidden",position:"absolute",top:"50%",transform:"translate(-50%, -50%)",width:e.width??"100%",zIndex:"11112"}));let f=(t=e.crossClassName,i=o,(a=document.createElement("button")).type="button",a.setAttribute("aria-label","Close 3D model viewer"),t&&(a.className=t),Object.assign(a.style,{alignItems:"center",background:"#fff",border:"1px solid #E3E7E7",borderRadius:"4px",boxSizing:"border-box",cursor:"pointer",display:"flex",height:"40px",inset:"24px 24px auto auto",justifyContent:"center",padding:"8px 16px",position:"absolute",width:"56px",zIndex:"11113"}),a.innerHTML='<svg aria-hidden="true" style="flex-shrink:0" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12L19 6.41Z" fill="#484D50"/></svg>',a.addEventListener("click",i),a);return d.append((r=ea(e),n=e.backgroundColor,(s=document.createElement("iframe")).src=r,s.title="3D model viewer",s.allow="fullscreen; xr-spatial-tracking",Object.assign(s.style,{backgroundColor:n??"white",border:"none",height:"100%",inset:"0",position:"absolute",width:"100%",zIndex:"11112"}),s),f),u?(d.id=er,u.appendChild(d)):(l.append(c,d),document.body.appendChild(l)),document.addEventListener("keydown",p),ee(h),f.focus({preventScroll:!0}),o}({apiKey:t.apiKey,backgroundColor:e.dataset.background,buttonBgColor:e.dataset.buttonBgColor,buttonBorderColor:e.dataset.buttonBorderColor,buttonTextColor:e.dataset.buttonTextColor,containerClassName:e.dataset.container,crossClassName:e.dataset.crossClassName,height:e.dataset.height?.trim(),hid:e.dataset.objectHid,hidePreview:e.dataset.hidePreview,hideTitle:e.dataset.hideTitle,mode:t.mode,modelViewerOrigin:t.modelViewerOrigin,onClose:()=>{i=void 0,t.onClose?.()},restoreFocusTo:e,sizeType:eo(e.dataset.sizeType),tinuuid:o,widgetSessionToken:a,width:e.dataset.width?.trim()});s&&(i=s,t.onOpen?.(),P(()=>t.onAction?.("widget_opened")))};return e.addEventListener("click",o),r.register(()=>{e.removeEventListener("click",o),i?.(),i=void 0})}(this.trigger,{apiKey:n,getWidgetSessionToken:async()=>(await this.ensureSession(n,i,o.mode)).token,mode:o.mode,modelViewerOrigin:i.modelViewerOrigin,onAction:e=>this.handleAction(e,i),onClose:()=>{this.isConnected&&this.setState("ready")},onOpen:()=>this.setState("opening"),widgetSessionToken:o.token});if(!t)throw new ew("INITIALIZATION_FAILED");let a={getDesktopQrUrl:async()=>{let e=await this.ensureSession(n,i,o.mode);return ea({apiKey:n,hid:this.variantId,mode:e.mode,modelViewerOrigin:i.modelViewerOrigin,sizeType:eo(this.trigger?.dataset.sizeType),tinuuid:this.trigger?.dataset.objectTinuuid??"",widgetSessionToken:e.token})},object:t,onAction:e=>this.handleAction(e,i),runtimeConfig:i,signal:r,trackView:()=>this.trackEvent("ar_launched",i)};if("ar-one-click"===e){if(!(this.trigger instanceof HTMLAnchorElement))throw new ew("INITIALIZATION_FAILED");return ed(this.trigger,a)}return U(this.trigger,a)}handleAction(e,t){this.setState("opening"),("interacted"===e||"widget_opened"===e)&&"ar-viewer"!==this.getAttribute("type")&&this.trackEvent(e,t),"ar-viewer"!==this.getAttribute("type")&&(this.clearActionResetTimer(),this.actionResetTimer=window.setTimeout(()=>{this.isConnected&&this.setState("ready")},300))}async trackEvent(e,t){let i=this.getAttribute("api-key")?.trim(),r=this.widgetMode;if(i&&r&&this.isConnected)try{let n=await this.ensureSession(i,t,r);await R(e,n.token,this.object?.uuid,{runtimeConfig:t,variantId:this.variantId})}catch{}}clearActionResetTimer(){void 0!==this.actionResetTimer&&(window.clearTimeout(this.actionResetTimer),this.actionResetTimer=void 0)}setState(e){this.dataset.state=e,this.updateTriggerAccessibility(e)}updateTriggerAccessibility(e){if(!this.trigger)return;let t="ready"===e;this.trigger.setAttribute("aria-busy",String("loading"===e)),this.trigger.setAttribute("aria-disabled",String(!t)),this.trigger.tabIndex=t?0:-1,this.trigger instanceof HTMLButtonElement&&(this.trigger.disabled=!t)}dispatchWidgetEvent(e,t){this.dispatchEvent(new CustomEvent(e,{bubbles:!0,composed:!0,detail:t}))}}function eC(e){if("u"<typeof customElements)return;let t=eu[e],i=customElements.get(t);if(i)return i;class n extends eI{resolveRuntimeConfig(){return function(e,t="prod"){var i,n;let o,a,s,l,d,c,u,g,h="arizo"===e?"arizo.ru":"vizbl.com",m="dev"===t?"-dev":"";return o=r((i={apiOrigin:`https://api${m}.${h}`,modelViewerOrigin:`https://integrations${m}.${h}`,viewerOrigin:`https://viewer${m}.${h}`}).apiOrigin,"apiOrigin"),a=r(i.viewerOrigin,"viewerOrigin"),d=i.modelViewerOrigin?r(i.modelViewerOrigin,"modelViewerOrigin"):(l=(s=new URL(a)).hostname.match(/^viewer(-dev)?\.(vizbl\.com|arizo\.ru)$/))?`${s.protocol}//integrations${l[1]??""}.${l[2]}`:a,g=i.legacyApiOrigin?(c=r(n=i.legacyApiOrigin,"legacyApiOrigin"),(u=new URL(n).pathname.replace(/\/+$/,""))?`${c}${u}`:c):`${o}/v1`,{apiOrigin:o,brand:new URL(a).hostname.endsWith("arizo.ru")?"arizo":"vizbl",fetchImpl:i.fetchImpl??fetch,legacyApiOrigin:g,modelViewerOrigin:d,qrCodeScriptUrl:i.qrCodeScriptUrl??`${a}/vendor/qrcode.min.js`,viewerOrigin:a}}(e,this.hasAttribute("dev")?"dev":"prod")}}return customElements.define(t,n),n}eC("arizo"),eC("vizbl")})();
package/dist/index.js CHANGED
@@ -15,9 +15,16 @@ function normalizeHttpBaseUrl(value, name) {
15
15
  const pathname = new URL(value).pathname.replace(/\/+$/, '');
16
16
  return pathname ? `${origin}${pathname}` : origin;
17
17
  }
18
+ function deriveModelViewerOrigin(viewerOrigin) {
19
+ const url = new URL(viewerOrigin);
20
+ const match = url.hostname.match(/^viewer(-dev)?\.(vizbl\.com|arizo\.ru)$/);
21
+ if (!match) return viewerOrigin;
22
+ return `${url.protocol}//integrations${match[1] ?? ''}.${match[2]}`;
23
+ }
18
24
  function resolveCoreArWidgetRuntimeConfig(config) {
19
25
  const apiOrigin = normalizeHttpOrigin(config.apiOrigin, 'apiOrigin');
20
26
  const viewerOrigin = normalizeHttpOrigin(config.viewerOrigin, 'viewerOrigin');
27
+ const modelViewerOrigin = config.modelViewerOrigin ? normalizeHttpOrigin(config.modelViewerOrigin, 'modelViewerOrigin') : deriveModelViewerOrigin(viewerOrigin);
21
28
  const legacyApiOrigin = config.legacyApiOrigin ? normalizeHttpBaseUrl(config.legacyApiOrigin, 'legacyApiOrigin') : `${apiOrigin}/v1`;
22
29
  const brand = new URL(viewerOrigin).hostname.endsWith('arizo.ru') ? 'arizo' : 'vizbl';
23
30
  return {
@@ -25,6 +32,7 @@ function resolveCoreArWidgetRuntimeConfig(config) {
25
32
  brand,
26
33
  fetchImpl: config.fetchImpl ?? fetch,
27
34
  legacyApiOrigin,
35
+ modelViewerOrigin,
28
36
  qrCodeScriptUrl: config.qrCodeScriptUrl ?? `${viewerOrigin}/vendor/qrcode.min.js`,
29
37
  viewerOrigin
30
38
  };
@@ -34,6 +42,7 @@ function createCoreArWidgetTenantConfig(brand, environment = 'prod') {
34
42
  const environmentSuffix = 'dev' === environment ? '-dev' : '';
35
43
  return resolveCoreArWidgetRuntimeConfig({
36
44
  apiOrigin: `https://api${environmentSuffix}.${domain}`,
45
+ modelViewerOrigin: `https://integrations${environmentSuffix}.${domain}`,
37
46
  viewerOrigin: `https://viewer${environmentSuffix}.${domain}`
38
47
  });
39
48
  }
@@ -148,19 +157,20 @@ function openNativeLink(nativeLink, delay = 0) {
148
157
  link.remove();
149
158
  }, delay);
150
159
  }
151
- function getAppViewLink(tinuuid, runtimeConfig) {
160
+ function getAppViewLink(tinuuid, variantId, runtimeConfig) {
152
161
  const { brand } = runtimeConfig ?? getCoreArWidgetRuntimeConfig();
153
162
  if (isIOS()) {
154
163
  const url = new URL('https://appclip.apple.com/id');
155
164
  url.searchParams.set('p', 'com.us.vizbl.Clip');
156
165
  url.searchParams.set('tinuuid', tinuuid);
166
+ if (variantId) url.searchParams.set('hid', variantId);
157
167
  url.searchParams.set('region', 'arizo' === brand ? 'ru' : 'en');
158
168
  return url.toString();
159
169
  }
160
170
  return `intent:/${window.location.pathname}#Intent;scheme=open;package=com.us.vizbl;end`;
161
171
  }
162
- function openAppViewLink(tinuuid, runtimeConfig) {
163
- const href = getAppViewLink(tinuuid, runtimeConfig);
172
+ function openAppViewLink(tinuuid, variantId, runtimeConfig) {
173
+ const href = getAppViewLink(tinuuid, variantId, runtimeConfig);
164
174
  const isIframe = window.self !== window.top;
165
175
  if (!isIframe) return void window.location.assign(href);
166
176
  if (getBrowserName().toLowerCase().includes('edge')) window.location.assign(href);
@@ -208,6 +218,22 @@ function createElementInitializerRegistry() {
208
218
  let qrCodeScriptPromise;
209
219
  let qrModalRevision = 0;
210
220
  let closeActiveQrModal;
221
+ const LEGAL_LINKS = {
222
+ arizo: {
223
+ conjunction: 'и',
224
+ privacyLabel: 'Политика конфиденциальности',
225
+ privacyUrl: 'https://arizo.ru/privacy-policy/',
226
+ termsLabel: 'Условия использования',
227
+ termsUrl: 'https://arizo.ru/terms-of-use/'
228
+ },
229
+ vizbl: {
230
+ conjunction: 'and',
231
+ privacyLabel: 'Privacy Policy',
232
+ privacyUrl: 'https://vizbl.com/legal/privacy-policy',
233
+ termsLabel: 'Terms of Use',
234
+ termsUrl: 'https://vizbl.com/legal/terms-of-use'
235
+ }
236
+ };
211
237
  function getQRCodeConstructor() {
212
238
  return window.QRCode;
213
239
  }
@@ -259,6 +285,21 @@ function ensureInterFont() {
259
285
  link.href = href;
260
286
  document.head.appendChild(link);
261
287
  }
288
+ function createLegalLink(kind, href, label) {
289
+ const link = document.createElement('a');
290
+ link.dataset.vizblLegalLink = kind;
291
+ link.href = href;
292
+ link.rel = 'noopener noreferrer';
293
+ link.target = '_blank';
294
+ link.textContent = label;
295
+ Object.assign(link.style, {
296
+ color: 'inherit',
297
+ textDecoration: 'underline',
298
+ textUnderlineOffset: '2px',
299
+ whiteSpace: 'nowrap'
300
+ });
301
+ return link;
302
+ }
262
303
  function createModal(runtimeConfig) {
263
304
  const { brand, viewerOrigin } = runtimeConfig ?? getCoreArWidgetRuntimeConfig();
264
305
  const isArizo = 'arizo' === brand;
@@ -311,7 +352,7 @@ function createModal(runtimeConfig) {
311
352
  qr.style.margin = '0 auto';
312
353
  qr.style.width = 'fit-content';
313
354
  const instructions = document.createElement('p');
314
- instructions.textContent = 'Scan this QR code with your phone camera to view the object in Augmented Reality';
355
+ instructions.textContent = isArizo ? 'Отсканируйте этот QR-код камерой телефона, чтобы примерить объект в интерьере' : 'Scan this QR code with your phone camera to view the object in Augmented Reality';
315
356
  Object.assign(instructions.style, {
316
357
  fontSize: '16px',
317
358
  fontWeight: '500',
@@ -319,8 +360,8 @@ function createModal(runtimeConfig) {
319
360
  margin: '24px 0 0',
320
361
  textAlign: 'center'
321
362
  });
363
+ const disclaimerText = isArizo ? '*Требуется устройство и браузер с поддержкой AR. Рекомендуем iOS 12 или новее с Safari либо Android 7.0 или новее с Chrome.' : '*Requires an AR-compatible device and browser. We recommend iOS 12 or later with Safari, or Android 7.0 or later with Chrome.';
322
364
  const disclaimer = document.createElement('p');
323
- disclaimer.textContent = isArizo ? '*Требуется устройство и браузер с поддержкой AR. Рекомендуем iOS 12 или новее с Safari либо Android 7.0 или новее с Chrome.' : '*Requires an AR-compatible device and browser. We recommend iOS 12 or later with Safari, or Android 7.0 or later with Chrome.';
324
365
  Object.assign(disclaimer.style, {
325
366
  color: '#93979F',
326
367
  fontSize: '12px',
@@ -328,6 +369,10 @@ function createModal(runtimeConfig) {
328
369
  margin: '12px 0 0',
329
370
  textAlign: 'center'
330
371
  });
372
+ const legalLinks = LEGAL_LINKS[brand];
373
+ const termsLink = createLegalLink('terms', legalLinks.termsUrl, legalLinks.termsLabel);
374
+ const privacyLink = createLegalLink('privacy', legalLinks.privacyUrl, legalLinks.privacyLabel);
375
+ disclaimer.append(disclaimerText, document.createElement('br'), termsLink, ` ${legalLinks.conjunction} `, privacyLink);
331
376
  const poweredBy = document.createElement('p');
332
377
  poweredBy.textContent = `Powered by ${isArizo ? 'Arizo' : 'Vizbl'}`;
333
378
  Object.assign(poweredBy.style, {
@@ -339,6 +384,7 @@ function createModal(runtimeConfig) {
339
384
  textTransform: 'uppercase'
340
385
  });
341
386
  const brandLink = document.createElement('a');
387
+ brandLink.dataset.vizblBrandLink = '';
342
388
  brandLink.href = isArizo ? 'https://arizo.ru' : 'https://vizbl.com';
343
389
  brandLink.style.display = 'block';
344
390
  brandLink.style.textAlign = 'center';
@@ -433,6 +479,11 @@ function getFetch(options) {
433
479
  function getRuntimeConfig(options) {
434
480
  return options.runtimeConfig ?? getCoreArWidgetRuntimeConfig();
435
481
  }
482
+ function getRuntimeUrl(apiOrigin, pathname, params = {}) {
483
+ const url = new URL(pathname, apiOrigin);
484
+ for (const [name, value] of Object.entries(params))if (value) url.searchParams.set(name, value);
485
+ return url.toString();
486
+ }
436
487
  async function runtimeFetch(input, init, options) {
437
488
  try {
438
489
  return await getFetch(options)(input, {
@@ -484,7 +535,9 @@ function parseWidgetSession(value) {
484
535
  }
485
536
  async function activateCoreWidget(publicKey, options = {}) {
486
537
  const { apiOrigin } = getRuntimeConfig(options);
487
- const response = await runtimeFetch(`${apiOrigin}/public/widget/activate-core`, {
538
+ const response = await runtimeFetch(getRuntimeUrl(apiOrigin, '/public/widget/activate-core', {
539
+ mode: options.mode
540
+ }), {
488
541
  cache: 'no-store',
489
542
  headers: {
490
543
  'x-api-key': publicKey
@@ -503,7 +556,10 @@ async function refreshWidgetSession(publicKey, previousToken, options = {}) {
503
556
  const { apiOrigin } = getRuntimeConfig(options);
504
557
  const response = await runtimeFetch(`${apiOrigin}/public/widget/token`, {
505
558
  body: JSON.stringify({
506
- token: previousToken
559
+ token: previousToken,
560
+ ...options.mode ? {
561
+ mode: options.mode
562
+ } : {}
507
563
  }),
508
564
  cache: 'no-store',
509
565
  headers: {
@@ -517,7 +573,9 @@ async function refreshWidgetSession(publicKey, previousToken, options = {}) {
517
573
  }
518
574
  async function fetchWidgetObject(objectId, sessionToken, options = {}) {
519
575
  const { apiOrigin } = getRuntimeConfig(options);
520
- const response = await runtimeFetch(`${apiOrigin}/public/objects/by-tinuuid/${encodeURIComponent(objectId)}`, {
576
+ const response = await runtimeFetch(getRuntimeUrl(apiOrigin, `/public/objects/by-tinuuid/${encodeURIComponent(objectId)}`, {
577
+ variantId: options.variantId
578
+ }), {
521
579
  cache: 'no-store',
522
580
  headers: {
523
581
  'x-widget-session-token': sessionToken
@@ -537,6 +595,9 @@ async function sendWidgetEvent(event, sessionToken, objectUuid, options = {}) {
537
595
  ...objectUuid ? {
538
596
  objectId: objectUuid
539
597
  } : {},
598
+ ...options.variantId ? {
599
+ variantId: options.variantId
600
+ } : {},
540
601
  timestamp: new Date().toISOString()
541
602
  }),
542
603
  cache: 'no-store',
@@ -544,6 +605,7 @@ async function sendWidgetEvent(event, sessionToken, objectUuid, options = {}) {
544
605
  'Content-Type': 'application/json',
545
606
  'x-widget-session-token': sessionToken
546
607
  },
608
+ keepalive: true,
547
609
  method: 'POST'
548
610
  }, options);
549
611
  if (!response.ok) throw await toRuntimeError(response, 'event');
@@ -621,11 +683,15 @@ async function initializeAdvancedArTrigger(trigger, options = {}) {
621
683
  const trackView = ()=>options.trackView ? options.trackView() : incrementLegacyObjectView(objectId, options.runtimeConfig);
622
684
  const handleDesktopClick = (event)=>{
623
685
  event.preventDefault();
624
- runSafely(()=>options.onAction?.('widget_opened'));
625
686
  const revision = ++qrRevision;
626
687
  closeOwnedQr?.();
627
688
  closeOwnedQr = void 0;
628
- showQrModal(getArRedirectLink(objectId, variantId, true, options.runtimeConfig), `vizbl-${objectId}`, trigger, options.runtimeConfig).then((cleanup)=>{
689
+ Promise.resolve(options.getDesktopQrUrl?.() ?? getArRedirectLink(objectId, variantId, true, options.runtimeConfig)).then((url)=>{
690
+ if (revision !== qrRevision || !initialization.isCurrent()) return;
691
+ runSafely(()=>options.onAction?.('interacted'));
692
+ return showQrModal(url, `vizbl-${objectId}`, trigger, options.runtimeConfig);
693
+ }).then((cleanup)=>{
694
+ if (!cleanup) return;
629
695
  if (revision !== qrRevision || !initialization.isCurrent()) return void cleanup();
630
696
  closeOwnedQr = cleanup;
631
697
  }).catch(()=>void 0);
@@ -640,7 +706,7 @@ async function initializeAdvancedArTrigger(trigger, options = {}) {
640
706
  await Promise.resolve(trackView()).catch(()=>void 0);
641
707
  } finally{
642
708
  handlingUnsupportedClick = false;
643
- if (isIOS() && isSupportedAppClip()) openAppViewLink(objectId, options.runtimeConfig);
709
+ if (isIOS() && isSupportedAppClip()) openAppViewLink(objectId, variantId, options.runtimeConfig);
644
710
  else openNativeLink(nativeLink);
645
711
  }
646
712
  return;
@@ -649,7 +715,7 @@ async function initializeAdvancedArTrigger(trigger, options = {}) {
649
715
  runSafely(trackView);
650
716
  if (isIOS() && isSupportedAppClip()) {
651
717
  event.preventDefault();
652
- openAppViewLink(objectId, options.runtimeConfig);
718
+ openAppViewLink(objectId, variantId, options.runtimeConfig);
653
719
  } else openNativeLink(nativeLink);
654
720
  };
655
721
  if (mobile) {
@@ -677,16 +743,16 @@ function resolveSizeType(value) {
677
743
  return value && SIZE_TYPES.includes(value) ? value : DEFAULT_SIZE_TYPE;
678
744
  }
679
745
  function createModalViewerUrl(params) {
680
- const viewerOrigin = params.viewerOrigin ?? getCoreArWidgetRuntimeConfig().viewerOrigin;
681
- const objectPath = params.hid ? `${encodeURIComponent(params.tinuuid)}/${encodeURIComponent(params.hid)}` : encodeURIComponent(params.tinuuid);
682
- const url = new URL(objectPath, `${viewerOrigin.replace(/\/$/, '')}/`);
683
- url.searchParams.set('hide-title', params.hideTitle ?? '');
684
- url.searchParams.set('hide-preview', params.hidePreview ?? '');
685
- url.searchParams.set('button-bg-color', params.buttonBgColor ?? '');
686
- url.searchParams.set('button-border-color', params.buttonBorderColor ?? '');
687
- url.searchParams.set('button-text-color', params.buttonTextColor ?? '');
688
- url.searchParams.set('background-color', params.backgroundColor ?? '');
689
- url.searchParams.set('size_type', params.sizeType);
746
+ const modelViewerOrigin = params.modelViewerOrigin ?? getCoreArWidgetRuntimeConfig().modelViewerOrigin;
747
+ const url = new URL('/model-viewer', modelViewerOrigin);
748
+ url.searchParams.set('tinuuid', params.tinuuid);
749
+ if (params.hid) url.searchParams.set('hid', params.hid);
750
+ url.searchParams.set('size-type', params.sizeType);
751
+ const fragment = new URLSearchParams();
752
+ if (params.apiKey) fragment.set('api-key', params.apiKey);
753
+ if (params.mode) fragment.set('mode', params.mode);
754
+ if (params.widgetSessionToken) fragment.set('widget-session-token', params.widgetSessionToken);
755
+ url.hash = fragment.toString();
690
756
  return url.toString();
691
757
  }
692
758
  function createFrame(src, backgroundColor) {
@@ -806,11 +872,23 @@ function openModal(options) {
806
872
  function initializeModalTrigger(trigger, options = {}) {
807
873
  const initialization = modal_trigger_beginInitialization(trigger);
808
874
  let closeOwnedModal;
809
- const handleClick = ()=>{
810
- if (closeOwnedModal) return;
875
+ let pendingOpen = false;
876
+ const handleClick = async ()=>{
877
+ if (closeOwnedModal || pendingOpen) return;
811
878
  const objectId = trigger.dataset.objectTinuuid?.trim();
812
879
  if (!objectId) return;
880
+ pendingOpen = true;
881
+ let widgetSessionToken = options.widgetSessionToken;
882
+ try {
883
+ if (options.getWidgetSessionToken) widgetSessionToken = await options.getWidgetSessionToken();
884
+ } catch {
885
+ pendingOpen = false;
886
+ return;
887
+ }
888
+ pendingOpen = false;
889
+ if (closeOwnedModal || !initialization.isCurrent()) return;
813
890
  const opened = openModal({
891
+ apiKey: options.apiKey,
814
892
  backgroundColor: trigger.dataset.background,
815
893
  buttonBgColor: trigger.dataset.buttonBgColor,
816
894
  buttonBorderColor: trigger.dataset.buttonBorderColor,
@@ -821,6 +899,8 @@ function initializeModalTrigger(trigger, options = {}) {
821
899
  hid: trigger.dataset.objectHid,
822
900
  hidePreview: trigger.dataset.hidePreview,
823
901
  hideTitle: trigger.dataset.hideTitle,
902
+ mode: options.mode,
903
+ modelViewerOrigin: options.modelViewerOrigin,
824
904
  onClose: ()=>{
825
905
  closeOwnedModal = void 0;
826
906
  options.onClose?.();
@@ -828,7 +908,7 @@ function initializeModalTrigger(trigger, options = {}) {
828
908
  restoreFocusTo: trigger,
829
909
  sizeType: resolveSizeType(trigger.dataset.sizeType),
830
910
  tinuuid: objectId,
831
- viewerOrigin: options.viewerOrigin,
911
+ widgetSessionToken,
832
912
  width: trigger.dataset.width?.trim()
833
913
  });
834
914
  if (!opened) return;
@@ -875,11 +955,15 @@ async function initializeNativeArAnchor(link, options = {}) {
875
955
  }
876
956
  const handleDesktopClick = (event)=>{
877
957
  event.preventDefault();
878
- runSafely(()=>options.onAction?.('widget_opened'));
879
958
  const revision = ++qrRevision;
880
959
  closeOwnedQr?.();
881
960
  closeOwnedQr = void 0;
882
- showQrModal(getArRedirectLink(objectId, variantId, false, options.runtimeConfig), `vizbl-${objectId}`, link, options.runtimeConfig).then((cleanup)=>{
961
+ Promise.resolve(options.getDesktopQrUrl?.() ?? getArRedirectLink(objectId, variantId, false, options.runtimeConfig)).then((url)=>{
962
+ if (revision !== qrRevision || !initialization.isCurrent()) return;
963
+ runSafely(()=>options.onAction?.('interacted'));
964
+ return showQrModal(url, `vizbl-${objectId}`, link, options.runtimeConfig);
965
+ }).then((cleanup)=>{
966
+ if (!cleanup) return;
883
967
  if (revision !== qrRevision || !initialization.isCurrent()) return void cleanup();
884
968
  closeOwnedQr = cleanup;
885
969
  }).catch(()=>void 0);
@@ -925,6 +1009,11 @@ const DEFAULT_LABELS = {
925
1009
  'ar-one-click': 'View in AR',
926
1010
  'ar-viewer': 'View in 3D & AR'
927
1011
  };
1012
+ const BACKEND_WIDGET_MODES = {
1013
+ 'advanced-ar': 'advanced-ar-view',
1014
+ 'ar-one-click': 'ar-view',
1015
+ 'ar-viewer': 'ar-viewer'
1016
+ };
928
1017
  const OBSERVED_ATTRIBUTES = [
929
1018
  'api-key',
930
1019
  'dev',
@@ -1035,7 +1124,7 @@ function getSelectedMaterial(object, variantId) {
1035
1124
  }
1036
1125
  function assertPolicy(type, object) {
1037
1126
  const policy = object.policy;
1038
- const allowed = 'ar-viewer' === type ? policy?.ignViewerModal !== false : 'ar-one-click' === type ? policy?.instantArView !== false : policy?.appClip !== false;
1127
+ const allowed = 'ar-one-click' === type ? policy?.instantArView !== false : policy?.appClip !== false;
1039
1128
  if (!allowed) throw new CoreArWidgetComponentError('POLICY_DENIED');
1040
1129
  }
1041
1130
  function toErrorCode(error) {
@@ -1074,6 +1163,8 @@ class CoreArWidgetElement extends HTMLElementBase {
1074
1163
  queued = false;
1075
1164
  session;
1076
1165
  trigger;
1166
+ variantId;
1167
+ widgetMode;
1077
1168
  connectedCallback() {
1078
1169
  installScopedStyles();
1079
1170
  this.captureCustomLabel();
@@ -1118,6 +1209,9 @@ class CoreArWidgetElement extends HTMLElementBase {
1118
1209
  this.abortController?.abort();
1119
1210
  this.cleanup?.();
1120
1211
  this.cleanup = void 0;
1212
+ this.object = void 0;
1213
+ this.variantId = void 0;
1214
+ this.widgetMode = void 0;
1121
1215
  this.clearActionResetTimer();
1122
1216
  const abortController = new AbortController();
1123
1217
  this.abortController = abortController;
@@ -1136,16 +1230,28 @@ class CoreArWidgetElement extends HTMLElementBase {
1136
1230
  if (!objectId) throw new CoreArWidgetComponentError('MISSING_OBJECT_ID');
1137
1231
  if (!isCoreArWidgetType(rawType)) throw new CoreArWidgetComponentError('INVALID_TYPE');
1138
1232
  if ('ar-viewer' === rawType && sizeType && 'cm' !== sizeType && 'inch' !== sizeType) throw new CoreArWidgetComponentError('INVALID_SIZE_TYPE');
1139
- const session = await this.ensureSession(publicKey, runtimeConfig, abortController.signal);
1233
+ const mode = BACKEND_WIDGET_MODES[rawType];
1234
+ const session = await this.ensureSession(publicKey, runtimeConfig, mode, abortController.signal);
1140
1235
  this.assertCurrent(revision, abortController.signal);
1141
- const object = await this.fetchObjectWithSession(objectId, publicKey, session, runtimeConfig, abortController.signal);
1142
- this.assertCurrent(revision, abortController.signal);
1143
- const material = getSelectedMaterial(object, variantId);
1144
- assertPolicy(rawType, object);
1145
- if ('ar-viewer' !== rawType && (!material.native?.glbUrl || !material.native.usdzUrl)) throw new CoreArWidgetComponentError('MODEL_UNAVAILABLE');
1146
- this.object = object;
1236
+ this.variantId = variantId;
1237
+ this.widgetMode = mode;
1147
1238
  this.applyIntegrationData(objectId, variantId, sizeType);
1148
- const cleanup = await this.initializeTrigger(rawType, object, runtimeConfig, abortController.signal);
1239
+ let object;
1240
+ if ('ar-viewer' === rawType) {
1241
+ object = await fetchLegacyObject(objectId, abortController.signal, runtimeConfig);
1242
+ this.assertCurrent(revision, abortController.signal);
1243
+ getSelectedMaterial(object, variantId);
1244
+ assertPolicy(rawType, object);
1245
+ this.object = object;
1246
+ } else {
1247
+ object = isMobile() ? await this.fetchObjectWithSession(objectId, publicKey, session, runtimeConfig, abortController.signal, variantId) : await fetchLegacyObject(objectId, abortController.signal, runtimeConfig);
1248
+ this.assertCurrent(revision, abortController.signal);
1249
+ const material = getSelectedMaterial(object, variantId);
1250
+ assertPolicy(rawType, object);
1251
+ if (!material.native?.glbUrl || !material.native.usdzUrl) throw new CoreArWidgetComponentError('MODEL_UNAVAILABLE');
1252
+ this.object = object;
1253
+ }
1254
+ const cleanup = await this.initializeTrigger(rawType, object, runtimeConfig, abortController.signal, publicKey, session);
1149
1255
  try {
1150
1256
  this.assertCurrent(revision, abortController.signal);
1151
1257
  } catch (error) {
@@ -1170,12 +1276,13 @@ class CoreArWidgetElement extends HTMLElementBase {
1170
1276
  });
1171
1277
  }
1172
1278
  }
1173
- async ensureSession(publicKey, runtimeConfig, signal, forceRefresh = false) {
1174
- const runtimeKey = `${runtimeConfig.apiOrigin}|${runtimeConfig.viewerOrigin}`;
1279
+ async ensureSession(publicKey, runtimeConfig, mode, signal, forceRefresh = false) {
1280
+ const runtimeKey = `${runtimeConfig.apiOrigin}|${runtimeConfig.viewerOrigin}|${runtimeConfig.modelViewerOrigin}|${mode}`;
1175
1281
  const existing = this.session?.publicKey === publicKey && this.session.runtimeKey === runtimeKey ? this.session : void 0;
1176
1282
  if (existing && !forceRefresh && existing.expiresAt - Date.now() > SESSION_REFRESH_THRESHOLD_MS) return existing;
1177
1283
  if (existing) try {
1178
1284
  const refreshed = await refreshWidgetSession(publicKey, existing.token, {
1285
+ mode: existing.mode,
1179
1286
  runtimeConfig,
1180
1287
  signal
1181
1288
  });
@@ -1191,12 +1298,14 @@ class CoreArWidgetElement extends HTMLElementBase {
1191
1298
  this.session = void 0;
1192
1299
  }
1193
1300
  const activated = await activateCoreWidget(publicKey, {
1301
+ mode,
1194
1302
  runtimeConfig,
1195
1303
  signal
1196
1304
  });
1197
1305
  if (!ALLOWED_CORE_PRODUCT_TYPES.has(activated.productType)) throw new CoreArWidgetComponentError('POLICY_DENIED');
1198
1306
  const session = {
1199
1307
  expiresAt: Date.now() + 1000 * activated.expiresIn,
1308
+ mode,
1200
1309
  productType: activated.productType,
1201
1310
  publicKey,
1202
1311
  runtimeKey,
@@ -1206,18 +1315,20 @@ class CoreArWidgetElement extends HTMLElementBase {
1206
1315
  this.session = session;
1207
1316
  return session;
1208
1317
  }
1209
- async fetchObjectWithSession(objectId, publicKey, session, runtimeConfig, signal) {
1318
+ async fetchObjectWithSession(objectId, publicKey, session, runtimeConfig, signal, variantId) {
1210
1319
  try {
1211
1320
  return await fetchWidgetObject(objectId, session.token, {
1212
1321
  runtimeConfig,
1213
- signal
1322
+ signal,
1323
+ variantId
1214
1324
  });
1215
1325
  } catch (error) {
1216
1326
  if (!(error instanceof WidgetRuntimeError) || 'SESSION_EXPIRED' !== error.code) throw error;
1217
- const refreshed = await this.ensureSession(publicKey, runtimeConfig, signal, true);
1327
+ const refreshed = await this.ensureSession(publicKey, runtimeConfig, session.mode, signal, true);
1218
1328
  return fetchWidgetObject(objectId, refreshed.token, {
1219
1329
  runtimeConfig,
1220
- signal
1330
+ signal,
1331
+ variantId
1221
1332
  });
1222
1333
  }
1223
1334
  }
@@ -1269,17 +1380,37 @@ class CoreArWidgetElement extends HTMLElementBase {
1269
1380
  if (sizeType) this.trigger.dataset.sizeType = sizeType;
1270
1381
  else delete this.trigger.dataset.sizeType;
1271
1382
  }
1272
- async initializeTrigger(type, object, runtimeConfig, signal) {
1383
+ async initializeTrigger(type, object, runtimeConfig, signal, publicKey, session) {
1273
1384
  if (!this.trigger) throw new CoreArWidgetComponentError('INITIALIZATION_FAILED');
1274
1385
  if ('ar-viewer' === type) return initializeModalTrigger(this.trigger, {
1386
+ apiKey: publicKey,
1387
+ getWidgetSessionToken: async ()=>{
1388
+ const currentSession = await this.ensureSession(publicKey, runtimeConfig, session.mode);
1389
+ return currentSession.token;
1390
+ },
1391
+ mode: session.mode,
1392
+ modelViewerOrigin: runtimeConfig.modelViewerOrigin,
1275
1393
  onAction: (action)=>this.handleAction(action, runtimeConfig),
1276
1394
  onClose: ()=>{
1277
1395
  if (this.isConnected) this.setState('ready');
1278
1396
  },
1279
1397
  onOpen: ()=>this.setState('opening'),
1280
- viewerOrigin: runtimeConfig.viewerOrigin
1398
+ widgetSessionToken: session.token
1281
1399
  });
1400
+ if (!object) throw new CoreArWidgetComponentError('INITIALIZATION_FAILED');
1282
1401
  const options = {
1402
+ getDesktopQrUrl: async ()=>{
1403
+ const currentSession = await this.ensureSession(publicKey, runtimeConfig, session.mode);
1404
+ return createModalViewerUrl({
1405
+ apiKey: publicKey,
1406
+ hid: this.variantId,
1407
+ mode: currentSession.mode,
1408
+ modelViewerOrigin: runtimeConfig.modelViewerOrigin,
1409
+ sizeType: resolveSizeType(this.trigger?.dataset.sizeType),
1410
+ tinuuid: this.trigger?.dataset.objectTinuuid ?? '',
1411
+ widgetSessionToken: currentSession.token
1412
+ });
1413
+ },
1283
1414
  object,
1284
1415
  onAction: (action)=>this.handleAction(action, runtimeConfig),
1285
1416
  runtimeConfig,
@@ -1294,7 +1425,7 @@ class CoreArWidgetElement extends HTMLElementBase {
1294
1425
  }
1295
1426
  handleAction(action, runtimeConfig) {
1296
1427
  this.setState('opening');
1297
- if ('widget_opened' === action) this.trackEvent(action, runtimeConfig);
1428
+ if (('interacted' === action || 'widget_opened' === action) && 'ar-viewer' !== this.getAttribute('type')) this.trackEvent(action, runtimeConfig);
1298
1429
  if ('ar-viewer' === this.getAttribute('type')) return;
1299
1430
  this.clearActionResetTimer();
1300
1431
  this.actionResetTimer = window.setTimeout(()=>{
@@ -1303,11 +1434,13 @@ class CoreArWidgetElement extends HTMLElementBase {
1303
1434
  }
1304
1435
  async trackEvent(event, runtimeConfig) {
1305
1436
  const publicKey = this.getAttribute('api-key')?.trim();
1306
- if (!publicKey || !this.isConnected) return;
1437
+ const mode = this.widgetMode;
1438
+ if (!publicKey || !mode || !this.isConnected) return;
1307
1439
  try {
1308
- const session = await this.ensureSession(publicKey, runtimeConfig);
1440
+ const session = await this.ensureSession(publicKey, runtimeConfig, mode);
1309
1441
  await sendWidgetEvent(event, session.token, this.object?.uuid, {
1310
- runtimeConfig
1442
+ runtimeConfig,
1443
+ variantId: this.variantId
1311
1444
  });
1312
1445
  } catch {}
1313
1446
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@neurodyn/core-ar",
3
3
  "type": "module",
4
- "version": "0.2.0",
4
+ "version": "0.2.2",
5
5
  "sideEffects": false,
6
6
  "publishConfig": {
7
7
  "access": "public"