@ifc-lite/viewer 1.17.4 → 1.17.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +16 -16
- package/.turbo/turbo-typecheck.log +1 -1
- package/CHANGELOG.md +117 -0
- package/DESKTOP_CONTRACT_VERSION +1 -1
- package/dist/assets/{basketViewActivator-BmnNtVfZ.js → basketViewActivator-86rgogji.js} +1 -1
- package/dist/assets/drawing-2d-DoxKMqbO.js +257 -0
- package/dist/assets/{exporters-ChAtBmlj.js → exporters-CcPS9MK5.js} +2274 -2227
- package/dist/assets/{geometry.worker-BQ0rzNo-.js → geometry.worker-BFUYA08u.js} +1 -1
- package/dist/assets/ids-DQ5jY0E8.js +1 -0
- package/dist/assets/ifc-lite_bg-BINvzoCP.wasm +0 -0
- package/dist/assets/{index-Co8E2-FE.js → index-Bfms9I4A.js} +35160 -33084
- package/dist/assets/index-_bfZsDCC.css +1 -0
- package/dist/assets/{native-bridge-BRvbckFQ.js → native-bridge-DUyLCMZS.js} +104 -104
- package/dist/assets/{sandbox-DZiNLNMk.js → sandbox-C8575tul.js} +4340 -4322
- package/dist/assets/{server-client-BV8zHZ7Y.js → server-client-BuZK7OST.js} +1 -1
- package/dist/assets/{wasm-bridge-g01g7T9b.js → wasm-bridge-JsqEGDV8.js} +1 -1
- package/dist/index.html +8 -7
- package/index.html +1 -0
- package/package.json +7 -7
- package/src/App.tsx +16 -2
- package/src/components/viewer/CesiumOverlay.tsx +62 -19
- package/src/components/viewer/ChatPanel.tsx +195 -91
- package/src/components/viewer/MainToolbar.tsx +4 -3
- package/src/components/viewer/PropertiesPanel.tsx +16 -2
- package/src/components/viewer/SettingsPage.tsx +252 -101
- package/src/components/viewer/ThemeSwitch.tsx +63 -7
- package/src/components/viewer/ViewerLayout.tsx +1 -0
- package/src/components/viewer/Viewport.tsx +14 -2
- package/src/components/viewer/ViewportContainer.tsx +49 -64
- package/src/components/viewer/ViewportOverlays.tsx +5 -2
- package/src/components/viewer/bcf/BCFTopicDetail.tsx +4 -4
- package/src/components/viewer/chat/ModelSelector.tsx +90 -54
- package/src/components/viewer/properties/GeoreferencingPanel.tsx +113 -51
- package/src/components/viewer/properties/LocationMap.tsx +9 -7
- package/src/components/viewer/properties/ModelMetadataPanel.tsx +1 -1
- package/src/components/viewer/tools/SectionCapControls.tsx +237 -0
- package/src/components/viewer/tools/SectionPanel.tsx +39 -18
- package/src/components/viewer/useAnimationLoop.ts +9 -1
- package/src/components/viewer/useRenderUpdates.ts +1 -1
- package/src/hooks/ids/idsDataAccessor.ts +60 -24
- package/src/hooks/ingest/viewerModelIngest.ts +7 -2
- package/src/hooks/useIfcFederation.ts +326 -71
- package/src/hooks/useIfcLoader.ts +1 -0
- package/src/hooks/useViewControls.ts +13 -5
- package/src/index.css +484 -10
- package/src/lib/desktop-entitlement.ts +2 -4
- package/src/lib/geo/cesium-bridge.ts +15 -7
- package/src/lib/geo/effective-georef.test.ts +73 -0
- package/src/lib/geo/effective-georef.ts +111 -0
- package/src/lib/geo/reproject.ts +105 -19
- package/src/lib/llm/byok-guard.test.ts +77 -0
- package/src/lib/llm/byok-guard.ts +39 -0
- package/src/lib/llm/free-models.test.ts +0 -6
- package/src/lib/llm/models.ts +104 -42
- package/src/lib/llm/stream-client.ts +74 -110
- package/src/lib/llm/stream-direct.test.ts +130 -0
- package/src/lib/llm/stream-direct.ts +316 -0
- package/src/lib/llm/types.ts +14 -2
- package/src/main.tsx +1 -10
- package/src/services/api-keys.ts +73 -0
- package/src/store/constants.ts +20 -2
- package/src/store/index.ts +12 -5
- package/src/store/slices/cesiumSlice.ts +5 -0
- package/src/store/slices/chatSlice.test.ts +6 -76
- package/src/store/slices/chatSlice.ts +17 -58
- package/src/store/slices/sectionSlice.test.ts +87 -7
- package/src/store/slices/sectionSlice.ts +151 -5
- package/src/store/slices/uiSlice.ts +28 -5
- package/src/store/types.ts +26 -0
- package/src/utils/nativeSpatialDataStore.ts +4 -1
- package/src/utils/viewportUtils.ts +7 -2
- package/src/vite-env.d.ts +0 -4
- package/dist/assets/drawing-2d-gWfpdfYe.js +0 -257
- package/dist/assets/ids-B4jTqB1O.js +0 -1
- package/dist/assets/ifc-lite_bg-BX4E7TX8.wasm +0 -0
- package/dist/assets/index-DckuDqlv.css +0 -1
- package/src/components/viewer/UpgradePage.tsx +0 -71
- package/src/lib/desktop/ClerkDesktopEntitlementSync.tsx +0 -175
- package/src/lib/llm/ClerkChatSync.tsx +0 -74
- package/src/lib/llm/clerk-auth.ts +0 -62
|
@@ -1,257 +0,0 @@
|
|
|
1
|
-
const wt={projectionDepth:10,includeHiddenLines:!0,creaseAngle:30,scale:100};function W(n,t){return`${n}:${t}`}const $=1e-7;function G(n,t,e){return{x:n,y:t,z:e}}function Z(n,t){return{x:n.x-t.x,y:n.y-t.y,z:n.z-t.z}}function _(n,t){return n.x*t.x+n.y*t.y+n.z*t.z}function Ft(n,t){return{x:n.y*t.z-n.z*t.y,y:n.z*t.x-n.x*t.z,z:n.x*t.y-n.y*t.x}}function St(n){return Math.sqrt(n.x*n.x+n.y*n.y+n.z*n.z)}function J(n){const t=St(n);return t<$?{x:0,y:0,z:0}:{x:n.x/t,y:n.y/t,z:n.z/t}}function $t(n,t,e){return{x:n.x+e*(t.x-n.x),y:n.y+e*(t.y-n.y),z:n.z+e*(t.z-n.z)}}function z(n,t){return{x:n.x-t.x,y:n.y-t.y}}function At(n,t){return n.x*t.x+n.y*t.y}function Pt(n){return Math.sqrt(n.x*n.x+n.y*n.y)}function R(n,t){const e=t.x-n.x,i=t.y-n.y;return Math.sqrt(e*e+i*i)}function K(n,t,e){return{x:n.x+e*(t.x-n.x),y:n.y+e*(t.y-n.y)}}function Lt(n){const t=Pt(n);return t<$?{x:0,y:0}:{x:n.x/t,y:n.y/t}}function Q(n,t){return n.x*t.y-n.y*t.x}function tt(n){return R(n.start,n.end)}function Y(n){return Lt(z(n.end,n.start))}function lt(){return{min:{x:1/0,y:1/0},max:{x:-1/0,y:-1/0}}}function H(n,t){return{min:{x:Math.min(n.min.x,t.x),y:Math.min(n.min.y,t.y)},max:{x:Math.max(n.max.x,t.x),y:Math.max(n.max.y,t.y)}}}function Et(n,t){let e=H(n,t.start);return e=H(e,t.end),e}function kt(n){return{x:(n.min.x+n.max.x)/2,y:(n.min.y+n.max.y)/2}}function vt(n){return{x:n.max.x-n.min.x,y:n.max.y-n.min.y}}function N(n,t,e){return _(n,t)-e}function ct(n,t){const e=t?-1:1;switch(n){case"x":return{x:e,y:0,z:0};case"y":return{x:0,y:e,z:0};case"z":return{x:0,y:0,z:e}}}function ht(n){switch(n){case"x":return{u:"z",v:"y"};case"y":return{u:"x",v:"z"};case"z":return{u:"x",v:"y"}}}function D(n,t,e){const i=ht(t),s=n[i.u],o=n[i.v];return{x:e?-s:s,y:o}}function dt(n){if(n.length<3)return 0;let t=0;for(let e=0;e<n.length;e++){const i=(e+1)%n.length;t+=n[e].x*n[i].y,t-=n[i].x*n[e].y}return t/2}function ut(n){return dt(n)>0}function ft(n){return[...n].reverse()}function Tt(n){return ut(n)?n:ft(n)}function Rt(n){return ut(n)?ft(n):n}class gt{tolerance;constructor(t=1e-4){this.tolerance=t}buildPolygons(t){const e=new Map;for(const s of t){const o=W(s.modelIndex,s.entityId);e.has(o)||e.set(o,[]),e.get(o).push(s)}const i=[];for(const[s,o]of e){const r=this.buildEntityPolygons(o);i.push(r)}return i.flat()}buildEntityPolygons(t){if(t.length===0)return[];const e=t[0],{entityId:i,ifcType:s,modelIndex:o}=e,r=t.map(c=>({start:c.p0_2d,end:c.p1_2d,used:!1})),a=this.buildLoops(r);return a.length===0?[]:this.classifyLoops(a).map(c=>({polygon:{outer:c.outer,holes:c.holes},entityId:i,ifcType:s,modelIndex:o,isCut:!0}))}buildLoops(t){const e=[];for(;;){const i=t.findIndex(o=>!o.used);if(i===-1)break;const s=this.buildSingleLoop(t,i);if(s&&s.length>=3){const o=dt(s);e.push({points:s,area:o})}}return e}buildSingleLoop(t,e){const i=[],s=t[e];s.used=!0,i.push(s.start);let o=s.end;const r=s.start,a=t.length;let l=0;for(;l<a;){if(l++,R(o,r)<this.tolerance)return i;const c=this.findConnectingSegment(t,o);if(c===-1)break;const u=t[c];u.used=!0,R(u.start,o)<this.tolerance?(i.push(u.start),o=u.end):(i.push(u.end),o=u.start)}return i.length>=3?i:null}findConnectingSegment(t,e){let i=-1,s=this.tolerance;for(let o=0;o<t.length;o++){if(t[o].used)continue;const r=t[o],a=R(r.start,e);a<s&&(s=a,i=o);const l=R(r.end,e);l<s&&(s=l,i=o)}return i}classifyLoops(t){if(t.length===0)return[];const e=[...t].sort((o,r)=>Math.abs(r.area)-Math.abs(o.area)),i=[],s=new Set;for(let o=0;o<e.length;o++){if(s.has(o))continue;const r=e[o],a=Tt(r.points),l=[];for(let c=o+1;c<e.length;c++){if(s.has(c))continue;const u=e[c];this.isLoopContainedIn(u.points,a)&&(l.push(Rt(u.points)),s.add(c))}s.add(o),i.push({outer:a,holes:l})}return i}isLoopContainedIn(t,e){const i=t[0];return this.pointInPolygon(i,e)}pointInPolygon(t,e){let i=!1;const s=e.length;for(let o=0,r=s-1;o<s;r=o++){const a=e[o],l=e[r];a.y>t.y!=l.y>t.y&&t.x<(l.x-a.x)*(t.y-a.y)/(l.y-a.y)+a.x&&(i=!i)}return i}}class Dt{planeNormal;planeDistance;axis;flipped;constructor(t){this.axis=t.axis,this.flipped=t.flipped,this.planeNormal=ct(t.axis,t.flipped),this.planeDistance=t.position}cutMeshes(t){const e=performance.now(),i=[];let s=0,o=0;for(const u of t){const h=this.cutSingleMesh(u);i.push(h.segments),s+=h.trianglesProcessed,o+=h.trianglesIntersected}const r=i.flat(),l=new gt().buildPolygons(r),c=performance.now()-e;return{segments:r,polygons:l,stats:{totalTriangles:s,intersectedTriangles:o,segmentCount:r.length,polygonCount:l.length,processingTimeMs:c}}}cutSingleMesh(t){const e=[],{positions:i,indices:s,expressId:o,ifcType:r,modelIndex:a}=t,l=s.length/3;let c=0;for(let u=0;u<l;u++){const h=s[u*3],d=s[u*3+1],f=s[u*3+2],g=this.getVertex(i,h),y=this.getVertex(i,d),p=this.getVertex(i,f),m=N(g,this.planeNormal,this.planeDistance),I=N(y,this.planeNormal,this.planeDistance),w=N(p,this.planeNormal,this.planeDistance),x=this.intersectTrianglePlane(g,y,p,m,I,w);if(x){c++;const C=D(x.p0,this.axis,this.flipped),b=D(x.p1,this.axis,this.flipped),A=b.x-C.x,M=b.y-C.y;if(A*A+M*M<$*$)continue;e.push({p0:x.p0,p1:x.p1,p0_2d:C,p1_2d:b,entityId:o,ifcType:r||"Unknown",modelIndex:a||0})}}return{segments:e,trianglesProcessed:l,trianglesIntersected:c}}getVertex(t,e){const i=e*3;return G(t[i],t[i+1],t[i+2])}intersectTrianglePlane(t,e,i,s,o,r){const a=(s>$?1:0)+(o>$?1:0)+(r>$?1:0),l=(s<-$?1:0)+(o<-$?1:0)+(r<-$?1:0);if(a===3||l===3||a===0&&l===0)return null;const c=[],u=this.edgePlaneIntersection(t,e,s,o);u&&c.push(u);const h=this.edgePlaneIntersection(e,i,o,r);if(h&&c.push(h),c.length<2){const d=this.edgePlaneIntersection(i,t,r,s);d&&c.push(d)}return c.length>=2?{p0:c[0],p1:c[1]}:null}edgePlaneIntersection(t,e,i,s){if(Math.abs(i)<$&&Math.abs(s)<$)return null;if(Math.abs(i)<$)return t;if(Math.abs(s)<$)return e;if(i>0==s>0)return null;const o=i/(i-s);return $t(t,e,o)}}const pt={angleTolerance:.01,distanceTolerance:.001,gapTolerance:.01};function Wt(n,t={}){const e={...pt,...t},i=new Map;for(const o of n){const r=`${o.modelIndex}:${o.entityId}:${o.category}:${o.visibility}`;i.has(r)||i.set(r,[]),i.get(r).push(o)}const s=[];for(const o of i.values()){const r=_t(o,e);s.push(...r)}return s}function _t(n,t){if(n.length<=1)return n;const e=n.map(o=>o.line),i=zt(e,t),s=n[0];return i.map(o=>({...s,line:o}))}function zt(n,t={}){const e={...pt,...t};if(n.length<=1)return n;const i=Bt(n,e.angleTolerance),s=[];for(const o of i.values()){const r=Nt(o,e.distanceTolerance);for(const a of r){const l=Ht(a,e.gapTolerance);s.push(...l)}}return s}function Bt(n,t){const e=new Map,i=t*2;for(const s of n){const o=Y(s);let r=Math.atan2(o.y,o.x);r<0&&(r+=Math.PI),r>=Math.PI&&(r-=Math.PI);const a=Math.floor(r/i);e.has(a)||e.set(a,[]),e.get(a).push(s)}return e}function Nt(n,t){const e=[],i=new Set;for(let s=0;s<n.length;s++){if(i.has(s))continue;const o=[n[s]];i.add(s);for(let r=s+1;r<n.length;r++)i.has(r)||Ot(n[s],n[r],t)&&(o.push(n[r]),i.add(r));e.push(o)}return e}function Ot(n,t,e){const i=Y(n),s=z(t.start,n.start);if(Math.abs(Q(i,s))>e)return!1;const r=z(t.end,n.start);return Math.abs(Q(i,r))<=e}function Ht(n,t){if(n.length<=1)return n;const e=n[0],i=Y(e),s=e.start,o=n.map(l=>{const c=et(l.start,s,i),u=et(l.end,s,i);return{t0:Math.min(c,u),t1:Math.max(c,u)}});o.sort((l,c)=>l.t0-c.t0);const r=[];let a=o[0];for(let l=1;l<o.length;l++){const c=o[l];c.t0<=a.t1+t?a={t0:a.t0,t1:Math.max(a.t1,c.t1)}:(r.push(a),a=c)}return r.push(a),r.map(l=>({start:{x:s.x+i.x*l.t0,y:s.y+i.y*l.t0},end:{x:s.x+i.x*l.t1,y:s.y+i.y*l.t1}}))}function et(n,t,e){const i=z(n,t);return At(i,e)}class Ut{creaseAngle;constructor(t=30){this.creaseAngle=t*Math.PI/180}extractEdges(t){const{positions:e,indices:i,expressId:s,ifcType:o,modelIndex:r}=t,a=new Map,l=[],c=i.length/3;for(let h=0;h<c;h++){const d=i[h*3],f=i[h*3+1],g=i[h*3+2],y=this.getVertex(e,d),p=this.getVertex(e,f),m=this.getVertex(e,g),I=this.computeFaceNormal(y,p,m);l.push(I),this.registerEdge(a,d,f,h),this.registerEdge(a,f,g,h),this.registerEdge(a,g,d,h)}const u=[];for(const[,h]of a){const d=this.getVertex(e,h.v0Idx),f=this.getVertex(e,h.v1Idx);let g=null,y=null,p=0,m="smooth";if(h.faceIndices.length===1)m="boundary",g=l[h.faceIndices[0]];else if(h.faceIndices.length>=2){g=l[h.faceIndices[0]],y=l[h.faceIndices[1]];const I=Math.max(-1,Math.min(1,_(g,y)));p=Math.acos(I),p>this.creaseAngle&&(m="crease")}m!=="smooth"&&u.push({v0:d,v1:f,face0Normal:g,face1Normal:y,dihedralAngle:p,type:m,entityId:s,ifcType:o||"Unknown",modelIndex:r||0})}return u}extractEdgesFromMeshes(t){const e=[];for(const i of t){const s=this.extractEdges(i);e.push(...s)}return e}extractSilhouettes(t,e){const i=J(e);return t.filter(s=>{if(s.type==="boundary")return!0;if(!s.face0Normal||!s.face1Normal)return!1;const o=_(s.face0Normal,i),r=_(s.face1Normal,i);return o<0!=r<0})}edgesToDrawingLines(t,e,i,s,o){return t.map(r=>{const a=D(r.v0,e,i),l=D(r.v1,e,i),c=e,u=Math.min(Math.abs(r.v0[c]-o),Math.abs(r.v1[c]-o));return{line:{start:a,end:l},category:s,visibility:"visible",entityId:r.entityId,ifcType:r.ifcType,modelIndex:r.modelIndex,depth:u}})}filterEdgesByDepth(t,e,i,s,o){return t.filter(r=>{const a=r.v0[e]-i,l=r.v1[e]-i,c=o?-s:0,u=o?0:s,h=a>=c&&a<=u,d=l>=c&&l<=u,f=a<c&&l>u||l<c&&a>u;return h||d||f})}getVertex(t,e){const i=e*3;return G(t[i],t[i+1],t[i+2])}computeFaceNormal(t,e,i){const s=Z(e,t),o=Z(i,t),r=Ft(s,o);return J(r)}registerEdge(t,e,i,s){const o=Math.min(e,i),r=Math.max(e,i),a=`${o}:${r}`;t.has(a)||t.set(a,{v0Idx:o,v1Idx:r,faceIndices:[]}),t.get(a).faceIndices.push(s)}}function jt(n,t){const e=t?1:-1;switch(n){case"x":return{x:e,y:0,z:0};case"y":return{x:0,y:e,z:0};case"z":return{x:0,y:0,z:e}}}function Gt(n,t,e){const i=[];for(const s of n){if(!Yt(s,t,e))continue;nt(i,s,s.outerPoints,"projection",t);let o=0;for(let r=0;r<s.holeCounts.length;r++){const a=s.holeCounts[r];if(a<2||o+a*2>s.holePoints.length){o+=a*2;continue}const l=s.holePoints.subarray(o,o+a*2);nt(i,s,l,"projection",t),o+=a*2}}return i}function Yt(n,t,e){const{axis:i,position:s,flipped:o}=t,{min:r,max:a}=Xt(n,i),l=o?s-e:s,c=o?s:s+e;return r<=c&&a>=l}function nt(n,t,e,i,s){const o=Math.floor(e.length/2);if(o<2)return;const r=t.transform;for(let a=0;a<o;a++){const l=(a+1)%o,c=e[a*2],u=e[a*2+1],h=e[l*2],d=e[l*2+1],f=U(c,u,r),g=U(h,d,r),y=D(f,s.axis,s.flipped),p=D(g,s.axis,s.flipped);Math.abs(y.x-p.x)<1e-7&&Math.abs(y.y-p.y)<1e-7||n.push({line:{start:y,end:p},category:i,visibility:"visible",entityId:t.expressId,ifcType:t.ifcType,modelIndex:t.modelIndex,depth:qt(f,g,s.axis,s.position)})}}function U(n,t,e){return{x:e[0]*n+e[4]*t+e[12],y:e[1]*n+e[5]*t+e[13],z:e[2]*n+e[6]*t+e[14]}}function Vt(n,t){return n[12+yt(t)]}function Xt(n,t){const e=t,i=n.extrusionDir[yt(t)]*n.extrusionDepth;let s=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY;const r=a=>{const l=Math.floor(a.length/2);for(let c=0;c<l;c++){const h=U(a[c*2],a[c*2+1],n.transform)[e],d=h+i;s=Math.min(s,h,d),o=Math.max(o,h,d)}};if(r(n.outerPoints),r(n.holePoints),!Number.isFinite(s)||!Number.isFinite(o)){const a=Vt(n.transform,t),l=a+i;return{min:Math.min(a,l),max:Math.max(a,l)}}return{min:s,max:o}}function yt(n){return n==="x"?0:n==="y"?1:2}function qt(n,t,e,i){const s=(n[e]+t[e])/2;return Math.abs(s-i)}const Zt={resolution:1024,samplesPerLine:10,depthBias:.001};class Jt{options;depthBuffer=null;width=0;height=0;bounds=null;constructor(t={}){this.options={...Zt,...t}}buildDepthBuffer(t,e,i,s,o,r){r||(r=this.computeBounds(t,e,i,s,o)),this.bounds=r;const a=r.max.x-r.min.x,l=r.max.y-r.min.y;if(a<$||l<$){this.width=1,this.height=1,this.depthBuffer=new Float32Array([1/0]);return}const c=a/l;c>1?(this.width=this.options.resolution,this.height=Math.max(1,Math.floor(this.options.resolution/c))):(this.height=this.options.resolution,this.width=Math.max(1,Math.floor(this.options.resolution*c))),this.depthBuffer=new Float32Array(this.width*this.height),this.depthBuffer.fill(1/0);for(const u of t)this.rasterizeMesh(u,e,i,s,o)}classifyLines(t){if(!this.depthBuffer||!this.bounds)throw new Error("Depth buffer not built. Call buildDepthBuffer first.");const e=[];for(const i of t){const s=this.classifySingleLine(i);e.push(s)}return e}applyVisibility(t){const e=this.classifyLines(t),i=[];for(const s of e)if(s.overallVisibility==="visible")i.push({...s.line,visibility:"visible"});else if(s.overallVisibility==="hidden")i.push({...s.line,visibility:"hidden"});else for(const o of s.segments)i.push({...s.line,line:{start:o.start,end:o.end},visibility:o.visible?"visible":"hidden"});return i}computeBounds(t,e,i,s,o){let r=lt();const a=this.getProjectionAxes(e);for(const c of t){const{positions:u}=c,h=u.length/3;for(let d=0;d<h;d++){const f=u[d*3],g=u[d*3+1],y=u[d*3+2],p={x:f,y:g,z:y},m=p[e]-i;if(o?m<=0&&m>=-s:m>=0&&m<=s){const w=p[a.u],x=p[a.v],C={x:o?-w:w,y:x};r=H(r,C)}}}const l=Math.max(r.max.x-r.min.x,r.max.y-r.min.y)*.01;return r.min.x-=l,r.min.y-=l,r.max.x+=l,r.max.y+=l,r}getProjectionAxes(t){switch(t){case"x":return{u:"z",v:"y"};case"y":return{u:"x",v:"z"};case"z":return{u:"x",v:"y"}}}rasterizeMesh(t,e,i,s,o){const{positions:r,indices:a}=t,l=this.getProjectionAxes(e),c=a.length/3;for(let u=0;u<c;u++){const h=a[u*3],d=a[u*3+1],f=a[u*3+2],g=this.getVertex(r,h),y=this.getVertex(r,d),p=this.getVertex(r,f),m=g[e]-i,I=y[e]-i,w=p[e]-i,x=M=>o?M<=0&&M>=-s:M>=0&&M<=s;if(!x(m)&&!x(I)&&!x(w))continue;const C=this.projectVertex(g,l,o),b=this.projectVertex(y,l,o),A=this.projectVertex(p,l,o);this.rasterizeTriangle(C,b,A)}}getVertex(t,e){const i=e*3;return G(t[i],t[i+1],t[i+2])}projectVertex(t,e,i){const s=t[e.u],o=t[e.v],a=["x","y","z"].find(l=>l!==e.u&&l!==e.v)??"z";return{x:i?-s:s,y:o,depth:t[a]}}rasterizeTriangle(t,e,i){if(!this.bounds||!this.depthBuffer)return;const s=f=>(f-this.bounds.min.x)/(this.bounds.max.x-this.bounds.min.x)*(this.width-1),o=f=>(f-this.bounds.min.y)/(this.bounds.max.y-this.bounds.min.y)*(this.height-1),r={x:s(t.x),y:o(t.y),depth:t.depth},a={x:s(e.x),y:o(e.y),depth:e.depth},l={x:s(i.x),y:o(i.y),depth:i.depth},c=Math.max(0,Math.floor(Math.min(r.x,a.x,l.x))),u=Math.min(this.width-1,Math.ceil(Math.max(r.x,a.x,l.x))),h=Math.max(0,Math.floor(Math.min(r.y,a.y,l.y))),d=Math.min(this.height-1,Math.ceil(Math.max(r.y,a.y,l.y)));for(let f=h;f<=d;f++)for(let g=c;g<=u;g++){const y=this.barycentricCoords(g+.5,f+.5,r,a,l);if(y.u>=0&&y.v>=0&&y.w>=0){const p=y.u*r.depth+y.v*a.depth+y.w*l.depth,m=f*this.width+g;p<this.depthBuffer[m]&&(this.depthBuffer[m]=p)}}}barycentricCoords(t,e,i,s,o){const r=s.x-i.x,a=s.y-i.y,l=o.x-i.x,c=o.y-i.y,u=t-i.x,h=e-i.y,d=r*r+a*a,f=r*l+a*c,g=r*u+a*h,y=l*l+c*c,p=l*u+c*h,m=d*y-f*f;if(Math.abs(m)<1e-10)return{u:-1,v:-1,w:-1};const I=1/m,w=(y*g-f*p)*I,x=(d*p-f*g)*I;return{u:1-w-x,v:w,w:x}}classifySingleLine(t){if(!this.bounds||!this.depthBuffer)return{line:t,segments:[{start:t.line.start,end:t.line.end,visible:!0}],overallVisibility:"visible"};const{samplesPerLine:e,depthBias:i}=this.options,o=R(t.line.start,t.line.end)<$?1:Math.max(2,e),r=[];let a=t.line.start,l=this.sampleVisibility(t.line.start,t.depth,i),c=l?1:0;for(let h=1;h<=o;h++){const d=h/o,f=K(t.line.start,t.line.end,d),g=this.sampleVisibility(f,t.depth,i);if(g&&c++,g!==l&&h<o){const y=(h-.5)/o,p=K(t.line.start,t.line.end,y);r.push({start:a,end:p,visible:l}),a=p,l=g}}r.push({start:a,end:t.line.end,visible:l});let u;return c===o+1?u="visible":c===0?u="hidden":u="partial",{line:t,segments:r,overallVisibility:u}}sampleVisibility(t,e,i){if(!this.bounds||!this.depthBuffer)return!0;const s=(t.x-this.bounds.min.x)/(this.bounds.max.x-this.bounds.min.x)*(this.width-1),o=(t.y-this.bounds.min.y)/(this.bounds.max.y-this.bounds.min.y)*(this.height-1),r=Math.max(0,Math.min(this.width-1,Math.floor(s))),a=Math.max(0,Math.min(this.height-1,Math.floor(o))),l=this.depthBuffer[a*this.width+r];return e<=l+i}}const it={IfcWall:{type:"diagonal",spacing:3,angle:45,lineWeight:.18,strokeColor:"#000000"},IfcWallStandardCase:{type:"diagonal",spacing:3,angle:45,lineWeight:.18,strokeColor:"#000000"},IfcCurtainWall:{type:"none",spacing:0,angle:0,lineWeight:.13,strokeColor:"#0066CC"},IfcSlab:{type:"concrete",spacing:2.5,angle:0,lineWeight:.13,strokeColor:"#666666"},IfcRoof:{type:"cross-hatch",spacing:4,angle:45,secondaryAngle:-45,lineWeight:.13,strokeColor:"#8B4513"},IfcCovering:{type:"horizontal",spacing:8,angle:0,lineWeight:.09,strokeColor:"#999999"},IfcColumn:{type:"steel",spacing:2,angle:45,lineWeight:.25,strokeColor:"#333333"},IfcBeam:{type:"steel",spacing:2,angle:45,lineWeight:.25,strokeColor:"#333333"},IfcMember:{type:"diagonal",spacing:2.5,angle:45,lineWeight:.18,strokeColor:"#444444"},IfcPlate:{type:"steel",spacing:1.5,angle:45,lineWeight:.18,strokeColor:"#555555"},IfcFooting:{type:"concrete",spacing:3,angle:0,lineWeight:.18,strokeColor:"#777777"},IfcPile:{type:"concrete",spacing:2.5,angle:0,lineWeight:.18,strokeColor:"#666666"},IfcWindow:{type:"glass",spacing:0,angle:0,lineWeight:.13,strokeColor:"#0099CC",fillColor:"rgba(200, 230, 255, 0.3)"},IfcDoor:{type:"none",spacing:0,angle:0,lineWeight:.25,strokeColor:"#000000"},IfcOpeningElement:{type:"none",spacing:0,angle:0,lineWeight:.13,strokeColor:"#CCCCCC"},IfcStair:{type:"horizontal",spacing:5,angle:0,lineWeight:.18,strokeColor:"#444444"},IfcStairFlight:{type:"horizontal",spacing:5,angle:0,lineWeight:.18,strokeColor:"#444444"},IfcRamp:{type:"diagonal",spacing:6,angle:30,lineWeight:.13,strokeColor:"#555555"},IfcRailing:{type:"none",spacing:0,angle:0,lineWeight:.13,strokeColor:"#666666"},IfcFlowTerminal:{type:"none",spacing:0,angle:0,lineWeight:.13,strokeColor:"#0066AA"},IfcFlowSegment:{type:"none",spacing:0,angle:0,lineWeight:.18,strokeColor:"#0066AA"},IfcDistributionElement:{type:"none",spacing:0,angle:0,lineWeight:.13,strokeColor:"#006688"},IfcSpace:{type:"none",spacing:0,angle:0,lineWeight:.09,strokeColor:"#CCCCCC"},IfcFurnishingElement:{type:"none",spacing:0,angle:0,lineWeight:.13,strokeColor:"#888888"},IfcFurniture:{type:"none",spacing:0,angle:0,lineWeight:.13,strokeColor:"#888888"},default:{type:"diagonal",spacing:4,angle:45,lineWeight:.13,strokeColor:"#666666"}};function mt(n){return it[n]||it.default}const Kt={cut:{weight:.5,color:"#000000",dashPattern:[],lineCap:"round",lineJoin:"round"},projection:{weight:.25,color:"#000000",dashPattern:[],lineCap:"round",lineJoin:"round"},hidden:{weight:.18,color:"#666666",dashPattern:[2,1],lineCap:"butt",lineJoin:"round"},silhouette:{weight:.35,color:"#000000",dashPattern:[],lineCap:"round",lineJoin:"round"},crease:{weight:.18,color:"#000000",dashPattern:[],lineCap:"round",lineJoin:"round"},boundary:{weight:.25,color:"#000000",dashPattern:[],lineCap:"round",lineJoin:"round"},annotation:{weight:.13,color:"#000000",dashPattern:[],lineCap:"butt",lineJoin:"miter"}},ot={IfcWall:{cut:.7,projection:.35},IfcWallStandardCase:{cut:.7,projection:.35},IfcSlab:{cut:.5,projection:.25},IfcColumn:{cut:.5,projection:.35},IfcBeam:{cut:.5,projection:.35},IfcWindow:{cut:.35,projection:.18},IfcDoor:{cut:.35,projection:.25},IfcStair:{cut:.35,projection:.25},IfcFurnishingElement:{cut:.18,projection:.13},IfcFurniture:{cut:.18,projection:.13},IfcSpace:{cut:.09,projection:.09}};function Qt(n,t){const e=Kt[n];if(t&&ot[t]){const i=ot[t][n];if(i!==void 0)return{...e,weight:i}}return e}const O=[{name:"1:1",factor:1,useCase:"Full size details"},{name:"1:2",factor:2,useCase:"Large details"},{name:"1:5",factor:5,useCase:"Construction details"},{name:"1:10",factor:10,useCase:"Details"},{name:"1:20",factor:20,useCase:"Room plans, sections"},{name:"1:50",factor:50,useCase:"Floor plans, elevations"},{name:"1:100",factor:100,useCase:"Building plans"},{name:"1:200",factor:200,useCase:"Site plans"},{name:"1:500",factor:500,useCase:"Site context"},{name:"1:1000",factor:1e3,useCase:"Urban context"}],st={A3_LANDSCAPE:{name:"A3 Landscape",width:420,height:297}};class xt{generateHatch(t,e=100,i){const s=mt(t.ifcType),o=i?{...s,type:i.type,spacing:i.spacing??s.spacing,angle:i.angle??s.angle,secondaryAngle:i.secondaryAngle??s.secondaryAngle}:s;if(o.type==="none"||o.type==="solid"||o.type==="glass")return{lines:[],pattern:o,polygon:t};const r=o.spacing*(e/100);let a=[];const l=this.generateParallelLines(t.polygon,r,o.angle,t.entityId,t.ifcType,t.modelIndex);if(a.push(...l),o.type==="cross-hatch"&&o.secondaryAngle!==void 0){const c=this.generateParallelLines(t.polygon,r,o.secondaryAngle,t.entityId,t.ifcType,t.modelIndex);a.push(...c)}if(o.type==="concrete"){const c=this.generateParallelLines(t.polygon,r*1.5,o.angle+90,t.entityId,t.ifcType,t.modelIndex);a.push(...c)}return{lines:a,pattern:o,polygon:t}}generateHatches(t,e=100,i){return t.map(s=>{const o=i?.(s);return this.generateHatch(s,e,o)})}generateParallelLines(t,e,i,s,o,r){if(e<$)return[];const a=i*Math.PI/180,l=Math.cos(a),c=Math.sin(a),u=-c,h=l,d=this.computePolygonBounds(t);if(!d)return[];const f=[{x:d.min.x,y:d.min.y},{x:d.max.x,y:d.min.y},{x:d.max.x,y:d.max.y},{x:d.min.x,y:d.max.y}];let g=1/0,y=-1/0;for(const I of f){const w=I.x*l+I.y*c;g=Math.min(g,w),y=Math.max(y,w)}const p=Math.sqrt(Math.pow(d.max.x-d.min.x,2)+Math.pow(d.max.y-d.min.y,2))*1.5,m=[];for(let I=g;I<=y;I+=e){const w=I*l,x=I*c,C={x:w-u*p,y:x-h*p},b={x:w+u*p,y:x+h*p},A=this.clipLineToPolygon({start:C,end:b},t);for(const M of A)m.push({line:M,entityId:s,ifcType:o,modelIndex:r})}return m}clipLineToPolygon(t,e){let i=this.clipLineToRing(t,e.outer,!0);for(const s of e.holes){const o=[];for(const r of i){const a=this.clipLineToRing(r,s,!1);o.push(...a)}i=o}return i}clipLineToRing(t,e,i){const s=[],o=t.end.x-t.start.x,r=t.end.y-t.start.y;for(let h=0;h<e.length;h++){const d=(h+1)%e.length,f=e[h],g=e[d],y=this.lineLineIntersection(t.start,t.end,f,g);if(y!==null&&y.t>=0&&y.t<=1){const p=-(g.y-f.y),m=g.x-f.x,I=o*p+r*m>0;s.push({t:y.t,entering:I})}}s.sort((h,d)=>h.t-d.t);const a=[];for(const h of s)(a.length===0||Math.abs(h.t-a[a.length-1].t)>$)&&a.push(h);if(a.length===0){const h={x:(t.start.x+t.end.x)/2,y:(t.start.y+t.end.y)/2};return this.pointInRing(h,e)===i?[t]:[]}const l=[];let c=this.pointInRing(t.start,e),u=0;for(const h of a)c===i&&l.push({start:{x:t.start.x+u*o,y:t.start.y+u*r},end:{x:t.start.x+h.t*o,y:t.start.y+h.t*r}}),u=h.t,c=!c;return c===i&&l.push({start:{x:t.start.x+u*o,y:t.start.y+u*r},end:t.end}),l.filter(h=>Math.abs(h.end.x-h.start.x)+Math.abs(h.end.y-h.start.y)>$)}lineLineIntersection(t,e,i,s){const o=e.x-t.x,r=e.y-t.y,a=s.x-i.x,l=s.y-i.y,c=o*l-r*a;if(Math.abs(c)<$)return null;const u=i.x-t.x,h=i.y-t.y,d=(u*l-h*a)/c,f=(u*r-h*o)/c;return f<0||f>1?null:{t:d,u:f}}pointInRing(t,e){let i=!1;const s=e.length;for(let o=0,r=s-1;o<s;r=o++){const a=e[o],l=e[r];a.y>t.y!=l.y>t.y&&t.x<(l.x-a.x)*(t.y-a.y)/(l.y-a.y)+a.x&&(i=!i)}return i}computePolygonBounds(t){if(t.outer.length===0)return null;let e=1/0,i=1/0,s=-1/0,o=-1/0;for(const r of t.outer)e=Math.min(e,r.x),i=Math.min(i,r.y),s=Math.max(s,r.x),o=Math.max(o,r.y);return{min:{x:e,y:i},max:{x:s,y:o}}}}class te{hatchGenerator=new xt;export(t,e={}){const{paperSize:i=st.A3_LANDSCAPE,scale:s=O.find(m=>m.factor===t.config.scale)||O[5],padding:o=20,showHiddenLines:r=!0,showHatching:a=!0,showTitleBlock:l=!1,title:c="Section",projectName:u="",backgroundColor:h="#FFFFFF"}=e,d=this.computeTransform(t.bounds,i,s,o);let f=this.createHeader(i,h);if(f+=this.createDefs(t,s.factor),a&&t.cutPolygons.length>0&&(f+=this.createHatchingLayer(t.cutPolygons,d,s.factor)),r){const m=t.lines.filter(I=>I.visibility==="hidden");m.length>0&&(f+=this.createLineLayer("hidden-lines",m,d,"Hidden Lines"))}const g=t.lines.filter(m=>m.category==="projection"&&m.visibility!=="hidden");g.length>0&&(f+=this.createLineLayer("projection-lines",g,d,"Projection"));const y=t.lines.filter(m=>(m.category==="silhouette"||m.category==="crease"||m.category==="boundary")&&m.visibility!=="hidden");y.length>0&&(f+=this.createLineLayer("feature-lines",y,d,"Feature Edges"));const p=t.lines.filter(m=>m.category==="cut");return p.length>0&&(f+=this.createLineLayer("cut-lines",p,d,"Cut Lines")),l&&(f+=this.createTitleBlock(i,c,u,s)),f+="</svg>",f}exportPolygons(t,e,i={}){const{paperSize:s=st.A3_LANDSCAPE,scale:o=O[5],padding:r=20,backgroundColor:a="#FFFFFF"}=i,l=this.computeTransform(e,s,o,r);let c=this.createHeader(s,a);return c+=this.createPolygonDefs(o.factor),c+=this.createHatchingLayer(t,l,o.factor),c+="</svg>",c}computeTransform(t,e,i,s){vt(t);const o=kt(t);e.width-s*2,e.height-s*2;const r=1e3/i.factor,a=e.width/2-o.x*r,l=e.height/2+o.y*r;return{scale:r,offsetX:a,offsetY:l,flipY:!0}}transformPoint(t,e){return{x:t.x*e.scale+e.offsetX,y:e.flipY?-t.y*e.scale+e.offsetY:t.y*e.scale+e.offsetY}}createHeader(t,e){return`<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
|
3
|
-
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
4
|
-
width="${t.width}mm"
|
|
5
|
-
height="${t.height}mm"
|
|
6
|
-
viewBox="0 0 ${t.width} ${t.height}">
|
|
7
|
-
<rect width="100%" height="100%" fill="${e}"/>
|
|
8
|
-
`}createDefs(t,e){let i=` <defs>
|
|
9
|
-
`;return i+=this.createHatchPatternDefs(e),i+=` </defs>
|
|
10
|
-
`,i}createPolygonDefs(t){let e=` <defs>
|
|
11
|
-
`;return e+=this.createHatchPatternDefs(t),e+=` </defs>
|
|
12
|
-
`,e}createHatchPatternDefs(t){const e=3*(t/100);let i="";return i+=` <pattern id="hatch-diagonal" patternUnits="userSpaceOnUse"
|
|
13
|
-
width="${e}" height="${e}" patternTransform="rotate(45)">
|
|
14
|
-
<line x1="0" y1="0" x2="0" y2="${e}" stroke="#000" stroke-width="0.15"/>
|
|
15
|
-
</pattern>
|
|
16
|
-
`,i+=` <pattern id="hatch-cross" patternUnits="userSpaceOnUse"
|
|
17
|
-
width="${e}" height="${e}">
|
|
18
|
-
<line x1="0" y1="0" x2="${e}" y2="${e}" stroke="#000" stroke-width="0.1"/>
|
|
19
|
-
<line x1="${e}" y1="0" x2="0" y2="${e}" stroke="#000" stroke-width="0.1"/>
|
|
20
|
-
</pattern>
|
|
21
|
-
`,i+=` <pattern id="hatch-horizontal" patternUnits="userSpaceOnUse"
|
|
22
|
-
width="${e}" height="${e}">
|
|
23
|
-
<line x1="0" y1="${e/2}" x2="${e}" y2="${e/2}" stroke="#000" stroke-width="0.1"/>
|
|
24
|
-
</pattern>
|
|
25
|
-
`,i+=` <pattern id="hatch-concrete" patternUnits="userSpaceOnUse"
|
|
26
|
-
width="${e*2}" height="${e*2}">
|
|
27
|
-
<circle cx="${e*.3}" cy="${e*.3}" r="0.3" fill="#666"/>
|
|
28
|
-
<circle cx="${e*1.3}" cy="${e*1.3}" r="0.3" fill="#666"/>
|
|
29
|
-
<circle cx="${e*.8}" cy="${e*1.6}" r="0.2" fill="#888"/>
|
|
30
|
-
</pattern>
|
|
31
|
-
`,i+=` <pattern id="hatch-steel" patternUnits="userSpaceOnUse"
|
|
32
|
-
width="${e*.7}" height="${e*.7}" patternTransform="rotate(45)">
|
|
33
|
-
<line x1="0" y1="0" x2="0" y2="${e*.7}" stroke="#333" stroke-width="0.2"/>
|
|
34
|
-
</pattern>
|
|
35
|
-
`,i}createLineLayer(t,e,i,s){let o=` <g id="${t}" inkscape:label="${s}" inkscape:groupmode="layer">
|
|
36
|
-
`;for(const r of e)o+=this.renderLine(r,i);return o+=` </g>
|
|
37
|
-
`,o}renderLine(t,e){const i=Qt(t.category,t.ifcType),s=this.transformPoint(t.line.start,e),o=this.transformPoint(t.line.end,e),r=i.dashPattern.length>0?` stroke-dasharray="${i.dashPattern.join(" ")}"`:"";return` <line x1="${s.x.toFixed(3)}" y1="${s.y.toFixed(3)}" x2="${o.x.toFixed(3)}" y2="${o.y.toFixed(3)}"
|
|
38
|
-
stroke="${i.color}" stroke-width="${i.weight}"
|
|
39
|
-
stroke-linecap="${i.lineCap}"${r}
|
|
40
|
-
data-entity-id="${t.entityId}" data-ifc-type="${t.ifcType}"/>
|
|
41
|
-
`}createHatchingLayer(t,e,i){let s=` <g id="hatching" inkscape:label="Hatching" inkscape:groupmode="layer">
|
|
42
|
-
`;for(const o of t){const r=mt(o.ifcType);if(r.type!=="none"&&(s+=this.renderPolygon(o,e,r),r.type!=="solid"&&r.type!=="glass")){const a=this.hatchGenerator.generateHatch(o,i);for(const l of a.lines)s+=this.renderHatchLine(l,e,r)}}return s+=` </g>
|
|
43
|
-
`,s}renderPolygon(t,e,i){const s=this.polygonToPath(t.polygon,e);let o;return i.type==="solid"?o=i.fillColor||"#CCCCCC":i.type==="glass"?o=i.fillColor||"rgba(200, 230, 255, 0.3)":i.type==="none"?o="none":o=`url(#hatch-${i.type})`,` <path d="${s}" fill="${o}"
|
|
44
|
-
stroke="${i.strokeColor}" stroke-width="${i.lineWeight}"
|
|
45
|
-
data-entity-id="${t.entityId}" data-ifc-type="${t.ifcType}"/>
|
|
46
|
-
`}polygonToPath(t,e){let i="";if(t.outer.length>0){const s=this.transformPoint(t.outer[0],e);i+=`M ${s.x.toFixed(3)} ${s.y.toFixed(3)}`;for(let o=1;o<t.outer.length;o++){const r=this.transformPoint(t.outer[o],e);i+=` L ${r.x.toFixed(3)} ${r.y.toFixed(3)}`}i+=" Z"}for(const s of t.holes)if(s.length>0){const o=this.transformPoint(s[0],e);i+=` M ${o.x.toFixed(3)} ${o.y.toFixed(3)}`;for(let r=1;r<s.length;r++){const a=this.transformPoint(s[r],e);i+=` L ${a.x.toFixed(3)} ${a.y.toFixed(3)}`}i+=" Z"}return i}renderHatchLine(t,e,i){const s=this.transformPoint(t.line.start,e),o=this.transformPoint(t.line.end,e);return` <line x1="${s.x.toFixed(3)}" y1="${s.y.toFixed(3)}" x2="${o.x.toFixed(3)}" y2="${o.y.toFixed(3)}"
|
|
47
|
-
stroke="${i.strokeColor}" stroke-width="${i.lineWeight}" stroke-linecap="butt"/>
|
|
48
|
-
`}createTitleBlock(t,e,i,s){const a=t.width-180-10,l=t.height-50-10;return` <g id="title-block">
|
|
49
|
-
<rect x="${a}" y="${l}" width="180" height="50"
|
|
50
|
-
fill="white" stroke="black" stroke-width="0.5"/>
|
|
51
|
-
<line x1="${a}" y1="${l+20}" x2="${a+180}" y2="${l+20}" stroke="black" stroke-width="0.3"/>
|
|
52
|
-
<line x1="${a}" y1="${l+35}" x2="${a+180}" y2="${l+35}" stroke="black" stroke-width="0.3"/>
|
|
53
|
-
<line x1="${a+100}" y1="${l+20}" x2="${a+100}" y2="${l+50}" stroke="black" stroke-width="0.3"/>
|
|
54
|
-
<text x="${a+5}" y="${l+14}" font-family="Arial" font-size="10" font-weight="bold">${this.escapeXml(e)}</text>
|
|
55
|
-
<text x="${a+5}" y="${l+30}" font-family="Arial" font-size="8">${this.escapeXml(i)}</text>
|
|
56
|
-
<text x="${a+5}" y="${l+45}" font-family="Arial" font-size="8">Scale: ${s.name}</text>
|
|
57
|
-
<text x="${a+105}" y="${l+30}" font-family="Arial" font-size="7">Date:</text>
|
|
58
|
-
<text x="${a+105}" y="${l+45}" font-family="Arial" font-size="7">${new Date().toLocaleDateString()}</text>
|
|
59
|
-
</g>
|
|
60
|
-
`}escapeXml(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}}const ee=`
|
|
61
|
-
struct Triangle {
|
|
62
|
-
v0: vec3<f32>,
|
|
63
|
-
v1: vec3<f32>,
|
|
64
|
-
v2: vec3<f32>,
|
|
65
|
-
entityId: u32,
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
struct Plane {
|
|
69
|
-
normal: vec3<f32>,
|
|
70
|
-
distance: f32,
|
|
71
|
-
// Projection axes for 2D output
|
|
72
|
-
axisU: u32, // 0=x, 1=y, 2=z
|
|
73
|
-
axisV: u32,
|
|
74
|
-
flipU: f32, // 1.0 or -1.0
|
|
75
|
-
_padding: f32,
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
struct Segment {
|
|
79
|
-
p0_3d: vec3<f32>,
|
|
80
|
-
_pad0: f32,
|
|
81
|
-
p1_3d: vec3<f32>,
|
|
82
|
-
_pad1: f32,
|
|
83
|
-
p0_2d: vec2<f32>,
|
|
84
|
-
p1_2d: vec2<f32>,
|
|
85
|
-
entityId: u32,
|
|
86
|
-
valid: u32,
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
@group(0) @binding(0) var<storage, read> triangles: array<Triangle>;
|
|
90
|
-
@group(0) @binding(1) var<uniform> plane: Plane;
|
|
91
|
-
@group(0) @binding(2) var<storage, read_write> segments: array<Segment>;
|
|
92
|
-
@group(0) @binding(3) var<storage, read_write> segmentCount: atomic<u32>;
|
|
93
|
-
|
|
94
|
-
const EPSILON: f32 = 1e-7;
|
|
95
|
-
|
|
96
|
-
fn signedDistance(point: vec3<f32>) -> f32 {
|
|
97
|
-
return dot(point, plane.normal) - plane.distance;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
fn edgeIntersection(v0: vec3<f32>, v1: vec3<f32>, d0: f32, d1: f32) -> vec3<f32> {
|
|
101
|
-
let t = d0 / (d0 - d1);
|
|
102
|
-
return mix(v0, v1, t);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
fn projectTo2D(p: vec3<f32>) -> vec2<f32> {
|
|
106
|
-
var coords: array<f32, 3>;
|
|
107
|
-
coords[0] = p.x;
|
|
108
|
-
coords[1] = p.y;
|
|
109
|
-
coords[2] = p.z;
|
|
110
|
-
|
|
111
|
-
let u = coords[plane.axisU] * plane.flipU;
|
|
112
|
-
let v = coords[plane.axisV];
|
|
113
|
-
return vec2<f32>(u, v);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
@compute @workgroup_size(64)
|
|
117
|
-
fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
118
|
-
let triIdx = id.x;
|
|
119
|
-
if (triIdx >= arrayLength(&triangles)) {
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
let tri = triangles[triIdx];
|
|
124
|
-
|
|
125
|
-
// Signed distances from plane
|
|
126
|
-
let d0 = signedDistance(tri.v0);
|
|
127
|
-
let d1 = signedDistance(tri.v1);
|
|
128
|
-
let d2 = signedDistance(tri.v2);
|
|
129
|
-
|
|
130
|
-
// Check for intersection
|
|
131
|
-
let pos = u32(d0 > EPSILON) + u32(d1 > EPSILON) + u32(d2 > EPSILON);
|
|
132
|
-
let neg = u32(d0 < -EPSILON) + u32(d1 < -EPSILON) + u32(d2 < -EPSILON);
|
|
133
|
-
|
|
134
|
-
// No intersection if all on same side
|
|
135
|
-
if (pos == 3u || neg == 3u || (pos == 0u && neg == 0u)) {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Find intersection points
|
|
140
|
-
var points: array<vec3<f32>, 2>;
|
|
141
|
-
var count: u32 = 0u;
|
|
142
|
-
|
|
143
|
-
// Edge v0-v1
|
|
144
|
-
if ((d0 > EPSILON) != (d1 > EPSILON)) {
|
|
145
|
-
points[count] = edgeIntersection(tri.v0, tri.v1, d0, d1);
|
|
146
|
-
count = count + 1u;
|
|
147
|
-
} else if (abs(d0) < EPSILON) {
|
|
148
|
-
points[count] = tri.v0;
|
|
149
|
-
count = count + 1u;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Edge v1-v2
|
|
153
|
-
if ((d1 > EPSILON) != (d2 > EPSILON)) {
|
|
154
|
-
points[count] = edgeIntersection(tri.v1, tri.v2, d1, d2);
|
|
155
|
-
count = count + 1u;
|
|
156
|
-
} else if (abs(d1) < EPSILON && count < 2u) {
|
|
157
|
-
points[count] = tri.v1;
|
|
158
|
-
count = count + 1u;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// Edge v2-v0
|
|
162
|
-
if (count < 2u) {
|
|
163
|
-
if ((d2 > EPSILON) != (d0 > EPSILON)) {
|
|
164
|
-
points[count] = edgeIntersection(tri.v2, tri.v0, d2, d0);
|
|
165
|
-
count = count + 1u;
|
|
166
|
-
} else if (abs(d2) < EPSILON && count < 2u) {
|
|
167
|
-
points[count] = tri.v2;
|
|
168
|
-
count = count + 1u;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
if (count >= 2u) {
|
|
173
|
-
// Project to 2D
|
|
174
|
-
let p0_2d = projectTo2D(points[0]);
|
|
175
|
-
let p1_2d = projectTo2D(points[1]);
|
|
176
|
-
|
|
177
|
-
// Skip degenerate segments
|
|
178
|
-
let diff = p1_2d - p0_2d;
|
|
179
|
-
if (dot(diff, diff) < EPSILON * EPSILON) {
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// Atomically allocate output slot
|
|
184
|
-
let outIdx = atomicAdd(&segmentCount, 1u);
|
|
185
|
-
|
|
186
|
-
segments[outIdx].p0_3d = points[0];
|
|
187
|
-
segments[outIdx].p1_3d = points[1];
|
|
188
|
-
segments[outIdx].p0_2d = p0_2d;
|
|
189
|
-
segments[outIdx].p1_2d = p1_2d;
|
|
190
|
-
segments[outIdx].entityId = tri.entityId;
|
|
191
|
-
segments[outIdx].valid = 1u;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
`;class ne{device;resources=null;constructor(t){this.device=t}async initialize(t){const e=t,i=this.device.createShaderModule({code:ee}),s=this.device.createComputePipeline({layout:"auto",compute:{module:i,entryPoint:"main"}}),o=t*48,r=this.device.createBuffer({size:o,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),a=this.device.createBuffer({size:32,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),l=e*64,c=this.device.createBuffer({size:l,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC}),u=this.device.createBuffer({size:4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC}),h=this.device.createBuffer({size:l,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),d=this.device.createBuffer({size:4,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),f=this.device.createBindGroup({layout:s.getBindGroupLayout(0),entries:[{binding:0,resource:{buffer:r}},{binding:1,resource:{buffer:a}},{binding:2,resource:{buffer:c}},{binding:3,resource:{buffer:u}}]});this.resources={pipeline:s,triangleBuffer:r,planeBuffer:a,segmentBuffer:c,countBuffer:u,readbackBuffer:h,countReadbackBuffer:d,bindGroup:f,maxTriangles:t,maxSegments:e}}async cutMeshes(t,e){if(!this.resources)throw new Error("GPU resources not initialized. Call initialize() first.");const i=this.collectTriangles(t),s=i.count;if(s===0)return[];s>this.resources.maxTriangles&&await this.initialize(s*2);const o=this.resources;if(!o)throw new Error("GPU resources became unavailable after initialization");this.device.queue.writeBuffer(o.triangleBuffer,0,i.buffer.buffer,i.buffer.byteOffset,i.buffer.byteLength);const r=this.createPlaneData(e);this.device.queue.writeBuffer(o.planeBuffer,0,r.buffer,r.byteOffset,r.byteLength),this.device.queue.writeBuffer(o.countBuffer,0,new Uint32Array([0]));const a=this.device.createCommandEncoder(),l=a.beginComputePass();l.setPipeline(o.pipeline),l.setBindGroup(0,o.bindGroup);const c=Math.ceil(s/64);l.dispatchWorkgroups(c),l.end(),a.copyBufferToBuffer(o.countBuffer,0,o.countReadbackBuffer,0,4),this.device.queue.submit([a.finish()]),await o.countReadbackBuffer.mapAsync(GPUMapMode.READ);const h=new Uint32Array(o.countReadbackBuffer.getMappedRange())[0];if(o.countReadbackBuffer.unmap(),h===0)return[];const d=this.device.createCommandEncoder();d.copyBufferToBuffer(o.segmentBuffer,0,o.readbackBuffer,0,h*64),this.device.queue.submit([d.finish()]),await o.readbackBuffer.mapAsync(GPUMapMode.READ);const f=new Float32Array(o.readbackBuffer.getMappedRange(0,h*64)),g=this.parseSegments(f,h,i.entityMap);return o.readbackBuffer.unmap(),g}collectTriangles(t){let e=0;for(const a of t)e+=a.indices.length/3;const i=new Float32Array(e*12),s=new Map;let o=0,r=0;for(const a of t){const{positions:l,indices:c,expressId:u,ifcType:h,modelIndex:d}=a,f=c.length/3;s.set(r,{entityId:u,ifcType:h||"Unknown",modelIndex:d||0});for(let g=0;g<f;g++){const y=c[g*3],p=c[g*3+1],m=c[g*3+2],I=o*12;i[I+0]=l[y*3],i[I+1]=l[y*3+1],i[I+2]=l[y*3+2],i[I+3]=l[p*3],i[I+4]=l[p*3+1],i[I+5]=l[p*3+2],i[I+6]=l[m*3],i[I+7]=l[m*3+1],i[I+8]=l[m*3+2],new DataView(i.buffer,(I+9)*4,4).setUint32(0,r,!0),i[I+10]=0,i[I+11]=0,o++}r++}return{buffer:i,count:e,entityMap:s}}createPlaneData(t){const e=ct(t.axis,t.flipped),i=ht(t.axis),s={x:0,y:1,z:2},o=new Float32Array(8);o[0]=e.x,o[1]=e.y,o[2]=e.z,o[3]=t.position;const r=new DataView(o.buffer);return r.setUint32(16,s[i.u],!0),r.setUint32(20,s[i.v],!0),o[6]=t.flipped?-1:1,o[7]=0,o}parseSegments(t,e,i){const s=[];for(let o=0;o<e;o++){const r=o*16;if(new DataView(t.buffer,(r+14)*4,4).getUint32(0,!0)!==1)continue;const l=new DataView(t.buffer,(r+13)*4,4).getUint32(0,!0),c=i.get(l)||{entityId:0,ifcType:"Unknown",modelIndex:0};s.push({p0:{x:t[r+0],y:t[r+1],z:t[r+2]},p1:{x:t[r+4],y:t[r+5],z:t[r+6]},p0_2d:{x:t[r+8],y:t[r+9]},p1_2d:{x:t[r+10],y:t[r+11]},entityId:c.entityId,ifcType:c.ifcType,modelIndex:c.modelIndex})}return s}destroy(){this.resources&&(this.resources.triangleBuffer.destroy(),this.resources.planeBuffer.destroy(),this.resources.segmentBuffer.destroy(),this.resources.countBuffer.destroy(),this.resources.readbackBuffer.destroy(),this.resources.countReadbackBuffer.destroy(),this.resources=null)}}const ie={useGPU:!0,includeHiddenLines:!0,includeProjection:!0,includeEdges:!0,mergeLines:!0};class ke{gpuCutter=null;cpuCutter=null;polygonBuilder=new gt;edgeExtractor=new Ut(30);hiddenLineClassifier=new Jt({resolution:1024});hatchGenerator=new xt;svgExporter=new te;gpuDevice=null;initialized=!1;async initialize(t){t&&(this.gpuDevice=t,this.gpuCutter=new ne(t),await this.gpuCutter.initialize(1e5)),this.initialized=!0}async generate(t,e,i={},s){const o={...ie,...i},r=performance.now(),a=(x,C)=>{o.onProgress?.(x,C)};a("cutting",0);let l;o.useGPU&&this.gpuCutter&&this.gpuDevice?l=await this.gpuCutter.cutMeshes(t,e.plane):((!this.cpuCutter||this.cpuCutter===null)&&(this.cpuCutter=new Dt(e.plane)),l=this.cpuCutter.cutMeshes(t).segments),a("cutting",1),a("polygons",0);const c=this.polygonBuilder.buildPolygons(l);a("polygons",1);const u=l.map(x=>({line:{start:x.p0_2d,end:x.p1_2d},category:"cut",visibility:"visible",entityId:x.entityId,ifcType:x.ifcType,modelIndex:x.modelIndex,depth:0}));let h=[],d=[];if(o.includeProjection||o.includeEdges){if(a("edges",0),s&&s.length>0&&o.includeProjection&&(h=Gt(s,e.plane,e.projectionDepth)),o.includeEdges){const C=this.edgeExtractor.extractEdgesFromMeshes(t),b=this.edgeExtractor.filterEdgesByDepth(C,e.plane.axis,e.plane.position,e.projectionDepth,e.plane.flipped),A=jt(e.plane.axis,e.plane.flipped),M=this.edgeExtractor.extractSilhouettes(b,A);if(d=this.edgeExtractor.edgesToDrawingLines(M,e.plane.axis,e.plane.flipped,"silhouette",e.plane.position),o.includeProjection){const P=new Set((s??[]).map(L=>W(L.modelIndex,L.expressId))),E=b.filter(L=>L.type!=="crease"||M.includes(L)?!1:P.size===0?!0:!P.has(W(L.modelIndex,L.entityId)));h=[...h,...this.edgeExtractor.edgesToDrawingLines(E,e.plane.axis,e.plane.flipped,"projection",e.plane.position)]}}else if(o.includeProjection){const C=new Set((s??[]).map(P=>W(P.modelIndex,P.expressId))),b=this.edgeExtractor.extractEdgesFromMeshes(t),M=this.edgeExtractor.filterEdgesByDepth(b,e.plane.axis,e.plane.position,e.projectionDepth,e.plane.flipped).filter(P=>P.type!=="crease"?!1:C.size===0?!0:!C.has(W(P.modelIndex,P.entityId)));h=[...h,...this.edgeExtractor.edgesToDrawingLines(M,e.plane.axis,e.plane.flipped,"projection",e.plane.position)]}const x=this.computeBounds(u);if(x.min.x<x.max.x&&x.min.y<x.max.y){const C=x.max.x-x.min.x,b=x.max.y-x.min.y,M=Math.sqrt(C*C+b*b)*1.5;d=d.filter(P=>tt(P.line)<=M),h=h.filter(P=>tt(P.line)<=M)}a("edges",1)}let f=[...u,...h,...d];if(o.includeHiddenLines&&(h.length>0||d.length>0)){a("hidden",0);const x=this.computeBounds(f);this.hiddenLineClassifier.buildDepthBuffer(t,e.plane.axis,e.plane.position,e.projectionDepth,e.plane.flipped,x);const C=f.filter(A=>A.category!=="cut"),b=this.hiddenLineClassifier.applyVisibility(C);f=[...u,...b],a("hidden",1)}o.mergeLines&&(a("merging",0),f=Wt(f),a("merging",1));const g=this.computeBounds(f),y=performance.now()-r,p=f.filter(x=>x.category==="cut").length,m=f.filter(x=>x.category==="projection").length,I=f.filter(x=>x.visibility==="hidden").length,w=f.filter(x=>x.category==="silhouette").length;return a("complete",1),{config:e,lines:f,cutPolygons:c,projectionPolygons:[],bounds:g,stats:{cutLineCount:p,projectionLineCount:m,hiddenLineCount:I,silhouetteLineCount:w,polygonCount:c.length,totalTriangles:t.reduce((x,C)=>x+C.indices.length/3,0),processingTimeMs:y}}}exportSVG(t,e){return this.svgExporter.export(t,e)}generateHatching(t){const e=this.hatchGenerator.generateHatches(t.cutPolygons,t.config.scale),i=[];for(const s of e)for(const o of s.lines)i.push({line:o.line,category:"annotation",visibility:"visible",entityId:o.entityId,ifcType:o.ifcType,modelIndex:o.modelIndex,depth:0});return i}computeBounds(t){let e=lt();for(const i of t)e=Et(e,i.line);return e}dispose(){this.gpuCutter&&(this.gpuCutter.destroy(),this.gpuCutter=null),this.gpuDevice=null,this.initialized=!1}}function ve(n,t,e={}){return{plane:{axis:n,position:t,flipped:!1},...wt,...e}}const oe={heavy:.5,medium:.35,light:.25,hairline:.18},rt={solid:[],dashed:[2,1],dotted:[.5,.5],dashdot:[3,1,.5,1],center:[6,1,1,1]},k={fillColor:"#CCCCCC",strokeColor:"#000000",backgroundColor:"#FFFFFF",lineWeight:.25,lineCap:"round",lineJoin:"round",dashPattern:[],hatchPattern:"none",hatchSpacing:3,hatchAngle:45,hatchSecondaryAngle:-45,hatchColor:"#000000",hatchLineWeight:.13,visible:!0,opacity:1,drawOrder:0},se={IfcWall:["IfcWallStandardCase","IfcWallElementedCase"],IfcSlab:["IfcSlabStandardCase","IfcSlabElementedCase"],IfcBeam:["IfcBeamStandardCase"],IfcColumn:["IfcColumnStandardCase"],IfcDoor:["IfcDoorStandardCase"],IfcWindow:["IfcWindowStandardCase"],IfcMember:["IfcMemberStandardCase"],IfcPlate:["IfcPlateStandardCase"],IfcStair:["IfcStairFlight"],IfcRamp:["IfcRampFlight"],IfcBuildingElement:["IfcWall","IfcSlab","IfcBeam","IfcColumn","IfcDoor","IfcWindow","IfcStair","IfcRamp","IfcRoof","IfcRailing","IfcCovering"],IfcDistributionElement:["IfcDistributionFlowElement","IfcDistributionControlElement"],IfcFlowElement:["IfcFlowTerminal","IfcFlowSegment","IfcFlowFitting","IfcFlowController"]};function Ct(n){const t=se[n]||[],e=[...t];for(const i of t)e.push(...Ct(i));return e}function re(n,t,e){switch(t){case"equals":return n===e;case"notEquals":return n!==e;case"contains":return typeof n=="string"&&typeof e=="string"?n.toLowerCase().includes(e.toLowerCase()):!1;case"notContains":return typeof n=="string"&&typeof e=="string"?!n.toLowerCase().includes(e.toLowerCase()):!0;case"startsWith":return typeof n=="string"&&typeof e=="string"?n.toLowerCase().startsWith(e.toLowerCase()):!1;case"endsWith":return typeof n=="string"&&typeof e=="string"?n.toLowerCase().endsWith(e.toLowerCase()):!1;case"greaterThan":return typeof n=="number"&&typeof e=="number"?n>e:!1;case"lessThan":return typeof n=="number"&&typeof e=="number"?n<e:!1;case"greaterOrEqual":return typeof n=="number"&&typeof e=="number"?n>=e:!1;case"lessOrEqual":return typeof n=="number"&&typeof e=="number"?n<=e:!1;case"exists":return n!=null;case"notExists":return n==null;case"in":return Array.isArray(e)?e.includes(n):!1;case"notIn":return Array.isArray(e)?!e.includes(n):!0;default:return!1}}function ae(n,t){switch(n.type){case"all":return!0;case"ifcType":return!n.ifcTypes||n.ifcTypes.length===0?!0:(n.includeSubtypes?n.ifcTypes.flatMap(i=>[i,...Ct(i)]):n.ifcTypes).some(i=>i.toLowerCase()===t.ifcType.toLowerCase());case"property":{if(!n.propertyName)return!1;const e=n.operator||"equals";let i;if(n.propertySet&&t.properties)i=t.properties[n.propertySet]?.[n.propertyName];else if(t.properties){for(const s of Object.values(t.properties))if(n.propertyName in s){i=s[n.propertyName];break}}return re(i,e,n.value)}case"propertySet":{if(!n.propertySet||!t.properties)return n.operator==="notExists";const e=n.propertySet in t.properties,i=n.operator||"exists";return i==="exists"?e:i==="notExists"?!e:e}case"material":return!n.materialNames||!t.materials?!1:n.materialNames.some(e=>t.materials.some(i=>i.toLowerCase().includes(e.toLowerCase())));case"layer":return!n.layerNames||!t.layers?!1:n.layerNames.some(e=>t.layers.some(i=>i.toLowerCase().includes(e.toLowerCase())));case"expressId":return n.expressIds?n.expressIds.includes(t.expressId):!1;case"modelId":return!n.modelIds||!t.modelId?!1:n.modelIds.includes(t.modelId);default:return!1}}function It(n){return"logic"in n&&"conditions"in n}function j(n,t){if(It(n)){const e=n.conditions.map(i=>j(i,t));return n.logic==="and"?e.every(Boolean):e.some(Boolean)}return ae(n,t)}function le(n){if(n===void 0)return k.lineWeight;if(typeof n=="number")return n;const t=oe[n];return t!==void 0?t:k.lineWeight}function ce(n){return n===void 0?k.dashPattern:typeof n=="string"?rt[n]??k.dashPattern:n.custom?n.custom:n.preset?rt[n.preset]??k.dashPattern:k.dashPattern}function at(n,t){return{fillColor:t.fillColor??n.fillColor,strokeColor:t.strokeColor??n.strokeColor,backgroundColor:t.backgroundColor??n.backgroundColor,lineWeight:t.lineWeight!==void 0?le(t.lineWeight):n.lineWeight,lineCap:t.lineCap??n.lineCap,lineJoin:t.lineJoin??n.lineJoin,dashPattern:t.lineStyle?ce(t.lineStyle):n.dashPattern,hatchPattern:t.hatchPattern??n.hatchPattern,hatchSpacing:t.hatchSpacing??n.hatchSpacing,hatchAngle:t.hatchAngle??n.hatchAngle,hatchSecondaryAngle:t.hatchSecondaryAngle??n.hatchSecondaryAngle,hatchColor:t.hatchColor??n.hatchColor,hatchLineWeight:t.hatchLineWeight??n.hatchLineWeight,visible:t.visible??n.visible,opacity:t.opacity??n.opacity,drawOrder:t.drawOrder??n.drawOrder}}class bt{rules=[];constructor(t){t&&this.setRules(t)}setRules(t){this.rules=[...t].sort((e,i)=>e.priority-i.priority)}addRule(t){this.rules.push(t),this.rules.sort((e,i)=>e.priority-i.priority)}removeRule(t){this.rules=this.rules.filter(e=>e.id!==t)}getRules(){return[...this.rules]}applyOverrides(t,e){let i=e?at(k,e):{...k};const s=[];for(const o of this.rules)o.enabled&&j(o.criteria,t)&&(i=at(i,o.style),s.push(o));return{element:t,style:i,matchedRules:s}}applyOverridesToMany(t,e){const i=new Map;for(const s of t){const o=e?.get(s.expressId);i.set(s.expressId,this.applyOverrides(s,o))}return i}getMatchingRules(t){return this.rules.filter(e=>e.enabled&&j(e.criteria,t))}static validateCriteria(t){const e=[];if(It(t)){(!t.conditions||t.conditions.length===0)&&e.push("Compound criteria must have at least one condition");for(const i of t.conditions)e.push(...bt.validateCriteria(i))}else t.type||e.push("Criterion must have a type"),t.type==="property"&&!t.propertyName&&e.push("Property criterion requires propertyName"),t.type==="ifcType"&&(!t.ifcTypes||t.ifcTypes.length===0)&&e.push("IFC type criterion requires at least one type");return e}}function S(n,t=!0){return{type:"ifcType",ifcTypes:n,includeSubtypes:t}}function v(n,t,e,i){return{type:"property",propertyName:n,propertySet:i,operator:t,value:e}}function T(...n){return{logic:"and",conditions:n}}let he=0;function de(){return`builtin-rule-${++he}`}function F(n,t,e,i=100,s){return{id:de(),name:n,description:s,enabled:!0,priority:i,criteria:t,style:e}}const ue=[F("Walls - Heavy cut lines",S(["IfcWall"]),{lineWeight:"heavy",strokeColor:"#000000",hatchPattern:"diagonal",hatchSpacing:3,hatchAngle:45},100,"Standard wall representation"),F("Columns - Heavy cut lines",S(["IfcColumn"]),{lineWeight:"heavy",strokeColor:"#000000",hatchPattern:"cross-hatch",hatchSpacing:2},100),F("Slabs - Medium lines",S(["IfcSlab"]),{lineWeight:"medium",fillColor:"#E0E0E0",hatchPattern:"concrete"},90),F("Windows - Light blue tint",S(["IfcWindow"]),{lineWeight:"light",fillColor:"#E3F2FD",strokeColor:"#1976D2",hatchPattern:"none"},80),F("Doors - No fill",S(["IfcDoor"]),{lineWeight:"medium",fillColor:"#FFFFFF",strokeColor:"#000000",hatchPattern:"none"},80),F("Furniture - Hairline",S(["IfcFurnishingElement","IfcFurniture"]),{lineWeight:"hairline",strokeColor:"#666666",fillColor:"#F5F5F5",hatchPattern:"none"},60)],fe={id:"preset-architectural",name:"Architectural Standards",description:"ISO 128 compliant architectural drawing standards",icon:"PenTool",rules:ue,builtIn:!0,category:"Standards"},ge=[F("Fire Rated 2hr+ - Red",T(S(["IfcWall"]),v("FireRating","greaterOrEqual",120)),{fillColor:"#FFCDD2",strokeColor:"#C62828",lineWeight:"heavy",hatchPattern:"diagonal",hatchColor:"#C62828"},200,"2-hour or higher fire rating"),F("Fire Rated 1hr - Orange",T(S(["IfcWall"]),v("FireRating","greaterOrEqual",60)),{fillColor:"#FFE0B2",strokeColor:"#E65100",lineWeight:"heavy",hatchPattern:"diagonal",hatchColor:"#E65100"},190),F("Fire Rated 30min - Yellow",T(S(["IfcWall"]),v("FireRating","greaterOrEqual",30)),{fillColor:"#FFF9C4",strokeColor:"#F9A825",lineWeight:"medium",hatchPattern:"diagonal",hatchColor:"#F9A825"},180),F("Fire Doors - Red outline",T(S(["IfcDoor"]),v("FireRating","exists")),{strokeColor:"#C62828",lineWeight:"heavy"},200),F("Escape Routes - Green",T(S(["IfcSpace"]),v("OccupancyType","contains","CIRCULATION")),{fillColor:"#C8E6C9",strokeColor:"#2E7D32",lineWeight:"light"},150)],pe={id:"preset-fire-safety",name:"Fire Safety",description:"Highlight fire-rated elements and escape routes",icon:"Flame",rules:ge,builtIn:!0,category:"Safety"},ye=[F("Load-bearing Walls - Blue",T(S(["IfcWall"]),v("LoadBearing","equals",!0)),{fillColor:"#BBDEFB",strokeColor:"#1565C0",lineWeight:"heavy",hatchPattern:"diagonal",hatchColor:"#1565C0"},200),F("Columns - Blue heavy",S(["IfcColumn"]),{fillColor:"#90CAF9",strokeColor:"#0D47A1",lineWeight:"heavy",hatchPattern:"cross-hatch",hatchColor:"#0D47A1"},190),F("Beams - Blue medium",S(["IfcBeam"]),{fillColor:"#64B5F6",strokeColor:"#1976D2",lineWeight:"medium",hatchPattern:"diagonal"},180),F("Slabs - Light blue",S(["IfcSlab"]),{fillColor:"#E3F2FD",strokeColor:"#42A5F5",lineWeight:"medium"},170),F("Footings - Dark blue",S(["IfcFooting","IfcPile"]),{fillColor:"#1976D2",strokeColor:"#0D47A1",lineWeight:"heavy",hatchPattern:"concrete"},200),F("Non-structural - Faded",S(["IfcFurnishingElement","IfcFurniture","IfcCovering"]),{opacity:.3,lineWeight:"hairline"},50)],me={id:"preset-structural",name:"Structural Highlight",description:"Emphasize structural elements, fade non-structural",icon:"Building2",rules:ye,builtIn:!0,category:"Discipline"},xe=[F("HVAC Ducts - Blue",S(["IfcDuctSegment","IfcDuctFitting"]),{fillColor:"#E3F2FD",strokeColor:"#1976D2",lineWeight:"medium"},150),F("Air Terminals - Blue",S(["IfcAirTerminal","IfcAirTerminalBox"]),{fillColor:"#BBDEFB",strokeColor:"#1565C0",lineWeight:"light"},140),F("Pipes - Green",S(["IfcPipeSegment","IfcPipeFitting"]),{fillColor:"#E8F5E9",strokeColor:"#388E3C",lineWeight:"medium"},150),F("Plumbing Fixtures - Green",S(["IfcSanitaryTerminal","IfcWasteTerminal"]),{fillColor:"#C8E6C9",strokeColor:"#2E7D32",lineWeight:"light"},140),F("Cable Trays - Orange",S(["IfcCableCarrierSegment","IfcCableCarrierFitting"]),{fillColor:"#FFF3E0",strokeColor:"#E65100",lineWeight:"light"},150),F("Electrical Equipment - Yellow",S(["IfcElectricDistributionBoard","IfcSwitchingDevice","IfcOutlet"]),{fillColor:"#FFFDE7",strokeColor:"#F9A825",lineWeight:"light"},140),F("Architectural - Faded",S(["IfcWall","IfcSlab","IfcDoor","IfcWindow"]),{opacity:.4,strokeColor:"#9E9E9E"},50)],Ce={id:"preset-mep",name:"MEP Highlight",description:"Color-code mechanical, electrical, and plumbing systems",icon:"Wrench",rules:xe,builtIn:!0,category:"Discipline"},Ie={id:"preset-3d-colors",name:"Default",description:"By material color",icon:"Palette",rules:[],builtIn:!0,category:"Standards"},be=[F("All elements - Black and white",{type:"all"},{strokeColor:"#000000",fillColor:"#FFFFFF",hatchColor:"#000000"},1),F("Cut elements - Gray fill",S(["IfcWall","IfcColumn","IfcSlab","IfcBeam"]),{fillColor:"#E0E0E0"},10)],Me={id:"preset-monochrome",name:"Monochrome",description:"Black and white print-ready output",icon:"Printer",rules:be,builtIn:!0,category:"Output"},Te=[Ie,fe,pe,me,Ce,Me],Re={A0_LANDSCAPE:{id:"A0_LANDSCAPE",name:"A0 Landscape",category:"ISO",widthMm:1189,heightMm:841,orientation:"landscape",defaultMarginMm:20},A0_PORTRAIT:{id:"A0_PORTRAIT",name:"A0 Portrait",category:"ISO",widthMm:841,heightMm:1189,orientation:"portrait",defaultMarginMm:20},A1_LANDSCAPE:{id:"A1_LANDSCAPE",name:"A1 Landscape",category:"ISO",widthMm:841,heightMm:594,orientation:"landscape",defaultMarginMm:20},A1_PORTRAIT:{id:"A1_PORTRAIT",name:"A1 Portrait",category:"ISO",widthMm:594,heightMm:841,orientation:"portrait",defaultMarginMm:20},A2_LANDSCAPE:{id:"A2_LANDSCAPE",name:"A2 Landscape",category:"ISO",widthMm:594,heightMm:420,orientation:"landscape",defaultMarginMm:15},A2_PORTRAIT:{id:"A2_PORTRAIT",name:"A2 Portrait",category:"ISO",widthMm:420,heightMm:594,orientation:"portrait",defaultMarginMm:15},A3_LANDSCAPE:{id:"A3_LANDSCAPE",name:"A3 Landscape",category:"ISO",widthMm:420,heightMm:297,orientation:"landscape",defaultMarginMm:10},A3_PORTRAIT:{id:"A3_PORTRAIT",name:"A3 Portrait",category:"ISO",widthMm:297,heightMm:420,orientation:"portrait",defaultMarginMm:10},A4_LANDSCAPE:{id:"A4_LANDSCAPE",name:"A4 Landscape",category:"ISO",widthMm:297,heightMm:210,orientation:"landscape",defaultMarginMm:10},A4_PORTRAIT:{id:"A4_PORTRAIT",name:"A4 Portrait",category:"ISO",widthMm:210,heightMm:297,orientation:"portrait",defaultMarginMm:10},LETTER_LANDSCAPE:{id:"LETTER_LANDSCAPE",name:"US Letter Landscape",category:"ANSI",widthMm:279.4,heightMm:215.9,orientation:"landscape",defaultMarginMm:10},LETTER_PORTRAIT:{id:"LETTER_PORTRAIT",name:"US Letter Portrait",category:"ANSI",widthMm:215.9,heightMm:279.4,orientation:"portrait",defaultMarginMm:10},LEGAL_LANDSCAPE:{id:"LEGAL_LANDSCAPE",name:"US Legal Landscape",category:"ANSI",widthMm:355.6,heightMm:215.9,orientation:"landscape",defaultMarginMm:10},LEGAL_PORTRAIT:{id:"LEGAL_PORTRAIT",name:"US Legal Portrait",category:"ANSI",widthMm:215.9,heightMm:355.6,orientation:"portrait",defaultMarginMm:10},TABLOID_LANDSCAPE:{id:"TABLOID_LANDSCAPE",name:"US Tabloid Landscape",category:"ANSI",widthMm:431.8,heightMm:279.4,orientation:"landscape",defaultMarginMm:15},TABLOID_PORTRAIT:{id:"TABLOID_PORTRAIT",name:"US Tabloid Portrait",category:"ANSI",widthMm:279.4,heightMm:431.8,orientation:"portrait",defaultMarginMm:15},ANSI_C:{id:"ANSI_C",name:"ANSI C (17x22)",category:"ANSI",widthMm:558.8,heightMm:431.8,orientation:"landscape",defaultMarginMm:15},ANSI_D:{id:"ANSI_D",name:"ANSI D (22x34)",category:"ANSI",widthMm:863.6,heightMm:558.8,orientation:"landscape",defaultMarginMm:20},ANSI_E:{id:"ANSI_E",name:"ANSI E (34x44)",category:"ANSI",widthMm:1117.6,heightMm:863.6,orientation:"landscape",defaultMarginMm:20},ARCH_A:{id:"ARCH_A",name:"ARCH A (9x12)",category:"ARCH",widthMm:304.8,heightMm:228.6,orientation:"landscape",defaultMarginMm:10},ARCH_B:{id:"ARCH_B",name:"ARCH B (12x18)",category:"ARCH",widthMm:457.2,heightMm:304.8,orientation:"landscape",defaultMarginMm:15},ARCH_C:{id:"ARCH_C",name:"ARCH C (18x24)",category:"ARCH",widthMm:609.6,heightMm:457.2,orientation:"landscape",defaultMarginMm:15},ARCH_D:{id:"ARCH_D",name:"ARCH D (24x36)",category:"ARCH",widthMm:914.4,heightMm:609.6,orientation:"landscape",defaultMarginMm:20},ARCH_E:{id:"ARCH_E",name:"ARCH E (36x48)",category:"ARCH",widthMm:1219.2,heightMm:914.4,orientation:"landscape",defaultMarginMm:20},ARCH_E1:{id:"ARCH_E1",name:"ARCH E1 (30x42)",category:"ARCH",widthMm:1066.8,heightMm:762,orientation:"landscape",defaultMarginMm:20}},De={simple:{margins:{top:10,right:10,bottom:10,left:10,bindingMargin:0},border:{outerLineWeight:.7,innerLineWeight:.35,borderGap:0,showFoldMarks:!1,showTrimMarks:!1},showZoneReferences:!1,horizontalZones:0,verticalZones:0,zoneFontSize:3},professional:{margins:{top:10,right:10,bottom:10,left:20,bindingMargin:10},border:{outerLineWeight:.7,innerLineWeight:.35,borderGap:5,showFoldMarks:!0,showTrimMarks:!0},showZoneReferences:!0,horizontalZones:8,verticalZones:6,zoneFontSize:3.5},minimal:{margins:{top:5,right:5,bottom:5,left:5,bindingMargin:0},border:{outerLineWeight:.35,innerLineWeight:0,borderGap:0,showFoldMarks:!1,showTrimMarks:!1},showZoneReferences:!1,horizontalZones:0,verticalZones:0,zoneFontSize:3},iso:{margins:{top:10,right:10,bottom:10,left:20,bindingMargin:10},border:{outerLineWeight:.7,innerLineWeight:.35,borderGap:5,showFoldMarks:!0,showTrimMarks:!0},showZoneReferences:!0,horizontalZones:8,verticalZones:4,zoneFontSize:3.5},custom:{margins:{top:10,right:10,bottom:10,left:10,bindingMargin:0},border:{outerLineWeight:.5,innerLineWeight:.25,borderGap:3,showFoldMarks:!1,showTrimMarks:!1},showZoneReferences:!1,horizontalZones:0,verticalZones:0,zoneFontSize:3}},We=[{id:"project-name",label:"Project",value:"",editable:!0,autoPopulate:!0,autoPopulateSource:"project.name",fontSize:4.5,fontWeight:"bold",row:0,col:0,colSpan:2},{id:"drawing-title",label:"Drawing Title",value:"Section",editable:!0,autoPopulate:!1,fontSize:5,fontWeight:"bold",row:1,col:0,colSpan:2},{id:"drawing-number",label:"Drawing No.",value:"A-001",editable:!0,autoPopulate:!1,fontSize:4,fontWeight:"bold",row:2,col:0},{id:"revision",label:"Rev",value:"-",editable:!0,autoPopulate:!1,fontSize:3.5,fontWeight:"bold",row:2,col:1},{id:"scale",label:"Scale",value:"1:100",editable:!1,autoPopulate:!0,autoPopulateSource:"drawing.scale",fontSize:3.5,fontWeight:"normal",row:3,col:0},{id:"date",label:"Date",value:"",editable:!0,autoPopulate:!0,autoPopulateSource:"date.today",fontSize:3,fontWeight:"normal",row:3,col:1},{id:"drawn-by",label:"Drawn",value:"",editable:!0,autoPopulate:!1,fontSize:3,fontWeight:"normal",row:4,col:0},{id:"checked-by",label:"Checked",value:"",editable:!0,autoPopulate:!1,fontSize:3,fontWeight:"normal",row:4,col:1},{id:"sheet-number",label:"Sheet",value:"1 of 1",editable:!0,autoPopulate:!1,fontSize:3,fontWeight:"normal",row:5,col:0,colSpan:2}],_e={compact:{layout:"compact",position:"bottom-right",widthMm:120,heightMm:35,borderWeight:.5,gridWeight:.25,showRevisionHistory:!1,maxRevisionEntries:0},standard:{layout:"standard",position:"bottom-right",widthMm:180,heightMm:55,borderWeight:.5,gridWeight:.25,showRevisionHistory:!0,maxRevisionEntries:3},extended:{layout:"extended",position:"bottom-full",widthMm:0,heightMm:70,borderWeight:.5,gridWeight:.25,showRevisionHistory:!0,maxRevisionEntries:5},custom:{layout:"custom",position:"bottom-right",widthMm:180,heightMm:55,borderWeight:.5,gridWeight:.25,showRevisionHistory:!1,maxRevisionEntries:0}},ze={visible:!0,style:"alternating",position:"below-viewport",units:"metric",totalLengthM:5,primaryDivisions:5,subdivisions:2,heightMm:3,labelFontSize:2.5,showUnitLabel:!0,fillColor:"#000000",strokeColor:"#000000",lineWeight:.25};function Be(n,t){const i=Math.min(80,t*.8)*n/1e3,s=[.1,.2,.5,1,2,5,10,20,50,100,200,500,1e3];for(const o of s)if(o>=i*.5&&o<=i*1.5)return o;return Math.round(i)}const Ne={style:"simple",rotation:0,positionMm:{x:30,y:30},sizeMm:15};function Oe(n,t,e){const i=t.margins.left+t.margins.bindingMargin+t.border.borderGap,s=n.widthMm-t.margins.right-t.border.borderGap,o=t.margins.top+t.border.borderGap,r=n.heightMm-t.margins.bottom-t.border.borderGap;let a=i,l=o,c=s-i,u=r-o;const h=5;switch(e.position){case"bottom-right":u=r-o-e.heightMm-h;break;case"bottom-full":u=r-o-e.heightMm-h;break;case"right-strip":c=s-i-e.widthMm-h;break}return{x:a,y:l,width:c,height:u}}function He(n,t,e){const i=n.maxX-n.minX,s=n.maxY-n.minY,o=1e3/e.factor,r=i*o,a=s*o,l=.95,c=t.width*l/r,u=t.height*l/a,h=Math.min(c,u,1),d=o*h,f=i*d,g=s*d,y=t.x+(t.width-f)/2-n.minX*d,p=t.y+(t.height-g)/2+n.maxY*d;return{translateX:y,translateY:p,scaleFactor:d}}function Ue(n,t){let e=` <g id="drawing-frame">
|
|
195
|
-
`;const i=t.margins.left+t.margins.bindingMargin,s=t.margins.top,o=n.widthMm-t.margins.left-t.margins.right-t.margins.bindingMargin,r=n.heightMm-t.margins.top-t.margins.bottom;e+=` <rect x="${i.toFixed(2)}" y="${s.toFixed(2)}" `,e+=`width="${o.toFixed(2)}" height="${r.toFixed(2)}" `,e+=`fill="none" stroke="#000000" stroke-width="${t.border.outerLineWeight}"/>
|
|
196
|
-
`;let a=i,l=s,c=o,u=r;return t.border.borderGap>0&&t.border.innerLineWeight>0&&(a=i+t.border.borderGap,l=s+t.border.borderGap,c=o-2*t.border.borderGap,u=r-2*t.border.borderGap,e+=` <rect x="${a.toFixed(2)}" y="${l.toFixed(2)}" `,e+=`width="${c.toFixed(2)}" height="${u.toFixed(2)}" `,e+=`fill="none" stroke="#000000" stroke-width="${t.border.innerLineWeight}"/>
|
|
197
|
-
`),t.showZoneReferences&&t.horizontalZones>0&&(e+=we(i,s,o,r,t.border.borderGap,t.horizontalZones,t.verticalZones,t.zoneFontSize,t.border.innerLineWeight)),t.border.showFoldMarks&&(e+=Fe(n)),t.border.showTrimMarks&&(e+=Se(n)),e+=` </g>
|
|
198
|
-
`,{svgElements:e,innerBounds:{x:a,y:l,width:c,height:u}}}function we(n,t,e,i,s,o,r,a,l){let c=` <g id="zone-references">
|
|
199
|
-
`;const u=e/o,h=i/r,d="ABCDEFGHIJKLMNOPQRSTUVWXYZ";for(let f=0;f<o;f++){const g=n+u*(f+.5),y=d[f%26];if(c+=` <text x="${g.toFixed(2)}" y="${(t-s/2).toFixed(2)}" `,c+=`font-family="Arial, sans-serif" font-size="${a}" `,c+=`text-anchor="middle" dominant-baseline="middle">${y}</text>
|
|
200
|
-
`,c+=` <text x="${g.toFixed(2)}" y="${(t+i+s/2).toFixed(2)}" `,c+=`font-family="Arial, sans-serif" font-size="${a}" `,c+=`text-anchor="middle" dominant-baseline="middle">${y}</text>
|
|
201
|
-
`,f>0){const p=n+u*f;c+=` <line x1="${p.toFixed(2)}" y1="${t.toFixed(2)}" `,c+=`x2="${p.toFixed(2)}" y2="${(t-s+2).toFixed(2)}" `,c+=`stroke="#000000" stroke-width="${l}"/>
|
|
202
|
-
`,c+=` <line x1="${p.toFixed(2)}" y1="${(t+i).toFixed(2)}" `,c+=`x2="${p.toFixed(2)}" y2="${(t+i+s-2).toFixed(2)}" `,c+=`stroke="#000000" stroke-width="${l}"/>
|
|
203
|
-
`}}for(let f=0;f<r;f++){const g=t+h*(f+.5),y=(f+1).toString();if(c+=` <text x="${(n-s/2).toFixed(2)}" y="${g.toFixed(2)}" `,c+=`font-family="Arial, sans-serif" font-size="${a}" `,c+=`text-anchor="middle" dominant-baseline="middle">${y}</text>
|
|
204
|
-
`,c+=` <text x="${(n+e+s/2).toFixed(2)}" y="${g.toFixed(2)}" `,c+=`font-family="Arial, sans-serif" font-size="${a}" `,c+=`text-anchor="middle" dominant-baseline="middle">${y}</text>
|
|
205
|
-
`,f>0){const p=t+h*f;c+=` <line x1="${n.toFixed(2)}" y1="${p.toFixed(2)}" `,c+=`x2="${(n-s+2).toFixed(2)}" y2="${p.toFixed(2)}" `,c+=`stroke="#000000" stroke-width="${l}"/>
|
|
206
|
-
`,c+=` <line x1="${(n+e).toFixed(2)}" y1="${p.toFixed(2)}" `,c+=`x2="${(n+e+s-2).toFixed(2)}" y2="${p.toFixed(2)}" `,c+=`stroke="#000000" stroke-width="${l}"/>
|
|
207
|
-
`}}return c+=` </g>
|
|
208
|
-
`,c}function Fe(n,t,e,i,s){let o=` <g id="fold-marks">
|
|
209
|
-
`;if(n.heightMm>297){const u=Math.ceil(n.heightMm/297);for(let h=1;h<u;h++){const d=h*297;d<n.heightMm-20&&(o+=` <line x1="0" y1="${d.toFixed(2)}" x2="${5 .toFixed(2)}" y2="${d.toFixed(2)}" `,o+=`stroke="#000000" stroke-width="${.25}"/>
|
|
210
|
-
`,o+=` <line x1="${(n.widthMm-5).toFixed(2)}" y1="${d.toFixed(2)}" `,o+=`x2="${n.widthMm.toFixed(2)}" y2="${d.toFixed(2)}" `,o+=`stroke="#000000" stroke-width="${.25}"/>
|
|
211
|
-
`)}}if(n.widthMm>210){const u=Math.ceil(n.widthMm/210);for(let h=1;h<u;h++){const d=n.widthMm-h*210;d>20&&(o+=` <line x1="${d.toFixed(2)}" y1="0" x2="${d.toFixed(2)}" y2="${5 .toFixed(2)}" `,o+=`stroke="#000000" stroke-width="${.25}"/>
|
|
212
|
-
`,o+=` <line x1="${d.toFixed(2)}" y1="${(n.heightMm-5).toFixed(2)}" `,o+=`x2="${d.toFixed(2)}" y2="${n.heightMm.toFixed(2)}" `,o+=`stroke="#000000" stroke-width="${.25}"/>
|
|
213
|
-
`)}}return o+=` </g>
|
|
214
|
-
`,o}function Se(n){let t=` <g id="trim-marks">
|
|
215
|
-
`;return t+=` <line x1="${3 .toFixed(2)}" y1="0" x2="${3 .toFixed(2)}" y2="${8 .toFixed(2)}" `,t+=`stroke="#000000" stroke-width="${.15}"/>
|
|
216
|
-
`,t+=` <line x1="0" y1="${3 .toFixed(2)}" x2="${8 .toFixed(2)}" y2="${3 .toFixed(2)}" `,t+=`stroke="#000000" stroke-width="${.15}"/>
|
|
217
|
-
`,t+=` <line x1="${(n.widthMm-3).toFixed(2)}" y1="0" `,t+=`x2="${(n.widthMm-3).toFixed(2)}" y2="${8 .toFixed(2)}" `,t+=`stroke="#000000" stroke-width="${.15}"/>
|
|
218
|
-
`,t+=` <line x1="${(n.widthMm-8).toFixed(2)}" y1="${3 .toFixed(2)}" `,t+=`x2="${n.widthMm.toFixed(2)}" y2="${3 .toFixed(2)}" `,t+=`stroke="#000000" stroke-width="${.15}"/>
|
|
219
|
-
`,t+=` <line x1="${3 .toFixed(2)}" y1="${(n.heightMm-8).toFixed(2)}" `,t+=`x2="${3 .toFixed(2)}" y2="${n.heightMm.toFixed(2)}" `,t+=`stroke="#000000" stroke-width="${.15}"/>
|
|
220
|
-
`,t+=` <line x1="0" y1="${(n.heightMm-3).toFixed(2)}" `,t+=`x2="${8 .toFixed(2)}" y2="${(n.heightMm-3).toFixed(2)}" `,t+=`stroke="#000000" stroke-width="${.15}"/>
|
|
221
|
-
`,t+=` <line x1="${(n.widthMm-3).toFixed(2)}" y1="${(n.heightMm-8).toFixed(2)}" `,t+=`x2="${(n.widthMm-3).toFixed(2)}" y2="${n.heightMm.toFixed(2)}" `,t+=`stroke="#000000" stroke-width="${.15}"/>
|
|
222
|
-
`,t+=` <line x1="${(n.widthMm-8).toFixed(2)}" y1="${(n.heightMm-3).toFixed(2)}" `,t+=`x2="${n.widthMm.toFixed(2)}" y2="${(n.heightMm-3).toFixed(2)}" `,t+=`stroke="#000000" stroke-width="${.15}"/>
|
|
223
|
-
`,t+=` </g>
|
|
224
|
-
`,t}function je(n,t,e=[],i){let s,o,r,a;switch(n.position){case"bottom-right":r=n.widthMm,a=n.heightMm,s=t.x+t.width-r,o=t.y+t.height-a;break;case"bottom-full":r=t.width,a=n.heightMm,s=t.x,o=t.y+t.height-a;break;case"right-strip":r=n.widthMm,a=t.height,s=t.x+t.width-r,o=t.y;break;default:r=n.widthMm,a=n.heightMm,s=t.x+t.width-r,o=t.y+t.height-a}let l=` <g id="title-block">
|
|
225
|
-
`;return n.backgroundColor&&(l+=` <rect x="${s.toFixed(2)}" y="${o.toFixed(2)}" `,l+=`width="${r.toFixed(2)}" height="${a.toFixed(2)}" `,l+=`fill="${n.backgroundColor}"/>
|
|
226
|
-
`),l+=` <rect x="${s.toFixed(2)}" y="${o.toFixed(2)}" `,l+=`width="${r.toFixed(2)}" height="${a.toFixed(2)}" `,l+=`fill="none" stroke="#000000" stroke-width="${n.borderWeight}"/>
|
|
227
|
-
`,l+=$e(n,s,o,r,a),n.logo?.source&&(l+=Ae(n.logo,s,o,r,a)),i?.scaleBar?.visible&&i?.scale&&a>10&&(l+=Le(i.scaleBar,i.scale,s,o,r,a,n.logo!=null,i.effectiveScaleFactor)),i?.northArrow&&i.northArrow.style!=="none"&&a>15&&(l+=Ee(i.northArrow,s,o,r,a,n.logo!=null,n.position)),n.showRevisionHistory&&e.length>0&&(l+=Pe(e.slice(0,n.maxRevisionEntries),s,o,r,a,n)),l+=` </g>
|
|
228
|
-
`,{svgElements:l,bounds:{x:s,y:o,width:r,height:a}}}function $e(n,t,e,i,s){let o=` <g id="title-block-fields">
|
|
229
|
-
`;const a=n.logo?50:0,l=n.showRevisionHistory?20:0,c=i-a-5,u=s-l-4,h=new Map;for(const C of n.fields){const b=C.row??0;h.has(b)||h.set(b,[]),h.get(b).push(C)}const d=Math.max(...Array.from(h.keys()))+1,f=[];let g=0;for(let C=0;C<d;C++){const b=h.get(C)||[],A=b.length>0?Math.max(...b.map(E=>E.fontSize)):3,P=Math.min(A*.5,2.2)+1+A+2;f.push(P),g+=P}const y=g>u?u/g:1,p=f.map(C=>C*y),m=t+a+2,I=e+2,w=c/2,x=[I];for(let C=0;C<p.length-1;C++)x.push(x[C]+p[C]);for(let C=1;C<d;C++){const b=x[C];o+=` <line x1="${m.toFixed(2)}" y1="${b.toFixed(2)}" `,o+=`x2="${(m+c-4).toFixed(2)}" y2="${b.toFixed(2)}" `,o+=`stroke="#000000" stroke-width="${n.gridWeight}"/>
|
|
230
|
-
`}for(const[C,b]of h)if(b.some(M=>(M.colSpan??1)<2)){const M=m+w,P=x[C],E=x[C]+p[C];o+=` <line x1="${M.toFixed(2)}" y1="${P.toFixed(2)}" `,o+=`x2="${M.toFixed(2)}" y2="${E.toFixed(2)}" `,o+=`stroke="#000000" stroke-width="${n.gridWeight}"/>
|
|
231
|
-
`}for(const[C,b]of h){const A=x[C];p[C];for(const M of b){const P=M.col??0;M.colSpan;const E=m+P*w+1.5,L=y<1?y:1,V=Math.min(M.fontSize*.45,2.2)*Math.max(L,.7),X=M.fontSize*Math.max(L,.7),q=A+.5+V;o+=` <text x="${E.toFixed(2)}" y="${q.toFixed(2)}" `,o+=`font-family="Arial, sans-serif" font-size="${V.toFixed(2)}" `,o+=`fill="#666666">${B(M.label)}</text>
|
|
232
|
-
`;const Mt=q+.8+X*.8;o+=` <text x="${E.toFixed(2)}" y="${Mt.toFixed(2)}" `,o+=`font-family="Arial, sans-serif" font-size="${X.toFixed(2)}" `,o+=`font-weight="${M.fontWeight}" fill="#000000">${B(M.value)}</text>
|
|
233
|
-
`}}return o+=` </g>
|
|
234
|
-
`,o}function Ae(n,t,e,i,s){let o=` <g id="title-block-logo">
|
|
235
|
-
`,r,a;switch(n.position){case"top-left":r=t+3,a=e+3;break;case"top-right":r=t+i-n.widthMm-3,a=e+3;break;case"bottom-left":default:r=t+3,a=e+s-n.heightMm-3;break}return o+=` <image x="${r.toFixed(2)}" y="${a.toFixed(2)}" `,o+=`width="${n.widthMm.toFixed(2)}" height="${n.heightMm.toFixed(2)}" `,o+=`href="${B(n.source)}" preserveAspectRatio="xMidYMid meet"/>
|
|
236
|
-
`,o+=` </g>
|
|
237
|
-
`,o}function Pe(n,t,e,i,s,o){let r=` <g id="revision-history">
|
|
238
|
-
`;const l=e-18-2,c=4,u=2.2;r+=` <rect x="${t.toFixed(2)}" y="${l.toFixed(2)}" `,r+=`width="${i.toFixed(2)}" height="${18 .toFixed(2)}" `,r+=`fill="none" stroke="#000000" stroke-width="${o.gridWeight}"/>
|
|
239
|
-
`;const h=[{label:"REV",width:i*.1},{label:"DESCRIPTION",width:i*.5},{label:"DATE",width:i*.2},{label:"BY",width:i*.2}];let d=t;for(const f of h)r+=` <text x="${(d+1).toFixed(2)}" y="${(l+3).toFixed(2)}" `,r+=`font-family="Arial, sans-serif" font-size="${u}" `,r+=`font-weight="bold" fill="#000000">${f.label}</text>
|
|
240
|
-
`,d>t&&(r+=` <line x1="${d.toFixed(2)}" y1="${l.toFixed(2)}" `,r+=`x2="${d.toFixed(2)}" y2="${(l+18).toFixed(2)}" `,r+=`stroke="#000000" stroke-width="${o.gridWeight}"/>
|
|
241
|
-
`),d+=f.width;r+=` <line x1="${t.toFixed(2)}" y1="${(l+c).toFixed(2)}" `,r+=`x2="${(t+i).toFixed(2)}" y2="${(l+c).toFixed(2)}" `,r+=`stroke="#000000" stroke-width="${o.gridWeight}"/>
|
|
242
|
-
`;for(let f=0;f<n.length&&f<o.maxRevisionEntries;f++){const g=n[f],y=l+c*(f+1.5);d=t;const p=[g.revision,g.description,g.date,g.author];for(let m=0;m<h.length;m++){const I=Math.floor(h[m].width/2),w=p[m].length>I?p[m].substring(0,I-2)+"..":p[m];r+=` <text x="${(d+1).toFixed(2)}" y="${y.toFixed(2)}" `,r+=`font-family="Arial, sans-serif" font-size="${u}" `,r+=`fill="#000000">${B(w)}</text>
|
|
243
|
-
`,d+=h[m].width}f<n.length-1&&(r+=` <line x1="${t.toFixed(2)}" y1="${(l+c*(f+2)).toFixed(2)}" `,r+=`x2="${(t+i).toFixed(2)}" y2="${(l+c*(f+2)).toFixed(2)}" `,r+=`stroke="#000000" stroke-width="${o.gridWeight*.5}"/>
|
|
244
|
-
`)}return r+=` </g>
|
|
245
|
-
`,r}function Le(n,t,e,i,s,o,r,a){let l=` <g id="title-block-scale-bar">
|
|
246
|
-
`;const c=a??t.factor,u=e+3,h=i+o-8,d=Math.min(s*.3,50),f=n.totalLengthM*1e3/c,g=Math.min(f,d),y=Math.min(n.heightMm,3),p=g*c/1e3,m=n.primaryDivisions,I=g/m;for(let b=0;b<m;b++){const A=u+b*I,M=b%2===0?n.fillColor:"#ffffff";l+=` <rect x="${A.toFixed(2)}" y="${h.toFixed(2)}" `,l+=`width="${I.toFixed(2)}" height="${y.toFixed(2)}" `,l+=`fill="${M}" stroke="${n.strokeColor}" stroke-width="${n.lineWeight}"/>
|
|
247
|
-
`}const w=1.8,x=h+y+w+.3;l+=` <text x="${u.toFixed(2)}" y="${x.toFixed(2)}" `,l+=`font-family="Arial, sans-serif" font-size="${w}" `,l+=`text-anchor="start" fill="#000000">0</text>
|
|
248
|
-
`;const C=p<1?`${(p*100).toFixed(0)}cm`:`${p.toFixed(0)}m`;return l+=` <text x="${(u+g).toFixed(2)}" y="${x.toFixed(2)}" `,l+=`font-family="Arial, sans-serif" font-size="${w}" `,l+=`text-anchor="end" fill="#000000">${C}</text>
|
|
249
|
-
`,l+=` </g>
|
|
250
|
-
`,l}function Ee(n,t,e,i,s,o,r){let a=` <g id="title-block-north-arrow">
|
|
251
|
-
`;const l=Math.min(n.sizeMm,8,s*.6),c=t+i-l-5,u=e+s-l/2-3,h=n.rotation;a+=` <g transform="translate(${c.toFixed(2)}, ${u.toFixed(2)}) rotate(${h})">
|
|
252
|
-
`;const d=l/2;a+=` <polygon points="0,${(-d).toFixed(2)} ${(-d/3).toFixed(2)},${(d/2).toFixed(2)} ${(d/3).toFixed(2)},${(d/2).toFixed(2)}" `,a+=`fill="#000000" stroke="none"/>
|
|
253
|
-
`,a+=` <polygon points="0,${(d/3).toFixed(2)} ${(-d/3).toFixed(2)},${(d/2).toFixed(2)} ${(d/3).toFixed(2)},${(d/2).toFixed(2)}" `,a+=`fill="#ffffff" stroke="#000000" stroke-width="0.25"/>
|
|
254
|
-
`;const f=l*.4;return a+=` <text x="0" y="${(-d-1).toFixed(2)}" `,a+=`font-family="Arial, sans-serif" font-size="${f.toFixed(2)}" font-weight="bold" `,a+=`text-anchor="middle" fill="#000000">N</text>
|
|
255
|
-
`,a+=` </g>
|
|
256
|
-
`,a+=` </g>
|
|
257
|
-
`,a}function B(n){return n.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}export{Te as B,O as C,We as D,De as F,bt as G,Re as P,_e as T,Oe as a,Ne as b,Be as c,ze as d,He as e,ke as f,ve as g,je as h,Ue as r};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const x="http://www.w3.org/2001/XMLSchema";class M extends Error{constructor(e,a){super(e),this.details=a,this.name="IDSParseError"}}function Ie(t){const e=typeof t=="string"?t:new TextDecoder().decode(t),i=new DOMParser().parseFromString(e,"text/xml"),n=i.querySelector("parsererror");if(n)throw new M("Invalid XML format",n.textContent||void 0);const s=i.documentElement;if(s.localName!=="ids")throw new M(`Invalid root element: expected "ids", got "${s.localName}"`);return{info:F(s),specifications:_(s)}}function F(t){const e=o(t,"info");return e?{title:b(e,"title")||"Untitled IDS",copyright:b(e,"copyright"),version:b(e,"version"),author:b(e,"author"),date:b(e,"date"),purpose:b(e,"purpose"),milestone:b(e,"milestone"),description:b(e,"description")}:{title:"Untitled IDS"}}function _(t){const e=o(t,"specifications");return e?R(e,"specification").map((i,n)=>L(i,n)):[]}function L(t,e){const a=t.getAttribute("name")||`Specification ${e+1}`,n=(t.getAttribute("ifcVersion")||"IFC4").split(/\s+/).map(d=>D(d)).filter(d=>d!==null),s=o(t,"applicability"),r={facets:s?B(s):[]},u=(s?s.getAttribute("minOccurs"):null)??t.getAttribute("minOccurs"),p=(s?s.getAttribute("maxOccurs"):null)??t.getAttribute("maxOccurs");let c;if(u!==null){const d=parseInt(u,10);Number.isFinite(d)&&(c=d)}let m;if(p!==null){const d=parseInt(p,10);p==="unbounded"?m="unbounded":Number.isFinite(d)&&(m=d)}const h=o(t,"requirements"),v=h?z(h):[];return{id:t.getAttribute("identifier")||`spec-${e}`,name:a,description:t.getAttribute("description")||void 0,instructions:t.getAttribute("instructions")||void 0,identifier:t.getAttribute("identifier")||void 0,ifcVersions:n.length>0?n:["IFC4"],applicability:r,requirements:v,minOccurs:c,maxOccurs:m}}function D(t){const e=t.toUpperCase().replace(/[^A-Z0-9]/g,"");switch(e){case"IFC2X3":return"IFC2X3";case"IFC4":return"IFC4";case"IFC4X3":case"IFC4X3ADD2":return"IFC4X3";default:return e.startsWith("IFC4X3")?"IFC4X3":e.startsWith("IFC4")?"IFC4":e.startsWith("IFC2X3")?"IFC2X3":null}}function B(t){const e=[];for(const a of Array.from(t.children)){const i=C(a);i&&e.push(i)}return e}function C(t){switch(t.localName.toLowerCase()){case"entity":return V(t);case"attribute":return q(t);case"property":return H(t);case"classification":return k(t);case"material":return U(t);case"partof":return Y(t);default:return null}}function V(t){const e=o(t,"name"),a=o(t,"predefinedType");if(!e)throw new M("Entity facet must have a name element");return{type:"entity",name:f(e),predefinedType:a?f(a):void 0}}function q(t){const e=o(t,"name"),a=o(t,"value");if(!e)throw new M("Attribute facet must have a name element");return{type:"attribute",name:f(e),value:a?f(a):void 0}}function H(t){const e=o(t,"propertySet"),a=o(t,"baseName"),i=o(t,"dataType"),n=o(t,"value");if(!e)throw new M("Property facet must have a propertySet element");if(!a)throw new M("Property facet must have a baseName element");return{type:"property",propertySet:f(e),baseName:f(a),dataType:i?f(i):void 0,value:n?f(n):void 0}}function k(t){const e=o(t,"system"),a=o(t,"value");return{type:"classification",system:e?f(e):void 0,value:a?f(a):void 0}}function U(t){const e=o(t,"value");return{type:"material",value:e?f(e):void 0}}function Y(t){const e=t.getAttribute("relation")||"IfcRelContainedInSpatialStructure",a=o(t,"entity");return{type:"partOf",relation:G(e),entity:a?V(a):void 0}}function G(t){const e=t.toUpperCase();return e.includes("AGGREGATE")?"IfcRelAggregates":e.includes("CONTAINED")||e.includes("SPATIAL")?"IfcRelContainedInSpatialStructure":e.includes("NEST")?"IfcRelNests":e.includes("VOID")?"IfcRelVoidsElement":e.includes("FILL")?"IfcRelFillsElement":"IfcRelContainedInSpatialStructure"}function z(t){const e=[];let a=0;for(const i of Array.from(t.children)){const n=C(i);if(n){const s=i.getAttribute("minOccurs"),r=i.getAttribute("maxOccurs");let u="required";s==="0"&&r==="0"?u="prohibited":s==="0"&&(u="optional"),e.push({id:`req-${a++}`,facet:n,optionality:u,description:i.getAttribute("description")||void 0,instructions:i.getAttribute("instructions")||void 0})}}return e}function f(t){const e=o(t,"simpleValue");if(e)return{type:"simpleValue",value:e.textContent?.trim()||""};const a=T(t,"restriction",x)||o(t,"restriction");if(a)return j(a);const i=t.textContent?.trim();return i?{type:"simpleValue",value:i}:{type:"simpleValue",value:""}}function j(t){const e=T(t,"pattern",x)||o(t,"pattern");if(e)return{type:"pattern",pattern:e.getAttribute("value")||e.textContent||""};const a=W(t,"enumeration",x);if(a.length===0){const p=R(t,"enumeration");if(p.length>0)return{type:"enumeration",values:p.map(c=>c.getAttribute("value")||c.textContent||"")}}else return{type:"enumeration",values:a.map(p=>p.getAttribute("value")||p.textContent||"")};const i=T(t,"minInclusive",x)||o(t,"minInclusive"),n=T(t,"maxInclusive",x)||o(t,"maxInclusive"),s=T(t,"minExclusive",x)||o(t,"minExclusive"),r=T(t,"maxExclusive",x)||o(t,"maxExclusive");if(i||n||s||r){const p={type:"bounds"};if(i){const c=parseFloat(i.getAttribute("value")||i.textContent||"");isNaN(c)||(p.minInclusive=c)}if(n){const c=parseFloat(n.getAttribute("value")||n.textContent||"");isNaN(c)||(p.maxInclusive=c)}if(s){const c=parseFloat(s.getAttribute("value")||s.textContent||"");isNaN(c)||(p.minExclusive=c)}if(r){const c=parseFloat(r.getAttribute("value")||r.textContent||"");isNaN(c)||(p.maxExclusive=c)}return p}const u=t.getAttribute("base");return u?{type:"simpleValue",value:u}:{type:"simpleValue",value:t.textContent?.trim()||""}}function o(t,e){for(const a of Array.from(t.children))if(a.localName.toLowerCase()===e.toLowerCase())return a;return null}function R(t,e){const a=[];for(const i of Array.from(t.children))i.localName.toLowerCase()===e.toLowerCase()&&a.push(i);return a}function T(t,e,a){for(const i of Array.from(t.children))if(i.localName.toLowerCase()===e.toLowerCase()&&i.namespaceURI===a)return i;return null}function W(t,e,a){const i=[];for(const n of Array.from(t.children))n.localName.toLowerCase()===e.toLowerCase()&&n.namespaceURI===a&&i.push(n);return i}function b(t,e){return o(t,e)?.textContent?.trim()||void 0}const A=1e-6;function y(t,e){if(e==null)return!1;switch(t.type){case"simpleValue":return X(t,e);case"pattern":return K(t,e);case"enumeration":return Z(t,e);case"bounds":return Q(t,e);default:return!1}}function X(t,e){const a=t.value,i=String(e);if(i===a||i.toUpperCase()===a.toUpperCase())return!0;const n=parseFloat(a),s=typeof e=="number"?e:parseFloat(i);if(!isNaN(n)&&!isNaN(s))return Math.abs(n-s)<=A;if(typeof e=="boolean"){const p=a.toLowerCase();if(p==="true"||p==="1")return e===!0;if(p==="false"||p==="0")return e===!1}const r=i.toLowerCase(),u=a.toLowerCase();return(r==="true"||r==="false")&&(u==="true"||u==="false")?r===u:!1}function K(t,e){const a=String(e);try{const i=J(t.pattern);return new RegExp(`^${i}$`,"i").test(a)}catch{return!1}}function J(t){return t.replace(/\\i/g,"[A-Za-z_:]").replace(/\\c/g,"[A-Za-z0-9._:-]").replace(/\\p\{[^}]+\}/g,".").replace(/\[([^\]]+)-\[[^\]]+\]\]/g,"[$1]")}function Z(t,e){const a=String(e),i=a.toUpperCase();return t.values.some(n=>{if(n===a||n.toUpperCase()===i)return!0;const s=parseFloat(n),r=typeof e=="number"?e:parseFloat(a);return!isNaN(s)&&!isNaN(r)?Math.abs(s-r)<=A:!1})}function Q(t,e){const a=typeof e=="number"?e:parseFloat(String(e));return!(isNaN(a)||t.minInclusive!==void 0&&a<t.minInclusive-A||t.maxInclusive!==void 0&&a>t.maxInclusive+A||t.minExclusive!==void 0&&a<=t.minExclusive||t.maxExclusive!==void 0&&a>=t.maxExclusive)}function l(t){switch(t.type){case"simpleValue":return`"${t.value}"`;case"pattern":return`pattern "${t.pattern}"`;case"enumeration":return t.values.length===1?`"${t.values[0]}"`:`one of [${t.values.map(e=>`"${e}"`).join(", ")}]`;case"bounds":return ee(t);default:return"unknown"}}function ee(t){const e=[];return t.minInclusive!==void 0&&t.maxInclusive!==void 0?`between ${t.minInclusive} and ${t.maxInclusive}`:(t.minInclusive!==void 0&&e.push(`>= ${t.minInclusive}`),t.maxInclusive!==void 0&&e.push(`<= ${t.maxInclusive}`),t.minExclusive!==void 0&&e.push(`> ${t.minExclusive}`),t.maxExclusive!==void 0&&e.push(`< ${t.maxExclusive}`),e.join(" and ")||"any value")}function te(t,e,a){const i=a.getEntityType(e);if(!i)return{passed:!1,actualValue:void 0,expectedValue:l(t.name),failure:{type:"ENTITY_TYPE_MISMATCH",field:"entityType",actual:"unknown",expected:l(t.name)}};if(!y(t.name,i))return{passed:!1,actualValue:i,expectedValue:l(t.name),failure:{type:"ENTITY_TYPE_MISMATCH",field:"entityType",actual:i,expected:l(t.name)}};if(t.predefinedType){const n=a.getObjectType(e);if(!n)return{passed:!1,actualValue:i,expectedValue:`${l(t.name)} with predefinedType ${l(t.predefinedType)}`,failure:{type:"PREDEFINED_TYPE_MISSING",field:"predefinedType",expected:l(t.predefinedType)}};if(!y(t.predefinedType,n))return{passed:!1,actualValue:`${i}[${n}]`,expectedValue:`${l(t.name)} with predefinedType ${l(t.predefinedType)}`,failure:{type:"PREDEFINED_TYPE_MISMATCH",field:"predefinedType",actual:n,expected:l(t.predefinedType)}}}return{passed:!0,actualValue:t.predefinedType?`${i}[${a.getObjectType(e)||""}]`:i,expectedValue:l(t.name)}}function ie(t,e){const a=t.name;if(a.type==="simpleValue")return e.getEntitiesByType(a.value);if(a.type==="enumeration"){const i=[];for(const n of a.values)i.push(...e.getEntitiesByType(n));return i}}const ae=["Name","Description","ObjectType","Tag","GlobalId","LongName"];function ne(t,e,a){const i=t.name;let n;if(i.type==="simpleValue")n=i.value;else{const r=ae.filter(u=>y(i,u));if(r.length===0)return{passed:!1,failure:{type:"ATTRIBUTE_MISSING",field:l(i),expected:l(i)}};n=r[0]}const s=se(n,e,a);return s==null||s===""?{passed:!1,actualValue:void 0,expectedValue:t.value?l(t.value):`attribute "${n}" to exist`,failure:{type:"ATTRIBUTE_MISSING",field:n,expected:t.value?l(t.value):"any value"}}:t.value?y(t.value,s)?{passed:!0,actualValue:String(s),expectedValue:l(t.value)}:{passed:!1,actualValue:String(s),expectedValue:l(t.value),failure:{type:t.value.type==="pattern"?"ATTRIBUTE_PATTERN_MISMATCH":"ATTRIBUTE_VALUE_MISMATCH",field:n,actual:String(s),expected:l(t.value)}}:{passed:!0,actualValue:String(s),expectedValue:`attribute "${n}" to exist`}}function se(t,e,a){switch(t.toLowerCase()){case"name":return a.getEntityName(e);case"description":return a.getDescription(e);case"objecttype":return a.getObjectType(e);case"globalid":return a.getGlobalId(e);default:return a.getAttribute(e,t)}}function re(t,e,a){const i=a.getPropertySets(e);if(i.length===0)return{passed:!1,expectedValue:`property "${l(t.baseName)}" in "${l(t.propertySet)}"`,failure:{type:"PSET_MISSING",field:l(t.propertySet),expected:l(t.propertySet)}};const n=i.filter(u=>y(t.propertySet,u.name));if(n.length===0){const u=i.map(p=>p.name).join(", ");return{passed:!1,actualValue:u||"(none)",expectedValue:l(t.propertySet),failure:{type:"PSET_MISSING",field:"propertySet",actual:u,expected:l(t.propertySet),context:{availablePsets:u}}}}for(const u of n){const p=le(t,u);if(p.passed)return p}const s=n.map(u=>u.name).join(", "),r=n.flatMap(u=>u.properties.map(p=>`${u.name}.${p.name}`)).join(", ");return{passed:!1,actualValue:r||"(none)",expectedValue:`${l(t.propertySet)}.${l(t.baseName)}`,failure:{type:"PROPERTY_MISSING",field:l(t.baseName),expected:l(t.baseName),context:{propertySet:s,availableProperties:r}}}}function le(t,e){const a=e.properties.filter(i=>y(t.baseName,i.name));if(a.length===0)return{passed:!1,failure:{type:"PROPERTY_MISSING",field:l(t.baseName),expected:l(t.baseName),context:{propertySet:e.name,availableProperties:e.properties.map(i=>i.name).join(", ")}}};for(const i of a){if(t.dataType&&!y(t.dataType,i.dataType))return{passed:!1,actualValue:`${e.name}.${i.name} (${i.dataType})`,expectedValue:`dataType ${l(t.dataType)}`,failure:{type:"PROPERTY_DATATYPE_MISMATCH",field:`${e.name}.${i.name}`,actual:i.dataType,expected:l(t.dataType)}};if(t.value){const n=i.value;if(n==null)return{passed:!1,actualValue:"(empty)",expectedValue:l(t.value),failure:{type:"PROPERTY_VALUE_MISMATCH",field:`${e.name}.${i.name}`,actual:"(empty)",expected:l(t.value)}};if(!y(t.value,n)){const s=t.value.type==="bounds"?"PROPERTY_OUT_OF_BOUNDS":"PROPERTY_VALUE_MISMATCH";return{passed:!1,actualValue:String(n),expectedValue:l(t.value),failure:{type:s,field:`${e.name}.${i.name}`,actual:String(n),expected:l(t.value)}}}}return{passed:!0,actualValue:`${e.name}.${i.name} = ${i.value}`,expectedValue:t.value?l(t.value):"property exists"}}return{passed:!1,failure:{type:"PROPERTY_MISSING",field:l(t.baseName)}}}function ue(t,e,a){const i=a.getClassifications(e);if(!t.system&&!t.value)return i.length===0?{passed:!1,actualValue:"(none)",expectedValue:"any classification",failure:{type:"CLASSIFICATION_MISSING",expected:"any classification"}}:{passed:!0,actualValue:i.map(s=>`${s.system}:${s.value}`).join(", "),expectedValue:"any classification"};let n=i;if(t.system&&(n=i.filter(s=>y(t.system,s.system)),n.length===0)){const s=[...new Set(i.map(r=>r.system))].join(", ");return{passed:!1,actualValue:s||"(none)",expectedValue:l(t.system),failure:{type:"CLASSIFICATION_SYSTEM_MISMATCH",field:"system",actual:s,expected:l(t.system),context:{availableSystems:s}}}}if(t.value){const s=n.filter(r=>y(t.value,r.value));if(s.length===0){const r=n.map(u=>u.value).join(", ");return{passed:!1,actualValue:r||"(none)",expectedValue:l(t.value),failure:{type:"CLASSIFICATION_VALUE_MISMATCH",field:"value",actual:r,expected:l(t.value),context:{system:t.system?l(t.system):"any",availableValues:r}}}}return{passed:!0,actualValue:s.map(r=>`${r.system}:${r.value}`).join(", "),expectedValue:t.system?`${l(t.system)}:${l(t.value)}`:l(t.value)}}return{passed:!0,actualValue:n.map(s=>`${s.system}:${s.value}`).join(", "),expectedValue:l(t.system)}}function pe(t,e,a){const i=a.getMaterials(e);if(!t.value)return i.length===0?{passed:!1,actualValue:"(none)",expectedValue:"any material",failure:{type:"MATERIAL_MISSING",expected:"any material"}}:{passed:!0,actualValue:i.map(s=>s.name).join(", "),expectedValue:"any material"};const n=i.filter(s=>y(t.value,s.name)||s.category&&y(t.value,s.category));if(n.length===0){if(i.length===0)return{passed:!1,actualValue:"(none)",expectedValue:l(t.value),failure:{type:"MATERIAL_MISSING",expected:l(t.value)}};const s=i.map(r=>r.name).join(", ");return{passed:!1,actualValue:s,expectedValue:l(t.value),failure:{type:"MATERIAL_VALUE_MISMATCH",field:"material",actual:s,expected:l(t.value),context:{availableMaterials:s}}}}return{passed:!0,actualValue:n.map(s=>s.name).join(", "),expectedValue:l(t.value)}}const S={IfcRelAggregates:"aggregated in",IfcRelContainedInSpatialStructure:"contained in",IfcRelNests:"nested in",IfcRelVoidsElement:"voiding",IfcRelFillsElement:"filling"};function oe(t,e,a){const i=a.getParent(e,t.relation);if(!i){const r=S[t.relation]||t.relation,u=t.entity?l(t.entity.name):"any entity";return{passed:!1,actualValue:"(no parent)",expectedValue:`${r} ${u}`,failure:{type:"PARTOF_RELATION_MISSING",field:t.relation,expected:`${r} ${u}`,context:{relation:t.relation}}}}if(!t.entity){const r=S[t.relation]||t.relation;return{passed:!0,actualValue:`${r} ${i.entityType}`,expectedValue:`${r} any entity`}}if(!y(t.entity.name,i.entityType)){const r=S[t.relation]||t.relation;return{passed:!1,actualValue:`${r} ${i.entityType}`,expectedValue:`${r} ${l(t.entity.name)}`,failure:{type:"PARTOF_ENTITY_MISMATCH",field:"entity",actual:i.entityType,expected:l(t.entity.name),context:{relation:t.relation,parentId:String(i.expressId)}}}}if(t.entity.predefinedType){if(!i.predefinedType)return{passed:!1,actualValue:`${i.entityType} (no predefinedType)`,expectedValue:`${l(t.entity.name)} with predefinedType ${l(t.entity.predefinedType)}`,failure:{type:"PARTOF_ENTITY_MISMATCH",field:"predefinedType",expected:l(t.entity.predefinedType),context:{relation:t.relation,parentType:i.entityType}}};if(!y(t.entity.predefinedType,i.predefinedType))return{passed:!1,actualValue:`${i.entityType}[${i.predefinedType}]`,expectedValue:`${l(t.entity.name)}[${l(t.entity.predefinedType)}]`,failure:{type:"PARTOF_ENTITY_MISMATCH",field:"predefinedType",actual:i.predefinedType,expected:l(t.entity.predefinedType),context:{relation:t.relation,parentType:i.entityType}}}}const n=S[t.relation]||t.relation,s=i.predefinedType?`${i.entityType}[${i.predefinedType}]`:i.entityType;return{passed:!0,actualValue:`${n} ${s}`,expectedValue:`${n} ${l(t.entity.name)}`}}function w(t,e,a){switch(t.type){case"entity":return te(t,e,a);case"attribute":return ne(t,e,a);case"property":return re(t,e,a);case"classification":return ue(t,e,a);case"material":return pe(t,e,a);case"partOf":return oe(t,e,a);default:return{passed:!1,failure:{type:"ENTITY_TYPE_MISMATCH",expected:"known facet type",actual:t.type}}}}function ce(t,e){switch(t.type){case"entity":return ie(t,e);default:return}}async function Se(t,e,a,i={}){const{translator:n,onProgress:s,includePassingEntities:r=!0}=i,u=[],p=t.specifications.length;for(let m=0;m<p;m++){const h=t.specifications[m];s&&s({phase:"filtering",specificationIndex:m,totalSpecifications:p,entitiesProcessed:0,totalEntities:0,percentage:Math.floor(m/p*100)});const v=await de(h,e,a.modelId,i,d=>{s&&s({...d,specificationIndex:m,totalSpecifications:p,percentage:Math.floor((m+d.entitiesProcessed/Math.max(d.totalEntities,1))/p*100)})});u.push(v)}s&&s({phase:"complete",specificationIndex:p,totalSpecifications:p,entitiesProcessed:0,totalEntities:0,percentage:100});const c=ve(u);return{document:t,modelInfo:a,timestamp:new Date,summary:c,specificationResults:u}}async function de(t,e,a,i,n){const{translator:s,maxEntities:r,includePassingEntities:u=!0}=i,p=me(t,e),c=r?p.slice(0,r):p,m=[],h=c.length;for(let E=0;E<h;E++){const $=c[E];n&&E%100===0&&n({phase:"validating",entitiesProcessed:E,totalEntities:h});const P=ye(t,$,a,e,s);(u||!P.passed)&&m.push(P)}let v=0,d=0;for(const E of m)E.passed?v++:d++;u||(v=h-d);const I=he(t,p.length);let g="pass";p.length===0?I?.passed===!1?g="fail":I?.passed===!0?g="pass":g="not_applicable":(d>0||I?.passed===!1)&&(g="fail");const O=h>0?Math.floor(v/h*100):100;return{specification:t,status:g,applicableCount:p.length,passedCount:v,failedCount:d,passRate:O,entityResults:m,cardinalityResult:I}}function me(t,e){const a=t.applicability.facets;if(a.length===0)return e.getAllEntityIds();let i;for(const s of a){const r=ce(s,e);if(r!==void 0){i=r;break}}i===void 0&&(i=e.getAllEntityIds());const n=[];for(const s of i){let r=!0;for(const u of a)if(!w(u,s,e).passed){r=!1;break}r&&n.push(s)}return n}function ye(t,e,a,i,n){const s=[];let r=!0;for(const u of t.requirements){const p=fe(u,e,i,n);s.push(p),p.status==="fail"&&(r=!1)}return{expressId:e,modelId:a,entityType:i.getEntityType(e)||"Unknown",entityName:i.getEntityName(e),globalId:i.getGlobalId(e),passed:r,requirementResults:s}}function fe(t,e,a,i){const n=w(t.facet,e,a);let s,r;switch(t.optionality){case"required":s=n.passed?"pass":"fail",n.passed||(r=i?i.describeFailure({requirement:t,status:"fail",facetType:t.facet.type,checkedDescription:"",actualValue:n.actualValue,expectedValue:n.expectedValue,failure:n.failure}):be(n));break;case"optional":s="pass";break;case"prohibited":s=n.passed?"fail":"pass",s==="fail"&&(r=i?i.t("failures.prohibited",{field:n.actualValue||"value"}):`Prohibited: found ${n.actualValue}`);break;default:s=n.passed?"pass":"fail"}const u=i?i.describeRequirement(t):Ee(t);return{requirement:t,status:s,facetType:t.facet.type,checkedDescription:u,failureReason:r,actualValue:n.actualValue,expectedValue:n.expectedValue,failure:n.failure}}function he(t,e){if(t.minOccurs===void 0&&t.maxOccurs===void 0)return;const a=t.minOccurs??0,i=t.maxOccurs;let n=!0;const s=[];return e<a&&(n=!1,s.push(`Expected at least ${a}, found ${e}`)),i!=="unbounded"&&i!==void 0&&e>i&&(n=!1,s.push(`Expected at most ${i}, found ${e}`)),{passed:n,actualCount:e,minExpected:t.minOccurs,maxExpected:t.maxOccurs,message:s.length>0?s.join("; "):"Cardinality satisfied"}}function ve(t){let e=t.length,a=0,i=0,n=0,s=0,r=0;for(const p of t)p.status==="pass"?a++:p.status==="fail"&&i++,n+=p.applicableCount,s+=p.passedCount,r+=p.failedCount;const u=n>0?Math.floor(s/n*100):100;return{totalSpecifications:e,passedSpecifications:a,failedSpecifications:i,totalEntitiesChecked:n,totalEntitiesPassed:s,totalEntitiesFailed:r,overallPassRate:u}}function be(t){if(!t.failure)return`Expected ${t.expectedValue}, got ${t.actualValue}`;const{type:e,field:a,actual:i,expected:n}=t.failure;switch(e){case"ENTITY_TYPE_MISMATCH":return`Entity type "${i}" does not match expected ${n}`;case"PREDEFINED_TYPE_MISMATCH":return`Predefined type "${i}" does not match expected ${n}`;case"PREDEFINED_TYPE_MISSING":return`Predefined type is missing, expected ${n}`;case"ATTRIBUTE_MISSING":return`Attribute "${a}" is missing`;case"ATTRIBUTE_VALUE_MISMATCH":return`Attribute "${a}" value "${i}" does not match expected ${n}`;case"ATTRIBUTE_PATTERN_MISMATCH":return`Attribute "${a}" value "${i}" does not match pattern ${n}`;case"PSET_MISSING":return`Property set "${a||n}" not found`;case"PROPERTY_MISSING":return`Property "${a}" not found`;case"PROPERTY_VALUE_MISMATCH":return`Property "${a}" value "${i}" does not match expected ${n}`;case"PROPERTY_DATATYPE_MISMATCH":return`Property "${a}" type "${i}" does not match expected ${n}`;case"PROPERTY_OUT_OF_BOUNDS":return`Property "${a}" value ${i} is out of bounds ${n}`;case"CLASSIFICATION_MISSING":return"No classification found";case"CLASSIFICATION_SYSTEM_MISMATCH":return`Classification system "${i}" does not match expected ${n}`;case"CLASSIFICATION_VALUE_MISMATCH":return`Classification value "${i}" does not match expected ${n}`;case"MATERIAL_MISSING":return"No material assigned";case"MATERIAL_VALUE_MISMATCH":return`Material "${i}" does not match expected ${n}`;case"PARTOF_RELATION_MISSING":return`Not ${a} any entity`;case"PARTOF_ENTITY_MISMATCH":return`Parent entity "${i}" does not match expected ${n}`;default:return`Validation failed: ${e}`}}function Ee(t){const e=t.facet,a=t.optionality;let i;switch(e.type){case"entity":i=`Must be ${l(e.name)}`,e.predefinedType&&(i+=` with predefinedType ${l(e.predefinedType)}`);break;case"attribute":e.value?i=`Attribute "${l(e.name)}" must equal ${l(e.value)}`:i=`Attribute "${l(e.name)}" must exist`;break;case"property":e.value?i=`Property "${l(e.propertySet)}.${l(e.baseName)}" must equal ${l(e.value)}`:i=`Property "${l(e.propertySet)}.${l(e.baseName)}" must exist`;break;case"classification":e.system&&e.value?i=`Must have classification ${l(e.value)} in ${l(e.system)}`:e.system?i=`Must be classified in ${l(e.system)}`:e.value?i=`Must have classification ${l(e.value)}`:i="Must have a classification";break;case"material":e.value?i=`Must have material ${l(e.value)}`:i="Must have a material assigned";break;case"partOf":{const n=e.relation.replace("IfcRel","").toLowerCase();e.entity?i=`Must be ${n} ${l(e.entity.name)}`:i=`Must be ${n} some entity`;break}default:i="Unknown requirement"}return a==="prohibited"?i=i.replace("Must","Must NOT").replace("must","must NOT"):a==="optional"&&(i=i.replace("Must","Should").replace("must","should")),i}const xe={status:{pass:"PASS",fail:"FAIL",not_applicable:"NOT APPLICABLE"},optionality:{required:"Required",optional:"Optional",prohibited:"Prohibited"},cardinality:{satisfied:"Cardinality satisfied",atLeast:"Expected at least {min}, found {count}",atMost:"Expected at most {max}, found {count}",between:"Expected between {min} and {max}, found {count}",exactly:"Expected exactly {count}"},relations:{IfcRelAggregates:"part of",IfcRelContainedInSpatialStructure:"contained in",IfcRelNests:"nested in",IfcRelVoidsElement:"voiding",IfcRelFillsElement:"filling"},constraints:{simpleValue:'"{value}"',pattern:'matching pattern "{pattern}"',enumeration:{single:'"{value}"',multiple:"one of [{values}]"},bounds:{between:"between {min} and {max}",atLeast:"at least {min}",atMost:"at most {max}",greaterThan:"greater than {min}",lessThan:"less than {max}"}},applicability:{entity:{simple:"Elements of type {entityType}",withPredefined:"{entityType} elements with predefined type {predefinedType}",pattern:"Elements with type matching {pattern}"},attribute:{exists:'Elements where attribute "{name}" exists',equals:'Elements where "{name}" equals {value}',pattern:'Elements where "{name}" matches {pattern}'},property:{exists:'Elements with property "{property}" in "{pset}"',equals:'Elements where "{pset}.{property}" equals {value}',pattern:'Elements where "{pset}.{property}" matches {pattern}',bounded:'Elements where "{pset}.{property}" is {bounds}'},classification:{any:"Elements with any classification",system:'Elements classified in "{system}"',value:'Elements with classification "{value}"',systemAndValue:'Elements classified as "{value}" in "{system}"'},material:{any:"Elements with any material assigned",value:'Elements with material "{value}"',pattern:"Elements with material matching {pattern}"},partOf:{simple:"Elements that are {relation} another element",withEntity:"Elements that are {relation} a {entity}",withEntityAndType:"Elements that are {relation} a {entity} with type {predefinedType}"}},requirements:{entity:{mustBe:"Must be of type {entityType}",mustHavePredefined:"Must have predefined type {predefinedType}",mustBeWithPredefined:"Must be {entityType} with predefined type {predefinedType}"},attribute:{mustExist:'Attribute "{name}" must exist',mustEqual:'Attribute "{name}" must equal {value}',mustMatch:'Attribute "{name}" must match {pattern}',mustNotExist:'Attribute "{name}" must not exist',mustNotEqual:'Attribute "{name}" must not equal {value}'},property:{mustExist:'Property "{pset}.{property}" must exist',mustEqual:'Property "{pset}.{property}" must equal {value}',mustMatch:'Property "{pset}.{property}" must match {pattern}',mustBeBounded:'Property "{pset}.{property}" must be {bounds}',mustHaveType:'Property "{pset}.{property}" must be of type {dataType}',mustNotExist:'Property "{pset}.{property}" must not exist'},classification:{mustHave:"Must have a classification",mustBeInSystem:'Must be classified in "{system}"',mustHaveValue:'Must have classification "{value}"',mustBeInSystemWithValue:'Must be classified as "{value}" in "{system}"',mustNotHave:"Must not have any classification",mustNotBeInSystem:'Must not be classified in "{system}"'},material:{mustHave:"Must have a material assigned",mustBe:'Must have material "{value}"',mustMatch:"Must have material matching {pattern}",mustNotHave:"Must not have any material assigned"},partOf:{mustBe:"Must be {relation} a {entity}",mustBeSimple:"Must be {relation} another element",mustNotBe:"Must not be {relation} any element"}},failures:{entityTypeMismatch:'Entity type is "{actual}", expected {expected}',predefinedTypeMismatch:'Predefined type is "{actual}", expected {expected}',predefinedTypeMissing:"Predefined type is not set, expected {expected}",attributeMissing:'Attribute "{name}" does not exist',attributeEmpty:'Attribute "{name}" is empty',attributeValueMismatch:'Attribute "{name}" is "{actual}", expected {expected}',attributePatternMismatch:'Attribute "{name}" value "{actual}" does not match pattern {expected}',attributeProhibited:'Prohibited attribute "{name}" exists with value "{actual}"',psetMissing:'Property set "{pset}" not found',psetMissingAvailable:'Property set "{pset}" not found. Available: {available}',propertyMissing:'Property "{property}" not found in "{pset}"',propertyMissingAvailable:'Property "{property}" not found in "{pset}". Available: {available}',propertyEmpty:'Property "{pset}.{property}" has no value',propertyValueMismatch:'Property "{pset}.{property}" is "{actual}", expected {expected}',propertyPatternMismatch:'Property "{pset}.{property}" value "{actual}" does not match {expected}',propertyDatatypeMismatch:'Property "{pset}.{property}" data type is "{actual}", expected {expected}',propertyOutOfBounds:'Property "{pset}.{property}" value {actual} is out of range {expected}',propertyProhibited:'Prohibited property "{pset}.{property}" exists with value "{actual}"',classificationMissing:"No classification assigned",classificationSystemMismatch:'Classification system "{actual}" does not match expected "{expected}"',classificationSystemMissingAvailable:'Classification system "{expected}" not found. Available: {available}',classificationValueMismatch:'Classification code "{actual}" does not match expected {expected}',classificationValueMissingAvailable:"Classification code {expected} not found. Available: {available}",classificationProhibited:'Prohibited classification "{actual}" exists in system "{system}"',materialMissing:"No material assigned",materialValueMismatch:'Material "{actual}" does not match expected {expected}',materialValueMissingAvailable:"Material {expected} not found. Available: {available}",materialProhibited:'Prohibited material "{actual}" is assigned',partOfMissing:"Element is not {relation} any {entity}",partOfMissingSimple:"Element is not {relation} any element",partOfEntityMismatch:"Parent element is {actual}, expected {expected}",partOfPredefinedMismatch:'Parent predefined type is "{actual}", expected {expected}',partOfProhibited:"Element is {relation} {actual}, which is prohibited",prohibited:'Prohibited {field} found: "{actual}"',unknown:"Validation failed: {reason}"},summary:{title:"IDS Validation Report",specifications:"{passed}/{total} specifications passed",entities:"{passed}/{total} entities compliant ({percent}%)",overallPass:"Model meets all requirements",overallFail:"Model has {count} failing specifications",noApplicable:"No applicable entities found"},ui:{specification:"Specification",specifications:"Specifications",requirement:"Requirement",requirements:"Requirements",applicability:"Applies to",entity:"Entity",entities:"Entities",passed:"Passed",failed:"Failed",passRate:"Pass rate",actualValue:"Actual",expectedValue:"Expected",failureReason:"Reason",showAll:"Show all",showFailed:"Show failed only",isolateFailed:"Isolate failed",isolatePassed:"Isolate passed",exportJson:"Export JSON",exportBcf:"Export BCF",loadIds:"Load IDS file",runValidation:"Run validation",clearResults:"Clear results"}},Te={status:{pass:"BESTANDEN",fail:"FEHLGESCHLAGEN",not_applicable:"NICHT ANWENDBAR"},optionality:{required:"Erforderlich",optional:"Optional",prohibited:"Verboten"},cardinality:{satisfied:"Kardinalität erfüllt",atLeast:"Mindestens {min} erwartet, {count} gefunden",atMost:"Maximal {max} erwartet, {count} gefunden",between:"Zwischen {min} und {max} erwartet, {count} gefunden",exactly:"Genau {count} erwartet"},relations:{IfcRelAggregates:"Teil von",IfcRelContainedInSpatialStructure:"enthalten in",IfcRelNests:"verschachtelt in",IfcRelVoidsElement:"durchbrechend",IfcRelFillsElement:"ausfüllend"},constraints:{simpleValue:'"{value}"',pattern:'entsprechend Muster "{pattern}"',enumeration:{single:'"{value}"',multiple:"eines von [{values}]"},bounds:{between:"zwischen {min} und {max}",atLeast:"mindestens {min}",atMost:"höchstens {max}",greaterThan:"größer als {min}",lessThan:"kleiner als {max}"}},applicability:{entity:{simple:"Elemente vom Typ {entityType}",withPredefined:"{entityType}-Elemente mit vordefiniertem Typ {predefinedType}",pattern:"Elemente mit Typ entsprechend {pattern}"},attribute:{exists:'Elemente bei denen Attribut "{name}" existiert',equals:'Elemente bei denen "{name}" gleich {value} ist',pattern:'Elemente bei denen "{name}" dem Muster {pattern} entspricht'},property:{exists:'Elemente mit Eigenschaft "{property}" in "{pset}"',equals:'Elemente bei denen "{pset}.{property}" gleich {value} ist',pattern:'Elemente bei denen "{pset}.{property}" dem Muster {pattern} entspricht',bounded:'Elemente bei denen "{pset}.{property}" {bounds} ist'},classification:{any:"Elemente mit beliebiger Klassifizierung",system:'Elemente klassifiziert in "{system}"',value:'Elemente mit Klassifizierung "{value}"',systemAndValue:'Elemente klassifiziert als "{value}" in "{system}"'},material:{any:"Elemente mit zugewiesenem Material",value:'Elemente mit Material "{value}"',pattern:"Elemente mit Material entsprechend {pattern}"},partOf:{simple:"Elemente die {relation} einem anderen Element sind",withEntity:"Elemente die {relation} einem/einer {entity} sind",withEntityAndType:"Elemente die {relation} einem/einer {entity} mit Typ {predefinedType} sind"}},requirements:{entity:{mustBe:"Muss vom Typ {entityType} sein",mustHavePredefined:"Muss vordefinierten Typ {predefinedType} haben",mustBeWithPredefined:"Muss {entityType} mit vordefiniertem Typ {predefinedType} sein"},attribute:{mustExist:'Attribut "{name}" muss existieren',mustEqual:'Attribut "{name}" muss {value} entsprechen',mustMatch:'Attribut "{name}" muss dem Muster {pattern} entsprechen',mustNotExist:'Attribut "{name}" darf nicht existieren',mustNotEqual:'Attribut "{name}" darf nicht {value} sein'},property:{mustExist:'Eigenschaft "{pset}.{property}" muss existieren',mustEqual:'Eigenschaft "{pset}.{property}" muss {value} sein',mustMatch:'Eigenschaft "{pset}.{property}" muss dem Muster {pattern} entsprechen',mustBeBounded:'Eigenschaft "{pset}.{property}" muss {bounds} sein',mustHaveType:'Eigenschaft "{pset}.{property}" muss vom Datentyp {dataType} sein',mustNotExist:'Eigenschaft "{pset}.{property}" darf nicht existieren'},classification:{mustHave:"Muss eine Klassifizierung haben",mustBeInSystem:'Muss in "{system}" klassifiziert sein',mustHaveValue:'Muss Klassifizierung "{value}" haben',mustBeInSystemWithValue:'Muss als "{value}" in "{system}" klassifiziert sein',mustNotHave:"Darf keine Klassifizierung haben",mustNotBeInSystem:'Darf nicht in "{system}" klassifiziert sein'},material:{mustHave:"Muss ein Material zugewiesen haben",mustBe:'Muss Material "{value}" haben',mustMatch:"Muss Material entsprechend {pattern} haben",mustNotHave:"Darf kein Material zugewiesen haben"},partOf:{mustBe:"Muss {relation} einem/einer {entity} sein",mustBeSimple:"Muss {relation} einem anderen Element sein",mustNotBe:"Darf nicht {relation} einem Element sein"}},failures:{entityTypeMismatch:'Elementtyp ist "{actual}", erwartet {expected}',predefinedTypeMismatch:'Vordefinierter Typ ist "{actual}", erwartet {expected}',predefinedTypeMissing:"Vordefinierter Typ ist nicht gesetzt, erwartet {expected}",attributeMissing:'Attribut "{name}" existiert nicht',attributeEmpty:'Attribut "{name}" ist leer',attributeValueMismatch:'Attribut "{name}" ist "{actual}", erwartet {expected}',attributePatternMismatch:'Attribut "{name}" Wert "{actual}" entspricht nicht dem Muster {expected}',attributeProhibited:'Verbotenes Attribut "{name}" existiert mit Wert "{actual}"',psetMissing:'PropertySet "{pset}" nicht gefunden',psetMissingAvailable:'PropertySet "{pset}" nicht gefunden. Verfügbar: {available}',propertyMissing:'Eigenschaft "{property}" nicht in "{pset}" gefunden',propertyMissingAvailable:'Eigenschaft "{property}" nicht in "{pset}" gefunden. Verfügbar: {available}',propertyEmpty:'Eigenschaft "{pset}.{property}" hat keinen Wert',propertyValueMismatch:'Eigenschaft "{pset}.{property}" ist "{actual}", erwartet {expected}',propertyPatternMismatch:'Eigenschaft "{pset}.{property}" Wert "{actual}" entspricht nicht {expected}',propertyDatatypeMismatch:'Eigenschaft "{pset}.{property}" Datentyp ist "{actual}", erwartet {expected}',propertyOutOfBounds:'Eigenschaft "{pset}.{property}" Wert {actual} liegt außerhalb des Bereichs {expected}',propertyProhibited:'Verbotene Eigenschaft "{pset}.{property}" existiert mit Wert "{actual}"',classificationMissing:"Keine Klassifizierung zugewiesen",classificationSystemMismatch:'Klassifizierungssystem "{actual}" entspricht nicht dem erwarteten "{expected}"',classificationSystemMissingAvailable:'Klassifizierungssystem "{expected}" nicht gefunden. Verfügbar: {available}',classificationValueMismatch:'Klassifizierungscode "{actual}" entspricht nicht dem erwarteten {expected}',classificationValueMissingAvailable:"Klassifizierungscode {expected} nicht gefunden. Verfügbar: {available}",classificationProhibited:'Verbotene Klassifizierung "{actual}" existiert im System "{system}"',materialMissing:"Kein Material zugewiesen",materialValueMismatch:'Material "{actual}" entspricht nicht dem erwarteten {expected}',materialValueMissingAvailable:"Material {expected} nicht gefunden. Verfügbar: {available}",materialProhibited:'Verbotenes Material "{actual}" ist zugewiesen',partOfMissing:"Element ist nicht {relation} einem/einer {entity}",partOfMissingSimple:"Element ist nicht {relation} einem anderen Element",partOfEntityMismatch:"Übergeordnetes Element ist {actual}, erwartet {expected}",partOfPredefinedMismatch:'Vordefinierter Typ des übergeordneten Elements ist "{actual}", erwartet {expected}',partOfProhibited:"Element ist {relation} {actual}, was verboten ist",prohibited:'Verbotenes {field} gefunden: "{actual}"',unknown:"Validierung fehlgeschlagen: {reason}"},summary:{title:"IDS-Validierungsbericht",specifications:"{passed}/{total} Spezifikationen bestanden",entities:"{passed}/{total} Elemente konform ({percent}%)",overallPass:"Modell erfüllt alle Anforderungen",overallFail:"Modell hat {count} fehlgeschlagene Spezifikationen",noApplicable:"Keine anwendbaren Elemente gefunden"},ui:{specification:"Spezifikation",specifications:"Spezifikationen",requirement:"Anforderung",requirements:"Anforderungen",applicability:"Gilt für",entity:"Element",entities:"Elemente",passed:"Bestanden",failed:"Fehlgeschlagen",passRate:"Erfolgsquote",actualValue:"Tatsächlich",expectedValue:"Erwartet",failureReason:"Grund",showAll:"Alle anzeigen",showFailed:"Nur fehlgeschlagene",isolateFailed:"Fehlgeschlagene isolieren",isolatePassed:"Bestandene isolieren",exportJson:"JSON exportieren",exportBcf:"BCF exportieren",loadIds:"IDS-Datei laden",runValidation:"Validierung starten",clearResults:"Ergebnisse löschen"}},Me={status:{pass:"CONFORME",fail:"NON CONFORME",not_applicable:"NON APPLICABLE"},optionality:{required:"Obligatoire",optional:"Optionnel",prohibited:"Interdit"},cardinality:{satisfied:"Cardinalité respectée",atLeast:"Au moins {min} attendu(s), {count} trouvé(s)",atMost:"Au maximum {max} attendu(s), {count} trouvé(s)",between:"Entre {min} et {max} attendu(s), {count} trouvé(s)",exactly:"Exactement {count} attendu(s)"},relations:{IfcRelAggregates:"agrégé dans",IfcRelContainedInSpatialStructure:"contenu dans",IfcRelNests:"imbriqué dans",IfcRelVoidsElement:"perçant",IfcRelFillsElement:"remplissant"},constraints:{simpleValue:'"{value}"',pattern:'correspondant au motif "{pattern}"',enumeration:{single:'"{value}"',multiple:"l'un de [{values}]"},bounds:{between:"entre {min} et {max}",atLeast:"au moins {min}",atMost:"au plus {max}",greaterThan:"supérieur à {min}",lessThan:"inférieur à {max}"}},applicability:{entity:{simple:"Éléments de type {entityType}",withPredefined:"Éléments {entityType} avec type prédéfini {predefinedType}",pattern:"Éléments avec type correspondant à {pattern}"},attribute:{exists:`Éléments où l'attribut "{name}" existe`,equals:'Éléments où "{name}" est égal à {value}',pattern:'Éléments où "{name}" correspond au motif {pattern}'},property:{exists:'Éléments avec propriété "{property}" dans "{pset}"',equals:'Éléments où "{pset}.{property}" est égal à {value}',pattern:'Éléments où "{pset}.{property}" correspond au motif {pattern}',bounded:'Éléments où "{pset}.{property}" est {bounds}'},classification:{any:"Éléments avec une classification quelconque",system:'Éléments classifiés dans "{system}"',value:'Éléments avec classification "{value}"',systemAndValue:'Éléments classifiés comme "{value}" dans "{system}"'},material:{any:"Éléments avec un matériau attribué",value:'Éléments avec matériau "{value}"',pattern:"Éléments avec matériau correspondant à {pattern}"},partOf:{simple:"Éléments qui sont {relation} un autre élément",withEntity:"Éléments qui sont {relation} un(e) {entity}",withEntityAndType:"Éléments qui sont {relation} un(e) {entity} de type {predefinedType}"}},requirements:{entity:{mustBe:"Doit être de type {entityType}",mustHavePredefined:"Doit avoir le type prédéfini {predefinedType}",mustBeWithPredefined:"Doit être {entityType} avec type prédéfini {predefinedType}"},attribute:{mustExist:`L'attribut "{name}" doit exister`,mustEqual:`L'attribut "{name}" doit être égal à {value}`,mustMatch:`L'attribut "{name}" doit correspondre au motif {pattern}`,mustNotExist:`L'attribut "{name}" ne doit pas exister`,mustNotEqual:`L'attribut "{name}" ne doit pas être {value}`},property:{mustExist:'La propriété "{pset}.{property}" doit exister',mustEqual:'La propriété "{pset}.{property}" doit être égale à {value}',mustMatch:'La propriété "{pset}.{property}" doit correspondre au motif {pattern}',mustBeBounded:'La propriété "{pset}.{property}" doit être {bounds}',mustHaveType:'La propriété "{pset}.{property}" doit être de type {dataType}',mustNotExist:'La propriété "{pset}.{property}" ne doit pas exister'},classification:{mustHave:"Doit avoir une classification",mustBeInSystem:'Doit être classifié dans "{system}"',mustHaveValue:'Doit avoir la classification "{value}"',mustBeInSystemWithValue:'Doit être classifié comme "{value}" dans "{system}"',mustNotHave:"Ne doit pas avoir de classification",mustNotBeInSystem:'Ne doit pas être classifié dans "{system}"'},material:{mustHave:"Doit avoir un matériau attribué",mustBe:'Doit avoir le matériau "{value}"',mustMatch:"Doit avoir un matériau correspondant à {pattern}",mustNotHave:"Ne doit pas avoir de matériau attribué"},partOf:{mustBe:"Doit être {relation} un(e) {entity}",mustBeSimple:"Doit être {relation} un autre élément",mustNotBe:"Ne doit pas être {relation} un élément"}},failures:{entityTypeMismatch:`Le type d'élément est "{actual}", attendu {expected}`,predefinedTypeMismatch:'Le type prédéfini est "{actual}", attendu {expected}',predefinedTypeMissing:"Le type prédéfini n'est pas défini, attendu {expected}",attributeMissing:`L'attribut "{name}" n'existe pas`,attributeEmpty:`L'attribut "{name}" est vide`,attributeValueMismatch:`L'attribut "{name}" est "{actual}", attendu {expected}`,attributePatternMismatch:`La valeur de l'attribut "{name}" "{actual}" ne correspond pas au motif {expected}`,attributeProhibited:`L'attribut interdit "{name}" existe avec la valeur "{actual}"`,psetMissing:`L'ensemble de propriétés "{pset}" n'a pas été trouvé`,psetMissingAvailable:`L'ensemble de propriétés "{pset}" n'a pas été trouvé. Disponibles : {available}`,propertyMissing:`La propriété "{property}" n'a pas été trouvée dans "{pset}"`,propertyMissingAvailable:`La propriété "{property}" n'a pas été trouvée dans "{pset}". Disponibles : {available}`,propertyEmpty:`La propriété "{pset}.{property}" n'a pas de valeur`,propertyValueMismatch:'La propriété "{pset}.{property}" est "{actual}", attendu {expected}',propertyPatternMismatch:'La valeur de la propriété "{pset}.{property}" "{actual}" ne correspond pas à {expected}',propertyDatatypeMismatch:'Le type de données de la propriété "{pset}.{property}" est "{actual}", attendu {expected}',propertyOutOfBounds:'La valeur de la propriété "{pset}.{property}" {actual} est hors de la plage {expected}',propertyProhibited:'La propriété interdite "{pset}.{property}" existe avec la valeur "{actual}"',classificationMissing:"Aucune classification attribuée",classificationSystemMismatch:'Le système de classification "{actual}" ne correspond pas à "{expected}" attendu',classificationSystemMissingAvailable:`Le système de classification "{expected}" n'a pas été trouvé. Disponibles : {available}`,classificationValueMismatch:'Le code de classification "{actual}" ne correspond pas à {expected} attendu',classificationValueMissingAvailable:"Le code de classification {expected} n'a pas été trouvé. Disponibles : {available}",classificationProhibited:'La classification interdite "{actual}" existe dans le système "{system}"',materialMissing:"Aucun matériau attribué",materialValueMismatch:'Le matériau "{actual}" ne correspond pas à {expected} attendu',materialValueMissingAvailable:"Le matériau {expected} n'a pas été trouvé. Disponibles : {available}",materialProhibited:'Le matériau interdit "{actual}" est attribué',partOfMissing:"L'élément n'est pas {relation} un(e) {entity}",partOfMissingSimple:"L'élément n'est pas {relation} un autre élément",partOfEntityMismatch:"L'élément parent est {actual}, attendu {expected}",partOfPredefinedMismatch:`Le type prédéfini de l'élément parent est "{actual}", attendu {expected}`,partOfProhibited:"L'élément est {relation} {actual}, ce qui est interdit",prohibited:'{field} interdit trouvé : "{actual}"',unknown:"Validation échouée : {reason}"},summary:{title:"Rapport de validation IDS",specifications:"{passed}/{total} spécifications conformes",entities:"{passed}/{total} éléments conformes ({percent}%)",overallPass:"Le modèle respecte toutes les exigences",overallFail:"Le modèle a {count} spécifications non conformes",noApplicable:"Aucun élément applicable trouvé"},ui:{specification:"Spécification",specifications:"Spécifications",requirement:"Exigence",requirements:"Exigences",applicability:"S'applique à",entity:"Élément",entities:"Éléments",passed:"Conforme",failed:"Non conforme",passRate:"Taux de conformité",actualValue:"Réel",expectedValue:"Attendu",failureReason:"Raison",showAll:"Afficher tout",showFailed:"Afficher non conformes",isolateFailed:"Isoler non conformes",isolatePassed:"Isoler conformes",exportJson:"Exporter JSON",exportBcf:"Exporter BCF",loadIds:"Charger fichier IDS",runValidation:"Lancer la validation",clearResults:"Effacer les résultats"}},N={en:xe,de:Te,fr:Me};function Ae(t="en"){return new ge(t)}class ge{locale;translations;constructor(e){this.locale=e,this.translations=N[e]||N.en}t(e,a){const i=e.split(".");let n=this.translations;for(const s of i)if(n&&typeof n=="object"&&s in n)n=n[s];else return e;return typeof n!="string"?e:a?this.interpolate(n,a):n}interpolate(e,a){return e.replace(/\{(\w+)\}/g,(i,n)=>n in a?String(a[n]):i)}describeFacet(e,a){switch(this.translations,e.type){case"entity":return this.describeEntityFacet(e,a);case"attribute":return this.describeAttributeFacet(e,a);case"property":return this.describePropertyFacet(e,a);case"classification":return this.describeClassificationFacet(e,a);case"material":return this.describeMaterialFacet(e,a);case"partOf":return this.describePartOfFacet(e,a);default:return"Unknown facet"}}describeEntityFacet(e,a){const i=this.translations,n=this.describeConstraint(e.name);return a==="applicability"?e.predefinedType?this.interpolate(i.applicability.entity.withPredefined,{entityType:n,predefinedType:this.describeConstraint(e.predefinedType)}):this.interpolate(i.applicability.entity.simple,{entityType:n}):e.predefinedType?this.interpolate(i.requirements.entity.mustBeWithPredefined,{entityType:n,predefinedType:this.describeConstraint(e.predefinedType)}):this.interpolate(i.requirements.entity.mustBe,{entityType:n})}describeAttributeFacet(e,a){const i=this.translations,n=this.describeConstraint(e.name);return a==="applicability"?e.value?e.value.type==="pattern"?this.interpolate(i.applicability.attribute.pattern,{name:n,pattern:this.describeConstraint(e.value)}):this.interpolate(i.applicability.attribute.equals,{name:n,value:this.describeConstraint(e.value)}):this.interpolate(i.applicability.attribute.exists,{name:n}):e.value?e.value.type==="pattern"?this.interpolate(i.requirements.attribute.mustMatch,{name:n,pattern:this.describeConstraint(e.value)}):this.interpolate(i.requirements.attribute.mustEqual,{name:n,value:this.describeConstraint(e.value)}):this.interpolate(i.requirements.attribute.mustExist,{name:n})}describePropertyFacet(e,a){const i=this.translations,n=this.describeConstraint(e.propertySet),s=this.describeConstraint(e.baseName);return a==="applicability"?e.value?e.value.type==="pattern"?this.interpolate(i.applicability.property.pattern,{pset:n,property:s,pattern:this.describeConstraint(e.value)}):e.value.type==="bounds"?this.interpolate(i.applicability.property.bounded,{pset:n,property:s,bounds:this.describeConstraint(e.value)}):this.interpolate(i.applicability.property.equals,{pset:n,property:s,value:this.describeConstraint(e.value)}):this.interpolate(i.applicability.property.exists,{pset:n,property:s}):e.value?e.value.type==="pattern"?this.interpolate(i.requirements.property.mustMatch,{pset:n,property:s,pattern:this.describeConstraint(e.value)}):e.value.type==="bounds"?this.interpolate(i.requirements.property.mustBeBounded,{pset:n,property:s,bounds:this.describeConstraint(e.value)}):this.interpolate(i.requirements.property.mustEqual,{pset:n,property:s,value:this.describeConstraint(e.value)}):this.interpolate(i.requirements.property.mustExist,{pset:n,property:s})}describeClassificationFacet(e,a){const i=this.translations;return a==="applicability"?e.system&&e.value?this.interpolate(i.applicability.classification.systemAndValue,{system:this.describeConstraint(e.system),value:this.describeConstraint(e.value)}):e.system?this.interpolate(i.applicability.classification.system,{system:this.describeConstraint(e.system)}):e.value?this.interpolate(i.applicability.classification.value,{value:this.describeConstraint(e.value)}):i.applicability.classification.any:e.system&&e.value?this.interpolate(i.requirements.classification.mustBeInSystemWithValue,{system:this.describeConstraint(e.system),value:this.describeConstraint(e.value)}):e.system?this.interpolate(i.requirements.classification.mustBeInSystem,{system:this.describeConstraint(e.system)}):e.value?this.interpolate(i.requirements.classification.mustHaveValue,{value:this.describeConstraint(e.value)}):i.requirements.classification.mustHave}describeMaterialFacet(e,a){const i=this.translations;return a==="applicability"?e.value?e.value.type==="pattern"?this.interpolate(i.applicability.material.pattern,{pattern:this.describeConstraint(e.value)}):this.interpolate(i.applicability.material.value,{value:this.describeConstraint(e.value)}):i.applicability.material.any:e.value?e.value.type==="pattern"?this.interpolate(i.requirements.material.mustMatch,{pattern:this.describeConstraint(e.value)}):this.interpolate(i.requirements.material.mustBe,{value:this.describeConstraint(e.value)}):i.requirements.material.mustHave}describePartOfFacet(e,a){const i=this.translations,n=this.getRelationDescription(e.relation);return a==="applicability"?e.entity?e.entity.predefinedType?this.interpolate(i.applicability.partOf.withEntityAndType,{relation:n,entity:this.describeConstraint(e.entity.name),predefinedType:this.describeConstraint(e.entity.predefinedType)}):this.interpolate(i.applicability.partOf.withEntity,{relation:n,entity:this.describeConstraint(e.entity.name)}):this.interpolate(i.applicability.partOf.simple,{relation:n}):e.entity?this.interpolate(i.requirements.partOf.mustBe,{relation:n,entity:this.describeConstraint(e.entity.name)}):this.interpolate(i.requirements.partOf.mustBeSimple,{relation:n})}describeConstraint(e){const a=this.translations;switch(e.type){case"simpleValue":return this.interpolate(a.constraints.simpleValue,{value:e.value});case"pattern":return this.interpolate(a.constraints.pattern,{pattern:e.pattern});case"enumeration":return e.values.length===1?this.interpolate(a.constraints.enumeration.single,{value:e.values[0]}):this.interpolate(a.constraints.enumeration.multiple,{values:e.values.map(i=>`"${i}"`).join(", ")});case"bounds":return this.describeBounds(e);default:return"unknown constraint"}}describeBounds(e){const a=this.translations.constraints.bounds;return e.minInclusive!==void 0&&e.maxInclusive!==void 0?this.interpolate(a.between,{min:e.minInclusive,max:e.maxInclusive}):e.minInclusive!==void 0?this.interpolate(a.atLeast,{min:e.minInclusive}):e.maxInclusive!==void 0?this.interpolate(a.atMost,{max:e.maxInclusive}):e.minExclusive!==void 0?this.interpolate(a.greaterThan,{min:e.minExclusive}):e.maxExclusive!==void 0?this.interpolate(a.lessThan,{max:e.maxExclusive}):"any value"}describeFailure(e){const a=this.translations.failures;if(!e.failure)return e.actualValue&&e.expectedValue?`${e.actualValue} ≠ ${e.expectedValue}`:a.unknown.replace("{reason}","no details");const{type:i,field:n,actual:s,expected:r,context:u}=e.failure;switch(i){case"ENTITY_TYPE_MISMATCH":return this.interpolate(a.entityTypeMismatch,{actual:s||"?",expected:r||"?"});case"PREDEFINED_TYPE_MISMATCH":return this.interpolate(a.predefinedTypeMismatch,{actual:s||"?",expected:r||"?"});case"PREDEFINED_TYPE_MISSING":return this.interpolate(a.predefinedTypeMissing,{expected:r||"?"});case"ATTRIBUTE_MISSING":return this.interpolate(a.attributeMissing,{name:n||"?"});case"ATTRIBUTE_VALUE_MISMATCH":return this.interpolate(a.attributeValueMismatch,{name:n||"?",actual:s||"?",expected:r||"?"});case"ATTRIBUTE_PATTERN_MISMATCH":return this.interpolate(a.attributePatternMismatch,{name:n||"?",actual:s||"?",expected:r||"?"});case"PSET_MISSING":return u?.availablePsets?this.interpolate(a.psetMissingAvailable,{pset:n||r||"?",available:u.availablePsets}):this.interpolate(a.psetMissing,{pset:n||r||"?"});case"PROPERTY_MISSING":return u?.availableProperties?this.interpolate(a.propertyMissingAvailable,{property:n||"?",pset:u.propertySet||"?",available:u.availableProperties}):this.interpolate(a.propertyMissing,{property:n||"?",pset:u?.propertySet||"?"});case"PROPERTY_VALUE_MISMATCH":return this.interpolate(a.propertyValueMismatch,{pset:this.extractPsetFromField(n),property:this.extractPropertyFromField(n),actual:s||"?",expected:r||"?"});case"PROPERTY_DATATYPE_MISMATCH":return this.interpolate(a.propertyDatatypeMismatch,{pset:this.extractPsetFromField(n),property:this.extractPropertyFromField(n),actual:s||"?",expected:r||"?"});case"PROPERTY_OUT_OF_BOUNDS":return this.interpolate(a.propertyOutOfBounds,{pset:this.extractPsetFromField(n),property:this.extractPropertyFromField(n),actual:s||"?",expected:r||"?"});case"CLASSIFICATION_MISSING":return a.classificationMissing;case"CLASSIFICATION_SYSTEM_MISMATCH":return u?.availableSystems?this.interpolate(a.classificationSystemMissingAvailable,{expected:r||"?",available:u.availableSystems}):this.interpolate(a.classificationSystemMismatch,{actual:s||"?",expected:r||"?"});case"CLASSIFICATION_VALUE_MISMATCH":return u?.availableValues?this.interpolate(a.classificationValueMissingAvailable,{expected:r||"?",available:u.availableValues}):this.interpolate(a.classificationValueMismatch,{actual:s||"?",expected:r||"?"});case"MATERIAL_MISSING":return a.materialMissing;case"MATERIAL_VALUE_MISMATCH":return u?.availableMaterials?this.interpolate(a.materialValueMissingAvailable,{expected:r||"?",available:u.availableMaterials}):this.interpolate(a.materialValueMismatch,{actual:s||"?",expected:r||"?"});case"PARTOF_RELATION_MISSING":return u?.entity?this.interpolate(a.partOfMissing,{relation:this.getRelationDescription(n||"IfcRelContainedInSpatialStructure"),entity:u.entity}):this.interpolate(a.partOfMissingSimple,{relation:this.getRelationDescription(n||"IfcRelContainedInSpatialStructure")});case"PARTOF_ENTITY_MISMATCH":return this.interpolate(a.partOfEntityMismatch,{actual:s||"?",expected:r||"?"});case"PROHIBITED_ATTRIBUTE_EXISTS":case"PROHIBITED_PROPERTY_EXISTS":case"PROHIBITED_CLASSIFICATION_EXISTS":case"PROHIBITED_MATERIAL_EXISTS":return this.interpolate(a.prohibited,{field:n||"value",actual:s||"?"});default:return this.interpolate(a.unknown,{reason:i})}}extractPsetFromField(e){if(!e)return"?";const a=e.split(".");return a.length>1?a[0]:"?"}extractPropertyFromField(e){if(!e)return"?";const a=e.split(".");return a.length>1?a.slice(1).join("."):e}describeRequirement(e){let a=this.describeFacet(e.facet,"requirement");return e.optionality==="prohibited"?a=this.applyProhibited(a):e.optionality==="optional"&&(a=this.applyOptional(a)),a}applyProhibited(e){return e.replace(/^Must be/i,"Must NOT be").replace(/^Must have/i,"Must NOT have").replace(/^Muss/i,"Darf nicht").replace(/^Doit être/i,"Ne doit pas être").replace(/^Doit avoir/i,"Ne doit pas avoir")}applyOptional(e){return e.replace(/^Must/i,"Should").replace(/^Muss/i,"Sollte").replace(/^Doit/i,"Devrait")}getStatusText(e){return this.translations.status[e]}getOptionalityText(e){return this.translations.optionality[e]}getRelationDescription(e){return this.translations.relations[e]||e.replace("IfcRel","").toLowerCase()}}export{Ae as c,Ie as p,Se as v};
|
|
Binary file
|