@jscad/web 2.5.3 → 2.5.4

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 (56) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/data/themes.js +40 -40
  3. package/dist/jscad-web.min.js +46 -46
  4. package/examples/core/colors/basicColors.js +0 -1
  5. package/examples/core/colors/colorCube.js +10 -12
  6. package/examples/core/curves/bezier/extrudeAlongPath.js +20 -22
  7. package/examples/core/curves/bezier/simpleExtrude.js +4 -6
  8. package/examples/core/extrusions/basicExtrusions.js +3 -3
  9. package/examples/core/hulls/hull2D.js +3 -5
  10. package/examples/core/hulls/hull3D.js +3 -5
  11. package/examples/core/measurements/measureAggregateBounds.js +5 -7
  12. package/examples/core/measurements/measureAreaAndVolume.js +6 -8
  13. package/examples/core/measurements/measureBounds.js +5 -7
  14. package/examples/core/other/orientation.js +2 -3
  15. package/examples/core/primitives/dodecahedron.js +1 -3
  16. package/examples/core/primitives/polyhedron.js +12 -14
  17. package/examples/core/primitives/primitives2D.js +1 -3
  18. package/examples/core/primitives/primitives3D.js +2 -4
  19. package/examples/core/primitives/roundedCuboid.js +7 -9
  20. package/examples/core/primitives/sphere.js +10 -12
  21. package/examples/core/primitives/torus.js +20 -22
  22. package/examples/core/text/text.js +5 -8
  23. package/examples/core/transforms/align.js +5 -7
  24. package/examples/core/transforms/center.js +6 -8
  25. package/examples/import/AMFImport/index.js +1 -3
  26. package/examples/import/STLImport/index.js +4 -6
  27. package/examples/import/SVGImport/index.js +0 -1
  28. package/examples/module-design/mountPlate.js +5 -9
  29. package/examples/module-design/subFolder/sphereShape.js +1 -3
  30. package/examples/parameters/allParamTypes.js +19 -21
  31. package/examples/parameters/balloons.js +15 -26
  32. package/examples/parameters/gear.js +9 -11
  33. package/package.json +7 -7
  34. package/postInstall.js +3 -3
  35. package/src/index.js +0 -1
  36. package/src/most-gestures/drags.js +15 -0
  37. package/src/most-gestures/zooms.js +20 -1
  38. package/src/sideEffects/dat/index.js +0 -6
  39. package/src/sideEffects/dom/index.js +0 -2
  40. package/src/sideEffects/fileDialog/index.js +0 -2
  41. package/src/sideEffects/i18n/index.js +0 -1
  42. package/src/sideEffects/localFs/index.js +1 -4
  43. package/src/sideEffects/localFs/walkFileTree.js +1 -7
  44. package/src/sideEffects/localStorage/index.js +0 -1
  45. package/src/sideEffects/state/index.js +0 -11
  46. package/src/ui/flow/design.js +5 -26
  47. package/src/ui/flow/dom.js +0 -1
  48. package/src/ui/flow/flowOut.js +0 -24
  49. package/src/ui/flow/languages.js +0 -1
  50. package/src/ui/flow/shortcuts.js +0 -1
  51. package/src/ui/flow/themes.js +1 -1
  52. package/src/ui/flow/tools.js +0 -6
  53. package/src/ui/views/editor.js +0 -6
  54. package/src/ui/views/parameterControls.js +0 -1
  55. package/src/ui/views/status.js +4 -2
  56. package/src/utils/keys.js +0 -1
@@ -7,7 +7,7 @@
7
7
  },{}],3:[function(require,module,exports){
8
8
  module.exports={
9
9
  "name": "@jscad/core",
10
- "version": "2.5.3",
10
+ "version": "2.5.4",
11
11
  "description": "Core functionality for JSCAD Applications",
12
12
  "repository": "https://github.com/jscad/OpenJSCAD.org",
13
13
  "main": "src/index.js",
@@ -42,9 +42,9 @@ module.exports={
42
42
  "license": "MIT",
43
43
  "dependencies": {
44
44
  "@jscad/array-utils": "2.1.1",
45
- "@jscad/io": "2.2.3",
46
- "@jscad/io-utils": "2.0.12",
47
- "@jscad/modeling": "2.7.1",
45
+ "@jscad/io": "2.2.4",
46
+ "@jscad/io-utils": "2.0.13",
47
+ "@jscad/modeling": "2.7.2",
48
48
  "json5": "2.2.0",
49
49
  "strip-bom": "4.0.0"
50
50
  },
@@ -68,10 +68,10 @@ module.exports={rebuildGeometry:require("./rebuildGeometry"),rebuildGeometryCli:
68
68
  const isGeom2=require("@jscad/modeling").geometries.geom2.isA,isGeom3=require("@jscad/modeling").geometries.geom3.isA,isPath2=require("@jscad/modeling").geometries.path2.isA,{flatten:flatten,toArray:toArray}=require("@jscad/array-utils"),serializeSolids=require("./serializeSolids"),isResultGeometry=e=>!!(Array.isArray(e)&&e.length>0)&&e.reduce((e,i)=>e||isGeom3(i)||isGeom2(i)||isPath2(i),!1),instanciateDesign=(e,i,r)=>{const{serialize:s}=r;let t;const o=flatten(toArray(e.main(i)));if(isResultGeometry(o))return{solids:t=s?serializeSolids(o):o};throw new Error("bad output from script: expected geom3/geom2/path2 objects")};module.exports=instanciateDesign;
69
69
 
70
70
  },{"./serializeSolids":9,"@jscad/array-utils":884,"@jscad/modeling":580}],6:[function(require,module,exports){
71
- const loadDesign=require("../code-loading/loadDesign"),instanciateDesign=require("./instanciateDesign"),applyParameterDefinitions=require("../parameters/applyParameterDefinitions"),rebuildSolids=(e,a)=>{console.log("rebuildSolids",e);let{mainPath:i,apiMainPath:o,serialize:s,lookup:l,lookupCounts:n,parameterValues:t}=Object.assign({},{mainPath:"",apiMainPath:"@jscad/modeling",serialize:!1,lookup:null,lookupCounts:null,parameterValues:{}},e);const r=e.filesAndFolders,u=loadDesign(i,o,r,t);a(null,{type:"params",parameterDefaults:u.parameterValues,parameterDefinitions:u.parameterDefinitions}),t=applyParameterDefinitions(t,u.parameterDefinitions),t=Object.assign({},u.parameterValues,t);const p={lookup:l,lookupCounts:n,serialize:s},d=instanciateDesign(u.rootModule,t,p);a(null,{type:"solids",solids:d.solids,lookup:d.lookup,lookupCounts:d.lookupCounts})};module.exports=rebuildSolids;
71
+ const loadDesign=require("../code-loading/loadDesign"),instanciateDesign=require("./instanciateDesign"),applyParameterDefinitions=require("../parameters/applyParameterDefinitions"),rebuildSolids=(e,a)=>{let{mainPath:i,apiMainPath:o,serialize:s,lookup:l,lookupCounts:n,parameterValues:t}=Object.assign({},{mainPath:"",apiMainPath:"@jscad/modeling",serialize:!1,lookup:null,lookupCounts:null,parameterValues:{}},e);const r=e.filesAndFolders,p=loadDesign(i,o,r,t);a(null,{type:"params",parameterDefaults:p.parameterValues,parameterDefinitions:p.parameterDefinitions}),t=applyParameterDefinitions(t,p.parameterDefinitions),t=Object.assign({},p.parameterValues,t);const u={lookup:l,lookupCounts:n,serialize:s},d=instanciateDesign(p.rootModule,t,u);a(null,{type:"solids",solids:d.solids,lookup:d.lookup,lookupCounts:d.lookupCounts})};module.exports=rebuildSolids;
72
72
 
73
73
  },{"../code-loading/loadDesign":11,"../parameters/applyParameterDefinitions":22,"./instanciateDesign":5}],7:[function(require,module,exports){
74
- const path=require("path"),{toArray:toArray}=require("@jscad/array-utils"),requireDesignFromModule=require("../code-loading/requireDesignFromModule"),getAllParameterDefintionsAndValues=require("../parameters/getParameterDefinitionsAndValues"),makeWebRequire=require("../code-loading/webRequire"),rebuildSolids=e=>{let{apiMainPath:r,serialize:a,mainPath:i,parameterValues:s,useFakeFs:t}=Object.assign({},{apiMainPath:"@jscad/modeling",serialize:!1},e),u=require;if(t){const a=path.parse(i),s=`${a.name}.js`,t=`/${a.name}.js`,n=[{ext:"js",fullPath:t,name:s,source:e.source}];u=makeWebRequire(n,{apiMainPath:r}),i=t}const n=requireDesignFromModule(i,u),l=getAllParameterDefintionsAndValues(n,s);return toArray(n.main(l.parameterValues))};module.exports=rebuildSolids;
74
+ const path=require("path"),{toArray:toArray}=require("@jscad/array-utils"),requireDesignFromModule=require("../code-loading/requireDesignFromModule"),getAllParameterDefintionsAndValues=require("../parameters/getParameterDefinitionsAndValues"),makeWebRequire=require("../code-loading/webRequire"),rebuildSolids=e=>{let{apiMainPath:r,mainPath:a,parameterValues:i,useFakeFs:t}=Object.assign({},{apiMainPath:"@jscad/modeling"},e),s=require;if(t){const i=path.parse(a),t=`${i.name}.js`,u=`/${i.name}.js`,n=[{ext:"js",fullPath:u,name:t,source:e.source}];s=makeWebRequire(n,{apiMainPath:r}),a=u}const u=requireDesignFromModule(a,s),n=getAllParameterDefintionsAndValues(u,i);return toArray(u.main(n.parameterValues))};module.exports=rebuildSolids;
75
75
 
76
76
  },{"../code-loading/requireDesignFromModule":14,"../code-loading/webRequire":18,"../parameters/getParameterDefinitionsAndValues":23,"@jscad/array-utils":884,"path":1046}],8:[function(require,module,exports){
77
77
  const rebuildGeometryWorker=e=>{const o=require("./rebuildGeometry");e.onmessage=function(r){if(r.data instanceof Object){const{data:t}=r;"generate"===t.cmd&&o(t,(o,r)=>e.postMessage(r))}}};module.exports=rebuildGeometryWorker;
@@ -104,7 +104,7 @@ const{deserializers:deserializers}=require("@jscad/io"),modulifyTransform=(e,r)=
104
104
  const validateDesignModule=n=>{if(!n)throw new Error("undefined root module passed !");if("function"==typeof n&&console.warn("please use named exports for your main() function ! auto updating"),!("main"in n))throw new Error("no main() function found in the input script")};module.exports=validateDesignModule;
105
105
 
106
106
  },{}],18:[function(require,module,exports){
107
- const path=require("path"),posix=path.posix?path.posix:path,getFileExtensionFromString=require("../utils/getFileExtensionFromString"),{combineParameterDefinitions:combineParameterDefinitions,getParameterDefinitionsFromSource:getParameterDefinitionsFromSource}=require("../parameters/getParameterDefinitionsFromSource"),findMatch=(e,r)=>{for(let t=0;t<r.length;t++){const n=r[t];if(e===n.fullPath||"/"+e===n.fullPath)return n;if(n.children){const r=findMatch(e,n.children);if(void 0!==r)return r}}},registerJsExtension=(e,r)=>{const t=require("strip-bom");r.extensions[".js"]=((r,n)=>{const i=e.readFileSync(n,"utf8");r._compile(t(i),n)})},registerJsonExtension=(e,r)=>{r.extensions[".json"]=((r,t)=>{const n=e.readFileSync(t,"utf8");r.exports=JSON.parse(n)})},makeWebRequire=(e,r)=>{const t={apiMainPath:"@jscad/modeling",fakeFs:require("./makeFakeFs")(e)},{apiMainPath:n,fakeFs:i}=Object.assign({},t,r),s="@jscad/modeling"===n?require("@jscad/modeling"):require(n),o={"@jscad/io":{exports:require("@jscad/io")},"@jscad/array-utils":{exports:require("@jscad/array-utils")},"@jscad/modeling":{exports:s},fs:{exports:i}},a={},l={},u=(r,t)=>{const n=o[t];if(n)return n.exports;r&&!t.startsWith("/")||(r="/");const i=r=>{let t=getFileExtensionFromString(r);t||(t="js",r+=".js"),t="."+t;const n=findMatch(r,e);if(!n)return null;if(n.children)return null;if(a[t]){if(l[r])return l[r];const e={exports:{},_compile:(r,t)=>{new Function("require","module",r)(u.bind(null,n.fullPath),e);const i=r.includes("@jscad-params")?getParameterDefinitionsFromSource(r,t):[],s=e.exports.getParameterDefinitions;e.exports.getParameterDefinitions=(()=>combineParameterDefinitions(i,s&&s()||[]))}};return a[t](e,n.fullPath),l[r]=e.exports}return null},s=r=>{if(!findMatch(r,e))return null;"/"===r&&(r="");let t=r+"/index.js",n=i(t);return n||((n=i(t=r+"/index.json"))||null)},c=r=>{let t,n=findMatch(r,e);if(!n)return null;if(!n.children)return null;if(n=findMatch(r+"/package.json",e)){const e=JSON.parse(n.source).main;if(e){const n=posix.normalize(r+"/"+e);return(t=i(n))?t:(t=s(n))||null}}return(t=s(r))||null};if(t.startsWith("./")||t.startsWith("/")||t.startsWith("../")){t=posix.normalize(posix.dirname(r)+posix.sep+t);let e=i(t);if(e)return e;if(e=c(t))return e;throw new Error(`Cannot find relative path to module ${t}`)}const f=((e,r)=>{const t=(e=>{const r=e.split("/"),t=[];for(let e=r.length-1;e>0;e--){if("node_modules"===r[e])continue;const n=posix.sep+posix.join(...r.slice(1,e+1),"node_modules");t.push(n)}return t})(r);for(let r=0;r<t.length;r++){const n=t[r],s=posix.join(n,e);let o=i(s);if(o)return o;if(o=c(s))return o}return null})(t,posix.dirname(r));if(f)return f;throw new Error(`Cannot find module ${t}`)},c=u.bind(null,"/");return c.extensions=a,c.resolve=(()=>{}),registerJsExtension(i,c),registerJsonExtension(i,c),c};module.exports=makeWebRequire;
107
+ const path=require("path"),posix=path.posix?path.posix:path,getFileExtensionFromString=require("../utils/getFileExtensionFromString"),{combineParameterDefinitions:combineParameterDefinitions,getParameterDefinitionsFromSource:getParameterDefinitionsFromSource}=require("../parameters/getParameterDefinitionsFromSource"),findMatch=(e,r)=>{for(let t=0;t<r.length;t++){const n=r[t];if(e===n.fullPath||"/"+e===n.fullPath)return n;if(n.children){const r=findMatch(e,n.children);if(void 0!==r)return r}}},registerJsExtension=(e,r)=>{const t=require("strip-bom");r.extensions[".js"]=((r,n)=>{const i=e.readFileSync(n,"utf8");r._compile(t(i),n)})},registerJsonExtension=(e,r)=>{r.extensions[".json"]=((r,t)=>{const n=e.readFileSync(t,"utf8");r.exports=JSON.parse(n)})},makeWebRequire=(e,r)=>{const t={apiMainPath:"@jscad/modeling",fakeFs:require("./makeFakeFs")(e)},{apiMainPath:n,fakeFs:i}=Object.assign({},t,r),s="@jscad/modeling"===n?require("@jscad/modeling"):require(n),o={"@jscad/io":{exports:require("@jscad/io")},"@jscad/array-utils":{exports:require("@jscad/array-utils")},"@jscad/modeling":{exports:s},fs:{exports:i}},a={},l={},u=(r,t)=>{const n=o[t];if(n)return n.exports;r&&!t.startsWith("/")||(r="/");const i=r=>{let t=getFileExtensionFromString(r);t||(t="js",r+=".js"),t="."+t;const n=findMatch(r,e);if(!n)return null;if(n.children)return null;if(a[t]){if(l[r])return l[r];const e={exports:{},_compile:(r,t)=>{new Function("require","module",r)(u.bind(null,n.fullPath),e);const i=r.includes("@jscad-params")?getParameterDefinitionsFromSource(r,t):[],s=e.exports.getParameterDefinitions;e.exports.getParameterDefinitions=(()=>combineParameterDefinitions(i,s&&s()||[]))}};return a[t](e,n.fullPath),l[r]=e.exports,l[r]}return null},s=r=>{if(!findMatch(r,e))return null;"/"===r&&(r="");let t=r+"/index.js",n=i(t);return n||((n=i(t=r+"/index.json"))||null)},c=r=>{let t,n=findMatch(r,e);if(!n)return null;if(!n.children)return null;if(n=findMatch(r+"/package.json",e)){const e=JSON.parse(n.source).main;if(e){const n=posix.normalize(r+"/"+e);return(t=i(n))?t:(t=s(n))||null}}return(t=s(r))||null};if(t.startsWith("./")||t.startsWith("/")||t.startsWith("../")){t=posix.normalize(posix.dirname(r)+posix.sep+t);let e=i(t);if(e)return e;if(e=c(t))return e;throw new Error(`Cannot find relative path to module ${t}`)}const f=((e,r)=>{const t=(e=>{const r=e.split("/"),t=[];for(let e=r.length-1;e>0;e--){if("node_modules"===r[e])continue;const n=posix.sep+posix.join(...r.slice(1,e+1),"node_modules");t.push(n)}return t})(r);for(let r=0;r<t.length;r++){const n=t[r],s=posix.join(n,e);let o=i(s);if(o)return o;if(o=c(s))return o}return null})(t,posix.dirname(r));if(f)return f;throw new Error(`Cannot find module ${t}`)},c=u.bind(null,"/");return c.extensions=a,c.resolve=(()=>{}),registerJsExtension(i,c),registerJsonExtension(i,c),c};module.exports=makeWebRequire;
108
108
 
109
109
  },{"../parameters/getParameterDefinitionsFromSource":24,"../utils/getFileExtensionFromString":28,"./makeFakeFs":12,"@jscad/array-utils":884,"@jscad/io":65,"@jscad/modeling":580,"path":1046,"strip-bom":2}],19:[function(require,module,exports){
110
110
  module.exports={evaluation:require("./code-evaluation"),io:require("./io"),loading:require("./code-loading"),parameters:require("./parameters"),utils:require("./utils"),web:require("./web")};
@@ -163,7 +163,7 @@ const{flatten:flatten}=require("@jscad/array-utils"),{formats:formats}=require("
163
163
  },{"xmlchars/xml/1.0/ed5":33,"xmlchars/xml/1.1/ed2":34,"xmlchars/xmlns/1.0/ed3":35}],37:[function(require,module,exports){
164
164
  module.exports={
165
165
  "name": "@jscad/amf-deserializer",
166
- "version": "2.2.5",
166
+ "version": "2.2.6",
167
167
  "description": "AMF Deserializer for JSCAD",
168
168
  "repository": "https://github.com/jscad/OpenJSCAD.org/",
169
169
  "main": "src/index.js",
@@ -194,7 +194,7 @@ module.exports={
194
194
  ],
195
195
  "license": "MIT",
196
196
  "dependencies": {
197
- "@jscad/modeling": "2.7.1",
197
+ "@jscad/modeling": "2.7.2",
198
198
  "saxes": "5.0.1"
199
199
  },
200
200
  "devDependencies": {
@@ -251,7 +251,7 @@ const{geometries:geometries,maths:maths,primitives:primitives}=require("@jscad/m
251
251
  },{"./helpers":50,"@jscad/modeling":580}],53:[function(require,module,exports){
252
252
  module.exports={
253
253
  "name": "@jscad/dxf-deserializer",
254
- "version": "2.3.9",
254
+ "version": "2.3.10",
255
255
  "description": "DXF Deserializer for JSCAD",
256
256
  "repository": "https://github.com/jscad/OpenJSCAD.org",
257
257
  "main": "index.js",
@@ -278,7 +278,7 @@ module.exports={
278
278
  ],
279
279
  "license": "MIT",
280
280
  "dependencies": {
281
- "@jscad/modeling": "2.7.1"
281
+ "@jscad/modeling": "2.7.2"
282
282
  },
283
283
  "devDependencies": {
284
284
  "ava": "3.15.0",
@@ -303,7 +303,7 @@ class BinaryReader{constructor(t){this._buffer=t,this._pos=0}readInt8(){return t
303
303
 
304
304
  },{}],59:[function(require,module,exports){
305
305
  (function (Buffer){(function (){
306
- class Blob{constructor(e,t){if(t=t||{},this.size=0,this.type="",this.isClosed=!1,this.encoding="utf8",this.buffer=null,this.length=32e6,!e)return;if(!Array.isArray(e))return;let s,i;t.type&&(this.type=t.type.toLowerCase()),t.endings,t.encoding&&(this.encoding=t.encoding.toLowerCase()),t.length&&(this.length=t.length),this.buffer=Buffer.allocUnsafe(this.length);for(let t=0;t<e.length;t++)switch(typeof e[t]){case"string":s=this.buffer.write(e[t],this.size,this.encoding),this.size=this.size+s;break;case"object":if(i=e[t],Buffer.isBuffer(i),i instanceof ArrayBuffer){const e=new DataView(i);for(let t=0;t<i.byteLength;t++){const i=e.getUint8(t);s=this.buffer.writeUInt8(i,this.size,!1),this.size++}}}}asBuffer(){return this.buffer.slice(0,this.size)}arrayBuffer(){return this.buffer.slice(0,this.size)}slice(e,t,s){return e=e||0,t=t||this.size,s=s||"",new Blob}stream(){return null}text(){return""}close(){this.isClosed||(this.isClosed=!0)}toString(){return""}}module.exports=Blob;
306
+ class Blob{constructor(e,t){if(t=t||{},this.size=0,this.type="",this.isClosed=!1,this.encoding="utf8",this.buffer=null,this.length=32e6,!e)return;if(!Array.isArray(e))return;let s,i;t.type&&(this.type=t.type.toLowerCase()),t.endings,t.encoding&&(this.encoding=t.encoding.toLowerCase()),t.length&&(this.length=t.length),this.buffer=Buffer.allocUnsafe(this.length);for(let t=0;t<e.length;t++)switch(typeof e[t]){case"string":s=this.buffer.write(e[t],this.size,this.encoding),this.size=this.size+s;break;case"object":if((i=e[t])instanceof ArrayBuffer){const e=new DataView(i);for(let t=0;t<i.byteLength;t++){const i=e.getUint8(t);s=this.buffer.writeUInt8(i,this.size,!1),this.size++}}}}asBuffer(){return this.buffer.slice(0,this.size)}arrayBuffer(){return this.buffer.slice(0,this.size)}slice(e,t,s){return e=e||0,t=t||this.size,s=s||"",new Blob}stream(){return null}text(){return""}close(){this.isClosed||(this.isClosed=!0)}toString(){return""}}module.exports=Blob;
307
307
 
308
308
  }).call(this)}).call(this,require("buffer").Buffer)
309
309
  },{"buffer":1044}],60:[function(require,module,exports){
@@ -333,7 +333,7 @@ const{flatten:flatten,toArray:toArray}=require("@jscad/array-utils"),version=req
333
333
  },{"./package.json":68,"@jscad/array-utils":884}],68:[function(require,module,exports){
334
334
  module.exports={
335
335
  "name": "@jscad/json-deserializer",
336
- "version": "2.0.13",
336
+ "version": "2.0.14",
337
337
  "description": "JSON Deserializer for JSCAD",
338
338
  "repository": "https://github.com/jscad/OpenJSCAD.org",
339
339
  "main": "index.js",
@@ -363,7 +363,7 @@ module.exports={
363
363
  "@jscad/array-utils": "2.1.1"
364
364
  },
365
365
  "devDependencies": {
366
- "@jscad/modeling": "2.7.1",
366
+ "@jscad/modeling": "2.7.2",
367
367
  "ava": "3.15.0",
368
368
  "nyc": "15.1.0"
369
369
  }
@@ -378,7 +378,7 @@ const{colors:colors,primitives:primitives}=require("@jscad/modeling"),version=re
378
378
  },{"./package.json":71,"@jscad/modeling":580}],71:[function(require,module,exports){
379
379
  module.exports={
380
380
  "name": "@jscad/obj-deserializer",
381
- "version": "2.0.12",
381
+ "version": "2.0.13",
382
382
  "description": "OBJ Deserializer for JSCAD",
383
383
  "repository": "https://github.com/jscad/OpenJSCAD.org",
384
384
  "main": "index.js",
@@ -409,7 +409,7 @@ module.exports={
409
409
  ],
410
410
  "license": "MIT",
411
411
  "dependencies": {
412
- "@jscad/modeling": "2.7.1"
412
+ "@jscad/modeling": "2.7.2"
413
413
  },
414
414
  "devDependencies": {
415
415
  "ava": "3.15.0",
@@ -426,7 +426,7 @@ const{maths:maths,primitives:primitives}=require("@jscad/modeling"),{BinaryReade
426
426
  },{"./package.json":74,"@jscad/io-utils":61,"@jscad/modeling":580}],74:[function(require,module,exports){
427
427
  module.exports={
428
428
  "name": "@jscad/stl-deserializer",
429
- "version": "2.1.9",
429
+ "version": "2.1.10",
430
430
  "description": "STL Deserializer for JSCAD",
431
431
  "repository": "https://github.com/jscad/OpenJSCAD.org",
432
432
  "main": "index.js",
@@ -457,8 +457,8 @@ module.exports={
457
457
  ],
458
458
  "license": "MIT",
459
459
  "dependencies": {
460
- "@jscad/io-utils": "2.0.12",
461
- "@jscad/modeling": "2.7.1"
460
+ "@jscad/io-utils": "2.0.13",
461
+ "@jscad/modeling": "2.7.2"
462
462
  },
463
463
  "devDependencies": {
464
464
  "ava": "3.15.0",
@@ -490,7 +490,7 @@ const{geometries:geometries,modifiers:modifiers}=require("@jscad/modeling"),{fla
490
490
  },{"xmlchars/xml/1.0/ed5":78,"xmlchars/xml/1.1/ed2":79,"xmlchars/xmlns/1.0/ed3":80}],82:[function(require,module,exports){
491
491
  module.exports={
492
492
  "name": "@jscad/svg-deserializer",
493
- "version": "2.4.5",
493
+ "version": "2.4.6",
494
494
  "description": "SVG Deserializer for JSCAD",
495
495
  "repository": "https://github.com/jscad/OpenJSCAD.org",
496
496
  "main": "src/index.js",
@@ -522,7 +522,7 @@ module.exports={
522
522
  "license": "MIT",
523
523
  "dependencies": {
524
524
  "@jscad/array-utils": "2.1.1",
525
- "@jscad/modeling": "2.7.1",
525
+ "@jscad/modeling": "2.7.2",
526
526
  "saxes": "5.0.1"
527
527
  },
528
528
  "devDependencies": {
@@ -550,7 +550,7 @@ const{svg2cagX:svg2cagX,svg2cagY:svg2cagY,cagLengthX:cagLengthX,cagLengthY:cagLe
550
550
  const{cagColor:cagColor,cssStyle:cssStyle,css2cag:css2cag}=require("./helpers"),{pxPmm:pxPmm}=require("./constants"),svgCore=(s,e)=>{"id"in e&&(s.id=e.id),"position"in e&&(s.position=e.position)},svgPresentation=(s,e)=>{if("display"in e&&(s.visible=e.display),"color"in e&&(s.fill=cagColor(e.color),s.stroke=s.fill),"opacity"in e&&(s.opacity=e.opacity),"fill"in e)s.fill=cagColor(e.fill);else{const t=cssStyle(e,"fill");t&&(s.fill=cagColor(t))}if("fill-opacity"in e&&(s.opacity=e["fill-opacity"]),"stroke-width"in e)s.strokeWidth=e["stroke-width"];else{const t=cssStyle(e,"stroke-width");t&&(s.strokeWidth=t)}if("stroke"in e)s.stroke=cagColor(e.stroke);else{const t=cssStyle(e,"stroke");t&&(s.stroke=cagColor(t))}"stroke-opacity"in e&&(s.strokeOpacity=e["stroke-opacity"])},svgTransformsRegExp=/\w+\(.+\)/i,svgTransforms=(s,e)=>{let t=null;if("transform"in e)t=e.transform;else{const s=cssStyle(e,"transform");s&&(t=s)}if(null!==t){s.transforms=[];let e=svgTransformsRegExp.exec(t);for(;null!==e;){const i=svgTransformsRegExp.lastIndex,n=t.indexOf(")")+1;let r=t.slice(i,n);const o=(r=r.trim()).slice(0,r.indexOf("("));let a,c=r.slice(r.indexOf("(")+1,r.indexOf(")")).trim();switch(c=c.indexOf(",")>0?c.split(","):c.split(" "),o){case"translate":1===c.length&&c.push(0),a={translate:[c[0],c[1]]},s.transforms.push(a);break;case"scale":1===c.length&&c.push(c[0]),a={scale:[c[0],c[1]]},s.transforms.push(a);break;case"rotate":a={rotate:c},s.transforms.push(a)}t=t.slice(n,t.length),e=svgTransformsRegExp.exec(t)}}},viewBoxRegExp=/([\d.-]+)[\s,]+([\d.-]+)[\s,]+([\d.-]+)[\s,]+([\d.-]+)/i,svgSvg=(s,{customPxPmm:e})=>{const t={type:"svg",x:0,y:0,width:"100%",height:"100%",strokeWidth:"1"};if(t.unitsPmm=[pxPmm,pxPmm],"pxpmm"in s&&(t.pxPmm=s.pxpmm,t.unitsPmm=[t.pxPmm,t.pxPmm]),"width"in s&&(t.width=s.width),"height"in s&&(t.height=s.height),"viewBox"in s){const i=s.viewBox.trim(),n=viewBoxRegExp.exec(i);if(null!==n&&(t.viewX=parseFloat(n[1]),t.viewY=parseFloat(n[2]),t.viewW=parseFloat(n[3]),t.viewH=parseFloat(n[4])),t.width.indexOf("%")<0){let s=css2cag(t.width,e);s=t.viewW/s,t.unitsPmm[0]=s}else{const s=t.unitsPmm[0]*(parseFloat(t.width)/100);t.unitsPmm[0]=s}if(t.height.indexOf("%")<0){let s=css2cag(t.height,pxPmm);s=t.viewH/s,t.unitsPmm[1]=s}else{const s=t.unitsPmm[1]*(parseFloat(t.height)/100);t.unitsPmm[1]=s}}else t.viewX=0,t.viewY=0,t.viewW=1920/t.unitsPmm[0],t.viewH=1080/t.unitsPmm[1];return t.viewP=Math.sqrt(t.viewW*t.viewW+t.viewH*t.viewH)/Math.SQRT2,svgCore(t,s),svgPresentation(t,s),t.objects=[],t},svgEllipse=s=>{const e={type:"ellipse",cx:"0",cy:"0",rx:"0",ry:"0"};return"cx"in s&&(e.cx=s.cx),"cy"in s&&(e.cy=s.cy),"rx"in s&&(e.rx=s.rx),"ry"in s&&(e.ry=s.ry),svgTransforms(e,s),svgCore(e,s),svgPresentation(e,s),e},svgLine=s=>{const e={type:"line",x1:"0",y1:"0",x2:"0",y2:"0"};return"x1"in s&&(e.x1=s.x1),"y1"in s&&(e.y1=s.y1),"x2"in s&&(e.x2=s.x2),"y2"in s&&(e.y2=s.y2),svgTransforms(e,s),svgCore(e,s),svgPresentation(e,s),e},svgListOfPoints=s=>{const e=[],t=/([\d\-+.]+)[\s,]+([\d\-+.]+)[\s,]*/i;s=s.trim();let i=t.exec(s);for(;null!==i;){let n=i[0];const r=t.lastIndex+n.length;n={x:i[1],y:i[2]},e.push(n),s=s.slice(r,s.length),i=t.exec(s)}return e},svgPolyline=s=>{const e={type:"polyline"};return svgTransforms(e,s),svgCore(e,s),svgPresentation(e,s),"points"in s&&(e.points=svgListOfPoints(s.points)),e},svgPolygon=s=>{const e={type:"polygon"};return svgTransforms(e,s),svgCore(e,s),svgPresentation(e,s),"points"in s&&(e.points=svgListOfPoints(s.points)),e},svgRect=s=>{const e={type:"rect",x:"0",y:"0",rx:"0",ry:"0",width:"0",height:"0"};return"x"in s&&(e.x=s.x),"y"in s&&(e.y=s.y),"rx"in s&&(e.rx=s.rx,"ry"in s||(e.ry=e.rx)),"ry"in s&&(e.ry=s.ry,"rx"in s||(e.rx=e.ry)),e.rx!==e.ry&&console.log("Warning: Unsupported RECT with rx and ry radius"),"width"in s&&(e.width=s.width),"height"in s&&(e.height=s.height),svgTransforms(e,s),svgCore(e,s),svgPresentation(e,s),e},svgCircle=s=>{const e={type:"circle",x:"0",y:"0",radius:"0"};return"cx"in s&&(e.x=s.cx),"cy"in s&&(e.y=s.cy),"r"in s&&(e.radius=s.r),svgTransforms(e,s),svgCore(e,s),svgPresentation(e,s),e},svgGroup=s=>{const e={type:"group"};if(svgTransforms(e,s),svgCore(e,s),svgPresentation(e,s),"x"in s||"y"in s){let t="0",i="0";"x"in s&&(t=s.x),"y"in s&&(i=s.y),"transforms"in e||(e.transforms=[]);const n={translate:[t,i]};e.transforms.push(n)}return e.objects=[],e},svgPath=s=>{const e={type:"path"};if(svgTransforms(e,s),svgCore(e,s),svgPresentation(e,s),e.commands=[],"d"in s){let t=null,i="",n=0;const r=s.d.length,o=s.position[1]-r-2;for(;n<r;){const r=s.d[n];switch(r){case"-":i.length>0&&(t.p.push(i),i=""),i+=r;break;case".":i.length>0&&i.indexOf(".")>=0&&(t.p.push(i),i=""),i+=r;break;case"0":case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":i+=r;break;case"a":case"A":case"c":case"C":case"h":case"H":case"l":case"L":case"v":case"V":case"m":case"M":case"q":case"Q":case"s":case"S":case"t":case"T":case"z":case"Z":null!==t&&(i.length>0&&(t.p.push(i),i=""),e.commands.push(t)),t={c:r,p:[],pos:n+o};break;case",":case" ":case"\n":null!==t&&i.length>0&&(t.p.push(i),i="")}n++}n===r&&null!==t&&(i.length>0&&t.p.push(i),e.commands.push(t))}return e},svgUse=(s,{svgObjects:e})=>{const t={type:"group"};if(svgTransforms(t,s),svgCore(t,s),svgPresentation(t,s),"x"in s||"y"in s){let e="0",i="0";"x"in s&&(e=s.x),"y"in s&&(i=s.y),"transforms"in t||(t.transforms=[]);const n={translate:[e,i]};t.transforms.push(n)}if(t.objects=[],"xlink:href"in s){let i=s["xlink:href"];"#"===i[0]&&(i=i.slice(1,i.length)),void 0!==e[i]&&(i=e[i],i=JSON.parse(JSON.stringify(i)),t.objects.push(i))}return t};module.exports={svgCore:svgCore,svgPresentation:svgPresentation,svgSvg:svgSvg,svgRect:svgRect,svgCircle:svgCircle,svgEllipse:svgEllipse,svgLine:svgLine,svgPolyline:svgPolyline,svgPolygon:svgPolygon,svgGroup:svgGroup,svgPath:svgPath,svgUse:svgUse};
551
551
 
552
552
  },{"./constants":83,"./helpers":84}],89:[function(require,module,exports){
553
- const{geometries:geometries,maths:maths,measurements:measurements,utils:utils}=require("@jscad/modeling"),stringify=require("onml/lib/stringify"),version=require("./package.json").version,mimeType="image/svg+xml",serialize=(e,...t)=>{const s={unit:"mm",decimals:1e4,version:version,statusCallback:null};e=Object.assign({},s,e);const o=(t=utils.flatten(t)).filter(e=>geometries.geom2.isA(e)||geometries.path2.isA(e));if(0===o.length)throw new Error("only 2D geometries can be serialized to SVG");t.length!==o.length&&console.warn("some objects could not be serialized to SVG"),e.statusCallback&&e.statusCallback({progress:0});const r=getBounds(o);let n=0,l=0;r&&(n=Math.round((r[1][0]-r[0][0])*e.decimals)/e.decimals,l=Math.round((r[1][1]-r[0][1])*e.decimals)/e.decimals);let i=["svg",{width:n+e.unit,height:l+e.unit,viewBox:"0 0 "+n+" "+l,fill:"none","fill-rule":"evenodd","stroke-width":"0.1px",version:"1.1",baseProfile:"tiny",xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink"}];r&&(i=i.concat(convertObjects(o,r,e)));const a=`<?xml version="1.0" encoding="UTF-8"?>\n\x3c!-- Created by JSCAD SVG Serializer --\x3e\n<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">\n${stringify(i,2)}`;return e.statusCallback&&e.statusCallback({progress:100}),[a]},getBounds=e=>{const t=measurements.measureBoundingBox(e);return 1===e.length?t:t.reduce((e,t)=>(maths.vec3.min(e[0],e[0],t[0]),maths.vec3.max(e[1],e[1],t[1]),e),[[0,0,0],[0,0,0]])},convertObjects=(e,t,s)=>{const o=0-t[0][0],r=0-t[1][1],n=[];return e.forEach((t,l)=>{s.statusCallback&&s.statusCallback({progress:100*l/e.length}),geometries.geom2.isA(t)&&n.push(convertGeom2(t,[o,r],s)),geometries.path2.isA(t)&&n.push(convertPaths([t],[o,r],s))}),n},reflect=(e,t,s,o)=>{const r=e-s,n=t-o;return e===s&&t===s?[e,t]:e===s?[e,o-n]:t===o?[s- -r,t]:[s- -r,o-n]},convertGeom2=(e,t,s)=>{const o=geometries.geom2.toOutlines(e).map(e=>geometries.path2.fromPoints({closed:!0},e));return s.color="black",e.color&&(s.color=convertColor(e.color)),s.id=null,e.id&&(s.id=e.id),s.class=null,e.class&&(s.class=e.class),convertToContinousPath(o,t,s)},convertToContinousPath=(e,t,s)=>{let o="";e.forEach(e=>o+=convertPath(e,t,s));const r={fill:s.color,d:o};return s.id&&(r.id=s.id),s.class&&(r.class=s.class),["g",["path",r]]},convertPaths=(e,t,s)=>e.reduce((e,o,r)=>(d={d:convertPath(o,t,s)},o.color&&(d.stroke=convertColor(o.color)),o.id&&(d.id=o.id),o.class&&(d.class=o.class),e.concat([["path",d]])),["g"]),convertPath=(e,t,s)=>{let o="";const r=e.points.length+(e.isClosed?1:0);for(let n=0;n<r;n++){let r=n;r>=e.points.length&&(r-=e.points.length);const l=e.points[r],i=[l[0]+t[0],l[1]+t[1]],a=reflect(i[0],i[1],0,0),c=Math.round(a[0]*s.decimals)/s.decimals,m=Math.round(a[1]*s.decimals)/s.decimals;o+=n>0?`L${c} ${m}`:`M${c} ${m}`}return o},convertColor=e=>`rgb(${255*e[0]},${255*e[1]},${255*e[2]},${255*e[3]})`;module.exports={serialize:serialize,mimeType:mimeType};
553
+ const{geometries:geometries,maths:maths,measurements:measurements,utils:utils}=require("@jscad/modeling"),stringify=require("onml/lib/stringify"),version=require("./package.json").version,mimeType="image/svg+xml",serialize=(e,...t)=>{const s={unit:"mm",decimals:1e4,version:version,statusCallback:null};e=Object.assign({},s,e);const o=(t=utils.flatten(t)).filter(e=>geometries.geom2.isA(e)||geometries.path2.isA(e));if(0===o.length)throw new Error("only 2D geometries can be serialized to SVG");t.length!==o.length&&console.warn("some objects could not be serialized to SVG"),e.statusCallback&&e.statusCallback({progress:0});const r=getBounds(o);let n=0,l=0;r&&(n=Math.round((r[1][0]-r[0][0])*e.decimals)/e.decimals,l=Math.round((r[1][1]-r[0][1])*e.decimals)/e.decimals);let i=["svg",{width:n+e.unit,height:l+e.unit,viewBox:"0 0 "+n+" "+l,fill:"none","fill-rule":"evenodd","stroke-width":"0.1px",version:"1.1",baseProfile:"tiny",xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink"}];r&&(i=i.concat(convertObjects(o,r,e)));const a=`<?xml version="1.0" encoding="UTF-8"?>\n\x3c!-- Created by JSCAD SVG Serializer --\x3e\n<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">\n${stringify(i,2)}`;return e.statusCallback&&e.statusCallback({progress:100}),[a]},getBounds=e=>{const t=measurements.measureBoundingBox(e);return 1===e.length?t:t.reduce((e,t)=>(maths.vec3.min(e[0],e[0],t[0]),maths.vec3.max(e[1],e[1],t[1]),e),[[0,0,0],[0,0,0]])},convertObjects=(e,t,s)=>{const o=0-t[0][0],r=0-t[1][1],n=[];return e.forEach((t,l)=>{s.statusCallback&&s.statusCallback({progress:100*l/e.length}),geometries.geom2.isA(t)&&n.push(convertGeom2(t,[o,r],s)),geometries.path2.isA(t)&&n.push(convertPaths([t],[o,r],s))}),n},reflect=(e,t,s,o)=>{const r=e-s,n=t-o;return e===s&&t===s?[e,t]:e===s?[e,o-n]:t===o?[s- -r,t]:[s- -r,o-n]},convertGeom2=(e,t,s)=>{const o=geometries.geom2.toOutlines(e).map(e=>geometries.path2.fromPoints({closed:!0},e));return s.color="black",e.color&&(s.color=convertColor(e.color)),s.id=null,e.id&&(s.id=e.id),s.class=null,e.class&&(s.class=e.class),convertToContinousPath(o,t,s)},convertToContinousPath=(e,t,s)=>{let o="";e.forEach(e=>o+=convertPath(e,t,s));const r={fill:s.color,d:o};return s.id&&(r.id=s.id),s.class&&(r.class=s.class),["g",["path",r]]},convertPaths=(e,t,s)=>e.reduce((e,o,r)=>{const n={d:convertPath(o,t,s)};return o.color&&(n.stroke=convertColor(o.color)),o.id&&(n.id=o.id),o.class&&(n.class=o.class),e.concat([["path",n]])},["g"]),convertPath=(e,t,s)=>{let o="";const r=e.points.length+(e.isClosed?1:0);for(let n=0;n<r;n++){let r=n;r>=e.points.length&&(r-=e.points.length);const l=e.points[r],i=[l[0]+t[0],l[1]+t[1]],a=reflect(i[0],i[1],0,0),c=Math.round(a[0]*s.decimals)/s.decimals,m=Math.round(a[1]*s.decimals)/s.decimals;o+=n>0?`L${c} ${m}`:`M${c} ${m}`}return o},convertColor=e=>`rgb(${255*e[0]},${255*e[1]},${255*e[2]},${255*e[3]})`;module.exports={serialize:serialize,mimeType:mimeType};
554
554
 
555
555
  },{"./package.json":91,"@jscad/modeling":580,"onml/lib/stringify":90}],90:[function(require,module,exports){
556
556
  "use strict";function isObject(n){return n&&"[object Object]"===Object.prototype.toString.call(n)}function indenter(n){var t=" ".repeat(n);return function(n){var e,r=[];return"string"!=typeof n?n:1===(e=n.split("\n")).length?t+n:(e.forEach(function(n){""!==n.trim()?r.push(t+n):r.push(n)}),r.join("\n"))}}function clean(n){var t=n.split("\n"),e=[];return t.forEach(function(n){""!==n.trim()&&e.push(n)}),e.join("\n")}function stringify(n,t){var e="",r=function(n){return n};return t>0&&(e="\n",r=indenter(t)),function n(t){var i,o,c;return o="",c=!0,t.some(function(t,r,u){if(0===r)return i="<"+t,1===u.length||void 0;if(1===r){if(isObject(t))return Object.keys(t).forEach(function(n){i+=" "+n+'="'+t[n]+'"'}),2===u.length||void(i+=">");i+=">"}switch(typeof t){case"string":case"number":case"boolean":case"undefined":return void(o+=t+e)}c=!1,o+=n(t)})?i+"/>"+e:c?i+clean(o)+"</"+t[0]+">"+e:i+e+r(o)+"</"+t[0]+">"+e}(n)}module.exports=stringify;
@@ -558,7 +558,7 @@ const{geometries:geometries,maths:maths,measurements:measurements,utils:utils}=r
558
558
  },{}],91:[function(require,module,exports){
559
559
  module.exports={
560
560
  "name": "@jscad/svg-serializer",
561
- "version": "2.3.0",
561
+ "version": "2.3.1",
562
562
  "description": "SVG Serializer for JSCAD",
563
563
  "repository": "https://github.com/jscad/OpenJSCAD.org",
564
564
  "main": "index.js",
@@ -589,7 +589,7 @@ module.exports={
589
589
  ],
590
590
  "license": "MIT",
591
591
  "dependencies": {
592
- "@jscad/modeling": "2.7.1",
592
+ "@jscad/modeling": "2.7.2",
593
593
  "onml": "1.2.0"
594
594
  },
595
595
  "devDependencies": {
@@ -1753,7 +1753,7 @@ const radiusToSegments=(t,e,a)=>{const s=e>0?2*t*Math.PI/e:0,o=a>0?2*Math.PI/a:0
1753
1753
  },{"xmlchars/xml/1.0/ed5":472,"xmlchars/xml/1.1/ed2":473,"xmlchars/xmlns/1.0/ed3":474}],476:[function(require,module,exports){
1754
1754
  module.exports={
1755
1755
  "name": "@jscad/x3d-deserializer",
1756
- "version": "2.1.1",
1756
+ "version": "2.1.2",
1757
1757
  "description": "X3D Deserializer for JSCAD",
1758
1758
  "repository": "https://github.com/jscad/OpenJSCAD.org/",
1759
1759
  "main": "src/index.js",
@@ -1922,7 +1922,7 @@ const create=require("./create"),toSides=require("./toSides"),reverse=e=>{const
1922
1922
  const toCompactBinary=o=>{const t=o.sides,r=o.transforms;let n=[-1,-1,-1,-1];o.color&&(n=o.color);const e=new Float32Array(21+4*t.length);e[0]=0,e[1]=r[0],e[2]=r[1],e[3]=r[2],e[4]=r[3],e[5]=r[4],e[6]=r[5],e[7]=r[6],e[8]=r[7],e[9]=r[8],e[10]=r[9],e[11]=r[10],e[12]=r[11],e[13]=r[12],e[14]=r[13],e[15]=r[14],e[16]=r[15],e[17]=n[0],e[18]=n[1],e[19]=n[2],e[20]=n[3];for(let o=0;o<t.length;o++){const r=4*o+21,n=t[o][0],s=t[o][1];e[r+0]=n[0],e[r+1]=n[1],e[r+2]=s[0],e[r+3]=s[1]}return e};module.exports=toCompactBinary;
1923
1923
 
1924
1924
  },{}],521:[function(require,module,exports){
1925
- const vec2=require("../../maths/vec2"),toSides=require("./toSides"),toEdges=e=>{const t=[],s=e=>{const s=t.findIndex(t=>vec2.equals(t,e));return s<0?(t.push(e),e):t[s]},o=[];return e.forEach(e=>{o.push([s(e[0]),s(e[1])])}),o},toOutlines=e=>{const t=new Map;toEdges(toSides(e)).forEach(e=>{t.has(e[0])||t.set(e[0],[]),t.get(e[0]).push(e)});const s=[];for(;;){let e;for(const[s,o]of t){if(e=o.shift())break;t.delete(s)}if(void 0===e)break;const o=[],r=e[0],n=vec2.create();for(;;){o.push(e[0]);const s=e[1];if(s===r)break;const c=t.get(s);if(!c)throw new Error("the given geometry is not closed. verify proper construction");let i=-1;if(1===c.length)i=0;else{let t;const s=vec2.angleDegrees(vec2.subtract(n,e[1],e[0]));for(let e=0;e<c.length;e++){const o=c[e];let r=vec2.angleDegrees(vec2.subtract(n,o[1],o[0]))-s;r<-180&&(r+=360),r>=180&&(r-=360),(i<0||r>t)&&(i=e,t=r)}}const l=c[i];c.splice(i,1),0===c.length&&t.delete(s),e=l}o.length>0&&o.push(o.shift()),s.push(o)}return t.clear(),s};module.exports=toOutlines;
1925
+ const vec2=require("../../maths/vec2"),toSides=require("./toSides"),toEdges=e=>{const t={},s=e=>{const s=e.toString();return t[s]||(t[s]=e),t[s]};return e.map(e=>e.map(s))},toOutlines=e=>{const t=new Map;toEdges(toSides(e)).forEach(e=>{t.has(e[0])||t.set(e[0],[]),t.get(e[0]).push(e)});const s=[];for(;;){let e;for(const[s,o]of t){if(e=o.shift())break;t.delete(s)}if(void 0===e)break;const o=[],r=e[0],n=vec2.create();for(;;){o.push(e[0]);const s=e[1];if(s===r)break;const c=t.get(s);if(!c)throw new Error("the given geometry is not closed. verify proper construction");let i=-1;if(1===c.length)i=0;else{let t;const s=vec2.angleDegrees(vec2.subtract(n,e[1],e[0]));for(let e=0;e<c.length;e++){const o=c[e];let r=vec2.angleDegrees(vec2.subtract(n,o[1],o[0]))-s;r<-180&&(r+=360),r>=180&&(r-=360),(i<0||r>t)&&(i=e,t=r)}}const l=c[i];c.splice(i,1),0===c.length&&t.delete(s),e=l}o.length>0&&o.push(o.shift()),s.push(o)}return t.clear(),s};module.exports=toOutlines;
1926
1926
 
1927
1927
  },{"../../maths/vec2":678,"./toSides":523}],522:[function(require,module,exports){
1928
1928
  const toSides=require("./toSides"),toPoints=t=>{const o=toSides(t).map(t=>t[0]);return o.length>0&&o.push(o.shift()),o};module.exports=toPoints;
@@ -2225,7 +2225,7 @@ const create=()=>[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];module.exports=create;
2225
2225
  const equals=(e,s)=>e[0]===s[0]&&e[1]===s[1]&&e[2]===s[2]&&e[3]===s[3]&&e[4]===s[4]&&e[5]===s[5]&&e[6]===s[6]&&e[7]===s[7]&&e[8]===s[8]&&e[9]===s[9]&&e[10]===s[10]&&e[11]===s[11]&&e[12]===s[12]&&e[13]===s[13]&&e[14]===s[14]&&e[15]===s[15];module.exports=equals;
2226
2226
 
2227
2227
  },{}],622:[function(require,module,exports){
2228
- const identity=require("./identity"),{EPSILON:EPSILON}=require("./constants"),fromRotation=(t,e,i)=>{let[n,o,r]=i,s=Math.sqrt(n*n+o*o+r*r);if(Math.abs(s)<EPSILON)return identity(t);n*=s=1/s,o*=s,r*=s;const a=Math.sin(e),u=Math.cos(e),c=1-u;return t[0]=n*n*c+u,t[1]=o*n*c+r*a,t[2]=r*n*c-o*a,t[3]=0,t[4]=n*o*c-r*a,t[5]=o*o*c+u,t[6]=r*o*c+n*a,t[7]=0,t[8]=n*r*c+o*a,t[9]=o*r*c-n*a,t[10]=r*r*c+u,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t};module.exports=fromRotation;
2228
+ const identity=require("./identity"),{EPSILON:EPSILON}=require("./constants"),fromRotation=(t,o,e)=>{let[i,n,r]=e,a=Math.hypot(i,n,r);if(Math.abs(a)<EPSILON)return identity(t);i*=a=1/a,n*=a,r*=a;const s=Math.sin(o),h=Math.cos(o),u=1-h;return t[0]=i*i*u+h,t[1]=n*i*u+r*s,t[2]=r*i*u-n*s,t[3]=0,t[4]=i*n*u-r*s,t[5]=n*n*u+h,t[6]=r*n*u+i*s,t[7]=0,t[8]=i*r*u+n*s,t[9]=n*r*u-i*s,t[10]=r*r*u+h,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t};module.exports=fromRotation;
2229
2229
 
2230
2230
  },{"./constants":618,"./identity":631}],623:[function(require,module,exports){
2231
2231
  const fromScaling=(o,c)=>(o[0]=c[0],o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=c[1],o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c[2],o[11]=0,o[12]=0,o[13]=0,o[14]=0,o[15]=1,o);module.exports=fromScaling;
@@ -2276,7 +2276,7 @@ const mirrorByPlane=(r,o)=>{const[e,n,t,l]=o;return r[0]=1-2*e*e,r[1]=-2*n*e,r[2
2276
2276
  const multiply=(t,l,e)=>{const o=l[0],u=l[1],m=l[2],n=l[3],p=l[4],r=l[5],s=l[6],c=l[7],i=l[8],y=l[9],d=l[10],x=l[11],a=l[12],b=l[13],f=l[14],g=l[15];let h=e[0],j=e[1],k=e[2],q=e[3];return t[0]=h*o+j*p+k*i+q*a,t[1]=h*u+j*r+k*y+q*b,t[2]=h*m+j*s+k*d+q*f,t[3]=h*n+j*c+k*x+q*g,h=e[4],j=e[5],k=e[6],q=e[7],t[4]=h*o+j*p+k*i+q*a,t[5]=h*u+j*r+k*y+q*b,t[6]=h*m+j*s+k*d+q*f,t[7]=h*n+j*c+k*x+q*g,h=e[8],j=e[9],k=e[10],q=e[11],t[8]=h*o+j*p+k*i+q*a,t[9]=h*u+j*r+k*y+q*b,t[10]=h*m+j*s+k*d+q*f,t[11]=h*n+j*c+k*x+q*g,h=e[12],j=e[13],k=e[14],q=e[15],t[12]=h*o+j*p+k*i+q*a,t[13]=h*u+j*r+k*y+q*b,t[14]=h*m+j*s+k*d+q*f,t[15]=h*n+j*c+k*x+q*g,t};module.exports=multiply;
2277
2277
 
2278
2278
  },{}],639:[function(require,module,exports){
2279
- const copy=require("./copy"),rotate=(t,e,o,r)=>{let[a,s,c]=r,n=Math.sqrt(a*a+s*s+c*c);if(Math.abs(n)<1e-6)return copy(t,e);a*=n=1/n,s*=n,c*=n;const h=Math.sin(o),p=Math.cos(o),u=1-p,M=e[0],i=e[1],y=e[2],l=e[3],q=e[4],b=e[5],d=e[6],f=e[7],m=e[8],x=e[9],g=e[10],j=e[11],k=a*a*u+p,v=s*a*u+c*h,w=c*a*u-s*h,z=a*s*u-c*h,A=s*s*u+p,B=c*s*u+a*h,C=a*c*u+s*h,D=s*c*u-a*h,E=c*c*u+p;return t[0]=M*k+q*v+m*w,t[1]=i*k+b*v+x*w,t[2]=y*k+d*v+g*w,t[3]=l*k+f*v+j*w,t[4]=M*z+q*A+m*B,t[5]=i*z+b*A+x*B,t[6]=y*z+d*A+g*B,t[7]=l*z+f*A+j*B,t[8]=M*C+q*D+m*E,t[9]=i*C+b*D+x*E,t[10]=y*C+d*D+g*E,t[11]=l*C+f*D+j*E,e!==t&&(t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15]),t};module.exports=rotate;
2279
+ const copy=require("./copy"),rotate=(t,o,e,r)=>{let[a,c,s]=r,h=Math.hypot(a,c,s);if(Math.abs(h)<1e-6)return copy(t,o);a*=h=1/h,c*=h,s*=h;const n=Math.sin(e),p=Math.cos(e),u=1-p,y=o[0],M=o[1],i=o[2],l=o[3],b=o[4],d=o[5],f=o[6],m=o[7],q=o[8],x=o[9],g=o[10],j=o[11],k=a*a*u+p,v=c*a*u+s*n,w=s*a*u-c*n,z=a*c*u-s*n,A=c*c*u+p,B=s*c*u+a*n,C=a*s*u+c*n,D=c*s*u-a*n,E=s*s*u+p;return t[0]=y*k+b*v+q*w,t[1]=M*k+d*v+x*w,t[2]=i*k+f*v+g*w,t[3]=l*k+m*v+j*w,t[4]=y*z+b*A+q*B,t[5]=M*z+d*A+x*B,t[6]=i*z+f*A+g*B,t[7]=l*z+m*A+j*B,t[8]=y*C+b*D+q*E,t[9]=M*C+d*D+x*E,t[10]=i*C+f*D+g*E,t[11]=l*C+m*D+j*E,o!==t&&(t[12]=o[12],t[13]=o[13],t[14]=o[14],t[15]=o[15]),t};module.exports=rotate;
2280
2280
 
2281
2281
  },{"./copy":619}],640:[function(require,module,exports){
2282
2282
  const rotateX=(t,o,e)=>{const r=Math.sin(e),s=Math.cos(e),a=o[4],n=o[5],c=o[6],h=o[7],u=o[8],M=o[9],X=o[10],d=o[11];return o!==t&&(t[0]=o[0],t[1]=o[1],t[2]=o[2],t[3]=o[3],t[12]=o[12],t[13]=o[13],t[14]=o[14],t[15]=o[15]),t[4]=a*s+u*r,t[5]=n*s+M*r,t[6]=c*s+X*r,t[7]=h*s+d*r,t[8]=u*s-a*r,t[9]=M*s-n*r,t[10]=X*s-c*r,t[11]=d*s-h*r,t};module.exports=rotateX;
@@ -2450,7 +2450,7 @@ const abs=(a,s)=>(a[0]=Math.abs(s[0]),a[1]=Math.abs(s[1]),a[2]=Math.abs(s[2]),a)
2450
2450
  const add=(d,o,a)=>(d[0]=o[0]+a[0],d[1]=o[1]+a[1],d[2]=o[2]+a[2],d);module.exports=add;
2451
2451
 
2452
2452
  },{}],697:[function(require,module,exports){
2453
- const dot=require("./dot"),angle=(t,a)=>{const o=t[0],e=t[1],r=t[2],n=a[0],s=a[1],h=a[2],M=Math.sqrt(o*o+e*e+r*r)*Math.sqrt(n*n+s*s+h*h),d=M&&dot(t,a)/M;return Math.acos(Math.min(Math.max(d,-1),1))};module.exports=angle;
2453
+ const dot=require("./dot"),angle=(t,o)=>{const a=t[0],e=t[1],h=t[2],n=o[0],r=o[1],M=o[2],d=Math.hypot(a,e,h)*Math.hypot(n,r,M),s=d&&dot(t,o)/d;return Math.acos(Math.min(Math.max(s,-1),1))};module.exports=angle;
2454
2454
 
2455
2455
  },{"./dot":704}],698:[function(require,module,exports){
2456
2456
  const create=require("./create"),clone=e=>{const r=create();return r[0]=e[0],r[1]=e[1],r[2]=e[2],r};module.exports=clone;
@@ -2918,7 +2918,7 @@ const{EPS:EPS}=require("../maths/constants"),vec2=require("../maths/vec2"),geom2
2918
2918
  const vec3=require("../maths/vec3"),geom3=require("../geometries/geom3"),poly3=require("../geometries/poly3"),{isGTE:isGTE,isNumberArray:isNumberArray}=require("./commonChecks"),ellipsoid=e=>{const{center:c,radius:a,segments:r,axes:s}=Object.assign({},{center:[0,0,0],radius:[1,1,1],segments:32,axes:[[1,0,0],[0,-1,0],[0,0,1]]},e);if(!isNumberArray(c,3))throw new Error("center must be an array of X, Y and Z values");if(!isNumberArray(a,3))throw new Error("radius must be an array of X, Y and Z values");if(!a.every(e=>e>0))throw new Error("radius values must be greater than zero");if(!isGTE(r,4))throw new Error("segments must be four or more");const t=vec3.scale(vec3.create(),vec3.normalize(vec3.create(),s[0]),a[0]),v=vec3.scale(vec3.create(),vec3.normalize(vec3.create(),s[1]),a[1]),o=vec3.scale(vec3.create(),vec3.normalize(vec3.create(),s[2]),a[2]),l=Math.round(r/4);let u;const d=[],i=vec3.create(),n=vec3.create();for(let e=0;e<=r;e++){const a=2*Math.PI*e/r,s=vec3.add(vec3.create(),vec3.scale(i,t,Math.cos(a)),vec3.scale(n,v,Math.sin(a)));if(e>0){let e,a;for(let r=0;r<=l;r++){const t=.5*Math.PI*r/l,v=Math.cos(t),m=Math.sin(t);if(r>0){let t,h=[];t=vec3.subtract(vec3.create(),vec3.scale(i,u,e),vec3.scale(n,o,a)),h.push(vec3.add(t,t,c)),t=vec3.subtract(vec3.create(),vec3.scale(i,s,e),vec3.scale(n,o,a)),h.push(vec3.add(t,t,c)),r<l&&(t=vec3.subtract(vec3.create(),vec3.scale(i,s,v),vec3.scale(n,o,m)),h.push(vec3.add(t,t,c))),t=vec3.subtract(vec3.create(),vec3.scale(i,u,v),vec3.scale(n,o,m)),h.push(vec3.add(t,t,c)),d.push(poly3.fromPoints(h)),h=[],t=vec3.add(vec3.create(),vec3.scale(i,u,e),vec3.scale(n,o,a)),h.push(vec3.add(vec3.create(),c,t)),t=vec3.add(t,vec3.scale(i,s,e),vec3.scale(n,o,a)),h.push(vec3.add(vec3.create(),c,t)),r<l&&(t=vec3.add(t,vec3.scale(i,s,v),vec3.scale(n,o,m)),h.push(vec3.add(vec3.create(),c,t))),t=vec3.add(t,vec3.scale(i,u,v),vec3.scale(n,o,m)),h.push(vec3.add(vec3.create(),c,t)),h.reverse(),d.push(poly3.fromPoints(h))}e=v,a=m}}u=s}return geom3.create(d)};module.exports=ellipsoid;
2919
2919
 
2920
2920
  },{"../geometries/geom3":531,"../geometries/poly3":568,"../maths/vec3":709,"./commonChecks":846}],853:[function(require,module,exports){
2921
- const mat4=require("../maths/mat4"),geom3=require("../geometries/geom3"),polyhedron=require("./polyhedron"),{isGT:isGT,isGTE:isGTE}=require("./commonChecks"),geodesicSphere=e=>{let{radius:r,frequency:t}=Object.assign({},{radius:1,frequency:6},e);if(!isGT(r,0))throw new Error("radius must be greater than zero");if(!isGTE(t,6))throw new Error("frequency must be six or more");t=Math.floor(t/6);const o=[[.850651,0,-.525731],[.850651,-0,.525731],[-.850651,-0,.525731],[-.850651,0,-.525731],[0,-.525731,.850651],[0,.525731,.850651],[0,.525731,-.850651],[0,-.525731,-.850651],[-.525731,-.850651,-0],[.525731,-.850651,-0],[.525731,.850651,0],[-.525731,.850651,0]],s=[[0,9,1],[1,10,0],[6,7,0],[10,6,0],[7,9,0],[5,1,4],[4,1,9],[5,10,1],[2,8,3],[3,11,2],[2,5,4],[4,8,2],[2,11,5],[3,7,6],[6,11,3],[8,7,3],[9,8,4],[11,10,5],[10,11,6],[8,9,7]],n=(e,r,t)=>{const o=e[0],s=e[1],n=e[2];let c=t;const a=[],f=[];for(let e=0;e<r;e++)for(let t=0;t<r-e;t++){const l=e/r,u=(e+1)/r,h=t/(r-e),m=(t+1)/(r-e),p=r-e-1?t/(r-e-1):1,g=[];g[0]=i(i(o,s,h),n,l),g[1]=i(i(o,s,m),n,l),g[2]=i(i(o,s,p),n,u);for(let e=0;e<3;e++){const r=Math.sqrt(g[e][0]*g[e][0]+g[e][1]*g[e][1]+g[e][2]*g[e][2]);for(let t=0;t<3;t++)g[e][t]/=r}if(a.push(g[0],g[1],g[2]),f.push([c,c+1,c+2]),c+=3,t<r-e-1){const h=r-e-1?(t+1)/(r-e-1):1;g[0]=i(i(o,s,m),n,l),g[1]=i(i(o,s,h),n,u),g[2]=i(i(o,s,p),n,u);for(let e=0;e<3;e++){const r=Math.sqrt(g[e][0]*g[e][0]+g[e][1]*g[e][1]+g[e][2]*g[e][2]);for(let t=0;t<3;t++)g[e][t]/=r}a.push(g[0],g[1],g[2]),f.push([c,c+1,c+2]),c+=3}}return{points:a,triangles:f,offset:c}},i=(e,r,t)=>{const o=1-t,s=[];for(let n=0;n<3;n++)s[n]=e[n]*o+r[n]*t;return s};let c=[],a=[],f=0;for(let e=0;e<s.length;e++){const r=n([o[s[e][0]],o[s[e][1]],o[s[e][2]]],t,f);c=c.concat(r.points),a=a.concat(r.triangles),f=r.offset}let l=polyhedron({points:c,faces:a,orientation:"inward"});return 1!==r&&(l=geom3.transform(mat4.fromScaling(mat4.create(),[r,r,r]),l)),l};module.exports=geodesicSphere;
2921
+ const mat4=require("../maths/mat4"),geom3=require("../geometries/geom3"),polyhedron=require("./polyhedron"),{isGT:isGT,isGTE:isGTE}=require("./commonChecks"),geodesicSphere=e=>{let{radius:t,frequency:r}=Object.assign({},{radius:1,frequency:6},e);if(!isGT(t,0))throw new Error("radius must be greater than zero");if(!isGTE(r,6))throw new Error("frequency must be six or more");r=Math.floor(r/6);const o=[[.850651,0,-.525731],[.850651,-0,.525731],[-.850651,-0,.525731],[-.850651,0,-.525731],[0,-.525731,.850651],[0,.525731,.850651],[0,.525731,-.850651],[0,-.525731,-.850651],[-.525731,-.850651,-0],[.525731,-.850651,-0],[.525731,.850651,0],[-.525731,.850651,0]],s=[[0,9,1],[1,10,0],[6,7,0],[10,6,0],[7,9,0],[5,1,4],[4,1,9],[5,10,1],[2,8,3],[3,11,2],[2,5,4],[4,8,2],[2,11,5],[3,7,6],[6,11,3],[8,7,3],[9,8,4],[11,10,5],[10,11,6],[8,9,7]],n=(e,t,r)=>{const o=e[0],s=e[1],n=e[2];let c=r;const a=[],f=[];for(let e=0;e<t;e++)for(let r=0;r<t-e;r++){const l=e/t,h=(e+1)/t,u=r/(t-e),m=(r+1)/(t-e),p=t-e-1?r/(t-e-1):1,g=[];g[0]=i(i(o,s,u),n,l),g[1]=i(i(o,s,m),n,l),g[2]=i(i(o,s,p),n,h);for(let e=0;e<3;e++){const t=Math.hypot(g[e][0],g[e][1],g[e][2]);for(let r=0;r<3;r++)g[e][r]/=t}if(a.push(g[0],g[1],g[2]),f.push([c,c+1,c+2]),c+=3,r<t-e-1){const u=t-e-1?(r+1)/(t-e-1):1;g[0]=i(i(o,s,m),n,l),g[1]=i(i(o,s,u),n,h),g[2]=i(i(o,s,p),n,h);for(let e=0;e<3;e++){const t=Math.hypot(g[e][0],g[e][1],g[e][2]);for(let r=0;r<3;r++)g[e][r]/=t}a.push(g[0],g[1],g[2]),f.push([c,c+1,c+2]),c+=3}}return{points:a,triangles:f,offset:c}},i=(e,t,r)=>{const o=1-r,s=[];for(let n=0;n<3;n++)s[n]=e[n]*o+t[n]*r;return s};let c=[],a=[],f=0;for(let e=0;e<s.length;e++){const t=n([o[s[e][0]],o[s[e][1]],o[s[e][2]]],r,f);c=c.concat(t.points),a=a.concat(t.triangles),f=t.offset}let l=polyhedron({points:c,faces:a,orientation:"inward"});return 1!==t&&(l=geom3.transform(mat4.fromScaling(mat4.create(),[t,t,t]),l)),l};module.exports=geodesicSphere;
2922
2922
 
2923
2923
  },{"../geometries/geom3":531,"../maths/mat4":632,"./commonChecks":846,"./polyhedron":857}],854:[function(require,module,exports){
2924
2924
  module.exports={arc:require("./arc"),circle:require("./circle"),cube:require("./cube"),cuboid:require("./cuboid"),cylinder:require("./cylinder"),cylinderElliptic:require("./cylinderElliptic"),ellipse:require("./ellipse"),ellipsoid:require("./ellipsoid"),geodesicSphere:require("./geodesicSphere"),line:require("./line"),polygon:require("./polygon"),polyhedron:require("./polyhedron"),rectangle:require("./rectangle"),roundedCuboid:require("./roundedCuboid"),roundedCylinder:require("./roundedCylinder"),roundedRectangle:require("./roundedRectangle"),sphere:require("./sphere"),square:require("./square"),star:require("./star"),torus:require("./torus"),triangle:require("./triangle")};
@@ -3269,7 +3269,7 @@ const boundingBox=r=>{if(0===r.length)return[[0,0,0],[0,0,0]];const e=Array.isAr
3269
3269
  const vec3=require("gl-vec3"),{flatten:flatten}=require("@jscad/array-utils"),boundingBox=require("./boundingBox"),computeBounds=(...e)=>{let c;(e=flatten(e)).forEach(e=>{let t=boundingBox(e.positions);t=t.map(c=>vec3.transformMat4(c,c,e.transforms)),c?(vec3.min(c[0],c[0],t[0]),vec3.max(c[1],c[1],t[1])):c=t});const t=vec3.min(vec3.create(),c[1],c[0]),a=vec3.max(vec3.create(),c[1],c[0]),n=vec3.subtract(vec3.create(),a,t);let r=vec3.scale(vec3.create(),n,.5);return r=vec3.add(r,t,r),{dia:vec3.distance(r,a),center:[...r],min:[...t],max:[...a],size:[...n]}};module.exports=computeBounds;
3270
3270
 
3271
3271
  },{"./boundingBox":968,"@jscad/array-utils":884,"gl-vec3":939}],970:[function(require,module,exports){
3272
- const vec3=require("gl-vec3"),mat4=require("gl-mat4"),fromOrthographicToPerspective=e=>{const{near:t,far:r,fov:o,zoom:a}=e;console.log("fov",o,"zoom",a);const{viewport:i}=e,c=require("./perspectiveCamera").setProjection(e,{width:i[2],height:i[3]}),{projectionType:p}=require("./perspectiveCamera").cameraState;return Object.assign({},e,c,{projectionType:p},{near:t,far:r,fov:o})},fromPerspectiveToOrthographic=e=>{const{fov:t,aspect:r}=e,o=.3*vec3.length(vec3.subtract([],e.position,e.target)),a=Math.tan(t)*o*r,i=Math.tan(t)*o,{near:c,far:p,viewport:s}=e,n={zoom:1,near:c,far:p},v=require("./orthographicCamera").cameraState,h=require("./orthographicCamera").setProjection(n,{width:a,height:i});return Object.assign({},v,e,h,{projectionType:v.projectionType,viewport:s})},toPerspectiveView=({camera:e})=>{const t=vec3.distance(e.position,e.target),r=[t,t,t];return{view:mat4.lookAt(mat4.create(),r,e.target,e.up),position:r}},toPresetView=(e,{camera:t})=>{const r=vec3.distance(t.position,t.target),o=vec3.add(vec3.create(),{top:[0,-1e-6,1],bottom:[0,0,-1],front:[0,1,0],back:[0,-1,0],left:[-1,0,0],right:[1,0,0],undefined:[0,0,0]}[e].map(e=>e*r),t.target);return{view:mat4.lookAt(mat4.create(),o,t.target,t.up),position:o}};module.exports={toPerspectiveView:toPerspectiveView,toPresetView:toPresetView,fromOrthographicToPerspective:fromOrthographicToPerspective,fromPerspectiveToOrthographic:fromPerspectiveToOrthographic};
3272
+ const vec3=require("gl-vec3"),mat4=require("gl-mat4"),fromOrthographicToPerspective=e=>{const{near:t,far:r,fov:o,zoom:a}=e,{viewport:i}=e,c=require("./perspectiveCamera").setProjection(e,{width:i[2],height:i[3]}),{projectionType:p}=require("./perspectiveCamera").cameraState;return Object.assign({},e,c,{projectionType:p},{near:t,far:r,fov:o})},fromPerspectiveToOrthographic=e=>{const{fov:t,aspect:r}=e,o=.3*vec3.length(vec3.subtract([],e.position,e.target)),a=Math.tan(t)*o*r,i=Math.tan(t)*o,{near:c,far:p,viewport:s}=e,n={zoom:1,near:c,far:p},v=require("./orthographicCamera").cameraState,h=require("./orthographicCamera").setProjection(n,{width:a,height:i});return Object.assign({},v,e,h,{projectionType:v.projectionType,viewport:s})},toPerspectiveView=({camera:e})=>{const t=vec3.distance(e.position,e.target),r=[t,t,t];return{view:mat4.lookAt(mat4.create(),r,e.target,e.up),position:r}},toPresetView=(e,{camera:t})=>{const r=vec3.distance(t.position,t.target),o=vec3.add(vec3.create(),{top:[0,-1e-6,1],bottom:[0,0,-1],front:[0,1,0],back:[0,-1,0],left:[-1,0,0],right:[1,0,0],undefined:[0,0,0]}[e].map(e=>e*r),t.target);return{view:mat4.lookAt(mat4.create(),o,t.target,t.up),position:o}};module.exports={toPerspectiveView:toPerspectiveView,toPresetView:toPresetView,fromOrthographicToPerspective:fromOrthographicToPerspective,fromPerspectiveToOrthographic:fromPerspectiveToOrthographic};
3273
3273
 
3274
3274
  },{"./orthographicCamera":971,"./perspectiveCamera":972,"gl-mat4":906,"gl-vec3":939}],971:[function(require,module,exports){
3275
3275
  const mat4=require("gl-mat4"),cameraState={view:mat4.identity(new Float32Array(16)),projection:mat4.identity(new Float32Array(16)),matrix:mat4.identity(new Float32Array(16)),near:1,far:1300,up:[0,0,1],eye:new Float32Array(3),position:[150,250,200],target:[0,0,0],fov:Math.PI/4,aspect:1,viewport:[0,0,0,0],zoom:1,projectionType:"orthographic"},cameraProps={},setProjection=(t,e)=>{const{width:a,height:r}=e,o=a/r,i=[0,0,a,r],n=t.zoom,c=-a*n,m=a*n,p=-r*n,s=r*n;return{projection:mat4.ortho([],c,m,p,s,t.near,t.far),aspect:o,viewport:i}};module.exports={cameraState:cameraState,cameraProps:cameraProps,setProjection:setProjection};
@@ -3278,7 +3278,7 @@ const mat4=require("gl-mat4"),cameraState={view:mat4.identity(new Float32Array(1
3278
3278
  const mat4=require("gl-mat4"),vec3=require("gl-vec3"),cameraState={view:mat4.identity(new Float32Array(16)),projection:mat4.identity(new Float32Array(16)),matrix:mat4.identity(new Float32Array(16)),near:1,far:18e3,up:[0,0,1],eye:new Float32Array(3),position:[450,550,700],target:[0,0,0],fov:Math.PI/4,aspect:1,viewport:[0,0,0,0],projectionType:"perspective"},cameraProps={},defaults=Object.assign({},cameraState,cameraProps),setProjection=(e,t,a)=>{const r=a.width/a.height,o=mat4.perspective(mat4.identity([]),t.fov,r,t.near,t.far),i=[0,0,a.width,a.height],c=e||{};return c.projection=o,c.aspect=r,c.viewport=i,c},update=(e,t)=>{t||(t=e);const{position:a,target:r,up:o}=t,i=vec3.subtract([],a,r),c=vec3.add(vec3.create(),r,i),n=mat4.lookAt(mat4.create(),c,r,o),p=e||{};return p.position=c,p.view=n,p};module.exports={cameraState:cameraState,cameraProps:cameraProps,defaults:defaults,setProjection:setProjection,update:update};
3279
3279
 
3280
3280
  },{"gl-mat4":906,"gl-vec3":939}],973:[function(require,module,exports){
3281
- const vec3=require("gl-vec3"),mat4=require("gl-mat4"),{max:max,min:min,sqrt:sqrt,PI:PI,sin:sin,cos:cos,atan2:atan2}=Math,computeBounds=require("../bound-utils/computeBounds"),controlsProps={limits:{minDistance:.01,maxDistance:1e4},drag:.27,EPS:1e-6,zoomToFit:{auto:!0,targets:"all",tightness:1.5},userControl:{zoom:!0,zoomSpeed:1,rotate:!0,rotateSpeed:1,pan:!0,panSpeed:1},autoRotate:{enabled:!1,speed:1},autoAdjustPlanes:!0},controlsState={thetaDelta:0,phiDelta:0,scale:1},defaults=Object.assign({},controlsState,controlsProps),update=({controls:t,camera:e},a)=>{const{EPS:o,drag:s}=t,{position:r,target:n}=e,c=t.up?t.up:e.up;let i=t.thetaDelta;const l=t.phiDelta,m=t.scale,p=vec3.subtract([],r,n);let u,d;1===c[2]?(u=atan2(p[0],p[1]),d=atan2(sqrt(p[0]*p[0]+p[1]*p[1]),p[2])):(u=atan2(p[0],p[2]),d=atan2(sqrt(p[0]*p[0]+p[2]*p[2]),p[1])),t.autoRotate.enabled&&t.userControl.rotate&&(i+=2*Math.PI/60/60*t.autoRotate.speed),u+=i,d=max(o,min(PI-o,d+=l));const h=max(t.limits.minDistance,min(t.limits.maxDistance,vec3.length(p)*m));1===c[2]?(p[0]=h*sin(d)*sin(u),p[2]=h*cos(d),p[1]=h*sin(d)*cos(u)):(p[0]=h*sin(d)*sin(u),p[1]=h*cos(d),p[2]=h*sin(d)*cos(u));const g=vec3.add(vec3.create(),n,p),v=mat4.lookAt(mat4.create(),g,n,c),D=1-max(min(s,1),.01);return{controls:{thetaDelta:i*D,phiDelta:l*D,scale:1,changed:vec3.distance(r,g)>.001},camera:{position:g,view:v}}},rotate=({controls:t,camera:e,speed:a=1},o)=>{let{thetaDelta:s,phiDelta:r}=t;return t.userControl.rotate&&(s+=o[0]*a,r+=o[1]*a),{controls:{thetaDelta:s,phiDelta:r},camera:e}},zoom=({controls:t,camera:e,speed:a=1},o=0)=>{let{scale:s}=t;if(t.userControl.zoom&&e&&void 0!==o&&0!==o&&!isNaN(o)){const r=(o=o/o*(0===Math.sign(o)?1:Math.sign(o))*a)+t.scale,n=vec3.distance(e.position,e.target)*r;if(n>t.limits.minDistance&&n<t.limits.maxDistance&&(s+=o),"orthographic"===e.projectionType){const t=.3*vec3.length(vec3.subtract([],e.position,e.target)),a=Math.tan(e.fov)*t*e.aspect,o=Math.tan(e.fov)*t;e=require("../cameras/orthographicCamera").setProjection(e,{width:a,height:o})}}return{controls:{scale:s},camera:e}},pan=({controls:t,camera:e,speed:a=1},o)=>{const s=require("camera-unproject"),{projection:r,view:n,viewport:c}=e,i=mat4.multiply([],r,n),l=mat4.invert([],i),m=[c[2],c[3],0],p=[c[2]-o[0],c[3]+o[1],0],u=s([],m,c,l),d=s([],p,c,l),h=vec3.distance(e.position,e.eye),g=vec3.subtract([],u,d).map(e=>e*a*h*t.scale);return{controls:t,camera:{position:vec3.add(vec3.create(),e.position,g),target:vec3.add(vec3.create(),e.target,g)}}},zoomToFit=({controls:t,camera:e,entities:a})=>{const{zoomToFit:o}=t;if("all"!==o.targets)return{controls:t,camera:e};if(0===a.length)return{controls:t,camera:e};const s=a.map(t=>t.geometry),r=computeBounds(s),{fov:n,target:c,position:i}=e,{tightness:l}=Object.assign({},o,controlsProps.zoomToFit),m=r.dia*l/Math.tan(n/2)/vec3.distance(c,i);return{camera:{target:r.center},controls:{scale:m}}},reset=({controls:t,camera:e},a)=>{return{camera:{position:a.camera.position,target:a.camera.target,projection:mat4.perspective([],e.fov,e.aspect,e.near,e.far),view:a.camera.view},controls:{thetaDelta:a.controls.thetaDelta,phiDelta:a.controls.phiDelta,scale:a.controls.scale}}},setFocus=({controls:t,camera:e},a)=>{const o=(t,e)=>t.map((t,a)=>t+e[a]),s=e.target,r=[0,0,.5*((t,e)=>t.map((t,a)=>t-e[a]))(a,s)[2]];return e.target=o(s,r),e.position=o(e.position,r),e};module.exports={controlsProps:controlsProps,controlsState:controlsState,defaults:defaults,update:update,rotate:rotate,zoom:zoom,pan:pan,zoomToFit:zoomToFit,reset:reset};
3281
+ const vec3=require("gl-vec3"),mat4=require("gl-mat4"),{max:max,min:min,sqrt:sqrt,PI:PI,sin:sin,cos:cos,atan2:atan2}=Math,computeBounds=require("../bound-utils/computeBounds"),controlsProps={limits:{minDistance:.01,maxDistance:1e4},drag:.27,EPS:1e-6,zoomToFit:{auto:!0,targets:"all",tightness:1.5},userControl:{zoom:!0,zoomSpeed:1,rotate:!0,rotateSpeed:1,pan:!0,panSpeed:1},autoRotate:{enabled:!1,speed:1},autoAdjustPlanes:!0},controlsState={thetaDelta:0,phiDelta:0,scale:1},defaults=Object.assign({},controlsState,controlsProps),update=({controls:t,camera:e},a)=>{const{EPS:o,drag:s}=t,{position:r,target:n}=e,c=t.up?t.up:e.up;let i=t.thetaDelta;const l=t.phiDelta,m=t.scale,p=vec3.subtract([],r,n);let u,d;1===c[2]?(u=atan2(p[0],p[1]),d=atan2(sqrt(p[0]*p[0]+p[1]*p[1]),p[2])):(u=atan2(p[0],p[2]),d=atan2(sqrt(p[0]*p[0]+p[2]*p[2]),p[1])),t.autoRotate.enabled&&t.userControl.rotate&&(i+=2*Math.PI/60/60*t.autoRotate.speed),u+=i,d=max(o,min(PI-o,d+=l));const h=max(t.limits.minDistance,min(t.limits.maxDistance,vec3.length(p)*m));1===c[2]?(p[0]=h*sin(d)*sin(u),p[2]=h*cos(d),p[1]=h*sin(d)*cos(u)):(p[0]=h*sin(d)*sin(u),p[1]=h*cos(d),p[2]=h*sin(d)*cos(u));const g=vec3.add(vec3.create(),n,p),v=mat4.lookAt(mat4.create(),g,n,c),D=1-max(min(s,1),.01);return{controls:{thetaDelta:i*D,phiDelta:l*D,scale:1,changed:vec3.distance(r,g)>.001},camera:{position:g,view:v}}},rotate=({controls:t,camera:e,speed:a=1},o)=>{let{thetaDelta:s,phiDelta:r}=t;return t.userControl.rotate&&(s+=o[0]*a,r+=o[1]*a),{controls:{thetaDelta:s,phiDelta:r},camera:e}},zoom=({controls:t,camera:e,speed:a=1},o=0)=>{let{scale:s}=t;if(t.userControl.zoom&&e&&void 0!==o&&0!==o&&!isNaN(o)){const r=(o=o/o*(0===Math.sign(o)?1:Math.sign(o))*a)+t.scale,n=vec3.distance(e.position,e.target)*r;if(n>t.limits.minDistance&&n<t.limits.maxDistance&&(s+=o),"orthographic"===e.projectionType){const t=.3*vec3.length(vec3.subtract([],e.position,e.target)),a=Math.tan(e.fov)*t*e.aspect,o=Math.tan(e.fov)*t;e=require("../cameras/orthographicCamera").setProjection(e,{width:a,height:o})}}return{controls:{scale:s},camera:e}},pan=({controls:t,camera:e,speed:a=1},o)=>{const s=require("camera-unproject"),{projection:r,view:n,viewport:c}=e,i=mat4.multiply([],r,n),l=mat4.invert([],i),m=[c[2],c[3],0],p=[c[2]-o[0],c[3]+o[1],0],u=s([],m,c,l),d=s([],p,c,l),h=vec3.distance(e.position,e.eye),g=vec3.subtract([],u,d).map(e=>e*a*h*t.scale);return{controls:t,camera:{position:vec3.add(vec3.create(),e.position,g),target:vec3.add(vec3.create(),e.target,g)}}},zoomToFit=({controls:t,camera:e,entities:a})=>{const{zoomToFit:o}=t;if("all"!==o.targets)return{controls:t,camera:e};if(0===a.length)return{controls:t,camera:e};const s=a.map(t=>t.geometry),r=computeBounds(s),{fov:n,target:c,position:i}=e,{tightness:l}=Object.assign({},o,controlsProps.zoomToFit),m=r.dia*l/Math.tan(n/2)/vec3.distance(c,i);return{camera:{target:r.center},controls:{scale:m}}},reset=({controls:t,camera:e},a)=>{return{camera:{position:a.camera.position,target:a.camera.target,projection:mat4.perspective([],e.fov,e.aspect,e.near,e.far),view:a.camera.view},controls:{thetaDelta:a.controls.thetaDelta,phiDelta:a.controls.phiDelta,scale:a.controls.scale}}};module.exports={controlsProps:controlsProps,controlsState:controlsState,defaults:defaults,update:update,rotate:rotate,zoom:zoom,pan:pan,zoomToFit:zoomToFit,reset:reset};
3282
3282
 
3283
3283
  },{"../bound-utils/computeBounds":969,"../cameras/orthographicCamera":971,"camera-unproject":889,"gl-mat4":906,"gl-vec3":939}],974:[function(require,module,exports){
3284
3284
  const{flatten:flatten,toArray:toArray}=require("@jscad/array-utils"),{meshColor:meshColor}=require("../rendering/renderDefaults"),geom2ToGeometries=require("./geom2ToGeometries"),geom3ToGeometries=require("./geom3ToGeometries"),path2ToGeometries=require("./path2ToGeometries"),assembleEntities=e=>{return e.map(e=>{return{geometry:e,visuals:{drawCmd:"2d"===e.type?"drawLines":"drawMesh",show:!0,transparent:e.isTransparent,useVertexColors:!0}}})},entitiesFromSolids=(e,...o)=>{const r={color:meshColor,smoothNormals:!0},{color:t,smoothNormals:s}=Object.assign({},r,e);o=(o=flatten(toArray(o))).filter(e=>e&&e instanceof Object);const i=[];return o.forEach(e=>{let o=[];"sides"in e?o=geom2ToGeometries({color:t},e):"points"in e?o=path2ToGeometries({color:t},e):"polygons"in e&&(o=geom3ToGeometries({smoothLighting:s,normalThreshold:.3,color:t},e)),i.push(...assembleEntities(o))}),i};module.exports=entitiesFromSolids;
@@ -3287,7 +3287,7 @@ const{flatten:flatten,toArray:toArray}=require("@jscad/array-utils"),{meshColor:
3287
3287
  const mat4=require("gl-mat4"),maxIndex=Math.floor(32767.5),geom2ToGeometries=(o,e)=>{let{color:t}=o;const r=e.sides;if(0===r.length)return[];"color"in e&&(t=e.color);const n=t[3]<1,s=Math.floor(r.length/maxIndex)+1,a=[];for(let o=0;o<s;o++){const s=o*maxIndex,m=Math.min(s+maxIndex,r.length),l=[];for(let o=s;o<m;o++){const e=r[o];l.push([e[0][0],e[0][1],0]),l.push([e[1][0],e[1][1],0])}const c=l.map(o=>[0,0,-1]),i=l.map((o,e)=>e),h=e.transforms?mat4.clone(e.transforms):mat4.create();a.push({type:"2d",positions:l,normals:c,indices:i,transforms:h,color:t,isTransparent:n})}return a};module.exports=geom2ToGeometries;
3288
3288
 
3289
3289
  },{"gl-mat4":906}],976:[function(require,module,exports){
3290
- const vec3=require("gl-vec3"),mat4=require("gl-mat4"),maxIndex=65535,geom3ToGeometries=(o,e)=>{let{color:t,smoothLighting:n,normalThreshold:r}=o;"color"in e&&(t=e.color);const l=e.polygons,s=e.transforms?mat4.clone(e.transforms):mat4.create(),c=[];let i=0;for(;i<l.length;){let o=0,e=i;for(let t=i;t<l.length&&!((o+=l[t].vertices.length)>65535);t++)e++;const n=[],r=[],a=[],m=[],p=!0;for(let o=i;o<e;o++){const e=l[o],s=e.vertices,c=calculateNormal(e),i=polygonColor(e,t),p=[];for(let o=0;o<s.length;o++){const e=s[o],t=[e[0],e[1],e[2]];n.push(t),r.push(c),m.push(i);const l=n.length-1;p.push(l)}for(let o=2;o<p.length;o++)a.push([p[0],p[o-1],p[o]])}const u={type:"3d",positions:n,normals:r,indices:a,colors:m,transforms:s,isTransparent:p};c.push(u),i=e}return c},smoothing=()=>{const o=[],e=[];let t=!0;const n=[],r=[],l=[],s=[],c=[];let i=0;for(let a=0;a<o.length;a++){const m=o[a],p=m.vertices,u=polygonColor(m,e),h=calculateNormal(m);u&&1!==u[3]&&(t=!0);const g=[];for(let o=0;o<p.length;o++){let e;const t=p[o],l=[t[0],t[1],t[2]];{const o={normal:h,position:l},t=fuzyNormalAndPositionLookup(c,o,.5);if(t)e=t.index;else{const t=c[o.position],a=[{normal:o.normal,index:i}];c[o.position]=t?c[o.position].concat(a):a,e=i,u&&s.push(u),r.push(h),n.push(l),i+=1}}g.push(e)}for(let o=2;o<g.length;o++)l.push([g[0],g[o-1],g[o]])}},polygonColor=(o,e)=>{let t=e;return o.color&&(t=o.color),t&&t.length<4&&t.push(1),t},calculateNormal=o=>{if(o.plane)return vec3.clone(o.plane);const e=o.vertices,t=vec3.create();vec3.subtract(t,e[1],e[0]);const n=vec3.create();vec3.subtract(n,e[2],e[0]);const r=vec3.create();return vec3.cross(r,t,n),vec3.normalize(r,r),r},areNormalsSimilar=(o,e,t)=>vec3.distance(o,e)<=t,fuzyNormalAndPositionLookup=(o,e,t)=>{const n=o[e.position];if(n)for(let o=0;o<n.length;o++){const r=n[o].normal;if(areNormalsSimilar(r,e.normal,t))return{tupple:{position:e.position,normal:r},index:n[o].index}}};module.exports=geom3ToGeometries;
3290
+ const vec3=require("gl-vec3"),mat4=require("gl-mat4"),maxIndex=65535,geom3ToGeometries=(o,e)=>{let{color:t,smoothLighting:n}=o;"color"in e&&(t=e.color);const r=e.polygons,l=e.transforms?mat4.clone(e.transforms):mat4.create(),s=[];let c=0;for(;c<r.length;){let o=0,e=c;for(let t=c;t<r.length&&!((o+=r[t].vertices.length)>65535);t++)e++;const n=[],i=[],a=[],p=[],m=!0;for(let o=c;o<e;o++){const e=r[o],l=e.vertices,s=calculateNormal(e),c=polygonColor(e,t),m=[];for(let o=0;o<l.length;o++){const e=l[o],t=[e[0],e[1],e[2]];n.push(t),i.push(s),p.push(c);const r=n.length-1;m.push(r)}for(let o=2;o<m.length;o++)a.push([m[0],m[o-1],m[o]])}const u={type:"3d",positions:n,normals:i,indices:a,colors:p,transforms:l,isTransparent:m};s.push(u),c=e}return s},smoothing=()=>{const o=[],e=[];let t=!0;const n=[],r=[],l=[],s=[],c=[];let i=0;for(let a=0;a<o.length;a++){const p=o[a],m=p.vertices,u=polygonColor(p,e),h=calculateNormal(p);u&&1!==u[3]&&(t=!0);const g=[];for(let o=0;o<m.length;o++){let e;const t=m[o],l=[t[0],t[1],t[2]];{const o={normal:h,position:l},t=fuzyNormalAndPositionLookup(c,o,.5);if(t)e=t.index;else{const t=c[o.position],a=[{normal:o.normal,index:i}];c[o.position]=t?c[o.position].concat(a):a,e=i,u&&s.push(u),r.push(h),n.push(l),i+=1}}g.push(e)}for(let o=2;o<g.length;o++)l.push([g[0],g[o-1],g[o]])}},polygonColor=(o,e)=>{let t=e;return o.color&&(t=o.color),t&&t.length<4&&t.push(1),t},calculateNormal=o=>{if(o.plane)return vec3.clone(o.plane);const e=o.vertices,t=vec3.create();vec3.subtract(t,e[1],e[0]);const n=vec3.create();vec3.subtract(n,e[2],e[0]);const r=vec3.create();return vec3.cross(r,t,n),vec3.normalize(r,r),r},areNormalsSimilar=(o,e,t)=>vec3.distance(o,e)<=t,fuzyNormalAndPositionLookup=(o,e,t)=>{const n=o[e.position];if(n)for(let o=0;o<n.length;o++){const r=n[o].normal;if(areNormalsSimilar(r,e.normal,t))return{tupple:{position:e.position,normal:r},index:n[o].index}}};module.exports=geom3ToGeometries;
3291
3291
 
3292
3292
  },{"gl-mat4":906,"gl-vec3":939}],977:[function(require,module,exports){
3293
3293
  const mat4=require("gl-mat4"),maxIndex=Math.floor(32767.5)-2,path2ToGeometries=(o,t)=>{let{color:e}=o;const s=t.points;if(0===s.length)return[];"color"in t&&(e=t.color);const n=e[3]<1,r=Math.floor(s.length/maxIndex)+1,a=[];for(let o=0;o<r;o++){const l=o*maxIndex,m=Math.min(l+maxIndex,s.length),c=[];let i;for(let o=l;o<m;o++){const t=s[o];i&&(c.push([i[0],i[1],0]),c.push([t[0],t[1],0])),i=t}if(o+1===r&&t.isClosed&&i){const o=s[0];c.push([i[0],i[1],0]),c.push([o[0],o[1],0])}const p=c.map(o=>[0,0,-1]),h=c.map((o,t)=>t),f=t.transforms?mat4.clone(t.transforms):mat4.create();a.push({type:"2d",positions:c,normals:p,indices:h,transforms:f,color:e,isTransparent:n})}return a};module.exports=path2ToGeometries;
@@ -3308,7 +3308,7 @@ const makeDrawMultiGrid=(e,i)=>{const{size:s,ticks:r}=Object.assign({},{size:[50
3308
3308
  const vColorFrag="\nprecision mediump float;\nuniform vec4 ucolor;\n\nvoid main () {\n gl_FragColor = ucolor;\n}\n";module.exports={frag:vColorFrag};
3309
3309
 
3310
3310
  },{}],983:[function(require,module,exports){
3311
- const mat4=require("gl-mat4"),{meshColor:meshColor}=require("../../renderDefaults"),drawLines=(e,r={})=>{const t={color:meshColor,geometry:void 0};let{geometry:o,color:s}=Object.assign({},t,r);"color"in o&&(s=o.color);const a=!!(o.indices&&o.indices.length>0),i=!!(o.normals&&o.normals.length>0);let l={primitive:"lines",vert:require("./meshShaders").vert,frag:require("./colorOnlyShaders").frag,uniforms:{model:(e,r)=>r.model||o.transforms||mat4.create(),ucolor:(e,r)=>r&&r.color?r.color:s},attributes:{position:e.buffer({usage:"static",type:"float",data:o.positions})}};return a&&(l.elements=e.elements({usage:"static",type:"uint16",data:o.indices})),i&&(l.attributes.normal=e.buffer({usage:"static",type:"float",data:o.normals})),e(l)};module.exports=drawLines;
3311
+ const mat4=require("gl-mat4"),{meshColor:meshColor}=require("../../renderDefaults"),drawLines=(e,r={})=>{const t={color:meshColor,geometry:void 0};let{geometry:o,color:s}=Object.assign({},t,r);"color"in o&&(s=o.color);const a=!!(o.indices&&o.indices.length>0),i=!!(o.normals&&o.normals.length>0),l={primitive:"lines",vert:require("./meshShaders").vert,frag:require("./colorOnlyShaders").frag,uniforms:{model:(e,r)=>r.model||o.transforms||mat4.create(),ucolor:(e,r)=>r&&r.color?r.color:s},attributes:{position:e.buffer({usage:"static",type:"float",data:o.positions})}};return a&&(l.elements=e.elements({usage:"static",type:"uint16",data:o.indices})),i&&(l.attributes.normal=e.buffer({usage:"static",type:"float",data:o.normals})),e(l)};module.exports=drawLines;
3312
3312
 
3313
3313
  },{"../../renderDefaults":990,"./colorOnlyShaders":982,"./meshShaders":984,"gl-mat4":906}],984:[function(require,module,exports){
3314
3314
  const meshFrag="\nprecision mediump float;\nvarying vec3 surfaceNormal;\nuniform float ambientLightAmount;\nuniform float diffuseLightAmount;\nuniform vec4 ucolor;\nuniform vec3 lightDirection;\nuniform vec3 opacity;\n\nvarying vec4 _worldSpacePosition;\n\nuniform vec2 printableArea;\n\nvec4 errorColor = vec4(0.15, 0.15, 0.15, 0.3);\n\nvoid main () {\n vec4 depth = gl_FragCoord;\n\n float v = 0.8; // shadow value\n vec4 endColor = ucolor;\n\n vec3 ambient = ambientLightAmount * endColor.rgb;\n float cosTheta = dot(surfaceNormal, lightDirection);\n vec3 diffuse = diffuseLightAmount * endColor.rgb * clamp(cosTheta , 0.0, 1.0 );\n\n float cosTheta2 = dot(surfaceNormal, vec3(-lightDirection.x, -lightDirection.y, lightDirection.z));\n vec3 diffuse2 = diffuseLightAmount * endColor.rgb * clamp(cosTheta2 , 0.0, 1.0 );\n\n gl_FragColor = vec4((ambient + diffuse + diffuse2 * v), endColor.a);\n}",meshVert="\nprecision mediump float;\n\nuniform float camNear, camFar;\nuniform mat4 model, view, projection;\n\nattribute vec3 position, normal;\n\nvarying vec3 surfaceNormal, surfacePosition;\nvarying vec4 _worldSpacePosition;\n\nvoid main() {\n surfacePosition = position;\n surfaceNormal = normal;\n vec4 worldSpacePosition = model * vec4(position, 1);\n _worldSpacePosition = worldSpacePosition;\n\n vec4 glPosition = projection * view * model * vec4(position, 1);\n gl_Position = glPosition;\n}\n";module.exports={vert:meshVert,frag:meshFrag};
@@ -4183,7 +4183,7 @@ var bundleFn=arguments[3],sources=arguments[4],cache=arguments[5],stringify=JSON
4183
4183
  },{}],1145:[function(require,module,exports){
4184
4184
  module.exports={
4185
4185
  "name": "@jscad/web",
4186
- "version": "2.5.3",
4186
+ "version": "2.5.4",
4187
4187
  "description": "Web Application for JSCAD",
4188
4188
  "repository": "https://github.com/jscad/OpenJSCAD.org",
4189
4189
  "main": "src/index.js",
@@ -4218,11 +4218,11 @@ module.exports={
4218
4218
  "license": "MIT",
4219
4219
  "dependencies": {
4220
4220
  "@jscad/array-utils": "2.1.1",
4221
- "@jscad/core": "2.5.3",
4222
- "@jscad/examples": "2.3.1",
4223
- "@jscad/io": "2.2.3",
4224
- "@jscad/modeling": "2.7.1",
4225
- "@jscad/regl-renderer": "2.5.3",
4221
+ "@jscad/core": "2.5.4",
4222
+ "@jscad/examples": "2.3.2",
4223
+ "@jscad/io": "2.2.4",
4224
+ "@jscad/modeling": "2.7.2",
4225
+ "@jscad/regl-renderer": "2.5.4",
4226
4226
  "@most/create": "2.0.1",
4227
4227
  "brace": "0.11.1",
4228
4228
  "codemirror": "5.57.0",
@@ -4258,7 +4258,7 @@ const path=require("path"),{head:head}=require("@jscad/array-utils"),{formats:fo
4258
4258
  const html=require("nanohtml"),{evaluation:evaluation}=require("@jscad/core"),callbackToObservable=require("./most-utils/callbackToObservable"),packageMetadata=require("../package.json"),keyBindings=require("../data/keybindings.json");let instances=0;const makeJscad=async(e,s)=>{const{name:a,logging:i}=Object.assign({},{name:"jscad",logging:!1},s),r=html`<div class='jscad' key=${a} tabindex=${instances}></div>`;e.appendChild(r);const t=require("./sideEffects/localStorage")({name:a,logging:i}),o=require("./sideEffects/titleBar")({logging:i}),l=require("./sideEffects/dragDrop")({targetEl:r,logging:i}),n=require("./sideEffects/fileDialog")({targetEl:r,logging:i}),c=require("./sideEffects/dom")({targetEl:r},i),g=require("./sideEffects/state/index")({logging:i,packageMetadata:packageMetadata,keyBindings:keyBindings}),u=await require("./sideEffects/localFs")({logging:i}),d=require("./sideEffects/http")({logging:i}),k=await require("./sideEffects/dat")({logging:i}),f=require("./sideEffects/i18n")({translations:{en:require("../locales/en.json"),fr:require("../locales/fr.json"),de:require("../locales/de.json"),ja:require("../locales/ja.json"),hr:require("../locales/hr.json")},logging:i}),m=require("./sideEffects/worker")(evaluation.rebuildGeometryWorker),q=callbackToObservable(),b=callbackToObservable(),p={paramChanges:q.stream,editor:b.stream,state:g.source(),store:t.source(),fs:u.source(),http:d.source(),https:d.source(),drops:l.source(),dom:c.source(),solidWorker:m.source(),i18n:f.source(),titleBar:o.source(),fileDialog:n.source(),dat:await k.source()},E={store:t.sink,fs:u.sink,http:d.sink,https:d.sink,i18n:f.sink,dom:c.sink,solidWorker:m.sink,state:g.sink,fileDialog:n.sink,dat:k.sink},j=require("./ui/flow/flowIn")(p),h={jscadEl:r,paramsCallbacktoStream:q,editorCallbackToStream:b};require("./ui/flow/flowOut")({sinks:E,sources:p,outputs$:j,extras:h}),instances+=1,setTimeout(()=>{document.getElementById("toggleAxes").click()},100),setTimeout(()=>{document.getElementById("toggleAxes").click()},200);const v=callbackToObservable();return e=>{v.callback(e)}};module.exports=makeJscad;
4259
4259
 
4260
4260
  },{"../data/keybindings.json":991,"../locales/de.json":1035,"../locales/en.json":1036,"../locales/fr.json":1037,"../locales/hr.json":1038,"../locales/ja.json":1039,"../package.json":1145,"./most-utils/callbackToObservable":1154,"./sideEffects/dat":1159,"./sideEffects/dom":1160,"./sideEffects/dragDrop":1161,"./sideEffects/fileDialog":1162,"./sideEffects/http":1163,"./sideEffects/i18n":1164,"./sideEffects/localFs":1165,"./sideEffects/localStorage":1167,"./sideEffects/state/index":1168,"./sideEffects/titleBar":1169,"./sideEffects/worker":1170,"./ui/flow/flowIn":1175,"./ui/flow/flowOut":1176,"@jscad/core":19,"nanohtml":1138}],1148:[function(require,module,exports){
4261
- const{merge:merge}=require("most"),mouseDrags=(e,t,o,s)=>{const{pixelRatio:a}=s;return e.flatMap(e=>{const s=e.pageX*a,r=e.pageY*a;let u=s,g=r;return o.map(e=>{const t=e.pageX*a,o=e.pageY*a,n={left:t-s,top:o-r,x:u-t,y:o-g};return u=t,g=o,{originalEvents:[e],delta:n,normalized:{x:t,y:o},type:"mouse"}}).takeUntil(t)})},touchDrags=(e,t,o,s)=>{const{pixelRatio:a}=s;return e.filter(e=>1===e.touches.length||3===e.touches.length).flatMap(e=>{const s=e.touches[0].pageX*a,r=e.touches[0].pageY*a;let u=s,g=r;return o.map(e=>{const t=e.touches[0].pageX*a,o=e.touches[0].pageY*a,n={left:t-s,top:o-r,x:u-t,y:o-g};return u=t,g=o,{originalEvents:[e],delta:n,normalized:{x:t,y:o},type:"touch"}}).takeUntil(t)})},drags=({mouseDowns$:e,mouseUps$:t,mouseMoves$:o,touchStarts$:s,touchEnds$:a,longTaps$:r,touchMoves$:u},g)=>{return merge(mouseDrags(e,t,o,g),touchDrags(s,a,u,g))};module.exports={mouseDrags:mouseDrags,touchDrags:touchDrags,drags:drags};
4261
+ const{merge:merge}=require("most");let isPinching=!1;"undefined"!=typeof window&&(window.addEventListener("pinchStarted",e=>{isPinching=!0}),window.addEventListener("pinchEnded",e=>{isPinching=!1}));const mouseDrags=(e,t,s,o)=>{const{pixelRatio:n}=o;return e.flatMap(e=>{const o=e.pageX*n,a=e.pageY*n;let r=o,i=a;return s.map(e=>{const t=e.pageX*n,s=e.pageY*n,u={left:t-o,top:s-a,x:r-t,y:s-i};return r=t,i=s,{originalEvents:[e],delta:u,normalized:{x:t,y:s},type:"mouse"}}).takeUntil(t)})},touchDrags=(e,t,s,o)=>{const{pixelRatio:n}=o;return e.filter(e=>1===e.touches.length||3===e.touches.length).flatMap(e=>{const o=e.touches[0].pageX*n,a=e.touches[0].pageY*n;let r=o,i=a;return s.takeWhile(e=>!1===isPinching).map(e=>{const t=e.touches[0].pageX*n,s=e.touches[0].pageY*n,u={left:t-o,top:s-a,x:r-t,y:s-i};return r=t,i=s,{originalEvents:[e],delta:u,normalized:{x:t,y:s},type:"touch"}}).takeUntil(t)})},drags=({mouseDowns$:e,mouseUps$:t,mouseMoves$:s,touchStarts$:o,touchEnds$:n,longTaps$:a,touchMoves$:r},i)=>{return merge(mouseDrags(e,t,s,i),touchDrags(o,n,r,i))};module.exports={mouseDrags:mouseDrags,touchDrags:touchDrags,drags:drags};
4262
4262
 
4263
4263
  },{"most":1102}],1149:[function(require,module,exports){
4264
4264
  const{fromEvent:fromEvent,merge:merge}=require("most"),{normalizeWheel:normalizeWheel,preventDefault:preventDefault}=require("./utils"),{presses:presses}=require("./presses"),{taps:taps}=require("./taps"),{drags:drags}=require("./drags"),{zooms:zooms}=require("./zooms"),baseInteractionsFromEvents=(e,s)=>{s=Object.assign({},{passiveEventsHandlers:!0,preventScroll:!0,preventMenu:!0},s);const{passiveEventsHandlers:t,preventScroll:r,preventMenu:o}=s,a=fromEvent("mousedown",e,{passive:t,capture:!1}),n=fromEvent("mouseup",e,{passive:t,capture:!1}),p=fromEvent("mousemove",e,{passive:t,capture:!1}),i=fromEvent("contextmenu",e,{passive:!s.preventMenu,capture:!1}),u=fromEvent("touchstart",e,{passive:t,capture:!1}),v=fromEvent("touchmove",e,{passive:t,capture:!1}),m=fromEvent("touchend",e,{passive:t,capture:!1}),l=merge(a,u),c=merge(n,m),f=merge(p,v.filter(e=>1===e.touches.length));return r&&(e=>{fromEvent("mousewheel",e,{passive:!1,capture:!1}).forEach(preventDefault),fromEvent("DOMMouseScroll",e,{passive:!1,capture:!1}).forEach(preventDefault),fromEvent("wheel",e,{passive:!1,capture:!1}).forEach(preventDefault),fromEvent("touchmove",e,{passive:!1,capture:!1}).forEach(preventDefault)})(e),o&&i.forEach(preventDefault),{mouseDowns$:a,mouseUps$:n,mouseMoves$:p,rightClicks$:i,wheel$:merge(fromEvent("wheel",e,{passive:t,capture:!1}),fromEvent("DOMMouseScroll",e,{passive:t,capture:!1}),fromEvent("mousewheel",e,{passive:t,capture:!1})).map(normalizeWheel),touchStarts$:u,touchMoves$:v,touchEnds$:m,pointerDowns$:l,pointerUps$:c,pointerMoves$:f}},pointerGestures=(e,s)=>{const t="addEventListener"in e?baseInteractionsFromEvents(e,s):e,r={multiTapDelay:250,longPressDelay:250,maxStaticDeltaSqr:100,zoomMultiplier:200,pinchThreshold:4e3,pixelRatio:"undefined"!=typeof window&&window.devicePixelRatio?window.devicePixelRatio:1},o=Object.assign({},r,s),a=presses(t,o),n=a.filter(e=>e.timeDelta>o.longPressDelay).filter(e=>e.moveDelta.sqrd<o.maxStaticDeltaSqr);return{press:a,holds:n,taps:taps(a,o),drags:drags(t,o),zooms:zooms(t,o)}};module.exports={baseInteractionsFromEvents:baseInteractionsFromEvents,pointerGestures:pointerGestures};
@@ -4273,7 +4273,7 @@ const{exists:exists}=require("./utils"),taps=(t,e)=>{const{longPressDelay:a,maxS
4273
4273
  const{empty:empty,continueWith:continueWith}=require("most"),repeat=(e,t)=>0===e?empty():1===e?t:continueWith(()=>repeat(e-1,t),t),preventDefault=e=>(e.preventDefault(),e),isMoving=(e,t)=>!0,normalizeWheel=e=>{let t={x:0,y:0};return e.wheelDelta?t=e.wheelDelta:e.detail?t=-e.detail:e.deltaY&&(t=-e.deltaY),t=t>=0?1:-1},exists=e=>null!=e;module.exports={repeat:repeat,preventDefault:preventDefault,isMoving:isMoving,normalizeWheel:normalizeWheel,exists:exists};
4274
4274
 
4275
4275
  },{"most":1102}],1153:[function(require,module,exports){
4276
- const{merge:merge}=require("most"),pinchZooms=({touchStarts$:e,touchMoves$:o,touchEnds$:t},s)=>{const{pixelRatio:h,pinchThreshold:u}=s;return e.filter(e=>2===e.touches.length).flatMap(e=>{const s=e.touches[0].pageX*h,c=e.touches[0].pageY*h,a=e.touches[1].pageX*h,p=e.touches[1].pageY*h,r=(s-a)*(s-a)+(c-p)*(c-p);return o.tap(e=>e.preventDefault()).filter(e=>2===e.touches.length).map(e=>{const o=e.touches[0].pageX*h,t=e.touches[0].pageY*h,s=e.touches[1].pageX*h,u=e.touches[1].pageY*h;return(o-s)*(o-s)+(t-u)*(t-u)}).loop((e,o)=>e?Math.abs(o-e)<u?{seed:o,value:void 0}:{seed:o,value:o-e}:{seed:o,value:o-r},void 0).filter(e=>void 0!==e).map(e=>3e-6*e).takeUntil(t)})},zooms=({touchStarts$:e,touchMoves$:o,touchEnds$:t,wheel$:s},h)=>{return merge(pinchZooms({touchStarts$:e,touchMoves$:o,touchEnds$:t},h),s).map(e=>e*h.zoomMultiplier)};module.exports={pinchZooms:pinchZooms,zooms:zooms};
4276
+ const{merge:merge}=require("most"),pinchZooms=({touchStarts$:e,touchMoves$:t,touchEnds$:o},s)=>{const{pixelRatio:n,pinchThreshold:u}=s;return e.filter(e=>2===e.touches.length).flatMap(e=>{const s=e.touches[0].pageX*n,c=e.touches[0].pageY*n,h=e.touches[1].pageX*n,a=e.touches[1].pageY*n,p=(s-h)*(s-h)+(c-a)*(c-a);return t.tap(e=>e.preventDefault()).filter(e=>2===e.touches.length).tap(e=>{if("undefined"!=typeof CustomEvent){const e=new CustomEvent("pinchStarted",{detail:!0});window.dispatchEvent(e)}}).map(e=>{const t=e.touches[0].pageX*n,o=e.touches[0].pageY*n,s=e.touches[1].pageX*n,u=e.touches[1].pageY*n;return(t-s)*(t-s)+(o-u)*(o-u)}).loop((e,t)=>e?Math.abs(t-e)<u?{seed:t,value:void 0}:{seed:t,value:t-e}:{seed:t,value:t-p},void 0).filter(e=>void 0!==e).map(e=>3e-6*e).takeUntil(o.tap(e=>{if("undefined"!=typeof CustomEvent){const e=new CustomEvent("pinchEnded",{detail:!0});window.dispatchEvent(e)}}))})},zooms=({touchStarts$:e,touchMoves$:t,touchEnds$:o,wheel$:s},n)=>{return merge(pinchZooms({touchStarts$:e,touchMoves$:t,touchEnds$:o},n),s).map(e=>e*n.zoomMultiplier)};module.exports={pinchZooms:pinchZooms,zooms:zooms};
4277
4277
 
4278
4278
  },{"most":1102}],1154:[function(require,module,exports){
4279
4279
  const{create:create}=require("@most/create"),callBackToStream=()=>{let e=function(){};const t=t=>{e(t)};return{stream:create((t,a,c)=>{e=t}),callback:t}};module.exports=callBackToStream;
@@ -4291,7 +4291,7 @@ module.exports={callbackToObservable:require("./callbackToObservable"),delayFrom
4291
4291
  const most=require("most"),withLatestFrom=(t,o)=>s=>most.sample(t,s,o,s);module.exports=withLatestFrom;
4292
4292
 
4293
4293
  },{"most":1102}],1159:[function(require,module,exports){
4294
- const{getFileExtensionFromString:getFileExtensionFromString}=require("@jscad/core").utils,callbackToObservable=require("../../most-utils/callbackToObservable"),makeLogger=require("../../utils/logger"),makeDatSideEffect=async e=>{const a=callbackToObservable(),{logging:t}=Object.assign({},{logging:!1},e),n=makeLogger({enabled:t});let r=!0;const i=window.DatArchive;i||(n.error("Dat archives not supported in this environment!"),r=!1);return{source:()=>a.stream.multicast(),sink:e=>{let t,l,o,s=[];e.forEach(e=>{const{type:c,id:d,urls:m,path:u}=e;if(!r)return void a.callback({type:c,id:d,error:new Error("Dat archives not supported in this environment!")});const h={unhandled:()=>{a.callback({type:c,id:d,error:new Error(`Dat: no handler found for command ${c}`)})},read:()=>{m.map(async e=>{e=e.replace(" ","+"),l=e,t=new i(e,{});const n=await t.readdir(u,{recursive:!0,stat:!0}),r=await Promise.all(n.map(async e=>{const a=`${u}/${e.name}`;if(e.stat.isFile()&&e.name.includes("js"))return{content:await t.readFile(a),name:e.name,fullPath:e.name,isFile:!0}})),m=await t.getInfo();o=m.title||"unnamed";const h=r.filter(e=>void 0!==e).map(e=>({name:e.name,ext:getFileExtensionFromString(e.name),source:e.content,fullPath:`/${o}/`+e.fullPath}));s=[{children:h,fullPath:`/${o}`,name:o}],a.callback({type:c,id:d,url:e,data:s});const g=await t.history();console.log("history",g)})},write:()=>{n.warning("writing to dat archives is not implemented yet")},watch:()=>{console.log("starting watch"),t.watch().addEventListener("changed",async({path:e})=>{console.log(e,"has been updated!");const n=await t.readFile(e),r={name:require("path").basename(e),ext:"js",source:n,fullPath:`/${o}`+e},i=s[0].children.findIndex(e=>e.fullPath===r.fullPath);(s=JSON.parse(JSON.stringify(s)))[0].children[i]=r,a.callback({type:"read",id:"loadRemote",url:l,data:s})})}};(h[c]||h.unhandled)()})}}};module.exports=makeDatSideEffect;
4294
+ const{getFileExtensionFromString:getFileExtensionFromString}=require("@jscad/core").utils,callbackToObservable=require("../../most-utils/callbackToObservable"),makeLogger=require("../../utils/logger"),makeDatSideEffect=async e=>{const a=callbackToObservable(),{logging:t}=Object.assign({},{logging:!1},e),n=makeLogger({enabled:t});let r=!0;const i=window.DatArchive;i||(n.error("Dat archives not supported in this environment!"),r=!1);return{source:()=>a.stream.multicast(),sink:e=>{let t,l,o,s=[];e.forEach(e=>{const{type:c,id:d,urls:m,path:u}=e;if(!r)return void a.callback({type:c,id:d,error:new Error("Dat archives not supported in this environment!")});const h={unhandled:()=>{a.callback({type:c,id:d,error:new Error(`Dat: no handler found for command ${c}`)})},read:()=>{m.map(async e=>{e=e.replace(" ","+"),l=e,t=new i(e,{});const n=await t.readdir(u,{recursive:!0,stat:!0}),r=await Promise.all(n.map(async e=>{const a=`${u}/${e.name}`;if(e.stat.isFile()&&e.name.includes("js"))return{content:await t.readFile(a),name:e.name,fullPath:e.name,isFile:!0}})),m=await t.getInfo();o=m.title||"unnamed";const h=r.filter(e=>void 0!==e).map(e=>({name:e.name,ext:getFileExtensionFromString(e.name),source:e.content,fullPath:`/${o}/`+e.fullPath}));s=[{children:h,fullPath:`/${o}`,name:o}],a.callback({type:c,id:d,url:e,data:s}),await t.history()})},write:()=>{n.warning("writing to dat archives is not implemented yet")},watch:()=>{t.watch().addEventListener("changed",async({path:e})=>{const n=await t.readFile(e),r={name:require("path").basename(e),ext:"js",source:n,fullPath:`/${o}`+e},i=s[0].children.findIndex(e=>e.fullPath===r.fullPath);(s=JSON.parse(JSON.stringify(s)))[0].children[i]=r,a.callback({type:"read",id:"loadRemote",url:l,data:s})})}};(h[c]||h.unhandled)()})}}};module.exports=makeDatSideEffect;
4295
4295
 
4296
4296
  },{"../../most-utils/callbackToObservable":1154,"../../utils/logger":1196,"@jscad/core":19,"path":1046}],1160:[function(require,module,exports){
4297
4297
  const most=require("most"),morph=require("morphdom"),{proxy:proxy}=require("most-proxy"),makeDomSideEffect=({targetEl:e})=>{const{attach:t,stream:r}=proxy(),o=r,s={};return{source:()=>{const t=t=>Array.from(e.querySelectorAll(t));return o.forEach(()=>{Object.keys(s).forEach(e=>{const[r]=e.split("@@"),o=t(r);if(o&&o.length>0){const t=s[e];if(!1===t.live){t.live=!0;const e=o.map(e=>most.fromEvent(t.events,e)),r=most.mergeArray(e);t.observable.attach(r)}}})}),{select:e=>{const r=t(e);let o;return{events:function(t){if(!r||r&&0===r.length){const r=proxy();o=r.stream,s[e+"@@"+t]={observable:r,live:!1}}return s[e+"@@"+t].events=t,o.multicast()}}},element:e}},sink:((e,r)=>{let o;const s=r.take(1).map(t=>{o=t,e.appendChild(o)}),m=r.skip(1).map(e=>{morph(o,e)}),n=most.mergeArray([s,m]).multicast();t(n),n.forEach(e=>e)}).bind(null,e)}};module.exports=makeDomSideEffect;
@@ -4300,7 +4300,7 @@ const most=require("most"),morph=require("morphdom"),{proxy:proxy}=require("most
4300
4300
  const{fromEvent:fromEvent}=require("most"),preventDefault=t=>(t.preventDefault(),t),isTextNotEmpty=t=>""!==t,exists=t=>null!=t,itemListToArray=t=>{const e=[];for(let r=0;r<t.length;r++){const a=t[r];e.push(a.webkitGetAsEntry?a.webkitGetAsEntry():a)}return e},extractData=t=>{if(isTextNotEmpty(t.dataTransfer.getData("url")))return{type:"url",data:t.dataTransfer.getData("url")};if(t.dataTransfer.types.includes("text/plain")){const e=t.dataTransfer.getData("text");try{return{type:"url",data:new URL(e).href}}catch{return{type:"text",data:e}}}return t.dataTransfer.items&&t.dataTransfer.items.length>0?{type:"fileOrFolder",data:itemListToArray(t.dataTransfer.items)}:void 0},makeDragAndDropSideEffect=({targetEl:t})=>{return{source:()=>{const{dragOvers$:e,drops$:r}=(t=>({dragOvers$:fromEvent("dragover",t),drops$:fromEvent("drop",t)}))(t);return r.multicast(),r.forEach(preventDefault),e.forEach(preventDefault),r.map(t=>extractData(t)).filter(exists).multicast()}}};module.exports=makeDragAndDropSideEffect;
4301
4301
 
4302
4302
  },{"most":1102}],1162:[function(require,module,exports){
4303
- const callbackToObservable=require("../../most-utils/callbackToObservable"),makeFileDialog=e=>{const l=callbackToObservable();return{source:()=>{},sink:e=>{e.forEach(e=>{l.callback(e),console.log("here");const o=document.createElement("input");o.id="foo",o.name="gna",o.setAttribute("type","file"),o.click(),o.addEventListener("change",()=>{console.log("foo")})})}}};module.exports=makeFileDialog;
4303
+ const callbackToObservable=require("../../most-utils/callbackToObservable"),makeFileDialog=e=>{const a=callbackToObservable();return{source:()=>{},sink:e=>{e.forEach(e=>{a.callback(e);const l=document.createElement("input");l.id="foo",l.name="gna",l.setAttribute("type","file"),l.click(),l.addEventListener("change",()=>{})})}}};module.exports=makeFileDialog;
4304
4304
 
4305
4305
  },{"../../most-utils/callbackToObservable":1154}],1163:[function(require,module,exports){
4306
4306
  const path=require("path"),{getFileExtensionFromString:getFileExtensionFromString}=require("@jscad/core").utils,{formats:formats}=require("@jscad/io/formats"),callbackToObservable=require("../../most-utils/callbackToObservable"),makeLogger=require("../../utils/logger"),proxyUrl="./remote.pl?url=",binaryMimetypes={stl:"application/sla"},makeHttpSideEffect=e=>{const{logging:t}=Object.assign({},{logging:!1},e),r=callbackToObservable(),a=makeLogger({enabled:t});return{source:()=>r.stream.multicast(),sink:e=>{e.forEach(e=>{const{type:t,id:o,urls:n,origin:i,proxy:l}=e,s={read:()=>{let e=[];n.forEach(n=>{const s=e=>{r.callback({type:t,id:o,url:n,error:e}),a.error(e)},c=a=>{e=e.concat(a),r.callback({type:t,id:o,url:n,data:e})};l?readProxy(n,s,e=>{if(e.file){const t=new URL(i),r=new URL(e.file,t);readFile(r.toString(),s,c)}}):readFile(n,s,c)})},write:()=>{a.warning("writing to http is not implemented yet")},watch:()=>{a.warning("watching http is not implemented yet")},unhandled:()=>{r.callback({type:t,id:o,error:new Error(`http: no handler found for command ${t}`)})}};(s[t]||s.unhandled)()})}}},readFile=(e,t,r)=>{const a=getFileExtensionFromString(e),o=void 0!==binaryMimetypes[a];fetch(e).then(e=>{if(e.ok)return o?e.arrayBuffer():e.text();t(new Error(`fetch error: ${e.status} ${e.statusText}`))}).then(t=>{const o=path.basename(e),n=`/${o}`,i=formats[a]?formats[a].mimetype:"";r({name:o,ext:a,mimetype:i,source:t,fullPath:n})}).catch(e=>{t(e)})},readProxy=(e,t,r)=>{fetch(proxyUrl+e).then(e=>{if(e.ok)return e.json();t(new Error(`fetch error: ${e.status} ${e.statusText}`))}).then(e=>{r(e)}).catch(e=>{t(e)})};module.exports=makeHttpSideEffect;
@@ -4309,7 +4309,7 @@ const path=require("path"),{getFileExtensionFromString:getFileExtensionFromStrin
4309
4309
  const isElectron=require("is-electron"),callBackToStream=require("../../most-utils/callbackToObservable"),longNames={en:"english",de:"german",fr:"french",ja:"japanese",hr:"croatian"},getDefaultLocale=()=>{let a;return isElectron()||(a=navigator.languages&&navigator.languages.length?navigator.languages[0]:navigator.language),a?a.split("-")[0]:""},initTranslations=a=>{const{translations:e}=Object.assign({},{translations:{}},a);return e},i18nImport=require("es2015-i18n-tag"),i18n=i18nImport.default,{i18nConfig:i18nConfig}=i18nImport,makei18nSideEffect=a=>{const e=callBackToStream();let t=initTranslations(a);const n={setAvailableTranslations:a=>{t=a.data},getDefaultLocale:a=>{e.callback({data:getDefaultLocale(),type:a.type})},changeSettings:a=>{const n=a.data;i18nConfig({locales:n,translations:t[n]}),e.callback({data:i18n,type:"changeSettings"})},getAvailableLanguages:a=>{const n=Object.keys(t).map(a=>{let e=longNames[a]?longNames[a]:"placeholder";const n=t[a];return n&&"language"in n&&(e=n.language),{code:a,fullName:e}});e.callback({data:n,type:"getAvailableLanguages"})}};return{sink:a=>{a.forEach(a=>{const e=n[a.type];e&&e(a)})},source:()=>e.stream.multicast()}};module.exports=makei18nSideEffect;
4310
4310
 
4311
4311
  },{"../../most-utils/callbackToObservable":1154,"es2015-i18n-tag":1057,"is-electron":1059}],1165:[function(require,module,exports){
4312
- const{walkFileTree:walkFileTree}=require("@jscad/core").web,callbackToObservable=require("../../most-utils/callbackToObservable"),{changedFiles:changedFiles,flattenFiles:flattenFiles}=require("./utils"),localFsOptions=require("../../../data/localFsOptions.json"),makeLocalFsSideEffect=async e=>{const o=callbackToObservable();let l=null,a=0;const t=e=>l.send(JSON.stringify(e));return{source:()=>o.stream.multicast(),sink:e=>{let n,c,s,r=5e3;e.forEach(e=>{const{type:i,id:d,data:f,options:m,path:u}=e,h={unhandled:()=>{o.callback({type:i,id:d,error:new Error(`LocalFs: no handler found for command ${i}`)})},read:async()=>{n=void 0,c=void 0,s&&(clearInterval(s),s=0,l&&l.close()),f.length&&f[0]instanceof File||(c=f),n=await walkFileTree(f),o.callback({type:i,id:d,data:n})},watch:()=>{if(void 0===c)return;const{enabled:e}=m;e?(l||((l=new WebSocket(localFsOptions.livereloadUrl)).onopen=function(e){console.log("websocket open",e),t({command:"hello",protocols:["http://livereload.com/protocols/official-6","http://livereload.com/protocols/official-7"],ver:"2.0.8",ext:"Chrome",extver:"2.1.0"})},l.onmessage=function(e){const o=JSON.parse(e.data);"hello"===o.command&&t({command:"info",plugins:{less:{disable:!1,version:"1.0"}},url:document.location}),"reload"===o.command&&(a=0)},l.onerror=function(e){console.log("websocket error",e)},l.onclose=function(e){console.log("websocket closed",e),l=null}),s=setInterval(()=>{const e=Date.now();!c||l&&a||e-a<r||(a=e,walkFileTree(c).catch(e=>{console.error("failed to read files",e)}).then(l=>{const a=flattenFiles(n),t=flattenFiles(l),c=changedFiles(a,t);c.length>0&&(n=l,o.callback({type:"read",id:"loadRemote",data:n,path:u,changed:c}));const s=Date.now();r=Math.max(2*(s-e),1e3)}))},50)):s&&(clearInterval(s),s=0)},write:()=>{}};(h[i]||h.unhandled)()})}}};module.exports=makeLocalFsSideEffect;
4312
+ const{walkFileTree:walkFileTree}=require("@jscad/core").web,callbackToObservable=require("../../most-utils/callbackToObservable"),{changedFiles:changedFiles,flattenFiles:flattenFiles}=require("./utils"),localFsOptions=require("../../../data/localFsOptions.json"),makeLocalFsSideEffect=async e=>{const l=callbackToObservable();let o=null,a=0;const t=e=>o.send(JSON.stringify(e));return{source:()=>l.stream.multicast(),sink:e=>{let n,c,r,s=5e3;e.forEach(e=>{const{type:i,id:d,data:f,options:m,path:u}=e,h={unhandled:()=>{l.callback({type:i,id:d,error:new Error(`LocalFs: no handler found for command ${i}`)})},read:async()=>{n=void 0,c=void 0,r&&(clearInterval(r),r=0,o&&o.close()),f.length&&f[0]instanceof File||(c=f),n=await walkFileTree(f),l.callback({type:i,id:d,data:n})},watch:()=>{if(void 0===c)return;const{enabled:e}=m;e?(o||((o=new WebSocket(localFsOptions.livereloadUrl)).onopen=function(e){t({command:"hello",protocols:["http://livereload.com/protocols/official-6","http://livereload.com/protocols/official-7"],ver:"2.0.8",ext:"Chrome",extver:"2.1.0"})},o.onmessage=function(e){const l=JSON.parse(e.data);"hello"===l.command&&t({command:"info",plugins:{less:{disable:!1,version:"1.0"}},url:document.location}),"reload"===l.command&&(a=0)},o.onerror=function(e){console.warn("websocket error",e)},o.onclose=function(e){o=null}),r=setInterval(()=>{const e=Date.now();!c||o&&a||e-a<s||(a=e,walkFileTree(c).catch(e=>{console.error("failed to read files",e)}).then(o=>{const a=flattenFiles(n),t=flattenFiles(o),c=changedFiles(a,t);c.length>0&&(n=o,l.callback({type:"read",id:"loadRemote",data:n,path:u,changed:c}));const r=Date.now();s=Math.max(2*(r-e),1e3)}))},50)):r&&(clearInterval(r),r=0)},write:()=>{}};(h[i]||h.unhandled)()})}}};module.exports=makeLocalFsSideEffect;
4313
4313
 
4314
4314
  },{"../../../data/localFsOptions.json":992,"../../most-utils/callbackToObservable":1154,"./utils":1166,"@jscad/core":19}],1166:[function(require,module,exports){
4315
4315
  const sameFile=(e,t)=>{if(e.fullPath===t.fullPath&&typeof e.source==typeof t.source){if(e.source.byteLength){const n=new Uint8Array(e.source),r=new Uint8Array(t.source);return n.length===r.length&&n.every((e,t)=>e===r[t])}return e.length===t.length&&e.source===t.source}return!1},changedFiles=(e,t)=>{const n=e.slice();return t.filter(e=>{const t=n.findIndex((t,n)=>sameFile(t,e));return t<0||(n.splice(t,1),!1)})},flattenFiles=e=>{let t=[];return e.forEach(e=>{e.children?t=t.concat(flattenFiles(e.children)):t.push(e)}),t};module.exports={changedFiles:changedFiles,flattenFiles:flattenFiles};
@@ -4327,7 +4327,7 @@ const most=require("most"),makeTitleBarSideEffect=()=>{return{sink:e=>{e.forEach
4327
4327
  const WebWorkify=require("webworkify"),callBackToStream=require("../../most-utils/callbackToObservable"),makeWorkerEffect=e=>{let r=WebWorkify(e);r.onerror=(e=>a.callback({error:e})),r.onmessage=(e=>a.callback(e));const a=callBackToStream();return{sink:c=>{c.filter(({cmd:e})=>"cancel"===e).forEach(e=>r.terminate()),c.filter(({cmd:e})=>"cancel"!==e).forEach(c=>{r.terminate(),(r=WebWorkify(e)).onerror=(e=>a.callback({error:e})),r.onmessage=(e=>a.callback(e)),r.postMessage(c)})},source:function(){return a.stream.multicast()}}};module.exports=makeWorkerEffect;
4328
4328
 
4329
4329
  },{"../../most-utils/callbackToObservable":1154,"webworkify":1144}],1171:[function(require,module,exports){
4330
- const path=require("path"),most=require("most"),{delayFromObservable:delayFromObservable,holdUntil:holdUntil,withLatestFrom:withLatestFrom}=require("../../most-utils"),{applyParameterDefinitions:applyParameterDefinitions,getParameterValuesFromUIControls:getParameterValuesFromUIControls}=require("@jscad/core").parameters,{getDesignEntryPoint:getDesignEntryPoint,getDesignName:getDesignName}=require("@jscad/core").loading.requireDesignUtilsFs,{makeFakeFs:makeFakeFs}=require("@jscad/core").loading,{keep:keep}=require("../../utils/object"),{fetchUriParams:fetchUriParams,getAllUriParams:getAllUriParams}=require("../../utils/urlUtils"),{availableExportFormatsFromSolids:availableExportFormatsFromSolids,exportFilePathFromFormatAndDesign:exportFilePathFromFormatAndDesign}=require("../../core/io/exportUtils"),packageMetadata=require("../../../package.json"),jsonCompare=(e,t)=>JSON.stringify(e)===JSON.stringify(t),designEqualityFields=["parameterDefinitions","parameterValues","mainPath","filesAndFolders","vtreeMode"],serializableFields=["name","mainPath","origin","parameterValues","vtreeMode","autoReload","instantUpdate","solidsTimeOut"],reducers={initialize:e=>{return{design:{name:"",path:"",mainPath:"",origin:void 0,filesAndFolders:[],instantUpdate:!1,autoReload:!1,convertSupportedTypes:!1,parameterDefinitions:[],parameterValues:{},parameterDefaults:{},solidsTimeOut:8e4,solids:[],vtreeMode:!1,lookup:{},lookupCounts:{},debug:{startTime:0,endTime:0,totalTime:0}}}},resetDesign:(e,t)=>{const s=Object.assign({},e.design,keep(["name","path","mainPath","origin","filesAndFolders","parameterDefinitions","parameterValues","parameterDefaults","lookup","lookupCounts","debug","solids"],reducers.initialize().design));return s.origin=t,{design:s}},setDesignContent:(e,t)=>{const{filesAndFolders:s}=t,a=makeFakeFs(s),r=s[0].fullPath,i=getDesignEntryPoint(a,r),n=getDesignName(a,r),o=path.dirname(r);let l=e.design;const d=Object.assign({},e.design.debug,{startTime:new Date});return{design:l=Object.assign({},l,{name:n,path:o,mainPath:i,filesAndFolders:s,debug:d}),appTitle:`jscad v ${packageMetadata.version}: ${e.design.name}`,status:Object.assign({},e.status,{busy:!0,error:void 0})}},setDesignSolids:(e,{solids:t,lookup:s,lookupCounts:a})=>{t=t||[],s=s||{},a=a||{};const r=new Date,i=r-e.design.debug.startTime,n=Object.assign({},e.design.debug,{endTime:r,totalTime:i});console.warn("total time for design regeneration",i,(new Date).getSeconds());const o=Object.assign({},e.design,{solids:t,lookup:s,lookupCounts:a,debug:n}),{exportFormat:l,availableExportFormats:d}=availableExportFormatsFromSolids(t),m={exportFormat:l,exportFilePath:exportFilePathFromFormatAndDesign(o,l).exportFilePath,availableExportFormats:d};return{design:o,status:Object.assign({},e.status,{busy:!1}),io:m}},setDesignParameterDefinitions:(e,t)=>{const s=t.parameterDefaults||e.design.parameterDefaults,a=t.parameterDefinitions||e.design.parameterDefinitions;return{design:Object.assign({},e.design,{parameterDefaults:s,parameterDefinitions:a,parametersOrigin:t.origin})}},setDesignParameterValues:(e,t)=>{let s=t.parameterValues;"instantUpdate"!==t.origin||e.design.instantUpdate||(s=e.design.parameterValues),s=s?applyParameterDefinitions(s,e.design.parameterDefinitions):s,s=Object.assign({},e.design.parameterValues,s);let a=Object.assign({},e.design,{parameterValues:s,parametersOrigin:t.origin});const r=Object.assign({},e.design.debug,{startTime:new Date});return{design:a=Object.assign({},a,{debug:r}),status:Object.assign({},e.status,{busy:!0,error:void 0})}},setSettings:(e,{data:t})=>{const{vtreeMode:s,autoReload:a,instantUpdate:r,solidsTimeOut:i}=t;return void 0===s?{design:e.design}:{design:Object.assign({},e.design,{vtreeMode:s,autoReload:a,instantUpdate:r,solidsTimeOut:i})}},requestGeometryRecompute:({design:e},t)=>keep(["mainPath","parameterValues","filesAndFolders","vtreeMode","lookup","lookupCounts"],e),timeoutGeometryRecompute:({status:e},t)=>e.isBusy?Object.assign({},e,{busy:!1,error:new Error("Failed to generate design within an acceptable time, bailing out")}):{status:e},requestWriteCachedGeometry:({design:e},t)=>{const s={};return Object.keys(t).forEach(e=>{s[e]=t[e]}),{path:".solidsCache",options:{isRawData:!0},origin:e.origin}},requestSaveSettings:({design:e})=>keep(serializableFields,e),isDesignValid:e=>e.design&&e.design.name&&""!==e.design.path,isDesignTheSame:(e,t)=>{if(!e.design)return!1;const s=JSON.stringify(keep(designEqualityFields,t.design));return JSON.stringify(keep(designEqualityFields,e.design))===s},isDesignTheSameForSerialization:(e,t)=>{if(!e.design)return!1;const s=JSON.stringify(keep(serializableFields,t.design));return JSON.stringify(keep(serializableFields,e.design))===s},toggleAutoReload:(e,t)=>{return{design:Object.assign({},e.design,{autoReload:t})}},toggleInstantUpdate:(e,t)=>{return{design:Object.assign({},e.design,{instantUpdate:t})}},toggleVtreeMode:(e,t)=>{return{design:Object.assign({},e.design,{vtreeMode:t})}},setSolidsTimeout:(e,t)=>{return{design:Object.assign({},e.design,{solidsTimeOut:t})}}},actions=({sources:e})=>{const t=most.just({}).thru(withLatestFrom(reducers.initialize,e.state)).map(e=>({type:"initializeDesign",state:e,sink:"state"})).multicast(),s=t.map(e=>({sink:"store",key:"design",type:"read"})),a=e.state.filter(reducers.isDesignValid).skipRepeatsWith(reducers.isDesignTheSameForSerialization).thru(holdUntil(e.store.filter(e=>"design"===e.key&&"read"===e.type))).map(reducers.requestSaveSettings).map(e=>Object.assign({},{data:e},{sink:"store",key:"design",type:"write"})).multicast(),r=e.store.filter(e=>"design"===e.key&&"read"===e.type&&void 0!==e.data).thru(withLatestFrom(reducers.setSettings,e.state)).map(e=>({type:"setDesignSettings",state:e,sink:"state"})).multicast(),i=most.mergeArray([e.drops.filter(e=>"fileOrFolder"===e.type).tap(e=>console.log("dropped file",e)).map(({data:e})=>({sink:"fs",data:e,path:"realFs",urls:[]})),e.drops.filter(e=>"url"===e.type).tap(e=>console.log("dropped url",e)).map(e=>{const t=window.location.href,s=e.data,a=new URL(s),r=s?[s]:[],{protocol:i,pathname:n}=a;return{sink:i.replace(":",""),urls:r,origin:t,path:n,proxy:!0}}).tap(e=>console.log("load url",e)),e.dom.select(".example").events("click").map(e=>e.target.dataset.path).map(e=>{const t=new URL(e),s=e?[e]:[],{protocol:a,origin:r}=t;return{sink:a.replace(":",""),urls:s,origin:r}}).tap(e=>console.log("load example",e)),e.dom.select("#fileLoader").events("change").tap(e=>console.log("selected directory",e)).filter(e=>e.target.files.length>0).map(e=>{const t=e.target.files,s=[];for(let e=0;e<t.length;e++)s.push(t.item(e));return{sink:"fs",data:s,path:"realFs",urls:[]}}),e.titleBar.filter(e=>void 0!==e).tap(e=>console.log("window href processing",e)).map(e=>{const t=e;let s=fetchUriParams(e,"uri",void 0);if(!s){const t=new URL(e);if(0===t.hash.length)return;s=t.hash.slice(1)}const a=new URL(s),r=[s],{protocol:i,pathname:n}=a;return{sink:i.replace(":",""),urls:r,origin:t,path:n,proxy:!0}})]).filter(e=>void 0!==e).thru(holdUntil(r)).map(e=>({type:"read",id:"loadRemote",urls:e.urls,sink:e.sink,origin:e.origin,path:e.path,data:e.data,proxy:e.proxy})).tap(e=>console.log("load remote",e)).multicast().skipRepeats(),n=most.mergeArray(Object.values(e).filter(e=>void 0!==e&&"source"in e)).filter(e=>!("loadRemote"!==e.id||"read"!==e.type||"error"in e||"sink"in e)).map(({data:e})=>({filesAndFolders:e})).thru(withLatestFrom(reducers.setDesignContent,e.state)).map(e=>({type:"setDesignContent",state:e,sink:"state"})).multicast(),o=most.mergeArray([e.state.filter(reducers.isDesignValid).map(({design:e})=>{return{id:"watchScript",path:e.mainPath,origin:e.origin,options:{enabled:e.autoReload}}}).skipRepeatsWith(jsonCompare)]).map(e=>Object.assign({},{type:"watch",sink:e.origin},e)).tap(e=>console.log("watch",e)).multicast(),l=most.mergeArray([e.state.filter(reducers.isDesignValid).filter(e=>void 0!==e.design.solids).map(e=>e.design.solids).skipRepeatsWith(jsonCompare)]).thru(withLatestFrom(reducers.requestWriteCachedGeometry,e.state)).map(e=>Object.assign({},{type:"write",id:"cachedGeometry",sink:e.origin},e)).multicast(),d=most.mergeArray([i.map(({sink:e})=>e)]).thru(withLatestFrom(reducers.resetDesign,e.state)).map(e=>({type:"resetDesign",state:e,sink:"state"})).multicast(),m=most.mergeArray([e.solidWorker.filter(e=>!("error"in e)&&e.data instanceof Object&&"solids"===e.data.type).map(e=>{const{lookupCounts:t,lookup:s,solids:a}=e.data;return{solids:a,lookup:s,lookupCounts:t}}).multicast(),e.fs.filter(e=>"read"===e.type&&"loadCachedGeometry"===e.id&&e.data).map(e=>{console.log("loading cached ");return{solids:void 0,lookupCounts:void 0,lookup:void e.data}}).multicast()]).thru(withLatestFrom(reducers.setDesignSolids,e.state)).map(e=>({type:"setDesignSolids",state:e,sink:"state"})).multicast(),g=e.state.skipRepeatsWith(reducers.isDesignTheSame).filter(reducers.isDesignValid).map(reducers.requestGeometryRecompute).map(e=>Object.assign({},e,{sink:"geometryWorker",cmd:"generate"})).multicast(),u=g.thru(delayFromObservable(e=>e.design.solidsTimeOut,e.state.filter(reducers.isDesignValid))).thru(withLatestFrom(reducers.timeoutGeometryRecompute,e.state)).map(e=>Object.assign({},{state:e},{sink:"state",type:"timeOutDesignGeneration"})).multicast(),p=u.filter(({state:e})=>void 0!==e.status.error).map(e=>Object.assign({},{sink:"geometryWorker",cmd:"cancel"})).multicast(),c=e.solidWorker.filter(e=>!("error"in e)&&e.data instanceof Object&&"params"===e.data.type).map(({data:e})=>({parameterDefaults:e.parameterDefaults,parameterDefinitions:e.parameterDefinitions,origin:"worker"})),h=most.mergeArray([c]).skipRepeatsWith(jsonCompare).thru(holdUntil(e.state.filter(reducers.isDesignValid))).thru(withLatestFrom(reducers.setDesignParameterDefinitions,e.state)).map(e=>({type:"setDesignParameterDefinitions",state:e,sink:"state"})).multicast(),y=()=>Array.from(document.getElementById("paramsTable").getElementsByTagName("input")).concat(Array.from(document.getElementById("paramsTable").getElementsByTagName("select"))).concat(Array.from(document.getElementById("paramsTable").getElementsByClassName("groupTitle"))),f=most.mergeArray([e.dom.select("#updateDesignFromParams").events("click").map(()=>{const e=y();return{parameterValues:getParameterValuesFromUIControls(e),origin:"uiManualUpdate"}}),e.paramChanges.filter(e=>(()=>document.getElementById("instantUpdate").checked)()).map(()=>{try{const e=y();return{parameterValues:getParameterValuesFromUIControls(e),origin:"uiInstantUpdate"}}catch(e){return{error:e,origin:"instantUpdate"}}})]).multicast().debounce(10),k=e.store.filter(e=>"design"===e.key&&"read"===e.type&&void 0!==e.data.parameterValues).map(({data:e})=>({parameterValues:e.parameterValues,origin:"store"})).multicast(),D=e.titleBar.map(e=>getAllUriParams(e)).filter(e=>Object.keys(e).length>0).map(e=>({parameterValues:e,origin:"titleBar"})).multicast(),F=e.state.filter(reducers.isDesignValid).multicast();return{initialize$:t,requestLoadDesignContent$:i,requestWatchDesign$:o,requestWriteCachedGeometry$:l,resetDesign$:d,setDesignContent$:n,setDesignSolids$:m,setDesignParameterDefinitions$:h,setDesignParameterValues$:most.mergeArray([f,k,D,e.dom.select("#resetDesignToParameterDefaults").events("click").thru(withLatestFrom((e,t)=>({parameterValues:e.design.parameterDefaults,origin:"reset"}),e.state))]).skipRepeatsWith(jsonCompare).thru(holdUntil(e.state.filter(reducers.isDesignValid))).thru(holdUntil(F.filter(e=>{return e.design&&Object.keys(e.design.parameterDefinitions).length>0}))).thru(withLatestFrom(reducers.setDesignParameterValues,e.state)).map(e=>({type:"setDesignParameterValues",state:e,sink:"state"})).multicast().delay(10),requestGeometryRecompute$:g,timeoutGeometryRecompute$:u,cancelGeometryRecompute$:p,requestLoadSettings$:s,requestSaveSettings$:a,setDesignSettings$:r,toggleAutoReload$:most.mergeArray([e.dom.select("#toggleAutoReload").events("click").map(e=>e.target.checked)]).thru(withLatestFrom(reducers.toggleAutoReload,e.state)).map(e=>({type:"toggleAutoReload",state:e,sink:"state"})),toggleInstantUpdate$:most.mergeArray([e.dom.select("#instantUpdate").events("click").map(e=>e.target.checked)]).thru(withLatestFrom(reducers.toggleInstantUpdate,e.state)).map(e=>({type:"toggleInstantUpdate",state:e,sink:"state"})),toggleVTreeMode$:most.mergeArray([e.dom.select("#toggleVtreeMode").events("click").map(e=>e.target.checked)]).thru(withLatestFrom(reducers.toggleVtreeMode,e.state)).map(e=>({type:"toggleVtreeMode",state:e,sink:"state"})),setSolidsTimeout$:most.mergeArray([e.dom.select("#solidsTimeout").events("change").map(e=>e.target.value).map(e=>parseFloat(e))]).thru(withLatestFrom(reducers.setSolidsTimeout,e.state)).map(e=>({type:"setSolidsTimeout",state:e,sink:"state"}))}};module.exports=actions;
4330
+ const path=require("path"),most=require("most"),{delayFromObservable:delayFromObservable,holdUntil:holdUntil,withLatestFrom:withLatestFrom}=require("../../most-utils"),{applyParameterDefinitions:applyParameterDefinitions,getParameterValuesFromUIControls:getParameterValuesFromUIControls}=require("@jscad/core").parameters,{getDesignEntryPoint:getDesignEntryPoint,getDesignName:getDesignName}=require("@jscad/core").loading.requireDesignUtilsFs,{makeFakeFs:makeFakeFs}=require("@jscad/core").loading,{keep:keep}=require("../../utils/object"),{fetchUriParams:fetchUriParams,getAllUriParams:getAllUriParams}=require("../../utils/urlUtils"),{availableExportFormatsFromSolids:availableExportFormatsFromSolids,exportFilePathFromFormatAndDesign:exportFilePathFromFormatAndDesign}=require("../../core/io/exportUtils"),packageMetadata=require("../../../package.json"),jsonCompare=(e,t)=>JSON.stringify(e)===JSON.stringify(t),designEqualityFields=["parameterDefinitions","parameterValues","mainPath","filesAndFolders","vtreeMode"],serializableFields=["name","mainPath","origin","parameterValues","vtreeMode","autoReload","instantUpdate","solidsTimeOut"],reducers={initialize:e=>{return{design:{name:"",path:"",mainPath:"",origin:void 0,filesAndFolders:[],instantUpdate:!1,autoReload:!1,convertSupportedTypes:!1,parameterDefinitions:[],parameterValues:{},parameterDefaults:{},solidsTimeOut:8e4,solids:[],vtreeMode:!1,lookup:{},lookupCounts:{},debug:{startTime:0,endTime:0,totalTime:0}}}},resetDesign:(e,t)=>{const s=Object.assign({},e.design,keep(["name","path","mainPath","origin","filesAndFolders","parameterDefinitions","parameterValues","parameterDefaults","lookup","lookupCounts","debug","solids"],reducers.initialize().design));return s.origin=t,{design:s}},setDesignContent:(e,t)=>{const{filesAndFolders:s}=t,a=makeFakeFs(s),i=s[0].fullPath,r=getDesignEntryPoint(a,i),n=getDesignName(a,i),o=path.dirname(i);let l=e.design;const d=Object.assign({},e.design.debug,{startTime:new Date});return{design:l=Object.assign({},l,{name:n,path:o,mainPath:r,filesAndFolders:s,debug:d}),appTitle:`jscad v ${packageMetadata.version}: ${e.design.name}`,status:Object.assign({},e.status,{busy:!0,error:void 0})}},setDesignSolids:(e,{solids:t,lookup:s,lookupCounts:a})=>{t=t||[],s=s||{},a=a||{};const i=new Date,r=i-e.design.debug.startTime,n=Object.assign({},e.design.debug,{endTime:i,totalTime:r});console.warn("total time for design regeneration",r,(new Date).getSeconds());const o=Object.assign({},e.design,{solids:t,lookup:s,lookupCounts:a,debug:n}),{exportFormat:l,availableExportFormats:d}=availableExportFormatsFromSolids(t),m={exportFormat:l,exportFilePath:exportFilePathFromFormatAndDesign(o,l).exportFilePath,availableExportFormats:d};return{design:o,status:Object.assign({},e.status,{busy:!1}),io:m}},setDesignParameterDefinitions:(e,t)=>{const s=t.parameterDefaults||e.design.parameterDefaults,a=t.parameterDefinitions||e.design.parameterDefinitions;return{design:Object.assign({},e.design,{parameterDefaults:s,parameterDefinitions:a,parametersOrigin:t.origin})}},setDesignParameterValues:(e,t)=>{let s=t.parameterValues;"instantUpdate"!==t.origin||e.design.instantUpdate||(s=e.design.parameterValues),s=s?applyParameterDefinitions(s,e.design.parameterDefinitions):s,s=Object.assign({},e.design.parameterValues,s);let a=Object.assign({},e.design,{parameterValues:s,parametersOrigin:t.origin});const i=Object.assign({},e.design.debug,{startTime:new Date});return{design:a=Object.assign({},a,{debug:i}),status:Object.assign({},e.status,{busy:!0,error:void 0})}},setSettings:(e,{data:t})=>{const{vtreeMode:s,autoReload:a,instantUpdate:i,solidsTimeOut:r}=t;return void 0===s?{design:e.design}:{design:Object.assign({},e.design,{vtreeMode:s,autoReload:a,instantUpdate:i,solidsTimeOut:r})}},requestGeometryRecompute:({design:e},t)=>keep(["mainPath","parameterValues","filesAndFolders","vtreeMode","lookup","lookupCounts"],e),timeoutGeometryRecompute:({status:e},t)=>e.isBusy?Object.assign({},e,{busy:!1,error:new Error("Failed to generate design within an acceptable time, bailing out")}):{status:e},requestWriteCachedGeometry:({design:e},t)=>{const s={};return Object.keys(t).forEach(e=>{s[e]=t[e]}),{path:".solidsCache",options:{isRawData:!0},origin:e.origin}},requestSaveSettings:({design:e})=>keep(serializableFields,e),isDesignValid:e=>e.design&&e.design.name&&""!==e.design.path,isDesignTheSame:(e,t)=>{if(!e.design)return!1;const s=JSON.stringify(keep(designEqualityFields,t.design));return JSON.stringify(keep(designEqualityFields,e.design))===s},isDesignTheSameForSerialization:(e,t)=>{if(!e.design)return!1;const s=JSON.stringify(keep(serializableFields,t.design));return JSON.stringify(keep(serializableFields,e.design))===s},toggleAutoReload:(e,t)=>{return{design:Object.assign({},e.design,{autoReload:t})}},toggleInstantUpdate:(e,t)=>{return{design:Object.assign({},e.design,{instantUpdate:t})}},toggleVtreeMode:(e,t)=>{return{design:Object.assign({},e.design,{vtreeMode:t})}},setSolidsTimeout:(e,t)=>{return{design:Object.assign({},e.design,{solidsTimeOut:t})}}},actions=({sources:e})=>{const t=most.just({}).thru(withLatestFrom(reducers.initialize,e.state)).map(e=>({type:"initializeDesign",state:e,sink:"state"})).multicast(),s=t.map(e=>({sink:"store",key:"design",type:"read"})),a=e.state.filter(reducers.isDesignValid).skipRepeatsWith(reducers.isDesignTheSameForSerialization).thru(holdUntil(e.store.filter(e=>"design"===e.key&&"read"===e.type))).map(reducers.requestSaveSettings).map(e=>Object.assign({},{data:e},{sink:"store",key:"design",type:"write"})).multicast(),i=e.store.filter(e=>"design"===e.key&&"read"===e.type&&void 0!==e.data).thru(withLatestFrom(reducers.setSettings,e.state)).map(e=>({type:"setDesignSettings",state:e,sink:"state"})).multicast(),r=most.mergeArray([e.drops.filter(e=>"fileOrFolder"===e.type).tap(e=>console.log("dropped file",e)).map(({data:e})=>({sink:"fs",data:e,path:"realFs",urls:[]})),e.drops.filter(e=>"url"===e.type).tap(e=>console.log("dropped url",e)).map(e=>{const t=window.location.href,s=e.data,a=new URL(s),i=s?[s]:[],{protocol:r,pathname:n}=a;return{sink:r.replace(":",""),urls:i,origin:t,path:n,proxy:!0}}),e.dom.select(".example").events("click").map(e=>e.target.dataset.path).map(e=>{const t=new URL(e),s=e?[e]:[],{protocol:a,origin:i}=t;return{sink:a.replace(":",""),urls:s,origin:i}}).tap(e=>console.log("load example",e)),e.dom.select("#fileLoader").events("change").tap(e=>console.log("selected directory",e)).filter(e=>e.target.files.length>0).map(e=>{const t=e.target.files,s=[];for(let e=0;e<t.length;e++)s.push(t.item(e));return{sink:"fs",data:s,path:"realFs",urls:[]}}),e.titleBar.filter(e=>void 0!==e).tap(e=>console.log("window href processing",e)).map(e=>{const t=e;let s=fetchUriParams(e,"uri",void 0);if(!s){const t=new URL(e);if(0===t.hash.length)return;s=t.hash.slice(1)}const a=new URL(s),i=[s],{protocol:r,pathname:n}=a;return{sink:r.replace(":",""),urls:i,origin:t,path:n,proxy:!0}})]).filter(e=>void 0!==e).thru(holdUntil(i)).map(e=>({type:"read",id:"loadRemote",urls:e.urls,sink:e.sink,origin:e.origin,path:e.path,data:e.data,proxy:e.proxy})).multicast().skipRepeats(),n=most.mergeArray(Object.values(e).filter(e=>void 0!==e&&"source"in e)).filter(e=>!("loadRemote"!==e.id||"read"!==e.type||"error"in e||"sink"in e)).map(({data:e})=>({filesAndFolders:e})).thru(withLatestFrom(reducers.setDesignContent,e.state)).map(e=>({type:"setDesignContent",state:e,sink:"state"})).multicast(),o=most.mergeArray([e.state.filter(reducers.isDesignValid).map(({design:e})=>{return{id:"watchScript",path:e.mainPath,origin:e.origin,options:{enabled:e.autoReload}}}).skipRepeatsWith(jsonCompare)]).map(e=>Object.assign({},{type:"watch",sink:e.origin},e)).multicast(),l=most.mergeArray([e.state.filter(reducers.isDesignValid).filter(e=>void 0!==e.design.solids).map(e=>e.design.solids).skipRepeatsWith(jsonCompare)]).thru(withLatestFrom(reducers.requestWriteCachedGeometry,e.state)).map(e=>Object.assign({},{type:"write",id:"cachedGeometry",sink:e.origin},e)).multicast(),d=most.mergeArray([r.map(({sink:e})=>e)]).thru(withLatestFrom(reducers.resetDesign,e.state)).map(e=>({type:"resetDesign",state:e,sink:"state"})).multicast(),m=most.mergeArray([e.solidWorker.filter(e=>!("error"in e)&&e.data instanceof Object&&"solids"===e.data.type).map(e=>{const{lookupCounts:t,lookup:s,solids:a}=e.data;return{solids:a,lookup:s,lookupCounts:t}}).multicast(),e.fs.filter(e=>"read"===e.type&&"loadCachedGeometry"===e.id&&e.data).map(e=>{return{solids:void 0,lookupCounts:void 0,lookup:void e.data}}).multicast()]).thru(withLatestFrom(reducers.setDesignSolids,e.state)).map(e=>({type:"setDesignSolids",state:e,sink:"state"})).multicast(),g=e.state.skipRepeatsWith(reducers.isDesignTheSame).filter(reducers.isDesignValid).map(reducers.requestGeometryRecompute).map(e=>Object.assign({},e,{sink:"geometryWorker",cmd:"generate"})).multicast(),u=g.thru(delayFromObservable(e=>e.design.solidsTimeOut,e.state.filter(reducers.isDesignValid))).thru(withLatestFrom(reducers.timeoutGeometryRecompute,e.state)).map(e=>Object.assign({},{state:e},{sink:"state",type:"timeOutDesignGeneration"})).multicast(),p=u.filter(({state:e})=>void 0!==e.status.error).map(e=>Object.assign({},{sink:"geometryWorker",cmd:"cancel"})).multicast(),c=e.solidWorker.filter(e=>!("error"in e)&&e.data instanceof Object&&"params"===e.data.type).map(({data:e})=>({parameterDefaults:e.parameterDefaults,parameterDefinitions:e.parameterDefinitions,origin:"worker"})),h=most.mergeArray([c]).skipRepeatsWith(jsonCompare).thru(holdUntil(e.state.filter(reducers.isDesignValid))).thru(withLatestFrom(reducers.setDesignParameterDefinitions,e.state)).map(e=>({type:"setDesignParameterDefinitions",state:e,sink:"state"})).multicast(),y=()=>Array.from(document.getElementById("paramsTable").getElementsByTagName("input")).concat(Array.from(document.getElementById("paramsTable").getElementsByTagName("select"))).concat(Array.from(document.getElementById("paramsTable").getElementsByClassName("groupTitle"))),f=most.mergeArray([e.dom.select("#updateDesignFromParams").events("click").map(()=>{const e=y();return{parameterValues:getParameterValuesFromUIControls(e),origin:"uiManualUpdate"}}),e.paramChanges.filter(e=>(()=>document.getElementById("instantUpdate").checked)()).map(()=>{try{const e=y();return{parameterValues:getParameterValuesFromUIControls(e),origin:"uiInstantUpdate"}}catch(e){return{error:e,origin:"instantUpdate"}}})]).multicast().debounce(10),k=e.store.filter(e=>"design"===e.key&&"read"===e.type&&void 0!==e.data.parameterValues).map(({data:e})=>({parameterValues:e.parameterValues,origin:"store"})).multicast(),D=e.titleBar.map(e=>getAllUriParams(e)).filter(e=>Object.keys(e).length>0).map(e=>({parameterValues:e,origin:"titleBar"})).multicast(),F=e.state.filter(reducers.isDesignValid).multicast();return{initialize$:t,requestLoadDesignContent$:r,requestWatchDesign$:o,requestWriteCachedGeometry$:l,resetDesign$:d,setDesignContent$:n,setDesignSolids$:m,setDesignParameterDefinitions$:h,setDesignParameterValues$:most.mergeArray([f,k,D,e.dom.select("#resetDesignToParameterDefaults").events("click").thru(withLatestFrom((e,t)=>({parameterValues:e.design.parameterDefaults,origin:"reset"}),e.state))]).skipRepeatsWith(jsonCompare).thru(holdUntil(e.state.filter(reducers.isDesignValid))).thru(holdUntil(F.filter(e=>{return e.design&&Object.keys(e.design.parameterDefinitions).length>0}))).thru(withLatestFrom(reducers.setDesignParameterValues,e.state)).map(e=>({type:"setDesignParameterValues",state:e,sink:"state"})).multicast().delay(10),requestGeometryRecompute$:g,timeoutGeometryRecompute$:u,cancelGeometryRecompute$:p,requestLoadSettings$:s,requestSaveSettings$:a,setDesignSettings$:i,toggleAutoReload$:most.mergeArray([e.dom.select("#toggleAutoReload").events("click").map(e=>e.target.checked)]).thru(withLatestFrom(reducers.toggleAutoReload,e.state)).map(e=>({type:"toggleAutoReload",state:e,sink:"state"})),toggleInstantUpdate$:most.mergeArray([e.dom.select("#instantUpdate").events("click").map(e=>e.target.checked)]).thru(withLatestFrom(reducers.toggleInstantUpdate,e.state)).map(e=>({type:"toggleInstantUpdate",state:e,sink:"state"})),toggleVTreeMode$:most.mergeArray([e.dom.select("#toggleVtreeMode").events("click").map(e=>e.target.checked)]).thru(withLatestFrom(reducers.toggleVtreeMode,e.state)).map(e=>({type:"toggleVtreeMode",state:e,sink:"state"})),setSolidsTimeout$:most.mergeArray([e.dom.select("#solidsTimeout").events("change").map(e=>e.target.value).map(e=>parseFloat(e))]).thru(withLatestFrom(reducers.setSolidsTimeout,e.state)).map(e=>({type:"setSolidsTimeout",state:e,sink:"state"}))}};module.exports=actions;
4331
4331
 
4332
4332
  },{"../../../package.json":1145,"../../core/io/exportUtils":1146,"../../most-utils":1157,"../../utils/object":1197,"../../utils/urlUtils":1198,"@jscad/core":19,"most":1102,"path":1046}],1172:[function(require,module,exports){
4333
4333
  const makeOutput=({sources:e,extras:t})=>e.state.filter(e=>e.design&&e.languages&&e.viewer).skipRepeatsWith((e,t)=>JSON.stringify(e)===JSON.stringify(t)).combine((e,a)=>require("../views/main")(e,a,t.paramsCallbacktoStream,t.editorCallbackToStream),e.i18n.filter(e=>"changeSettings"===e.type).map(e=>e.data));module.exports=makeOutput;