@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.
- package/dist/core-ar.embed.min.js +2 -2
- package/dist/index.js +181 -48
- package/package.json +1 -1
|
@@ -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(
|
|
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(
|
|
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
|
-
|
|
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
|
|
681
|
-
const
|
|
682
|
-
|
|
683
|
-
url.searchParams.set('
|
|
684
|
-
url.searchParams.set('
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
url.
|
|
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
|
-
|
|
810
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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-
|
|
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
|
|
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
|
-
|
|
1142
|
-
this.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|