@virtualdisplay.io/client 4.0.0-alpha.19 → 4.0.0-alpha.20

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";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const k={NO_MAPPING:"NO_MAPPING",ATTRIBUTE_NOT_FOUND:"ATTRIBUTE_NOT_FOUND",VALUE_NOT_FOUND:"VALUE_NOT_FOUND",PARENT_NOT_FOUND:"PARENT_NOT_FOUND",INVALID_PARAMETER:"INVALID_PARAMETER",SNAPSHOT_FAILED:"SNAPSHOT_FAILED"};class f extends Error{code;constructor(t,e){super(t),this.name="VirtualdisplayError",this.code=e}static valueNotFound(t,e){return new f(`Value "${e}" not found for attribute "${t}"`,k.VALUE_NOT_FOUND)}static parentNotFound(t){return new f(`Parent element not found: ${t}`,k.PARENT_NOT_FOUND)}static invalidParameter(t){return new f(t,k.INVALID_PARAMETER)}}const It={};class Lt{defaultServer="https://server.virtualdisplay.io";options;constructor(t){this.options=t}create(){const t=this.createContainer(),e=this.createIframe();return t.appendChild(e),this.attachToParent(t),{container:t,iframe:e}}createContainer(){const t=document.createElement("div");return t.className="vd-container",Object.assign(t.style,{position:"relative",width:"100%",height:"100%",overflow:"hidden"}),t}createIframe(){const t=document.createElement("iframe");return t.src=this.buildUrl(),Object.assign(t.style,{width:"100%",height:"100%",border:"none",display:"block"}),t.setAttribute("allow","xr-spatial-tracking; fullscreen"),t}attachToParent(t){this.getParentElement().appendChild(t)}buildUrl(){const t=this.getServerUrl(),e=new URL(t);return e.searchParams.set("license",this.options.license),e.searchParams.set("model",this.options.model),this.options.language!==void 0&&e.searchParams.set("language",this.options.language),this.options.debug===!0&&e.searchParams.set("debug","true"),this.options.traceparent!==void 0&&e.searchParams.set("traceparent",this.options.traceparent),e.toString()}getServerUrl(){if(It?.VITE_VIRTUALDISPLAY_SERVER_HOST===void 0)return this.defaultServer}getParentElement(){if(typeof this.options.parent!="string")return this.options.parent;const t=document.querySelector(this.options.parent);if(t===null)throw f.parentNotFound(this.options.parent);return t}}function Mt(n){const t=new Date(n.timestamp).toLocaleTimeString("en-GB",{hour12:!1}),e=n.level.toUpperCase().padEnd(5),i=n.trace_id?.slice(0,8)??"--------",o=n.msg,s=["timestamp","level","msg","service","trace_id","span_id"],r=Object.entries(n).filter(([l])=>!s.includes(l)).map(([l,d])=>`${l}=${JSON.stringify(d)}`).join(" ");return`${t} ${e} [${i}] ${o}${r?" "+r:""}`}function zt(n){return JSON.stringify(n)}function Pt(n,t){const e=t?Mt(n):zt(n);n.level==="error"?console.error(e):n.level==="warn"?console.warn(e):console.log(e)}function lt(n,t=0){const e={name:n.name,message:n.message};n.stack!==void 0&&(e.stack=n.stack);for(const i of Object.getOwnPropertyNames(n)){if(i==="name"||i==="message"||i==="stack"||i==="cause")continue;const o=n[i];o!==void 0&&(e[i]=o)}return n.cause!==void 0&&n.cause!==null&&(e.cause=n.cause instanceof Error&&t<5?lt(n.cause,t+1):String(n.cause)),e}function Ft(n){const t={};for(const[e,i]of Object.entries(n))t[e]=i instanceof Error?lt(i):i;return t}function $t(){return new Date}function Dt(n){return n.toISOString()}function ct(){return typeof navigator>"u"?"":navigator.userAgent}function Bt(){return typeof navigator>"u"?!1:navigator.platform==="MacIntel"&&navigator.maxTouchPoints>1}function Ut(){return/iPhone|iPad|iPod/i.test(ct())||Bt()}function Vt(){return/Android/i.test(ct())}function jt(){return Ut()||Vt()}class q{constructor(t){this.config=t}config;log(t,e,i={}){const o=this.config.traceProvider?.()??{},s={timestamp:Dt($t()),level:t,msg:e,service:this.config.service,...o,...Ft(i)};Pt(s,this.config.isDev)}debug(t,e){this.config.isDev&&this.log("debug",t,e)}info(t,e){this.log("info",t,e)}warn(t,e){this.log("warn",t,e)}error(t,e){this.log("error",t,e)}with(t){const e=new q(this.config);return e.log=((i,o,s={})=>{this.log(i,o,{...t,...s})}).bind(this),e}}function ut(n,t){const e=t?.isDev!==void 0?t.isDev:typeof process<"u"?process.env.NODE_ENV!=="production":!0;return new q({service:n,isDev:e,traceProvider:t?.traceProvider})}function O(n){if(n!==void 0)return typeof n=="object"&&n!==null&&!Array.isArray(n)&&!(n instanceof Error)?n:n instanceof Error?{error:n.message}:{value:n}}function dt(n){return{debug:(t,e)=>n.debug(t,O(e)),info:(t,e)=>n.info(t,O(e)),warn:(t,e)=>n.warn(t,O(e)),error:(t,e)=>n.error(t,O(e))}}let ht=!1;exports.logger=dt(ut("client",{isDev:!1}));function mt(){ht=!0,exports.logger=dt(ut("client",{isDev:!0}))}function Ht(){return ht}class Gt{ready=!1;onReady;constructor(t){this.onReady=t}handleMappingReceived(){this.ready||(this.ready=!0,exports.logger.info("Mapping received from server, client is now ready"),this.onReady?.())}get isReady(){return this.ready}clear(){this.ready=!1}}const T={SELECT:"ui:select",SELECTED:"ui:selected",FOCUS_CHANGE:"vd:focus-change",CONFIGURATION_CHANGE:"vd:configuration-change",CONFIGURATION_SUBMIT:"vd:configuration-submit"};class pt{constructor(t,e){this.value=t,this.attribute=e}value;attribute;isSelectedValue=!1;get isSelected(){return this.isSelectedValue}setSelected(t){this.isSelectedValue=t}}class ft{name;defaultValue;values;onSelect;onChangeCallback;constructor(t){this.name=t.name,this.defaultValue=t.defaultValue,this.onSelect=t.onSelect,this.values=this.createValues(t.values)}select(t){if(!this.values.has(t))throw f.valueNotFound(this.name,t);this.onSelect(this.name,t)}getValues(){return Array.from(this.values.values())}getValue(t){return this.values.get(t)}get selected(){for(const t of this.values.values())if(t.isSelected)return t.value}onChange(t){this.onChangeCallback=t}handleResult(t){let e;for(const i of this.values.values()){const o=i.value===t;i.setSelected(o),o&&(e=i)}e!==void 0&&this.onChangeCallback!==void 0&&this.onChangeCallback(e)}createValues(t){const e=new Map;for(const i of t){const o=new pt(i,this.name);i===this.defaultValue&&o.setSelected(!0),e.set(i,o)}return e}}class qt{attributes=new Map;constructor(t,e,i){for(const o of t){const s=this.buildOptions(o,e);this.attributes.set(o.name,new ft(s))}this.onMutationFailed=i}onMutationFailed;get(t){return this.attributes.get(t)}getSelection(){const t={};for(const[e,i]of this.attributes){const o=i.selected;o!==void 0&&(t[e]=o)}return t}handleResults(t){for(const e of t){if(!e.success){this.onMutationFailed?.(e.name,e.value);continue}this.get(e.name)?.handleResult(e.value)}}buildOptions(t,e){const i={name:t.name,values:t.values,onSelect:(o,s)=>{e([{name:o,value:s}],!1)}};return t.defaultValue!==void 0?{...i,defaultValue:t.defaultValue}:i}}const c={HANDSHAKE:"handshake",SESSION:"session",MUTATION:"mutation",STATE:"state",LOADING_INDICATOR:"loading_indicator",CAMERA:"camera",SNAPSHOT:"snapshot",MAPPING:"mapping",AR_ACTIVATE:"ar_activate",FULLSCREEN:"fullscreen",CONFIG:"config",ANNOTATION_PLACE_MODE:"annotation_place_mode",ANNOTATION_PLACED:"annotation_placed",ANNOTATION_TOGGLE:"annotation_toggle",FOCUS:"focus",PRICING:"pricing"},Y={FOCUS:"focus",UNFOCUS:"unfocus"},Zt={FOCUSED:"focused"},Wt={HIDDEN:"hidden"},Yt=new Set(Object.values(c));function Xt(n){if(typeof n!="object"||n===null)return!1;const t=n;return typeof t.target=="string"?!1:typeof t.type=="string"&&Yt.has(t.type)}function Kt(n){const t=C(n);return t!==null&&t.type===c.HANDSHAKE}function Qt(n){const t=C(n);return t!==null&&t.type===c.SESSION&&typeof t.sessionId=="string"}function Jt(n){const t=C(n);return t!==null&&t.type===c.MUTATION&&Array.isArray(t.results)}function te(n){const t=C(n);return t!==null&&t.type===c.SNAPSHOT&&("data"in t||"error"in t)}function ee(n){const t=C(n);return t!==null&&t.type===c.CAMERA&&Array.isArray(t.transforms)}function ne(n){const t=C(n);return t!==null&&t.type===c.MAPPING&&Array.isArray(t.attributes)}function ie(n){const t=C(n);return t!==null&&t.type===c.LOADING_INDICATOR&&typeof t.progress=="number"}function oe(n){const t=C(n);return t!==null&&t.type===c.CONFIG&&typeof t.viewerSettings=="object"}function se(n){const t=C(n);return t!==null&&t.type===c.ANNOTATION_PLACED&&typeof t.position=="object"&&t.position!==null}function re(n){const t=C(n);return t!==null&&t.type===c.FOCUS&&typeof t.state=="string"}function ae(n){const t=C(n);return t!==null&&t.type===c.PRICING&&typeof t.pricing=="object"&&t.pricing!==null}function C(n){return typeof n!="object"||n===null?null:n}class X{constructor(t){this.processor=t}processor;pending=[];isReady=!1;enqueue(t){if(this.isReady){this.processor(t);return}this.pending.push(t)}markReady(){if(this.isReady||(this.isReady=!0,this.pending.length===0))return;const t=[...this.pending];this.pending.length=0;for(const e of t)this.processor(e)}get ready(){return this.isReady}get pendingCount(){return this.pending.length}hasPending(t){return this.pending.some(e=>e.type===t)}clear(){this.pending.length=0}}class le{constructor(t,e){this.getTarget=t,this.sourceId=`vd-${Math.random().toString(36).slice(2,8)}`,this.targetOrigin=e?.targetOrigin??"*",this.publisher=new X(i=>this.post(i)),this.consumer=new X(i=>this.routeToHandler(i)),this.shouldBuffer=e?.shouldBuffer??null,e?.bufferIncoming!==!0&&this.consumer.markReady()}getTarget;handlers=new Map;publisher;consumer;shouldBuffer;listener=null;sourceId;targetOrigin;on(t,e){this.handlers.set(t,e)}off(t){this.handlers.delete(t)}setTargetOrigin(t){this.targetOrigin=t}send(t){this.publisher.enqueue(t)}markReady(){this.publisher.markReady()}markConsumerReady(){this.consumer.markReady()}consumerHasPending(t){return this.consumer.hasPending(t)}start(){this.listener===null&&(this.listener=t=>{const{data:e}=t;if(!Xt(e)||e._source===this.sourceId)return;const i=this.getTarget();if(i!==null&&t.source!==null&&t.source!==i)return;const o=e;if(this.shouldBuffer!==null&&!this.shouldBuffer(o)){this.routeToHandler(o);return}this.consumer.enqueue(o)},window.addEventListener("message",this.listener))}destroy(){this.listener!==null&&(window.removeEventListener("message",this.listener),this.listener=null),this.publisher.clear(),this.consumer.clear(),this.handlers.clear()}get ready(){return this.publisher.ready}get pendingCount(){return this.publisher.pendingCount}post(t){const e=this.getTarget();e!==null&&e.postMessage({...t,_source:this.sourceId},this.targetOrigin)}routeToHandler(t){const e=this.handlers.get(t.type);if(e===void 0)return;const i=e(t);i instanceof Promise&&i.catch(o=>{const s=o instanceof Error?o.message:String(o);console.error(`Virtualdisplay: error handling ${t.type}: ${s}`)})}}class ce{constructor(t,e){this.send=t,this.onMutationFailed=e}send;onMutationFailed;registry;pendingCallbacks=[];handleMappingReceived(t){exports.logger.debug("Initializing from server mapping",{attributeCount:t.attributes.length}),this.registry=new qt(t.attributes,(e,i)=>this.sendMutation(e,i),this.onMutationFailed),this.replayPendingCallbacks()}handleMutationResult(t){this.registry?.handleResults(t.results)}select(t,e){this.sendMutation([{name:t,value:e}],!1)}getValues(t){return this.registry?.get(t)?.getValues()??[]}getValue(t,e){return this.registry?.get(t)?.getValue(e)}onChange(t,e){if(this.registry===void 0){this.pendingCallbacks.push({name:t,callback:e});return}const i=this.registry.get(t);if(i===void 0){exports.logger.warn(`onChange: attribute "${t}" not found — callback will not fire`);return}i.onChange(e)}getAttribute(t){return this.registry?.get(t)}getSelection(){return this.registry?.getSelection()??{}}get hasMapping(){return this.registry!==void 0}sendMutation(t,e){const i={type:c.MUTATION,mutations:t,isInitial:e};this.send(i)}replayPendingCallbacks(){for(const{name:t,callback:e}of this.pendingCallbacks){const i=this.registry?.get(t);i===void 0&&exports.logger.warn(`onChange: attribute "${t}" not found — buffered callback will not fire`),i?.onChange(e)}this.pendingCallbacks.length=0}}let gt=class{constructor(t){this.send=t}send;commands=[];rotate(t){return this.validateFiniteNumber(t,"rotate"),this.commands.push({action:"rotate",value:t}),this}tilt(t){return this.validateFiniteNumber(t,"tilt"),this.commands.push({action:"tilt",value:t}),this}zoom(t){return this.validateFiniteNumber(t,"zoom"),this.commands.push({action:"zoom",value:t}),this}set(){if(this.commands.length===0)throw f.invalidParameter("No camera commands to execute. Call rotate(), tilt(), or zoom() before set().");const t={type:c.CAMERA,commands:this.commands};this.send(t),this.commands=[]}validateFiniteNumber(t,e){if(!Number.isFinite(t))throw f.invalidParameter(`${e}() requires a finite number, got ${String(t)}`)}reset(){const t={type:c.CAMERA,commands:[{action:"reset"}]};this.send(t)}};class ue{state;limitsState;changeCallbacks=[];constructor(){this.state={rotation:0,tilt:0,zoom:100}}get rotation(){return this.state.rotation}get tilt(){return this.state.tilt}get zoom(){return this.state.zoom}onChange(t){this.changeCallbacks.push(t)}get limits(){return this.limitsState}applyLimits(t){this.limitsState=t;const e={rotation:this.rotation,tilt:this.tilt,zoom:this.zoom};for(const i of this.changeCallbacks)i(e)}handlePositionUpdate(t){this.update(t.transforms)}update(t){let e=!1;for(const i of t)switch(i.type){case"rotation":this.state.rotation=i.value,e=!0;break;case"tilt":this.state.tilt=i.value,e=!0;break;case"zoom":this.state.zoom=i.value,e=!0;break}if(e){const i={rotation:this.rotation,tilt:this.tilt,zoom:this.zoom};for(const o of this.changeCallbacks)o(i)}}}class bt{constructor(t,e){this.send=t,this.dispatch=e}send;dispatch;focused=null;attributes=[];changeCallbacks=[];get current(){return this.focused}set(t){if(typeof t!="string"||t.length===0)throw f.invalidParameter(`set() requires a non-empty component name, got ${String(t)}`);this.send({type:c.FOCUS,action:Y.FOCUS,component:t})}clear(){this.send({type:c.FOCUS,action:Y.UNFOCUS})}onChange(t){this.changeCallbacks.push(t)}handleStateReceived(t){t.state===Zt.FOCUSED&&t.component!==void 0?(this.focused=t.component,this.attributes=t.attributes??[]):(this.focused=null,this.attributes=[]);const e=this.focused!==null?{component:this.focused,attributes:this.attributes}:null;for(const i of this.changeCallbacks)i(e);this.dispatch(e)}}function de(n,t){const e=n.filter(s=>he(s,t));if(e.length===0)return;const i=Math.max(...e.map(K)),o=e.filter(s=>K(s)===i);return o.length===1?o[0]:void 0}function he(n,t){return Object.entries(n.attributes).every(([e,i])=>t[e]===i)}function K(n){return Object.keys(n.attributes).length}class vt{constructor(t,e){this.dispatchChange=t,this.dispatchSubmit=e}dispatchChange;dispatchSubmit;pricing;selection={};resolved;changeCallbacks=[];renderCallbacks=[];submitCallback;submitDefaultLabel;get current(){return this.resolved}get vatDisplay(){return this.pricing?.vatDisplay}get buttonLabel(){const t=this.pricing?.buttonLabel;if(t!=null&&t!=="")return t;if(this.submitDefaultLabel!==void 0&&this.submitDefaultLabel!=="")return this.submitDefaultLabel}get submittable(){return this.submitCallback===void 0?!1:this.pricing===void 0?!0:this.resolved?.availability==="available"}get submitEnabled(){return this.submittable&&this.buttonLabel!==void 0}onChange(t){this.changeCallbacks.push(t)}onSubmit(t,e){this.submitCallback=t,this.submitDefaultLabel=e?.defaultLabel,this.notifyRender()}onRender(t){return this.renderCallbacks.push(t),()=>{const e=this.renderCallbacks.indexOf(t);e!==-1&&this.renderCallbacks.splice(e,1)}}async submit(){if(!this.submittable)return;const t=this.resolved!==void 0?{attributes:this.resolved.attributes,reference:this.resolved.reference}:{attributes:{...this.selection},reference:""};this.dispatchSubmit(t),await this.submitCallback?.(t)}handlePricingReceived(t){this.pricing=t,this.recompute()}handleSelectionChanged(t){this.selection=t,this.recompute()}recompute(){this.resolved=this.resolve();for(const t of this.changeCallbacks)t(this.resolved);this.dispatchChange(this.resolved),this.notifyRender()}notifyRender(){for(const t of this.renderCallbacks)t()}resolve(){if(this.pricing===void 0)return;const t=de(this.pricing.rules,this.selection);if(!(t===void 0||t.availability===Wt.HIDDEN))return{attributes:{...this.selection},reference:t.reference,price:t.priceCents,currency:this.pricing.currency,availability:t.availability}}}class yt{constructor(t){this.filename=t}filename;developedCallbacks=new Set;errorCallbacks=new Set;developed=!1;failed=!1;photoData=null;onDeveloped(t){return this.developed&&this.photoData!==null?(t(this.photoData),this):(this.developedCallbacks.add(t),this)}onError(t){return this.errorCallbacks.add(t),this}getFilename(){return this.filename}develop(t){this.developed||this.failed||(this.photoData=t,this.developed=!0,this.developedCallbacks.forEach(e=>{e(this.photoData)}),this.developedCallbacks.clear(),this.errorCallbacks.clear())}fail(t){this.developed||this.failed||(this.failed=!0,this.errorCallbacks.forEach(e=>{e(t)}),this.developedCallbacks.clear(),this.errorCallbacks.clear())}}const Q=3e4;class _t{constructor(t){this.send=t}send;validExtensions=[".png"];pendingPhotos=new Map;take(t){this.validateFilename(t),exports.logger.debug("Taking snapshot",{filename:t});const e=new yt(t),i=setTimeout(()=>{this.pendingPhotos.delete(t),exports.logger.warn("Snapshot timed out",{filename:t}),e.fail(new f(`Snapshot timed out: the viewer did not respond within ${Q}ms`,k.SNAPSHOT_FAILED))},Q);return this.pendingPhotos.set(t,{photo:e,timeout:i}),this.send({type:c.SNAPSHOT,filename:t}),e}handleSnapshotResult(t){const e=this.pendingPhotos.get(t.filename);if(e===void 0){exports.logger.warn("No pending photo found for filename",{filename:t.filename,pendingFilenames:Array.from(this.pendingPhotos.keys())});return}clearTimeout(e.timeout),this.pendingPhotos.delete(t.filename);const{photo:i}=e;if(t.error!==void 0){i.fail(new f(t.error,k.SNAPSHOT_FAILED));return}t.data!==void 0&&i.develop({filename:t.filename,data:t.data})}clear(){if(this.pendingPhotos.size===0)return;const t=new f("Client destroyed before snapshot completed",k.SNAPSHOT_FAILED);for(const{photo:e,timeout:i}of this.pendingPhotos.values())clearTimeout(i),e.fail(t);this.pendingPhotos.clear()}validateFilename(t){if(t===""||typeof t!="string")throw new f("Filename must be a non-empty string",k.INVALID_PARAMETER);if(!this.validExtensions.some(i=>t.toLowerCase().endsWith(i)))throw new f(`Invalid filename: "${t}". Filename must end with one of: ${this.validExtensions.join(", ")}`,k.INVALID_PARAMETER);if(t.includes("..")||t.includes("/")||t.includes("\\"))throw new f('Filename cannot contain path separators or ".."',k.INVALID_PARAMETER)}}class me{container=null;attach(t){this.container=t}dispatch(t,e,i=!1){const o=new CustomEvent(t,{detail:e,cancelable:i});return this.container?.dispatchEvent(o),o}on(t,e){const i=o=>{const s=o,r={...s.detail,preventDefault:()=>{s.preventDefault()}};e(r)};return this.container?.addEventListener(t,i),()=>{this.container?.removeEventListener(t,i)}}}const pe={},fe="en",Ct=["en","nl","de"],Z=["baseLocale"],J=[];let tt,et;function ge(n){if(J.length===0)return;const t=typeof n=="string"?n:n.href;if(tt===t)return et;const e=new URL(t,"http://dummy.com");let i;for(const o of J)if(new pe(o.match,e.href).exec(e.href)){i=o;break}return tt=t,et=i,i}function wt(n){const t=ge(n);return t&&t.exclude!==!0&&Array.isArray(t.strategy)?t.strategy:Z}const G=typeof window>"u";globalThis.__paraglide=globalThis.__paraglide??{};globalThis.__paraglide.ssr=globalThis.__paraglide.ssr??{};let nt=!1,h=()=>{let n=Z;!G&&typeof window<"u"&&window.location?.href&&(n=wt(window.location.href));const t=be(n);if(t)return nt||(nt=!0,kt(t,{reload:!1})),t;throw new Error("No locale found. Read the docs https://paraglidejs.com/errors#no-locale-found")};function be(n,t){let e;for(const i of n){if(i==="baseLocale")e=fe;else if(At(i)&&N.has(i)){const s=N.get(i);if(s){const r=s.getLocale();if(r instanceof Promise)continue;if(r!==void 0)return ye(r)}}const o=St(e);if(o)return o}}const ve=n=>{window.location.reload()};let kt=(n,t)=>{const e={reload:!0,...t};let i;try{i=h()}catch{}const o=[];let s=Z;!G&&typeof window<"u"&&window.location?.href&&(s=wt(window.location.href));for(const l of s)if(l!=="baseLocale"&&At(l)&&N.has(l)){const d=N.get(l);if(d){let u=d.setLocale(n);u instanceof Promise&&(u=u.catch(p=>{throw new Error(`Custom strategy "${l}" setLocale failed.`,{cause:p})}),o.push(u))}}const r=()=>{!G&&e.reload&&window.location&&n!==i&&ve()};if(o.length)return Promise.all(o).then(()=>{r()});r()};function St(n){if(typeof n!="string")return;const t=n.toLowerCase();for(const e of Ct)if(e.toLowerCase()===t)return e}function ye(n){const t=St(n);if(t)return t;throw new Error(`Invalid locale: ${n}. Expected one of: ${Ct.join(", ")}`)}const N=new Map;function At(n){return typeof n=="string"&&/^custom-[A-Za-z0-9_-]+$/.test(n)}const _e=()=>"Activate AR",Ce=()=>"AR activeren",we=()=>"AR aktivieren",ke=((n={},t={})=>{const e=t.locale??h();return e==="en"?_e():e==="nl"?Ce():we()}),Se=()=>"Scan to view in AR",Ae=()=>"Scan om in AR te bekijken",Ee=()=>"Scannen für AR-Ansicht",xe=((n={},t={})=>{const e=t.locale??h();return e==="en"?Se():e==="nl"?Ae():Ee()}),Te=()=>"Use your smartphone camera to scan this QR code",Re=()=>"Gebruik de camera van je smartphone om deze QR-code te scannen",Oe=()=>"Verwende die Kamera deines Smartphones, um diesen QR-Code zu scannen",Ne=((n={},t={})=>{const e=t.locale??h();return e==="en"?Te():e==="nl"?Re():Oe()}),Ie=()=>"Your phone will open the 3D model in AR mode.",Le=()=>"Je telefoon opent het 3D-model in AR-modus.",Me=()=>"Dein Telefon öffnet das 3D-Modell im AR-Modus.",ze=((n={},t={})=>{const e=t.locale??h();return e==="en"?Ie():e==="nl"?Le():Me()}),Pe=()=>"Close",Fe=()=>"Sluiten",$e=()=>"Schließen",De=((n={},t={})=>{const e=t.locale??h();return e==="en"?Pe():e==="nl"?Fe():$e()}),Be=()=>"Fullscreen",Ue=()=>"Volledig scherm",Ve=()=>"Vollbild",je=((n={},t={})=>{const e=t.locale??h();return e==="en"?Be():e==="nl"?Ue():Ve()}),He=()=>"Downloading",Ge=()=>"Downloaden",qe=()=>"Herunterladen",Et=((n={},t={})=>{const e=t.locale??h();return e==="en"?He():e==="nl"?Ge():qe()}),Ze=()=>"Rendering",We=()=>"Renderen",Ye=()=>"Rendern",Xe=((n={},t={})=>{const e=t.locale??h();return e==="en"?Ze():e==="nl"?We():Ye()}),Ke=()=>"Screenshot",Qe=()=>"Screenshot",Je=()=>"Screenshot",tn=((n={},t={})=>{const e=t.locale??h();return e==="en"?Ke():e==="nl"?Qe():Je()}),en=()=>"Configure",nn=()=>"Configureren",on=()=>"Konfigurieren",sn=((n={},t={})=>{const e=t.locale??h();return e==="en"?en():e==="nl"?nn():on()}),rn=()=>"Close",an=()=>"Sluiten",ln=()=>"Schließen",cn=((n={},t={})=>{const e=t.locale??h();return e==="en"?rn():e==="nl"?an():ln()}),un=()=>"Reset camera",dn=()=>"Camera resetten",hn=()=>"Kamera zurücksetzen",mn=((n={},t={})=>{const e=t.locale??h();return e==="en"?un():e==="nl"?dn():hn()}),pn=()=>"Zoom in",fn=()=>"Inzoomen",gn=()=>"Hineinzoomen",bn=((n={},t={})=>{const e=t.locale??h();return e==="en"?pn():e==="nl"?fn():gn()}),vn=()=>"Zoom out",yn=()=>"Uitzoomen",_n=()=>"Herauszoomen",Cn=((n={},t={})=>{const e=t.locale??h();return e==="en"?vn():e==="nl"?yn():_n()}),wn=()=>"Rotate left",kn=()=>"Naar links draaien",Sn=()=>"Nach links drehen",An=((n={},t={})=>{const e=t.locale??h();return e==="en"?wn():e==="nl"?kn():Sn()}),En=()=>"Rotate right",xn=()=>"Naar rechts draaien",Tn=()=>"Nach rechts drehen",Rn=((n={},t={})=>{const e=t.locale??h();return e==="en"?En():e==="nl"?xn():Tn()}),On=()=>"Tilt up",Nn=()=>"Omhoog kantelen",In=()=>"Nach oben kippen",Ln=((n={},t={})=>{const e=t.locale??h();return e==="en"?On():e==="nl"?Nn():In()}),Mn=()=>"Tilt down",zn=()=>"Omlaag kantelen",Pn=()=>"Nach unten kippen",Fn=((n={},t={})=>{const e=t.locale??h();return e==="en"?Mn():e==="nl"?zn():Pn()}),$n=()=>"Working…",Dn=()=>"Bezig…",Bn=()=>"Läuft…",Un=((n={},t={})=>{const e=t.locale??h();return e==="en"?$n():e==="nl"?Dn():Bn()}),Vn=()=>"Done",jn=()=>"Gelukt",Hn=()=>"Fertig",Gn=((n={},t={})=>{const e=t.locale??h();return e==="en"?Vn():e==="nl"?jn():Hn()}),qn=()=>"Failed",Zn=()=>"Mislukt",Wn=()=>"Fehlgeschlagen",Yn=((n={},t={})=>{const e=t.locale??h();return e==="en"?qn():e==="nl"?Zn():Wn()});const Xn={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":2,"stroke-linecap":"round","stroke-linejoin":"round"};const xt=([n,t,e])=>{const i=document.createElementNS("http://www.w3.org/2000/svg",n);return Object.keys(t).forEach(o=>{i.setAttribute(o,String(t[o]))}),e?.length&&e.forEach(o=>{const s=xt(o);i.appendChild(s)}),i},Tt=(n,t={})=>{const i={...Xn,...t};return xt(["svg",i,n])};const Kn=[["path",{d:"M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"}],["path",{d:"m3.3 7 8.7 5 8.7-5"}],["path",{d:"M12 22V12"}]];const Qn=[["path",{d:"M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z"}],["circle",{cx:"12",cy:"13",r:"3"}]];const Rt=[["path",{d:"m6 9 6 6 6-6"}]];const Jn=[["path",{d:"m15 18-6-6 6-6"}]];const ti=[["path",{d:"m9 18 6-6-6-6"}]];const ei=[["path",{d:"m18 15-6-6-6 6"}]];const ni=[["path",{d:"M15 3h6v6"}],["path",{d:"m21 3-7 7"}],["path",{d:"m3 21 7-7"}],["path",{d:"M9 21H3v-6"}]];const ii=[["path",{d:"m14 10 7-7"}],["path",{d:"M20 10h-6V4"}],["path",{d:"m3 21 7-7"}],["path",{d:"M4 14h6v6"}]];const oi=[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"}],["path",{d:"M3 3v5h5"}]];const si=[["path",{d:"M10 5H3"}],["path",{d:"M12 19H3"}],["path",{d:"M14 3v4"}],["path",{d:"M16 17v4"}],["path",{d:"M21 12h-9"}],["path",{d:"M21 19h-5"}],["path",{d:"M21 5h-7"}],["path",{d:"M8 10v4"}],["path",{d:"M8 12H3"}]];const ri=[["path",{d:"M18 6 6 18"}],["path",{d:"m6 6 12 12"}]];const ai=[["circle",{cx:"11",cy:"11",r:"8"}],["line",{x1:"21",x2:"16.65",y1:"21",y2:"16.65"}],["line",{x1:"11",x2:"11",y1:"8",y2:"14"}],["line",{x1:"8",x2:"14",y1:"11",y2:"11"}]];const li=[["circle",{cx:"11",cy:"11",r:"8"}],["line",{x1:"21",x2:"16.65",y1:"21",y2:"16.65"}],["line",{x1:"8",x2:"14",y1:"11",y2:"11"}]];function y(n,{size:t=20,strokeWidth:e=1.75}={}){return Tt(n,{width:t,height:t,"stroke-width":e})}const g={ar:n=>y(Kn,n),fullscreen:n=>y(ni,n),exitFullscreen:n=>y(ii,n),screenshot:n=>y(Qn,n),tiltUp:n=>y(ei,n),tiltDown:n=>y(Rt,n),rotateLeft:n=>y(Jn,n),rotateRight:n=>y(ti,n),zoomIn:n=>y(ai,n),zoomOut:n=>y(li,n),reset:n=>y(oi,n),configurator:n=>y(si,n),close:n=>y(ri,n)};class b{element;constructor({variant:t="default",size:e="default",label:i,icon:o,onClick:s,disabled:r=!1}={}){this.element=document.createElement("button"),this.element.className=`ui-btn ui-btn--${t} ui-btn--size-${e}`,i!==void 0&&(this.element.setAttribute("aria-label",i),this.element.title=i),o!==void 0?this.element.appendChild(o):i!==void 0&&(this.element.textContent=i),s&&this.element.addEventListener("click",s),this.element.disabled=r}setIcon(t){const e=this.element.querySelector("svg");e!==null?e.replaceWith(t):this.element.appendChild(t)}}const m={semantic:{error:"#dc2626"},neutral:{500:"#737373",600:"#525252",900:"#171717"},white:"#ffffff",black:"#000000"},a={0:"0",.5:"0.125rem",1:"0.25rem",1.5:"0.375rem",2:"0.5rem",3:"0.75rem",4:"1rem",5:"1.25rem",6:"1.5rem",8:"2rem",9:"2.25rem",24:"6rem"};class ci{element;constructor(){this.element=document.createElement("div"),Object.assign(this.element.style,{background:m.white,borderRadius:a[3],padding:a[6],boxShadow:`0 ${a[2]} ${a[8]} oklch(0% 0 0 / 20%)`,maxWidth:"20rem",width:"100%"})}}class ui{constructor(t={}){this.options=t,this.card=new ci,this.backdrop=this.createBackdrop(),this.backdrop.appendChild(this.card.element)}options;card;backdrop;keyHandler=null;open(){document.body.appendChild(this.backdrop),this.keyHandler=t=>{t.key==="Escape"&&this.close()},document.addEventListener("keydown",this.keyHandler)}close(){this.backdrop.remove(),this.keyHandler!==null&&(document.removeEventListener("keydown",this.keyHandler),this.keyHandler=null),this.options.onClose?.()}createBackdrop(){const t=document.createElement("div");return Object.assign(t.style,{position:"fixed",inset:a[0],background:"oklch(0% 0 0 / 50%)",zIndex:"9999",display:"flex",alignItems:"center",justifyContent:"center"}),t.addEventListener("click",e=>{e.target===t&&this.close()}),t}}class di{element;selectCallback=null;constructor(t,e,i){this.element=document.createElement("div"),this.element.className="ui-toggle-group";for(let o=0;o<t.length;o++){const s=t[o],r=document.createElement("button");r.className="ui-toggle-group-item",r.dataset.value=s,r.textContent=i?.[o]??s,r.dataset.state=s===e?"on":"off",r.setAttribute("aria-pressed",s===e?"true":"false"),r.addEventListener("click",()=>{this.selectCallback?.(s)}),this.element.appendChild(r)}}setSelected(t){for(const e of this.element.querySelectorAll(".ui-toggle-group-item")){const i=e.dataset.value===t;e.dataset.state=i?"on":"off",e.setAttribute("aria-pressed",i?"true":"false")}}onSelect(t){this.selectCallback=t}}class hi{element;select;constructor(t,e,i,o,s){this.select=document.createElement("select"),this.select.className="ui-native-select",this.select.dataset.name=t,this.select.setAttribute("aria-label",i);const r=document.createElement("option");r.value="",r.disabled=!0,r.textContent=i,this.select.appendChild(r);let l=!1;for(let u=0;u<e.length;u++){const p=e[u],v=document.createElement("option");v.value=p,v.textContent=s?.[u]??p,p===o&&(v.selected=!0,l=!0),this.select.appendChild(v)}l||(r.selected=!0);const d=Tt(Rt,{width:16,height:16,"stroke-width":2});d.classList.add("ui-native-select-icon"),this.element=document.createElement("div"),this.element.className="ui-native-select-wrap",this.element.appendChild(this.select),this.element.appendChild(d)}setSelected(t){this.select.value=t}onSelect(t){this.select.addEventListener("change",()=>{t(this.select.value)})}}const _={fontFamily:{sans:["Mona Sans","ui-sans-serif","system-ui","sans-serif","Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"]},fontSize:{xs:"0.75rem",sm:"0.875rem",base:"1rem",lg:"1.125rem"},fontWeight:{medium:"500",semibold:"600"}},mi=_.fontFamily.sans.join(", ");class pi{qrLib=null;dialog=null;async show(t){this.hide(),this.qrLib??=await Promise.resolve().then(()=>require("./browser-DfB_An57.cjs")).then(o=>o.browser);const e=await this.qrLib.toDataURL(t,{width:256,margin:4,errorCorrectionLevel:"M",color:{dark:m.black,light:m.white}});this.dialog=new ui({onClose:()=>{this.dialog=null}}),Object.assign(this.dialog.card.element.style,{display:"flex",flexDirection:"column",alignItems:"center",gap:a[3],fontFamily:mi}),this.dialog.card.element.appendChild(this.createText(xe(),{fontSize:_.fontSize.base,fontWeight:_.fontWeight.semibold,color:m.neutral[900]})),this.dialog.card.element.appendChild(this.createText(Ne(),{fontSize:_.fontSize.sm,color:m.neutral[600]})),this.dialog.card.element.appendChild(this.createQrImage(e)),this.dialog.card.element.appendChild(this.createText(ze(),{fontSize:_.fontSize.xs,color:m.neutral[500]}));const i=new b({variant:"outline",label:De(),onClick:()=>{this.hide()}});this.dialog.card.element.appendChild(i.element),this.dialog.open()}hide(){this.dialog?.close(),this.dialog=null}createText(t,e){const i=document.createElement("p");return i.textContent=t,Object.assign(i.style,{margin:"0",textAlign:"center",...e}),i}createQrImage(t){const e=document.createElement("img");return e.src=t,e.alt="QR code",Object.assign(e.style,{width:a[24],height:a[24],borderRadius:a[1]}),e}}const E=_.fontFamily.sans.join(", "),fi=`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c={HANDSHAKE:"handshake",SESSION:"session",MUTATION:"mutation",STATE:"state",LOADING_INDICATOR:"loading_indicator",CAMERA:"camera",SNAPSHOT:"snapshot",MAPPING:"mapping",AR_ACTIVATE:"ar_activate",FULLSCREEN:"fullscreen",CONFIG:"config",ANNOTATION_TOGGLE:"annotation_toggle",FOCUS:"focus",PRICING:"pricing"},W={FOCUS:"focus",UNFOCUS:"unfocus"},It={FOCUSED:"focused"},Nt={HIDDEN:"hidden"},Lt=new Set(Object.values(c));function Mt(n){if(typeof n!="object"||n===null)return!1;const t=n;return typeof t.target=="string"?!1:typeof t.type=="string"&&Lt.has(t.type)}function zt(n){const t=S(n);return t!==null&&t.type===c.HANDSHAKE}function Pt(n){const t=S(n);return t!==null&&t.type===c.SESSION&&typeof t.sessionId=="string"}function Ft(n){const t=S(n);return t!==null&&t.type===c.MUTATION&&Array.isArray(t.results)}function $t(n){const t=S(n);return t!==null&&t.type===c.SNAPSHOT&&("data"in t||"error"in t)}function Dt(n){const t=S(n);return t!==null&&t.type===c.CAMERA&&Array.isArray(t.transforms)}function Bt(n){const t=S(n);return t!==null&&t.type===c.MAPPING&&Array.isArray(t.attributes)}function Ut(n){const t=S(n);return t!==null&&t.type===c.LOADING_INDICATOR&&typeof t.progress=="number"}function Vt(n){const t=S(n);return t!==null&&t.type===c.CONFIG&&typeof t.viewerSettings=="object"}function jt(n){const t=S(n);return t!==null&&t.type===c.FOCUS&&typeof t.state=="string"}function Ht(n){const t=S(n);return t!==null&&t.type===c.PRICING&&typeof t.pricing=="object"&&t.pricing!==null}function S(n){return typeof n!="object"||n===null?null:n}class Y{constructor(t){this.processor=t}processor;pending=[];isReady=!1;enqueue(t){if(this.isReady){this.processor(t);return}this.pending.push(t)}markReady(){if(this.isReady||(this.isReady=!0,this.pending.length===0))return;const t=[...this.pending];this.pending.length=0;for(const e of t)this.processor(e)}get ready(){return this.isReady}get pendingCount(){return this.pending.length}hasPending(t){return this.pending.some(e=>e.type===t)}clear(){this.pending.length=0}}class Gt{constructor(t,e){this.getTarget=t,this.sourceId=`vd-${Math.random().toString(36).slice(2,8)}`,this.targetOrigin=e?.targetOrigin??"*",this.isValid=e?.isValid??Mt,this.publisher=new Y(i=>this.post(i)),this.consumer=new Y(i=>this.routeToHandler(i)),this.shouldBuffer=e?.shouldBuffer??null,e?.bufferIncoming!==!0&&this.consumer.markReady()}getTarget;handlers=new Map;publisher;consumer;shouldBuffer;listener=null;sourceId;targetOrigin;isValid;on(t,e){this.handlers.set(t,e)}off(t){this.handlers.delete(t)}setTargetOrigin(t){this.targetOrigin=t}send(t){this.publisher.enqueue(t)}markReady(){this.publisher.markReady()}markConsumerReady(){this.consumer.markReady()}consumerHasPending(t){return this.consumer.hasPending(t)}start(){this.listener===null&&(this.listener=t=>{const{data:e}=t;if(!this.isValid(e)||e._source===this.sourceId)return;const i=this.getTarget();if(i!==null&&t.source!==null&&t.source!==i)return;const o=e;if(this.shouldBuffer!==null&&!this.shouldBuffer(o)){this.routeToHandler(o);return}this.consumer.enqueue(o)},window.addEventListener("message",this.listener))}destroy(){this.listener!==null&&(window.removeEventListener("message",this.listener),this.listener=null),this.publisher.clear(),this.consumer.clear(),this.handlers.clear()}get ready(){return this.publisher.ready}get pendingCount(){return this.publisher.pendingCount}post(t){const e=this.getTarget();e!==null&&e.postMessage({...t,_source:this.sourceId},this.targetOrigin)}routeToHandler(t){const e=this.handlers.get(t.type);if(e===void 0)return;const i=e(t);i instanceof Promise&&i.catch(o=>{const s=o instanceof Error?o.message:String(o);console.error(`Virtualdisplay: error handling ${t.type}: ${s}`)})}}class g{element;constructor({variant:t="default",size:e="default",label:i,icon:o,onClick:s,disabled:r=!1}={}){this.element=document.createElement("button"),this.element.className=`ui-btn ui-btn--${t} ui-btn--size-${e}`,i!==void 0&&(this.element.setAttribute("aria-label",i),this.element.title=i),o!==void 0?this.element.appendChild(o):i!==void 0&&(this.element.textContent=i),s&&this.element.addEventListener("click",s),this.element.disabled=r}setIcon(t){const e=this.element.querySelector("svg");e!==null?e.replaceWith(t):this.element.appendChild(t)}}const qt={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":2,"stroke-linecap":"round","stroke-linejoin":"round"};const at=([n,t,e])=>{const i=document.createElementNS("http://www.w3.org/2000/svg",n);return Object.keys(t).forEach(o=>{i.setAttribute(o,String(t[o]))}),e?.length&&e.forEach(o=>{const s=at(o);i.appendChild(s)}),i},lt=(n,t={})=>{const i={...qt,...t};return at(["svg",i,n])};const Zt=[["path",{d:"M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"}],["path",{d:"m3.3 7 8.7 5 8.7-5"}],["path",{d:"M12 22V12"}]];const Wt=[["path",{d:"M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z"}],["circle",{cx:"12",cy:"13",r:"3"}]];const ct=[["path",{d:"m6 9 6 6 6-6"}]];const Yt=[["path",{d:"m15 18-6-6 6-6"}]];const Xt=[["path",{d:"m9 18 6-6-6-6"}]];const Kt=[["path",{d:"m18 15-6-6-6 6"}]];const Qt=[["path",{d:"M15 3h6v6"}],["path",{d:"m21 3-7 7"}],["path",{d:"m3 21 7-7"}],["path",{d:"M9 21H3v-6"}]];const Jt=[["path",{d:"m14 10 7-7"}],["path",{d:"M20 10h-6V4"}],["path",{d:"m3 21 7-7"}],["path",{d:"M4 14h6v6"}]];const te=[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"}],["path",{d:"M3 3v5h5"}]];const ee=[["path",{d:"M10 5H3"}],["path",{d:"M12 19H3"}],["path",{d:"M14 3v4"}],["path",{d:"M16 17v4"}],["path",{d:"M21 12h-9"}],["path",{d:"M21 19h-5"}],["path",{d:"M21 5h-7"}],["path",{d:"M8 10v4"}],["path",{d:"M8 12H3"}]];const ne=[["path",{d:"M18 6 6 18"}],["path",{d:"m6 6 12 12"}]];const ie=[["circle",{cx:"11",cy:"11",r:"8"}],["line",{x1:"21",x2:"16.65",y1:"21",y2:"16.65"}],["line",{x1:"11",x2:"11",y1:"8",y2:"14"}],["line",{x1:"8",x2:"14",y1:"11",y2:"11"}]];const oe=[["circle",{cx:"11",cy:"11",r:"8"}],["line",{x1:"21",x2:"16.65",y1:"21",y2:"16.65"}],["line",{x1:"8",x2:"14",y1:"11",y2:"11"}]],m={semantic:{error:"#dc2626"},neutral:{500:"#737373",600:"#525252",900:"#171717"},white:"#ffffff",black:"#000000"},a={0:"0",.5:"0.125rem",1:"0.25rem",1.5:"0.375rem",2:"0.5rem",3:"0.75rem",4:"1rem",5:"1.25rem",6:"1.5rem",8:"2rem",9:"2.25rem",24:"6rem"};class se{element;constructor(){this.element=document.createElement("div"),Object.assign(this.element.style,{background:m.white,borderRadius:a[3],padding:a[6],boxShadow:`0 ${a[2]} ${a[8]} oklch(0% 0 0 / 20%)`,maxWidth:"20rem",width:"100%"})}}class re{constructor(t={}){this.options=t,this.card=new se,this.backdrop=this.createBackdrop(),this.backdrop.appendChild(this.card.element)}options;card;backdrop;keyHandler=null;open(){document.body.appendChild(this.backdrop),this.keyHandler=t=>{t.key==="Escape"&&this.close()},document.addEventListener("keydown",this.keyHandler)}close(){this.backdrop.remove(),this.keyHandler!==null&&(document.removeEventListener("keydown",this.keyHandler),this.keyHandler=null),this.options.onClose?.()}createBackdrop(){const t=document.createElement("div");return Object.assign(t.style,{position:"fixed",inset:a[0],background:"oklch(0% 0 0 / 50%)",zIndex:"9999",display:"flex",alignItems:"center",justifyContent:"center"}),t.addEventListener("click",e=>{e.target===t&&this.close()}),t}}class ae{element;selectCallback=null;constructor(t,e,i){this.element=document.createElement("div"),this.element.className="ui-toggle-group";for(let o=0;o<t.length;o++){const s=t[o],r=document.createElement("button");r.className="ui-toggle-group-item",r.dataset.value=s,r.textContent=i?.[o]??s,r.dataset.state=s===e?"on":"off",r.setAttribute("aria-pressed",s===e?"true":"false"),r.addEventListener("click",()=>{this.selectCallback?.(s)}),this.element.appendChild(r)}}setSelected(t){for(const e of this.element.querySelectorAll(".ui-toggle-group-item")){const i=e.dataset.value===t;e.dataset.state=i?"on":"off",e.setAttribute("aria-pressed",i?"true":"false")}}onSelect(t){this.selectCallback=t}}class le{element;select;constructor(t,e,i,o,s){this.select=document.createElement("select"),this.select.className="ui-native-select",this.select.dataset.name=t,this.select.setAttribute("aria-label",i);const r=document.createElement("option");r.value="",r.disabled=!0,r.textContent=i,this.select.appendChild(r);let l=!1;for(let u=0;u<e.length;u++){const p=e[u],v=document.createElement("option");v.value=p,v.textContent=s?.[u]??p,p===o&&(v.selected=!0,l=!0),this.select.appendChild(v)}l||(r.selected=!0);const d=lt(ct,{width:16,height:16,"stroke-width":2});d.classList.add("ui-native-select-icon"),this.element=document.createElement("div"),this.element.className="ui-native-select-wrap",this.element.appendChild(this.select),this.element.appendChild(d)}setSelected(t){this.select.value=t}onSelect(t){this.select.addEventListener("change",()=>{t(this.select.value)})}}const ce={},ue="en",ut=["en","nl","de"],q=["baseLocale"],X=[];let K,Q;function de(n){if(X.length===0)return;const t=typeof n=="string"?n:n.href;if(K===t)return Q;const e=new URL(t,"http://dummy.com");let i;for(const o of X)if(new ce(o.match,e.href).exec(e.href)){i=o;break}return K=t,Q=i,i}function dt(n){const t=de(n);return t&&t.exclude!==!0&&Array.isArray(t.strategy)?t.strategy:q}const G=typeof window>"u";globalThis.__paraglide=globalThis.__paraglide??{};globalThis.__paraglide.ssr=globalThis.__paraglide.ssr??{};let J=!1,h=()=>{let n=q;!G&&typeof window<"u"&&window.location?.href&&(n=dt(window.location.href));const t=he(n);if(t)return J||(J=!0,ht(t,{reload:!1})),t;throw new Error("No locale found. Read the docs https://paraglidejs.com/errors#no-locale-found")};function he(n,t){let e;for(const i of n){if(i==="baseLocale")e=ue;else if(pt(i)&&I.has(i)){const s=I.get(i);if(s){const r=s.getLocale();if(r instanceof Promise)continue;if(r!==void 0)return pe(r)}}const o=mt(e);if(o)return o}}const me=n=>{window.location.reload()};let ht=(n,t)=>{const e={reload:!0,...t};let i;try{i=h()}catch{}const o=[];let s=q;!G&&typeof window<"u"&&window.location?.href&&(s=dt(window.location.href));for(const l of s)if(l!=="baseLocale"&&pt(l)&&I.has(l)){const d=I.get(l);if(d){let u=d.setLocale(n);u instanceof Promise&&(u=u.catch(p=>{throw new Error(`Custom strategy "${l}" setLocale failed.`,{cause:p})}),o.push(u))}}const r=()=>{!G&&e.reload&&window.location&&n!==i&&me()};if(o.length)return Promise.all(o).then(()=>{r()});r()};function mt(n){if(typeof n!="string")return;const t=n.toLowerCase();for(const e of ut)if(e.toLowerCase()===t)return e}function pe(n){const t=mt(n);if(t)return t;throw new Error(`Invalid locale: ${n}. Expected one of: ${ut.join(", ")}`)}const I=new Map;function pt(n){return typeof n=="string"&&/^custom-[A-Za-z0-9_-]+$/.test(n)}const fe=()=>"Activate AR",ge=()=>"AR activeren",be=()=>"AR aktivieren",ve=((n={},t={})=>{const e=t.locale??h();return e==="en"?fe():e==="nl"?ge():be()}),ye=()=>"Scan to view in AR",_e=()=>"Scan om in AR te bekijken",we=()=>"Scannen für AR-Ansicht",Ce=((n={},t={})=>{const e=t.locale??h();return e==="en"?ye():e==="nl"?_e():we()}),Se=()=>"Use your smartphone camera to scan this QR code",ke=()=>"Gebruik de camera van je smartphone om deze QR-code te scannen",Ee=()=>"Verwende die Kamera deines Smartphones, um diesen QR-Code zu scannen",Ae=((n={},t={})=>{const e=t.locale??h();return e==="en"?Se():e==="nl"?ke():Ee()}),xe=()=>"Your phone will open the 3D model in AR mode.",Te=()=>"Je telefoon opent het 3D-model in AR-modus.",Re=()=>"Dein Telefon öffnet das 3D-Modell im AR-Modus.",Oe=((n={},t={})=>{const e=t.locale??h();return e==="en"?xe():e==="nl"?Te():Re()}),Ie=()=>"Close",Ne=()=>"Sluiten",Le=()=>"Schließen",Me=((n={},t={})=>{const e=t.locale??h();return e==="en"?Ie():e==="nl"?Ne():Le()}),ze=()=>"Fullscreen",Pe=()=>"Volledig scherm",Fe=()=>"Vollbild",$e=((n={},t={})=>{const e=t.locale??h();return e==="en"?ze():e==="nl"?Pe():Fe()}),De=()=>"Downloading",Be=()=>"Downloaden",Ue=()=>"Herunterladen",ft=((n={},t={})=>{const e=t.locale??h();return e==="en"?De():e==="nl"?Be():Ue()}),Ve=()=>"Rendering",je=()=>"Renderen",He=()=>"Rendern",Ge=((n={},t={})=>{const e=t.locale??h();return e==="en"?Ve():e==="nl"?je():He()}),qe=()=>"Screenshot",Ze=()=>"Screenshot",We=()=>"Screenshot",Ye=((n={},t={})=>{const e=t.locale??h();return e==="en"?qe():e==="nl"?Ze():We()}),Xe=()=>"Configure",Ke=()=>"Configureren",Qe=()=>"Konfigurieren",Je=((n={},t={})=>{const e=t.locale??h();return e==="en"?Xe():e==="nl"?Ke():Qe()}),tn=()=>"Close",en=()=>"Sluiten",nn=()=>"Schließen",on=((n={},t={})=>{const e=t.locale??h();return e==="en"?tn():e==="nl"?en():nn()}),sn=()=>"Reset camera",rn=()=>"Camera resetten",an=()=>"Kamera zurücksetzen",ln=((n={},t={})=>{const e=t.locale??h();return e==="en"?sn():e==="nl"?rn():an()}),cn=()=>"Zoom in",un=()=>"Inzoomen",dn=()=>"Hineinzoomen",hn=((n={},t={})=>{const e=t.locale??h();return e==="en"?cn():e==="nl"?un():dn()}),mn=()=>"Zoom out",pn=()=>"Uitzoomen",fn=()=>"Herauszoomen",gn=((n={},t={})=>{const e=t.locale??h();return e==="en"?mn():e==="nl"?pn():fn()}),bn=()=>"Rotate left",vn=()=>"Naar links draaien",yn=()=>"Nach links drehen",_n=((n={},t={})=>{const e=t.locale??h();return e==="en"?bn():e==="nl"?vn():yn()}),wn=()=>"Rotate right",Cn=()=>"Naar rechts draaien",Sn=()=>"Nach rechts drehen",kn=((n={},t={})=>{const e=t.locale??h();return e==="en"?wn():e==="nl"?Cn():Sn()}),En=()=>"Tilt up",An=()=>"Omhoog kantelen",xn=()=>"Nach oben kippen",Tn=((n={},t={})=>{const e=t.locale??h();return e==="en"?En():e==="nl"?An():xn()}),Rn=()=>"Tilt down",On=()=>"Omlaag kantelen",In=()=>"Nach unten kippen",Nn=((n={},t={})=>{const e=t.locale??h();return e==="en"?Rn():e==="nl"?On():In()}),Ln=()=>"Working…",Mn=()=>"Bezig…",zn=()=>"Läuft…",Pn=((n={},t={})=>{const e=t.locale??h();return e==="en"?Ln():e==="nl"?Mn():zn()}),Fn=()=>"Done",$n=()=>"Gelukt",Dn=()=>"Fertig",Bn=((n={},t={})=>{const e=t.locale??h();return e==="en"?Fn():e==="nl"?$n():Dn()}),Un=()=>"Failed",Vn=()=>"Mislukt",jn=()=>"Fehlgeschlagen",Hn=((n={},t={})=>{const e=t.locale??h();return e==="en"?Un():e==="nl"?Vn():jn()}),_={fontFamily:{sans:["Mona Sans","ui-sans-serif","system-ui","sans-serif","Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"]},fontSize:{xs:"0.75rem",sm:"0.875rem",base:"1rem",lg:"1.125rem"},fontWeight:{medium:"500",semibold:"600"}},Gn=_.fontFamily.sans.join(", ");class qn{qrLib=null;dialog=null;async show(t){this.hide(),this.qrLib??=await Promise.resolve().then(()=>require("./browser-DfB_An57.cjs")).then(o=>o.browser);const e=await this.qrLib.toDataURL(t,{width:256,margin:4,errorCorrectionLevel:"M",color:{dark:m.black,light:m.white}});this.dialog=new re({onClose:()=>{this.dialog=null}}),Object.assign(this.dialog.card.element.style,{display:"flex",flexDirection:"column",alignItems:"center",gap:a[3],fontFamily:Gn}),this.dialog.card.element.appendChild(this.createText(Ce(),{fontSize:_.fontSize.base,fontWeight:_.fontWeight.semibold,color:m.neutral[900]})),this.dialog.card.element.appendChild(this.createText(Ae(),{fontSize:_.fontSize.sm,color:m.neutral[600]})),this.dialog.card.element.appendChild(this.createQrImage(e)),this.dialog.card.element.appendChild(this.createText(Oe(),{fontSize:_.fontSize.xs,color:m.neutral[500]}));const i=new g({variant:"outline",label:Me(),onClick:()=>{this.hide()}});this.dialog.card.element.appendChild(i.element),this.dialog.open()}hide(){this.dialog?.close(),this.dialog=null}createText(t,e){const i=document.createElement("p");return i.textContent=t,Object.assign(i.style,{margin:"0",textAlign:"center",...e}),i}createQrImage(t){const e=document.createElement("img");return e.src=t,e.alt="QR code",Object.assign(e.style,{width:a[24],height:a[24],borderRadius:a[1]}),e}}const A=_.fontFamily.sans.join(", "),Zn=`
2
2
  --primary: oklch(5% 0 0);
3
3
  --primary-foreground: oklch(100% 0 0);
4
4
  --secondary: oklch(92% 0 0);
@@ -11,8 +11,8 @@
11
11
  --accent: oklch(92% 0 0);
12
12
  --accent-foreground: oklch(5% 0 0);
13
13
  --muted-foreground: oklch(44% 0 0);
14
- `,gi=`
15
- :root { ${fi} }
14
+ `,Wn=`
15
+ :root { ${Zn} }
16
16
 
17
17
  /* ── Button ──────────────────────────────────────────────── */
18
18
  .ui-btn {
@@ -22,7 +22,7 @@
22
22
  gap: 0.5rem;
23
23
  border: 1px solid transparent;
24
24
  border-radius: var(--radius);
25
- font-family: ${E};
25
+ font-family: ${A};
26
26
  font-size: 0.875rem;
27
27
  font-weight: 600;
28
28
  white-space: nowrap;
@@ -79,7 +79,7 @@
79
79
  border-radius: var(--radius);
80
80
  background: var(--background);
81
81
  color: var(--foreground);
82
- font-family: ${E};
82
+ font-family: ${A};
83
83
  font-size: 0.875rem;
84
84
  font-weight: 600;
85
85
  cursor: pointer;
@@ -118,7 +118,7 @@
118
118
  background: var(--background);
119
119
  appearance: none;
120
120
  color: var(--foreground);
121
- font-family: ${E};
121
+ font-family: ${A};
122
122
  font-size: 0.875rem;
123
123
  font-weight: 400;
124
124
  cursor: pointer;
@@ -166,7 +166,7 @@
166
166
  border: 2px solid oklch(100% 0 0);
167
167
  background: var(--primary);
168
168
  color: var(--primary-foreground);
169
- font-family: ${E};
169
+ font-family: ${A};
170
170
  font-size: 0.8125rem;
171
171
  font-weight: 600;
172
172
  cursor: pointer;
@@ -240,7 +240,7 @@
240
240
  }
241
241
 
242
242
  .vd-annotation-popup-title {
243
- font-family: ${E};
243
+ font-family: ${A};
244
244
  font-size: 0.875rem;
245
245
  font-weight: 600;
246
246
  line-height: 1.25rem;
@@ -249,19 +249,19 @@
249
249
  }
250
250
 
251
251
  .vd-annotation-popup-description {
252
- font-family: ${E};
252
+ font-family: ${A};
253
253
  font-size: 0.8125rem;
254
254
  font-weight: 400;
255
255
  line-height: 1.125rem;
256
256
  color: var(--muted-foreground);
257
257
  margin-block-start: 0.25rem;
258
258
  }
259
- `;let it=!1;function bi(){if(it||typeof document>"u")return;it=!0;const n=document.createElement("style");n.id="vd-ui-vanilla",n.textContent=gi,document.head.appendChild(n)}function ot(n){const t=Math.max(0,Math.min(1,n));return t*t*(3-2*t)}function vi(n,t,e,i,o,s){const[r,l,d]=n,u=Math.cos(t),p=Math.sin(t),v=u*r+p*d,A=-p*r+u*d,S=Math.cos(e),w=Math.sin(e),R=S*l-w*A,L=w*l+S*A,W=.55;return[i+v*s*W,o-R*s*W,L]}function yi(n,t,e){n.beginPath(),n.moveTo(t[0],t[1]),n.lineTo(e[0],e[1]),n.strokeStyle="#000",n.lineWidth=2,n.stroke()}function _i(n,t,e,i,o){const s=t(e),r=t(i),l=[s[0]+(r[0]-s[0])*o,s[1]+(r[1]-s[1])*o,s[2]];yi(n,s,l)}const M=[-1,-1,1],z=[1,-1,1],P=[1,-1,-1],F=[-1,-1,-1],$=[-1,1,1],D=[1,1,1],B=[1,1,-1],U=[-1,1,-1],st=[[M,z],[z,P],[P,F],[F,M],[M,$],[z,D],[P,B],[F,U],[$,D],[D,B],[B,U],[U,$]],Ci=400,rt='-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif';function wi(){const n=document.createElement("div");Object.assign(n.style,{position:"absolute",inset:"0",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",background:"#fff",zIndex:"20",opacity:"0",transition:"opacity 0.3s ease-in-out"});const t=document.createElement("canvas");Object.assign(t.style,{width:"100%",height:"100%",position:"absolute",inset:"0"});const e=document.createElement("div");Object.assign(e.style,{position:"absolute",top:"56%",left:"0",right:"0",textAlign:"center",pointerEvents:"none"});const i=document.createElement("span");Object.assign(i.style,{fontSize:"13px",fontWeight:"400",color:"#000",fontVariantNumeric:"tabular-nums",fontFamily:rt});const o=document.createElement("span");return Object.assign(o.style,{fontSize:"13px",color:"#000",fontFamily:rt}),o.textContent=Et(),e.appendChild(i),e.appendChild(o),n.appendChild(t),n.appendChild(e),{overlay:n,canvas:t,pctEl:i,phaseEl:o}}class ki{overlay;canvas;ctx;pctEl;phaseEl;animationId=null;showTimerId=null;startTime;hidden=!1;visible=!1;constructor(t,e={}){this.startTime=performance.now();const i=wi();this.overlay=i.overlay,this.canvas=i.canvas,this.pctEl=i.pctEl,this.phaseEl=i.phaseEl,t.appendChild(this.overlay),this.ctx=this.canvas.getContext("2d"),this.ctx!==null&&(this.sizeCanvas(),this.tick());const o=e.showDelay??Ci;this.showTimerId=setTimeout(()=>{this.reveal()},o)}get loadingTexts(){return{downloading:Et(),rendering:Xe()}}updateProgress(t,e){this.hidden||(this.pctEl.textContent=`${Math.round(t)}%`,this.phaseEl.textContent=e!==""?` · ${e}`:"")}showError(t){if(this.hidden=!1,this.animationId!==null&&(cancelAnimationFrame(this.animationId),this.animationId=null),this.ctx!==null){const e=Math.min(devicePixelRatio,2),i=this.canvas.width/e,o=this.canvas.height/e;this.ctx.fillStyle="#fff",this.ctx.fillRect(0,0,i*e,o*e)}this.pctEl.textContent="",this.phaseEl.textContent=t,this.phaseEl.style.color="#b91c1c",this.reveal()}hide(){if(!this.hidden){if(this.hidden=!0,this.cancelShowTimer(),!this.visible){this.destroy();return}this.overlay.style.opacity="0",this.overlay.addEventListener("transitionend",()=>{this.destroy()},{once:!0}),setTimeout(()=>{this.destroy()},500)}}destroy(){this.cancelShowTimer(),this.animationId!==null&&(cancelAnimationFrame(this.animationId),this.animationId=null),this.overlay.remove()}reveal(){this.hidden||this.visible||(this.visible=!0,this.overlay.style.opacity="1")}cancelShowTimer(){this.showTimerId!==null&&(clearTimeout(this.showTimerId),this.showTimerId=null)}sizeCanvas(){if(this.ctx===null)return;const t=Math.min(devicePixelRatio,2),e=this.overlay.clientWidth||440,i=this.overlay.clientHeight||360;this.canvas.width=e*t,this.canvas.height=i*t,this.ctx.scale(t,t),this.ctx.lineCap="round",this.ctx.lineJoin="round"}tick=()=>{this.hidden||(this.drawFrame(),this.animationId=requestAnimationFrame(this.tick))};drawFrame(){if(this.ctx===null)return;const t=this.canvas.width/Math.min(devicePixelRatio,2),e=this.canvas.height/Math.min(devicePixelRatio,2),i=(performance.now()-this.startTime)/1e3;this.ctx.fillStyle="#fff",this.ctx.fillRect(0,0,t,e);const o=t/2,s=e*.44,r=Math.min(t,e)*.08,l=.785,d=.615,u=w=>vi(w,l,d,o,s,r),p=6,v=i%p/p,A=st.length;let S;v<.35?S=ot(v/.35)*A:v<.55?S=A:v<.9?S=(1-ot((v-.55)/.35))*A:S=0,this.ctx.shadowBlur=5,this.ctx.shadowColor="rgba(30,30,30,0.08)";for(let w=0;w<A&&!(w>=S);w++){const R=st[w];if(R===void 0)continue;const L=Math.min(1,S-w);_i(this.ctx,u,R[0],R[1],L)}this.ctx.shadowBlur=0}}class Si{constructor(t){this.options=t,this.element=document.createElement("div"),Object.assign(this.element.style,{display:"flex",gap:"0.375rem"}),this.onFullscreenChange=()=>{this.setFullscreenIcon(document.fullscreenElement!==null)},document.addEventListener("fullscreenchange",this.onFullscreenChange)}options;element;arBtn=null;fullscreenBtn=null;onFullscreenChange;setFullscreenIcon(t){this.fullscreenBtn!==null&&this.fullscreenBtn.setIcon(t?g.exitFullscreen():g.fullscreen())}syncButton(t,e,i){if(e&&t===null){const o=i();return this.element.appendChild(o.element),o}return!e&&t!==null?(t.element.remove(),null):t}applySettings(t){this.arBtn=this.syncButton(this.arBtn,t.ar!==!1&&this.options.onAr!==void 0,()=>new b({variant:"outline",size:"icon",label:ke(),icon:g.ar(),onClick:()=>{this.options.onAr?.()}})),this.fullscreenBtn=this.syncButton(this.fullscreenBtn,t.fullscreen!==!1&&this.options.onFullscreen!==void 0,()=>new b({variant:"outline",size:"icon",label:je(),icon:g.fullscreen(),onClick:()=>{this.options.onFullscreen?.()}}))}destroy(){document.removeEventListener("fullscreenchange",this.onFullscreenChange)}}const x=.5;class I{element;constructor(t,e){this.element=Object.assign(document.createElement("div"),{className:"vd-camera-controls"});const i={targetRotation:e.rotation,targetTilt:e.tilt,targetZoom:e.zoom,thetaOffset:0},o=Ai(t,e,i);e.onChange(s=>{i.targetRotation=s.rotation-i.thetaOffset,i.targetTilt=s.tilt,i.targetZoom=s.zoom,Ei(o,e,s)}),this.element.appendChild(I.buildZoom(o.zoomOut,o.zoomIn)),this.element.appendChild(I.buildDpad(o.tiltUp,o.rotateLeft,o.reset,o.rotateRight,o.tiltDown))}static buildZoom(t,e){const i=document.createElement("div");return i.className="vd-zoom",i.appendChild(t.element),i.appendChild(e.element),i}static buildDpad(t,e,i,o,s){const r=document.createElement("div");r.className="vd-dpad";for(const[l,d]of[[t,"up"],[e,"left"],[i,"center"],[o,"right"],[s,"down"]])l.element.classList.add(`vd-dpad-${d}`),r.appendChild(l.element);return r}}function Ai(n,t,e){const i=r=>Math.max(t.limits?.minZoom??1,Math.min(t.limits?.maxZoom??1/0,r)),o=r=>{const l=t.limits?.minRotate,d=t.limits?.maxRotate;return l!==void 0||d!==void 0?Math.max(l??-1/0,Math.min(d??1/0,r)):r},s=r=>{const l=t.limits?.minTilt,d=t.limits?.maxTilt;if(l!==void 0||d!==void 0){e.targetTilt=Math.max(l??0,Math.min(d??180,e.targetTilt+r)),n.tilt(e.targetTilt).set();return}const u=e.targetTilt+r;u>180||u<0?(e.targetTilt=u>180?360-u:-u,e.thetaOffset=(e.thetaOffset+180)%360,n.tilt(e.targetTilt).rotate(e.targetRotation+e.thetaOffset).set()):(e.targetTilt=u,n.tilt(e.targetTilt).set())};return{zoomOut:new b({variant:"outline",size:"icon",label:Cn(),icon:g.zoomOut(),onClick:()=>{e.targetZoom=i(e.targetZoom-10),n.zoom(e.targetZoom).set()}}),zoomIn:new b({variant:"outline",size:"icon",label:bn(),icon:g.zoomIn(),onClick:()=>{e.targetZoom=i(e.targetZoom+10),n.zoom(e.targetZoom).set()}}),tiltUp:new b({variant:"outline",size:"icon",label:Ln(),icon:g.tiltUp(),onClick:()=>{s(-15)}}),rotateLeft:new b({variant:"outline",size:"icon",label:An(),icon:g.rotateLeft(),onClick:()=>{e.targetRotation=o(e.targetRotation-15),n.rotate(e.targetRotation+e.thetaOffset).set()}}),reset:new b({variant:"outline",size:"icon",label:mn(),icon:g.reset(),onClick:()=>{e.thetaOffset=0,n.reset()}}),rotateRight:new b({variant:"outline",size:"icon",label:Rn(),icon:g.rotateRight(),onClick:()=>{e.targetRotation=o(e.targetRotation+15),n.rotate(e.targetRotation+e.thetaOffset).set()}}),tiltDown:new b({variant:"outline",size:"icon",label:Fn(),icon:g.tiltDown(),onClick:()=>{s(15)}})}}function Ei(n,t,e){const i=t.limits;i!==void 0&&(n.zoomOut.element.disabled=i.minZoom!==void 0&&e.zoom<=i.minZoom+x,n.zoomIn.element.disabled=i.maxZoom!==void 0&&e.zoom>=i.maxZoom-x,n.tiltUp.element.disabled=i.minTilt!==void 0&&e.tilt<=i.minTilt+x,n.tiltDown.element.disabled=i.maxTilt!==void 0&&e.tilt>=i.maxTilt-x,n.rotateLeft.element.disabled=i.minRotate!==void 0&&e.rotation<=i.minRotate+x,n.rotateRight.element.disabled=i.maxRotate!==void 0&&e.rotation>=i.maxRotate-x)}const xi=5;let Ti=0;function V(n){const t=n.replace(/([A-Z])/g," $1").trim();return t.charAt(0).toUpperCase()+t.slice(1).toLowerCase()}function Ri(n,t,e,i,o){const s=document.createElement("div");s.className="vd-attribute",s.dataset.name=n.name;const r=document.createElement("span");r.className="vd-attribute-label",r.textContent=V(n.name),r.id=`vd-attribute-label-${Ti++}`,s.appendChild(r),s.setAttribute("role","group"),s.setAttribute("aria-labelledby",r.id);const l=n.values.find(p=>t.getValue(n.name,p)?.isSelected===!0),d=n.values.map(V),u=n.values.length<=xi?new di(n.values,l,d):new hi(n.name,n.values,V(n.name),l,d);return u.onSelect(p=>{e.dispatch(T.SELECT,{attribute:n.name,value:p},!0).defaultPrevented||i(n.name,p)}),o(n.name,p=>{u.setSelected(p.value),e.dispatch(T.SELECTED,{attribute:n.name,value:p.value})}),s.appendChild(u.element),s}const Oi=80,Ni=2500;class Ii{constructor(t,e=Ni){this.configuration=t,this.resetMs=e,this.element=document.createElement("div"),this.element.className="vd-commerce vd-hidden";const i=document.createElement("div");i.className="vd-commerce-price",this.priceEl=document.createElement("span"),this.priceEl.className="vd-price",this.vatEl=document.createElement("span"),this.vatEl.className="vd-vat",i.append(this.priceEl,this.vatEl),this.button=new b({variant:"default",onClick:()=>{this.handleSubmit()}}),this.button.element.classList.add("vd-cta","vd-hidden"),this.element.append(i,this.button.element),this.unsubscribe=this.configuration.onRender(()=>{this.update()}),this.update()}configuration;resetMs;element;priceEl;vatEl;button;unsubscribe;state="idle";resetTimer;update(){this.renderPrice(this.configuration.current),this.renderButton();const t=this.configuration.current!==void 0||this.configuration.submitEnabled;this.element.classList.toggle("vd-hidden",!t)}destroy(){this.unsubscribe(),this.resetTimer!==void 0&&clearTimeout(this.resetTimer),this.element.remove()}renderPrice(t){if(t===void 0){this.priceEl.textContent="",this.vatEl.textContent="";return}this.priceEl.textContent=Li(t.price,t.currency),this.vatEl.textContent=at(this.configuration.vatDisplay)}renderButton(){const t=this.configuration.submitEnabled;this.button.element.classList.toggle("vd-hidden",!t),t&&this.state==="idle"&&this.setButtonText(at(this.configuration.buttonLabel))}async handleSubmit(){if(this.state!=="busy"){this.setState("busy",Un());try{await this.configuration.submit(),this.setState("success",Gn())}catch{this.setState("failed",Yn())}this.scheduleReset()}}scheduleReset(){this.resetTimer!==void 0&&clearTimeout(this.resetTimer),this.resetTimer=setTimeout(()=>{this.state="idle",this.update()},this.resetMs)}setState(t,e){this.state=t,this.element.dataset.submit=t,this.button.element.disabled=t==="busy",this.setButtonText(e)}setButtonText(t){this.button.element.textContent=t,this.button.element.setAttribute("aria-label",t)}}function at(n){return(n??"").slice(0,Oi)}function Li(n,t){try{const e=new Intl.NumberFormat(h(),{style:"currency",currency:t}),i=e.resolvedOptions().maximumFractionDigits??2;return e.format(n/10**i)}catch{return`${t} ${(n/100).toFixed(2)}`}}class Ot{slot=null;panel=null;attach(t,e){this.panel=e,e.style.display="none",this.slot=document.createElement("div"),this.slot.className="vd-slot-bottom-left",this.slot.appendChild(e),t.appendChild(this.slot)}setVisible(t){this.panel!==null&&(this.panel.style.display=t?"flex":"none")}destroy(){this.slot?.remove(),this.slot=null,this.panel=null}}const Mi=572;class zi{element=null;body=null;openButton=null;closeButton=null;container=null;observer=null;collapsible=!1;expanded=!0;visible=!1;attach(t,e){this.container=t,e.classList.add("vd-attributes-sidebar"),this.closeButton=new b({variant:"ghost",size:"icon-sm",label:cn(),icon:g.close({size:18}),onClick:()=>{this.expanded=!1,this.render()}});const i=document.createElement("div");i.className="vd-sidebar-header",i.appendChild(this.closeButton.element),this.body=document.createElement("div"),this.body.className="vd-sidebar-body",this.body.appendChild(e),this.element=document.createElement("div"),this.element.className="vd-sidebar vd-hidden",this.element.append(i,this.body),t.appendChild(this.element),this.openButton=new b({variant:"outline",size:"default",label:sn(),icon:g.configurator({size:18}),onClick:()=>{this.expanded=!0,this.render()}}),this.openButton.element.classList.add("vd-configurator-toggle","vd-hidden"),t.appendChild(this.openButton.element),this.observe()}setVisible(t){this.visible=t,this.render()}destroy(){this.observer?.disconnect(),this.observer=null,this.openButton?.element.remove(),this.element?.remove(),this.container?.classList.remove("vd-layout-sidebar-right","vd-layout-sidebar-collapsed"),this.container=null}observe(){typeof ResizeObserver>"u"||this.container===null||(this.observer=new ResizeObserver(t=>{const e=t[0]?.contentRect.width??0;this.setCollapsible(e>0&&e<Mi)}),this.observer.observe(this.container))}setCollapsible(t){t!==this.collapsible&&(this.collapsible=t,this.expanded=!t,this.render())}render(){if(this.element===null||this.openButton===null||this.closeButton===null||this.container===null)return;const t=this.visible&&this.expanded,e=this.visible&&!this.expanded;this.element.classList.toggle("vd-hidden",!this.visible),this.element.classList.toggle("vd-sidebar-collapsed",e),this.openButton.element.classList.toggle("vd-hidden",!e),this.closeButton.element.style.display=this.collapsible?"":"none",this.container.classList.toggle("vd-layout-sidebar-right",t),this.container.classList.toggle("vd-layout-sidebar-collapsed",e)}}class Pi{attach(t,e){}setVisible(t){}destroy(){}}const Fi={"inframe-bottom-left":()=>new Ot,"sidebar-right":()=>new zi,hidden:()=>new Pi};function $i(n){return(Fi[n??""]??(()=>new Ot))()}const j=_.fontFamily.sans.join(", "),H=`
259
+ `;let tt=!1;function Yn(){if(tt||typeof document>"u")return;tt=!0;const n=document.createElement("style");n.id="vd-ui-vanilla",n.textContent=Wn,document.head.appendChild(n)}function Xn(){return new Date}function Kn(n){return n.toISOString()}function gt(){return typeof navigator>"u"?"":navigator.userAgent}function Qn(){return typeof navigator>"u"?!1:navigator.platform==="MacIntel"&&navigator.maxTouchPoints>1}function Jn(){return/iPhone|iPad|iPod/i.test(gt())||Qn()}function ti(){return/Android/i.test(gt())}function ei(){return Jn()||ti()}class bt{constructor(t){this.send=t}send;setEnabled(t){this.send({type:c.ANNOTATION_TOGGLE,enabled:t})}}class vt{constructor(t,e){this.value=t,this.attribute=e}value;attribute;isSelectedValue=!1;get isSelected(){return this.isSelectedValue}setSelected(t){this.isSelectedValue=t}}const C={NO_MAPPING:"NO_MAPPING",ATTRIBUTE_NOT_FOUND:"ATTRIBUTE_NOT_FOUND",VALUE_NOT_FOUND:"VALUE_NOT_FOUND",PARENT_NOT_FOUND:"PARENT_NOT_FOUND",INVALID_PARAMETER:"INVALID_PARAMETER",SNAPSHOT_FAILED:"SNAPSHOT_FAILED"};class f extends Error{code;constructor(t,e){super(t),this.name="VirtualdisplayError",this.code=e}static valueNotFound(t,e){return new f(`Value "${e}" not found for attribute "${t}"`,C.VALUE_NOT_FOUND)}static parentNotFound(t){return new f(`Parent element not found: ${t}`,C.PARENT_NOT_FOUND)}static invalidParameter(t){return new f(t,C.INVALID_PARAMETER)}}class yt{name;defaultValue;values;onSelect;onChangeCallback;constructor(t){this.name=t.name,this.defaultValue=t.defaultValue,this.onSelect=t.onSelect,this.values=this.createValues(t.values)}select(t){if(!this.values.has(t))throw f.valueNotFound(this.name,t);this.onSelect(this.name,t)}getValues(){return Array.from(this.values.values())}getValue(t){return this.values.get(t)}get selected(){for(const t of this.values.values())if(t.isSelected)return t.value}onChange(t){this.onChangeCallback=t}handleResult(t){let e;for(const i of this.values.values()){const o=i.value===t;i.setSelected(o),o&&(e=i)}e!==void 0&&this.onChangeCallback!==void 0&&this.onChangeCallback(e)}createValues(t){const e=new Map;for(const i of t){const o=new vt(i,this.name);i===this.defaultValue&&o.setSelected(!0),e.set(i,o)}return e}}class ni{attributes=new Map;constructor(t,e,i){for(const o of t){const s=this.buildOptions(o,e);this.attributes.set(o.name,new yt(s))}this.onMutationFailed=i}onMutationFailed;get(t){return this.attributes.get(t)}getSelection(){const t={};for(const[e,i]of this.attributes){const o=i.selected;o!==void 0&&(t[e]=o)}return t}handleResults(t){for(const e of t){if(!e.success){this.onMutationFailed?.(e.name,e.value);continue}this.get(e.name)?.handleResult(e.value)}}buildOptions(t,e){const i={name:t.name,values:t.values,onSelect:(o,s)=>{e([{name:o,value:s}],!1)}};return t.defaultValue!==void 0?{...i,defaultValue:t.defaultValue}:i}}function ii(n){const t=new Date(n.timestamp).toLocaleTimeString("en-GB",{hour12:!1}),e=n.level.toUpperCase().padEnd(5),i=n.trace_id?.slice(0,8)??"--------",o=n.msg,s=["timestamp","level","msg","service","trace_id","span_id"],r=Object.entries(n).filter(([l])=>!s.includes(l)).map(([l,d])=>`${l}=${JSON.stringify(d)}`).join(" ");return`${t} ${e} [${i}] ${o}${r?" "+r:""}`}function oi(n){return JSON.stringify(n)}function si(n,t){const e=t?ii(n):oi(n);n.level==="error"?console.error(e):n.level==="warn"?console.warn(e):console.log(e)}function _t(n,t=0){const e={name:n.name,message:n.message};n.stack!==void 0&&(e.stack=n.stack);for(const i of Object.getOwnPropertyNames(n)){if(i==="name"||i==="message"||i==="stack"||i==="cause")continue;const o=n[i];o!==void 0&&(e[i]=o)}return n.cause!==void 0&&n.cause!==null&&(e.cause=n.cause instanceof Error&&t<5?_t(n.cause,t+1):String(n.cause)),e}function ri(n){const t={};for(const[e,i]of Object.entries(n))t[e]=i instanceof Error?_t(i):i;return t}class ai{constructor(t){this.config=t}config;log(t,e,i={}){const o=this.config.traceProvider?.()??{},s={timestamp:Kn(Xn()),level:t,msg:e,service:this.config.service,...o,...ri(i)};si(s,this.config.isDev)}debug(t,e){this.config.isDev&&this.log("debug",t,e)}info(t,e){this.log("info",t,e)}warn(t,e){this.log("warn",t,e)}error(t,e){this.log("error",t,e)}}function wt(n,t){const e=t?.isDev!==void 0?t.isDev:typeof process<"u"?process.env.NODE_ENV!=="production":!0;return new ai({service:n,isDev:e,traceProvider:t?.traceProvider})}function O(n){if(n!==void 0)return typeof n=="object"&&n!==null&&!Array.isArray(n)&&!(n instanceof Error)?n:n instanceof Error?{error:n.message}:{value:n}}function Ct(n){return{debug:(t,e)=>n.debug(t,O(e)),info:(t,e)=>n.info(t,O(e)),warn:(t,e)=>n.warn(t,O(e)),error:(t,e)=>n.error(t,O(e))}}let St=!1;exports.logger=Ct(wt("client",{isDev:!1}));function kt(){St=!0,exports.logger=Ct(wt("client",{isDev:!0}))}function li(){return St}class ci{constructor(t,e){this.send=t,this.onMutationFailed=e}send;onMutationFailed;registry;pendingCallbacks=[];handleMappingReceived(t){exports.logger.debug("Initializing from server mapping",{attributeCount:t.attributes.length}),this.registry=new ni(t.attributes,(e,i)=>this.sendMutation(e,i),this.onMutationFailed),this.replayPendingCallbacks()}handleMutationResult(t){this.registry?.handleResults(t.results)}select(t,e){this.sendMutation([{name:t,value:e}],!1)}getValues(t){return this.registry?.get(t)?.getValues()??[]}getValue(t,e){return this.registry?.get(t)?.getValue(e)}onChange(t,e){if(this.registry===void 0){this.pendingCallbacks.push({name:t,callback:e});return}const i=this.registry.get(t);if(i===void 0){exports.logger.warn(`onChange: attribute "${t}" not found — callback will not fire`);return}i.onChange(e)}getAttribute(t){return this.registry?.get(t)}getSelection(){return this.registry?.getSelection()??{}}get hasMapping(){return this.registry!==void 0}sendMutation(t,e){const i={type:c.MUTATION,mutations:t,isInitial:e};this.send(i)}replayPendingCallbacks(){for(const{name:t,callback:e}of this.pendingCallbacks){const i=this.registry?.get(t);i===void 0&&exports.logger.warn(`onChange: attribute "${t}" not found — buffered callback will not fire`),i?.onChange(e)}this.pendingCallbacks.length=0}}class Et{constructor(t){this.send=t}send;commands=[];rotate(t){return this.validateFiniteNumber(t,"rotate"),this.commands.push({action:"rotate",value:t}),this}tilt(t){return this.validateFiniteNumber(t,"tilt"),this.commands.push({action:"tilt",value:t}),this}zoom(t){return this.validateFiniteNumber(t,"zoom"),this.commands.push({action:"zoom",value:t}),this}set(){if(this.commands.length===0)throw f.invalidParameter("No camera commands to execute. Call rotate(), tilt(), or zoom() before set().");const t={type:c.CAMERA,commands:this.commands};this.send(t),this.commands=[]}validateFiniteNumber(t,e){if(!Number.isFinite(t))throw f.invalidParameter(`${e}() requires a finite number, got ${String(t)}`)}reset(){const t={type:c.CAMERA,commands:[{action:"reset"}]};this.send(t)}}class ui{state;limitsState;changeCallbacks=[];constructor(){this.state={rotation:0,tilt:0,zoom:100}}get rotation(){return this.state.rotation}get tilt(){return this.state.tilt}get zoom(){return this.state.zoom}onChange(t){this.changeCallbacks.push(t)}get limits(){return this.limitsState}applyLimits(t){this.limitsState=t;const e={rotation:this.rotation,tilt:this.tilt,zoom:this.zoom};for(const i of this.changeCallbacks)i(e)}handlePositionUpdate(t){this.update(t.transforms)}update(t){let e=!1;for(const i of t)switch(i.type){case"rotation":this.state.rotation=i.value,e=!0;break;case"tilt":this.state.tilt=i.value,e=!0;break;case"zoom":this.state.zoom=i.value,e=!0;break}if(e){const i={rotation:this.rotation,tilt:this.tilt,zoom:this.zoom};for(const o of this.changeCallbacks)o(i)}}}function di(n,t){const e=n.filter(s=>hi(s,t));if(e.length===0)return;const i=Math.max(...e.map(et)),o=e.filter(s=>et(s)===i);return o.length===1?o[0]:void 0}function hi(n,t){return Object.entries(n.attributes).every(([e,i])=>t[e]===i)}function et(n){return Object.keys(n.attributes).length}class At{constructor(t,e){this.dispatchChange=t,this.dispatchSubmit=e}dispatchChange;dispatchSubmit;pricing;selection={};resolved;changeCallbacks=[];renderCallbacks=[];submitCallback;submitDefaultLabel;get current(){return this.resolved}get vatDisplay(){return this.pricing?.vatDisplay}get buttonLabel(){const t=this.pricing?.buttonLabel;if(t!=null&&t!=="")return t;if(this.submitDefaultLabel!==void 0&&this.submitDefaultLabel!=="")return this.submitDefaultLabel}get submittable(){return this.submitCallback===void 0?!1:this.pricing===void 0?!0:this.resolved?.availability==="available"}get submitEnabled(){return this.submittable&&this.buttonLabel!==void 0}onChange(t){this.changeCallbacks.push(t)}onSubmit(t,e){this.submitCallback=t,this.submitDefaultLabel=e?.defaultLabel,this.notifyRender()}onRender(t){return this.renderCallbacks.push(t),()=>{const e=this.renderCallbacks.indexOf(t);e!==-1&&this.renderCallbacks.splice(e,1)}}async submit(){if(!this.submittable)return;const t=this.resolved!==void 0?{attributes:this.resolved.attributes,reference:this.resolved.reference}:{attributes:{...this.selection},reference:""};this.dispatchSubmit(t),await this.submitCallback?.(t)}handlePricingReceived(t){this.pricing=t,this.recompute()}handleSelectionChanged(t){this.selection=t,this.recompute()}recompute(){this.resolved=this.resolve();for(const t of this.changeCallbacks)t(this.resolved);this.dispatchChange(this.resolved),this.notifyRender()}notifyRender(){for(const t of this.renderCallbacks)t()}resolve(){if(this.pricing===void 0)return;const t=di(this.pricing.rules,this.selection);if(!(t===void 0||t.availability===Nt.HIDDEN))return{attributes:{...this.selection},reference:t.reference,price:t.priceCents,currency:this.pricing.currency,availability:t.availability}}}class xt{constructor(t,e){this.send=t,this.dispatch=e}send;dispatch;focused=null;attributes=[];changeCallbacks=[];get current(){return this.focused}set(t){if(typeof t!="string"||t.length===0)throw f.invalidParameter(`set() requires a non-empty component name, got ${String(t)}`);this.send({type:c.FOCUS,action:W.FOCUS,component:t})}clear(){this.send({type:c.FOCUS,action:W.UNFOCUS})}onChange(t){this.changeCallbacks.push(t)}handleStateReceived(t){t.state===It.FOCUSED&&t.component!==void 0?(this.focused=t.component,this.attributes=t.attributes??[]):(this.focused=null,this.attributes=[]);const e=this.focused!==null?{component:this.focused,attributes:this.attributes}:null;for(const i of this.changeCallbacks)i(e);this.dispatch(e)}}class Tt{constructor(t){this.filename=t}filename;developedCallbacks=new Set;errorCallbacks=new Set;developed=!1;failed=!1;photoData=null;onDeveloped(t){return this.developed&&this.photoData!==null?(t(this.photoData),this):(this.developedCallbacks.add(t),this)}onError(t){return this.errorCallbacks.add(t),this}getFilename(){return this.filename}develop(t){this.developed||this.failed||(this.photoData=t,this.developed=!0,this.developedCallbacks.forEach(e=>{e(this.photoData)}),this.developedCallbacks.clear(),this.errorCallbacks.clear())}fail(t){this.developed||this.failed||(this.failed=!0,this.errorCallbacks.forEach(e=>{e(t)}),this.developedCallbacks.clear(),this.errorCallbacks.clear())}}const nt=3e4;class Rt{constructor(t){this.send=t}send;validExtensions=[".png"];pendingPhotos=new Map;take(t){this.validateFilename(t),exports.logger.debug("Taking snapshot",{filename:t});const e=new Tt(t),i=setTimeout(()=>{this.pendingPhotos.delete(t),exports.logger.warn("Snapshot timed out",{filename:t}),e.fail(new f(`Snapshot timed out: the viewer did not respond within ${nt}ms`,C.SNAPSHOT_FAILED))},nt);return this.pendingPhotos.set(t,{photo:e,timeout:i}),this.send({type:c.SNAPSHOT,filename:t}),e}handleSnapshotResult(t){const e=this.pendingPhotos.get(t.filename);if(e===void 0){exports.logger.warn("No pending photo found for filename",{filename:t.filename,pendingFilenames:Array.from(this.pendingPhotos.keys())});return}clearTimeout(e.timeout),this.pendingPhotos.delete(t.filename);const{photo:i}=e;if(t.error!==void 0){i.fail(new f(t.error,C.SNAPSHOT_FAILED));return}t.data!==void 0&&i.develop({filename:t.filename,data:t.data})}clear(){if(this.pendingPhotos.size===0)return;const t=new f("Client destroyed before snapshot completed",C.SNAPSHOT_FAILED);for(const{photo:e,timeout:i}of this.pendingPhotos.values())clearTimeout(i),e.fail(t);this.pendingPhotos.clear()}validateFilename(t){if(t===""||typeof t!="string")throw new f("Filename must be a non-empty string",C.INVALID_PARAMETER);if(!this.validExtensions.some(i=>t.toLowerCase().endsWith(i)))throw new f(`Invalid filename: "${t}". Filename must end with one of: ${this.validExtensions.join(", ")}`,C.INVALID_PARAMETER);if(t.includes("..")||t.includes("/")||t.includes("\\"))throw new f('Filename cannot contain path separators or ".."',C.INVALID_PARAMETER)}}class mi{container=null;attach(t){this.container=t}dispatch(t,e,i=!1){const o=new CustomEvent(t,{detail:e,cancelable:i});return this.container?.dispatchEvent(o),o}on(t,e){const i=o=>{const s=o,r={...s.detail,preventDefault:()=>{s.preventDefault()}};e(r)};return this.container?.addEventListener(t,i),()=>{this.container?.removeEventListener(t,i)}}}function y(n,{size:t=20,strokeWidth:e=1.75}={}){return lt(n,{width:t,height:t,"stroke-width":e})}const b={ar:n=>y(Zt,n),fullscreen:n=>y(Qt,n),exitFullscreen:n=>y(Jt,n),screenshot:n=>y(Wt,n),tiltUp:n=>y(Kt,n),tiltDown:n=>y(ct,n),rotateLeft:n=>y(Yt,n),rotateRight:n=>y(Xt,n),zoomIn:n=>y(ie,n),zoomOut:n=>y(oe,n),reset:n=>y(te,n),configurator:n=>y(ee,n),close:n=>y(ne,n)};function it(n){const t=Math.max(0,Math.min(1,n));return t*t*(3-2*t)}function pi(n,t,e,i,o,s){const[r,l,d]=n,u=Math.cos(t),p=Math.sin(t),v=u*r+p*d,E=-p*r+u*d,k=Math.cos(e),w=Math.sin(e),R=k*l-w*E,L=w*l+k*E,Z=.55;return[i+v*s*Z,o-R*s*Z,L]}function fi(n,t,e){n.beginPath(),n.moveTo(t[0],t[1]),n.lineTo(e[0],e[1]),n.strokeStyle="#000",n.lineWidth=2,n.stroke()}function gi(n,t,e,i,o){const s=t(e),r=t(i),l=[s[0]+(r[0]-s[0])*o,s[1]+(r[1]-s[1])*o,s[2]];fi(n,s,l)}const M=[-1,-1,1],z=[1,-1,1],P=[1,-1,-1],F=[-1,-1,-1],$=[-1,1,1],D=[1,1,1],B=[1,1,-1],U=[-1,1,-1],ot=[[M,z],[z,P],[P,F],[F,M],[M,$],[z,D],[P,B],[F,U],[$,D],[D,B],[B,U],[U,$]],bi=400,st='-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif';function vi(){const n=document.createElement("div");Object.assign(n.style,{position:"absolute",inset:"0",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",background:"#fff",zIndex:"20",opacity:"0",transition:"opacity 0.3s ease-in-out"});const t=document.createElement("canvas");Object.assign(t.style,{width:"100%",height:"100%",position:"absolute",inset:"0"});const e=document.createElement("div");Object.assign(e.style,{position:"absolute",top:"56%",left:"0",right:"0",textAlign:"center",pointerEvents:"none"});const i=document.createElement("span");Object.assign(i.style,{fontSize:"13px",fontWeight:"400",color:"#000",fontVariantNumeric:"tabular-nums",fontFamily:st});const o=document.createElement("span");return Object.assign(o.style,{fontSize:"13px",color:"#000",fontFamily:st}),o.textContent=ft(),e.appendChild(i),e.appendChild(o),n.appendChild(t),n.appendChild(e),{overlay:n,canvas:t,pctEl:i,phaseEl:o}}class yi{overlay;canvas;ctx;pctEl;phaseEl;animationId=null;showTimerId=null;startTime;hidden=!1;visible=!1;constructor(t,e={}){this.startTime=performance.now();const i=vi();this.overlay=i.overlay,this.canvas=i.canvas,this.pctEl=i.pctEl,this.phaseEl=i.phaseEl,t.appendChild(this.overlay),this.ctx=this.canvas.getContext("2d"),this.ctx!==null&&(this.sizeCanvas(),this.tick());const o=e.showDelay??bi;this.showTimerId=setTimeout(()=>{this.reveal()},o)}get loadingTexts(){return{downloading:ft(),rendering:Ge()}}updateProgress(t,e){this.hidden||(this.pctEl.textContent=`${Math.round(t)}%`,this.phaseEl.textContent=e!==""?` · ${e}`:"")}showError(t){if(this.hidden=!1,this.animationId!==null&&(cancelAnimationFrame(this.animationId),this.animationId=null),this.ctx!==null){const e=Math.min(devicePixelRatio,2),i=this.canvas.width/e,o=this.canvas.height/e;this.ctx.fillStyle="#fff",this.ctx.fillRect(0,0,i*e,o*e)}this.pctEl.textContent="",this.phaseEl.textContent=t,this.phaseEl.style.color="#b91c1c",this.reveal()}hide(){if(!this.hidden){if(this.hidden=!0,this.cancelShowTimer(),!this.visible){this.destroy();return}this.overlay.style.opacity="0",this.overlay.addEventListener("transitionend",()=>{this.destroy()},{once:!0}),setTimeout(()=>{this.destroy()},500)}}destroy(){this.cancelShowTimer(),this.animationId!==null&&(cancelAnimationFrame(this.animationId),this.animationId=null),this.overlay.remove()}reveal(){this.hidden||this.visible||(this.visible=!0,this.overlay.style.opacity="1")}cancelShowTimer(){this.showTimerId!==null&&(clearTimeout(this.showTimerId),this.showTimerId=null)}sizeCanvas(){if(this.ctx===null)return;const t=Math.min(devicePixelRatio,2),e=this.overlay.clientWidth||440,i=this.overlay.clientHeight||360;this.canvas.width=e*t,this.canvas.height=i*t,this.ctx.scale(t,t),this.ctx.lineCap="round",this.ctx.lineJoin="round"}tick=()=>{this.hidden||(this.drawFrame(),this.animationId=requestAnimationFrame(this.tick))};drawFrame(){if(this.ctx===null)return;const t=this.canvas.width/Math.min(devicePixelRatio,2),e=this.canvas.height/Math.min(devicePixelRatio,2),i=(performance.now()-this.startTime)/1e3;this.ctx.fillStyle="#fff",this.ctx.fillRect(0,0,t,e);const o=t/2,s=e*.44,r=Math.min(t,e)*.08,l=.785,d=.615,u=w=>pi(w,l,d,o,s,r),p=6,v=i%p/p,E=ot.length;let k;v<.35?k=it(v/.35)*E:v<.55?k=E:v<.9?k=(1-it((v-.55)/.35))*E:k=0,this.ctx.shadowBlur=5,this.ctx.shadowColor="rgba(30,30,30,0.08)";for(let w=0;w<E&&!(w>=k);w++){const R=ot[w];if(R===void 0)continue;const L=Math.min(1,k-w);gi(this.ctx,u,R[0],R[1],L)}this.ctx.shadowBlur=0}}class _i{constructor(t){this.options=t,this.element=document.createElement("div"),Object.assign(this.element.style,{display:"flex",gap:"0.375rem"}),this.onFullscreenChange=()=>{this.setFullscreenIcon(document.fullscreenElement!==null)},document.addEventListener("fullscreenchange",this.onFullscreenChange)}options;element;arBtn=null;fullscreenBtn=null;onFullscreenChange;setFullscreenIcon(t){this.fullscreenBtn!==null&&this.fullscreenBtn.setIcon(t?b.exitFullscreen():b.fullscreen())}syncButton(t,e,i){if(e&&t===null){const o=i();return this.element.appendChild(o.element),o}return!e&&t!==null?(t.element.remove(),null):t}applySettings(t){this.arBtn=this.syncButton(this.arBtn,t.ar!==!1&&this.options.onAr!==void 0,()=>new g({variant:"outline",size:"icon",label:ve(),icon:b.ar(),onClick:()=>{this.options.onAr?.()}})),this.fullscreenBtn=this.syncButton(this.fullscreenBtn,t.fullscreen!==!1&&this.options.onFullscreen!==void 0,()=>new g({variant:"outline",size:"icon",label:$e(),icon:b.fullscreen(),onClick:()=>{this.options.onFullscreen?.()}}))}destroy(){document.removeEventListener("fullscreenchange",this.onFullscreenChange)}}const x=.5;class N{element;constructor(t,e){this.element=Object.assign(document.createElement("div"),{className:"vd-camera-controls"});const i={targetRotation:e.rotation,targetTilt:e.tilt,targetZoom:e.zoom,thetaOffset:0},o=wi(t,e,i);e.onChange(s=>{i.targetRotation=s.rotation-i.thetaOffset,i.targetTilt=s.tilt,i.targetZoom=s.zoom,Ci(o,e,s)}),this.element.appendChild(N.buildZoom(o.zoomOut,o.zoomIn)),this.element.appendChild(N.buildDpad(o.tiltUp,o.rotateLeft,o.reset,o.rotateRight,o.tiltDown))}static buildZoom(t,e){const i=document.createElement("div");return i.className="vd-zoom",i.appendChild(t.element),i.appendChild(e.element),i}static buildDpad(t,e,i,o,s){const r=document.createElement("div");r.className="vd-dpad";for(const[l,d]of[[t,"up"],[e,"left"],[i,"center"],[o,"right"],[s,"down"]])l.element.classList.add(`vd-dpad-${d}`),r.appendChild(l.element);return r}}function wi(n,t,e){const i=r=>Math.max(t.limits?.minZoom??1,Math.min(t.limits?.maxZoom??1/0,r)),o=r=>{const l=t.limits?.minRotate,d=t.limits?.maxRotate;return l!==void 0||d!==void 0?Math.max(l??-1/0,Math.min(d??1/0,r)):r},s=r=>{const l=t.limits?.minTilt,d=t.limits?.maxTilt;if(l!==void 0||d!==void 0){e.targetTilt=Math.max(l??0,Math.min(d??180,e.targetTilt+r)),n.tilt(e.targetTilt).set();return}const u=e.targetTilt+r;u>180||u<0?(e.targetTilt=u>180?360-u:-u,e.thetaOffset=(e.thetaOffset+180)%360,n.tilt(e.targetTilt).rotate(e.targetRotation+e.thetaOffset).set()):(e.targetTilt=u,n.tilt(e.targetTilt).set())};return{zoomOut:new g({variant:"outline",size:"icon",label:gn(),icon:b.zoomOut(),onClick:()=>{e.targetZoom=i(e.targetZoom-10),n.zoom(e.targetZoom).set()}}),zoomIn:new g({variant:"outline",size:"icon",label:hn(),icon:b.zoomIn(),onClick:()=>{e.targetZoom=i(e.targetZoom+10),n.zoom(e.targetZoom).set()}}),tiltUp:new g({variant:"outline",size:"icon",label:Tn(),icon:b.tiltUp(),onClick:()=>{s(-15)}}),rotateLeft:new g({variant:"outline",size:"icon",label:_n(),icon:b.rotateLeft(),onClick:()=>{e.targetRotation=o(e.targetRotation-15),n.rotate(e.targetRotation+e.thetaOffset).set()}}),reset:new g({variant:"outline",size:"icon",label:ln(),icon:b.reset(),onClick:()=>{e.thetaOffset=0,n.reset()}}),rotateRight:new g({variant:"outline",size:"icon",label:kn(),icon:b.rotateRight(),onClick:()=>{e.targetRotation=o(e.targetRotation+15),n.rotate(e.targetRotation+e.thetaOffset).set()}}),tiltDown:new g({variant:"outline",size:"icon",label:Nn(),icon:b.tiltDown(),onClick:()=>{s(15)}})}}function Ci(n,t,e){const i=t.limits;i!==void 0&&(n.zoomOut.element.disabled=i.minZoom!==void 0&&e.zoom<=i.minZoom+x,n.zoomIn.element.disabled=i.maxZoom!==void 0&&e.zoom>=i.maxZoom-x,n.tiltUp.element.disabled=i.minTilt!==void 0&&e.tilt<=i.minTilt+x,n.tiltDown.element.disabled=i.maxTilt!==void 0&&e.tilt>=i.maxTilt-x,n.rotateLeft.element.disabled=i.minRotate!==void 0&&e.rotation<=i.minRotate+x,n.rotateRight.element.disabled=i.maxRotate!==void 0&&e.rotation>=i.maxRotate-x)}const T={SELECT:"ui:select",SELECTED:"ui:selected",FOCUS_CHANGE:"vd:focus-change",CONFIGURATION_CHANGE:"vd:configuration-change",CONFIGURATION_SUBMIT:"vd:configuration-submit"},Si=5;let ki=0;function V(n){const t=n.replace(/([A-Z])/g," $1").trim();return t.charAt(0).toUpperCase()+t.slice(1).toLowerCase()}function Ei(n,t,e,i,o){const s=document.createElement("div");s.className="vd-attribute",s.dataset.name=n.name;const r=document.createElement("span");r.className="vd-attribute-label",r.textContent=V(n.name),r.id=`vd-attribute-label-${ki++}`,s.appendChild(r),s.setAttribute("role","group"),s.setAttribute("aria-labelledby",r.id);const l=n.values.find(p=>t.getValue(n.name,p)?.isSelected===!0),d=n.values.map(V),u=n.values.length<=Si?new ae(n.values,l,d):new le(n.name,n.values,V(n.name),l,d);return u.onSelect(p=>{e.dispatch(T.SELECT,{attribute:n.name,value:p},!0).defaultPrevented||i(n.name,p)}),o(n.name,p=>{u.setSelected(p.value),e.dispatch(T.SELECTED,{attribute:n.name,value:p.value})}),s.appendChild(u.element),s}const Ai=80,xi=2500;class Ti{constructor(t,e=xi){this.configuration=t,this.resetMs=e,this.element=document.createElement("div"),this.element.className="vd-commerce vd-hidden";const i=document.createElement("div");i.className="vd-commerce-price",this.priceEl=document.createElement("span"),this.priceEl.className="vd-price",this.vatEl=document.createElement("span"),this.vatEl.className="vd-vat",i.append(this.priceEl,this.vatEl),this.button=new g({variant:"default",onClick:()=>{this.handleSubmit()}}),this.button.element.classList.add("vd-cta","vd-hidden"),this.element.append(i,this.button.element),this.unsubscribe=this.configuration.onRender(()=>{this.update()}),this.update()}configuration;resetMs;element;priceEl;vatEl;button;unsubscribe;state="idle";resetTimer;update(){this.renderPrice(this.configuration.current),this.renderButton();const t=this.configuration.current!==void 0||this.configuration.submitEnabled;this.element.classList.toggle("vd-hidden",!t)}destroy(){this.unsubscribe(),this.resetTimer!==void 0&&clearTimeout(this.resetTimer),this.element.remove()}renderPrice(t){if(t===void 0){this.priceEl.textContent="",this.vatEl.textContent="";return}this.priceEl.textContent=Ri(t.price,t.currency),this.vatEl.textContent=rt(this.configuration.vatDisplay)}renderButton(){const t=this.configuration.submitEnabled;this.button.element.classList.toggle("vd-hidden",!t),t&&this.state==="idle"&&this.setButtonText(rt(this.configuration.buttonLabel))}async handleSubmit(){if(this.state!=="busy"){this.setState("busy",Pn());try{await this.configuration.submit(),this.setState("success",Bn())}catch{this.setState("failed",Hn())}this.scheduleReset()}}scheduleReset(){this.resetTimer!==void 0&&clearTimeout(this.resetTimer),this.resetTimer=setTimeout(()=>{this.state="idle",this.update()},this.resetMs)}setState(t,e){this.state=t,this.element.dataset.submit=t,this.button.element.disabled=t==="busy",this.setButtonText(e)}setButtonText(t){this.button.element.textContent=t,this.button.element.setAttribute("aria-label",t)}}function rt(n){return(n??"").slice(0,Ai)}function Ri(n,t){try{const e=new Intl.NumberFormat(h(),{style:"currency",currency:t}),i=e.resolvedOptions().maximumFractionDigits??2;return e.format(n/10**i)}catch{return`${t} ${(n/100).toFixed(2)}`}}class Ot{slot=null;panel=null;attach(t,e){this.panel=e,e.style.display="none",this.slot=document.createElement("div"),this.slot.className="vd-slot-bottom-left",this.slot.appendChild(e),t.appendChild(this.slot)}setVisible(t){this.panel!==null&&(this.panel.style.display=t?"flex":"none")}destroy(){this.slot?.remove(),this.slot=null,this.panel=null}}const Oi=572;class Ii{element=null;body=null;openButton=null;closeButton=null;container=null;observer=null;collapsible=!1;expanded=!0;visible=!1;attach(t,e){this.container=t,e.classList.add("vd-attributes-sidebar"),this.closeButton=new g({variant:"ghost",size:"icon-sm",label:on(),icon:b.close({size:18}),onClick:()=>{this.expanded=!1,this.render()}});const i=document.createElement("div");i.className="vd-sidebar-header",i.appendChild(this.closeButton.element),this.body=document.createElement("div"),this.body.className="vd-sidebar-body",this.body.appendChild(e),this.element=document.createElement("div"),this.element.className="vd-sidebar vd-hidden",this.element.append(i,this.body),t.appendChild(this.element),this.openButton=new g({variant:"outline",size:"default",label:Je(),icon:b.configurator({size:18}),onClick:()=>{this.expanded=!0,this.render()}}),this.openButton.element.classList.add("vd-configurator-toggle","vd-hidden"),t.appendChild(this.openButton.element),this.observe()}setVisible(t){this.visible=t,this.render()}destroy(){this.observer?.disconnect(),this.observer=null,this.openButton?.element.remove(),this.element?.remove(),this.container?.classList.remove("vd-layout-sidebar-right","vd-layout-sidebar-collapsed"),this.container=null}observe(){typeof ResizeObserver>"u"||this.container===null||(this.observer=new ResizeObserver(t=>{const e=t[0]?.contentRect.width??0;this.setCollapsible(e>0&&e<Oi)}),this.observer.observe(this.container))}setCollapsible(t){t!==this.collapsible&&(this.collapsible=t,this.expanded=!t,this.render())}render(){if(this.element===null||this.openButton===null||this.closeButton===null||this.container===null)return;const t=this.visible&&this.expanded,e=this.visible&&!this.expanded;this.element.classList.toggle("vd-hidden",!this.visible),this.element.classList.toggle("vd-sidebar-collapsed",e),this.openButton.element.classList.toggle("vd-hidden",!e),this.closeButton.element.style.display=this.collapsible?"":"none",this.container.classList.toggle("vd-layout-sidebar-right",t),this.container.classList.toggle("vd-layout-sidebar-collapsed",e)}}class Ni{attach(t,e){}setVisible(t){}destroy(){}}const Li={"inframe-bottom-left":()=>new Ot,"sidebar-right":()=>new Ii,hidden:()=>new Ni};function Mi(n){return(Li[n??""]??(()=>new Ot))()}const j=_.fontFamily.sans.join(", "),H=`
260
260
  position: absolute;
261
261
  display: flex;
262
262
  z-index: 10;
263
263
  transition: inset-inline-end 0.18s ease;
264
- `,Di=`
264
+ `,zi=`
265
265
  /* Override browser's default black fullscreen backdrop */
266
266
  .vd-container:fullscreen {
267
267
  background: oklch(100% 0 0);
@@ -458,4 +458,4 @@
458
458
  color: ${m.white};
459
459
  }
460
460
 
461
- `;function Bi(){if(bi(),document.getElementById("vd-styles")!==null)return;const n=document.createElement("style");n.id="vd-styles",n.textContent=Di,document.head.appendChild(n)}function Ui(n,t){const e=document.createElement("a");e.href=`data:image/png;base64,${n}`,e.download=t,e.click()}class Vi{options;settings={};container=null;loading=null;slots={topRight:null,bottomRight:null};screenshotBtn=null;actionBar=null;cameraControls=null;attributes=null;layout=null;commerce=null;constructor(t){this.options=t}attach(t){Bi(),this.container=t,this.loading=new ki(t),this.slots.topRight=this.createSlot(t,"vd-slot-top-right"),this.slots.bottomRight=this.createSlot(t,"vd-slot-bottom-right")}onReady(){this.loading?.hide(),this.loading=null,this.mountToolbar(),this.cameraControls!==null&&(this.cameraControls.element.style.display="flex"),this.layout?.setVisible(!0)}mountToolbar(){if(this.actionBar!==null||this.slots.bottomRight===null||this.container===null)return;const t=typeof this.container.requestFullscreen=="function";this.actionBar=new Si({onAr:this.options.onAr,onFullscreen:t?()=>{this.toggleFullscreen()}:void 0}),this.actionBar.applySettings(this.settings),this.slots.bottomRight.appendChild(this.actionBar.element),this.syncScreenshotButton(),this.placeScreenshotButton()}toggleFullscreen(){this.container!==null&&(document.fullscreenElement!==null?document.exitFullscreen():(this.options.onFullscreenEnter?.(),this.container.requestFullscreen()))}updateProgress(t,e){this.loading?.updateProgress(t,e)}showError(t){this.loading?.showError(t)}applyViewerSettings(t){this.settings=t,t.language!==void 0&&kt(t.language,{reload:!1}),this.syncScreenshotButton(),this.actionBar?.applySettings(t),this.cameraControls!==null&&(this.cameraControls.element.style.display=t.cameraControls===!0?"flex":"none"),this.placeScreenshotButton()}renderAttributeControls(t,e){if(!(this.container===null||this.slots.topRight===null)&&(this.cameraControls?.element.remove(),this.cameraControls=null,this.teardownConfigurator(),this.settings.cameraControls===!0&&(this.cameraControls=new I(this.options.cameraApi,this.options.cameraPositionApi),this.cameraControls.element.style.display="none",this.slots.topRight.appendChild(this.cameraControls.element)),this.placeScreenshotButton(),e.length!==0)){this.attributes=document.createElement("div"),this.attributes.className="vd-attributes";for(const i of e)this.attributes.appendChild(Ri(i,t,this.options.eventBus,this.options.onSelect,this.options.onSubscribe));this.commerce=new Ii(this.options.configuration),this.attributes.appendChild(this.commerce.element),this.layout=$i(this.settings.configuratorLayout),this.layout.attach(this.container,this.attributes)}}get viewerSettings(){return this.settings}teardownConfigurator(){this.commerce?.destroy(),this.commerce=null,this.attributes?.remove(),this.attributes=null,this.layout?.destroy(),this.layout=null}destroy(){this.loading?.destroy(),this.screenshotBtn?.element.remove(),this.actionBar?.destroy(),this.actionBar?.element.remove(),this.cameraControls?.element.remove(),this.teardownConfigurator();for(const t of Object.values(this.slots))t?.remove();this.container=null}createSlot(t,e){const i=document.createElement("div");return i.className=e,t.appendChild(i),i}syncScreenshotButton(){const t=this.settings.screenshot===!0;t&&this.screenshotBtn===null&&(this.screenshotBtn=new b({variant:"outline",size:"icon",label:tn(),icon:g.screenshot(),onClick:()=>{this.options.snapshotApi.take("snapshot.png").onDeveloped(({data:e,filename:i})=>{Ui(e,i)})}})),!t&&this.screenshotBtn!==null&&(this.screenshotBtn.element.remove(),this.screenshotBtn=null)}placeScreenshotButton(){this.screenshotBtn===null||this.slots.topRight===null||(this.cameraControls!==null?this.cameraControls.element.appendChild(this.screenshotBtn.element):this.slots.topRight.appendChild(this.screenshotBtn.element))}}class Nt{constructor(t){this.send=t}send;placedCallbacks=[];setEnabled(t){this.send({type:c.ANNOTATION_TOGGLE,enabled:t})}startPlacing(){this.send({type:c.ANNOTATION_PLACE_MODE,enabled:!0})}stopPlacing(){this.send({type:c.ANNOTATION_PLACE_MODE,enabled:!1})}onPlaced(t){this.placedCallbacks.push(t)}handlePlaced(t){for(const e of this.placedCallbacks)e(t)}}class ji{attributes;readyStateTracker;messenger;cameraApi;cameraPositionApi;focusApi;configurationApi;snapshotApi;annotationsApi;eventBus;ui;qrModal;options;iframe;container;viewerSessionId;readyCallbacks=[];mutationFailedCallbacks=[];constructor(t){this.options=t,this.initializeLogging(),this.messenger=new le(()=>this.iframe?.contentWindow??null);const e=i=>{this.messenger.send(i)};this.attributes=new ce(e,(i,o)=>{for(const s of this.mutationFailedCallbacks)s({attribute:i,value:o})}),this.snapshotApi=new _t(e),this.annotationsApi=new Nt(e),this.cameraApi=new gt(e),this.cameraPositionApi=new ue,this.focusApi=new bt(e,i=>{this.dispatchFocusChange(i)}),this.configurationApi=new vt(i=>{this.dispatchConfigurationChange(i)},i=>{this.dispatchConfigurationSubmit(i)}),this.eventBus=new me,this.qrModal=new pi,this.readyStateTracker=new Gt(()=>{const i=this.readyCallbacks;this.readyCallbacks=[];for(const o of i)o(this);this.ui.onReady()}),this.ui=new Vi({snapshotApi:this.snapshotApi,cameraApi:this.cameraApi,cameraPositionApi:this.cameraPositionApi,eventBus:this.eventBus,configuration:this.configurationApi,onSelect:(i,o)=>this.attributes.select(i,o),onSubscribe:(i,o)=>this.attributes.onChange(i,o),onAr:()=>{this.activateAr()},onFullscreenEnter:()=>{this.trackFullscreen()}}),this.registerHandlers(),this.messenger.start(),this.createAndConnectIframe()}registerHandlers(){this.registerLifecycleHandlers(),this.messenger.on(c.MUTATION,t=>{Jt(t)&&(this.attributes.handleMutationResult(t),this.configurationApi.handleSelectionChanged(this.attributes.getSelection()))}),this.messenger.on(c.SNAPSHOT,t=>{te(t)&&this.snapshotApi.handleSnapshotResult(t)}),this.messenger.on(c.CAMERA,t=>{ee(t)&&this.cameraPositionApi.handlePositionUpdate(t)}),this.messenger.on(c.LOADING_INDICATOR,t=>{ie(t)&&(t.error!==void 0?this.ui.showError(t.error):this.ui.updateProgress(t.progress,t.phase))}),this.messenger.on(c.CONFIG,t=>{oe(t)&&this.handleConfig(t)}),this.messenger.on(c.ANNOTATION_PLACED,t=>{se(t)&&this.annotationsApi.handlePlaced(t.position)}),this.messenger.on(c.MAPPING,t=>{ne(t)&&(this.attributes.handleMappingReceived(t),this.configurationApi.handleSelectionChanged(this.attributes.getSelection()),this.ui.renderAttributeControls(this.attributes,t.attributes),this.readyStateTracker.handleMappingReceived())}),this.registerFacadeStateHandlers()}registerLifecycleHandlers(){this.messenger.on(c.HANDSHAKE,t=>{Kt(t)&&(exports.logger.info("Server handshake received, flushing publisher queue"),this.messenger.markReady())}),this.messenger.on(c.SESSION,t=>{Qt(t)&&(this.viewerSessionId=t.sessionId)})}registerFacadeStateHandlers(){this.messenger.on(c.FOCUS,t=>{re(t)&&this.focusApi.handleStateReceived(t)}),this.messenger.on(c.PRICING,t=>{ae(t)&&this.configurationApi.handlePricingReceived(t.pricing)})}dispatchFocusChange(t){this.container?.dispatchEvent(new CustomEvent(T.FOCUS_CHANGE,{detail:t,bubbles:!0}))}dispatchConfigurationChange(t){this.container?.dispatchEvent(new CustomEvent(T.CONFIGURATION_CHANGE,{detail:t??null,bubbles:!0}))}dispatchConfigurationSubmit(t){this.container?.dispatchEvent(new CustomEvent(T.CONFIGURATION_SUBMIT,{detail:t,bubbles:!0}))}handleConfig(t){const e=t.viewerSettings,i=this.options.viewerSettings;if(e!==void 0||i!==void 0){const o=i!==void 0?{...e??{},...i}:e;if(i!==void 0&&e!==void 0){const s=Object.entries(i).filter(([r,l])=>e[r]!==l).map(([r,l])=>`${r} (metadata: ${e[r]??"undefined"}, override: ${l})`);s.length>0&&exports.logger.warn(`Viewer settings override active: ${s.join(", ")}`)}this.ui.applyViewerSettings(o),this.annotationsApi.setEnabled(o.annotations!==!1)}this.cameraPositionApi.applyLimits(t.cameraLimits)}activateAr(){if(jt()){this.messenger.send({type:c.AR_ACTIVATE});return}this.qrModal.show(this.iframe?.src??"")}trackFullscreen(){this.messenger.send({type:c.FULLSCREEN})}initializeLogging(){this.options.debug===!0&&mt(),exports.logger.info("Initializing Virtualdisplay client",{model:this.options.model})}createAndConnectIframe(){const e=new Lt(this.options).create();this.container=e.container,this.iframe=e.iframe,this.eventBus.attach(this.container),this.ui.attach(this.container);try{const i=new URL(this.iframe.src).origin;this.messenger.setTargetOrigin(i)}catch{}}select(t,e){this.attributes.select(t,e)}getValues(t){return this.attributes.getValues(t)}getValue(t,e){return this.attributes.getValue(t,e)}onChange(t,e){this.attributes.onChange(t,e)}getAttribute(t){return this.attributes.getAttribute(t)}get isReady(){return this.readyStateTracker.isReady}onReady(t){if(this.readyStateTracker.isReady){t(this);return}this.readyCallbacks.push(t)}onMutationFailed(t){this.mutationFailedCallbacks.push(t)}on(t,e){this.eventBus.on(t,e)}get annotations(){return this.annotationsApi}get camera(){return this.cameraApi}get focus(){return this.focusApi}get configuration(){return this.configurationApi}get cameraPosition(){return this.cameraPositionApi}get snapshot(){return this.snapshotApi}get viewerSettings(){return this.ui.viewerSettings}get sessionId(){return this.viewerSessionId}destroy(){this.readyStateTracker.clear(),this.readyCallbacks=[],this.mutationFailedCallbacks.length=0,this.snapshotApi.clear(),this.messenger.destroy(),this.qrModal.hide(),this.ui.destroy(),this.container?.parentElement!==null&&this.container?.parentElement!==void 0&&this.container.parentElement.removeChild(this.container),this.container=void 0,this.iframe=void 0}}exports.Annotations=Nt;exports.Attribute=ft;exports.AttributeValue=pt;exports.Camera=gt;exports.Configuration=vt;exports.ERROR_CODES=k;exports.Focus=bt;exports.Photo=yt;exports.Snapshot=_t;exports.VD_EVENTS=T;exports.VirtualdisplayClient=ji;exports.VirtualdisplayError=f;exports.enableDebugMode=mt;exports.isDebugMode=Ht;
461
+ `;function Pi(){if(Yn(),document.getElementById("vd-styles")!==null)return;const n=document.createElement("style");n.id="vd-styles",n.textContent=zi,document.head.appendChild(n)}function Fi(n,t){const e=document.createElement("a");e.href=`data:image/png;base64,${n}`,e.download=t,e.click()}class $i{options;settings={};container=null;loading=null;slots={topRight:null,bottomRight:null};screenshotBtn=null;actionBar=null;cameraControls=null;attributes=null;layout=null;commerce=null;constructor(t){this.options=t}attach(t){Pi(),this.container=t,this.loading=new yi(t),this.slots.topRight=this.createSlot(t,"vd-slot-top-right"),this.slots.bottomRight=this.createSlot(t,"vd-slot-bottom-right")}onReady(){this.loading?.hide(),this.loading=null,this.mountToolbar(),this.cameraControls!==null&&(this.cameraControls.element.style.display="flex"),this.layout?.setVisible(!0)}mountToolbar(){if(this.actionBar!==null||this.slots.bottomRight===null||this.container===null)return;const t=typeof this.container.requestFullscreen=="function";this.actionBar=new _i({onAr:this.options.onAr,onFullscreen:t?()=>{this.toggleFullscreen()}:void 0}),this.actionBar.applySettings(this.settings),this.slots.bottomRight.appendChild(this.actionBar.element),this.syncScreenshotButton(),this.placeScreenshotButton()}toggleFullscreen(){this.container!==null&&(document.fullscreenElement!==null?document.exitFullscreen():(this.options.onFullscreenEnter?.(),this.container.requestFullscreen()))}updateProgress(t,e){this.loading?.updateProgress(t,e)}showError(t){this.loading?.showError(t)}applyViewerSettings(t){this.settings=t,t.language!==void 0&&ht(t.language,{reload:!1}),this.syncScreenshotButton(),this.actionBar?.applySettings(t),this.cameraControls!==null&&(this.cameraControls.element.style.display=t.cameraControls===!0?"flex":"none"),this.placeScreenshotButton()}renderAttributeControls(t,e){if(!(this.container===null||this.slots.topRight===null)&&(this.cameraControls?.element.remove(),this.cameraControls=null,this.teardownConfigurator(),this.settings.cameraControls===!0&&(this.cameraControls=new N(this.options.cameraApi,this.options.cameraPositionApi),this.cameraControls.element.style.display="none",this.slots.topRight.appendChild(this.cameraControls.element)),this.placeScreenshotButton(),e.length!==0)){this.attributes=document.createElement("div"),this.attributes.className="vd-attributes";for(const i of e)this.attributes.appendChild(Ei(i,t,this.options.eventBus,this.options.onSelect,this.options.onSubscribe));this.commerce=new Ti(this.options.configuration),this.attributes.appendChild(this.commerce.element),this.layout=Mi(this.settings.configuratorLayout),this.layout.attach(this.container,this.attributes)}}get viewerSettings(){return this.settings}teardownConfigurator(){this.commerce?.destroy(),this.commerce=null,this.attributes?.remove(),this.attributes=null,this.layout?.destroy(),this.layout=null}destroy(){this.loading?.destroy(),this.screenshotBtn?.element.remove(),this.actionBar?.destroy(),this.actionBar?.element.remove(),this.cameraControls?.element.remove(),this.teardownConfigurator();for(const t of Object.values(this.slots))t?.remove();this.container=null}createSlot(t,e){const i=document.createElement("div");return i.className=e,t.appendChild(i),i}syncScreenshotButton(){const t=this.settings.screenshot===!0;t&&this.screenshotBtn===null&&(this.screenshotBtn=new g({variant:"outline",size:"icon",label:Ye(),icon:b.screenshot(),onClick:()=>{this.options.snapshotApi.take("snapshot.png").onDeveloped(({data:e,filename:i})=>{Fi(e,i)})}})),!t&&this.screenshotBtn!==null&&(this.screenshotBtn.element.remove(),this.screenshotBtn=null)}placeScreenshotButton(){this.screenshotBtn===null||this.slots.topRight===null||(this.cameraControls!==null?this.cameraControls.element.appendChild(this.screenshotBtn.element):this.slots.topRight.appendChild(this.screenshotBtn.element))}}const Di={};class Bi{defaultServer="https://server.virtualdisplay.io";options;serverHost;constructor(t,e){this.options=t,this.serverHost=e}create(){const t=this.createContainer(),e=this.createIframe();return t.appendChild(e),this.attachToParent(t),{container:t,iframe:e}}createContainer(){const t=document.createElement("div");return t.className="vd-container",Object.assign(t.style,{position:"relative",width:"100%",height:"100%",overflow:"hidden"}),t}createIframe(){const t=document.createElement("iframe");return t.src=this.buildUrl(),Object.assign(t.style,{width:"100%",height:"100%",border:"none",display:"block"}),t.setAttribute("allow","xr-spatial-tracking; fullscreen"),t}attachToParent(t){this.getParentElement().appendChild(t)}buildUrl(){const t=this.getServerUrl(),e=new URL(t);return e.searchParams.set("license",this.options.license),e.searchParams.set("model",this.options.model),this.options.language!==void 0&&e.searchParams.set("language",this.options.language),this.options.debug===!0&&e.searchParams.set("debug","true"),this.options.traceparent!==void 0&&e.searchParams.set("traceparent",this.options.traceparent),e.toString()}getServerUrl(){if(this.serverHost!==void 0)return this.serverHost;if(Di?.VITE_VIRTUALDISPLAY_SERVER_HOST===void 0)return this.defaultServer}getParentElement(){if(typeof this.options.parent!="string")return this.options.parent;const t=document.querySelector(this.options.parent);if(t===null)throw f.parentNotFound(this.options.parent);return t}}function Ui(n){const{messenger:t}=n;t.on(c.HANDSHAKE,e=>{zt(e)&&(exports.logger.info("Server handshake received, flushing publisher queue"),t.markReady())}),t.on(c.SESSION,e=>{Pt(e)&&n.onSession(e.sessionId)}),t.on(c.MUTATION,e=>{Ft(e)&&(n.attributes.handleMutationResult(e),n.configuration.handleSelectionChanged(n.attributes.getSelection()))}),t.on(c.SNAPSHOT,e=>{$t(e)&&n.snapshot.handleSnapshotResult(e)}),t.on(c.CAMERA,e=>{Dt(e)&&n.cameraPosition.handlePositionUpdate(e)}),t.on(c.LOADING_INDICATOR,e=>{Ut(e)&&(e.error!==void 0?n.ui.showError(e.error):n.ui.updateProgress(e.progress,e.phase))}),t.on(c.CONFIG,e=>{Vt(e)&&n.applyConfig(e)}),t.on(c.MAPPING,e=>{Bt(e)&&(n.attributes.handleMappingReceived(e),n.configuration.handleSelectionChanged(n.attributes.getSelection()),n.ui.renderAttributeControls(n.attributes,e.attributes),n.readyStateTracker.handleMappingReceived())}),Vi(n)}function Vi(n){const{messenger:t}=n;t.on(c.FOCUS,e=>{jt(e)&&n.focus.handleStateReceived(e)}),t.on(c.PRICING,e=>{Ht(e)&&n.configuration.handlePricingReceived(e.pricing)})}class ji{ready=!1;onReady;constructor(t){this.onReady=t}handleMappingReceived(){this.ready||(this.ready=!0,exports.logger.info("Mapping received from server, client is now ready"),this.onReady?.())}get isReady(){return this.ready}clear(){this.ready=!1}}class Hi{attributes;readyStateTracker;messenger;cameraApi;cameraPositionApi;focusApi;configurationApi;snapshotApi;annotationsApi;eventBus;ui;qrModal;options;serverHost;iframe;container;readyCallbacks=[];mutationFailedCallbacks=[];viewerSessionId;constructor(t,e){this.options=t,this.serverHost=e?.serverHost,this.initializeLogging(),this.messenger=new Gt(()=>this.iframe?.contentWindow??null,e?.messengerOptions);const i=o=>{this.messenger.send(o)};this.attributes=new ci(i,(o,s)=>{for(const r of this.mutationFailedCallbacks)r({attribute:o,value:s})}),this.snapshotApi=new Rt(i),this.annotationsApi=new bt(i),this.cameraApi=new Et(i),this.cameraPositionApi=new ui,this.focusApi=new xt(i,o=>{this.dispatchFocusChange(o)}),this.configurationApi=new At(o=>{this.dispatchConfigurationChange(o)},o=>{this.dispatchConfigurationSubmit(o)}),this.eventBus=new mi,this.qrModal=new qn,this.readyStateTracker=new ji(()=>{const o=this.readyCallbacks;this.readyCallbacks=[];for(const s of o)s(this);this.ui.onReady()}),this.ui=new $i({snapshotApi:this.snapshotApi,cameraApi:this.cameraApi,cameraPositionApi:this.cameraPositionApi,eventBus:this.eventBus,configuration:this.configurationApi,onSelect:(o,s)=>this.attributes.select(o,s),onSubscribe:(o,s)=>this.attributes.onChange(o,s),onAr:()=>{this.activateAr()},onFullscreenEnter:()=>{this.trackFullscreen()}}),this.wireIncomingMessages(),e?.registerHandlers?.(this.messenger,i),this.messenger.start(),this.createAndConnectIframe()}wireIncomingMessages(){Ui({messenger:this.messenger,attributes:this.attributes,configuration:this.configurationApi,snapshot:this.snapshotApi,cameraPosition:this.cameraPositionApi,focus:this.focusApi,ui:this.ui,readyStateTracker:this.readyStateTracker,applyConfig:t=>{this.handleConfig(t)},onSession:t=>{this.viewerSessionId=t}})}dispatchFocusChange(t){this.container?.dispatchEvent(new CustomEvent(T.FOCUS_CHANGE,{detail:t,bubbles:!0}))}dispatchConfigurationChange(t){this.container?.dispatchEvent(new CustomEvent(T.CONFIGURATION_CHANGE,{detail:t??null,bubbles:!0}))}dispatchConfigurationSubmit(t){this.container?.dispatchEvent(new CustomEvent(T.CONFIGURATION_SUBMIT,{detail:t,bubbles:!0}))}handleConfig(t){const e=t.viewerSettings,i=this.options.viewerSettings;if(e!==void 0||i!==void 0){const o=i!==void 0?{...e??{},...i}:e;if(i!==void 0&&e!==void 0){const s=Object.entries(i).filter(([r,l])=>e[r]!==l).map(([r,l])=>`${r} (metadata: ${e[r]??"undefined"}, override: ${l})`);s.length>0&&exports.logger.warn(`Viewer settings override active: ${s.join(", ")}`)}this.ui.applyViewerSettings(o),this.annotationsApi.setEnabled(o.annotations!==!1)}this.cameraPositionApi.applyLimits(t.cameraLimits)}activateAr(){if(ei()){this.messenger.send({type:c.AR_ACTIVATE});return}this.qrModal.show(this.iframe?.src??"")}trackFullscreen(){this.messenger.send({type:c.FULLSCREEN})}initializeLogging(){this.options.debug===!0&&kt(),exports.logger.info("Initializing Virtualdisplay client",{model:this.options.model})}createAndConnectIframe(){const e=new Bi(this.options,this.serverHost).create();this.container=e.container,this.iframe=e.iframe,this.eventBus.attach(this.container),this.ui.attach(this.container);try{const i=new URL(this.iframe.src).origin;this.messenger.setTargetOrigin(i)}catch{}}select(t,e){this.attributes.select(t,e)}getValues(t){return this.attributes.getValues(t)}getValue(t,e){return this.attributes.getValue(t,e)}onChange(t,e){this.attributes.onChange(t,e)}getAttribute(t){return this.attributes.getAttribute(t)}get isReady(){return this.readyStateTracker.isReady}onReady(t){if(this.readyStateTracker.isReady){t(this);return}this.readyCallbacks.push(t)}onMutationFailed(t){this.mutationFailedCallbacks.push(t)}on(t,e){this.eventBus.on(t,e)}get annotations(){return this.annotationsApi}get camera(){return this.cameraApi}get focus(){return this.focusApi}get configuration(){return this.configurationApi}get cameraPosition(){return this.cameraPositionApi}get snapshot(){return this.snapshotApi}get sessionId(){return this.viewerSessionId}get viewerSettings(){return this.ui.viewerSettings}destroy(){this.readyStateTracker.clear(),this.readyCallbacks=[],this.mutationFailedCallbacks.length=0,this.snapshotApi.clear(),this.messenger.destroy(),this.qrModal.hide(),this.ui.destroy(),this.container?.parentElement!==null&&this.container?.parentElement!==void 0&&this.container.parentElement.removeChild(this.container),this.container=void 0,this.iframe=void 0}}class Gi extends Hi{}exports.Annotations=bt;exports.Attribute=yt;exports.AttributeValue=vt;exports.Camera=Et;exports.Configuration=At;exports.ERROR_CODES=C;exports.Focus=xt;exports.Photo=Tt;exports.Snapshot=Rt;exports.VD_EVENTS=T;exports.VirtualdisplayClient=Gi;exports.VirtualdisplayError=f;exports.enableDebugMode=kt;exports.isDebugMode=li;