Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@2gis/general

Package Overview
Dependencies
Maintainers
3
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@2gis/general - npm Package Compare versions

Comparing version 1.0.0 to 1.1.0

dist/src/labelArray.d.ts

2

dist/general.js

@@ -1,2 +0,2 @@

!function(r,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.General=e():r.General=e()}(this,function(){return function(r){function e(t){if(n[t])return n[t].exports;var o=n[t]={i:t,l:!1,exports:{}};return r[t].call(o.exports,o,o.exports,e),o.l=!0,o.exports}var n={};return e.m=r,e.c=n,e.d=function(r,n,t){e.o(r,n)||Object.defineProperty(r,n,{configurable:!1,enumerable:!0,get:t})},e.n=function(r){var n=r&&r.__esModule?function(){return r.default}:function(){return r};return e.d(n,"a",n),n},e.o=function(r,e){return Object.prototype.hasOwnProperty.call(r,e)},e.p="/dist/",e(e.s=1)}([function(r,e,n){"use strict";function t(r,e){for(var n=0,t=0;n<e.length;n++,t+=a){var o=e[n];r[t+i.pixelPositionX]=o.pixelPosition[0],r[t+i.pixelPositionY]=o.pixelPosition[1],r[t+i.groupIndex]=o.groupIndex,r[t+i.iconIndex]=o.iconIndex}}function o(r,e){for(var n=0,t=0;n<r.length;n++,t+=a)r[n].iconIndex=e[t+i.iconIndex]}n.d(e,"a",function(){return i}),n.d(e,"c",function(){return a}),e.b=t,e.d=o;var i={pixelPositionX:0,pixelPositionY:1,groupIndex:2,iconIndex:3},a=Object.keys(i).length},function(r,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var t=n(2);n.d(e,"General",function(){return t.a})},function(r,e,n){"use strict";n.d(e,"a",function(){return a});var t=n(0),o=n(3),i=n.n(o),a=function(){function r(){var r=this;this.worker=i()(4),this.queue=[],this.currentJob=void 0,this.markerArray=new Float32Array(1e3*t.c),this.worker.onmessage=function(e){if(void 0!==r.currentJob){var n=r.currentJob,o=n.markers,i=n.resolve;Object(t.d)(o,e.data),r.markerArray=e.data,r.currentJob=void 0,r.dequeue(),i()}}}return r.prototype.generalize=function(r,e,n,t){var o=this,i={bounds:r,priorityGroups:e,sprites:n};return new Promise(function(r){o.queue.push({message:i,markers:t,resolve:r}),o.dequeue()})},r.prototype.clear=function(){this.queue=[]},r.prototype.pack=function(r){r.length*t.c>this.markerArray.length&&(this.markerArray=new Float32Array(r.length*t.c)),Object(t.b)(this.markerArray,r)},r.prototype.dequeue=function(){if(void 0===this.currentJob){var r=this.queue.shift();if(void 0!==r){this.pack(r.markers);var e=r.message;e.markers=this.markerArray,e.markerCount=r.markers.length,this.worker.postMessage(e,[e.markers.buffer]),this.currentJob=r}}},r}()},function(r,e,n){function t(r){function e(t){if(n[t])return n[t].exports;var o=n[t]={i:t,l:!1,exports:{}};return r[t].call(o.exports,o,o.exports,e),o.l=!0,o.exports}var n={};e.m=r,e.c=n,e.i=function(r){return r},e.d=function(r,n,t){e.o(r,n)||Object.defineProperty(r,n,{configurable:!1,enumerable:!0,get:t})},e.n=function(r){var n=r&&r.__esModule?function(){return r.default}:function(){return r};return e.d(n,"a",n),n},e.o=function(r,e){return Object.prototype.hasOwnProperty.call(r,e)},e.p="/",e.oe=function(r){throw console.error(r),r};var t=e(e.s=ENTRY_MODULE);return t.default||t}function o(r){return(r+"").replace(/[.?*+^$[\]\\(){}|-]/g,"\\$&")}function i(r){var e=[],n=r.toString(),t=n.match(/^function\s?\(\w+,\s*\w+,\s*(\w+)\)/);if(!t)return e;for(var i,a=t[1],u=new RegExp("(\\\\n|\\W)"+o(a)+"\\((/\\*.*?\\*/)?s?.*?([\\.|\\-|\\w|/|@]+).*?\\)","g");i=u.exec(n);)e.push(i[3]);return e}function a(r,e){for(var n=[e],t=[],o={};n.length;){var a=n.pop();if(!o[a]&&r[a]){o[a]=!0,t.push(a);var u=i(r[a]);n=n.concat(u)}}return t}r.exports=function(r,e){e=e||{};var o=n.m,i=e.all?Object.keys(o):a(o,r),u="("+t.toString().replace("ENTRY_MODULE",JSON.stringify(r))+")({"+i.map(function(r){return JSON.stringify(r)+": "+o[r].toString()}).join(",")+"})(self);",c=new window.Blob([u],{type:"text/javascript"});if(e.bare)return c;var s=window.URL||window.webkitURL||window.mozURL||window.msURL,f=s.createObjectURL(c),p=new window.Worker(f);return p.objectURL=f,p}},function(r,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var t=n(5);e.default=function(r){r.onmessage=function(e){var n=e.data;Object(t.a)(n),r.postMessage(n.markers)}}},function(r,e,n){"use strict";function t(r){for(var e=r.bounds,n=r.priorityGroups,t=r.sprites,i=r.markers,a=r.markerCount,u=1+(e.maxX-e.minX>>3)<<3,c=e.maxY-e.minY,f=u*c+8>>3,p=new Uint8Array(f),d=[],m=0;m<n.length;m++)d[m]=new Uint8Array(f);for(var l=new Int8Array(a),m=0;m<a;m++){var v=m*s.c+s.a.iconIndex;l[m]=i[v],i[v]=-1}for(var m=0;m<n.length;m++){var x=t[n[m].iconIndex];if(x)for(var h=0!==m?d[m-1]:void 0,g=m!==n.length-1?d[m]:void 0,b=0;b<a;b++)-1!==l[b]&&o(i,n,t,e,h,g,p,u,c,m,b)}for(var m=0;m<n.length;m++){var x=t[n[m].iconIndex];if(x)for(var h=0!==m?d[m-1]:void 0,g=m!==n.length-1?d[m]:void 0,b=0;b<a;b++)-1===l[b]&&o(i,n,t,e,h,g,p,u,c,m,b)}}function o(r,e,n,t,o,m,l,v,x,h,g){var b=e[h],y=b.safeZone,w=b.iconIndex,k=b.margin,Y=b.degradation,X=n[w],j=X.size,O=X.anchor,I=g*s.c,P=r[I+s.a.groupIndex],A=r[I+s.a.pixelPositionX]-t.minX,U=r[I+s.a.pixelPositionY]-t.minY;P>h||(c(p,v,x,j,O,A,U,k),u(p)||P===h&&o&&i(o,v,p)||(c(f,v,x,j,O,A,U,y),u(f)||i(l,v,f)||(c(d,v,x,j,O,A,U,Y),a(l,v,p),m&&a(m,v,d),r[I+s.a.iconIndex]=w)))}function i(r,e,n){for(var t=n.minX,o=n.minY,i=n.maxX,a=n.maxY,u=o;u<a;u++){var c=u*e+t>>3,s=u*e+i>>3,f=0;if(c===s)f=r[c]&255>>(7&t)&255<<8-(7&i);else{f=r[c]&255>>(7&t);for(var p=c+1;p<s;p++)f=r[p]|f;f=r[s]&255<<8-(7&i)|f}if(0!==f)return!0}return!1}function a(r,e,n){for(var t=n.minX,o=n.minY,i=n.maxX,a=n.maxY,u=o;u<a;u++){var c=u*e+t>>3,s=u*e+i>>3;if(c===s)r[c]=r[c]|255>>(7&t)&255<<8-(7&i);else{r[c]=r[c]|255>>(7&t);for(var f=c+1;f<s;f++)r[f]=255;r[s]=r[s]|255<<8-(7&i)}}}function u(r){return r.minX===r.maxX||r.minY===r.maxY}function c(r,e,n,t,o,i,a,u){var c=i-t[0]*o[0]-u|0,s=a-t[1]*o[1]-u|0,f=i+t[0]*(1-o[0])+u|0,p=a+t[1]*(1-o[1])+u|0;r.minX=c>0?c<e?c:e:0,r.minY=s>0?s<n?s:n:0,r.maxX=f>0?f<e?f:e:0,r.maxY=p>0?p<n?p:n:0}e.a=t;var s=n(0),f={minX:0,minY:0,maxX:0,maxY:0},p={minX:0,minY:0,maxX:0,maxY:0},d={minX:0,minY:0,maxX:0,maxY:0}}])});
!function(r,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.General=e():r.General=e()}(window,function(){return function(r){var e={};function n(t){if(e[t])return e[t].exports;var o=e[t]={i:t,l:!1,exports:{}};return r[t].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=r,n.c=e,n.d=function(r,e,t){n.o(r,e)||Object.defineProperty(r,e,{enumerable:!0,get:t})},n.r=function(r){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(r,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(r,"__esModule",{value:!0})},n.t=function(r,e){if(1&e&&(r=n(r)),8&e)return r;if(4&e&&"object"==typeof r&&r&&r.__esModule)return r;var t=Object.create(null);if(n.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:r}),2&e&&"string"!=typeof r)for(var o in r)n.d(t,o,function(e){return r[e]}.bind(null,o));return t},n.n=function(r){var e=r&&r.__esModule?function(){return r.default}:function(){return r};return n.d(e,"a",e),e},n.o=function(r,e){return Object.prototype.hasOwnProperty.call(r,e)},n.p="/dist/",n(n.s=3)}([function(r,e,n){"use strict";n.d(e,"a",function(){return o}),n.d(e,"c",function(){return i}),n.d(e,"b",function(){return a}),n.d(e,"d",function(){return u});var t=0,o={pixelPositionX:t++,pixelPositionY:t++,groupIndex:t++,iconIndex:t++,priority:t++},i=Object.keys(o).length;function a(r,e){for(var n=0,t=0;n<e.length;n++,t+=i){var a=e[n];r[t+o.pixelPositionX]=a.pixelPosition[0],r[t+o.pixelPositionY]=a.pixelPosition[1],r[t+o.groupIndex]=a.groupIndex,r[t+o.iconIndex]=a.iconIndex,r[t+o.priority]=Boolean(a.priority)?1:0}}function u(r,e){for(var n=0,t=0;n<r.length;n++,t+=i)r[n].iconIndex=e[t+o.iconIndex]}},function(r,e,n){"use strict";n.d(e,"a",function(){return o}),n.d(e,"c",function(){return i}),n.d(e,"b",function(){return a}),n.d(e,"d",function(){return u});var t=0,o={markerIndex:t++,offsetX:t++,offsetY:t++,width:t++,height:t++,display:t++},i=6;function a(r,e,n){for(var t=0,a=0;a<e.length;a++){var u=e[a].htmlLabel;void 0!==u&&(r[t+o.markerIndex]=a,r[t+o.offsetX]=u.offset[0]*n,r[t+o.offsetY]=u.offset[1]*n,r[t+o.width]=u.width*n,r[t+o.height]=u.height*n,r[t+o.display]=u.display?1:0,t+=i)}}function u(r,e){for(var n=0,t=0,a=r;t<a.length;t++){var u=a[t].htmlLabel;void 0!==u&&(u.display=1===e[n+o.display],n+=i)}}},function(r,e,n){function t(r){var e={};function n(t){if(e[t])return e[t].exports;var o=e[t]={i:t,l:!1,exports:{}};return r[t].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=r,n.c=e,n.i=function(r){return r},n.d=function(r,e,t){n.o(r,e)||Object.defineProperty(r,e,{configurable:!1,enumerable:!0,get:t})},n.r=function(r){Object.defineProperty(r,"__esModule",{value:!0})},n.n=function(r){var e=r&&r.__esModule?function(){return r.default}:function(){return r};return n.d(e,"a",e),e},n.o=function(r,e){return Object.prototype.hasOwnProperty.call(r,e)},n.p="/",n.oe=function(r){throw console.error(r),r};var t=n(n.s=ENTRY_MODULE);return t.default||t}var o="[\\.|\\-|\\+|\\w|/|@]+",i="\\(\\s*(/\\*.*?\\*/)?\\s*.*?("+o+").*?\\)";function a(r){return(r+"").replace(/[.?*+^$[\]\\(){}|-]/g,"\\$&")}function u(r,e,t){var u={};u[t]=[];var f=e.toString(),c=f.match(/^function\s?\w*\(\w+,\s*\w+,\s*(\w+)\)/);if(!c)return u;for(var s,l=c[1],d=new RegExp("(\\\\n|\\W)"+a(l)+i,"g");s=d.exec(f);)"dll-reference"!==s[3]&&u[t].push(s[3]);for(d=new RegExp("\\("+a(l)+'\\("(dll-reference\\s('+o+'))"\\)\\)'+i,"g");s=d.exec(f);)r[s[2]]||(u[t].push(s[1]),r[s[2]]=n(s[1]).m),u[s[2]]=u[s[2]]||[],u[s[2]].push(s[4]);for(var m,p=Object.keys(u),y=0;y<p.length;y++)for(var v=0;v<u[p[y]].length;v++)m=u[p[y]][v],isNaN(1*m)||(u[p[y]][v]=1*u[p[y]][v]);return u}function f(r){return Object.keys(r).reduce(function(e,n){return e||r[n].length>0},!1)}r.exports=function(r,e){e=e||{};var o={main:n.m},i=e.all?{main:Object.keys(o.main)}:function(r,e){for(var n={main:[e]},t={main:[]},o={main:{}};f(n);)for(var i=Object.keys(n),a=0;a<i.length;a++){var c=i[a],s=n[c].pop();if(o[c]=o[c]||{},!o[c][s]&&r[c][s]){o[c][s]=!0,t[c]=t[c]||[],t[c].push(s);for(var l=u(r,r[c][s],c),d=Object.keys(l),m=0;m<d.length;m++)n[d[m]]=n[d[m]]||[],n[d[m]]=n[d[m]].concat(l[d[m]])}}return t}(o,r),a="";Object.keys(i).filter(function(r){return"main"!==r}).forEach(function(r){for(var e=0;i[r][e];)e++;i[r].push(e),o[r][e]="(function(module, exports, __webpack_require__) { module.exports = __webpack_require__; })",a=a+"var "+r+" = ("+t.toString().replace("ENTRY_MODULE",JSON.stringify(e))+")({"+i[r].map(function(e){return JSON.stringify(e)+": "+o[r][e].toString()}).join(",")+"});\n"}),a=a+"new (("+t.toString().replace("ENTRY_MODULE",JSON.stringify(r))+")({"+i.main.map(function(r){return JSON.stringify(r)+": "+o.main[r].toString()}).join(",")+"}))(self);";var c=new window.Blob([a],{type:"text/javascript"});if(e.bare)return c;var s=(window.URL||window.webkitURL||window.mozURL||window.msURL).createObjectURL(c),l=new window.Worker(s);return l.objectURL=s,l}},function(r,e,n){"use strict";n.r(e);var t=n(0),o=n(1),i=n(2),a=n.n(i),u=function(){function r(){var r=this;this.worker=a()(4),this.queue=[],this.currentJob=void 0,this.markerArray=new Float32Array(1e3*t.c),this.labelArray=new Float32Array(1e3*o.c),this.worker.onmessage=function(e){if(void 0!==r.currentJob){var n=r.currentJob,i=n.markers,a=n.resolve,u=e.data;t.d(i,u.markerArray),o.d(i,u.labelArray),r.markerArray=u.markerArray,r.labelArray=u.labelArray,r.currentJob=void 0,r.dequeue(),a()}}}return r.prototype.generalize=function(r,e,n,t){var o=this,i={bounds:r,priorityGroups:e,sprites:n},a=t.length,u=t.filter(function(r){return void 0!==r.htmlLabel}).length;return new Promise(function(r){o.queue.push({message:i,markers:t,resolve:r,markerCount:a,labelCount:u}),o.dequeue()})},r.prototype.clear=function(){this.queue=[]},r.prototype.pack=function(r,e,n){e*t.c>this.markerArray.length&&(this.markerArray=new Float32Array(e*t.c)),n*o.c>this.labelArray.length&&(this.labelArray=new Float32Array(n*o.c)),t.b(this.markerArray,r),o.b(this.labelArray,r,window.devicePixelRatio)},r.prototype.dequeue=function(){if(void 0===this.currentJob){var r=this.queue.shift();if(void 0!==r){this.pack(r.markers,r.markerCount,r.labelCount);var e=r.message;e.markers=this.markerArray,e.markerCount=r.markerCount,e.labels=this.labelArray,e.labelCount=r.labelCount,this.worker.postMessage(e,[e.markers.buffer,e.labels.buffer]),this.currentJob=r}}},r}();n.d(e,"General",function(){return u})},function(r,e,n){"use strict";n.r(e);var t=n(0),o=n(1),i={minX:0,minY:0,maxX:0,maxY:0},a={minX:0,minY:0,maxX:0,maxY:0},u={minX:0,minY:0,maxX:0,maxY:0},f={minX:0,minY:0,maxX:0,maxY:0};function c(r){for(var e=r.bounds,n=r.priorityGroups,i=r.markers,a=r.markerCount,u=r.labels,f=r.labelCount,c=1+(e.maxX-e.minX>>3)<<3,l=e.maxY-e.minY,d=c*l+8>>3,m=new Uint8Array(d),p=new Uint8Array(d),y=[],v=0;v<n.length;v++)y[v]=new Uint8Array(d);var b=new Int8Array(a);for(v=0;v<a;v++){var x=v*t.c+t.a.iconIndex;b[v]=i[x],i[x]=-1}var h=new Uint8Array(f);for(v=0;v<f;v++){x=v*o.c+o.a.display;h[v]=u[x],u[x]=0}s(r,m,p,y,c,l,b,h,!0,!0),s(r,m,p,y,c,l,b,h,!1,!0),s(r,m,p,y,c,l,b,h,!0,!1),s(r,m,p,y,c,l,b,h,!1,!1)}function s(r,e,n,i,a,u,f,c,s,m){for(var p=r.bounds,y=r.priorityGroups,v=r.sprites,b=r.markers,x=r.markerCount,h=r.labels,g=r.labelCount,w=0;w<y.length;w++){if(v[y[w].iconIndex])for(var k=0!==w?i[w-1]:void 0,Y=w!==y.length-1?i[w]:void 0,A=0;A<x;A++){var X=-1!==f[A],O=1===b[t.c*A+t.a.priority],j=m&&O||!m&&!O;(s&&X||!s&&!X)&&j&&l(b,y,v,p,k,Y,e,n,a,u,w,A)}}for(w=0;w<g;w++){var _=h[w*o.c+o.a.markerIndex];X=1===c[w],O=1===b[_*t.c+t.a.priority],j=m&&O||!m&&!O;(s&&X||!s&&!X)&&j&&d(b,h,p,e,n,a,u,w)}}function l(r,e,n,o,c,s,l,d,b,x,h,g){var w=e[h],k=w.safeZone,Y=w.iconIndex,A=w.margin,X=w.degradation,O=n[Y],j=O.size,_=O.anchor,P=t.c,I=t.a,S=g*P,U=r[S+I.groupIndex],C=r[S+I.pixelPositionX]-o.minX,L=r[S+I.pixelPositionY]-o.minY;U>h||(v(a,b,x,j,_,C,L,A),y(a)||U===h&&c&&m(c,b,a)||(v(i,b,x,j,_,C,L,k),y(i)||m(l,b,i)||(v(u,b,x,j,_,C,L,X),p(l,b,a),v(f,b,x,j,_,C,L,0),p(d,b,f),s&&p(s,b,u),r[S+I.iconIndex]=Y)))}function d(r,e,n,i,a,u,c,s){var l=o.c,d=o.a,b=s*l,x=e[b+d.markerIndex]*t.c;if(-1!==r[x+t.a.iconIndex]){var h=r[x+t.a.pixelPositionX]-n.minX,g=r[x+t.a.pixelPositionY]-n.minY,w=[e[b+d.width],e[b+d.height]],k=[-e[b+d.offsetX]/w[0],-e[b+d.offsetY]/w[1]];v(f,u,c,w,k,h,g,0),y(f)||m(a,u,f)||(p(i,u,f),p(a,u,f),e[b+d.display]=1)}}function m(r,e,n){for(var t=n.minX,o=n.minY,i=n.maxX,a=n.maxY,u=o;u<a;u++){var f=u*e+t>>3,c=u*e+i>>3,s=0;if(f===c)s=r[f]&255>>(7&t)&255<<8-(7&i);else{s=r[f]&255>>(7&t);for(var l=f+1;l<c;l++)s=r[l]|s;s=r[c]&255<<8-(7&i)|s}if(0!==s)return!0}return!1}function p(r,e,n){for(var t=n.minX,o=n.minY,i=n.maxX,a=n.maxY,u=o;u<a;u++){var f=u*e+t>>3,c=u*e+i>>3;if(f===c)r[f]=r[f]|255>>(7&t)&255<<8-(7&i);else{r[f]=r[f]|255>>(7&t);for(var s=f+1;s<c;s++)r[s]=255;r[c]=r[c]|255<<8-(7&i)}}}function y(r){return r.minX===r.maxX||r.minY===r.maxY}function v(r,e,n,t,o,i,a,u){var f=i-t[0]*o[0]-u|0,c=a-t[1]*o[1]-u|0,s=i+t[0]*(1-o[0])+u|0,l=a+t[1]*(1-o[1])+u|0;r.minX=f>0?f<e?f:e:0,r.minY=c>0?c<n?c:n:0,r.maxX=s>0?s<e?s:e:0,r.maxY=l>0?l<n?l:n:0}e.default=function(r){r.onmessage=function(e){c(e.data);var n=e.data,t=n.markers,o=n.labels;r.postMessage({markerArray:t,labelArray:o},[t.buffer,o.buffer])}}}])});
//# sourceMappingURL=general.js.map

@@ -7,7 +7,8 @@ import { BBox, PriorityGroup, Sprite, Marker } from './types';

private markerArray;
private labelArray;
constructor();
generalize(bounds: BBox, priorityGroups: PriorityGroup[], sprites: Sprite[], markers: Marker[]): Promise<void>;
clear(): void;
private pack(markers);
private dequeue();
private pack;
private dequeue;
}

@@ -1,2 +0,2 @@

export { General } from './General';
export { Marker, Sprite, PriorityGroup, BBox } from './types';
export { General, } from './General';
export { Marker, Sprite, PriorityGroup, BBox, } from './types';

@@ -7,2 +7,3 @@ import { Marker } from './types';

iconIndex: number;
priority: number;
};

@@ -9,0 +10,0 @@ export declare const stride: number;

export declare type Vec2 = [number, number] | Float64Array | number[];
export interface Sprite {
/** Размер иконки */
size: Vec2;
/** Центр иконки относительно ее размеров, принимает значения от 0 до 1 */
anchor: Vec2;
}
export interface Marker {
/** Позиция маркера в пикселях */
pixelPosition: Vec2;
/** Индекс в массиве групп, к которой маркер будет изначально принадлежать */
groupIndex: number;
/** Индекс спрайта в атласе, добавляется в ходе генерализации */
iconIndex: number;
/** Опциональный флаг, указывающий приоритетность маркера */
priority?: boolean;
/** Подпись маркера */
htmlLabel?: Label;
}
export interface Label {
offset: Vec2;
width: number;
height: number;
display: boolean;
}
export interface PriorityGroup {
/** Индекс иконки в атласе, которая будет установлена маркеру, попавшему в эту группу */
iconIndex: number;
/** Отступ чтобы встать */
safeZone: number;
/** Отступ после того как встал */
margin: number;
/** Отступ для области в которой все остальные маркера будут деградировать в следующую группу */
degradation: number;

@@ -34,2 +53,4 @@ }

markers: Float32Array;
labelCount: number;
labels: Float32Array;
}

@@ -39,3 +60,5 @@ export interface Job {

markers: Marker[];
markerCount: number;
labelCount: number;
resolve: () => void;
}
import { BBox, Vec2, WorkerMessage } from '../types';
export declare function generalize(data: WorkerMessage): void;
/**
* Проверяет, пересекает ли область что-либо в плоскости
*
* @param arr Плоскость
* @param width Ширина плоскости
* @param bbox Проверяемая область
*/
declare function collide(arr: Uint8Array, width: number, bbox: BBox): boolean;
/**
* Закрашиваем переданную область на плоскости
*
* @param arr Плоскость
* @param width Ширина плоскости
* @param bbox Закрашиваемая область
*/
declare function putToArray(arr: Uint8Array, width: number, bbox: BBox): void;
declare function bboxIsEmpty(a: BBox): boolean;
declare function createBBox(dst: BBox, planeWidth: number, planeHeight: number, size: Vec2, anchor: Vec2, positionX: number, positionY: number, offset: number): void;
export declare const testHandlers: {
collide: (arr: Uint8Array, width: number, bbox: BBox) => boolean;
putToArray: (arr: Uint8Array, width: number, bbox: BBox) => void;
bboxIsEmpty: (a: BBox) => boolean;
createBBox: (dst: BBox, planeWidth: number, planeHeight: number, size: Vec2, anchor: Vec2, positionX: number, positionY: number, offset: number) => void;
generalize: (data: WorkerMessage) => void;
collide: typeof collide;
putToArray: typeof putToArray;
bboxIsEmpty: typeof bboxIsEmpty;
createBBox: typeof createBBox;
generalize: typeof generalize;
};
export {};
{
"name": "@2gis/general",
"version": "1.0.0",
"version": "1.1.0",
"description": "Fast marker generalization algorithm",

@@ -26,28 +26,29 @@ "contributors": [

"test": "npm run lint && npm run unit",
"dev": "webpack-dev-server",
"build": "webpack --env.production",
"builddemo": "webpack --env.demo",
"unit": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' mocha --compilers ts:ts-node/register test/**/*.spec.ts",
"unit-dev": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' mocha -w --compilers ts:ts-node/register test/**/*.spec.ts",
"dev": "webpack-dev-server --mode=development",
"build": "webpack --mode=production",
"builddemo": "webpack --mode=production --demo",
"unit": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' mocha --require ts-node/register test/**/*.spec.ts",
"unit-dev": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' mocha -w --require ts-node/register test/**/*.spec.ts",
"lint": "tslint 'src/**/*.ts' 'demo/**/*.ts' 'test/**/*.ts'"
},
"devDependencies": {
"2gis-maps": "^3.3.5",
"@2gis/markerdrawer": "^0.0.9",
"2gis-maps": "^3.5.8",
"@2gis/markerdrawer": "^1.0.1",
"@types/leaflet": "^1.0.66",
"@types/mocha": "^2.2.41",
"@types/node": "^8.0.14",
"fork-ts-checker-webpack-plugin": "^0.4.1",
"mocha": "^3.4.2",
"ts-loader": "^2.3.1",
"ts-node": "^3.2.1",
"tslib": "^1.7.1",
"tslint": "^5.5.0",
"tslint-eslint-rules": "^4.1.1",
"typescript": "^2.4.2",
"webpack": "^3.3.0",
"webpack-dev-server": "^2.5.1",
"webworkify-webpack": "^2.0.5",
"whatwg-fetch": "^2.0.3"
"@types/mocha": "^5.2.7",
"@types/node": "^12.6.2",
"fork-ts-checker-webpack-plugin": "^1.3.7",
"mocha": "^6.1.4",
"ts-loader": "^6.0.4",
"ts-node": "^8.3.0",
"tslib": "^1.10.0",
"tslint": "^5.18.0",
"tslint-eslint-rules": "^5.4.0",
"typescript": "^3.5.3",
"webpack": "^4.35.3",
"webpack-cli": "^3.3.5",
"webpack-dev-server": "^3.7.2",
"webworkify-webpack": "^2.1.5",
"whatwg-fetch": "^3.0.0"
}
}

@@ -109,3 +109,11 @@ # General [![Build Status](https://travis-ci.org/2gis/general.svg?branch=master)](https://travis-ci.org/2gis/general)

- `groupIndex` – индекс в массиве групп, к которой маркер будет изначально принадлежать
- `priority?: boolean` — опциональный флаг, позволяющий поднять приоритет маркера над другими. Приоритетные маркеры генерализуются раньше остальных, даже если расположены после них в исходном массиве.
- `htmlLabel?: Label` — опциональная подпись маркера. Подписи генерализуются аналогично маркерам. У подписей при генерализации меньший приоритет, чем у маркеров. Другими словами, сначала генерализуются все маркеры, а затем все подписи.
`Label` описывается следующим образом:
- `offset: Vec2` - отступ в пикселях вправо и вниз от маркера
- `width: number` - ширина в пикселях
- `height: number` - высота в пикселях
- `display: boolean` - флаг, означающий, нужно ли отображать подпись. Выставляется в процессе генерализации.
Метод `generalize` **не возвращает** новый массив маркеров, он мутирует старый.

@@ -112,0 +120,0 @@

@@ -1,2 +0,3 @@

import { stride, pack, unpack } from './markerArray';
import * as markerArray from './markerArray';
import * as labelArray from './labelArray';
import {

@@ -18,2 +19,3 @@ BBox,

private markerArray: Float32Array;
private labelArray: Float32Array;

@@ -24,3 +26,4 @@ constructor() {

this.currentJob = undefined;
this.markerArray = new Float32Array(1000 * stride);
this.markerArray = new Float32Array(1000 * markerArray.stride);
this.labelArray = new Float32Array(1000 * labelArray.stride);

@@ -33,4 +36,10 @@ this.worker.onmessage = (event) => {

const { markers, resolve } = this.currentJob;
unpack(markers, event.data);
this.markerArray = event.data;
const { data } = event;
markerArray.unpack(markers, data.markerArray);
labelArray.unpack(markers, data.labelArray);
this.markerArray = data.markerArray;
this.labelArray = data.labelArray;
this.currentJob = undefined;

@@ -55,4 +64,7 @@

const markerCount = markers.length;
const labelCount = markers.filter((marker) => marker.htmlLabel !== undefined).length;
return new Promise((resolve) => {
this.queue.push({ message, markers, resolve });
this.queue.push({ message, markers, resolve, markerCount, labelCount });
this.dequeue();

@@ -66,8 +78,13 @@ });

private pack(markers: Marker[]) {
if (markers.length * stride > this.markerArray.length) {
this.markerArray = new Float32Array(markers.length * stride);
private pack(markers: Marker[], markerCount: number, labelCount: number): void {
if (markerCount * markerArray.stride > this.markerArray.length) {
this.markerArray = new Float32Array(markerCount * markerArray.stride);
}
pack(this.markerArray, markers);
if (labelCount * labelArray.stride > this.labelArray.length) {
this.labelArray = new Float32Array(labelCount * labelArray.stride);
}
markerArray.pack(this.markerArray, markers);
labelArray.pack(this.labelArray, markers, window.devicePixelRatio);
}

@@ -86,9 +103,11 @@

this.pack(job.markers);
this.pack(job.markers, job.markerCount, job.labelCount);
const message = job.message as WorkerMessage;
message.markers = this.markerArray;
message.markerCount = job.markers.length;
message.markerCount = job.markerCount;
message.labels = this.labelArray;
message.labelCount = job.labelCount;
this.worker.postMessage(message, [message.markers.buffer]);
this.worker.postMessage(message, [message.markers.buffer, message.labels.buffer]);

@@ -95,0 +114,0 @@ this.currentJob = job;

import { Marker } from './types';
// Оффсеты должны быть пронумерованы по порядку
let i = 0;
export const offsets = {
pixelPositionX: 0,
pixelPositionY: 1,
groupIndex: 2,
iconIndex: 3,
pixelPositionX: i++,
pixelPositionY: i++,
groupIndex: i++,
iconIndex: i++,
priority: i++,
};

@@ -24,2 +26,3 @@

markerArray[markerOffset + offsets.iconIndex] = marker.iconIndex;
markerArray[markerOffset + offsets.priority] = Boolean(marker.priority) ? 1 : 0;
}

@@ -26,0 +29,0 @@ }

export type Vec2 = [number, number] | Float64Array | number[];
export interface Sprite {
size: Vec2; // Размер иконки
anchor: Vec2; // Центр иконки относительно ее размеров, принимает значения от 0 до 1
/** Размер иконки */
size: Vec2;
/** Центр иконки относительно ее размеров, принимает значения от 0 до 1 */
anchor: Vec2;
}
export interface Marker {
pixelPosition: Vec2; // позиция маркера в пикселях
groupIndex: number; // Индекс в массиве групп, к которой маркер будет изначально принадлежать
iconIndex: number; // Индекс спрайта в атласе, добавляется в ходе генерализации
/** Позиция маркера в пикселях */
pixelPosition: Vec2;
/** Индекс в массиве групп, к которой маркер будет изначально принадлежать */
groupIndex: number;
/** Индекс спрайта в атласе, добавляется в ходе генерализации */
iconIndex: number;
/** Опциональный флаг, указывающий приоритетность маркера */
priority?: boolean;
/** Подпись маркера */
htmlLabel?: Label;
}
export interface Label {
offset: Vec2;
width: number;
height: number;
display: boolean;
}
export interface PriorityGroup {
iconIndex: number; // Индекс иконки в атласе, которая будет установлена маркеру, попавшему в эту группу
safeZone: number; // Отступ чтобы встать
margin: number; // Отступ после того как встал
degradation: number; // Отступ для области в которой все остальные маркера будут деградировать в следующую группу
/** Индекс иконки в атласе, которая будет установлена маркеру, попавшему в эту группу */
iconIndex: number;
/** Отступ чтобы встать */
safeZone: number;
/** Отступ после того как встал */
margin: number;
/** Отступ для области в которой все остальные маркера будут деградировать в следующую группу */
degradation: number;
}

@@ -40,2 +60,4 @@

markers: Float32Array;
labelCount: number;
labels: Float32Array;
}

@@ -46,3 +68,5 @@

markers: Marker[];
markerCount: number;
labelCount: number;
resolve: () => void;
}
import { BBox, Vec2, WorkerMessage, PriorityGroup, Sprite } from '../types';
import { stride, offsets } from '../markerArray';
import * as markerArray from '../markerArray';
import * as labelArray from '../labelArray';

@@ -7,5 +8,6 @@ const collideBBox: BBox = { minX: 0, minY: 0, maxX: 0, maxY: 0 };

const degradationBBox: BBox = { minX: 0, minY: 0, maxX: 0, maxY: 0 };
const noMarginBBox: BBox = { minX: 0, minY: 0, maxX: 0, maxY: 0 };
export function generalize(data: WorkerMessage) {
const { bounds, priorityGroups, sprites, markers, markerCount } = data;
const { bounds, priorityGroups, markers, markerCount, labels, labelCount } = data;

@@ -27,2 +29,5 @@ const planeWidth = (bounds.maxX - bounds.minX >> 3) + 1 << 3; // Ширина должна быть кратна 8

// Эта плоскость аналогична plane, но маркеры вставляются в неё без margin
const noMarginPlane = new Uint8Array(planeLength);
/**

@@ -45,3 +50,3 @@ * Следующие плоскости используются для проверки на деградацию маркеров.

for (let i = 0; i < markerCount; i++) {
const index = i * stride + offsets.iconIndex;
const index = i * markerArray.stride + markerArray.offsets.iconIndex;

@@ -55,5 +60,53 @@ // Сохраняем предыдущие индексы иконок для работы гистерезиса

// Здесь начинает работу основной алгоритм генерализации.
// У нас два вложенных цикла: по группам -> по маркерам.
// Циклы запускаются два раза: первый прогон — для маркеров, которые были видны на экране
const prevLabelState = new Uint8Array(labelCount);
for (let i = 0; i < labelCount; i++) {
const index = i * labelArray.stride + labelArray.offsets.display;
// Сохраняем предыдущее состояние лейблов
prevLabelState[i] = labels[index];
// Сбрасываем состояние лейблов
labels[index] = 0;
}
// Здесь начинает работу основной алгоритм генерализации
// Генерализуем в таком порядке:
// 1. Приоритетные маркеры, видимые на экране, затем их подписи
// 2. Приоритетные маркеры, не видимые на экране, затем их подписи
// 3. Неприоритетные маркеры, видимые на экране, затем их подписи
// 4. Неприоритетные маркеры, не видимые на экране, затем их подписи
generalizePart(
data, plane, noMarginPlane, degradationPlanes, planeWidth, planeHeight,
prevIconIndices, prevLabelState, true, true,
);
generalizePart(
data, plane, noMarginPlane, degradationPlanes, planeWidth, planeHeight,
prevIconIndices, prevLabelState, false, true,
);
generalizePart(
data, plane, noMarginPlane, degradationPlanes, planeWidth, planeHeight,
prevIconIndices, prevLabelState, true, false,
);
generalizePart(
data, plane, noMarginPlane, degradationPlanes, planeWidth, planeHeight,
prevIconIndices, prevLabelState, false, false,
);
}
function generalizePart(
data: WorkerMessage,
plane: Uint8Array,
noMarginPlane: Uint8Array,
degradationPlanes: Uint8Array[],
planeWidth: number,
planeHeight: number,
prevIconIndices: Int8Array,
prevLabelState: Uint8Array,
processVisible: boolean,
processPriority: boolean,
): void {
const { bounds, priorityGroups, sprites, markers, markerCount, labels, labelCount } = data;
for (let i = 0; i < priorityGroups.length; i++) {

@@ -70,3 +123,9 @@ const sprite = sprites[priorityGroups[i].iconIndex];

for (let j = 0; j < markerCount; j++) {
if (prevIconIndices[j] !== -1) {
const isVisible = prevIconIndices[j] !== -1;
const isPriority = markers[markerArray.stride * j + markerArray.offsets.priority] === 1;
const visibilityOk = processVisible && isVisible || !processVisible && !isVisible;
const priorityOk = processPriority && isPriority || !processPriority && !isPriority;
if (visibilityOk && priorityOk) {
generalizeMarker(

@@ -80,2 +139,3 @@ markers,

plane,
noMarginPlane,
planeWidth,

@@ -89,28 +149,13 @@ planeHeight,

// Второй прогон циклов — для маркеров, которые в данный момент не видны на экране.
for (let i = 0; i < priorityGroups.length; i++) {
const sprite = sprites[priorityGroups[i].iconIndex];
if (!sprite) {
// Защищаемся от ситуации, когда в конфиге передан некорректный индекс спрайта
continue;
}
for (let i = 0; i < labelCount; i++) {
const markerIndex = labels[i * labelArray.stride + labelArray.offsets.markerIndex];
const prevDegradationPlane = i !== 0 ? degradationPlanes[i - 1] : undefined;
const degradationPlane = i !== priorityGroups.length - 1 ? degradationPlanes[i] : undefined;
const isVisible = prevLabelState[i] === 1;
const isPriority = markers[markerIndex * markerArray.stride + markerArray.offsets.priority] === 1;
for (let j = 0; j < markerCount; j++) {
if (prevIconIndices[j] === -1) {
generalizeMarker(
markers,
priorityGroups,
sprites,
bounds,
prevDegradationPlane,
degradationPlane,
plane,
planeWidth,
planeHeight,
i, j,
);
}
const visibilityOk = processVisible && isVisible || !processVisible && !isVisible;
const priorityOk = processPriority && isPriority || !processPriority && !isPriority;
if (visibilityOk && priorityOk) {
generalizeLabel(markers, labels, bounds, plane, noMarginPlane, planeWidth, planeHeight, i);
}

@@ -128,2 +173,3 @@ }

plane: Uint8Array,
noMarginPlane: Uint8Array,
planeWidth: number,

@@ -136,2 +182,3 @@ planeHeight: number,

const { size, anchor } = sprites[iconIndex];
const { stride, offsets } = markerArray;

@@ -170,2 +217,6 @@ const markerOffset = markerIndex * stride;

// Вставляем маркер в noMarginPlane для корректного лейблинга подписей
createBBox(noMarginBBox, planeWidth, planeHeight, size, anchor, pixelPositionX, pixelPositionY, 0);
putToArray(noMarginPlane, planeWidth, noMarginBBox);
if (degradationPlane) {

@@ -179,9 +230,54 @@ putToArray(degradationPlane, planeWidth, degradationBBox);

function generalizeLabel(
markers: Float32Array,
labels: Float32Array,
bounds: BBox,
plane: Uint8Array,
noMarginPlane: Uint8Array,
planeWidth: number,
planeHeight: number,
labelIndex: number,
): void {
const { stride, offsets } = labelArray;
const labelOffset = labelIndex * stride;
const markerIndex = labels[labelOffset + offsets.markerIndex];
const markerOffset = markerIndex * markerArray.stride;
const markerIsDisplayed = markers[markerOffset + markerArray.offsets.iconIndex] !== -1;
if (!markerIsDisplayed) {
return;
}
const pixelPositionX = markers[markerOffset + markerArray.offsets.pixelPositionX] - bounds.minX;
const pixelPositionY = markers[markerOffset + markerArray.offsets.pixelPositionY] - bounds.minY;
const size = [
labels[labelOffset + offsets.width],
labels[labelOffset + offsets.height],
];
const anchor = [
-labels[labelOffset + offsets.offsetX] / size[0],
-labels[labelOffset + offsets.offsetY] / size[1],
];
createBBox(noMarginBBox, planeWidth, planeHeight, size, anchor, pixelPositionX, pixelPositionY, 0);
if (bboxIsEmpty(noMarginBBox)) {
return;
}
if (!collide(noMarginPlane, planeWidth, noMarginBBox)) {
putToArray(plane, planeWidth, noMarginBBox);
putToArray(noMarginPlane, planeWidth, noMarginBBox);
labels[labelOffset + offsets.display] = 1;
}
}
/**
* Проверяет, пересекает ли область что-либо в плоскости
*
* @param {Uint8Array} arr Плоскость
* @param {number} width Ширина плоскости
* @param {BBox} bbox Проверяемая область
* @returns {boolean}
* @param arr Плоскость
* @param width Ширина плоскости
* @param bbox Проверяемая область
*/

@@ -224,5 +320,5 @@ function collide(arr: Uint8Array, width: number, bbox: BBox): boolean {

*
* @param {Uint8Array} arr Плоскость
* @param {number} width Ширина плоскости
* @param {BBox} bbox Закрашиваемая область
* @param arr Плоскость
* @param width Ширина плоскости
* @param bbox Закрашиваемая область
*/

@@ -229,0 +325,0 @@ function putToArray(arr: Uint8Array, width: number, bbox: BBox) {

@@ -9,8 +9,17 @@ import { WorkerMessage } from '../types';

// tslint:disable-next-line:no-default-export
export default (self: WorkerGlobalScope) => {
self.onmessage = (event) => {
const data = event.data;
generalize(data);
self.postMessage(data.markers);
generalize(event.data);
const { markers, labels } = event.data;
self.postMessage({
markerArray: markers,
labelArray: labels,
}, [
markers.buffer,
labels.buffer,
]);
};
};
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"tslib": ["./node_modules/tslib/tslib.d.ts"],
"*": [
"src/*",
"demo/*"
]
},
"target": "es5",
"module": "es6",
"module": "es2015",
"moduleResolution": "node",

@@ -23,8 +15,5 @@ "lib": ["dom", "es6"],

"declaration": true,
"declarationDir": "dist",
"skipLibCheck": true
},
"exclude": [
"node_modules"
],
"compileOnSave": false
}
}
{
"extends": [
"tslint:recommended",
"tslint-eslint-rules"
],
"rules": {
"no-null-keyword": true,
"no-shadowed-variable": false,
"ordered-imports": [false],
"only-arrow-functions": [true, "allow-declarations", "allow-named-functions"],
"object-literal-key-quotes": [true, "consistent"],
"quotemark": [
true,
"single"
],
"max-classes-per-file": [false],
"class-name": false,
"interface-name": [false],
"no-namespace": "allow-decalarations",
"object-literal-sort-keys": false,
"prefer-for-of": false,
"ter-indent": [2, 4, {"SwitchCase": 1}],
"trailing-comma": [
true,
{
"singleline": "never",
"multiline": "always"
}
],
"no-bitwise": false,
"no-string-literal": false,
"no-var-requires": false,
"object-curly-spacing": [
true,
"always"
],
"array-bracket-spacing": [
true,
"never"
],
"no-irregular-whitespace": "error",
"valid-typeof": 2,
"no-multi-spaces": true,
"block-spacing": "always",
"brace-style": [
2,
"1tbs"
],
"variable-name": [
true,
"ban-keywords",
"check-format",
"allow-pascal-case",
"allow-leading-underscore"
],
"no-constant-condition": true
}
"extends": ["tslint:recommended", "tslint-eslint-rules"],
"rules": {
"no-console": false,
"no-constant-condition": true,
"triple-equals": true,
"no-multi-spaces": true,
"array-bracket-spacing": [true, "never"],
"block-spacing": [true, "always"],
"brace-style": [true, "1tbs", { "allowSingleLine": true }],
"ter-indent": [2, 4, {"SwitchCase": 1}],
"linebreak-style": [true, "LF"],
"no-bitwise": false,
"indent": [true, "spaces", 4],
"no-trailing-whitespace": true,
"object-curly-spacing": [false],
"object-literal-key-quotes": [true, "as-needed"],
"quotemark": [true, "single", "avoid-escape"],
"space-in-parens": [true, "never"],
"ter-no-tabs": true,
"ter-arrow-parens": [true],
"no-shadowed-variable": false,
"ordered-imports": [false],
"only-arrow-functions": [false],
"forin": false,
"max-classes-per-file": [false, 1],
"class-name": true,
"interface-name": [false],
"no-namespace": [true, "allow-decalarations"],
"object-literal-sort-keys": false,
"prefer-for-of": false,
"trailing-comma": [true, { "singleline": "never", "multiline": "always" }],
"no-string-literal": false,
"no-var-requires": false,
"no-irregular-whitespace": true,
"no-default-export": true,
"variable-name": [false],
"no-empty": false,
"one-variable-per-declaration": false,
"align": false,
"no-redundant-jsdoc": true,
"jsdoc-format": true,
"no-inferrable-types": true,
"semicolon": [true, "always", "ignore-bound-class-methods"],
"member-access": true,
"member-ordering": [
true,
{
"order": [
"public-instance-field",
"protected-instance-field",
"private-instance-field",
"constructor",
"public-instance-method",
"protected-instance-method",
"private-instance-method"
]
}
]
}
}
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const webpack = require('webpack');
const path = require('path');
module.exports = (env = {}) => {
const tsCheckerPlugin = new ForkTsCheckerWebpackPlugin({
watch: ['./src'],
});
module.exports = (_, args) => {
const production = args.mode === 'production' && !args.demo;
const config = {
module: {
rules: [{
test: /\.ts$/,
exclude: /(node_modules)/,
use: {
loader: 'ts-loader',
options: {
transpileOnly: !env.production,
rules: [
{
test: /\.ts$/,
exclude: /node_modules/,
use: {
loader: 'ts-loader',
options: {
transpileOnly: !production,
},
},
},
}],
],
},
resolve: {
modules: [
path.resolve(__dirname, 'node_modules'),
path.resolve(__dirname),
],
extensions: ['.ts', '.js'],
}
},
devtool: 'source-map',
devServer: {
host: '0.0.0.0',
port: 3000,
stats: {
modules: false,
},
disableHostCheck: true,
},
};
if (env.production) {
if (production) {
Object.assign(config, {
devtool: 'source-map',
entry: './src/index.ts',

@@ -43,7 +49,5 @@ output: {

},
plugins: [new webpack.optimize.UglifyJsPlugin({sourceMap: true})],
});
} else if (env.demo) {
} else {
Object.assign(config, {
devtool: 'source-map',
entry: './demo/index.ts',

@@ -56,21 +60,7 @@ output: {

plugins: [
tsCheckerPlugin,
new webpack.optimize.UglifyJsPlugin({sourceMap: true}),
new ForkTsCheckerWebpackPlugin({
watch: ['./src', './demo'],
}),
],
});
} else {
Object.assign(config, {
devtool: 'eval-source-map',
entry: './demo/index.ts',
output: {
filename: 'demo.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/dist/',
},
plugins: [tsCheckerPlugin],
devServer: {
host: '0.0.0.0',
port: 3000,
},
});
}

@@ -77,0 +67,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc