1!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},t=(new e.Error).stack;t&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[t]="291a16b4-5204-4921-bc01-89b048dd814b",e._sentryDebugIdIdentifier="sentry-dbid-291a16b4-5204-4921-bc01-89b048dd814b")}catch(e){}}();"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[56999],{56999:(e,t,n)=>{n.r(t),n.d(t,{LidarPointCloudViewer:()=>x});var o=n(95155),a=n(12115),r=n(30258),l=n(88945),i=n(83388),s=n(85339);let u=a.forwardRef(({envMap:e,resolution:t=256,frames:n=1/0,makeDefault:o,children:r,...u},c)=>{let d=(0,i.C)(({set:e})=>e),p=(0,i.C)(({camera:e})=>e),h=(0,i.C)(({size:e})=>e),m=a.useRef(null);a.useImperativeHandle(c,()=>m.current,[]);let f=a.useRef(null),g=function(e,t,n){let o=(0,i.C)(e=>e.size),r=(0,i.C)(e=>e.viewport),l="number"==typeof e?e:o.width*r.dpr,u=o.height*r.dpr,c=("number"==typeof e?void 0:e)||{},{samples:d=0,depth:p,...h}=c,m=null!=p?p:c.depthBuffer,f=a.useMemo(()=>{let e=new s.nWS(l,u,{minFilter:s.k6q,magFilter:s.k6q,type:s.ix0,...h});return m&&(e.depthTexture=new s.VCu(l,u,s.RQf)),e.samples=d,e},[]);return a.useLayoutEffect(()=>{f.setSize(l,u),d&&(f.samples=d)},[d,f,l,u]),a.useEffect(()=>()=>f.dispose(),[]),f}(t);a.useLayoutEffect(()=>{u.manual||(m.current.aspect=h.width/h.height)},[h,u]),a.useLayoutEffect(()=>{m.current.updateProjectionMatrix()});let x=0,b=null,v="function"==typeof r;return(0,i.D)(t=>{v&&(n===1/0||x<n)&&(f.current.visible=!1,t.gl.setRenderTarget(g),b=t.scene.background,e&&(t.scene.background=e),t.gl.render(t.scene,m.current),t.scene.background=b,t.gl.setRenderTarget(null),f.current.visible=!0,x++)}),a.useLayoutEffect(()=>{if(o)return d(()=>({camera:m.current})),()=>d(()=>({camera:p}))},[m,o,d]),a.createElement(a.Fragment,null,a.createElement("perspectiveCamera",(0,l.A)({ref:m},u),!v&&r),a.createElement("group",{ref:f},v&&r(g.texture)))});var c=n(16750),d=n(25016),p=n(71574);function h(e){return[(e.bounds.min[0]+e.bounds.max[0])/2,(e.bounds.min[1]+e.bounds.max[1])/2,(e.bounds.min[2]+e.bounds.max[2])/2]}function m(e){let{points:t,mode:n,pointSize:r,onPoint:l,sectionMode:i,onSectionStart:u,onSectionEnd:c,regionMode:d,onRegionStart:p,onRegionEnd:h}=e,m=(0,a.useMemo)(()=>{let e=new Float32Array(t.colors.length),o="deviation"===n?t.deviations:t.slopes,a=o.length?o[0]:0,r=o.length?o[0]:1;for(let e=1;e<o.length;e+=1)a=Math.min(a,o[e]),r=Math.max(r,o[e]);let l=Math.max(r-a,1e-6);for(let r=0;r<o.length;r+=1)if("rgb"===n)e[3*r]=t.colors[3*r]/255,e[3*r+1]=t.colors[3*r+1]/255,e[3*r+2]=t.colors[3*r+2]/255;else{let t=new s.Q1f().setHSL(.66-(o[r]-a)/l*.66,.9,.55);e[3*r]=t.r,e[3*r+1]=t.g,e[3*r+2]=t.b}return e},[n,t.colors,t.deviations,t.slopes]),f=(0,a.useMemo)(()=>{let e=new s.LoY;return e.setAttribute("position",new s.THS(t.positions,3)),e.setAttribute("color",new s.THS(m,3)),e},[m,t.positions]);return(0,o.jsx)("points",{geometry:f,onClick:e=>{e.stopPropagation(),i||d||l(e.point.clone())},onPointerDown:e=>{(i||d)&&(e.stopPropagation(),i?u(e.point.clone()):p(e.point.clone()))},onPointerUp:e=>{(i||d)&&(e.stopPropagation(),i?c(e.point.clone()):h(e.point.clone()))},children:(0,o.jsx)("pointsMaterial",{size:r,sizeAttenuation:!0,vertexColors:!0})})}function f(e){var t,n,r;let{baseUrl:l,modelId:u,manifest:c,mode:d,pointSize:p,onPointsChange:f,onStatus:g,onPoint:x,sectionMode:b,onSectionStart:v,onSectionEnd:w,regionMode:M,onRegionStart:y,onRegionEnd:j}=e,{camera:S,size:k}=(0,i.C)(),D=null!=(r=null==(t=c.nodes.find(e=>"r"===e.id))?void 0:t.id)?r:null==(n=c.nodes[0])?void 0:n.id,[C,E]=(0,a.useState)(D?[D]:[]),z=(0,a.useRef)(""),R=(0,a.useRef)(1),P=function(e,t,n,o){let[r,l]=(0,a.useState)({points:null,loading:!0,error:null});return(0,a.useEffect)(()=>{if(!n||!o.length)return void l({points:null,loading:!1,error:null});let a=new AbortController;return l(e=>({...e,loading:!0,error:null})),(async()=>{try{let r=t?"?modelId=".concat(encodeURIComponent(t)):"",i=new Map(n.nodes.map(e=>[e.id,e])),s=o.map(e=>i.get(e)).filter(e=>!!(null==e?void 0:e.path)),u=await Promise.all(s.map(async t=>{let o=await fetch("".concat(e,"/").concat(t.path).concat(r),{signal:a.signal});if(!o.ok)throw Error("LiDAR tile ".concat(t.id," unavailable"));let l=null;if(t.valuesPath){let n=await fetch("".concat(e,"/").concat(t.valuesPath).concat(r),{signal:a.signal});n.ok&&(l=await n.arrayBuffer())}return function(e,t,n){var o,a,r,l,i;let s=null!=(o=n.pointStride)?o:16,u=null!=(a=n.positionOffset)?a:0,c=null!=(r=n.colorOffset)?r:12,d=null!=(l=n.scale)?l:.001,p=null!=(i=n.offset)?i:[0,0,0],h=Math.floor(e.byteLength/s),m=new DataView(e),f=new Float32Array(3*h),g=new Uint8Array(3*h),x=new Float32Array(h),b=new Float32Array(h),v=t&&t.byteLength>=8*h?new DataView(t):null;for(let e=0;e<h;e+=1){let t=e*s;f[3*e]=m.getInt32(t+u,!0)*d+p[0],f[3*e+1]=m.getInt32(t+u+4,!0)*d+p[1],f[3*e+2]=m.getInt32(t+u+8,!0)*d+p[2],g[3*e]=m.getUint8(t+c),g[3*e+1]=m.getUint8(t+c+1),g[3*e+2]=m.getUint8(t+c+2),v&&(x[e]=v.getFloat32(8*e,!0),b[e]=v.getFloat32(8*e+4,!0))}return{positions:f,colors:g,deviations:x,slopes:b}}(await o.arrayBuffer(),l,n)}));a.signal.aborted||l({points:function(e){let t=Math.max(1,Math.ceil(e.reduce((e,t)=>
1e+t.deviations.length,0)/15e5)),n=e.reduce((e,n)=>e+Math.ceil(n.deviations.length/t),0),o=new Float32Array(3*n),a=new Uint8Array(3*n),r=new Float32Array(n),l=new Float32Array(n),i=0;for(let n of e)for(let e=0;e<n.deviations.length;e+=t)o.set(n.positions.subarray(3*e,3*e+3),3*i),a.set(n.colors.subarray(3*e,3*e+3),3*i),r[i]=n.deviations[e],l[i]=n.slopes[e],i+=1;return{positions:o,colors:a,deviations:r,slopes:l}}(u),loading:!1,error:null})}catch(e){a.signal.aborted||l({points:null,loading:!1,error:e instanceof Error?e.message:"LiDAR tile load failed"})}})(),()=>a.abort()},[e,t,n,o.join("|")]),r}(l,u,c,C);return((0,a.useEffect)(()=>f(P.points),[f,P.points]),(0,a.useEffect)(()=>g(P.loading,P.error),[g,P.error,P.loading]),(0,i.D)((e,t)=>{if(R.current+=t,R.current<.2)return;R.current=0,S.updateMatrixWorld();let n=function(e,t,n){var o,a;let r=new s.kn4().multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse),l=new s.PPD().setFromProjectionMatrix(r),i="fov"in t&&"number"==typeof t.fov?t.fov*Math.PI/180:Math.PI/3,u=null!=(o=e.nodes.find(e=>"r"===e.id))?o:e.nodes[0];if(!u)return[];let c=h(u),d=Math.max(t.position.distanceTo(new s.Pq0(...c)),.05),p=.5*Math.max(u.bounds.max[0]-u.bounds.min[0],u.bounds.max[1]-u.bounds.min[1],u.bounds.max[2]-u.bounds.min[2],.01)*n/(d*Math.tan(.5*i)),m=Math.max(null!=(a=e.spacing)?a:.05,.01),f=Math.min(e.nodes.reduce((e,t)=>Math.max(e,t.level),0),Math.max(0,Math.floor(Math.log2(Math.max(p/(40*m),1))))),g=e.nodes.filter(e=>!!e.path&&!(e.level>f)&&l.intersectsBox(new s.NRn(new s.Pq0(...e.bounds.min),new s.Pq0(...e.bounds.max)))),x=g.filter(e=>!g.some(t=>t.level>e.level&&t.id.startsWith(e.id)));return x.length?x.sort((e,t)=>h(e)[0]-h(t)[0]).slice(0,36).map(e=>e.id):g.slice(0,Math.min(4,g.length)).map(e=>e.id)}(c,S,k.height),o=n.join(",");o&&o!==z.current&&(z.current=o,E(n))}),P.points)?(0,o.jsx)(m,{points:P.points,mode:d,pointSize:p,onPoint:x,sectionMode:b,onSectionStart:v,onSectionEnd:w,regionMode:M,onRegionStart:y,onRegionEnd:j}):null}function g(e){let{profile:t}=e;if(t.length<2)return(0,o.jsx)("p",{className:"text-xs text-zinc-500",children:"No points crossed that section."});let n=t.map(e=>{let[t]=e;return t}),a=t.map(e=>{let[,t]=e;return t}),r=Math.min(...n),l=Math.min(...a),i=Math.max(Math.max(...n)-r,1e-6),s=Math.max(Math.max(...a)-l,1e-6),u=t.map((e,t)=>{let[n,o]=e;return"".concat(t?"L":"M"," ").concat((n-r)/i*180+10," ").concat(90-(o-l)/s*80)}).join(" ");return(0,o.jsx)("svg",{viewBox:"0 0 200 100",className:"h-24 w-full",role:"img","aria-label":"Elevation profile",children:(0,o.jsx)("path",{d:u,fill:"none",stroke:"var(--twin360-blue)",strokeWidth:"1.5"})})}function x(e){let{baseUrl:t,modelId:n}=e,{manifest:l,loading:i,error:h}=function(e,t){let[n,o]=(0,a.useState)({manifest:null,loading:!0,error:null});return(0,a.useEffect)(()=>{let n=new AbortController;return o({manifest:null,loading:!0,error:null}),(async()=>{try{let a=t?"?modelId=".concat(encodeURIComponent(t)):"",r=await fetch("".concat(e,"/hierarchy.json").concat(a),{signal:n.signal});if(!r.ok)throw Error("LiDAR hierarchy unavailable");let l=await r.json();n.signal.aborted||o({manifest:l,loading:!1,error:null})}catch(e){n.signal.aborted||o({manifest:null,loading:!1,error:e instanceof Error?e.message:"LiDAR hierarchy failed"})}})(),()=>n.abort()},[e,t]),n}(t,n),[m,x]=(0,a.useState)(null),[b,v]=(0,a.useState)(!1),[w,M]=(0,a.useState)(null),[y,j]=(0,a.useState)("rgb"),[S,k]=(0,a.useState)("navigate"),[D,C]=(0,a.useState)(null),[E,z]=(0,a.useState)(null),[R,P]=(0,a.useState)([]),[A,N]=(0,a.useState)(null),_=(0,a.useMemo)(()=>l?l.bounds.min.map((e,t)=>(e+l.bounds.max[t])/2):[0,0,0],[l]),F=(0,a.useMemo)(()=>l?Math.max(...l.bounds.max.map((e,t)=>e-l.bounds.min[t]),1):10,[l]),I=(0,a.useCallback)(e=>{if("measure"===S){if(!D){C(e),z(null);return}z(D.distanceTo(e)),C(null)}},[D,S]),L=(0,a.useCallback)(e=>{C(e),P([]),z(null),N(null)},[]),T=(0,a.useCallback)(e=>{"section"===S&&D&&m&&(P(function(e,t,n){let o=new s.I9Y(n.x-t.x,n.y-t.y),a=o.length();if(a<1e-6)return[];o.normalize();let r=Math.max(.02*a,.02),l=[];for(let n=0;n<e.deviations.length;n+=1){let i=e.positions[3*n]-t.x,s=e.positions[3*n+1]-t.y,u=i*o.x+s*o.y,c=Math.abs(i*o.y-s*o.x);u>=0&&u<=a&&c<=r&&l.push([u,e.positions[3*n+2]])}return l.sort((e,t)=>
1e[0]-t[0]).slice(0,256)}(m,D,e)),C(null))},[D,m,S]),U=(0,a.useCallback)(e=>{C(e),N(null),z(null),P([])},[]),q=(0,a.useCallback)(e=>{"region"===S&&D&&m&&(N(function(e,t,n){let o=Math.min(t.x,n.x),a=Math.max(t.x,n.x),r=Math.min(t.y,n.y),l=Math.max(t.y,n.y),i=[];for(let t=0;t<e.deviations.length;t+=1){let n=e.positions[3*t],s=e.positions[3*t+1];n>=o&&n<=a&&s>=r&&s<=l&&i.push([n,s,e.positions[3*t+2]])}if(i.length<3)return null;let s=[[0,0,0,0],[0,0,0,0],[0,0,0,0]];for(let[e,t,n]of i)s[0][0]+=e*e,s[0][1]+=e*t,s[0][2]+=e,s[0][3]+=e*n,s[1][0]+=e*t,s[1][1]+=t*t,s[1][2]+=t,s[1][3]+=t*n,s[2][0]+=e,s[2][1]+=t,s[2][2]+=1,s[2][3]+=n;for(let e=0;e<3;e+=1){let t=e;for(let n=e+1;n<3;n+=1)Math.abs(s[n][e])>Math.abs(s[t][e])&&(t=n);if(1e-9>Math.abs(s[t][e]))return null;[s[e],s[t]]=[s[t],s[e]];let n=s[e][e];for(let t=e;t<4;t+=1)s[e][t]/=n;for(let t=0;t<3;t+=1){if(t===e)continue;let n=s[t][e];for(let o=e;o<4;o+=1)s[t][o]-=n*s[e][o]}}let[u,c,d]=s.map(e=>e[3]),p=i.map(e=>{let[t,n,o]=e;return o-(u*t+c*n+d)});return{pointCount:i.length,slopeDegrees:180*Math.atan(Math.hypot(u,c))/Math.PI,rmsDeviationM:Math.sqrt(p.reduce((e,t)=>e+t*t,0)/p.length),minDeviationM:Math.min(...p),maxDeviationM:Math.max(...p)}}(m,D,e)),C(null))},[D,m,S]),B=(0,a.useCallback)((e,t)=>{v(e),M(t)},[]);return i?(0,o.jsx)("div",{className:"flex h-full items-center justify-center text-xs text-zinc-400",children:"Loading LiDAR hierarchyâ¦"}):h||!l?(0,o.jsx)("div",{className:"flex h-full items-center justify-center px-6 text-center text-xs text-zinc-400",children:null!=h?h:"LiDAR point cloud unavailable"}):(0,o.jsxs)("div",{className:"relative h-full w-full bg-[var(--graphite-canvas)]",children:[(0,o.jsxs)(r.Hl,{className:"absolute inset-0 touch-none",gl:{antialias:!1,alpha:!0},children:[(0,o.jsx)(u,{makeDefault:!0,position:[_[0]+F,_[1]+F,_[2]+F],fov:50,near:.01,far:20*F}),(0,o.jsx)(f,{baseUrl:t,modelId:n,manifest:l,mode:y,pointSize:Math.max(F/700,.004),onPointsChange:x,onStatus:B,onPoint:I,sectionMode:"section"===S,onSectionStart:L,onSectionEnd:T,regionMode:"region"===S,onRegionStart:U,onRegionEnd:q}),(0,o.jsx)(c.N,{makeDefault:!0,target:_,enableDamping:!0,dampingFactor:.08})]}),(0,o.jsxs)("div",{className:"absolute left-3 top-3 z-10 flex flex-wrap items-center gap-2 rounded-xl border border-white/10 bg-[color-mix(in_srgb,var(--graphite-canvas)_90%,transparent)] p-2 backdrop-blur-md",children:[(0,o.jsxs)("label",{className:"font-mono text-[10px] uppercase tracking-wide text-zinc-400",children:["Color",(0,o.jsxs)("select",{value:y,onChange:e=>j(e.target.value),className:"ml-2 rounded-lg border border-white/10 bg-white/[0.04] px-2 py-1 text-xs text-zinc-100",children:[(0,o.jsx)("option",{value:"rgb",children:"RGB"}),(0,o.jsx)("option",{value:"deviation",children:"Deviation"}),(0,o.jsx)("option",{value:"slope",children:"Slope"})]})]}),["navigate","measure","section","region"].map(e=>(0,o.jsx)("button",{type:"button",onClick:()=>{k(e),C(null),z(null),P([]),N(null)},className:(0,d.cn)("rounded-lg border px-2 py-1 text-[10px] uppercase tracking-wide",S===e?p.t.button:"border-white/10 text-zinc-400"),children:e},e))]}),(b||w)&&(0,o.jsx)("p",{className:"absolute right-3 top-3 z-10 rounded-xl border border-white/10 bg-[color-mix(in_srgb,var(--graphite-canvas)_90%,transparent)] px-3 py-2 text-xs text-zinc-300",children:null!=w?w:"Loading visible point tilesâ¦"}),"navigate"!==S&&(0,o.jsx)("p",{className:"absolute bottom-3 left-3 z-10 rounded-xl border border-white/10 bg-[color-mix(in_srgb,var(--graphite-canvas)_90%,transparent)] px-3 py-2 text-xs text-zinc-300",children:"measure"===S?"Select two points to measure distance.":"section"===S?"Drag from one point to another to build a section profile.":"Drag across two corners to calculate regional flatness."}),null!==E&&(0,o.jsxs)("p",{className:"absolute right-3 top-14 z-10 rounded-xl border border-white/10 bg-[color-mix(in_srgb,var(--graphite-canvas)_90%,transparent)] px-3 py-2 font-mono text-xs text-zinc-200",children:["Distance ",E.toFixed(3)," m"]}),A&&(0,o.jsxs)("p",{className:"absolute right-3 top-14 z-10 max-w-64 rounded-xl border border-white/10 bg-[color-mix(in_srgb,var(--graphite-canvas)_90%,transparent)] px-3 py-2 font-mono text-xs text-zinc-200",children:["Region ",A.pointCount," points \xb7 slope ",A.slopeDegrees.toFixed(2),"\xb0 \xb7 RMS"," ",A.rmsDeviationM.toFixed(4)," m \xb7 range ",A.minDeviationM.toFixed(4),"â",A.maxDeviationM.toFixed(4)," m"]}),R.length>1&&(0,o.jsxs)("aside",{className:"absolute bottom-3 right-3 z-10 w-64 roun
1ded-xl border border-white/10 bg-[color-mix(in_srgb,var(--graphite-canvas)_94%,transparent)] p-3 backdrop-blur-md",children:[(0,o.jsx)("p",{className:"mb-1 font-mono text-[10px] uppercase tracking-wide text-zinc-400",children:"Elevation profile"}),(0,o.jsx)(g,{profile:R})]})]})}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.