@deck.gl/extensions 9.4.0-alpha.2 → 9.4.0-beta.3

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.
Files changed (43) hide show
  1. package/dist/clip/clip-extension.d.ts +3 -0
  2. package/dist/clip/clip-extension.d.ts.map +1 -1
  3. package/dist/clip/clip-extension.js +7 -0
  4. package/dist/clip/clip-extension.js.map +1 -1
  5. package/dist/dist.dev.js +2195 -142
  6. package/dist/fill-style/fill-style-extension.d.ts +38 -6
  7. package/dist/fill-style/fill-style-extension.d.ts.map +1 -1
  8. package/dist/fill-style/fill-style-extension.js +88 -10
  9. package/dist/fill-style/fill-style-extension.js.map +1 -1
  10. package/dist/fill-style/procedural-pattern.d.ts +65 -0
  11. package/dist/fill-style/procedural-pattern.d.ts.map +1 -0
  12. package/dist/fill-style/procedural-pattern.js +135 -0
  13. package/dist/fill-style/procedural-pattern.js.map +1 -0
  14. package/dist/fill-style/shader-module.d.ts +13 -4
  15. package/dist/fill-style/shader-module.d.ts.map +1 -1
  16. package/dist/fill-style/shader-module.js +212 -21
  17. package/dist/fill-style/shader-module.js.map +1 -1
  18. package/dist/index.cjs +3484 -215
  19. package/dist/index.cjs.map +3 -4
  20. package/dist/index.d.ts +2 -1
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/mask/shader-module.d.ts +1 -0
  23. package/dist/mask/shader-module.d.ts.map +1 -1
  24. package/dist/path-style/path-style-extension.d.ts +49 -6
  25. package/dist/path-style/path-style-extension.d.ts.map +1 -1
  26. package/dist/path-style/path-style-extension.js +237 -37
  27. package/dist/path-style/path-style-extension.js.map +1 -1
  28. package/dist/path-style/shaders.glsl.d.ts +30 -1
  29. package/dist/path-style/shaders.glsl.d.ts.map +1 -1
  30. package/dist/path-style/shaders.glsl.js +136 -21
  31. package/dist/path-style/shaders.glsl.js.map +1 -1
  32. package/dist/terrain/shader-module.d.ts +17 -2
  33. package/dist/terrain/shader-module.d.ts.map +1 -1
  34. package/dist/utils/debug.d.ts.map +1 -1
  35. package/dist.min.js +1251 -96
  36. package/package.json +6 -6
  37. package/src/clip/clip-extension.ts +15 -1
  38. package/src/fill-style/fill-style-extension.ts +135 -13
  39. package/src/fill-style/procedural-pattern.ts +203 -0
  40. package/src/fill-style/shader-module.ts +233 -23
  41. package/src/index.ts +10 -1
  42. package/src/path-style/path-style-extension.ts +350 -44
  43. package/src/path-style/shaders.glsl.ts +268 -27
package/dist.min.js CHANGED
@@ -4,13 +4,13 @@
4
4
  else if (typeof define === 'function' && define.amd) define([], factory);
5
5
  else if (typeof exports === 'object') exports['deck'] = factory();
6
6
  else root['deck'] = factory();})(globalThis, function () {
7
- "use strict";var __exports__=(()=>{var Yt=Object.create;var Q=Object.defineProperty;var Kt=Object.getOwnPropertyDescriptor;var $t=Object.getOwnPropertyNames;var Zt=Object.getPrototypeOf,Jt=Object.prototype.hasOwnProperty;var Ae=(i,e)=>()=>(e||i((e={exports:{}}).exports,e),e.exports),Se=(i,e)=>{for(var t in e)Q(i,t,{get:e[t],enumerable:!0})},X=(i,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of $t(e))!Jt.call(i,o)&&o!==t&&Q(i,o,{get:()=>e[o],enumerable:!(r=Kt(e,o))||r.enumerable});return i},y=(i,e,t)=>(X(i,e,"default"),t&&X(t,e,"default")),d=(i,e,t)=>(t=i!=null?Yt(Zt(i)):{},X(e||!i||!i.__esModule?Q(t,"default",{value:i,enumerable:!0}):t,i)),Xt=i=>X(Q({},"__esModule",{value:!0}),i);var _=Ae((qr,Ie)=>{Ie.exports=globalThis.deck});var Ye=Ae((Jr,We)=>{We.exports=globalThis.luma});var J={};Se(J,{BrushingExtension:()=>Be,ClipExtension:()=>Ft,CollisionFilterExtension:()=>It,DataFilterExtension:()=>Qe,FillStyleExtension:()=>Pt,Fp64Extension:()=>dt,MaskExtension:()=>Nt,PathStyleExtension:()=>gt,_TerrainExtension:()=>Wt,project64:()=>oe});var x={},Ce=d(_(),1);y(x,d(_(),1));if(!Ce.Layer)throw new Error("@deck.gl/core is not found");y(J,x);var Ne=d(_(),1);var Re=d(_(),1),ke=`layout(std140) uniform brushingUniforms {
7
+ "use strict";var __exports__=(()=>{var Ai=Object.create;var de=Object.defineProperty;var Ti=Object.getOwnPropertyDescriptor;var Si=Object.getOwnPropertyNames;var Li=Object.getPrototypeOf,Fi=Object.prototype.hasOwnProperty;var Ge=(t,e)=>()=>{try{return e||t((e={exports:{}}).exports,e),e.exports}catch(i){throw e=0,i}},Le=(t,e)=>{for(var i in e)de(t,i,{get:e[i],enumerable:!0})},ue=(t,e,i,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Si(e))!Fi.call(t,n)&&n!==i&&de(t,n,{get:()=>e[n],enumerable:!(r=Ti(e,n))||r.enumerable});return t},B=(t,e,i)=>(ue(t,e,"default"),i&&ue(i,e,"default")),_=(t,e,i)=>(i=t!=null?Ai(Li(t)):{},ue(e||!t||!t.__esModule?de(i,"default",{value:t,enumerable:!0}):i,t)),Oi=t=>ue(de({},"__esModule",{value:!0}),t);var h=Ge((po,qe)=>{qe.exports=globalThis.deck});var st=Ge((xo,at)=>{at.exports=globalThis.luma});var ce={};Le(ce,{BrushingExtension:()=>Xe,ClipExtension:()=>ei,CollisionFilterExtension:()=>ai,DataFilterExtension:()=>pt,FillStyleExtension:()=>Xt,Fp64Extension:()=>Nt,MaskExtension:()=>ui,PathStyleExtension:()=>Ht,_TerrainExtension:()=>yi,project64:()=>ge});var E={},We=_(h(),1);B(E,_(h(),1));if(!We.Layer)throw new Error("@deck.gl/core is not found");B(ce,E);var $e=_(h(),1);var Ye=_(h(),1),Ke=`layout(std140) uniform brushingUniforms {
8
8
  bool enabled;
9
9
  highp int target;
10
10
  vec2 mousePos;
11
11
  float radius;
12
12
  } brushing;
13
- `,Qt=`
13
+ `,Bi=`
14
14
  in vec2 brushingTargets;
15
15
 
16
16
  out float brushing_isVisible;
@@ -33,15 +33,15 @@
33
33
  void brushing_setVisible(bool visible) {
34
34
  brushing_isVisible = float(visible);
35
35
  }
36
- `,ei=`
37
- ${ke}
38
- ${Qt}
39
- `,ti=`
36
+ `,wi=`
37
+ ${Ke}
38
+ ${Bi}
39
+ `,Ii=`
40
40
  in float brushing_isVisible;
41
- `,ii=`
42
- ${ke}
43
- ${ti}
44
- `,ri={source:0,target:1,custom:2,source_target:3},oi={"vs:DECKGL_FILTER_GL_POSITION":`
41
+ `,Ci=`
42
+ ${Ke}
43
+ ${Ii}
44
+ `,Ri={source:0,target:1,custom:2,source_target:3},ki={"vs:DECKGL_FILTER_GL_POSITION":`
45
45
  vec2 brushingTarget;
46
46
  vec2 brushingSource;
47
47
  if (brushing.target == 3) {
@@ -65,7 +65,7 @@ ${ti}
65
65
  if (brushing.enabled && brushing_isVisible < 0.5) {
66
66
  discard;
67
67
  }
68
- `},we={name:"brushing",dependencies:[Re.project],vs:ei,fs:ii,inject:oi,getUniforms:i=>{if(!i||!("viewport"in i))return{};let{brushingEnabled:e=!0,brushingRadius:t=1e4,brushingTarget:r="source",mousePosition:o,viewport:s}=i;return{enabled:Boolean(e&&o&&s.containsPixel(o)),radius:t,target:ri[r]||0,mousePos:o?s.unproject([o.x-s.x,o.y-s.y]):[0,0]}},uniformTypes:{enabled:"i32",target:"i32",mousePos:"vec2<f32>",radius:"f32"}};var si={getBrushingTarget:{type:"accessor",value:[0,0]},brushingTarget:"source",brushingEnabled:!0,brushingRadius:1e4},S=class extends Ne.LayerExtension{getShaders(){return{modules:[we]}}initializeState(e,t){let r=this.getAttributeManager();r&&r.add({brushingTargets:{size:2,stepMode:"dynamic",accessor:"getBrushingTarget"}});let o=()=>{this.getCurrentLayer()?.setNeedsRedraw()};this.state.onMouseMove=o,e.deck&&e.deck.eventManager.on({pointermove:o,pointerleave:o})}finalizeState(e,t){if(e.deck){let r=this.state.onMouseMove;e.deck.eventManager.off({pointermove:r,pointerleave:r})}}draw(e,t){let{viewport:r,mousePosition:o}=e.context,{brushingEnabled:s,brushingRadius:n,brushingTarget:a}=this.props,l={viewport:r,mousePosition:o,brushingEnabled:s,brushingRadius:n,brushingTarget:a};this.setShaderModuleProps({brushing:l})}};S.defaultProps=si;S.extensionName="BrushingExtension";var Be=S;var E=d(_(),1);var De=`layout(std140) uniform dataFilterUniforms {
68
+ `},Ze={name:"brushing",dependencies:[Ye.project],vs:wi,fs:Ci,inject:ki,getUniforms:t=>{if(!t||!("viewport"in t))return{};let{brushingEnabled:e=!0,brushingRadius:i=1e4,brushingTarget:r="source",mousePosition:n,viewport:o}=t;return{enabled:!!(e&&n&&o.containsPixel(n)),radius:i,target:Ri[r]||0,mousePos:n?o.unproject([n.x-o.x,n.y-o.y]):[0,0]}},uniformTypes:{enabled:"i32",target:"i32",mousePos:"vec2<f32>",radius:"f32"}};var Ni={getBrushingTarget:{type:"accessor",value:[0,0]},brushingTarget:"source",brushingEnabled:!0,brushingRadius:1e4},q=class extends $e.LayerExtension{getShaders(){return{modules:[Ze]}}initializeState(e,i){let r=this.getAttributeManager();r&&r.add({brushingTargets:{size:2,stepMode:"dynamic",accessor:"getBrushingTarget"}});let n=()=>{this.getCurrentLayer()?.setNeedsRedraw()};this.state.onMouseMove=n,e.deck&&e.deck.eventManager.on({pointermove:n,pointerleave:n})}finalizeState(e,i){if(e.deck){let r=this.state.onMouseMove;e.deck.eventManager.off({pointermove:r,pointerleave:r})}}draw(e,i){let{viewport:r,mousePosition:n}=e.context,{brushingEnabled:o,brushingRadius:a,brushingTarget:s}=this.props,l={viewport:r,mousePosition:n,brushingEnabled:o,brushingRadius:a,brushingTarget:s};this.setShaderModuleProps({brushing:l})}};q.defaultProps=Ni;q.extensionName="BrushingExtension";var Xe=q;var D=_(h(),1);var Qe=`layout(std140) uniform dataFilterUniforms {
69
69
  bool useSoftMargin;
70
70
  bool enabled;
71
71
  bool transformSize;
@@ -78,7 +78,7 @@ ${ti}
78
78
  vec4 max64High;
79
79
  highp uvec4 categoryBitMask;
80
80
  } dataFilter;
81
- `,ni=`
81
+ `,Di=`
82
82
  #ifdef DATAFILTER_TYPE
83
83
  in DATAFILTER_TYPE filterValues;
84
84
  #ifdef DATAFILTER_DOUBLE
@@ -239,15 +239,15 @@ float dataFilter_reduceValue(vec4 value) {
239
239
  #endif
240
240
  }
241
241
  #endif
242
- `,ze=`
243
- ${De}
244
- ${ni}
245
- `,ai=`
242
+ `,Je=`
243
+ ${Qe}
244
+ ${Di}
245
+ `,zi=`
246
246
  in float dataFilter_value;
247
- `,Ve=`
248
- ${De}
249
- ${ai}
250
- `;function je(i){if(!i||!("extensions"in i))return{};let{filterRange:e=[-1,1],filterEnabled:t=!0,filterTransformSize:r=!0,filterTransformColor:o=!0,categoryBitMask:s}=i,n=i.filterSoftRange||e,a=l=>Array.isArray(l)?[l[0]||0,l[1]||0,l[2]||0,l[3]||0]:[l,0,0,0];return{...Number.isFinite(e[0])?{min:a(e[0]),softMin:a(n[0]),softMax:a(n[1]),max:a(e[1])}:{min:a(e.map(l=>l[0])),softMin:a(n.map(l=>l[0])),softMax:a(n.map(l=>l[1])),max:a(e.map(l=>l[1]))},enabled:t,useSoftMargin:Boolean(i.filterSoftRange),transformSize:t&&r,transformColor:t&&o,...s&&{categoryBitMask:s}}}function li(i){if(!i||!("extensions"in i))return{};let e=je(i),t=e.min.map(Math.fround);e.min=e.min.map((o,s)=>o-t[s]),e.softMin=e.softMin.map((o,s)=>o-t[s]),e.min64High=t;let r=e.max.map(Math.fround);return e.max=e.max.map((o,s)=>o-r[s]),e.softMax=e.softMax.map((o,s)=>o-r[s]),e.max64High=r,e}var Ue={"vs:#main-start":`
247
+ `,et=`
248
+ ${Qe}
249
+ ${zi}
250
+ `;function tt(t){if(!t||!("extensions"in t))return{};let{filterRange:e=[-1,1],filterEnabled:i=!0,filterTransformSize:r=!0,filterTransformColor:n=!0,categoryBitMask:o}=t,a=t.filterSoftRange||e,s=l=>Array.isArray(l)?[l[0]||0,l[1]||0,l[2]||0,l[3]||0]:[l,0,0,0];return{...Number.isFinite(e[0])?{min:s(e[0]),softMin:s(a[0]),softMax:s(a[1]),max:s(e[1])}:{min:s(e.map(l=>l[0])),softMin:s(a.map(l=>l[0])),softMax:s(a.map(l=>l[1])),max:s(e.map(l=>l[1]))},enabled:i,useSoftMargin:!!t.filterSoftRange,transformSize:i&&r,transformColor:i&&n,...o&&{categoryBitMask:o}}}function Ui(t){if(!t||!("extensions"in t))return{};let e=tt(t),i=e.min.map(Math.fround);e.min=e.min.map((n,o)=>n-i[o]),e.softMin=e.softMin.map((n,o)=>n-i[o]),e.min64High=i;let r=e.max.map(Math.fround);return e.max=e.max.map((n,o)=>n-r[o]),e.softMax=e.softMax.map((n,o)=>n-r[o]),e.max64High=r,e}var it={"vs:#main-start":`
251
251
  dataFilter_value = 1.0;
252
252
  if (dataFilter.enabled) {
253
253
  #ifdef DATAFILTER_TYPE
@@ -278,7 +278,7 @@ ${ai}
278
278
  if (dataFilter.transformColor) {
279
279
  color.a *= dataFilter_value;
280
280
  }
281
- `};function Ge(i){return{useSoftMargin:"i32",enabled:"i32",transformSize:"i32",transformColor:"i32",min:"vec4<f32>",softMin:"vec4<f32>",softMax:"vec4<f32>",max:"vec4<f32>",min64High:"vec4<f32>",max64High:"vec4<f32>",categoryBitMask:"vec4<u32>"}}var He={name:"dataFilter",vs:ze,fs:Ve,inject:Ue,getUniforms:je,uniformTypesFromOptions:Ge},qe={name:"dataFilter",vs:ze,fs:Ve,inject:Ue,getUniforms:li,uniformTypesFromOptions:Ge};var Ke=d(Ye(),1),fi=`#version 300 es
281
+ `};function rt(t){return{useSoftMargin:"i32",enabled:"i32",transformSize:"i32",transformColor:"i32",min:"vec4<f32>",softMin:"vec4<f32>",softMax:"vec4<f32>",max:"vec4<f32>",min64High:"vec4<f32>",max64High:"vec4<f32>",categoryBitMask:"vec4<u32>"}}var nt={name:"dataFilter",vs:Je,fs:et,inject:it,getUniforms:tt,uniformTypesFromOptions:rt},ot={name:"dataFilter",vs:Je,fs:et,inject:it,getUniforms:Ui,uniformTypesFromOptions:rt};var lt=_(st(),1),Vi=`#version 300 es
282
282
  #define SHADER_NAME data-filter-vertex-shader
283
283
 
284
284
  #ifdef FLOAT_TARGET
@@ -309,7 +309,7 @@ void main() {
309
309
  #endif
310
310
  gl_PointSize = 1.0;
311
311
  }
312
- `,ci=`#version 300 es
312
+ `,ji=`#version 300 es
313
313
  #define SHADER_NAME data-filter-fragment-shader
314
314
  precision highp float;
315
315
 
@@ -323,7 +323,7 @@ void main() {
323
323
  }
324
324
  fragColor = vColor;
325
325
  }
326
- `,ui=["float32-renderable-webgl","texture-blend-float-webgl"];function $e(i){return ui.every(e=>i.features.has(e))}function Ze(i,e){return e?i.createFramebuffer({width:1,height:1,colorAttachments:[i.createTexture({format:"rgba32float",dimension:"2d",width:1,height:1})]}):i.createFramebuffer({width:256,height:64,colorAttachments:[i.createTexture({format:"rgba8unorm",dimension:"2d",width:256,height:64})]})}function Je(i,e,t,r){return t.defines.NON_INSTANCED_MODEL=1,r&&(t.defines.FLOAT_TARGET=1),new Ke.Model(i,{id:"data-filter-aggregation-model",vertexCount:1,isInstanced:!1,topology:"point-list",disableWarnings:!0,vs:fi,fs:ci,bufferLayout:e,...t})}var Xe={blend:!0,blendColorSrcFactor:"one",blendColorDstFactor:"one",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one",blendColorOperation:"add",blendAlphaOperation:"add",depthCompare:"never"};var di={getFilterValue:{type:"accessor",value:0},getFilterCategory:{type:"accessor",value:0},onFilteredItemsChange:{type:"function",value:null,optional:!0},filterEnabled:!0,filterRange:[-1,1],filterSoftRange:null,filterCategories:[0],filterTransformSize:!0,filterTransformColor:!0},_i={categorySize:0,filterSize:1,fp64:!1,countItems:!1},mi={1:"uint",2:"uvec2",3:"uvec3",4:"uvec4"},hi={1:"float",2:"vec2",3:"vec3",4:"vec4"},I=class extends E.LayerExtension{constructor(e={}){super({..._i,...e})}getShaders(e){let{categorySize:t,filterSize:r,fp64:o}=e.opts,s={};t&&(s.DATACATEGORY_TYPE=mi[t],s.DATACATEGORY_CHANNELS=t),r&&(s.DATAFILTER_TYPE=hi[r],s.DATAFILTER_DOUBLE=Boolean(o));let n=o?qe:He;return n.uniformTypes=n.uniformTypesFromOptions(e.opts),{modules:[n],defines:s}}initializeState(e,t){let r=this.getAttributeManager(),{categorySize:o,filterSize:s,fp64:n}=t.opts;r&&(s&&r.add({filterValues:{size:s,type:n?"float64":"float32",stepMode:"dynamic",accessor:"getFilterValue"}}),o&&r.add({filterCategoryValues:{size:o,stepMode:"dynamic",accessor:"getFilterCategory",type:"uint32",transform:o===1?l=>t._getCategoryKey.call(this,l,0):l=>l.map((f,u)=>t._getCategoryKey.call(this,f,u))}}));let{device:a}=this.context;if(r&&t.opts.countItems){let l=$e(a);r.add({filterVertexIndices:{size:l?1:2,vertexOffset:1,type:"unorm8",accessor:(c,{index:p})=>{let m=c&&c.__source?c.__source.index:p;return l?(m+1)%255:[(m+1)%255,Math.floor(m/255)%255]},shaderAttributes:{filterPrevIndices:{vertexOffset:0},filterIndices:{vertexOffset:1}}}});let f=Ze(a,l),u=Je(a,r.getBufferLayouts({isInstanced:!1}),t.getShaders.call(this,t),l);this.setState({filterFBO:f,filterModel:u})}}updateState({props:e,oldProps:t,changeFlags:r},o){let s=this.getAttributeManager(),{categorySize:n}=o.opts;if(this.state.filterModel){let a=s.attributes.filterValues?.needsUpdate()||s.attributes.filterCategoryValues?.needsUpdate()||e.filterEnabled!==t.filterEnabled||e.filterRange!==t.filterRange||e.filterSoftRange!==t.filterSoftRange||e.filterCategories!==t.filterCategories;a&&this.setState({filterNeedsUpdate:a})}s?.attributes.filterCategoryValues&&((s.attributes.filterCategoryValues.needsUpdate()||!(0,E._deepEqual)(e.filterCategories,t.filterCategories,2))&&this.setState({categoryBitMask:null}),r.dataChanged&&(this.setState({categoryMap:Array(n).fill(0).map(()=>({}))}),s.attributes.filterCategoryValues.setNeedsUpdate("categoryMap")))}draw(e,t){let r=this.state.filterFBO,o=this.state.filterModel,s=this.state.filterNeedsUpdate;this.state.categoryBitMask||t._updateCategoryBitMask.call(this,e,t);let{onFilteredItemsChange:n,extensions:a,filterEnabled:l,filterRange:f,filterSoftRange:u,filterTransformSize:c,filterTransformColor:p,filterCategories:m}=this.props,h={extensions:a,filterEnabled:l,filterRange:f,filterSoftRange:u,filterTransformSize:c,filterTransformColor:p,filterCategories:m};if(this.state.categoryBitMask&&(h.categoryBitMask=this.state.categoryBitMask),this.setShaderModuleProps({dataFilter:h}),s&&n&&o){let P=this.getAttributeManager(),{attributes:{filterValues:v,filterCategoryValues:A,filterVertexIndices:ue}}=P;o.setVertexCount(this.getNumInstances());let pe={...v?.getValue(),...A?.getValue(),...ue?.getValue()};o.setAttributes(pe),o.shaderInputs.setProps({dataFilter:h});let de=[0,0,r.width,r.height],Te=o.device.beginRenderPass({id:"data-filter-aggregation",framebuffer:r,parameters:{viewport:de},clearColor:[0,0,0,0]});o.setParameters(Xe),o.draw(Te),Te.end();let Oe=o.device.readPixelsToArrayWebGL(r),Le=0;for(let _e=0;_e<Oe.length;_e++)Le+=Oe[_e];n({id:this.id,count:Le}),this.state.filterNeedsUpdate=!1}}finalizeState(){let e=this.state.filterFBO,t=this.state.filterModel;e?.destroy(),t?.destroy()}_updateCategoryBitMask(e,t){let{categorySize:r}=t.opts;if(!r)return;let{filterCategories:o}=this.props,s=new Uint32Array([0,0,0,0]),n=r===1?[o]:o,a=r===1?128:r===2?64:32;for(let l=0;l<n.length;l++){let f=n[l];for(let u of f){let c=t._getCategoryKey.call(this,u,l);if(c<a){let p=l*(a/32)+Math.floor(c/32);s[p]+=Math.pow(2,c%32)}else E.log.warn(`Exceeded maximum number of categories (${a})`)()}}this.state.categoryBitMask=s}_getCategoryKey(e,t){let r=this.state.categoryMap[t];return e in r||(r[e]=Object.keys(r).length),r[e]}};I.defaultProps=di;I.extensionName="DataFilterExtension";var Qe=I;var pt=d(_(),1);var eo=1/Math.PI*180,to=1/180*Math.PI,vi={EPSILON:1e-12,debug:!1,precision:4,printTypes:!1,printDegrees:!1,printRowMajor:!0,_cartographicRadians:!1};globalThis.mathgl=globalThis.mathgl||{config:{...vi}};var C=globalThis.mathgl.config;function me(i){return Array.isArray(i)||ArrayBuffer.isView(i)&&!(i instanceof DataView)}function M(i,e,t){let r=C.EPSILON;t&&(C.EPSILON=t);try{if(i===e)return!0;if(me(i)&&me(e)){if(i.length!==e.length)return!1;for(let o=0;o<i.length;++o)if(!M(i[o],e[o]))return!1;return!0}return i&&i.equals?i.equals(e):e&&e.equals?e.equals(i):typeof i=="number"&&typeof e=="number"?Math.abs(i-e)<=C.EPSILON*Math.max(1,Math.abs(i),Math.abs(e)):!1}finally{C.EPSILON=r}}var R=typeof Float32Array<"u"?Float32Array:Array,he=Math.random;function ee(i){return i>=0?Math.round(i):i%.5===0?Math.floor(i):Math.round(i)}var ro=Math.PI/180;var k={};Se(k,{add:()=>Ei,angle:()=>Wi,bezier:()=>Di,ceil:()=>Mi,clone:()=>xi,copy:()=>bi,create:()=>et,cross:()=>ki,dist:()=>er,distance:()=>st,div:()=>Qi,divide:()=>ot,dot:()=>ge,equals:()=>Zi,exactEquals:()=>$i,floor:()=>Fi,forEach:()=>or,fromValues:()=>yi,hermite:()=>Bi,inverse:()=>Ci,len:()=>ir,length:()=>tt,lerp:()=>wi,max:()=>Oi,min:()=>Ti,mul:()=>Xi,multiply:()=>rt,negate:()=>Ii,normalize:()=>Ri,random:()=>zi,rotateX:()=>Gi,rotateY:()=>Hi,rotateZ:()=>qi,round:()=>Li,scale:()=>Ai,scaleAndAdd:()=>Si,set:()=>Pi,slerp:()=>Ni,sqrDist:()=>tr,sqrLen:()=>rr,squaredDistance:()=>nt,squaredLength:()=>at,str:()=>Ki,sub:()=>Ji,subtract:()=>it,transformMat3:()=>ji,transformMat4:()=>Vi,transformQuat:()=>Ui,zero:()=>Yi});function et(){let i=new R(3);return R!=Float32Array&&(i[0]=0,i[1]=0,i[2]=0),i}function xi(i){let e=new R(3);return e[0]=i[0],e[1]=i[1],e[2]=i[2],e}function tt(i){let e=i[0],t=i[1],r=i[2];return Math.sqrt(e*e+t*t+r*r)}function yi(i,e,t){let r=new R(3);return r[0]=i,r[1]=e,r[2]=t,r}function bi(i,e){return i[0]=e[0],i[1]=e[1],i[2]=e[2],i}function Pi(i,e,t,r){return i[0]=e,i[1]=t,i[2]=r,i}function Ei(i,e,t){return i[0]=e[0]+t[0],i[1]=e[1]+t[1],i[2]=e[2]+t[2],i}function it(i,e,t){return i[0]=e[0]-t[0],i[1]=e[1]-t[1],i[2]=e[2]-t[2],i}function rt(i,e,t){return i[0]=e[0]*t[0],i[1]=e[1]*t[1],i[2]=e[2]*t[2],i}function ot(i,e,t){return i[0]=e[0]/t[0],i[1]=e[1]/t[1],i[2]=e[2]/t[2],i}function Mi(i,e){return i[0]=Math.ceil(e[0]),i[1]=Math.ceil(e[1]),i[2]=Math.ceil(e[2]),i}function Fi(i,e){return i[0]=Math.floor(e[0]),i[1]=Math.floor(e[1]),i[2]=Math.floor(e[2]),i}function Ti(i,e,t){return i[0]=Math.min(e[0],t[0]),i[1]=Math.min(e[1],t[1]),i[2]=Math.min(e[2],t[2]),i}function Oi(i,e,t){return i[0]=Math.max(e[0],t[0]),i[1]=Math.max(e[1],t[1]),i[2]=Math.max(e[2],t[2]),i}function Li(i,e){return i[0]=ee(e[0]),i[1]=ee(e[1]),i[2]=ee(e[2]),i}function Ai(i,e,t){return i[0]=e[0]*t,i[1]=e[1]*t,i[2]=e[2]*t,i}function Si(i,e,t,r){return i[0]=e[0]+t[0]*r,i[1]=e[1]+t[1]*r,i[2]=e[2]+t[2]*r,i}function st(i,e){let t=e[0]-i[0],r=e[1]-i[1],o=e[2]-i[2];return Math.sqrt(t*t+r*r+o*o)}function nt(i,e){let t=e[0]-i[0],r=e[1]-i[1],o=e[2]-i[2];return t*t+r*r+o*o}function at(i){let e=i[0],t=i[1],r=i[2];return e*e+t*t+r*r}function Ii(i,e){return i[0]=-e[0],i[1]=-e[1],i[2]=-e[2],i}function Ci(i,e){return i[0]=1/e[0],i[1]=1/e[1],i[2]=1/e[2],i}function Ri(i,e){let t=e[0],r=e[1],o=e[2],s=t*t+r*r+o*o;return s>0&&(s=1/Math.sqrt(s)),i[0]=e[0]*s,i[1]=e[1]*s,i[2]=e[2]*s,i}function ge(i,e){return i[0]*e[0]+i[1]*e[1]+i[2]*e[2]}function ki(i,e,t){let r=e[0],o=e[1],s=e[2],n=t[0],a=t[1],l=t[2];return i[0]=o*l-s*a,i[1]=s*n-r*l,i[2]=r*a-o*n,i}function wi(i,e,t,r){let o=e[0],s=e[1],n=e[2];return i[0]=o+r*(t[0]-o),i[1]=s+r*(t[1]-s),i[2]=n+r*(t[2]-n),i}function Ni(i,e,t,r){let o=Math.acos(Math.min(Math.max(ge(e,t),-1),1)),s=Math.sin(o),n=Math.sin((1-r)*o)/s,a=Math.sin(r*o)/s;return i[0]=n*e[0]+a*t[0],i[1]=n*e[1]+a*t[1],i[2]=n*e[2]+a*t[2],i}function Bi(i,e,t,r,o,s){let n=s*s,a=n*(2*s-3)+1,l=n*(s-2)+s,f=n*(s-1),u=n*(3-2*s);return i[0]=e[0]*a+t[0]*l+r[0]*f+o[0]*u,i[1]=e[1]*a+t[1]*l+r[1]*f+o[1]*u,i[2]=e[2]*a+t[2]*l+r[2]*f+o[2]*u,i}function Di(i,e,t,r,o,s){let n=1-s,a=n*n,l=s*s,f=a*n,u=3*s*a,c=3*l*n,p=l*s;return i[0]=e[0]*f+t[0]*u+r[0]*c+o[0]*p,i[1]=e[1]*f+t[1]*u+r[1]*c+o[1]*p,i[2]=e[2]*f+t[2]*u+r[2]*c+o[2]*p,i}function zi(i,e){e=e===void 0?1:e;let t=he()*2*Math.PI,r=he()*2-1,o=Math.sqrt(1-r*r)*e;return i[0]=Math.cos(t)*o,i[1]=Math.sin(t)*o,i[2]=r*e,i}function Vi(i,e,t){let r=e[0],o=e[1],s=e[2],n=t[3]*r+t[7]*o+t[11]*s+t[15];return n=n||1,i[0]=(t[0]*r+t[4]*o+t[8]*s+t[12])/n,i[1]=(t[1]*r+t[5]*o+t[9]*s+t[13])/n,i[2]=(t[2]*r+t[6]*o+t[10]*s+t[14])/n,i}function ji(i,e,t){let r=e[0],o=e[1],s=e[2];return i[0]=r*t[0]+o*t[3]+s*t[6],i[1]=r*t[1]+o*t[4]+s*t[7],i[2]=r*t[2]+o*t[5]+s*t[8],i}function Ui(i,e,t){let r=t[0],o=t[1],s=t[2],n=t[3],a=e[0],l=e[1],f=e[2],u=o*f-s*l,c=s*a-r*f,p=r*l-o*a,m=o*p-s*c,h=s*u-r*p,P=r*c-o*u,v=n*2;return u*=v,c*=v,p*=v,m*=2,h*=2,P*=2,i[0]=a+u+m,i[1]=l+c+h,i[2]=f+p+P,i}function Gi(i,e,t,r){let o=[],s=[];return o[0]=e[0]-t[0],o[1]=e[1]-t[1],o[2]=e[2]-t[2],s[0]=o[0],s[1]=o[1]*Math.cos(r)-o[2]*Math.sin(r),s[2]=o[1]*Math.sin(r)+o[2]*Math.cos(r),i[0]=s[0]+t[0],i[1]=s[1]+t[1],i[2]=s[2]+t[2],i}function Hi(i,e,t,r){let o=[],s=[];return o[0]=e[0]-t[0],o[1]=e[1]-t[1],o[2]=e[2]-t[2],s[0]=o[2]*Math.sin(r)+o[0]*Math.cos(r),s[1]=o[1],s[2]=o[2]*Math.cos(r)-o[0]*Math.sin(r),i[0]=s[0]+t[0],i[1]=s[1]+t[1],i[2]=s[2]+t[2],i}function qi(i,e,t,r){let o=[],s=[];return o[0]=e[0]-t[0],o[1]=e[1]-t[1],o[2]=e[2]-t[2],s[0]=o[0]*Math.cos(r)-o[1]*Math.sin(r),s[1]=o[0]*Math.sin(r)+o[1]*Math.cos(r),s[2]=o[2],i[0]=s[0]+t[0],i[1]=s[1]+t[1],i[2]=s[2]+t[2],i}function Wi(i,e){let t=i[0],r=i[1],o=i[2],s=e[0],n=e[1],a=e[2],l=Math.sqrt((t*t+r*r+o*o)*(s*s+n*n+a*a)),f=l&&ge(i,e)/l;return Math.acos(Math.min(Math.max(f,-1),1))}function Yi(i){return i[0]=0,i[1]=0,i[2]=0,i}function Ki(i){return`vec3(${i[0]}, ${i[1]}, ${i[2]})`}function $i(i,e){return i[0]===e[0]&&i[1]===e[1]&&i[2]===e[2]}function Zi(i,e){let t=i[0],r=i[1],o=i[2],s=e[0],n=e[1],a=e[2];return Math.abs(t-s)<=1e-6*Math.max(1,Math.abs(t),Math.abs(s))&&Math.abs(r-n)<=1e-6*Math.max(1,Math.abs(r),Math.abs(n))&&Math.abs(o-a)<=1e-6*Math.max(1,Math.abs(o),Math.abs(a))}var Ji=it,Xi=rt,Qi=ot,er=st,tr=nt,ir=tt,rr=at,or=function(){let i=et();return function(e,t,r,o,s,n){let a,l;for(t||(t=3),r||(r=0),o?l=Math.min(o*t+r,e.length):l=e.length,a=r;a<l;a+=t)i[0]=e[a],i[1]=e[a+1],i[2]=e[a+2],s(i,i,n),e[a]=i[0],e[a+1]=i[1],e[a+2]=i[2];return e}}();function te(i,e=[],t=0){let r=Math.fround(i),o=i-r;return e[t]=r,e[t+1]=o,e}function xe(i){return i-Math.fround(i)}function ye(i){let e=new Float32Array(32);for(let t=0;t<4;++t)for(let r=0;r<4;++r){let o=t*4+r;te(i[r*4+t],e,o*2)}return e}var be=`
326
+ `,Hi=["float32-renderable-webgl","texture-blend-float-webgl"];function ft(t){return Hi.every(e=>t.features.has(e))}function ct(t,e){return e?t.createFramebuffer({width:1,height:1,colorAttachments:[t.createTexture({format:"rgba32float",dimension:"2d",width:1,height:1})]}):t.createFramebuffer({width:256,height:64,colorAttachments:[t.createTexture({format:"rgba8unorm",dimension:"2d",width:256,height:64})]})}function ut(t,e,i,r){return i.defines.NON_INSTANCED_MODEL=1,r&&(i.defines.FLOAT_TARGET=1),new lt.Model(t,{id:"data-filter-aggregation-model",vertexCount:1,isInstanced:!1,topology:"point-list",disableWarnings:!0,vs:Vi,fs:ji,bufferLayout:e,...i})}var dt={blend:!0,blendColorSrcFactor:"one",blendColorDstFactor:"one",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one",blendColorOperation:"add",blendAlphaOperation:"add",depthCompare:"never"};var qi={getFilterValue:{type:"accessor",value:0},getFilterCategory:{type:"accessor",value:0},onFilteredItemsChange:{type:"function",value:null,optional:!0},filterEnabled:!0,filterRange:[-1,1],filterSoftRange:null,filterCategories:[0],filterTransformSize:!0,filterTransformColor:!0},Wi={categorySize:0,filterSize:1,fp64:!1,countItems:!1},Yi={1:"uint",2:"uvec2",3:"uvec3",4:"uvec4"},Ki={1:"float",2:"vec2",3:"vec3",4:"vec4"},W=class extends D.LayerExtension{constructor(e={}){super({...Wi,...e})}getShaders(e){let{categorySize:i,filterSize:r,fp64:n}=e.opts,o={};i&&(o.DATACATEGORY_TYPE=Yi[i],o.DATACATEGORY_CHANNELS=i),r&&(o.DATAFILTER_TYPE=Ki[r],o.DATAFILTER_DOUBLE=!!n);let a=n?ot:nt;return a.uniformTypes=a.uniformTypesFromOptions(e.opts),{modules:[a],defines:o}}initializeState(e,i){let r=this.getAttributeManager(),{categorySize:n,filterSize:o,fp64:a}=i.opts;r&&(o&&r.add({filterValues:{size:o,type:a?"float64":"float32",stepMode:"dynamic",accessor:"getFilterValue"}}),n&&r.add({filterCategoryValues:{size:n,stepMode:"dynamic",accessor:"getFilterCategory",type:"uint32",transform:n===1?l=>i._getCategoryKey.call(this,l,0):l=>l.map((f,c)=>i._getCategoryKey.call(this,f,c))}}));let{device:s}=this.context;if(r&&i.opts.countItems){let l=ft(s);r.add({filterVertexIndices:{size:l?1:2,vertexOffset:1,type:"unorm8",accessor:(u,{index:d})=>{let p=u&&u.__source?u.__source.index:d;return l?(p+1)%255:[(p+1)%255,Math.floor(p/255)%255]},shaderAttributes:{filterPrevIndices:{vertexOffset:0},filterIndices:{vertexOffset:1}}}});let f=ct(s,l),c=ut(s,r.getBufferLayouts({isInstanced:!1}),i.getShaders.call(this,i),l);this.setState({filterFBO:f,filterModel:c})}}updateState({props:e,oldProps:i,changeFlags:r},n){let o=this.getAttributeManager(),{categorySize:a}=n.opts;if(this.state.filterModel){let s=o.attributes.filterValues?.needsUpdate()||o.attributes.filterCategoryValues?.needsUpdate()||e.filterEnabled!==i.filterEnabled||e.filterRange!==i.filterRange||e.filterSoftRange!==i.filterSoftRange||e.filterCategories!==i.filterCategories;s&&this.setState({filterNeedsUpdate:s})}o?.attributes.filterCategoryValues&&((o.attributes.filterCategoryValues.needsUpdate()||!(0,D._deepEqual)(e.filterCategories,i.filterCategories,2))&&this.setState({categoryBitMask:null}),r.dataChanged&&(this.setState({categoryMap:Array(a).fill(0).map(()=>({}))}),o.attributes.filterCategoryValues.setNeedsUpdate("categoryMap")))}draw(e,i){let r=this.state.filterFBO,n=this.state.filterModel,o=this.state.filterNeedsUpdate;this.state.categoryBitMask||i._updateCategoryBitMask.call(this,e,i);let{onFilteredItemsChange:a,extensions:s,filterEnabled:l,filterRange:f,filterSoftRange:c,filterTransformSize:u,filterTransformColor:d,filterCategories:p}=this.props,m={extensions:s,filterEnabled:l,filterRange:f,filterSoftRange:c,filterTransformSize:u,filterTransformColor:d,filterCategories:p};if(this.state.categoryBitMask&&(m.categoryBitMask=this.state.categoryBitMask),this.setShaderModuleProps({dataFilter:m}),o&&a&&n){let F=this.getAttributeManager(),{attributes:{filterValues:v,filterCategoryValues:O,filterVertexIndices:R}}=F;n.setVertexCount(this.getNumInstances());let P={...v?.getValue(),...O?.getValue(),...R?.getValue()};n.setAttributes(P),n.shaderInputs.setProps({dataFilter:m});let k=[0,0,r.width,r.height],G=n.device.beginRenderPass({id:"data-filter-aggregation",framebuffer:r,parameters:{viewport:k},clearColor:[0,0,0,0]});n.setParameters(dt),n.draw(G),G.end();let x=n.device.readPixelsToArrayWebGL(r),A=0;for(let N=0;N<x.length;N++)A+=x[N];a({id:this.id,count:A}),this.state.filterNeedsUpdate=!1}}finalizeState(){let e=this.state.filterFBO,i=this.state.filterModel;e?.destroy(),i?.destroy()}_updateCategoryBitMask(e,i){let{categorySize:r}=i.opts;if(!r)return;let{filterCategories:n}=this.props,o=new Uint32Array([0,0,0,0]),a=r===1?[n]:n,s=r===1?128:r===2?64:32;for(let l=0;l<a.length;l++){let f=a[l];for(let c of f){let u=i._getCategoryKey.call(this,c,l);if(u<s){let d=l*(s/32)+Math.floor(u/32);o[d]+=Math.pow(2,u%32)}else D.log.warn(`Exceeded maximum number of categories (${s})`)()}}this.state.categoryBitMask=o}_getCategoryKey(e,i){let r=this.state.categoryMap[i];return e in r||(r[e]=Object.keys(r).length),r[e]}};W.defaultProps=qi;W.extensionName="DataFilterExtension";var pt=W;var kt=_(h(),1);var Po=1/Math.PI*180,Eo=1/180*Math.PI,Zi={EPSILON:1e-12,debug:!1,precision:4,printTypes:!1,printDegrees:!1,printRowMajor:!0,_cartographicRadians:!1};globalThis.mathgl=globalThis.mathgl||{config:{...Zi}};var Y=globalThis.mathgl.config;function Fe(t){return Array.isArray(t)||ArrayBuffer.isView(t)&&!(t instanceof DataView)}function z(t,e,i){let r=Y.EPSILON;i&&(Y.EPSILON=i);try{if(t===e)return!0;if(Fe(t)&&Fe(e)){if(t.length!==e.length)return!1;for(let n=0;n<t.length;++n)if(!z(t[n],e[n]))return!1;return!0}return t&&t.equals?t.equals(e):e&&e.equals?e.equals(t):typeof t=="number"&&typeof e=="number"?Math.abs(t-e)<=Y.EPSILON*Math.max(1,Math.abs(t),Math.abs(e)):!1}finally{Y.EPSILON=r}}var M=typeof Float32Array<"u"?Float32Array:Array,w=Math.random;function S(t){return t>=0?Math.round(t):t%.5===0?Math.floor(t):Math.round(t)}var Ao=Math.PI/180;var L={};Le(L,{add:()=>er,angle:()=>Er,bezier:()=>hr,ceil:()=>tr,clone:()=>$i,copy:()=>Qi,create:()=>ht,cross:()=>ur,dist:()=>Br,distance:()=>bt,div:()=>Or,divide:()=>xt,dot:()=>Oe,equals:()=>Sr,exactEquals:()=>Tr,floor:()=>ir,forEach:()=>Rr,fromValues:()=>Xi,hermite:()=>_r,inverse:()=>fr,len:()=>Ir,length:()=>mt,lerp:()=>dr,max:()=>nr,min:()=>rr,mul:()=>Fr,multiply:()=>vt,negate:()=>lr,normalize:()=>cr,random:()=>mr,rotateX:()=>br,rotateY:()=>yr,rotateZ:()=>Pr,round:()=>or,scale:()=>ar,scaleAndAdd:()=>sr,set:()=>Ji,slerp:()=>pr,sqrDist:()=>wr,sqrLen:()=>Cr,squaredDistance:()=>yt,squaredLength:()=>Pt,str:()=>Ar,sub:()=>Lr,subtract:()=>gt,transformMat3:()=>vr,transformMat4:()=>gr,transformQuat:()=>xr,zero:()=>Mr});function ht(){let t=new M(3);return M!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0),t}function $i(t){let e=new M(3);return e[0]=t[0],e[1]=t[1],e[2]=t[2],e}function mt(t){let e=t[0],i=t[1],r=t[2];return Math.sqrt(e*e+i*i+r*r)}function Xi(t,e,i){let r=new M(3);return r[0]=t,r[1]=e,r[2]=i,r}function Qi(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t}function Ji(t,e,i,r){return t[0]=e,t[1]=i,t[2]=r,t}function er(t,e,i){return t[0]=e[0]+i[0],t[1]=e[1]+i[1],t[2]=e[2]+i[2],t}function gt(t,e,i){return t[0]=e[0]-i[0],t[1]=e[1]-i[1],t[2]=e[2]-i[2],t}function vt(t,e,i){return t[0]=e[0]*i[0],t[1]=e[1]*i[1],t[2]=e[2]*i[2],t}function xt(t,e,i){return t[0]=e[0]/i[0],t[1]=e[1]/i[1],t[2]=e[2]/i[2],t}function tr(t,e){return t[0]=Math.ceil(e[0]),t[1]=Math.ceil(e[1]),t[2]=Math.ceil(e[2]),t}function ir(t,e){return t[0]=Math.floor(e[0]),t[1]=Math.floor(e[1]),t[2]=Math.floor(e[2]),t}function rr(t,e,i){return t[0]=Math.min(e[0],i[0]),t[1]=Math.min(e[1],i[1]),t[2]=Math.min(e[2],i[2]),t}function nr(t,e,i){return t[0]=Math.max(e[0],i[0]),t[1]=Math.max(e[1],i[1]),t[2]=Math.max(e[2],i[2]),t}function or(t,e){return t[0]=S(e[0]),t[1]=S(e[1]),t[2]=S(e[2]),t}function ar(t,e,i){return t[0]=e[0]*i,t[1]=e[1]*i,t[2]=e[2]*i,t}function sr(t,e,i,r){return t[0]=e[0]+i[0]*r,t[1]=e[1]+i[1]*r,t[2]=e[2]+i[2]*r,t}function bt(t,e){let i=e[0]-t[0],r=e[1]-t[1],n=e[2]-t[2];return Math.sqrt(i*i+r*r+n*n)}function yt(t,e){let i=e[0]-t[0],r=e[1]-t[1],n=e[2]-t[2];return i*i+r*r+n*n}function Pt(t){let e=t[0],i=t[1],r=t[2];return e*e+i*i+r*r}function lr(t,e){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t}function fr(t,e){return t[0]=1/e[0],t[1]=1/e[1],t[2]=1/e[2],t}function cr(t,e){let i=e[0],r=e[1],n=e[2],o=i*i+r*r+n*n;return o>0&&(o=1/Math.sqrt(o)),t[0]=e[0]*o,t[1]=e[1]*o,t[2]=e[2]*o,t}function Oe(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}function ur(t,e,i){let r=e[0],n=e[1],o=e[2],a=i[0],s=i[1],l=i[2];return t[0]=n*l-o*s,t[1]=o*a-r*l,t[2]=r*s-n*a,t}function dr(t,e,i,r){let n=e[0],o=e[1],a=e[2];return t[0]=n+r*(i[0]-n),t[1]=o+r*(i[1]-o),t[2]=a+r*(i[2]-a),t}function pr(t,e,i,r){let n=Math.acos(Math.min(Math.max(Oe(e,i),-1),1)),o=Math.sin(n),a=Math.sin((1-r)*n)/o,s=Math.sin(r*n)/o;return t[0]=a*e[0]+s*i[0],t[1]=a*e[1]+s*i[1],t[2]=a*e[2]+s*i[2],t}function _r(t,e,i,r,n,o){let a=o*o,s=a*(2*o-3)+1,l=a*(o-2)+o,f=a*(o-1),c=a*(3-2*o);return t[0]=e[0]*s+i[0]*l+r[0]*f+n[0]*c,t[1]=e[1]*s+i[1]*l+r[1]*f+n[1]*c,t[2]=e[2]*s+i[2]*l+r[2]*f+n[2]*c,t}function hr(t,e,i,r,n,o){let a=1-o,s=a*a,l=o*o,f=s*a,c=3*o*s,u=3*l*a,d=l*o;return t[0]=e[0]*f+i[0]*c+r[0]*u+n[0]*d,t[1]=e[1]*f+i[1]*c+r[1]*u+n[1]*d,t[2]=e[2]*f+i[2]*c+r[2]*u+n[2]*d,t}function mr(t,e){e=e===void 0?1:e;let i=w()*2*Math.PI,r=w()*2-1,n=Math.sqrt(1-r*r)*e;return t[0]=Math.cos(i)*n,t[1]=Math.sin(i)*n,t[2]=r*e,t}function gr(t,e,i){let r=e[0],n=e[1],o=e[2],a=i[3]*r+i[7]*n+i[11]*o+i[15];return a=a||1,t[0]=(i[0]*r+i[4]*n+i[8]*o+i[12])/a,t[1]=(i[1]*r+i[5]*n+i[9]*o+i[13])/a,t[2]=(i[2]*r+i[6]*n+i[10]*o+i[14])/a,t}function vr(t,e,i){let r=e[0],n=e[1],o=e[2];return t[0]=r*i[0]+n*i[3]+o*i[6],t[1]=r*i[1]+n*i[4]+o*i[7],t[2]=r*i[2]+n*i[5]+o*i[8],t}function xr(t,e,i){let r=i[0],n=i[1],o=i[2],a=i[3],s=e[0],l=e[1],f=e[2],c=n*f-o*l,u=o*s-r*f,d=r*l-n*s,p=n*d-o*u,m=o*c-r*d,F=r*u-n*c,v=a*2;return c*=v,u*=v,d*=v,p*=2,m*=2,F*=2,t[0]=s+c+p,t[1]=l+u+m,t[2]=f+d+F,t}function br(t,e,i,r){let n=[],o=[];return n[0]=e[0]-i[0],n[1]=e[1]-i[1],n[2]=e[2]-i[2],o[0]=n[0],o[1]=n[1]*Math.cos(r)-n[2]*Math.sin(r),o[2]=n[1]*Math.sin(r)+n[2]*Math.cos(r),t[0]=o[0]+i[0],t[1]=o[1]+i[1],t[2]=o[2]+i[2],t}function yr(t,e,i,r){let n=[],o=[];return n[0]=e[0]-i[0],n[1]=e[1]-i[1],n[2]=e[2]-i[2],o[0]=n[2]*Math.sin(r)+n[0]*Math.cos(r),o[1]=n[1],o[2]=n[2]*Math.cos(r)-n[0]*Math.sin(r),t[0]=o[0]+i[0],t[1]=o[1]+i[1],t[2]=o[2]+i[2],t}function Pr(t,e,i,r){let n=[],o=[];return n[0]=e[0]-i[0],n[1]=e[1]-i[1],n[2]=e[2]-i[2],o[0]=n[0]*Math.cos(r)-n[1]*Math.sin(r),o[1]=n[0]*Math.sin(r)+n[1]*Math.cos(r),o[2]=n[2],t[0]=o[0]+i[0],t[1]=o[1]+i[1],t[2]=o[2]+i[2],t}function Er(t,e){let i=t[0],r=t[1],n=t[2],o=e[0],a=e[1],s=e[2],l=Math.sqrt((i*i+r*r+n*n)*(o*o+a*a+s*s)),f=l&&Oe(t,e)/l;return Math.acos(Math.min(Math.max(f,-1),1))}function Mr(t){return t[0]=0,t[1]=0,t[2]=0,t}function Ar(t){return`vec3(${t[0]}, ${t[1]}, ${t[2]})`}function Tr(t,e){return t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]}function Sr(t,e){let i=t[0],r=t[1],n=t[2],o=e[0],a=e[1],s=e[2];return Math.abs(i-o)<=1e-6*Math.max(1,Math.abs(i),Math.abs(o))&&Math.abs(r-a)<=1e-6*Math.max(1,Math.abs(r),Math.abs(a))&&Math.abs(n-s)<=1e-6*Math.max(1,Math.abs(n),Math.abs(s))}var Lr=gt,Fr=vt,Or=xt,Br=bt,wr=yt,Ir=mt,Cr=Pt,Rr=(function(){let t=ht();return function(e,i,r,n,o,a){let s,l;for(i||(i=3),r||(r=0),n?l=Math.min(n*i+r,e.length):l=e.length,s=r;s<l;s+=i)t[0]=e[s],t[1]=e[s+1],t[2]=e[s+2],o(t,t,a),e[s]=t[0],e[s+1]=t[1],e[s+2]=t[2];return e}})();var pe={};Le(pe,{add:()=>Ur,ceil:()=>Vr,clone:()=>kr,copy:()=>Dr,create:()=>Et,cross:()=>Qr,dist:()=>un,distance:()=>St,div:()=>cn,divide:()=>Tt,dot:()=>Xr,equals:()=>sn,exactEquals:()=>an,floor:()=>jr,forEach:()=>hn,fromValues:()=>Nr,inverse:()=>Zr,len:()=>pn,length:()=>Ft,lerp:()=>Jr,max:()=>Gr,min:()=>Hr,mul:()=>fn,multiply:()=>At,negate:()=>Kr,normalize:()=>$r,random:()=>en,round:()=>qr,scale:()=>Wr,scaleAndAdd:()=>Yr,set:()=>zr,sqrDist:()=>dn,sqrLen:()=>_n,squaredDistance:()=>Lt,squaredLength:()=>Ot,str:()=>on,sub:()=>ln,subtract:()=>Mt,transformMat4:()=>tn,transformQuat:()=>rn,zero:()=>nn});function Et(){let t=new M(4);return M!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0,t[3]=0),t}function kr(t){let e=new M(4);return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e}function Nr(t,e,i,r){let n=new M(4);return n[0]=t,n[1]=e,n[2]=i,n[3]=r,n}function Dr(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t}function zr(t,e,i,r,n){return t[0]=e,t[1]=i,t[2]=r,t[3]=n,t}function Ur(t,e,i){return t[0]=e[0]+i[0],t[1]=e[1]+i[1],t[2]=e[2]+i[2],t[3]=e[3]+i[3],t}function Mt(t,e,i){return t[0]=e[0]-i[0],t[1]=e[1]-i[1],t[2]=e[2]-i[2],t[3]=e[3]-i[3],t}function At(t,e,i){return t[0]=e[0]*i[0],t[1]=e[1]*i[1],t[2]=e[2]*i[2],t[3]=e[3]*i[3],t}function Tt(t,e,i){return t[0]=e[0]/i[0],t[1]=e[1]/i[1],t[2]=e[2]/i[2],t[3]=e[3]/i[3],t}function Vr(t,e){return t[0]=Math.ceil(e[0]),t[1]=Math.ceil(e[1]),t[2]=Math.ceil(e[2]),t[3]=Math.ceil(e[3]),t}function jr(t,e){return t[0]=Math.floor(e[0]),t[1]=Math.floor(e[1]),t[2]=Math.floor(e[2]),t[3]=Math.floor(e[3]),t}function Hr(t,e,i){return t[0]=Math.min(e[0],i[0]),t[1]=Math.min(e[1],i[1]),t[2]=Math.min(e[2],i[2]),t[3]=Math.min(e[3],i[3]),t}function Gr(t,e,i){return t[0]=Math.max(e[0],i[0]),t[1]=Math.max(e[1],i[1]),t[2]=Math.max(e[2],i[2]),t[3]=Math.max(e[3],i[3]),t}function qr(t,e){return t[0]=S(e[0]),t[1]=S(e[1]),t[2]=S(e[2]),t[3]=S(e[3]),t}function Wr(t,e,i){return t[0]=e[0]*i,t[1]=e[1]*i,t[2]=e[2]*i,t[3]=e[3]*i,t}function Yr(t,e,i,r){return t[0]=e[0]+i[0]*r,t[1]=e[1]+i[1]*r,t[2]=e[2]+i[2]*r,t[3]=e[3]+i[3]*r,t}function St(t,e){let i=e[0]-t[0],r=e[1]-t[1],n=e[2]-t[2],o=e[3]-t[3];return Math.sqrt(i*i+r*r+n*n+o*o)}function Lt(t,e){let i=e[0]-t[0],r=e[1]-t[1],n=e[2]-t[2],o=e[3]-t[3];return i*i+r*r+n*n+o*o}function Ft(t){let e=t[0],i=t[1],r=t[2],n=t[3];return Math.sqrt(e*e+i*i+r*r+n*n)}function Ot(t){let e=t[0],i=t[1],r=t[2],n=t[3];return e*e+i*i+r*r+n*n}function Kr(t,e){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t}function Zr(t,e){return t[0]=1/e[0],t[1]=1/e[1],t[2]=1/e[2],t[3]=1/e[3],t}function $r(t,e){let i=e[0],r=e[1],n=e[2],o=e[3],a=i*i+r*r+n*n+o*o;return a>0&&(a=1/Math.sqrt(a)),t[0]=i*a,t[1]=r*a,t[2]=n*a,t[3]=o*a,t}function Xr(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]+t[3]*e[3]}function Qr(t,e,i,r){let n=i[0]*r[1]-i[1]*r[0],o=i[0]*r[2]-i[2]*r[0],a=i[0]*r[3]-i[3]*r[0],s=i[1]*r[2]-i[2]*r[1],l=i[1]*r[3]-i[3]*r[1],f=i[2]*r[3]-i[3]*r[2],c=e[0],u=e[1],d=e[2],p=e[3];return t[0]=u*f-d*l+p*s,t[1]=-(c*f)+d*a-p*o,t[2]=c*l-u*a+p*n,t[3]=-(c*s)+u*o-d*n,t}function Jr(t,e,i,r){let n=e[0],o=e[1],a=e[2],s=e[3];return t[0]=n+r*(i[0]-n),t[1]=o+r*(i[1]-o),t[2]=a+r*(i[2]-a),t[3]=s+r*(i[3]-s),t}function en(t,e){e=e===void 0?1:e;let i,r,n,o,a,s;do i=w()*2-1,r=w()*2-1,a=i*i+r*r;while(a>=1);do n=w()*2-1,o=w()*2-1,s=n*n+o*o;while(s>=1);let l=Math.sqrt((1-a)/s);return t[0]=e*i,t[1]=e*r,t[2]=e*n*l,t[3]=e*o*l,t}function tn(t,e,i){let r=e[0],n=e[1],o=e[2],a=e[3];return t[0]=i[0]*r+i[4]*n+i[8]*o+i[12]*a,t[1]=i[1]*r+i[5]*n+i[9]*o+i[13]*a,t[2]=i[2]*r+i[6]*n+i[10]*o+i[14]*a,t[3]=i[3]*r+i[7]*n+i[11]*o+i[15]*a,t}function rn(t,e,i){let r=e[0],n=e[1],o=e[2],a=i[0],s=i[1],l=i[2],f=i[3],c=f*r+s*o-l*n,u=f*n+l*r-a*o,d=f*o+a*n-s*r,p=-a*r-s*n-l*o;return t[0]=c*f+p*-a+u*-l-d*-s,t[1]=u*f+p*-s+d*-a-c*-l,t[2]=d*f+p*-l+c*-s-u*-a,t[3]=e[3],t}function nn(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=0,t}function on(t){return`vec4(${t[0]}, ${t[1]}, ${t[2]}, ${t[3]})`}function an(t,e){return t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]}function sn(t,e){let i=t[0],r=t[1],n=t[2],o=t[3],a=e[0],s=e[1],l=e[2],f=e[3];return Math.abs(i-a)<=1e-6*Math.max(1,Math.abs(i),Math.abs(a))&&Math.abs(r-s)<=1e-6*Math.max(1,Math.abs(r),Math.abs(s))&&Math.abs(n-l)<=1e-6*Math.max(1,Math.abs(n),Math.abs(l))&&Math.abs(o-f)<=1e-6*Math.max(1,Math.abs(o),Math.abs(f))}var ln=Mt,fn=At,cn=Tt,un=St,dn=Lt,pn=Ft,_n=Ot,hn=(function(){let t=Et();return function(e,i,r,n,o,a){let s,l;for(i||(i=4),r||(r=0),n?l=Math.min(n*i+r,e.length):l=e.length,s=r;s<l;s+=i)t[0]=e[s],t[1]=e[s+1],t[2]=e[s+2],t[3]=e[s+3],o(t,t,a),e[s]=t[0],e[s+1]=t[1],e[s+2]=t[2],e[s+3]=t[3];return e}})();function _e(t,e=[],i=0){let r=Math.fround(t),n=t-r;return e[i]=r,e[i+1]=n,e}function Be(t){return t-Math.fround(t)}function we(t){let e=new Float32Array(32);for(let i=0;i<4;++i)for(let r=0;r<4;++r){let n=i*4+r;_e(t[r*4+i],e,n*2)}return e}var Ie=`
327
327
  layout(std140) uniform fp64arithmeticUniforms {
328
328
  uniform float ONE;
329
329
  uniform float SPLIT;
@@ -522,13 +522,464 @@ vec2 sqrt_fp64(vec2 a) {
522
522
  return sum_fp64(vec2(yn, 0.0), prod);
523
523
  #endif
524
524
  }
525
- `;var lt=`struct Fp64ArithmeticUniforms {
525
+ `;var Bt=`struct Fp64F32Bits {
526
+ sign: u32,
527
+ baseExponent: i32,
528
+ significand: u32,
529
+ isZero: bool,
530
+ isInf: bool,
531
+ isNan: bool,
532
+ };
533
+
534
+ // Decode an f32 as (-1)^sign * significand * 2^baseExponent.
535
+ fn fp64_decode_f32_bits(bits: u32) -> Fp64F32Bits {
536
+ let sign = bits >> 31u;
537
+ let exponentBits = (bits >> 23u) & 0xffu;
538
+ let fraction = bits & 0x7fffffu;
539
+
540
+ if (exponentBits == 0xffu) {
541
+ return Fp64F32Bits(sign, 0, 0u, false, fraction == 0u, fraction != 0u);
542
+ }
543
+ if (exponentBits == 0u) {
544
+ return Fp64F32Bits(sign, -149, fraction, fraction == 0u, false, false);
545
+ }
546
+ return Fp64F32Bits(sign, i32(exponentBits) - 150, 0x800000u | fraction, false, false, false);
547
+ }
548
+
549
+ fn fp64_f32_magnitude_compare(aBits: u32, bBits: u32) -> i32 {
550
+ let aMagnitude = aBits & 0x7fffffffu;
551
+ let bMagnitude = bBits & 0x7fffffffu;
552
+ if (aMagnitude == bMagnitude) {
553
+ return 0;
554
+ }
555
+ return select(-1, 1, aMagnitude > bMagnitude);
556
+ }
557
+
558
+ fn fp64_make_residual_f32_bits(
559
+ exactSign: u32,
560
+ exactMagnitude: vec2u,
561
+ exactBaseExponent: i32,
562
+ highBits: u32
563
+ ) -> u32 {
564
+ if (fp64_u64_is_zero(exactMagnitude)) {
565
+ return 0u;
566
+ }
567
+
568
+ let high = fp64_decode_f32_bits(highBits);
569
+ if (high.isInf || high.isNan) {
570
+ return exactSign << 31u;
571
+ }
572
+ if (high.isZero) {
573
+ return fp64_make_f32_bits_from_u64(exactSign, exactMagnitude, exactBaseExponent);
574
+ }
575
+
576
+ let commonBaseExponent = min(exactBaseExponent, high.baseExponent);
577
+ let exactShift = exactBaseExponent - commonBaseExponent;
578
+ let highShift = high.baseExponent - commonBaseExponent;
579
+
580
+ // A normal two-sum/two-product residual never needs a shift this large.
581
+ // This guard gives deterministic underflow behavior outside that contract.
582
+ if (exactShift >= 64 || highShift >= 64) {
583
+ return exactSign << 31u;
584
+ }
585
+
586
+ let exactAligned = fp64_u64_shift_left(exactMagnitude, u32(exactShift));
587
+ let highAligned = fp64_u64_shift_left(vec2u(0u, high.significand), u32(highShift));
588
+ let comparison = fp64_u64_compare(exactAligned, highAligned);
589
+ if (comparison == 0) {
590
+ return 0u;
591
+ }
592
+
593
+ var residualSign = exactSign;
594
+ var residualMagnitude: vec2u;
595
+ if (comparison > 0) {
596
+ residualMagnitude = fp64_u64_sub(exactAligned, highAligned);
597
+ } else {
598
+ residualSign = exactSign ^ 1u;
599
+ residualMagnitude = fp64_u64_sub(highAligned, exactAligned);
600
+ }
601
+ return fp64_make_f32_bits_from_u64(
602
+ residualSign,
603
+ residualMagnitude,
604
+ commonBaseExponent
605
+ );
606
+ }
607
+
608
+ fn fp64_split_accumulator_bits(
609
+ sign: u32,
610
+ magnitude: vec2u,
611
+ baseExponent: i32
612
+ ) -> vec2u {
613
+ let highBits = fp64_make_f32_bits_from_u64(sign, magnitude, baseExponent);
614
+ let lowBits = fp64_make_residual_f32_bits(sign, magnitude, baseExponent, highBits);
615
+ return vec2u(highBits, lowBits);
616
+ }
617
+
618
+ fn fp64_two_sum_integer_bits(aBits: u32, bBits: u32) -> vec2u {
619
+ let a = fp64_decode_f32_bits(aBits);
620
+ let b = fp64_decode_f32_bits(bBits);
621
+
622
+ if (a.isNan || b.isNan) {
623
+ return vec2u(0x7fc00000u, 0u);
624
+ }
625
+ if (a.isInf || b.isInf) {
626
+ if (a.isInf && b.isInf && a.sign != b.sign) {
627
+ return vec2u(0x7fc00000u, 0u);
628
+ }
629
+ return select(vec2u(bBits, 0u), vec2u(aBits, 0u), a.isInf);
630
+ }
631
+ if (a.isZero && b.isZero) {
632
+ return vec2u((a.sign & b.sign) << 31u, 0u);
633
+ }
634
+ if (a.isZero) {
635
+ return vec2u(bBits, 0u);
636
+ }
637
+ if (b.isZero) {
638
+ return vec2u(aBits, 0u);
639
+ }
640
+
641
+ let exponentDifference = select(
642
+ b.baseExponent - a.baseExponent,
643
+ a.baseExponent - b.baseExponent,
644
+ a.baseExponent >= b.baseExponent
645
+ );
646
+
647
+ // Beyond half an ulp, rounding cannot change the larger operand. Returning
648
+ // the smaller operand intact also avoids an unbounded integer alignment.
649
+ // At a power-of-two boundary the spacing below the larger operand is half
650
+ // the spacing above it, so an opposite-sign gap-25 operand can still change
651
+ // the rounded high limb. Gap 26 is the first universally safe early-out.
652
+ if (exponentDifference > 25) {
653
+ if (fp64_f32_magnitude_compare(aBits, bBits) >= 0) {
654
+ return vec2u(aBits, bBits);
655
+ }
656
+ return vec2u(bBits, aBits);
657
+ }
658
+
659
+ let commonBaseExponent = min(a.baseExponent, b.baseExponent);
660
+ let aMagnitude = fp64_u64_shift_left(
661
+ vec2u(0u, a.significand),
662
+ u32(a.baseExponent - commonBaseExponent)
663
+ );
664
+ let bMagnitude = fp64_u64_shift_left(
665
+ vec2u(0u, b.significand),
666
+ u32(b.baseExponent - commonBaseExponent)
667
+ );
668
+
669
+ var resultSign = a.sign;
670
+ var resultMagnitude: vec2u;
671
+ if (a.sign == b.sign) {
672
+ resultMagnitude = fp64_u64_add(aMagnitude, bMagnitude);
673
+ } else {
674
+ let comparison = fp64_u64_compare(aMagnitude, bMagnitude);
675
+ if (comparison == 0) {
676
+ return vec2u(0u, 0u);
677
+ }
678
+ if (comparison > 0) {
679
+ resultMagnitude = fp64_u64_sub(aMagnitude, bMagnitude);
680
+ } else {
681
+ resultSign = b.sign;
682
+ resultMagnitude = fp64_u64_sub(bMagnitude, aMagnitude);
683
+ }
684
+ }
685
+
686
+ return fp64_split_accumulator_bits(resultSign, resultMagnitude, commonBaseExponent);
687
+ }
688
+
689
+ fn fp64_two_sum_integer(a: f32, b: f32) -> vec2f {
690
+ let resultBits = fp64_two_sum_integer_bits(bitcast<u32>(a), bitcast<u32>(b));
691
+ return vec2f(bitcast<f32>(resultBits.x), bitcast<f32>(resultBits.y));
692
+ }
693
+
694
+ fn fp64_multiply_significands(a: u32, b: u32) -> vec2u {
695
+ let aLow = a & 0xffffu;
696
+ let aHigh = a >> 16u;
697
+ let bLow = b & 0xffffu;
698
+ let bHigh = b >> 16u;
699
+ let lowProduct = aLow * bLow;
700
+ let crossProduct = aLow * bHigh + aHigh * bLow;
701
+ let highProduct = aHigh * bHigh;
702
+
703
+ var result = vec2u(0u, lowProduct);
704
+ result = fp64_u64_add(
705
+ result,
706
+ fp64_u64_shift_left(vec2u(0u, crossProduct), 16u)
707
+ );
708
+ result = fp64_u64_add(result, vec2u(highProduct, 0u));
709
+ return result;
710
+ }
711
+
712
+ fn fp64_two_prod_integer_bits(aBits: u32, bBits: u32) -> vec2u {
713
+ let a = fp64_decode_f32_bits(aBits);
714
+ let b = fp64_decode_f32_bits(bBits);
715
+ let resultSign = a.sign ^ b.sign;
716
+
717
+ if (a.isNan || b.isNan || ((a.isZero || b.isZero) && (a.isInf || b.isInf))) {
718
+ return vec2u(0x7fc00000u, 0u);
719
+ }
720
+ if (a.isInf || b.isInf) {
721
+ return vec2u((resultSign << 31u) | 0x7f800000u, resultSign << 31u);
722
+ }
723
+ if (a.isZero || b.isZero) {
724
+ return vec2u(resultSign << 31u, resultSign << 31u);
725
+ }
726
+
727
+ let magnitude = fp64_multiply_significands(a.significand, b.significand);
728
+ return fp64_split_accumulator_bits(
729
+ resultSign,
730
+ magnitude,
731
+ a.baseExponent + b.baseExponent
732
+ );
733
+ }
734
+
735
+ fn fp64_two_prod_integer(a: f32, b: f32) -> vec2f {
736
+ let resultBits = fp64_two_prod_integer_bits(bitcast<u32>(a), bitcast<u32>(b));
737
+ return vec2f(bitcast<f32>(resultBits.x), bitcast<f32>(resultBits.y));
738
+ }
739
+
740
+ fn fp64_round_add_integer(a: f32, b: f32) -> f32 {
741
+ return fp64_two_sum_integer(a, b).x;
742
+ }
743
+
744
+ fn fp64_round_mul_integer(a: f32, b: f32) -> f32 {
745
+ return fp64_two_prod_integer(a, b).x;
746
+ }
747
+
748
+ #ifndef LUMA_FP64_PREDICATE_ONLY
749
+ fn fp64_f32_finite_exponent(value: Fp64F32Bits) -> i32 {
750
+ let mostSignificantBit = 31u - countLeadingZeros(value.significand);
751
+ return value.baseExponent + i32(mostSignificantBit);
752
+ }
753
+
754
+ fn fp64_scale_f32_integer(value: f32, exponent: i32) -> f32 {
755
+ let decoded = fp64_decode_f32_bits(bitcast<u32>(value));
756
+ if (decoded.isZero || decoded.isInf || decoded.isNan) {
757
+ return value;
758
+ }
759
+ let resultBits = fp64_make_f32_bits_from_u64(
760
+ decoded.sign,
761
+ vec2u(0u, decoded.significand),
762
+ decoded.baseExponent + exponent
763
+ );
764
+ return bitcast<f32>(resultBits);
765
+ }
766
+
767
+ // Divide normalized significands so the hardware operation cannot overflow,
768
+ // underflow, or flush a subnormal result. Reapply the exponent with integer
769
+ // packing, which also produces subnormal correction limbs without relying on
770
+ // floating-point arithmetic to preserve them.
771
+ fn fp64_divide_f32_integer(aValue: f32, bValue: f32) -> f32 {
772
+ let a = fp64_decode_f32_bits(bitcast<u32>(aValue));
773
+ let b = fp64_decode_f32_bits(bitcast<u32>(bValue));
774
+ if (a.isZero || b.isZero || a.isInf || b.isInf || a.isNan || b.isNan) {
775
+ return aValue / bValue;
776
+ }
777
+
778
+ let aMostSignificantBit = 31u - countLeadingZeros(a.significand);
779
+ let bMostSignificantBit = 31u - countLeadingZeros(b.significand);
780
+ let normalizedABits = fp64_make_f32_bits_from_u64(
781
+ a.sign,
782
+ vec2u(0u, a.significand),
783
+ -i32(aMostSignificantBit)
784
+ );
785
+ let normalizedBBits = fp64_make_f32_bits_from_u64(
786
+ b.sign,
787
+ vec2u(0u, b.significand),
788
+ -i32(bMostSignificantBit)
789
+ );
790
+ let normalizedQuotient = bitcast<f32>(normalizedABits) / bitcast<f32>(normalizedBBits);
791
+ let quotient = fp64_decode_f32_bits(bitcast<u32>(normalizedQuotient));
792
+ let exponentShift =
793
+ a.baseExponent + i32(aMostSignificantBit) -
794
+ b.baseExponent - i32(bMostSignificantBit);
795
+ let quotientBits = fp64_make_f32_bits_from_u64(
796
+ quotient.sign,
797
+ vec2u(0u, quotient.significand),
798
+ quotient.baseExponent + exponentShift
799
+ );
800
+ return bitcast<f32>(quotientBits);
801
+ }
802
+ #endif
803
+
804
+ #ifndef LUMA_FP64_PREDICATE_ONLY
805
+ fn split(a: f32) -> vec2f {
806
+ let aBits = bitcast<u32>(a);
807
+ let decoded = fp64_decode_f32_bits(aBits);
808
+ if (decoded.isZero || decoded.isInf || decoded.isNan) {
809
+ return vec2f(a, 0.0);
810
+ }
811
+
812
+ var roundedHigh = decoded.significand >> 12u;
813
+ let remainder = decoded.significand & 0xfffu;
814
+ if (remainder > 0x800u || (remainder == 0x800u && (roundedHigh & 1u) == 1u)) {
815
+ roundedHigh = roundedHigh + 1u;
816
+ }
817
+ var highMagnitude = vec2u(0u, roundedHigh << 12u);
818
+ var highBits = fp64_make_f32_bits_from_u64(
819
+ decoded.sign,
820
+ highMagnitude,
821
+ decoded.baseExponent
822
+ );
823
+ // Rounding the high limb of a maximum-exponent value can overflow even
824
+ // though the original value is finite. Truncate only in that boundary case
825
+ // so split remains an exact finite decomposition.
826
+ if (fp64_decode_f32_bits(highBits).isInf) {
827
+ roundedHigh = decoded.significand >> 12u;
828
+ highMagnitude = vec2u(0u, roundedHigh << 12u);
829
+ highBits = fp64_make_f32_bits_from_u64(
830
+ decoded.sign,
831
+ highMagnitude,
832
+ decoded.baseExponent
833
+ );
834
+ }
835
+ let lowBits = fp64_make_residual_f32_bits(
836
+ decoded.sign,
837
+ vec2u(0u, decoded.significand),
838
+ decoded.baseExponent,
839
+ highBits
840
+ );
841
+ return vec2f(bitcast<f32>(highBits), bitcast<f32>(lowBits));
842
+ }
843
+
844
+ fn split2(a: vec2f) -> vec2f {
845
+ var result = split(a.x);
846
+ result.y = fp64_round_add_integer(result.y, a.y);
847
+ return result;
848
+ }
849
+ #endif
850
+
851
+ #ifndef LUMA_FP64_PREDICATE_ONLY
852
+ fn quickTwoSum(a: f32, b: f32) -> vec2f {
853
+ return fp64_two_sum_integer(a, b);
854
+ }
855
+ #endif
856
+
857
+ fn twoSum(a: f32, b: f32) -> vec2f {
858
+ return fp64_two_sum_integer(a, b);
859
+ }
860
+
861
+ fn twoSub(a: f32, b: f32) -> vec2f {
862
+ let bBits = bitcast<u32>(b) ^ 0x80000000u;
863
+ let resultBits = fp64_two_sum_integer_bits(bitcast<u32>(a), bBits);
864
+ return vec2f(bitcast<f32>(resultBits.x), bitcast<f32>(resultBits.y));
865
+ }
866
+
867
+ #ifndef LUMA_FP64_PREDICATE_ONLY
868
+ fn twoSqr(a: f32) -> vec2f {
869
+ return fp64_two_prod_integer(a, a);
870
+ }
871
+
872
+ fn twoProd(a: f32, b: f32) -> vec2f {
873
+ return fp64_two_prod_integer(a, b);
874
+ }
875
+ #endif
876
+
877
+ fn sum_fp64(a: vec2f, b: vec2f) -> vec2f {
878
+ var sum = fp64_two_sum_integer(a.x, b.x);
879
+ let lowSum = fp64_two_sum_integer(a.y, b.y);
880
+ sum.y = fp64_round_add_integer(sum.y, lowSum.x);
881
+ sum = fp64_two_sum_integer(sum.x, sum.y);
882
+ sum.y = fp64_round_add_integer(sum.y, lowSum.y);
883
+ return fp64_two_sum_integer(sum.x, sum.y);
884
+ }
885
+
886
+ fn sub_fp64(a: vec2f, b: vec2f) -> vec2f {
887
+ let negatedB = vec2f(
888
+ bitcast<f32>(bitcast<u32>(b.x) ^ 0x80000000u),
889
+ bitcast<f32>(bitcast<u32>(b.y) ^ 0x80000000u)
890
+ );
891
+ return sum_fp64(a, negatedB);
892
+ }
893
+
894
+ fn mul_fp64(a: vec2f, b: vec2f) -> vec2f {
895
+ var product = fp64_two_prod_integer(a.x, b.x);
896
+ let crossProduct1 = fp64_round_mul_integer(a.x, b.y);
897
+ product.y = fp64_round_add_integer(product.y, crossProduct1);
898
+ product = fp64_two_sum_integer(product.x, product.y);
899
+ let crossProduct2 = fp64_round_mul_integer(a.y, b.x);
900
+ product.y = fp64_round_add_integer(product.y, crossProduct2);
901
+ return fp64_two_sum_integer(product.x, product.y);
902
+ }
903
+
904
+ #ifndef LUMA_FP64_PREDICATE_ONLY
905
+ fn fp64_scale_fp64_integer(value: vec2f, exponent: i32) -> vec2f {
906
+ let high = fp64_scale_f32_integer(value.x, exponent);
907
+ let low = fp64_scale_f32_integer(value.y, exponent);
908
+ return sum_fp64(vec2f(high, 0.0), vec2f(low, 0.0));
909
+ }
910
+
911
+ fn fp64_div_fp64_normalized(a: vec2f, b: vec2f) -> vec2f {
912
+ let quotientHigh = fp64_divide_f32_integer(a.x, b.x);
913
+ var quotient = vec2f(quotientHigh, 0.0);
914
+
915
+ let remainder = sub_fp64(a, mul_fp64(b, quotient));
916
+ let quotientLow = fp64_divide_f32_integer(remainder.x, b.x);
917
+ quotient = sum_fp64(quotient, vec2f(quotientLow, 0.0));
918
+
919
+ let secondRemainder = sub_fp64(a, mul_fp64(b, quotient));
920
+ let correction = fp64_divide_f32_integer(secondRemainder.x, b.x);
921
+ return sum_fp64(quotient, vec2f(correction, 0.0));
922
+ }
923
+
924
+ fn div_fp64(a: vec2f, b: vec2f) -> vec2f {
925
+ let decodedA = fp64_decode_f32_bits(bitcast<u32>(a.x));
926
+ let decodedB = fp64_decode_f32_bits(bitcast<u32>(b.x));
927
+ if (
928
+ decodedA.isZero || decodedB.isZero ||
929
+ decodedA.isInf || decodedB.isInf ||
930
+ decodedA.isNan || decodedB.isNan
931
+ ) {
932
+ return fp64_div_fp64_normalized(a, b);
933
+ }
934
+
935
+ let exponentA = fp64_f32_finite_exponent(decodedA);
936
+ let exponentB = fp64_f32_finite_exponent(decodedB);
937
+ // Correct the quotient near unity so b * q and the remainder stay clear of
938
+ // both f32 underflow and overflow. The exponent difference is applied once.
939
+ let normalizedA = fp64_scale_fp64_integer(a, -exponentA);
940
+ let normalizedB = fp64_scale_fp64_integer(b, -exponentB);
941
+ let normalizedQuotient = fp64_div_fp64_normalized(normalizedA, normalizedB);
942
+ return fp64_scale_fp64_integer(normalizedQuotient, exponentA - exponentB);
943
+ }
944
+
945
+ fn fp64_sqrt_fp64_normalized(a: vec2f) -> vec2f {
946
+ let estimate = sqrt(a.x);
947
+ let difference = sub_fp64(a, fp64_two_prod_integer(estimate, estimate)).x;
948
+ let denominator = fp64_round_add_integer(estimate, estimate);
949
+ let correction = fp64_divide_f32_integer(difference, denominator);
950
+ return sum_fp64(vec2f(estimate, 0.0), vec2f(correction, 0.0));
951
+ }
952
+
953
+ fn sqrt_fp64(a: vec2f) -> vec2f {
954
+ let decoded = fp64_decode_f32_bits(bitcast<u32>(a.x));
955
+ let decodedLow = fp64_decode_f32_bits(bitcast<u32>(a.y));
956
+ if (decoded.isZero && decodedLow.isZero) {
957
+ return vec2f(0.0, 0.0);
958
+ }
959
+ if (decoded.sign == 1u) {
960
+ let nanValue = fp64_nan(a.x);
961
+ return vec2f(nanValue, nanValue);
962
+ }
963
+
964
+ if (decoded.isInf || decoded.isNan) {
965
+ return fp64_sqrt_fp64_normalized(a);
966
+ }
967
+ let exponent = fp64_f32_finite_exponent(decoded);
968
+ // An even scale lets the final square-root rescale use an integer exponent.
969
+ let evenExponent = exponent - (exponent & 1);
970
+ let normalizedA = fp64_scale_fp64_integer(a, -evenExponent);
971
+ let normalizedRoot = fp64_sqrt_fp64_normalized(normalizedA);
972
+ return fp64_scale_fp64_integer(normalizedRoot, evenExponent / 2);
973
+ }
974
+ #endif
975
+ `;var wt=`struct Fp64ArithmeticUniforms {
526
976
  ONE: f32,
527
977
  SPLIT: f32,
528
978
  };
529
979
 
530
980
  @group(0) @binding(auto) var<uniform> fp64arithmetic : Fp64ArithmeticUniforms;
531
981
 
982
+ #ifndef LUMA_FP64_F32_INPUT_ONLY
532
983
  struct Fp64Bits {
533
984
  sign: u32,
534
985
  exponent: i32,
@@ -537,11 +988,14 @@ struct Fp64Bits {
537
988
  isInf: bool,
538
989
  isNan: bool,
539
990
  };
991
+ #endif
540
992
 
993
+ #ifndef LUMA_FP64_PREDICATE_ONLY
541
994
  fn fp64_nan(seed: f32) -> f32 {
542
995
  let nanBits = 0x7fc00000u | select(0u, 1u, seed < 0.0);
543
996
  return bitcast<f32>(nanBits);
544
997
  }
998
+ #endif
545
999
 
546
1000
  fn fp64_u64_is_zero(value: vec2u) -> bool {
547
1001
  return value.x == 0u && value.y == 0u;
@@ -629,6 +1083,7 @@ fn fp64_u64_has_bits_below(value: vec2u, bitCount: u32) -> bool {
629
1083
  return (value.y & lowMask) != 0u;
630
1084
  }
631
1085
 
1086
+ #ifndef LUMA_FP64_F32_INPUT_ONLY
632
1087
  fn fp64_u64_shift_right_sticky(value: vec2u, shift: u32) -> vec2u {
633
1088
  var shifted = fp64_u64_shift_right(value, shift);
634
1089
  if (fp64_u64_has_bits_below(value, shift)) {
@@ -636,6 +1091,7 @@ fn fp64_u64_shift_right_sticky(value: vec2u, shift: u32) -> vec2u {
636
1091
  }
637
1092
  return shifted;
638
1093
  }
1094
+ #endif
639
1095
 
640
1096
  fn fp64_u64_count_leading_zeros(value: vec2u) -> u32 {
641
1097
  if (value.x != 0u) {
@@ -659,6 +1115,22 @@ fn fp64_round_shift_right_to_u32(value: vec2u, shift: u32) -> u32 {
659
1115
  return rounded;
660
1116
  }
661
1117
 
1118
+ #ifndef LUMA_FP64_F32_INPUT_ONLY
1119
+ fn fp64_round_shift_right(value: vec2u, shift: u32) -> vec2u {
1120
+ if (shift == 0u) {
1121
+ return value;
1122
+ }
1123
+
1124
+ var rounded = fp64_u64_shift_right(value, shift);
1125
+ let guard = fp64_u64_get_bit(value, shift - 1u);
1126
+ let hasTrailingBits = fp64_u64_has_bits_below(value, shift - 1u);
1127
+ if (guard && (hasTrailingBits || (rounded.y & 1u) == 1u)) {
1128
+ rounded = fp64_u64_add(rounded, vec2u(0u, 1u));
1129
+ }
1130
+ return rounded;
1131
+ }
1132
+ #endif
1133
+
662
1134
  fn fp64_make_f32_bits_from_u64(sign: u32, significand: vec2u, baseExponent: i32) -> u32 {
663
1135
  if (fp64_u64_is_zero(significand)) {
664
1136
  return sign << 31u;
@@ -706,6 +1178,7 @@ fn fp64_make_f32_bits_from_u64(sign: u32, significand: vec2u, baseExponent: i32)
706
1178
  return (sign << 31u) | mantissa;
707
1179
  }
708
1180
 
1181
+ #ifndef LUMA_FP64_F32_INPUT_ONLY
709
1182
  fn fp64_decode_bits(bits: vec2u) -> Fp64Bits {
710
1183
  let sign = bits.x >> 31u;
711
1184
  let exponentBits = (bits.x >> 20u) & 0x7ffu;
@@ -732,6 +1205,261 @@ fn fp64_finite_magnitude_compare(a: Fp64Bits, b: Fp64Bits) -> i32 {
732
1205
  }
733
1206
  return fp64_u64_compare(a.significand, b.significand);
734
1207
  }
1208
+ #endif
1209
+
1210
+ #ifndef LUMA_FP64_F32_INPUT_ONLY
1211
+ struct Fp64RawF32Bits {
1212
+ sign: u32,
1213
+ baseExponent: i32,
1214
+ significand: u32,
1215
+ isZero: bool,
1216
+ isInf: bool,
1217
+ isNan: bool,
1218
+ };
1219
+
1220
+ // Decode an f32 as (-1)^sign * significand * 2^baseExponent. This shared
1221
+ // integer representation lets normalization remain independent of the
1222
+ // selected double-single arithmetic implementation.
1223
+ fn fp64_decode_raw_f32_bits(bits: u32) -> Fp64RawF32Bits {
1224
+ let sign = bits >> 31u;
1225
+ let exponentBits = (bits >> 23u) & 0xffu;
1226
+ let fraction = bits & 0x7fffffu;
1227
+
1228
+ if (exponentBits == 0xffu) {
1229
+ return Fp64RawF32Bits(sign, 0, 0u, false, fraction == 0u, fraction != 0u);
1230
+ }
1231
+ if (exponentBits == 0u) {
1232
+ return Fp64RawF32Bits(sign, -149, fraction, fraction == 0u, false, false);
1233
+ }
1234
+ return Fp64RawF32Bits(
1235
+ sign,
1236
+ i32(exponentBits) - 150,
1237
+ 0x800000u | fraction,
1238
+ false,
1239
+ false,
1240
+ false
1241
+ );
1242
+ }
1243
+
1244
+ fn fp64_raw_f32_magnitude_compare(aBits: u32, bBits: u32) -> i32 {
1245
+ let aMagnitude = aBits & 0x7fffffffu;
1246
+ let bMagnitude = bBits & 0x7fffffffu;
1247
+ if (aMagnitude == bMagnitude) {
1248
+ return 0;
1249
+ }
1250
+ return select(-1, 1, aMagnitude > bMagnitude);
1251
+ }
1252
+
1253
+ fn fp64_make_raw_residual_f32_bits(
1254
+ exactSign: u32,
1255
+ exactMagnitude: vec2u,
1256
+ exactBaseExponent: i32,
1257
+ highBits: u32
1258
+ ) -> u32 {
1259
+ if (fp64_u64_is_zero(exactMagnitude)) {
1260
+ return 0u;
1261
+ }
1262
+
1263
+ let high = fp64_decode_raw_f32_bits(highBits);
1264
+ if (high.isInf || high.isNan) {
1265
+ return 0u;
1266
+ }
1267
+ if (high.isZero) {
1268
+ return fp64_make_f32_bits_from_u64(exactSign, exactMagnitude, exactBaseExponent);
1269
+ }
1270
+
1271
+ let commonBaseExponent = min(exactBaseExponent, high.baseExponent);
1272
+ let exactShift = exactBaseExponent - commonBaseExponent;
1273
+ let highShift = high.baseExponent - commonBaseExponent;
1274
+ if (exactShift >= 64 || highShift >= 64) {
1275
+ return 0u;
1276
+ }
1277
+
1278
+ let exactAligned = fp64_u64_shift_left(exactMagnitude, u32(exactShift));
1279
+ let highAligned = fp64_u64_shift_left(vec2u(0u, high.significand), u32(highShift));
1280
+ let comparison = fp64_u64_compare(exactAligned, highAligned);
1281
+ if (comparison == 0) {
1282
+ return 0u;
1283
+ }
1284
+
1285
+ var residualSign = exactSign;
1286
+ var residualMagnitude: vec2u;
1287
+ if (comparison > 0) {
1288
+ residualMagnitude = fp64_u64_sub(exactAligned, highAligned);
1289
+ } else {
1290
+ residualSign = exactSign ^ 1u;
1291
+ residualMagnitude = fp64_u64_sub(highAligned, exactAligned);
1292
+ }
1293
+ return fp64_make_f32_bits_from_u64(
1294
+ residualSign,
1295
+ residualMagnitude,
1296
+ commonBaseExponent
1297
+ );
1298
+ }
1299
+
1300
+ fn fp64_split_raw_accumulator_bits(
1301
+ sign: u32,
1302
+ magnitude: vec2u,
1303
+ baseExponent: i32
1304
+ ) -> vec2u {
1305
+ if (fp64_u64_is_zero(magnitude)) {
1306
+ return vec2u(0u);
1307
+ }
1308
+ let highBits = fp64_make_f32_bits_from_u64(sign, magnitude, baseExponent);
1309
+ let rawLowBits = fp64_make_raw_residual_f32_bits(sign, magnitude, baseExponent, highBits);
1310
+ let lowBits = select(rawLowBits, 0u, (rawLowBits & 0x7fffffffu) == 0u);
1311
+ if ((highBits & 0x7fffffffu) == 0u && (lowBits & 0x7fffffffu) == 0u) {
1312
+ return vec2u(0u);
1313
+ }
1314
+ return vec2u(highBits, lowBits);
1315
+ }
1316
+ #endif
1317
+
1318
+ #ifndef LUMA_FP64_F32_INPUT_ONLY
1319
+ // Round an arithmetic accumulator to binary64 before splitting it. The
1320
+ // aligned add/subtract paths retain three guard bits plus a sticky bit, which
1321
+ // is sufficient for round-to-nearest-even at the binary64 boundary.
1322
+ fn fp64_split_binary64_accumulator_bits(
1323
+ sign: u32,
1324
+ magnitude: vec2u,
1325
+ baseExponent: i32
1326
+ ) -> vec2u {
1327
+ if (fp64_u64_is_zero(magnitude)) {
1328
+ return vec2u(0u);
1329
+ }
1330
+
1331
+ let mostSignificantBit = 63u - fp64_u64_count_leading_zeros(magnitude);
1332
+ let exponent = baseExponent + i32(mostSignificantBit);
1333
+ if (exponent > 1023) {
1334
+ return vec2u((sign << 31u) | 0x7f800000u, 0u);
1335
+ }
1336
+
1337
+ var roundedMagnitude = magnitude;
1338
+ var roundedBaseExponent = baseExponent;
1339
+ if (exponent >= -1022) {
1340
+ if (mostSignificantBit > 52u) {
1341
+ let shift = mostSignificantBit - 52u;
1342
+ roundedMagnitude = fp64_round_shift_right(magnitude, shift);
1343
+ roundedBaseExponent = baseExponent + i32(shift);
1344
+ }
1345
+ } else {
1346
+ let shift = -1074 - baseExponent;
1347
+ if (shift > 0) {
1348
+ roundedMagnitude = fp64_round_shift_right(magnitude, u32(shift));
1349
+ roundedBaseExponent = -1074;
1350
+ }
1351
+ }
1352
+
1353
+ if (fp64_u64_is_zero(roundedMagnitude)) {
1354
+ return vec2u(0u);
1355
+ }
1356
+ return fp64_split_raw_accumulator_bits(sign, roundedMagnitude, roundedBaseExponent);
1357
+ }
1358
+ #endif
1359
+
1360
+ #ifndef LUMA_FP64_PREDICATE_ONLY
1361
+ fn fp64_add_raw_f32_bits(aBits: u32, bBits: u32) -> vec2u {
1362
+ let a = fp64_decode_raw_f32_bits(aBits);
1363
+ let b = fp64_decode_raw_f32_bits(bBits);
1364
+
1365
+ if (a.isNan || b.isNan) {
1366
+ return vec2u(0x7fc00000u, 0u);
1367
+ }
1368
+ if (a.isInf || b.isInf) {
1369
+ if (a.isInf && b.isInf && a.sign != b.sign) {
1370
+ return vec2u(0x7fc00000u, 0u);
1371
+ }
1372
+ return select(vec2u(bBits, 0u), vec2u(aBits, 0u), a.isInf);
1373
+ }
1374
+ if (a.isZero && b.isZero) {
1375
+ return vec2u(0u);
1376
+ }
1377
+ if (a.isZero) {
1378
+ return vec2u(bBits, 0u);
1379
+ }
1380
+ if (b.isZero) {
1381
+ return vec2u(aBits, 0u);
1382
+ }
1383
+
1384
+ let exponentDifference = abs(a.baseExponent - b.baseExponent);
1385
+ if (exponentDifference > 25) {
1386
+ if (fp64_raw_f32_magnitude_compare(aBits, bBits) >= 0) {
1387
+ return vec2u(aBits, bBits);
1388
+ }
1389
+ return vec2u(bBits, aBits);
1390
+ }
1391
+
1392
+ let commonBaseExponent = min(a.baseExponent, b.baseExponent);
1393
+ let aMagnitude = fp64_u64_shift_left(
1394
+ vec2u(0u, a.significand),
1395
+ u32(a.baseExponent - commonBaseExponent)
1396
+ );
1397
+ let bMagnitude = fp64_u64_shift_left(
1398
+ vec2u(0u, b.significand),
1399
+ u32(b.baseExponent - commonBaseExponent)
1400
+ );
1401
+
1402
+ var resultSign = a.sign;
1403
+ var resultMagnitude: vec2u;
1404
+ if (a.sign == b.sign) {
1405
+ resultMagnitude = fp64_u64_add(aMagnitude, bMagnitude);
1406
+ } else {
1407
+ let comparison = fp64_u64_compare(aMagnitude, bMagnitude);
1408
+ if (comparison == 0) {
1409
+ return vec2u(0u);
1410
+ }
1411
+ if (comparison > 0) {
1412
+ resultMagnitude = fp64_u64_sub(aMagnitude, bMagnitude);
1413
+ } else {
1414
+ resultSign = b.sign;
1415
+ resultMagnitude = fp64_u64_sub(bMagnitude, aMagnitude);
1416
+ }
1417
+ }
1418
+
1419
+ return fp64_split_raw_accumulator_bits(
1420
+ resultSign,
1421
+ resultMagnitude,
1422
+ commonBaseExponent
1423
+ );
1424
+ }
1425
+ #endif
1426
+
1427
+ #ifndef LUMA_FP64_F32_INPUT_ONLY
1428
+ fn fp64_add_aligned_magnitudes_to_fp64_bits(
1429
+ sign: u32,
1430
+ larger: Fp64Bits,
1431
+ smaller: Fp64Bits
1432
+ ) -> vec2u {
1433
+ let largeSignificand = fp64_u64_shift_left(larger.significand, 3u);
1434
+ let smallSignificand = fp64_u64_shift_right_sticky(
1435
+ fp64_u64_shift_left(smaller.significand, 3u),
1436
+ u32(larger.exponent - smaller.exponent)
1437
+ );
1438
+ let resultSignificand = fp64_u64_add(largeSignificand, smallSignificand);
1439
+ return fp64_split_binary64_accumulator_bits(
1440
+ sign,
1441
+ resultSignificand,
1442
+ larger.exponent - 55
1443
+ );
1444
+ }
1445
+
1446
+ fn fp64_sub_aligned_magnitudes_to_fp64_bits(
1447
+ sign: u32,
1448
+ larger: Fp64Bits,
1449
+ smaller: Fp64Bits
1450
+ ) -> vec2u {
1451
+ let largeSignificand = fp64_u64_shift_left(larger.significand, 3u);
1452
+ let smallSignificand = fp64_u64_shift_right_sticky(
1453
+ fp64_u64_shift_left(smaller.significand, 3u),
1454
+ u32(larger.exponent - smaller.exponent)
1455
+ );
1456
+ let resultSignificand = fp64_u64_sub(largeSignificand, smallSignificand);
1457
+ return fp64_split_binary64_accumulator_bits(
1458
+ sign,
1459
+ resultSignificand,
1460
+ larger.exponent - 55
1461
+ );
1462
+ }
735
1463
 
736
1464
  fn fp64_add_aligned_magnitudes_to_f32_bits(sign: u32, larger: Fp64Bits, smaller: Fp64Bits) -> u32 {
737
1465
  let largeSignificand = fp64_u64_shift_left(larger.significand, 3u);
@@ -801,6 +1529,58 @@ fn sub_fp64u32_to_f32(aBits: vec2u, bBits: vec2u) -> f32 {
801
1529
  return bitcast<f32>(sub_fp64u32_to_f32_bits(aBits, bBits));
802
1530
  }
803
1531
 
1532
+ // Subtract two raw binary64 values, round once to binary64, then split the
1533
+ // result into normalized f32 limbs. Finite results must fit within the f32
1534
+ // exponent range; larger magnitudes map to infinity and smaller magnitudes
1535
+ // map to zero. The input words use canonical high/low word order.
1536
+ fn sub_fp64u32_to_fp64_bits(aBits: vec2u, bBits: vec2u) -> vec2u {
1537
+ let a = fp64_decode_bits(aBits);
1538
+ let b = fp64_decode_bits(bBits);
1539
+ let bSubtractionSign = b.sign ^ 1u;
1540
+
1541
+ if (a.isNan || b.isNan) {
1542
+ return vec2u(0x7fc00000u, 0u);
1543
+ }
1544
+ if (a.isInf && b.isInf) {
1545
+ if (a.sign == bSubtractionSign) {
1546
+ return vec2u((a.sign << 31u) | 0x7f800000u, 0u);
1547
+ }
1548
+ return vec2u(0x7fc00000u, 0u);
1549
+ }
1550
+ if (a.isInf) {
1551
+ return vec2u((a.sign << 31u) | 0x7f800000u, 0u);
1552
+ }
1553
+ if (b.isInf) {
1554
+ return vec2u((bSubtractionSign << 31u) | 0x7f800000u, 0u);
1555
+ }
1556
+ if (a.isZero && b.isZero) {
1557
+ return vec2u(0u);
1558
+ }
1559
+
1560
+ let magnitudeComparison = fp64_finite_magnitude_compare(a, b);
1561
+ if (a.sign == bSubtractionSign) {
1562
+ if (magnitudeComparison >= 0) {
1563
+ return fp64_add_aligned_magnitudes_to_fp64_bits(a.sign, a, b);
1564
+ }
1565
+ return fp64_add_aligned_magnitudes_to_fp64_bits(a.sign, b, a);
1566
+ }
1567
+
1568
+ if (magnitudeComparison == 0) {
1569
+ return vec2u(0u);
1570
+ }
1571
+ if (magnitudeComparison > 0) {
1572
+ return fp64_sub_aligned_magnitudes_to_fp64_bits(a.sign, a, b);
1573
+ }
1574
+ return fp64_sub_aligned_magnitudes_to_fp64_bits(bSubtractionSign, b, a);
1575
+ }
1576
+
1577
+ fn sub_fp64u32_to_fp64(aBits: vec2u, bBits: vec2u) -> vec2f {
1578
+ let resultBits = sub_fp64u32_to_fp64_bits(aBits, bBits);
1579
+ return vec2f(bitcast<f32>(resultBits.x), bitcast<f32>(resultBits.y));
1580
+ }
1581
+ #endif
1582
+
1583
+ #ifndef LUMA_FP64_PREDICATE_ONLY
804
1584
  fn fp64_runtime_zero() -> f32 {
805
1585
  return fp64arithmetic.ONE * 0.0;
806
1586
  }
@@ -812,7 +1592,11 @@ fn prevent_fp64_optimization(value: f32) -> f32 {
812
1592
  return value;
813
1593
  #endif
814
1594
  }
1595
+ #endif
815
1596
 
1597
+ #ifdef LUMA_FP64_INTEGER_ARITHMETIC
1598
+ ${Bt}
1599
+ #else
816
1600
  fn split(a: f32) -> vec2f {
817
1601
  let splitValue = prevent_fp64_optimization(fp64arithmetic.SPLIT + fp64_runtime_zero());
818
1602
  let t = prevent_fp64_optimization(a * splitValue);
@@ -963,6 +1747,7 @@ fn mul_fp64(a: vec2f, b: vec2f) -> vec2f {
963
1747
  return prod;
964
1748
  }
965
1749
 
1750
+ #ifndef LUMA_FP64_PREDICATE_ONLY
966
1751
  fn div_fp64(a: vec2f, b: vec2f) -> vec2f {
967
1752
  let xn = prevent_fp64_optimization(1.0 / b.x);
968
1753
  let yn = mul_fp64(a, vec2f(xn, fp64_runtime_zero()));
@@ -995,7 +1780,98 @@ fn sqrt_fp64(a: vec2f) -> vec2f {
995
1780
  return sum_fp64(vec2f(yn, 0.0), prod);
996
1781
  #endif
997
1782
  }
998
- `;var ft=`const vec2 E_FP64 = vec2(2.7182817459106445e+00, 8.254840366817007e-08);
1783
+ #endif
1784
+ #endif
1785
+
1786
+ #ifndef LUMA_FP64_PREDICATE_ONLY
1787
+ fn fp64_f32_bits_is_nan(bits: u32) -> bool {
1788
+ return (bits & 0x7fffffffu) > 0x7f800000u;
1789
+ }
1790
+
1791
+ fn fp64_f32_bits_is_inf(bits: u32) -> bool {
1792
+ return (bits & 0x7fffffffu) == 0x7f800000u;
1793
+ }
1794
+
1795
+ fn fp64_compare_f32_bits(aBits: u32, bBits: u32) -> i32 {
1796
+ let aMagnitude = aBits & 0x7fffffffu;
1797
+ let bMagnitude = bBits & 0x7fffffffu;
1798
+ if (aMagnitude == 0u && bMagnitude == 0u) {
1799
+ return 0;
1800
+ }
1801
+ let aSign = aBits >> 31u;
1802
+ let bSign = bBits >> 31u;
1803
+ if (aSign != bSign) {
1804
+ return select(1, -1, aSign == 1u);
1805
+ }
1806
+ if (aMagnitude == bMagnitude) {
1807
+ return 0;
1808
+ }
1809
+ let magnitudeComparison = select(-1, 1, aMagnitude > bMagnitude);
1810
+ return select(magnitudeComparison, -magnitudeComparison, aSign == 1u);
1811
+ }
1812
+
1813
+ // Normalize an arbitrary pair of finite f32 limbs with integer accumulation.
1814
+ // This is independent of LUMA_FP64_INTEGER_ARITHMETIC and canonicalizes every
1815
+ // representation of zero to vec2f(+0.0, +0.0).
1816
+ fn normalize_fp64(value: vec2f) -> vec2f {
1817
+ let resultBits = fp64_add_raw_f32_bits(bitcast<u32>(value.x), bitcast<u32>(value.y));
1818
+ return vec2f(bitcast<f32>(resultBits.x), bitcast<f32>(resultBits.y));
1819
+ }
1820
+
1821
+ fn is_nan_fp64(value: vec2f) -> bool {
1822
+ let normalized = normalize_fp64(value);
1823
+ return fp64_f32_bits_is_nan(bitcast<u32>(normalized.x)) ||
1824
+ fp64_f32_bits_is_nan(bitcast<u32>(normalized.y));
1825
+ }
1826
+
1827
+ fn is_finite_fp64(value: vec2f) -> bool {
1828
+ let normalized = normalize_fp64(value);
1829
+ let highBits = bitcast<u32>(normalized.x);
1830
+ let lowBits = bitcast<u32>(normalized.y);
1831
+ return !fp64_f32_bits_is_nan(highBits) && !fp64_f32_bits_is_nan(lowBits) &&
1832
+ !fp64_f32_bits_is_inf(highBits) && !fp64_f32_bits_is_inf(lowBits);
1833
+ }
1834
+
1835
+ // Returns -1, 0, or 1. NaN is unordered and returns 0; call is_nan_fp64 or
1836
+ // is_finite_fp64 first when 0 must mean a finite zero.
1837
+ fn sign_fp64(value: vec2f) -> i32 {
1838
+ let normalized = normalize_fp64(value);
1839
+ let highBits = bitcast<u32>(normalized.x);
1840
+ let lowBits = bitcast<u32>(normalized.y);
1841
+ if (fp64_f32_bits_is_nan(highBits) || fp64_f32_bits_is_nan(lowBits)) {
1842
+ return 0;
1843
+ }
1844
+ if ((highBits & 0x7fffffffu) != 0u) {
1845
+ return select(1, -1, (highBits >> 31u) == 1u);
1846
+ }
1847
+ if ((lowBits & 0x7fffffffu) != 0u) {
1848
+ return select(1, -1, (lowBits >> 31u) == 1u);
1849
+ }
1850
+ return 0;
1851
+ }
1852
+
1853
+ // Compares double-single values and returns -1, 0, or 1. NaN is unordered
1854
+ // and returns 0; callers that require equality semantics must first check
1855
+ // is_nan_fp64 or is_finite_fp64.
1856
+ fn compare_fp64(a: vec2f, b: vec2f) -> i32 {
1857
+ let normalizedA = normalize_fp64(a);
1858
+ let normalizedB = normalize_fp64(b);
1859
+ let aHighBits = bitcast<u32>(normalizedA.x);
1860
+ let aLowBits = bitcast<u32>(normalizedA.y);
1861
+ let bHighBits = bitcast<u32>(normalizedB.x);
1862
+ let bLowBits = bitcast<u32>(normalizedB.y);
1863
+ if (fp64_f32_bits_is_nan(aHighBits) || fp64_f32_bits_is_nan(aLowBits) ||
1864
+ fp64_f32_bits_is_nan(bHighBits) || fp64_f32_bits_is_nan(bLowBits)) {
1865
+ return 0;
1866
+ }
1867
+ let highComparison = fp64_compare_f32_bits(aHighBits, bHighBits);
1868
+ if (highComparison != 0) {
1869
+ return highComparison;
1870
+ }
1871
+ return fp64_compare_f32_bits(aLowBits, bLowBits);
1872
+ }
1873
+ #endif
1874
+ `;var It=`const vec2 E_FP64 = vec2(2.7182817459106445e+00, 8.254840366817007e-08);
999
1875
  const vec2 LOG2_FP64 = vec2(0.6931471824645996e+00, -1.9046542121259336e-09);
1000
1876
  const vec2 PI_FP64 = vec2(3.1415927410125732, -8.742278012618954e-8);
1001
1877
  const vec2 TWO_PI_FP64 = vec2(6.2831854820251465, -1.7484556025237907e-7);
@@ -1664,7 +2540,7 @@ void mat4_vec4_mul_fp64(vec2 b[16], vec2 a[4], out vec2 out_val[4]) {
1664
2540
  vec4_dot_fp64(a, tmp, out_val[i]);
1665
2541
  }
1666
2542
  }
1667
- `;var sr={ONE:1,SPLIT:4097},ct={name:"fp64arithmetic",source:lt,fs:be,vs:be,defaultUniforms:sr,uniformTypes:{ONE:"f32",SPLIT:"f32"},fp64ify:te,fp64LowPart:xe,fp64ifyMatrix4:ye},ie={name:"fp64",vs:ft,dependencies:[ct],fp64ify:te,fp64LowPart:xe,fp64ifyMatrix4:ye};var re=d(_(),1);var ut=`const vec2 WORLD_SCALE_FP64 = vec2(81.4873275756836, 0.0000032873668232014097);
2543
+ `;var mn={ONE:1,SPLIT:4097},Ct={name:"fp64arithmetic",source:wt,fs:Ie,vs:Ie,defaultUniforms:mn,uniformTypes:{ONE:"f32",SPLIT:"f32"},fp64ify:_e,fp64LowPart:Be,fp64ifyMatrix4:we},he={name:"fp64",vs:It,dependencies:[Ct],fp64ify:_e,fp64LowPart:Be,fp64ifyMatrix4:we};var me=_(h(),1);var Rt=`const vec2 WORLD_SCALE_FP64 = vec2(81.4873275756836, 0.0000032873668232014097);
1668
2544
  layout(std140) uniform project64Uniforms {
1669
2545
  vec2 scale;
1670
2546
  mat4 viewProjectionMatrix;
@@ -1737,59 +2613,154 @@ return project_position_to_clipspace(
1737
2613
  position, position64xyLow, offset, commonPosition
1738
2614
  );
1739
2615
  }
1740
- `;var{fp64ify:nr,fp64ifyMatrix4:ar}=ie,oe={name:"project64",dependencies:[re.project,ie],vs:ut,getUniforms:fr,uniformTypes:{scale:"vec2<f32>",viewProjectionMatrix:"mat4x4<f32>",viewProjectionMatrix64Low:"mat4x4<f32>"}},lr=(0,re._memoize)(cr);function fr(i){if(i&&"viewport"in i){let{viewProjectionMatrix:e,scale:t}=i.viewport;return lr({viewProjectionMatrix:e,scale:t})}return{}}function cr({viewProjectionMatrix:i,scale:e}){let t=ar(i),r=new Float32Array(16),o=new Float32Array(16);for(let s=0;s<4;s++)for(let n=0;n<4;n++){let a=4*s+n,l=4*n+s;r[l]=t[2*a],o[l]=t[2*a+1]}return{scale:nr(e),viewProjectionMatrix:[...r],viewProjectionMatrix64Low:[...o]}}var se=class extends pt.LayerExtension{getShaders(){let{coordinateSystem:e}=this.props;if(e!=="lnglat"&&e!=="default")throw new Error("fp64: coordinateSystem must be LNGLAT");return{modules:[oe]}}draw(e,t){let{viewport:r}=e.context;this.setShaderModuleProps({project64:{viewport:r}})}};se.extensionName="Fp64Extension";var dt=se;var w=d(_(),1);var _t={inject:{"vs:#decl":`
2616
+ `;var{fp64ify:gn,fp64ifyMatrix4:vn}=he,ge={name:"project64",dependencies:[me.project,he],vs:Rt,getUniforms:bn,uniformTypes:{scale:"vec2<f32>",viewProjectionMatrix:"mat4x4<f32>",viewProjectionMatrix64Low:"mat4x4<f32>"}},xn=(0,me._memoize)(yn);function bn(t){if(t&&"viewport"in t){let{viewProjectionMatrix:e,scale:i}=t.viewport;return xn({viewProjectionMatrix:e,scale:i})}return{}}function yn({viewProjectionMatrix:t,scale:e}){let i=vn(t),r=new Float32Array(16),n=new Float32Array(16);for(let o=0;o<4;o++)for(let a=0;a<4;a++){let s=4*o+a,l=4*a+o;r[l]=i[2*s],n[l]=i[2*s+1]}return{scale:gn(e),viewProjectionMatrix:[...r],viewProjectionMatrix64Low:[...n]}}var ve=class extends kt.LayerExtension{getShaders(){let{coordinateSystem:e}=this.props;if(e!=="lnglat"&&e!=="default")throw new Error("fp64: coordinateSystem must be LNGLAT");return{modules:[ge]}}draw(e,i){let{viewport:r}=e.context;this.setShaderModuleProps({project64:{viewport:r}})}};ve.extensionName="Fp64Extension";var Nt=ve;var b=_(h(),1);var Dt={inject:{"vs:#decl":`
1741
2617
  in vec2 instanceDashArrays;
1742
2618
  #ifdef HIGH_PRECISION_DASH
1743
- in float instanceDashOffsets;
2619
+ in vec2 instanceDashOffsets;
1744
2620
  #endif
1745
2621
  out vec2 vDashArray;
1746
2622
  out float vDashOffset;
2623
+ out float vDashPathLength;
2624
+ layout(std140) uniform pathStyleUniforms {
2625
+ float dashAlignMode;
2626
+ bool dashGapPickable;
2627
+ highp int dashUnits;
2628
+ } pathStyle;
1747
2629
  `,"vs:#main-end":`
1748
- vDashArray = instanceDashArrays;
2630
+ float dashWidthPixels = path.billboard
2631
+ ? width.x * project.focalDistance
2632
+ : width.x * project.scale;
2633
+ float strokeHalfWidthPixels = path.billboard ? width.x : width.x * project.scale;
2634
+ float dashUnitPixels = strokeHalfWidthPixels;
2635
+ if (pathStyle.dashUnits == 1) {
2636
+ dashUnitPixels = 1.0;
2637
+ } else if (pathStyle.dashUnits == 2) {
2638
+ dashUnitPixels = project_size_to_pixel(1.0);
2639
+ } else if (pathStyle.dashUnits == 3) {
2640
+ dashUnitPixels = project.scale;
2641
+ }
2642
+ vDashArray = instanceDashArrays * (dashUnitPixels / dashWidthPixels);
1749
2643
  #ifdef HIGH_PRECISION_DASH
1750
- vDashOffset = instanceDashOffsets / width.x;
2644
+ vec2 dashOffsetAndLength = (instanceDashOffsets * project.scale) / dashWidthPixels;
2645
+ vDashPathLength = dashOffsetAndLength.y;
2646
+ float dashUnitLength = vDashArray.x + vDashArray.y;
2647
+ float dashPeriod = pathStyle.dashAlignMode == 0.0
2648
+ ? dashUnitLength
2649
+ : vDashPathLength / max(round(vDashPathLength / max(dashUnitLength, 0.0001)), 1.0);
2650
+ vDashOffset = dashPeriod > 0.0 ? mod(dashOffsetAndLength.x, dashPeriod) : 0.0;
1751
2651
  #else
1752
2652
  vDashOffset = 0.0;
2653
+ vDashPathLength = 0.0;
1753
2654
  #endif
1754
2655
  `,"fs:#decl":`
1755
2656
  layout(std140) uniform pathStyleUniforms {
1756
2657
  float dashAlignMode;
1757
2658
  bool dashGapPickable;
2659
+ highp int dashUnits;
1758
2660
  } pathStyle;
1759
2661
  in vec2 vDashArray;
1760
2662
  in float vDashOffset;
2663
+ in float vDashPathLength;
2664
+ float dashPatternIntegral(float position, float solidLength, float unitLength) {
2665
+ return floor(position / unitLength) * solidLength +
2666
+ min(mod(position, unitLength), solidLength);
2667
+ }
2668
+ float dashPatternCoverage(
2669
+ float position,
2670
+ float solidLength,
2671
+ float unitLength,
2672
+ float filterWidth
2673
+ ) {
2674
+ float halfFilter = 0.5 * filterWidth;
2675
+ float reducedPosition = mod(position, unitLength);
2676
+ return (dashPatternIntegral(reducedPosition + halfFilter, solidLength, unitLength) -
2677
+ dashPatternIntegral(reducedPosition - halfFilter, solidLength, unitLength)) / filterWidth;
2678
+ }
1761
2679
  `,"fs:#main-start":`
2680
+ float dashCoverage = 1.0;
2681
+ bool shouldDiscardDash = false;
2682
+ bool inRoundedDashGap = false;
2683
+ float roundedDashResolvedCoverage = 1.0;
2684
+ float roundedDashSubPixelBlend = 0.0;
2685
+ float roundedDashDutyCycle = 1.0;
1762
2686
  float solidLength = vDashArray.x;
1763
2687
  float gapLength = vDashArray.y;
1764
2688
  float unitLength = solidLength + gapLength;
2689
+ if (unitLength > 0.0 && gapLength > 0.0) {
1765
2690
  float offset;
1766
- if (unitLength > 0.0) {
1767
2691
  if (pathStyle.dashAlignMode == 0.0) {
1768
2692
  offset = vDashOffset;
1769
2693
  } else {
1770
- unitLength = vPathLength / round(vPathLength / unitLength);
2694
+ #ifdef HIGH_PRECISION_DASH
2695
+ unitLength = vDashPathLength / max(round(vDashPathLength / unitLength), 1.0);
2696
+ #else
2697
+ unitLength = vPathLength / max(round(vPathLength / unitLength), 1.0);
2698
+ #endif
2699
+ solidLength = min(solidLength, unitLength);
1771
2700
  offset = solidLength / 2.0;
2701
+ #ifdef HIGH_PRECISION_DASH
2702
+ offset += vDashOffset;
2703
+ #endif
1772
2704
  }
1773
- float unitOffset = mod(vPathPosition.y + offset, unitLength);
1774
- if (gapLength > 0.0 && unitOffset > solidLength) {
1775
- if (path.capType <= 0.5) {
1776
- if (!(pathStyle.dashGapPickable && bool(picking.isActive))) {
1777
- discard;
1778
- }
1779
- } else {
1780
- float distToEnd = length(vec2(
2705
+ float alongPath = vPathPosition.y + offset;
2706
+ float unitOffset = mod(alongPath, unitLength);
2707
+ float filterWidth = max(fwidth(alongPath), 0.0001);
2708
+ if (bool(picking.isActive)) {
2709
+ bool inGap = unitOffset > solidLength;
2710
+ if (inGap && path.capType > 0.5) {
2711
+ inGap = length(vec2(
1781
2712
  min(unitOffset - solidLength, unitLength - unitOffset),
1782
2713
  vPathPosition.x
1783
- ));
1784
- if (distToEnd > 1.0) {
1785
- if (!(pathStyle.dashGapPickable && bool(picking.isActive))) {
1786
- discard;
2714
+ )) > 1.0;
1787
2715
  }
2716
+ if (inGap && !pathStyle.dashGapPickable) {
2717
+ shouldDiscardDash = true;
1788
2718
  }
2719
+ } else if (path.capType <= 0.5) {
2720
+ dashCoverage = dashPatternCoverage(alongPath, solidLength, unitLength, filterWidth);
2721
+ } else {
2722
+ float distanceAlongGap = min(unitOffset - solidLength, unitLength - unitOffset);
2723
+ float distanceToEnd = length(vec2(max(distanceAlongGap, 0.0), vPathPosition.x));
2724
+ float capEdgePixels = (1.0 - distanceToEnd) / max(fwidth(distanceToEnd), 1e-6);
2725
+ if (distanceAlongGap > 0.0) {
2726
+ inRoundedDashGap = true;
2727
+ roundedDashResolvedCoverage = smoothedge(0.0, capEdgePixels);
2728
+ dashCoverage = roundedDashResolvedCoverage;
2729
+ }
2730
+ float subPixelBlend = smoothstep(unitLength, 2.0 * unitLength, filterWidth);
2731
+ roundedDashSubPixelBlend = subPixelBlend;
2732
+ float boundedSolidLength = min(solidLength, unitLength);
2733
+ float effectiveGap = max(unitLength - boundedSolidLength, 0.0);
2734
+ float capSpan = 2.0 * sqrt(max(1.0 - vPathPosition.x * vPathPosition.x, 0.0));
2735
+ float roundedDutyCycle = clamp(
2736
+ (boundedSolidLength + min(effectiveGap, capSpan)) / unitLength,
2737
+ 0.0,
2738
+ 1.0
2739
+ );
2740
+ roundedDashDutyCycle = roundedDutyCycle;
2741
+ dashCoverage = mix(dashCoverage, roundedDutyCycle, subPixelBlend);
2742
+ }
2743
+ dashCoverage = clamp(dashCoverage, 0.0, 1.0);
2744
+ shouldDiscardDash = shouldDiscardDash || dashCoverage <= 0.0;
1789
2745
  }
2746
+ `,"fs:#main-end":`
2747
+ #ifdef ANTIALIASING
2748
+ if (inRoundedDashGap) {
2749
+ float pathCoverage = smoothedge(0.0, edgePixels);
2750
+ float resolvedCapMultiplier =
2751
+ min(pathCoverage, roundedDashResolvedCoverage) / max(pathCoverage, 1e-6);
2752
+ dashCoverage = mix(
2753
+ resolvedCapMultiplier,
2754
+ roundedDashDutyCycle,
2755
+ roundedDashSubPixelBlend
2756
+ );
1790
2757
  }
2758
+ #endif
2759
+ if (shouldDiscardDash) {
2760
+ discard;
1791
2761
  }
1792
- `}},mt={inject:{"vs:#decl":`
2762
+ fragColor.a *= dashCoverage;
2763
+ `}},zt={inject:{"vs:#decl":`
1793
2764
  in vec2 instanceDashArrays;
1794
2765
  out vec2 vDashArray;
1795
2766
  `,"vs:#main-end":`
@@ -1831,7 +2802,7 @@ fragColor = vec4(vFillColor.rgb, vFillColor.a * alphaFactor);
1831
2802
  fragColor = picking_filterPickingColor(fragColor);
1832
2803
  fragColor = picking_filterHighlightColor(fragColor);
1833
2804
  }
1834
- `}},ht={inject:{"vs:#decl":`
2805
+ `}},Ut={inject:{"vs:#decl":`
1835
2806
  in vec2 instanceDashArrays;
1836
2807
  out vec2 vDashArray;
1837
2808
  `,"vs:#main-end":`
@@ -1953,7 +2924,7 @@ fragColor = vec4(vFillColor.rgb, vFillColor.a * alphaFactor);
1953
2924
  fragColor = picking_filterPickingColor(fragColor);
1954
2925
  fragColor = picking_filterHighlightColor(fragColor);
1955
2926
  }
1956
- `}},vt={inject:{"vs:#decl":`
2927
+ `}},Vt={inject:{"vs:#decl":`
1957
2928
  in float instanceOffsets;
1958
2929
  `,"vs:DECKGL_FILTER_SIZE":`
1959
2930
  float offsetWidth = abs(instanceOffsets * 2.0) + 1.0;
@@ -1964,64 +2935,248 @@ float offsetDir = sign(instanceOffsets);
1964
2935
  vPathPosition.x = (vPathPosition.x + offsetDir) * offsetWidth - offsetDir;
1965
2936
  vPathPosition.y *= offsetWidth;
1966
2937
  vPathLength *= offsetWidth;
1967
- `,"fs:#main-start":`
1968
- float isInside;
1969
- isInside = step(-1.0, vPathPosition.x) * step(vPathPosition.x, 1.0);
1970
- if (isInside == 0.0) {
2938
+ #ifdef DASH_ENABLED
2939
+ if (pathStyle.dashUnits != 0) {
2940
+ vDashArray *= offsetWidth;
2941
+ }
2942
+ vPathBounds *= offsetWidth;
2943
+ #ifdef HIGH_PRECISION_DASH
2944
+ vDashPathLength *= offsetWidth;
2945
+ float restoredDashUnitLength = vDashArray.x + vDashArray.y;
2946
+ float restoredDashPeriod = pathStyle.dashAlignMode == 0.0
2947
+ ? restoredDashUnitLength
2948
+ : vDashPathLength /
2949
+ max(round(vDashPathLength / max(restoredDashUnitLength, 0.0001)), 1.0);
2950
+ vDashOffset = restoredDashPeriod > 0.0
2951
+ ? mod(dashOffsetAndLength.x * offsetWidth, restoredDashPeriod)
2952
+ : 0.0;
2953
+ #else
2954
+ vDashOffset *= offsetWidth;
2955
+ #endif
2956
+ #endif
2957
+ `,"fs:#main-end":`
2958
+ #ifndef ANTIALIASING
2959
+ if (abs(vPathPosition.x) > 1.0) {
1971
2960
  discard;
1972
2961
  }
1973
- `}};var ur={getDashArray:{type:"accessor",value:[0,0]},getOffset:{type:"accessor",value:0},dashJustified:!1,dashGapPickable:!1},N=class extends w.LayerExtension{constructor({dash:e=!1,offset:t=!1,highPrecisionDash:r=!1}={}){super({dash:e||r,offset:t,highPrecisionDash:r})}getLayerType(e){if("pathTesselator"in e.state)return"path";let t=e.constructor.layerName;return t==="ScatterplotLayer"?"scatterplot":t==="TextBackgroundLayer"?"textBackground":null}isEnabled(e){return this.getLayerType(e)!==null}getShaders(e){let t=e.getLayerType(this);if(!t)return null;if(t==="scatterplot"||t==="textBackground")return e.opts.dash?{modules:[{name:"pathStyle",inject:t==="scatterplot"?mt.inject:ht.inject,uniformTypes:{dashGapPickable:"i32"}}]}:null;let r={},o={};e.opts.dash&&(r=(0,w._mergeShaders)(r,_t),e.opts.highPrecisionDash&&(o.HIGH_PRECISION_DASH=!0)),e.opts.offset&&(r=(0,w._mergeShaders)(r,vt));let{inject:s}=r;return{modules:[{name:"pathStyle",inject:s,uniformTypes:{dashAlignMode:"f32",dashGapPickable:"i32"}}],defines:o}}initializeState(e,t){let r=this.getAttributeManager(),o=t.getLayerType(this);!r||!o||(t.opts.dash&&r.addInstanced({instanceDashArrays:{size:2,accessor:"getDashArray"},...o==="path"&&t.opts.highPrecisionDash?{instanceDashOffsets:{size:1,accessor:"getPath",transform:t.getDashOffsets.bind(this)}}:{}}),o==="path"&&t.opts.offset&&r.addInstanced({instanceOffsets:{size:1,accessor:"getOffset"}}))}updateState(e,t){if(t.isEnabled(this)&&t.opts.dash){let r=t.getLayerType(this);if(r==="scatterplot"||r==="textBackground"){let o={dashGapPickable:Boolean(this.props.dashGapPickable)};this.setShaderModuleProps({pathStyle:o})}else{let o={dashAlignMode:this.props.dashJustified?1:0,dashGapPickable:Boolean(this.props.dashGapPickable)};this.setShaderModuleProps({pathStyle:o})}}}getDashOffsets(e){let t=[0],r=this.props.positionFormat==="XY"?2:3,o=Array.isArray(e[0]),s=o?e.length:e.length/r,n,a;for(let l=0;l<s-1;l++)n=o?e[l]:e.slice(l*r,l*r+r),n=this.projectPosition(n),l>0&&(t[l]=t[l-1]+k.dist(a,n)),a=n;return t[s-1]=0,t}};N.defaultProps=ur;N.extensionName="PathStyleExtension";var gt=N;var bt=d(_(),1);var F=d(_(),1),xt=`layout(std140) uniform fillUniforms {
2962
+ #endif
2963
+ `}};var Pn={getDashArray:{type:"accessor",value:[0,0]},getOffset:{type:"accessor",value:0},dashJustified:!1,dashGapPickable:!1,dashUnits:"widths"},En={widths:0,pixels:1,meters:2,common:3},Mn=["instanceDashArrays","instanceDashOffsets","instanceOffsets"];function An({props:t,oldProps:e}){return!(0,b._deepEqual)(t.modelMatrix,e.modelMatrix,2)||t.coordinateSystem!==e.coordinateSystem||!(0,b._deepEqual)(t.coordinateOrigin,e.coordinateOrigin,1)}function jt(t,e,i){let r=t.context.viewport;if(!(r instanceof b.WebMercatorViewport)||r.zoom<12)return t.projectPosition(e,{autoOffset:!1});let n=pe.transformMat4([],[e[0],e[1],e[2]||0,1],i.modelMatrix),o=t.props.coordinateSystem==="default"?"lnglat":t.props.coordinateSystem;if(o==="lnglat"){if(Math.abs(n[1]-i.coordinateOrigin[1])>.25){let l=n[0];i.wrapLongitude&&(l=((l+180)%360+360)%360-180);let f=r.projectPosition([l,n[1],0]);return[f[0]-i.commonOrigin[0],f[1]-i.commonOrigin[1],n[2]*i.commonUnitsPerMeter[2]]}L.sub(n,n,i.coordinateOrigin)}else o==="cartesian"&&L.sub(n,n,i.coordinateOrigin);let a=n[1],s=L.scaleAndAdd([],i.commonUnitsPerWorldUnit,i.commonUnitsPerWorldUnit2,a);return L.multiply([],n,s)}var K=class extends b.LayerExtension{constructor({dash:e=!1,offset:i=!1,dashMode:r,highPrecisionDash:n=!1}={}){let o=r??(n?"path":"segment");super({dash:e||n||r!==void 0,offset:i,dashMode:o,highPrecisionDash:o==="path"})}getLayerType(e){if("pathTesselator"in e.state)return"path";let i=e.constructor.layerName;return i==="ScatterplotLayer"?"scatterplot":i==="TextBackgroundLayer"?"textBackground":null}synchronizeAttributes(e){let i=e.getAttributeManager(),r=this.getLayerType(e);if(!i||!r)return!1;let n=i.getAttributes(),o=new Set;this.opts.dash&&o.add("instanceDashArrays"),r==="path"&&this.opts.dash&&this.opts.dashMode==="path"&&o.add("instanceDashOffsets"),r==="path"&&this.opts.offset&&o.add("instanceOffsets");let a=!1;for(let s of Mn)n[s]&&!o.has(s)&&(i.remove([s]),a=!0);return o.has("instanceDashArrays")&&!n.instanceDashArrays&&(i.addInstanced({instanceDashArrays:{size:2,accessor:"getDashArray"}}),a=!0),o.has("instanceDashOffsets")&&!n.instanceDashOffsets&&(i.addInstanced({instanceDashOffsets:{size:2,accessor:["getPath"],update:this.calculateDashMetrics}}),a=!0),o.has("instanceOffsets")&&!n.instanceOffsets&&(i.addInstanced({instanceOffsets:{size:1,accessor:"getOffset"}}),a=!0),a}isEnabled(e){return this.getLayerType(e)!==null}getShaders(e){let i=e.getLayerType(this);if(!i)return null;if(i==="scatterplot"||i==="textBackground")return e.opts.dash?{modules:[{name:"pathStyle",inject:i==="scatterplot"?zt.inject:Ut.inject,uniformTypes:{dashGapPickable:"i32"}}]}:null;let r={},n={};e.opts.dash&&(r=(0,b._mergeShaders)(r,Dt),n.DASH_ENABLED=!0,e.opts.dashMode==="path"&&(n.HIGH_PRECISION_DASH=!0)),e.opts.offset&&(r=(0,b._mergeShaders)(r,Vt),n.PATH_STYLE_OFFSET=!0);let{inject:o}=r,a={name:"pathStyle",inject:o};return e.opts.dash&&(a.uniformTypes={dashAlignMode:"f32",dashGapPickable:"i32",dashUnits:"i32"}),{modules:[a],defines:n}}initializeState(e,i){i.synchronizeAttributes(this)}updateState(e,i){if(i.isEnabled(this)){if(e.changeFlags.extensionsChanged){let r=i.synchronizeAttributes(this),n=this.getAttributeManager();if(n&&r){n.invalidateAll();for(let o of this.getModels())o.setBufferLayout(n.getBufferLayouts(o))}}if(i.opts.dash){let r=i.getLayerType(this);if(r==="path"&&i.opts.dashMode==="path"&&An(e)&&this.getAttributeManager()?.invalidate("instanceDashOffsets"),r==="scatterplot"||r==="textBackground"){let n={dashGapPickable:!!this.props.dashGapPickable};this.setShaderModuleProps({pathStyle:n})}else{let n={dashAlignMode:this.props.dashJustified?1:0,dashGapPickable:!!this.props.dashGapPickable,dashUnits:En[this.props.dashUnits??"widths"]};this.setShaderModuleProps({pathStyle:n})}}}}calculateDashMetrics(e,{startRow:i,endRow:r}){let n=this.state.pathTesselator,o=n?.vertexStarts,a=n?.instanceCount,s=n?.get("positions");if(!o||a===void 0||typeof n?.getPathSegmentIndices!="function")throw new Error("PathStyleExtension requires PathLayer tessellation data for path dashes.");let l=this.props.data?.attributes?.getPath,f=ArrayBuffer.isView(l)?l:l?.value,c=ArrayBuffer.isView(f),u=s&&(!l||n.normalize||n.opts?.isWebGPU);if(l&&!c||!u&&!c)throw new Error("PathStyleExtension cannot calculate whole-path dash metrics from GPU-only getPath data; supply data.attributes.instanceDashOffsets.");let d=e.value,p=e.size,m=Math.max(0,i),F=Math.min(r,o.length-1),v=3,O=3,R=0;if(!u){let x=f.BYTES_PER_ELEMENT;v=l?.size||(this.props.positionFormat==="XY"?2:3),O=l?.stride?l.stride/x:v,R=l?.offset?l.offset/x:0}let P=new Array(3),k=b.project.getUniforms({viewport:this.context.viewport,modelMatrix:this.props.modelMatrix,coordinateSystem:this.props.coordinateSystem,coordinateOrigin:this.props.coordinateOrigin,autoWrapLongitude:this.wrapLongitude}),G=x=>{if(u)P[0]=s[x*3],P[1]=s[x*3+1],P[2]=s[x*3+2];else{let A=R+x*O;P[0]=f[A],P[1]=f[A+1],P[2]=v===3?f[A+2]:0}return P};e.startIndices=o;for(let x=m;x<F;x++){let A=o[x],N=Math.min(o[x+1]??a,a);d.fill(0,A*p,N*p);let Pi=n.getPathSegmentIndices(x),Te=0,je=-2,Se=null;for(let T of Pi){let Ei=T*p;d[Ei]=Te;let Mi=T===je+1&&Se?Se:jt(this,G(T),k),He=jt(this,G(T+1),k);Te+=L.dist(Mi,He),je=T,Se=He}if(p>1)for(let T=A;T<N;T++)d[T*p+1]=Te}}getDashOffsets(e){let i=[0],r=this.props.positionFormat==="XY"?2:3,n=Array.isArray(e[0]),o=n?e.length:e.length/r,a,s;for(let l=0;l<o-1;l++)a=n?e[l]:e.slice(l*r,l*r+r),a=this.projectPosition(a,{autoOffset:!1}),l>0&&(i[l]=i[l-1]+L.dist(s,a)),s=a;return i[o-1]=0,i}};K.defaultProps=Pn;K.extensionName="PathStyleExtension";var Ht=K;var $t=_(h(),1);var U=_(h(),1),Tn=512/4e7;function Sn(t,e){switch(t){case"pixels":return 2**-Math.round(e.zoom);case"common":return 1;default:return Tn}}var Gt=`layout(std140) uniform fillUniforms {
1974
2964
  vec2 patternTextureSize;
2965
+ float patternUnitScale;
1975
2966
  bool patternEnabled;
1976
2967
  bool patternMask;
2968
+ bool procedural;
2969
+ bool flipY;
1977
2970
  vec2 uvCoordinateOrigin;
1978
2971
  vec2 uvCoordinateOrigin64Low;
1979
2972
  } fill;
1980
- `,pr=`
2973
+ `,Ln=`
2974
+ uniform sampler2D fill_patternTexture;
2975
+
1981
2976
  in vec4 fillPatternFrames;
1982
2977
  in float fillPatternScales;
1983
2978
  in vec2 fillPatternOffsets;
2979
+ in vec4 fillPatternBackgroundColors;
1984
2980
 
1985
2981
  out vec2 fill_uv;
1986
2982
  out vec4 fill_patternBounds;
1987
2983
  out vec4 fill_patternPlacement;
1988
- `,dr=`
1989
- ${xt}
1990
- ${pr}
1991
- `,_r=`
2984
+ out vec4 fill_backgroundColor;
2985
+ out float fill_patternCoordinateScale;
2986
+ flat out vec4 fill_patternParams0;
2987
+ flat out vec4 fill_patternParams1;
2988
+ `,Fn=`
2989
+ ${Gt}
2990
+ ${Ln}
2991
+ `,On=`
1992
2992
  uniform sampler2D fill_patternTexture;
1993
2993
 
1994
2994
  in vec4 fill_patternBounds;
1995
2995
  in vec4 fill_patternPlacement;
2996
+ in vec4 fill_backgroundColor;
1996
2997
  in vec2 fill_uv;
2998
+ in float fill_patternCoordinateScale;
2999
+ flat in vec4 fill_patternParams0;
3000
+ flat in vec4 fill_patternParams1;
3001
+
3002
+ const float FILL_PATTERN_HATCH = 1.0;
3003
+ const float FILL_PATTERN_CROSS_HATCH = 2.0;
3004
+ const float FILL_PATTERN_DOTS = 3.0;
3005
+
3006
+ float fill_getPatternCoordinate(vec2 axis, float period, float offset) {
3007
+ float coordinateScale = max(abs(fill_patternCoordinateScale), 1.0e-20);
3008
+ vec2 coordinateOrigin = fill.uvCoordinateOrigin;
3009
+ vec2 coordinateOffset = fill.uvCoordinateOrigin64Low + fill_uv;
3010
+ float yDirection = fill.flipY ? 1.0 : -1.0;
3011
+ coordinateOrigin.y *= yDirection;
3012
+ coordinateOffset.y *= yDirection;
3013
+
3014
+ // Reduce the high part before adding the local offset to retain precision in large coordinates.
3015
+ float highPart = mod(dot(coordinateOrigin, axis) / coordinateScale, period);
3016
+ float lowPart = dot(coordinateOffset, axis) / coordinateScale;
3017
+ return mod(highPart + lowPart + offset * period, period);
3018
+ }
3019
+
3020
+ vec2 fill_getPatternCoords(
3021
+ vec2 axis0,
3022
+ vec2 axis1,
3023
+ vec2 period,
3024
+ vec2 offset
3025
+ ) {
3026
+ return vec2(
3027
+ fill_getPatternCoordinate(axis0, period.x, offset.x),
3028
+ fill_getPatternCoordinate(axis1, period.y, offset.y)
3029
+ );
3030
+ }
1997
3031
 
1998
- const float FILL_UV_SCALE = 512.0 / 40000000.0;
1999
- `,mr=`
2000
- ${xt}
2001
- ${_r}
2002
- `,hr={"vs:DECKGL_FILTER_GL_POSITION":`
2003
- fill_uv = geometry.position.xy;
2004
- `,"vs:DECKGL_FILTER_COLOR":`
3032
+ float fill_getScreenSpaceAlpha(float signedDistance) {
3033
+ float distanceDerivative = fwidth(signedDistance);
3034
+ if (distanceDerivative == 0.0) {
3035
+ return signedDistance <= 0.0 ? 1.0 : 0.0;
3036
+ }
3037
+ // Normalize the SDF to screen pixels so the coverage ramp is independent of pattern units.
3038
+ float distanceInPixels = signedDistance / distanceDerivative;
3039
+ return 1.0 - smoothstep(-0.5, 0.5, distanceInPixels);
3040
+ }
3041
+
3042
+ float fill_getLineAlpha(float position, float center, float period, float strokeWidth) {
3043
+ float distanceToLine = abs(mod(position - center + period * 0.5, period) - period * 0.5);
3044
+ return fill_getScreenSpaceAlpha(distanceToLine - strokeWidth * 0.5);
3045
+ }
3046
+
3047
+ float fill_getHatchAlpha(float angle, float strokeWidth, vec2 gaps, bool alternating) {
3048
+ vec2 lineDirection = vec2(cos(angle), sin(angle));
3049
+ vec2 lineNormal = vec2(-lineDirection.y, lineDirection.x);
3050
+ float period = alternating
3051
+ ? strokeWidth * 2.0 + gaps.x + gaps.y
3052
+ : strokeWidth + gaps.x;
3053
+ float offset = dot(fill_patternPlacement.xy, lineNormal);
3054
+ float position = fill_getPatternCoordinate(lineNormal, period, offset);
3055
+ float alpha = fill_getLineAlpha(position, 0.0, period, strokeWidth);
3056
+ if (alternating) {
3057
+ alpha = max(
3058
+ alpha,
3059
+ fill_getLineAlpha(position, strokeWidth + gaps.x, period, strokeWidth)
3060
+ );
3061
+ }
3062
+ return alpha;
3063
+ }
3064
+
3065
+ float fill_getDotAlpha(float angle, float skew, float radius, float gap) {
3066
+ vec2 axis0 = vec2(cos(angle), sin(angle));
3067
+ float axis1Angle = angle + 1.5707963267948966 - skew;
3068
+ vec2 axis1 = vec2(cos(axis1Angle), sin(axis1Angle));
3069
+ float determinant = axis0.x * axis1.y - axis0.y * axis1.x;
3070
+
3071
+ // The reciprocal basis maps common coordinates into the skewed dot lattice.
3072
+ vec2 reciprocal0 = vec2(axis1.y, -axis1.x) / determinant;
3073
+ vec2 reciprocal1 = vec2(-axis0.y, axis0.x) / determinant;
3074
+ float period = radius * 2.0 + gap;
3075
+ vec2 latticeCoords = fill_getPatternCoords(
3076
+ reciprocal0,
3077
+ reciprocal1,
3078
+ vec2(period),
3079
+ fill_patternPlacement.xy
3080
+ );
3081
+ vec2 cellOffset = mod(latticeCoords + period * 0.5, period) - period * 0.5;
3082
+ float distanceToDotSquared = 1.0e20;
3083
+ // In a skewed lattice the closest dot is not necessarily in the independently wrapped cell.
3084
+ // Include adjacent cells to keep the repeated distance field continuous at cell boundaries.
3085
+ for (int x = -1; x <= 1; x++) {
3086
+ for (int y = -1; y <= 1; y++) {
3087
+ vec2 neighborOffset = cellOffset + vec2(float(x), float(y)) * period;
3088
+ vec2 dotOffset = axis0 * neighborOffset.x + axis1 * neighborOffset.y;
3089
+ distanceToDotSquared = min(distanceToDotSquared, dot(dotOffset, dotOffset));
3090
+ }
3091
+ }
3092
+ float distanceToDot = sqrt(distanceToDotSquared);
3093
+ return fill_getScreenSpaceAlpha(distanceToDot - radius);
3094
+ }
3095
+
3096
+ float fill_getProceduralPatternAlpha() {
3097
+ float patternType = fill_patternParams0.x;
3098
+ float size = fill_patternParams0.y;
3099
+ vec2 gaps = fill_patternParams0.zw;
3100
+ vec2 angles = fill_patternParams1.xy;
3101
+ float elementCount = fill_patternParams1.z;
3102
+
3103
+ if (patternType == FILL_PATTERN_HATCH) {
3104
+ return fill_getHatchAlpha(angles.x, size, gaps, elementCount == 2.0);
3105
+ }
3106
+ if (patternType == FILL_PATTERN_CROSS_HATCH) {
3107
+ return max(
3108
+ fill_getHatchAlpha(angles.x, size, gaps, false),
3109
+ fill_getHatchAlpha(angles.y, size, gaps, false)
3110
+ );
3111
+ }
3112
+ if (patternType == FILL_PATTERN_DOTS) {
3113
+ return fill_getDotAlpha(angles.x, angles.y, size, gaps.x);
3114
+ }
3115
+ return 1.0;
3116
+ }
3117
+
3118
+ // Draw the pattern over the background fill (Porter-Duff source-over)
3119
+ vec4 fill_blendOverBackground(vec4 pattern, vec4 background) {
3120
+ if (background.a == 0.0 || layer.opacity == 0.0) return pattern;
3121
+ float patternAlpha = pattern.a / layer.opacity;
3122
+ float blendedAlpha = patternAlpha + background.a * (1.0 - patternAlpha);
3123
+ vec3 blendedRGB = mix(background.rgb, pattern.rgb, patternAlpha / blendedAlpha);
3124
+ return vec4(blendedRGB, blendedAlpha * layer.opacity);
3125
+ }
3126
+ `,Bn=`
3127
+ ${Gt}
3128
+ ${On}
3129
+ `,wn={"vs:DECKGL_FILTER_GL_POSITION":`
2005
3130
  if (fill.patternEnabled) {
2006
- fill_patternBounds = fillPatternFrames / vec4(fill.patternTextureSize, fill.patternTextureSize);
2007
3131
  fill_patternPlacement.xy = fillPatternOffsets;
2008
- fill_patternPlacement.zw = fillPatternScales * fillPatternFrames.zw;
3132
+ fill_backgroundColor = fillPatternBackgroundColors;
3133
+ if (fill.procedural) {
3134
+ fill_uv = geometry.position.xy;
3135
+ fill_patternCoordinateScale = fill.patternUnitScale * fillPatternScales;
3136
+ int texelIndex = int(fillPatternFrames.x) * 4;
3137
+ fill_patternParams0 = vec4(
3138
+ texelFetch(fill_patternTexture, ivec2(texelIndex, 0), 0).rg,
3139
+ texelFetch(fill_patternTexture, ivec2(texelIndex + 1, 0), 0).rg
3140
+ );
3141
+ fill_patternParams1 = vec4(
3142
+ texelFetch(fill_patternTexture, ivec2(texelIndex + 2, 0), 0).rg,
3143
+ texelFetch(fill_patternTexture, ivec2(texelIndex + 3, 0), 0).rg
3144
+ );
3145
+ } else {
3146
+ fill_patternBounds = fillPatternFrames / vec4(fill.patternTextureSize, fill.patternTextureSize);
3147
+ vec2 patternFrameCommon = fill.patternUnitScale * fillPatternScales * fillPatternFrames.zw;
3148
+ // Reduce the coordinate origin to within one tile before adding the vertex position. The
3149
+ // origin is large in common space, and fp32 cannot carry the sum at full precision.
3150
+ vec2 origin = mod(fill.uvCoordinateOrigin, patternFrameCommon) + fill.uvCoordinateOrigin64Low;
3151
+ fill_uv = (origin + geometry.position.xy) / patternFrameCommon;
3152
+ // Pattern atlases use top-left coordinates, so reverse common-space Y in bottom-left views.
3153
+ fill_uv.y *= fill.flipY ? 1.0 : -1.0;
3154
+ fill_uv += fillPatternOffsets;
3155
+ }
2009
3156
  }
2010
3157
  `,"fs:DECKGL_FILTER_COLOR":`
2011
3158
  if (fill.patternEnabled) {
2012
- vec2 scale = FILL_UV_SCALE * fill_patternPlacement.zw;
2013
- vec2 patternUV = mod(mod(fill.uvCoordinateOrigin, scale) + fill.uvCoordinateOrigin64Low + fill_uv, scale) / scale;
2014
- patternUV = mod(fill_patternPlacement.xy + patternUV, 1.0);
2015
-
2016
- vec2 texCoords = fill_patternBounds.xy + fill_patternBounds.zw * patternUV;
2017
-
2018
- vec4 patternColor = texture(fill_patternTexture, texCoords);
2019
- color.a *= patternColor.a;
2020
- if (!fill.patternMask) {
2021
- color.rgb = patternColor.rgb;
3159
+ if (fill.procedural) {
3160
+ color.a *= fill_getProceduralPatternAlpha();
3161
+ } else {
3162
+ vec2 patternUV = fract(fill_uv);
3163
+ vec2 texCoords = fill_patternBounds.xy + fill_patternBounds.zw * patternUV;
3164
+
3165
+ // Tiling is emulated by wrapping the coordinate, so texCoords jumps from the end of the
3166
+ // frame back to its start once per tile, leading to the wrong mip level being selected,
3167
+ // which leads to artifacts at pattern edges. fill_uv is continuous across the primitive,
3168
+ // meaning that the correct mip level is always selected
3169
+ vec4 grad = fill_patternBounds.zwzw * vec4(dFdx(fill_uv), dFdy(fill_uv));
3170
+ vec4 patternColor = textureGrad(fill_patternTexture, texCoords, grad.xy, grad.zw);
3171
+
3172
+ color.a *= patternColor.a;
3173
+ if (!fill.patternMask) {
3174
+ color.rgb = patternColor.rgb;
3175
+ }
2022
3176
  }
3177
+ color = fill_blendOverBackground(color, fill_backgroundColor);
2023
3178
  }
2024
- `};function vr(i){if(!i)return{};let e={};if("fillPatternTexture"in i){let{fillPatternTexture:t}=i;e.fill_patternTexture=t,e.patternTextureSize=[t.width,t.height]}if("project"in i){let{fillPatternMask:t=!0,fillPatternEnabled:r=!0}=i,o=F.project.getUniforms(i.project),{commonOrigin:s}=o,n=[(0,F.fp64LowPart)(s[0]),(0,F.fp64LowPart)(s[1])];e.uvCoordinateOrigin=s.slice(0,2),e.uvCoordinateOrigin64Low=n,e.patternMask=t,e.patternEnabled=r}return e}var yt={name:"fill",vs:dr,fs:mr,inject:hr,dependencies:[F.project],getUniforms:vr,uniformTypes:{patternTextureSize:"vec2<f32>",patternEnabled:"i32",patternMask:"i32",uvCoordinateOrigin:"vec2<f32>",uvCoordinateOrigin64Low:"vec2<f32>"}};var gr={fillPatternEnabled:!0,fillPatternAtlas:{type:"image",value:null,async:!0,parameters:{lodMaxClamp:0}},fillPatternMapping:{type:"object",value:{},async:!0},fillPatternMask:!0,getFillPattern:{type:"accessor",value:i=>i.pattern},getFillPatternScale:{type:"accessor",value:1},getFillPatternOffset:{type:"accessor",value:[0,0]}},B=class extends bt.LayerExtension{constructor({pattern:e=!1}={}){super({pattern:e})}isEnabled(e){return e.getAttributeManager()!==null&&!("pathTesselator"in e.state)}getShaders(e){return e.isEnabled(this)?{modules:[e.opts.pattern&&yt].filter(Boolean)}:null}initializeState(e,t){if(!t.isEnabled(this))return;let r=this.getAttributeManager();t.opts.pattern&&r.add({fillPatternFrames:{size:4,stepMode:"dynamic",accessor:"getFillPattern",transform:t.getPatternFrame.bind(this)},fillPatternScales:{size:1,stepMode:"dynamic",accessor:"getFillPatternScale",defaultValue:1},fillPatternOffsets:{size:2,stepMode:"dynamic",accessor:"getFillPatternOffset"}}),this.setState({emptyTexture:this.context.device.createTexture({data:new Uint8Array(4),width:1,height:1})})}updateState({props:e,oldProps:t},r){r.isEnabled(this)&&e.fillPatternMapping&&e.fillPatternMapping!==t.fillPatternMapping&&this.getAttributeManager().invalidate("getFillPattern")}draw(e,t){if(!t.isEnabled(this))return;let{fillPatternAtlas:r,fillPatternEnabled:o,fillPatternMask:s}=this.props,n={project:e.shaderModuleProps.project,fillPatternEnabled:o,fillPatternMask:s,fillPatternTexture:r||this.state.emptyTexture};this.setShaderModuleProps({fill:n})}finalizeState(){this.state.emptyTexture?.delete()}getPatternFrame(e){let{fillPatternMapping:t}=this.getCurrentLayer().props,r=t&&t[e];return r?[r.x,r.y,r.width,r.height]:[0,0,0,0]}};B.defaultProps=gr;B.extensionName="FillStyleExtension";var Pt=B;var Et=d(_(),1),xr={clipBounds:[0,0,1,1],clipByInstance:void 0},Mt=`
3179
+ `};function In(t){if(!t)return{};let e={};if("fillPatternTexture"in t){let{fillPatternTexture:i}=t;e.fill_patternTexture=i,e.patternTextureSize=[i.width,i.height]}if("project"in t){let{fillPatternMask:i=!0,fillPatternEnabled:r=!0,fillPatternSizeUnits:n="meters",fillPatternCommonFrame:o=null,procedural:a=!1}=t,s=U.project.getUniforms(t.project),{commonOrigin:l}=s,f=Sn(n,t.project.viewport),c=[l[0],l[1]];o&&(c[0]%=f*o[0],c[1]%=f*o[1]),e.uvCoordinateOrigin=c,e.uvCoordinateOrigin64Low=[(0,U.fp64LowPart)(c[0]),(0,U.fp64LowPart)(c[1])],e.patternUnitScale=f,e.patternMask=i,e.patternEnabled=r,e.procedural=a,e.flipY=t.project.viewport?.flipY??!1}return e}var qt={name:"fill",vs:Fn,fs:Bn,inject:wn,dependencies:[U.project],getUniforms:In,uniformTypes:{patternTextureSize:"vec2<f32>",patternUnitScale:"f32",patternEnabled:"i32",patternMask:"i32",procedural:"i32",flipY:"i32",uvCoordinateOrigin:"vec2<f32>",uvCoordinateOrigin64Low:"vec2<f32>"}};var Yt="rg32float";var Ce={none:0,hatch:1,crossHatch:2,dots:3},g={type:0,size:1,gap0:2,gap1:3,angle0:4,angle1:5,elementCount:6},Wt=8,Z=Math.PI/180,Re=1,ke=1,Cn=0,Rn=[45,135],kn=0,Nn=0;function Kt(t){let e=Object.entries(t),i=new Float32Array((e.length+1)*Wt),r=new Map;return e.forEach(([n,o],a)=>{let s=a+1,l=s*Wt;switch(r.set(n,s),o.type){case"hatch":{let f=o.gap===void 0?ke:o.gap,c=o.strokeWidth===void 0?Re:o.strokeWidth,u=o.angle===void 0?Cn:o.angle;if(Array.isArray(f)&&f.length!==2)throw new Error(`${n}.gap must be a number or a two-element array`);let d=Array.isArray(f)?f:[f,f];Ne(c,`${n}.strokeWidth`),xe(d[0],`${n}.gap[0]`),xe(d[1],`${n}.gap[1]`),be(u,`${n}.angle`),i[l+g.type]=Ce.hatch,i[l+g.size]=c,i[l+g.gap0]=d[0],i[l+g.gap1]=d[1],i[l+g.angle0]=u*Z,i[l+g.elementCount]=Array.isArray(f)?2:1;break}case"cross-hatch":{let f=o.angles===void 0?Rn:o.angles,c=o.strokeWidth===void 0?Re:o.strokeWidth,u=o.gap===void 0?ke:o.gap;if(!Array.isArray(f)||f.length!==2)throw new Error(`${n}.angles must be a two-element array`);Ne(c,`${n}.strokeWidth`),xe(u,`${n}.gap`),be(f[0],`${n}.angles[0]`),be(f[1],`${n}.angles[1]`),i[l+g.type]=Ce.crossHatch,i[l+g.size]=c,i[l+g.gap0]=u,i[l+g.gap1]=u,i[l+g.angle0]=f[0]*Z,i[l+g.angle1]=f[1]*Z,i[l+g.elementCount]=2;break}case"dots":{let f=o.radius===void 0?Re:o.radius,c=o.gap===void 0?ke:o.gap,u=o.angle===void 0?kn:o.angle,d=o.skew===void 0?Nn:o.skew;Ne(f,`${n}.radius`),xe(c,`${n}.gap`),be(u,`${n}.angle`),Dn(d,`${n}.skew`),i[l+g.type]=Ce.dots,i[l+g.size]=f,i[l+g.gap0]=c,i[l+g.gap1]=c,i[l+g.angle0]=u*Z,i[l+g.angle1]=d*Z,i[l+g.elementCount]=2;break}default:throw new Error(`${n}.type is not a supported procedural pattern type`)}}),{data:i,width:i.length/2,height:1,patternIndices:r}}function Ne(t,e){if(!Number.isFinite(t)||t<=0)throw new Error(`${e} must be a finite number greater than 0`)}function xe(t,e){if(!Number.isFinite(t)||t<0)throw new Error(`${e} must be a finite number greater than or equal to 0`)}function be(t,e){if(!Number.isFinite(t))throw new Error(`${e} must be a finite number`)}function Dn(t,e){if(!Number.isFinite(t)||t<=-90||t>=90)throw new Error(`${e} must be a finite number greater than -90 and less than 90`)}function Zt(t,e){if(!Number.isInteger(e)||e<=0)return 0;if(t===0)return e;let[i,r]=[t,e];for(;r>0;)[i,r]=[r,i%r];return t/i*e}var zn={fillPatternEnabled:!0,fillPatternAtlas:{type:"image",value:null,async:!0},fillPatternMapping:{type:"object",value:{},async:!0},fillPatternMask:!0,fillPatternSizeUnits:"meters",getFillPattern:{type:"accessor",value:t=>t.pattern},getFillPatternScale:{type:"accessor",value:1},getFillPatternOffset:{type:"accessor",value:[0,0]},getFillPatternBackgroundColor:{type:"accessor",value:[0,0,0,0]}},$=class extends $t.LayerExtension{constructor({pattern:e=!1,proceduralPattern:i=!1}={}){super({pattern:e||i,proceduralPattern:i})}isEnabled(e){return e.getAttributeManager()!==null&&!("pathTesselator"in e.state)}getShaders(e){return e.isEnabled(this)?{modules:[e.opts.pattern&&qt].filter(Boolean)}:null}initializeState(e,i){if(!i.isEnabled(this))return;let r=this.getAttributeManager();i.opts.pattern&&r.add({fillPatternFrames:{size:4,stepMode:"dynamic",accessor:"getFillPattern",transform:i.opts.proceduralPattern?i.getProceduralPatternIndex.bind(this):i.getPatternFrame.bind(this)},fillPatternScales:{size:1,stepMode:"dynamic",accessor:"getFillPatternScale",defaultValue:1},fillPatternOffsets:{size:2,stepMode:"dynamic",accessor:"getFillPatternOffset"},fillPatternBackgroundColors:{size:4,type:"unorm8",stepMode:"dynamic",accessor:"getFillPatternBackgroundColor",defaultValue:[0,0,0,255]}}),this.setState({emptyTexture:this.context.device.createTexture({data:new Uint8Array(4),width:1,height:1}),...i.opts.proceduralPattern&&i.createProceduralPatternTexture.call(this,{})})}updateState({props:e,oldProps:i},r){if(r.isEnabled(this)){if(e.fillPatternMapping&&e.fillPatternMapping!==i.fillPatternMapping){if(r.opts.proceduralPattern&&typeof e.fillPatternMapping!="string"){let n=this.state.proceduralPatternTexture;this.setState(r.createProceduralPatternTexture.call(this,e.fillPatternMapping)),n?.delete()}this.getAttributeManager().invalidate("getFillPattern")}(e.fillPatternMapping!==i.fillPatternMapping||e.getFillPatternScale!==i.getFillPatternScale)&&this.setState({commonFrame:r.getCommonFrame(e)})}}draw(e,i){if(!i.isEnabled(this))return;let{fillPatternAtlas:r,fillPatternEnabled:n,fillPatternMask:o,fillPatternSizeUnits:a}=this.props,s={project:e.shaderModuleProps.project,fillPatternEnabled:n,fillPatternMask:o,fillPatternSizeUnits:a,procedural:i.opts.proceduralPattern,fillPatternTexture:i.opts.proceduralPattern?this.state.proceduralPatternTexture||this.state.emptyTexture:r||this.state.emptyTexture,fillPatternCommonFrame:this.state.commonFrame};this.setShaderModuleProps({fill:s})}finalizeState(){this.state.emptyTexture?.delete(),this.state.proceduralPatternTexture?.delete()}getPatternFrame(e){let{fillPatternMapping:i}=this.getCurrentLayer().props,r=i&&i[e];return r&&"x"in r?[r.x,r.y,r.width,r.height]:[0,0,0,0]}getCommonFrame(e){let{fillPatternMapping:i,getFillPatternScale:r}=e;if(typeof r!="number"||!(r>0)||typeof i!="object")return null;let n=0,o=0;for(let a in i){let s=i[a];if(!("width"in s)||(n=Zt(n,s.width),o=Zt(o,s.height),!n||!o))return null}return n?[r*n,r*o]:null}getProceduralPatternIndex(e){return[this.state.proceduralPatternIndices?.get(e)??0,0,0,0]}createProceduralPatternTexture(e){let i=Kt(e);return{proceduralPatternIndices:i.patternIndices,proceduralPatternTexture:this.context.device.createTexture({data:i.data,width:i.width,height:i.height,format:Yt,sampler:{minFilter:"nearest",magFilter:"nearest"}})}}};$.defaultProps=zn;$.extensionName="FillStyleExtension";var Xt=$;var Qt=_(h(),1),Un={clipBounds:[0,0,1,1],clipByInstance:void 0},Jt=`
2025
3180
  layout(std140) uniform clipUniforms {
2026
3181
  vec4 bounds;
2027
3182
  } clip;
@@ -2029,7 +3184,7 @@ layout(std140) uniform clipUniforms {
2029
3184
  bool clip_isInBounds(vec2 position) {
2030
3185
  return position.x >= clip.bounds[0] && position.y >= clip.bounds[1] && position.x < clip.bounds[2] && position.y < clip.bounds[3];
2031
3186
  }
2032
- `,yr={name:"clip",vs:Mt,uniformTypes:{bounds:"vec4<f32>"}},br={"vs:#decl":`
3187
+ `,Vn={name:"clip",vs:Jt,uniformTypes:{bounds:"vec4<f32>"}},jn={"vs:#decl":`
2033
3188
  out float clip_isVisible;
2034
3189
  `,"vs:DECKGL_FILTER_GL_POSITION":`
2035
3190
  clip_isVisible = float(clip_isInBounds(geometry.worldPosition.xy));
@@ -2037,7 +3192,7 @@ out float clip_isVisible;
2037
3192
  in float clip_isVisible;
2038
3193
  `,"fs:DECKGL_FILTER_COLOR":`
2039
3194
  if (clip_isVisible < 0.5) discard;
2040
- `},Pr={name:"clip",fs:Mt,uniformTypes:{bounds:"vec4<f32>"}},Er={"vs:#decl":`
3195
+ `},Hn={name:"clip",fs:Jt,uniformTypes:{bounds:"vec4<f32>"}},Gn={"vs:#decl":`
2041
3196
  out vec2 clip_commonPosition;
2042
3197
  `,"vs:DECKGL_FILTER_GL_POSITION":`
2043
3198
  clip_commonPosition = geometry.position.xy;
@@ -2045,7 +3200,7 @@ out vec2 clip_commonPosition;
2045
3200
  in vec2 clip_commonPosition;
2046
3201
  `,"fs:DECKGL_FILTER_COLOR":`
2047
3202
  if (!clip_isInBounds(clip_commonPosition)) discard;
2048
- `},D=class extends Et.LayerExtension{getShaders(){let e="instancePositions"in this.getAttributeManager().attributes;return this.props.clipByInstance!==void 0&&(e=Boolean(this.props.clipByInstance)),this.state.clipByInstance=e,e?{modules:[yr],inject:br}:{modules:[Pr],inject:Er}}draw(){let{clipBounds:e}=this.props,t={};if(this.state.clipByInstance)t.bounds=e;else{let r=this.projectPosition([e[0],e[1],0]),o=this.projectPosition([e[2],e[3],0]);t.bounds=[Math.min(r[0],o[0]),Math.min(r[1],o[1]),Math.max(r[0],o[0]),Math.max(r[1],o[1])]}this.setShaderModuleProps({clip:t})}};D.defaultProps=xr;D.extensionName="ClipExtension";var Ft=D;var St=d(_(),1);var Tt=d(_(),1),Mr=`
3203
+ `},X=class extends Qt.LayerExtension{getShaders(){let e="instancePositions"in this.getAttributeManager().attributes;return this.props.clipByInstance!==void 0&&(e=!!this.props.clipByInstance),this.state.clipByInstance=e,this.context.device.type==="webgpu"?{}:e?{modules:[Vn],inject:jn}:{modules:[Hn],inject:Gn}}draw(){let{clipBounds:e}=this.props,i={};if(this.state.clipByInstance)i.bounds=e;else{let r=this.projectPosition([e[0],e[1],0]),n=this.projectPosition([e[2],e[3],0]);i.bounds=[Math.min(r[0],n[0]),Math.min(r[1],n[1]),Math.max(r[0],n[0]),Math.max(r[1],n[1])]}this.context.device.type==="webgpu"&&(i.enabled=!0,i.mode=this.state.clipByInstance?"instance":"geometry"),this.setShaderModuleProps({clip:i})}};X.defaultProps=Un;X.extensionName="ClipExtension";var ei=X;var oi=_(h(),1);var ti=_(h(),1),qn=`
2049
3204
  in float collisionPriorities;
2050
3205
 
2051
3206
  uniform sampler2D collision_texture;
@@ -2093,7 +3248,7 @@ float collision_isVisible(vec2 texCoords, vec3 pickingColor) {
2093
3248
  float W = 2.0 * floatN + 1.0;
2094
3249
  return pow(accumulator / (W * W), 2.2);
2095
3250
  }
2096
- `,Fr={"vs:#decl":`
3251
+ `,Wn={"vs:#decl":`
2097
3252
  float collision_fade = 1.0;
2098
3253
  `,"vs:DECKGL_FILTER_GL_POSITION":`
2099
3254
  if (collision.sort) {
@@ -2112,21 +3267,21 @@ float collision_isVisible(vec2 texCoords, vec3 pickingColor) {
2112
3267
  }
2113
3268
  `,"vs:DECKGL_FILTER_COLOR":`
2114
3269
  color.a *= collision_fade;
2115
- `},Tr=i=>{if(!i||!("dummyCollisionMap"in i))return{};let{enabled:e,collisionFBO:t,drawToCollisionMap:r,dummyCollisionMap:o}=i;return{enabled:e&&!r,sort:Boolean(r),collision_texture:!r&&t?t.colorAttachments[0]:o}},Ot={name:"collision",dependencies:[Tt.project],vs:Mr,inject:Fr,getUniforms:Tr,uniformTypes:{sort:"i32",enabled:"i32"}};var At=d(_(),1);var Lt=d(_(),1),z=class extends Lt._LayersPass{renderCollisionMap(e,t){let o=[0,0,0,0],s=[1,1,e.width-2*1,e.height-2*1];this.render({...t,clearColor:o,scissorRect:s,target:e,pass:"collision"})}getLayerParameters(e,t,r){return{...e.props.parameters,blend:!1,depthWriteEnabled:!0,depthCompare:"less-equal"}}getShaderModuleProps(){return{collision:{drawToCollisionMap:!0},picking:{isActive:1,isAttribute:!1},lighting:{enabled:!1}}}};var Pe=2,V=class{constructor(){this.id="collision-filter-effect",this.props=null,this.useInPicking=!0,this.order=1,this.channels={},this.collisionFBOs={}}setup(e){this.context=e;let{device:t}=e;this.dummyCollisionMap=t.createTexture({width:1,height:1}),this.collisionFilterPass=new z(t,{id:"default-collision-filter"})}preRender({effects:e,layers:t,layerFilter:r,viewports:o,onViewportActive:s,views:n,isPicking:a,preRenderStats:l={}}){let{device:f}=this.context;if(a)return;let u=t.filter(({props:{visible:v,collisionEnabled:A}})=>v&&A);if(u.length===0){this.channels={};return}let c=e?.filter(v=>v.useInPicking&&l[v.id]),p=l["mask-effect"]?.didRender,m=this._groupByCollisionGroup(f,u),h=o[0],P=!this.lastViewport||!this.lastViewport.equals(h)||p;for(let v in m){let A=this.collisionFBOs[v],ue=m[v],[pe,de]=f.canvasContext.getPixelSize();A.resize({width:pe/Pe,height:de/Pe}),this._render(ue,{effects:c,layerFilter:r,onViewportActive:s,views:n,viewport:h,viewportChanged:P})}}_render(e,{effects:t,layerFilter:r,onViewportActive:o,views:s,viewport:n,viewportChanged:a}){let{collisionGroup:l}=e,f=this.channels[l];if(!f)return;let u=a||e===f||!(0,At._deepEqual)(f.layers,e.layers,1)||e.layerBounds.some((c,p)=>!M(c,f.layerBounds[p]))||e.allLayersLoaded!==f.allLayersLoaded||e.layers.some(c=>c.props.transitions);if(this.channels[l]=e,u){this.lastViewport=n;let c=this.collisionFBOs[l];this.collisionFilterPass.renderCollisionMap(c,{pass:"collision-filter",isPicking:!0,layers:e.layers,effects:t,layerFilter:r,viewports:n?[n]:[],onViewportActive:o,views:s,shaderModuleProps:{collision:{enabled:!0,dummyCollisionMap:this.dummyCollisionMap},project:{devicePixelRatio:c.device.canvasContext.getDevicePixelRatio()/Pe}}})}}_groupByCollisionGroup(e,t){let r={};for(let o of t){let s=o.props.collisionGroup,n=r[s];n||(n={collisionGroup:s,layers:[],layerBounds:[],allLayersLoaded:!0},r[s]=n),n.layers.push(o),n.layerBounds.push(o.getBounds()),o.isLoaded||(n.allLayersLoaded=!1)}for(let o of Object.keys(r))this.collisionFBOs[o]||this.createFBO(e,o),this.channels[o]||(this.channels[o]=r[o]);for(let o of Object.keys(this.collisionFBOs))r[o]||this.destroyFBO(o);return r}getShaderModuleProps(e){let{collisionGroup:t,collisionEnabled:r}=e.props,{collisionFBOs:o,dummyCollisionMap:s}=this,n=o[t];return{collision:{enabled:r&&Boolean(n),collisionFBO:n,dummyCollisionMap:s}}}cleanup(){this.dummyCollisionMap&&(this.dummyCollisionMap.delete(),this.dummyCollisionMap=void 0),this.channels={};for(let e of Object.keys(this.collisionFBOs))this.destroyFBO(e);this.collisionFBOs={},this.lastViewport=void 0}createFBO(e,t){let{width:r,height:o}=e.getDefaultCanvasContext().canvas,s=e.createTexture({format:"rgba8unorm",width:r,height:o,sampler:{minFilter:"nearest",magFilter:"nearest",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"}}),n=e.createTexture({format:"depth16unorm",width:r,height:o});this.collisionFBOs[t]=e.createFramebuffer({id:`collision-${t}`,width:r,height:o,colorAttachments:[s],depthStencilAttachment:n})}destroyFBO(e){let t=this.collisionFBOs[e];t.colorAttachments[0]?.destroy(),t.depthStencilAttachment?.destroy(),t.destroy(),delete this.collisionFBOs[e]}};var Or={getCollisionPriority:{type:"accessor",value:0},collisionEnabled:!0,collisionGroup:{type:"string",value:"default"},collisionTestProps:{}},j=class extends St.LayerExtension{getShaders(){return{modules:[Ot]}}draw({shaderModuleProps:e}){e.collision?.drawToCollisionMap&&(this.props=this.clone(this.props.collisionTestProps).props)}initializeState(e,t){if(this.getAttributeManager()===null)return;this.context.deck?._addDefaultEffect(new V),this.getAttributeManager().add({collisionPriorities:{size:1,stepMode:"dynamic",accessor:"getCollisionPriority"}})}getNeedsPickingBuffer(){return this.props.collisionEnabled}};j.defaultProps=Or;j.extensionName="CollisionFilterExtension";var It=j;var b=d(_(),1);var Ct=d(_(),1),Rt=`layout(std140) uniform maskUniforms {
3270
+ `},Yn=t=>{if(!t||!("dummyCollisionMap"in t))return{};let{enabled:e,collisionFBO:i,drawToCollisionMap:r,dummyCollisionMap:n}=t;return{enabled:e&&!r,sort:!!r,collision_texture:!r&&i?i.colorAttachments[0]:n}},ii={name:"collision",dependencies:[ti.project],vs:qn,inject:Wn,getUniforms:Yn,uniformTypes:{sort:"i32",enabled:"i32"}};var ni=_(h(),1);var ri=_(h(),1),Q=class extends ri._LayersPass{renderCollisionMap(e,i){let n=[0,0,0,0],o=[1,1,e.width-2,e.height-2];this.render({...i,clearColor:n,scissorRect:o,target:e,pass:"collision"})}getLayerParameters(e,i,r){return{...e.props.parameters,blend:!1,depthWriteEnabled:!0,depthCompare:"less-equal"}}getShaderModuleProps(){return{collision:{drawToCollisionMap:!0},picking:{isActive:1,isAttribute:!1},lighting:{enabled:!1}}}};var De=2,J=class{constructor(){this.id="collision-filter-effect",this.props=null,this.useInPicking=!0,this.order=1,this.channels={},this.collisionFBOs={}}setup(e){this.context=e;let{device:i}=e;this.dummyCollisionMap=i.createTexture({width:1,height:1}),this.collisionFilterPass=new Q(i,{id:"default-collision-filter"})}preRender({effects:e,layers:i,layerFilter:r,viewports:n,onViewportActive:o,views:a,isPicking:s,preRenderStats:l={}}){let{device:f}=this.context;if(s)return;let c=i.filter(({props:{visible:v,collisionEnabled:O}})=>v&&O);if(c.length===0){this.channels={};return}let u=e?.filter(v=>v.useInPicking&&l[v.id]),d=l["mask-effect"]?.didRender,p=this._groupByCollisionGroup(f,c),m=n[0],F=!this.lastViewport||!this.lastViewport.equals(m)||d;for(let v in p){let O=this.collisionFBOs[v],R=p[v],[P,k]=f.canvasContext.getPixelSize();O.resize({width:P/De,height:k/De}),this._render(R,{effects:u,layerFilter:r,onViewportActive:o,views:a,viewport:m,viewportChanged:F})}}_render(e,{effects:i,layerFilter:r,onViewportActive:n,views:o,viewport:a,viewportChanged:s}){let{collisionGroup:l}=e,f=this.channels[l];if(!f)return;let c=s||e===f||!(0,ni._deepEqual)(f.layers,e.layers,1)||e.layerBounds.some((u,d)=>!z(u,f.layerBounds[d]))||e.allLayersLoaded!==f.allLayersLoaded||e.layers.some(u=>u.props.transitions);if(this.channels[l]=e,c){this.lastViewport=a;let u=this.collisionFBOs[l];this.collisionFilterPass.renderCollisionMap(u,{pass:"collision-filter",isPicking:!0,layers:e.layers,effects:i,layerFilter:r,viewports:a?[a]:[],onViewportActive:n,views:o,shaderModuleProps:{collision:{enabled:!0,dummyCollisionMap:this.dummyCollisionMap},project:{devicePixelRatio:u.device.canvasContext.getDevicePixelRatio()/De}}})}}_groupByCollisionGroup(e,i){let r={};for(let n of i){let o=n.props.collisionGroup,a=r[o];a||(a={collisionGroup:o,layers:[],layerBounds:[],allLayersLoaded:!0},r[o]=a),a.layers.push(n),a.layerBounds.push(n.getBounds()),n.isLoaded||(a.allLayersLoaded=!1)}for(let n of Object.keys(r))this.collisionFBOs[n]||this.createFBO(e,n),this.channels[n]||(this.channels[n]=r[n]);for(let n of Object.keys(this.collisionFBOs))r[n]||this.destroyFBO(n);return r}getShaderModuleProps(e){let{collisionGroup:i,collisionEnabled:r}=e.props,{collisionFBOs:n,dummyCollisionMap:o}=this,a=n[i];return{collision:{enabled:r&&!!a,collisionFBO:a,dummyCollisionMap:o}}}cleanup(){this.dummyCollisionMap&&(this.dummyCollisionMap.delete(),this.dummyCollisionMap=void 0),this.channels={};for(let e of Object.keys(this.collisionFBOs))this.destroyFBO(e);this.collisionFBOs={},this.lastViewport=void 0}createFBO(e,i){let{width:r,height:n}=e.getDefaultCanvasContext().canvas,o=e.createTexture({format:"rgba8unorm",width:r,height:n,sampler:{minFilter:"nearest",magFilter:"nearest",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"}}),a=e.createTexture({format:"depth16unorm",width:r,height:n});this.collisionFBOs[i]=e.createFramebuffer({id:`collision-${i}`,width:r,height:n,colorAttachments:[o],depthStencilAttachment:a})}destroyFBO(e){let i=this.collisionFBOs[e];i.colorAttachments[0]?.destroy(),i.depthStencilAttachment?.destroy(),i.destroy(),delete this.collisionFBOs[e]}};var Kn={getCollisionPriority:{type:"accessor",value:0},collisionEnabled:!0,collisionGroup:{type:"string",value:"default"},collisionTestProps:{}},ee=class extends oi.LayerExtension{getShaders(){return{modules:[ii]}}draw({shaderModuleProps:e}){e.collision?.drawToCollisionMap&&(this.props=this.clone(this.props.collisionTestProps).props)}initializeState(e,i){if(this.getAttributeManager()===null)return;this.context.deck?._addDefaultEffect(new J),this.getAttributeManager().add({collisionPriorities:{size:1,stepMode:"dynamic",accessor:"getCollisionPriority"}})}getNeedsPickingBuffer(){return this.props.collisionEnabled}};ee.defaultProps=Kn;ee.extensionName="CollisionFilterExtension";var ai=ee;var C=_(h(),1);var si=_(h(),1),li=`layout(std140) uniform maskUniforms {
2116
3271
  vec4 bounds;
2117
3272
  highp int channel;
2118
3273
  bool enabled;
2119
3274
  bool inverted;
2120
3275
  bool maskByInstance;
2121
3276
  } mask;
2122
- `,Lr=`
3277
+ `,Zn=`
2123
3278
  vec2 mask_getCoords(vec4 position) {
2124
3279
  return (position.xy - mask.bounds.xy) / (mask.bounds.zw - mask.bounds.xy);
2125
3280
  }
2126
- `,Ar=`
2127
- ${Rt}
2128
- ${Lr}
2129
- `,Sr=`
3281
+ `,$n=`
3282
+ ${li}
3283
+ ${Zn}
3284
+ `,Xn=`
2130
3285
  uniform sampler2D mask_texture;
2131
3286
 
2132
3287
  bool mask_isInBounds(vec2 texCoords) {
@@ -2151,10 +3306,10 @@ bool mask_isInBounds(vec2 texCoords) {
2151
3306
  return maskValue < 0.5;
2152
3307
  }
2153
3308
  }
2154
- `,Ir=`
2155
- ${Rt}
2156
- ${Sr}
2157
- `,Cr={"vs:#decl":`
3309
+ `,Qn=`
3310
+ ${li}
3311
+ ${Xn}
3312
+ `,Jn={"vs:#decl":`
2158
3313
  out vec2 mask_texCoords;
2159
3314
  `,"vs:#main-end":`
2160
3315
  vec4 mask_common_position;
@@ -2176,15 +3331,15 @@ in vec2 mask_texCoords;
2176
3331
 
2177
3332
  if (!mask) discard;
2178
3333
  }
2179
- `},Rr=i=>i&&"maskMap"in i?{mask_texture:i.maskMap}:i||{},kt={name:"mask",dependencies:[Ct.project],vs:Ar,fs:Ir,inject:Cr,getUniforms:Rr,uniformTypes:{bounds:"vec4<f32>",channel:"i32",enabled:"i32",inverted:"i32",maskByInstance:"i32"}};var Me=d(_(),1);var wt=d(_(),1),kr={blendColorOperation:"subtract",blendColorSrcFactor:"zero",blendColorDstFactor:"one",blendAlphaOperation:"subtract",blendAlphaSrcFactor:"zero",blendAlphaDstFactor:"one"},U=class extends wt._LayersPass{constructor(e,t){super(e,t);let{mapSize:r=2048}=t;this.maskMap=e.createTexture({format:"rgba8unorm",width:r,height:r,sampler:{minFilter:"linear",magFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"}}),this.fbo=e.createFramebuffer({id:"maskmap",width:r,height:r,colorAttachments:[this.maskMap]})}render(e){let t=2**e.channel,r=[255,255,255,255];super.render({...e,clearColor:r,colorMask:t,target:this.fbo,pass:"mask"})}getLayerParameters(e,t,r){return{...e.props.parameters,blend:!0,depthCompare:"always",...kr}}shouldDrawLayer(e){return e.props.operation.includes("mask")}delete(){this.fbo.delete(),this.maskMap.delete()}};var G=d(_(),1),Ee=new G.WebMercatorViewport({width:1,height:1,longitude:0,latitude:0,zoom:0});function H(i){let[e,t]=Ee.projectPosition(i);return[e,t]}function ne(i){return i.isGeospatial?Ee:i}function T(i,e){let t=[1/0,1/0,-1/0,-1/0];for(let r of i){let o=r.getBounds();if(o){let s=r.projectPosition(o[0],{viewport:e,autoOffset:!1}),n=r.projectPosition(o[1],{viewport:e,autoOffset:!1});t[0]=Math.min(t[0],s[0]),t[1]=Math.min(t[1],s[1]),t[2]=Math.max(t[2],n[0]),t[3]=Math.max(t[3],n[1])}}return Number.isFinite(t[0])?t:null}var wr=2048;function O(i){let{bounds:e,viewport:t,border:r=0}=i,{isGeospatial:o}=t;if(e[2]<=e[0]||e[3]<=e[1])return null;let s=o?Ee.unprojectPosition([(e[0]+e[2])/2,(e[1]+e[3])/2,0]):t.unprojectPosition([(e[0]+e[2])/2,(e[1]+e[3])/2,0]),{width:n,height:a,zoom:l}=i;if(l===void 0){n=n-r*2,a=a-r*2;let f=Math.min(n/(e[2]-e[0]),a/(e[3]-e[1]));l=Math.min(Math.log2(f),20)}else if(!n||!a){let f=2**l;n=Math.round(Math.abs(e[2]-e[0])*f),a=Math.round(Math.abs(e[3]-e[1])*f);let u=wr-r*2;if(n>u||a>u){let c=u/Math.max(n,a);n=Math.round(n*c),a=Math.round(a*c),l+=Math.log2(c)}}return o?new G.WebMercatorViewport({id:t.id,x:r,y:r,width:n,height:a,longitude:s[0],latitude:s[1],zoom:l,orthographic:!0}):new G.OrthographicViewport({id:t.id,x:r,y:r,width:n,height:a,target:s,zoom:l,flipY:!1})}function Nr(i,e){let t;if(e&&e.length===2){let[s,n]=e,a=i.getBounds({z:s}),l=i.getBounds({z:n});t=[Math.min(a[0],l[0]),Math.min(a[1],l[1]),Math.max(a[2],l[2]),Math.max(a[3],l[3])]}else t=i.getBounds();let r=i.projectPosition(t.slice(0,2)),o=i.projectPosition(t.slice(2,4));return[r[0],r[1],o[0],o[1]]}function L(i,e,t){if(!i)return[0,0,1,1];let r=Nr(e,t),o=Br(r);return i[2]-i[0]<=o[2]-o[0]&&i[3]-i[1]<=o[3]-o[1]?i:[Math.max(i[0],o[0]),Math.max(i[1],o[1]),Math.min(i[2],o[2]),Math.min(i[3],o[3])]}function Br(i){let e=i[2]-i[0],t=i[3]-i[1],r=(i[0]+i[2])/2,o=(i[1]+i[3])/2;return[r-e,o-t,r+e,o+t]}var q=class{constructor(){this.id="mask-effect",this.props=null,this.useInPicking=!0,this.order=0,this.channels=[],this.masks=null}setup({device:e}){this.dummyMaskMap=e.createTexture({width:1,height:1}),this.maskPass=new U(e,{id:"default-mask"}),this.maskMap=this.maskPass.maskMap}preRender({layers:e,layerFilter:t,viewports:r,onViewportActive:o,views:s,effects:n,isPicking:a}){let l=!1;if(a)return{didRender:l};let f=e.filter(m=>m.props.visible&&m.props.operation.includes("mask"));if(f.length===0)return this.masks=null,this.channels.length=0,{didRender:l};this.masks={};let u=this._sortMaskChannels(f),c=r[0],p=!this.lastViewport||!this.lastViewport.equals(c);if(c.resolution!==void 0)return Me.log.warn("MaskExtension is not supported in GlobeView")(),{didRender:l};for(let m in u){let h=this._renderChannel(u[m],{layerFilter:t,onViewportActive:o,views:s,effects:n,viewport:c,viewportChanged:p});l||(l=h)}return{didRender:l}}_renderChannel(e,{layerFilter:t,onViewportActive:r,views:o,effects:s,viewport:n,viewportChanged:a}){let l=!1,f=this.channels[e.index];if(!f)return l;let u=e===f||e.layers.length!==f.layers.length||e.layers.some((c,p)=>c!==f.layers[p]||c.props.transitions)||e.layerBounds.some((c,p)=>c!==f.layerBounds[p]);if(e.bounds=f.bounds,e.maskBounds=f.maskBounds,this.channels[e.index]=e,u||a){this.lastViewport=n;let c=T(e.layers,n);if(e.bounds=c&&L(c,n),u||!M(e.bounds,f.bounds)){let{maskPass:p,maskMap:m}=this,h=c&&O({bounds:e.bounds,viewport:n,width:m.width,height:m.height,border:1});e.maskBounds=h?h.getBounds():[0,0,1,1],p.render({pass:"mask",channel:e.index,layers:e.layers,layerFilter:t,viewports:h?[h]:[],onViewportActive:r,views:o,effects:s,shaderModuleProps:{project:{devicePixelRatio:1}}}),l=!0}}return this.masks[e.id]={index:e.index,bounds:e.maskBounds,coordinateOrigin:e.coordinateOrigin,coordinateSystem:e.coordinateSystem},l}_sortMaskChannels(e){let t={},r=0;for(let o of e){let{id:s}=o.root,n=t[s];if(!n){if(++r>4){Me.log.warn("Too many mask layers. The max supported is 4")();continue}n={id:s,index:this.channels.findIndex(a=>a?.id===s),layers:[],layerBounds:[],coordinateOrigin:o.root.props.coordinateOrigin,coordinateSystem:o.root.props.coordinateSystem},t[s]=n}n.layers.push(o),n.layerBounds.push(o.getBounds())}for(let o=0;o<4;o++){let s=this.channels[o];(!s||!(s.id in t))&&(this.channels[o]=null)}for(let o in t){let s=t[o];s.index<0&&(s.index=this.channels.findIndex(n=>!n),this.channels[s.index]=s)}return t}getShaderModuleProps(){return{mask:{maskMap:this.masks?this.maskMap:this.dummyMaskMap,maskChannels:this.masks}}}cleanup(){this.dummyMaskMap&&(this.dummyMaskMap.delete(),this.dummyMaskMap=void 0),this.maskPass&&(this.maskPass.delete(),this.maskPass=void 0,this.maskMap=void 0),this.lastViewport=void 0,this.masks=null,this.channels.length=0}};var Dr={maskId:"",maskByInstance:void 0,maskInverted:!1},W=class extends b.LayerExtension{initializeState(){this.context.deck?._addDefaultEffect(new q)}getShaders(){let e="instancePositions"in this.getAttributeManager().attributes;return this.props.maskByInstance!==void 0&&(e=Boolean(this.props.maskByInstance)),this.state.maskByInstance=e,{modules:[kt]}}draw({context:e,shaderModuleProps:t}){let r={};r.maskByInstance=Boolean(this.state.maskByInstance);let{maskId:o,maskInverted:s}=this.props,{maskChannels:n}=t.mask||{},{viewport:a}=e;if(n&&n[o]){let{index:l,bounds:f,coordinateOrigin:u}=n[o],{coordinateSystem:c}=n[o];r.enabled=!0,r.channel=l,r.inverted=s,c===b.COORDINATE_SYSTEM.DEFAULT&&(c=a.isGeospatial?b.COORDINATE_SYSTEM.LNGLAT:b.COORDINATE_SYSTEM.CARTESIAN);let p={modelMatrix:null,fromCoordinateOrigin:u,fromCoordinateSystem:c},m=this.projectPosition([f[0],f[1],0],p),h=this.projectPosition([f[2],f[3],0],p);r.bounds=[m[0],m[1],h[0],h[1]]}else o&&b.log.warn(`Could not find a mask layer with id: ${o}`)(),r.enabled=!1;this.setShaderModuleProps({mask:r})}};W.defaultProps=Dr;W.extensionName="MaskExtension";var Nt=W;var qt=d(_(),1);var Ht=d(_(),1);var Fe=d(_(),1),g={NONE:0,WRITE_HEIGHT_MAP:1,USE_HEIGHT_MAP:2,USE_COVER:3,USE_COVER_ONLY:4,SKIP:5},zr=Object.keys(g).map(i=>`const float TERRAIN_MODE_${i} = ${g[i]}.0;`).join(`
2180
- `),Bt=zr+`
3334
+ `},eo=t=>t&&"maskMap"in t?{mask_texture:t.maskMap}:t||{},fi={name:"mask",dependencies:[si.project],vs:$n,fs:Qn,inject:Jn,getUniforms:eo,uniformTypes:{bounds:"vec4<f32>",channel:"i32",enabled:"i32",inverted:"i32",maskByInstance:"i32"}};var Ue=_(h(),1);var ci=_(h(),1),to={blendColorOperation:"subtract",blendColorSrcFactor:"zero",blendColorDstFactor:"one",blendAlphaOperation:"subtract",blendAlphaSrcFactor:"zero",blendAlphaDstFactor:"one"},te=class extends ci._LayersPass{constructor(e,i){super(e,i);let{mapSize:r=2048}=i;this.maskMap=e.createTexture({format:"rgba8unorm",width:r,height:r,sampler:{minFilter:"linear",magFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"}}),this.fbo=e.createFramebuffer({id:"maskmap",width:r,height:r,colorAttachments:[this.maskMap]})}render(e){let i=2**e.channel,r=[255,255,255,255];super.render({...e,clearColor:r,colorMask:i,target:this.fbo,pass:"mask"})}getLayerParameters(e,i,r){return{...e.props.parameters,blend:!0,depthCompare:"always",...to}}shouldDrawLayer(e){return e.props.operation.includes("mask")}delete(){this.fbo.delete(),this.maskMap.delete()}};var ie=_(h(),1),ze=new ie.WebMercatorViewport({width:1,height:1,longitude:0,latitude:0,zoom:0});function re(t){let[e,i]=ze.projectPosition(t);return[e,i]}function ye(t){return t.isGeospatial?ze:t}function V(t,e){let i=[1/0,1/0,-1/0,-1/0];for(let r of t){let n=r.getBounds();if(n){let o=r.projectPosition(n[0],{viewport:e,autoOffset:!1}),a=r.projectPosition(n[1],{viewport:e,autoOffset:!1});i[0]=Math.min(i[0],o[0]),i[1]=Math.min(i[1],o[1]),i[2]=Math.max(i[2],a[0]),i[3]=Math.max(i[3],a[1])}}return Number.isFinite(i[0])?i:null}var io=2048;function j(t){let{bounds:e,viewport:i,border:r=0}=t,{isGeospatial:n}=i;if(e[2]<=e[0]||e[3]<=e[1])return null;let o=n?ze.unprojectPosition([(e[0]+e[2])/2,(e[1]+e[3])/2,0]):i.unprojectPosition([(e[0]+e[2])/2,(e[1]+e[3])/2,0]),{width:a,height:s,zoom:l}=t;if(l===void 0){a=a-r*2,s=s-r*2;let f=Math.min(a/(e[2]-e[0]),s/(e[3]-e[1]));l=Math.min(Math.log2(f),20)}else if(!a||!s){let f=2**l;a=Math.round(Math.abs(e[2]-e[0])*f),s=Math.round(Math.abs(e[3]-e[1])*f);let c=io-r*2;if(a>c||s>c){let u=c/Math.max(a,s);a=Math.round(a*u),s=Math.round(s*u),l+=Math.log2(u)}}return n?new ie.WebMercatorViewport({id:i.id,x:r,y:r,width:a,height:s,longitude:o[0],latitude:o[1],zoom:l,orthographic:!0}):new ie.OrthographicViewport({id:i.id,x:r,y:r,width:a,height:s,target:o,zoom:l,flipY:!1})}function ro(t,e){let i;if(e&&e.length===2){let[o,a]=e,s=t.getBounds({z:o}),l=t.getBounds({z:a});i=[Math.min(s[0],l[0]),Math.min(s[1],l[1]),Math.max(s[2],l[2]),Math.max(s[3],l[3])]}else i=t.getBounds();let r=t.projectPosition(i.slice(0,2)),n=t.projectPosition(i.slice(2,4));return[r[0],r[1],n[0],n[1]]}function H(t,e,i){if(!t)return[0,0,1,1];let r=ro(e,i),n=no(r);return t[2]-t[0]<=n[2]-n[0]&&t[3]-t[1]<=n[3]-n[1]?t:[Math.max(t[0],n[0]),Math.max(t[1],n[1]),Math.min(t[2],n[2]),Math.min(t[3],n[3])]}function no(t){let e=t[2]-t[0],i=t[3]-t[1],r=(t[0]+t[2])/2,n=(t[1]+t[3])/2;return[r-e,n-i,r+e,n+i]}var ne=class{constructor(){this.id="mask-effect",this.props=null,this.useInPicking=!0,this.order=0,this.channels=[],this.masks=null}setup({device:e}){this.dummyMaskMap=e.createTexture({width:1,height:1}),this.maskPass=new te(e,{id:"default-mask"}),this.maskMap=this.maskPass.maskMap}preRender({layers:e,layerFilter:i,viewports:r,onViewportActive:n,views:o,effects:a,isPicking:s}){let l=!1;if(s)return{didRender:l};let f=e.filter(p=>p.props.visible&&p.props.operation.includes("mask"));if(f.length===0)return this.masks=null,this.channels.length=0,{didRender:l};this.masks={};let c=this._sortMaskChannels(f),u=r[0],d=!this.lastViewport||!this.lastViewport.equals(u);if(u.resolution!==void 0)return Ue.log.warn("MaskExtension is not supported in GlobeView")(),{didRender:l};for(let p in c){let m=this._renderChannel(c[p],{layerFilter:i,onViewportActive:n,views:o,effects:a,viewport:u,viewportChanged:d});l||(l=m)}return{didRender:l}}_renderChannel(e,{layerFilter:i,onViewportActive:r,views:n,effects:o,viewport:a,viewportChanged:s}){let l=!1,f=this.channels[e.index];if(!f)return l;let c=e===f||e.layers.length!==f.layers.length||e.layers.some((u,d)=>u!==f.layers[d]||u.props.transitions)||e.layerBounds.some((u,d)=>u!==f.layerBounds[d]);if(e.bounds=f.bounds,e.maskBounds=f.maskBounds,this.channels[e.index]=e,c||s){this.lastViewport=a;let u=V(e.layers,a);if(e.bounds=u&&H(u,a),c||!z(e.bounds,f.bounds)){let{maskPass:d,maskMap:p}=this,m=u&&j({bounds:e.bounds,viewport:a,width:p.width,height:p.height,border:1});e.maskBounds=m?m.getBounds():[0,0,1,1],d.render({pass:"mask",channel:e.index,layers:e.layers,layerFilter:i,viewports:m?[m]:[],onViewportActive:r,views:n,effects:o,shaderModuleProps:{project:{devicePixelRatio:1}}}),l=!0}}return this.masks[e.id]={index:e.index,bounds:e.maskBounds,coordinateOrigin:e.coordinateOrigin,coordinateSystem:e.coordinateSystem},l}_sortMaskChannels(e){let i={},r=0;for(let n of e){let{id:o}=n.root,a=i[o];if(!a){if(++r>4){Ue.log.warn("Too many mask layers. The max supported is 4")();continue}a={id:o,index:this.channels.findIndex(s=>s?.id===o),layers:[],layerBounds:[],coordinateOrigin:n.root.props.coordinateOrigin,coordinateSystem:n.root.props.coordinateSystem},i[o]=a}a.layers.push(n),a.layerBounds.push(n.getBounds())}for(let n=0;n<4;n++){let o=this.channels[n];(!o||!(o.id in i))&&(this.channels[n]=null)}for(let n in i){let o=i[n];o.index<0&&(o.index=this.channels.findIndex(a=>!a),this.channels[o.index]=o)}return i}getShaderModuleProps(){return{mask:{maskMap:this.masks?this.maskMap:this.dummyMaskMap,maskChannels:this.masks}}}cleanup(){this.dummyMaskMap&&(this.dummyMaskMap.delete(),this.dummyMaskMap=void 0),this.maskPass&&(this.maskPass.delete(),this.maskPass=void 0,this.maskMap=void 0),this.lastViewport=void 0,this.masks=null,this.channels.length=0}};var oo={maskId:"",maskByInstance:void 0,maskInverted:!1},oe=class extends C.LayerExtension{initializeState(){this.context.deck?._addDefaultEffect(new ne)}getShaders(){let e="instancePositions"in this.getAttributeManager().attributes;return this.props.maskByInstance!==void 0&&(e=!!this.props.maskByInstance),this.state.maskByInstance=e,{modules:[fi]}}draw({context:e,shaderModuleProps:i}){let r={};r.maskByInstance=!!this.state.maskByInstance;let{maskId:n,maskInverted:o}=this.props,{maskChannels:a}=i.mask||{},{viewport:s}=e;if(a&&a[n]){let{index:l,bounds:f,coordinateOrigin:c}=a[n],{coordinateSystem:u}=a[n];r.enabled=!0,r.channel=l,r.inverted=o,u===C.COORDINATE_SYSTEM.DEFAULT&&(u=s.isGeospatial?C.COORDINATE_SYSTEM.LNGLAT:C.COORDINATE_SYSTEM.CARTESIAN);let d={modelMatrix:null,fromCoordinateOrigin:c,fromCoordinateSystem:u},p=this.projectPosition([f[0],f[1],0],d),m=this.projectPosition([f[2],f[3],0],d);r.bounds=[p[0],p[1],m[0],m[1]]}else n&&C.log.warn(`Could not find a mask layer with id: ${n}`)(),r.enabled=!1;this.setShaderModuleProps({mask:r})}};oe.defaultProps=oo;oe.extensionName="MaskExtension";var ui=oe;var bi=_(h(),1);var xi=_(h(),1);var Ve=_(h(),1),y={NONE:0,WRITE_HEIGHT_MAP:1,USE_HEIGHT_MAP:2,USE_COVER:3,USE_COVER_ONLY:4,SKIP:5},ao=Object.keys(y).map(t=>`const float TERRAIN_MODE_${t} = ${y[t]}.0;`).join(`
3335
+ `),di=ao+`
2181
3336
  layout(std140) uniform terrainUniforms {
2182
3337
  float mode;
2183
3338
  vec4 bounds;
2184
3339
  } terrain;
2185
3340
 
2186
3341
  uniform sampler2D terrain_map;
2187
- `,Y={name:"terrain",dependencies:[Fe.project],vs:`${Bt}
3342
+ `,ae={name:"terrain",dependencies:[Ve.project],vs:`${di}
2188
3343
  out vec3 commonPos;
2189
3344
  // In globe mode, absolute Mercator position for terrain FBO UV lookups
2190
3345
  out vec2 terrainMercPos;
@@ -2197,7 +3352,7 @@ vec2 terrain_globe_to_mercator(vec3 globePosition) {
2197
3352
  float y = atanh(sinLat);
2198
3353
  return (vec2(x, y) + PI) * WORLD_SCALE;
2199
3354
  }
2200
- `,fs:`${Bt}in vec2 terrainMercPos;
3355
+ `,fs:`${di}in vec2 terrainMercPos;
2201
3356
  in float terrainHeight;`,inject:{"vs:#main-start":`
2202
3357
  if (terrain.mode == TERRAIN_MODE_SKIP) {
2203
3358
  gl_Position = vec4(0.0);
@@ -2254,6 +3409,6 @@ if ((terrain.mode == TERRAIN_MODE_USE_COVER) || (terrain.mode == TERRAIN_MODE_US
2254
3409
  }
2255
3410
  return;
2256
3411
  }
2257
- `},getUniforms:(i={})=>{if(!i.dummyHeightMap)return{};if("terrainSkipRender"in i||"drawToTerrainHeightMap"in i){let{drawToTerrainHeightMap:e,heightMap:t,heightMapBounds:r,dummyHeightMap:o,terrainCover:s,useTerrainHeightMap:n,terrainSkipRender:a}=i,l=Fe.project.getUniforms(i.project),{commonOrigin:f}=l,u=a?g.SKIP:g.NONE,c=o,p=null;if(e)u=g.WRITE_HEIGHT_MAP,p=r;else if(n&&t)u=g.USE_HEIGHT_MAP,c=t,p=r;else if(s){let h=(i.isPicking?s.getPickingFramebuffer():s.getRenderFramebuffer())?.colorAttachments[0].texture;i.isPicking&&(u=g.SKIP),h?(c=h,u=u===g.SKIP?g.USE_COVER_ONLY:g.USE_COVER,p=s.bounds):i.isPicking&&!a&&(u=g.NONE)}return{mode:u,terrain_map:c,bounds:p?[p[0]-f[0],p[1]-f[1],p[2]-p[0],p[3]-p[1]]:[0,0,0,0]}}return{mode:g.NONE,terrain_map:i.dummyHeightMap,bounds:[0,0,0,0]}},uniformTypes:{mode:"f32",bounds:"vec4<f32>"}};var Dt=d(_(),1);function K(i,e){return i.createFramebuffer({id:e.id,colorAttachments:[i.createTexture({id:e.id,...e.float&&{format:"rgba32float",type:5126},dimension:"2d",width:1,height:1,sampler:e.interpolate===!1?{minFilter:"nearest",magFilter:"nearest"}:{minFilter:"linear",magFilter:"linear"}})]})}var ae=class{constructor(e){this.isDirty=!0,this.renderViewport=null,this.bounds=null,this.layers=[],this.targetBounds=null,this.targetBoundsCommon=null,this.targetLayer=e,this.tile=zt(e)}get id(){return this.targetLayer.id}get isActive(){return Boolean(this.targetLayer.getCurrentLayer())}shouldUpdate({targetLayer:e,viewport:t,layers:r,layerNeedsRedraw:o}){e&&(this.targetLayer=e);let s=t?this._updateViewport(t):!1,n=r?this._updateLayers(r):!1;if(o){for(let a of this.layers)if(o[a]){n=!0;break}}return n||s}_updateLayers(e){let t=!1;if(e=this.tile?Vr(this.tile,e):e,e.length!==this.layers.length)t=!0;else for(let r=0;r<e.length;r++)if(e[r].id!==this.layers[r]){t=!0;break}return t&&(this.layers=e.map(r=>r.id)),t}_updateViewport(e){let t=this.targetLayer,r=!1;if(this.tile&&"boundingBox"in this.tile){if(!this.targetBounds){r=!0,this.targetBounds=this.tile.boundingBox;let s=H(this.targetBounds[0]),n=H(this.targetBounds[1]);this.targetBoundsCommon=[s[0],s[1],n[0],n[1]]}}else this.targetBounds!==t.getBounds()&&(r=!0,this.targetBounds=t.getBounds(),this.targetBoundsCommon=T([t],ne(e)));if(!this.targetBoundsCommon)return!1;let o=Math.ceil(e.zoom+.5);if(this.tile)this.bounds=this.targetBoundsCommon;else{let s=this.renderViewport?.zoom;r=r||o!==s;let n=e instanceof Dt._GlobeViewport?this.targetBoundsCommon:L(this.targetBoundsCommon,e),a=this.bounds;r=r||!a||n.some((l,f)=>l!==a[f]),this.bounds=n}return r&&(this.renderViewport=O({bounds:this.bounds,zoom:o,viewport:e})),r}getRenderFramebuffer(){return!this.renderViewport||this.layers.length===0?null:(this.fbo||(this.fbo=K(this.targetLayer.context.device,{id:this.id})),this.fbo)}getPickingFramebuffer(){return!this.renderViewport||this.layers.length===0&&!this.targetLayer.props.pickable?null:(this.pickingFbo||(this.pickingFbo=K(this.targetLayer.context.device,{id:`${this.id}-picking`,interpolate:!1})),this.pickingFbo)}filterLayers(e){return e.filter(({id:t})=>this.layers.includes(t))}delete(){let{fbo:e,pickingFbo:t}=this;e&&(e.colorAttachments[0].destroy(),e.destroy()),t&&(t.colorAttachments[0].destroy(),t.destroy())}};function Vr(i,e){return e.filter(t=>{let r=zt(t);return r?jr(i.boundingBox,r.boundingBox):!0})}function zt(i){for(;i;){let{tile:e}=i.props;if(e)return e;i=i.parent}return null}function jr(i,e){return i&&e?i[0][0]<e[1][0]&&e[0][0]<i[1][0]&&i[0][1]<e[1][1]&&e[0][1]<i[1][1]:!1}var Vt=d(_(),1),Ur={blendColorOperation:"max",blendColorSrcFactor:"one",blendColorDstFactor:"one",blendAlphaOperation:"max",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one"},le=class extends Vt._LayersPass{getRenderableLayers(e,t){let{layers:r}=t,o=[],s=this._getDrawLayerParams(e,t,!0);for(let n=0;n<r.length;n++){let a=r[n];!a.isComposite&&s[n].shouldDrawLayer&&o.push(a)}return o}renderHeightMap(e,t){let r=e.getRenderFramebuffer(),o=e.renderViewport;!r||!o||(r.resize(o),this.render({...t,target:r,pass:"terrain-height-map",layers:t.layers,viewports:[o],effects:[],clearColor:[0,0,0,0]}))}renderTerrainCover(e,t){let r=e.getRenderFramebuffer(),o=e.renderViewport;if(!r||!o)return;let s=e.filterLayers(t.layers);r.resize(o),this.render({...t,target:r,pass:`terrain-cover-${e.id}`,layers:s,viewports:[o],clearColor:[0,0,0,0]})}getLayerParameters(e,t,r){return{...e.props.parameters,blend:!0,depthCompare:"always",...e.props.operation.includes("terrain")&&Ur}}getShaderModuleProps(e,t,r){return{terrain:{project:r.project}}}};var jt=d(_(),1),fe=class extends jt._PickLayersPass{constructor(){super(...arguments),this.drawParameters={}}getRenderableLayers(e,t){let{layers:r}=t,o=[];this.drawParameters={},this._resetColorEncoder(t.pickZ);let s=this._getDrawLayerParams(e,t);for(let n=0;n<r.length;n++){let a=r[n];!a.isComposite&&s[n].shouldDrawLayer&&(o.push(a),this.drawParameters[a.id]=s[n].layerParameters)}return o}renderTerrainCover(e,t){let r=e.getPickingFramebuffer(),o=e.renderViewport;if(!r||!o)return;let s=e.filterLayers(t.layers),n=e.targetLayer;n.props.pickable&&s.unshift(n),r.resize(o);let l=this.drawParameters[n.id]?.blendColor?.[3]??0;this.render({...t,pickingFBO:r,pass:`terrain-cover-picking-${e.id}`,layers:s,viewports:[o],cullRect:void 0,deviceRect:o,pickZ:!1,clearColor:[0,0,0,l]})}getLayerParameters(e,t,r){let o;return this.drawParameters[e.id]?o=this.drawParameters[e.id]:(o=super.getLayerParameters(e,t,r),o.blend=!0),{...o,depthCompare:"always",blendAlphaSrcFactor:"constant"}}getShaderModuleProps(e,t,r){return{...super.getShaderModuleProps(e,t,r),terrain:{project:r.project}}}};var Gt=d(_(),1),Ut=2048,$=class{static isSupported(e){return e.isTextureFormatRenderable("rgba32float")}constructor(e){this.renderViewport=null,this.bounds=null,this.layers=[],this.layersBounds=[],this.layersBoundsCommon=null,this.lastViewport=null,this.device=e}getRenderFramebuffer(){return this.renderViewport?(this.fbo||(this.fbo=K(this.device,{id:"height-map",float:!0})),this.fbo):null}shouldUpdate({layers:e,viewport:t}){let r=e.length!==this.layers.length||e.some((s,n)=>s!==this.layers[n]||s.props.transitions||s.getBounds()!==this.layersBounds[n]);r&&(this.layers=e,this.layersBounds=e.map(s=>s.getBounds()),this.layersBoundsCommon=T(e,ne(t)));let o=!this.lastViewport||!t.equals(this.lastViewport);if(!this.layersBoundsCommon)this.renderViewport=null;else if(r||o){let s=t instanceof Gt._GlobeViewport?this.layersBoundsCommon:L(this.layersBoundsCommon,t);if(s[2]<=s[0]||s[3]<=s[1])return this.renderViewport=null,!1;this.bounds=s,this.lastViewport=t;let n=t.scale,a=(s[2]-s[0])*n,l=(s[3]-s[1])*n,f=t.isGeospatial?H([t.longitude??0,t.latitude??0]):[t.center[0],t.center[1]];return this.renderViewport=a>0||l>0?O({bounds:[f[0]-1,f[1]-1,f[0]+1,f[1]+1],zoom:t.zoom,width:Math.min(a,Ut),height:Math.min(l,Ut),viewport:t}):null,!0}return!1}delete(){this.fbo&&(this.fbo.colorAttachments[0].delete(),this.fbo.delete())}};var ce=class{constructor(){this.id="terrain-effect",this.props=null,this.useInPicking=!0,this.isPicking=!1,this.isDrapingEnabled=!1,this.terrainCovers=new Map}setup({device:e,deck:t}){this.dummyHeightMap=e.createTexture({width:1,height:1,data:new Uint8Array([0,0,0,0])}),this.terrainPass=new le(e,{id:"terrain"}),this.terrainPickingPass=new fe(e,{id:"terrain-picking"}),$.isSupported(e)?this.heightMap=new $(e):Ht.log.warn("Terrain offset mode is not supported by this browser")(),t._addDefaultShaderModule(Y)}preRender(e){if(e.pickZ){this.isDrapingEnabled=!1;return}let{viewports:t}=e,r=e.pass.startsWith("picking");this.isPicking=r,this.isDrapingEnabled=!0;let o=t[0],s=(r?this.terrainPickingPass:this.terrainPass).getRenderableLayers(o,e),n=s.filter(f=>f.props.operation.includes("terrain"));if(n.length===0)return;r||s.filter(u=>u.state.terrainDrawMode==="offset").length>0&&this._updateHeightMap(n,o,e);let a=s.filter(f=>f.state.terrainDrawMode==="drape"),l=e.effects?.filter(f=>f!==this);this._updateTerrainCovers(n,a,o,{...e,effects:l})}getShaderModuleProps(e,t){if(e.props.operation.includes("mask"))return{terrain:{dummyHeightMap:this.dummyHeightMap}};let{terrainDrawMode:r}=e.state,o=this.isDrapingEnabled?this.terrainCovers.get(e.id)??null:null;return this.isPicking&&e.props.operation.includes("terrain")&&(e.state._hasPickingCover=Boolean(o?.getPickingFramebuffer())),{terrain:{project:t.project,isPicking:this.isPicking,heightMap:this.heightMap?.getRenderFramebuffer()?.colorAttachments[0].texture||null,heightMapBounds:this.heightMap?.bounds,dummyHeightMap:this.dummyHeightMap,terrainCover:o,useTerrainHeightMap:r==="offset",terrainSkipRender:r==="drape"||!e.props.operation.includes("draw")}}}cleanup({deck:e}){this.dummyHeightMap&&(this.dummyHeightMap.delete(),this.dummyHeightMap=void 0),this.heightMap&&(this.heightMap.delete(),this.heightMap=void 0);for(let t of this.terrainCovers.values())t.delete();this.terrainCovers.clear(),e._removeDefaultShaderModule(Y)}_updateHeightMap(e,t,r){!this.heightMap||!this.heightMap.shouldUpdate({layers:e,viewport:t})||this.terrainPass.renderHeightMap(this.heightMap,{...r,layers:e,shaderModuleProps:{terrain:{heightMapBounds:this.heightMap.bounds,dummyHeightMap:this.dummyHeightMap,drawToTerrainHeightMap:!0},project:{devicePixelRatio:1}}})}_updateTerrainCovers(e,t,r,o){let s={};for(let n of t)n.state.terrainCoverNeedsRedraw&&(s[n.id]=!0,n.state.terrainCoverNeedsRedraw=!1);for(let n of this.terrainCovers.values())n.isDirty=n.isDirty||n.shouldUpdate({layerNeedsRedraw:s});for(let n of e)this._updateTerrainCover(n,t,r,o);this.isPicking||this._pruneTerrainCovers()}_updateTerrainCover(e,t,r,o){let s=this.isPicking?this.terrainPickingPass:this.terrainPass,n=this.terrainCovers.get(e.id);n||(n=new ae(e),this.terrainCovers.set(e.id,n));try{let a=n.shouldUpdate({targetLayer:e,viewport:r,layers:t});(this.isPicking||n.isDirty||a)&&(s.renderTerrainCover(n,{...o,layers:t,shaderModuleProps:{terrain:{dummyHeightMap:this.dummyHeightMap,terrainSkipRender:!1},project:{devicePixelRatio:1}}}),this.isPicking||(n.isDirty=!1))}catch(a){e.raiseError(a,`Error rendering terrain cover ${n.id}`)}}_pruneTerrainCovers(){let e=[];for(let[t,r]of this.terrainCovers)r.isActive||e.push(t);for(let t of e)this.terrainCovers.delete(t)}};var Gr={terrainDrawMode:void 0},Z=class extends qt.LayerExtension{getShaders(){return{modules:[Y]}}initializeState(){this.context.deck?._addDefaultEffect(new ce)}updateState(e){let{props:t,oldProps:r}=e;if(this.state.terrainDrawMode&&t.terrainDrawMode===r.terrainDrawMode&&t.extruded===r.extruded)return;let{terrainDrawMode:o}=t;if(!o){let s=this.props.extruded,n=this.getAttributeManager()?.attributes,a=n&&"instancePositions"in n;o=s||a?"offset":"drape"}this.setState({terrainDrawMode:o})}onNeedsRedraw(){let e=this.state;e.terrainDrawMode==="drape"&&(e.terrainCoverNeedsRedraw=!0)}};Z.defaultProps=Gr;Z.extensionName="TerrainExtension";var Wt=Z;return Xt(J);})();
3412
+ `},getUniforms:(t={})=>{if(!t.dummyHeightMap)return{};if("terrainSkipRender"in t||"drawToTerrainHeightMap"in t){let{drawToTerrainHeightMap:e,heightMap:i,heightMapBounds:r,dummyHeightMap:n,terrainCover:o,useTerrainHeightMap:a,terrainSkipRender:s}=t,l=Ve.project.getUniforms(t.project),{commonOrigin:f}=l,c=s?y.SKIP:y.NONE,u=n,d=null;if(e)c=y.WRITE_HEIGHT_MAP,d=r;else if(a&&i)c=y.USE_HEIGHT_MAP,u=i,d=r;else if(o){let m=(t.isPicking?o.getPickingFramebuffer():o.getRenderFramebuffer())?.colorAttachments[0].texture;t.isPicking&&(c=y.SKIP),m?(u=m,c=c===y.SKIP?y.USE_COVER_ONLY:y.USE_COVER,d=o.bounds):t.isPicking&&!s&&(c=y.NONE)}return{mode:c,terrain_map:u,bounds:d?[d[0]-f[0],d[1]-f[1],d[2]-d[0],d[3]-d[1]]:[0,0,0,0]}}return{mode:y.NONE,terrain_map:t.dummyHeightMap,bounds:[0,0,0,0]}},uniformTypes:{mode:"f32",bounds:"vec4<f32>"}};var pi=_(h(),1);function se(t,e){return t.createFramebuffer({id:e.id,colorAttachments:[t.createTexture({id:e.id,...e.float&&{format:"rgba32float",type:5126},dimension:"2d",width:1,height:1,sampler:e.interpolate===!1?{minFilter:"nearest",magFilter:"nearest"}:{minFilter:"linear",magFilter:"linear"}})]})}var Pe=class{constructor(e){this.isDirty=!0,this.renderViewport=null,this.bounds=null,this.layers=[],this.targetBounds=null,this.targetBoundsCommon=null,this.targetLayer=e,this.tile=_i(e)}get id(){return this.targetLayer.id}get isActive(){return!!this.targetLayer.getCurrentLayer()}shouldUpdate({targetLayer:e,viewport:i,layers:r,layerNeedsRedraw:n}){e&&(this.targetLayer=e);let o=i?this._updateViewport(i):!1,a=r?this._updateLayers(r):!1;if(n){for(let s of this.layers)if(n[s]){a=!0;break}}return a||o}_updateLayers(e){let i=!1;if(e=this.tile?so(this.tile,e):e,e.length!==this.layers.length)i=!0;else for(let r=0;r<e.length;r++)if(e[r].id!==this.layers[r]){i=!0;break}return i&&(this.layers=e.map(r=>r.id)),i}_updateViewport(e){let i=this.targetLayer,r=!1;if(this.tile&&"boundingBox"in this.tile){if(!this.targetBounds){r=!0,this.targetBounds=this.tile.boundingBox;let o=re(this.targetBounds[0]),a=re(this.targetBounds[1]);this.targetBoundsCommon=[o[0],o[1],a[0],a[1]]}}else this.targetBounds!==i.getBounds()&&(r=!0,this.targetBounds=i.getBounds(),this.targetBoundsCommon=V([i],ye(e)));if(!this.targetBoundsCommon)return!1;let n=Math.ceil(e.zoom+.5);if(this.tile)this.bounds=this.targetBoundsCommon;else{let o=this.renderViewport?.zoom;r=r||n!==o;let a=e instanceof pi._GlobeViewport?this.targetBoundsCommon:H(this.targetBoundsCommon,e),s=this.bounds;r=r||!s||a.some((l,f)=>l!==s[f]),this.bounds=a}return r&&(this.renderViewport=j({bounds:this.bounds,zoom:n,viewport:e})),r}getRenderFramebuffer(){return!this.renderViewport||this.layers.length===0?null:(this.fbo||(this.fbo=se(this.targetLayer.context.device,{id:this.id})),this.fbo)}getPickingFramebuffer(){return!this.renderViewport||this.layers.length===0&&!this.targetLayer.props.pickable?null:(this.pickingFbo||(this.pickingFbo=se(this.targetLayer.context.device,{id:`${this.id}-picking`,interpolate:!1})),this.pickingFbo)}filterLayers(e){return e.filter(({id:i})=>this.layers.includes(i))}delete(){let{fbo:e,pickingFbo:i}=this;e&&(e.colorAttachments[0].destroy(),e.destroy()),i&&(i.colorAttachments[0].destroy(),i.destroy())}};function so(t,e){return e.filter(i=>{let r=_i(i);return r?lo(t.boundingBox,r.boundingBox):!0})}function _i(t){for(;t;){let{tile:e}=t.props;if(e)return e;t=t.parent}return null}function lo(t,e){return t&&e?t[0][0]<e[1][0]&&e[0][0]<t[1][0]&&t[0][1]<e[1][1]&&e[0][1]<t[1][1]:!1}var hi=_(h(),1),fo={blendColorOperation:"max",blendColorSrcFactor:"one",blendColorDstFactor:"one",blendAlphaOperation:"max",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one"},Ee=class extends hi._LayersPass{getRenderableLayers(e,i){let{layers:r}=i,n=[],o=this._getDrawLayerParams(e,i,!0);for(let a=0;a<r.length;a++){let s=r[a];!s.isComposite&&o[a].shouldDrawLayer&&n.push(s)}return n}renderHeightMap(e,i){let r=e.getRenderFramebuffer(),n=e.renderViewport;!r||!n||(r.resize(n),this.render({...i,target:r,pass:"terrain-height-map",layers:i.layers,viewports:[n],effects:[],clearColor:[0,0,0,0]}))}renderTerrainCover(e,i){let r=e.getRenderFramebuffer(),n=e.renderViewport;if(!r||!n)return;let o=e.filterLayers(i.layers);r.resize(n),this.render({...i,target:r,pass:`terrain-cover-${e.id}`,layers:o,viewports:[n],clearColor:[0,0,0,0]})}getLayerParameters(e,i,r){return{...e.props.parameters,blend:!0,depthCompare:"always",...e.props.operation.includes("terrain")&&fo}}getShaderModuleProps(e,i,r){return{terrain:{project:r.project}}}};var mi=_(h(),1),Me=class extends mi._PickLayersPass{constructor(){super(...arguments),this.drawParameters={}}getRenderableLayers(e,i){let{layers:r}=i,n=[];this.drawParameters={},this._resetColorEncoder(i.pickZ);let o=this._getDrawLayerParams(e,i);for(let a=0;a<r.length;a++){let s=r[a];!s.isComposite&&o[a].shouldDrawLayer&&(n.push(s),this.drawParameters[s.id]=o[a].layerParameters)}return n}renderTerrainCover(e,i){let r=e.getPickingFramebuffer(),n=e.renderViewport;if(!r||!n)return;let o=e.filterLayers(i.layers),a=e.targetLayer;a.props.pickable&&o.unshift(a),r.resize(n);let l=this.drawParameters[a.id]?.blendColor?.[3]??0;this.render({...i,pickingFBO:r,pass:`terrain-cover-picking-${e.id}`,layers:o,viewports:[n],cullRect:void 0,deviceRect:n,pickZ:!1,clearColor:[0,0,0,l]})}getLayerParameters(e,i,r){let n;return this.drawParameters[e.id]?n=this.drawParameters[e.id]:(n=super.getLayerParameters(e,i,r),n.blend=!0),{...n,depthCompare:"always",blendAlphaSrcFactor:"constant"}}getShaderModuleProps(e,i,r){return{...super.getShaderModuleProps(e,i,r),terrain:{project:r.project}}}};var vi=_(h(),1),gi=2048,le=class{static isSupported(e){return e.isTextureFormatRenderable("rgba32float")}constructor(e){this.renderViewport=null,this.bounds=null,this.layers=[],this.layersBounds=[],this.layersBoundsCommon=null,this.lastViewport=null,this.device=e}getRenderFramebuffer(){return this.renderViewport?(this.fbo||(this.fbo=se(this.device,{id:"height-map",float:!0})),this.fbo):null}shouldUpdate({layers:e,viewport:i}){let r=e.length!==this.layers.length||e.some((o,a)=>o!==this.layers[a]||o.props.transitions||o.getBounds()!==this.layersBounds[a]);r&&(this.layers=e,this.layersBounds=e.map(o=>o.getBounds()),this.layersBoundsCommon=V(e,ye(i)));let n=!this.lastViewport||!i.equals(this.lastViewport);if(!this.layersBoundsCommon)this.renderViewport=null;else if(r||n){let o=i instanceof vi._GlobeViewport?this.layersBoundsCommon:H(this.layersBoundsCommon,i);if(o[2]<=o[0]||o[3]<=o[1])return this.renderViewport=null,!1;this.bounds=o,this.lastViewport=i;let a=i.scale,s=(o[2]-o[0])*a,l=(o[3]-o[1])*a,f=i.isGeospatial?re([i.longitude??0,i.latitude??0]):[i.center[0],i.center[1]];return this.renderViewport=s>0||l>0?j({bounds:[f[0]-1,f[1]-1,f[0]+1,f[1]+1],zoom:i.zoom,width:Math.min(s,gi),height:Math.min(l,gi),viewport:i}):null,!0}return!1}delete(){this.fbo&&(this.fbo.colorAttachments[0].delete(),this.fbo.delete())}};var Ae=class{constructor(){this.id="terrain-effect",this.props=null,this.useInPicking=!0,this.isPicking=!1,this.isDrapingEnabled=!1,this.terrainCovers=new Map}setup({device:e,deck:i}){this.dummyHeightMap=e.createTexture({width:1,height:1,data:new Uint8Array([0,0,0,0])}),this.terrainPass=new Ee(e,{id:"terrain"}),this.terrainPickingPass=new Me(e,{id:"terrain-picking"}),le.isSupported(e)?this.heightMap=new le(e):xi.log.warn("Terrain offset mode is not supported by this browser")(),i._addDefaultShaderModule(ae)}preRender(e){if(e.pickZ){this.isDrapingEnabled=!1;return}let{viewports:i}=e,r=e.pass.startsWith("picking");this.isPicking=r,this.isDrapingEnabled=!0;let n=i[0],o=(r?this.terrainPickingPass:this.terrainPass).getRenderableLayers(n,e),a=o.filter(f=>f.props.operation.includes("terrain"));if(a.length===0)return;r||o.filter(c=>c.state.terrainDrawMode==="offset").length>0&&this._updateHeightMap(a,n,e);let s=o.filter(f=>f.state.terrainDrawMode==="drape"),l=e.effects?.filter(f=>f!==this);this._updateTerrainCovers(a,s,n,{...e,effects:l})}getShaderModuleProps(e,i){if(e.props.operation.includes("mask"))return{terrain:{dummyHeightMap:this.dummyHeightMap}};let{terrainDrawMode:r}=e.state,n=this.isDrapingEnabled?this.terrainCovers.get(e.id)??null:null;return this.isPicking&&e.props.operation.includes("terrain")&&(e.state._hasPickingCover=!!n?.getPickingFramebuffer()),{terrain:{project:i.project,isPicking:this.isPicking,heightMap:this.heightMap?.getRenderFramebuffer()?.colorAttachments[0].texture||null,heightMapBounds:this.heightMap?.bounds,dummyHeightMap:this.dummyHeightMap,terrainCover:n,useTerrainHeightMap:r==="offset",terrainSkipRender:r==="drape"||!e.props.operation.includes("draw")}}}cleanup({deck:e}){this.dummyHeightMap&&(this.dummyHeightMap.delete(),this.dummyHeightMap=void 0),this.heightMap&&(this.heightMap.delete(),this.heightMap=void 0);for(let i of this.terrainCovers.values())i.delete();this.terrainCovers.clear(),e._removeDefaultShaderModule(ae)}_updateHeightMap(e,i,r){!this.heightMap||!this.heightMap.shouldUpdate({layers:e,viewport:i})||this.terrainPass.renderHeightMap(this.heightMap,{...r,layers:e,shaderModuleProps:{terrain:{heightMapBounds:this.heightMap.bounds,dummyHeightMap:this.dummyHeightMap,drawToTerrainHeightMap:!0},project:{devicePixelRatio:1}}})}_updateTerrainCovers(e,i,r,n){let o={};for(let a of i)a.state.terrainCoverNeedsRedraw&&(o[a.id]=!0,a.state.terrainCoverNeedsRedraw=!1);for(let a of this.terrainCovers.values())a.isDirty=a.isDirty||a.shouldUpdate({layerNeedsRedraw:o});for(let a of e)this._updateTerrainCover(a,i,r,n);this.isPicking||this._pruneTerrainCovers()}_updateTerrainCover(e,i,r,n){let o=this.isPicking?this.terrainPickingPass:this.terrainPass,a=this.terrainCovers.get(e.id);a||(a=new Pe(e),this.terrainCovers.set(e.id,a));try{let s=a.shouldUpdate({targetLayer:e,viewport:r,layers:i});(this.isPicking||a.isDirty||s)&&(o.renderTerrainCover(a,{...n,layers:i,shaderModuleProps:{terrain:{dummyHeightMap:this.dummyHeightMap,terrainSkipRender:!1},project:{devicePixelRatio:1}}}),this.isPicking||(a.isDirty=!1))}catch(s){e.raiseError(s,`Error rendering terrain cover ${a.id}`)}}_pruneTerrainCovers(){let e=[];for(let[i,r]of this.terrainCovers)r.isActive||e.push(i);for(let i of e)this.terrainCovers.delete(i)}};var co={terrainDrawMode:void 0},fe=class extends bi.LayerExtension{getShaders(){return{modules:[ae]}}initializeState(){this.context.deck?._addDefaultEffect(new Ae)}updateState(e){let{props:i,oldProps:r}=e;if(this.state.terrainDrawMode&&i.terrainDrawMode===r.terrainDrawMode&&i.extruded===r.extruded)return;let{terrainDrawMode:n}=i;if(!n){let o=this.props.extruded,a=this.getAttributeManager()?.attributes,s=a&&"instancePositions"in a;n=o||s?"offset":"drape"}this.setState({terrainDrawMode:n})}onNeedsRedraw(){let e=this.state;e.terrainDrawMode==="drape"&&(e.terrainCoverNeedsRedraw=!0)}};fe.defaultProps=co;fe.extensionName="TerrainExtension";var yi=fe;return Oi(ce);})();
2258
3413
  return __exports__;
2259
3414
  });