rough-native
Version:
Create graphics using HTML Canvas or SVG with a hand-drawn, sketchy, appearance. Features comprehensive React hooks, memory management, and React 18 concurrent rendering support.
2 lines (1 loc) • 48 kB
JavaScript
import{useEffect as e,useRef as t,useSyncExternalStore as r,useMemo as s}from"react";function n(e,t,r){if(e&&e.length){const[s,n]=t,a=Math.PI/180*r,o=Math.cos(a),i=Math.sin(a);for(const t of e){const[e,r]=t;t[0]=(e-s)*o-(r-n)*i+s,t[1]=(e-s)*i+(r-n)*o+n}}}function a(e,t){return e[0]===t[0]&&e[1]===t[1]}function o(e,t,r,s=1){const o=r,i=Math.max(t,.1),h=e[0]&&e[0][0]&&"number"==typeof e[0][0]?[e]:e,c=[0,0];if(o)for(const e of h)n(e,c,o);const l=function(e,t,r){const s=[];for(const t of e){const e=[...t];a(e[0],e[e.length-1])||e.push([e[0][0],e[0][1]]),e.length>2&&s.push(e)}const n=[];t=Math.max(t,.1);const o=[];for(const e of s)for(let t=0;t<e.length-1;t++){const r=e[t],s=e[t+1];if(r[1]!==s[1]){const e=Math.min(r[1],s[1]);o.push({ymin:e,ymax:Math.max(r[1],s[1]),x:e===r[1]?r[0]:s[0],islope:(s[0]-r[0])/(s[1]-r[1])})}}if(o.sort(((e,t)=>e.ymin<t.ymin?-1:e.ymin>t.ymin?1:e.x<t.x?-1:e.x>t.x?1:e.ymax===t.ymax?0:(e.ymax-t.ymax)/Math.abs(e.ymax-t.ymax))),!o.length)return n;let i=[],h=o[0].ymin,c=0;for(;i.length||o.length;){if(o.length){let e=-1;for(let t=0;t<o.length&&!(o[t].ymin>h);t++)e=t;o.splice(0,e+1).forEach((e=>{i.push({s:h,edge:e})}))}if(i=i.filter((e=>!(e.edge.ymax<=h))),i.sort(((e,t)=>e.edge.x===t.edge.x?0:(e.edge.x-t.edge.x)/Math.abs(e.edge.x-t.edge.x))),(1!==r||c%t==0)&&i.length>1)for(let e=0;e<i.length;e+=2){const t=e+1;if(t>=i.length)break;const r=i[e].edge,s=i[t].edge;n.push([[Math.round(r.x),h],[Math.round(s.x),h]])}h+=r,i.forEach((e=>{e.edge.x=e.edge.x+r*e.edge.islope})),c++}return n}(h,i,s);if(o){for(const e of h)n(e,c,-o);!function(e,t,r){const s=[];e.forEach((e=>s.push(...e))),n(s,t,r)}(l,c,-o)}return l}const i={HIGH_MEMORY_PRESSURE_THRESHOLD:.8,MEDIUM_MEMORY_PRESSURE_THRESHOLD:.6,CACHE_SIZE_HIGH_PRESSURE:50,CACHE_SIZE_MEDIUM_PRESSURE:200,CACHE_SIZE_LOW_PRESSURE:500,CACHE_SIZE_DEFAULT:200,HIGH_PRESSURE_CLEANUP_PERCENT:.75,HIGH_PRESSURE_KEEP_PERCENT:.25,MEDIUM_PRESSURE_CLEANUP_PERCENT:.5,MEDIUM_PRESSURE_KEEP_PERCENT:.5,SHAPE_CACHE_MULTIPLIER:2,MAX_CONCURRENT_GENERATIONS_UNDER_PRESSURE:2,MEMORY_CHECK_INTERVAL_MS:5e3,BYTES_TO_KB:1024,KB_TO_MB:1024},h={MAX_ERROR_CACHE_SIZE:50,ERROR_RATE_LIMIT_PER_MINUTE:10,ERROR_CACHE_CLEANUP_INTERVAL_MS:6e4,SAMPLE_SIZE_FOR_ARRAY_PARAMS:3,MS_PER_MINUTE:6e4},c={MEMORY:i,ERROR:h,DRAWING:{DEFAULT_MAX_RANDOMNESS_OFFSET:2,DEFAULT_ROUGHNESS:1,DEFAULT_BOWING:1,DEFAULT_STROKE_WIDTH:1,DEFAULT_CURVE_TIGHTNESS:0,DEFAULT_CURVE_FITTING:.95,DEFAULT_CURVE_STEP_COUNT:9,DEFAULT_FILL_WEIGHT:-1,DEFAULT_HACHURE_ANGLE:-41,DEFAULT_HACHURE_GAP:-1,DEFAULT_DASH_OFFSET:-1,DEFAULT_DASH_GAP:-1,DEFAULT_ZIGZAG_OFFSET:-1,DEFAULT_SEED:0,DEFAULT_DISABLE_MULTI_STROKE:!1,DEFAULT_DISABLE_MULTI_STROKE_FILL:!1,DEFAULT_PRESERVE_VERTICES:!1,DEFAULT_FILL_SHAPE_ROUGHNESS_GAIN:.8,CURVE_ROUGHNESS_MULTIPLIER:.2,MULTI_STROKE_OFFSET_MULTIPLIER:1.5,MULTI_STROKE_ROUGHNESS_MULTIPLIER:.22,BEZIER_CURVE_POINTS:10,SIMPLIFICATION_FACTOR:4},RENDERING:{CURVE_STEP_COUNT_BASE:200,ELLIPSE_INCREMENT_OFFSET_FACTOR:.1,ELLIPSE_INCREMENT_OFFSET_RANGE:.4,ELLIPSE_MULTI_STROKE_FACTOR:1.5,ARC_RADIUS_OFFSET_FACTOR:.01,ARC_INCREMENT_DIVISOR:2,ARC_MULTI_STROKE_FACTOR:1.5,PATTERN_FILL_ARC_RADIUS_OFFSET:.01,LINE_LENGTH_THRESHOLD_SHORT:200,LINE_LENGTH_THRESHOLD_LONG:500,ROUGHNESS_GAIN_LONG_LINES:.4,ROUGHNESS_GAIN_COEFFICIENT:-.0016668,ROUGHNESS_GAIN_CONSTANT:1.233334,OFFSET_SQUARED_MULTIPLIER:100,OFFSET_DIVISOR_LONG_LINES:10,DIVERGE_POINT_BASE:.2,DIVERGE_POINT_RANGE:.2,BOWING_DISPLACEMENT_DIVISOR:200},FILL_PATTERN:{HACHURE_ANGLE_ADJUSTMENT:90,DEFAULT_HACHURE_GAP_MULTIPLIER:4,MIN_HACHURE_GAP:.1,HACHURE_SKIP_OFFSET_THRESHOLD:.7,CROSS_HATCH_ANGLE_INCREMENT:90,DEFAULT_ZIGZAG_GAP_MULTIPLIER:4,MIN_ZIGZAG_GAP:.1,DEGREES_TO_RADIANS_FACTOR:180,ZIGZAG_DISPLACEMENT_FACTOR:.5},RANDOM:{SEED_UPPER_BOUND:2**31,LCG_MASK:2**31-1,LCG_MULTIPLIER:48271,LCG_DIVISOR:2**31},REACT_HOOK:{ID_PREFIX:"rough-",MAX_RECURSION_DEPTH:10,KEY_LOOKUP_SET_THRESHOLD:10,DEFAULT_CURVE_TIGHTNESS:2},VALIDATION:{MIN_POINT_ARRAY_LENGTH:2,MIN_POLYGON_POINTS:3,MIN_PATH_STRING_LENGTH:0},getEnvironment:()=>{var e,t;const r="undefined"!=typeof process&&"production"===(null===(e=process.env)||void 0===e?void 0:e.NODE_ENV),s="undefined"!=typeof process&&"true"===(null===(t=process.env)||void 0===t?void 0:t.ROUGH_LOW_END_DEVICE);return{cacheSize:s?i.CACHE_SIZE_HIGH_PRESSURE:r?i.CACHE_SIZE_MEDIUM_PRESSURE:i.CACHE_SIZE_DEFAULT,highMemoryThreshold:s?.7:i.HIGH_MEMORY_PRESSURE_THRESHOLD,memoryCheckInterval:r?2*i.MEMORY_CHECK_INTERVAL_MS:i.MEMORY_CHECK_INTERVAL_MS,enableErrorLogging:!r,errorRateLimit:r?h.ERROR_RATE_LIMIT_PER_MINUTE/2:h.ERROR_RATE_LIMIT_PER_MINUTE}}};function l(e,t){var r;const s=t.hachureAngle+c.FILL_PATTERN.HACHURE_ANGLE_ADJUSTMENT;let n=t.hachureGap;n<0&&(n=t.strokeWidth*c.FILL_PATTERN.DEFAULT_HACHURE_GAP_MULTIPLIER),n=Math.round(Math.max(n,c.FILL_PATTERN.MIN_HACHURE_GAP));let a=1;return t.roughness>=1&&((null===(r=t.randomizer)||void 0===r?void 0:r.next())||Math.random())>c.FILL_PATTERN.HACHURE_SKIP_OFFSET_THRESHOLD&&(a=n),o(e,n,s,a||1)}class u{constructor(e){this.helper=e}fillPolygons(e,t){return this._fillPolygons(e,t)}_fillPolygons(e,t){const r=l(e,t);return{type:"fillSketch",ops:this.renderLines(r,t)}}renderLines(e,t){const r=[];for(const s of e)r.push(...this.helper.doubleLineOps(s[0][0],s[0][1],s[1][0],s[1][1],t));return r}}function E(e){const t=e[0],r=e[1];return Math.sqrt(Math.pow(t[0]-r[0],2)+Math.pow(t[1]-r[1],2))}class p extends u{fillPolygons(e,t){let r=t.hachureGap;r<0&&(r=4*t.strokeWidth),r=Math.max(r,.1);const s=l(e,Object.assign({},t,{hachureGap:r})),n=Math.PI/180*t.hachureAngle,a=[],o=.5*r*Math.cos(n),i=.5*r*Math.sin(n);for(const[e,t]of s)E([e,t])&&a.push([[e[0]-o,e[1]+i],[...t]],[[e[0]+o,e[1]-i],[...t]]);return{type:"fillSketch",ops:this.renderLines(a,t)}}}class f extends u{fillPolygons(e,t){const r=this._fillPolygons(e,t),s=Object.assign({},t,{hachureAngle:t.hachureAngle+c.FILL_PATTERN.CROSS_HATCH_ANGLE_INCREMENT}),n=this._fillPolygons(e,s);return r.ops=r.ops.concat(n.ops),r}}class d{constructor(e){this.helper=e}fillPolygons(e,t){const r=l(e,t=Object.assign({},t,{hachureAngle:0}));return this.dotsOnLines(r,t)}dotsOnLines(e,t){const r=[];let s=t.hachureGap;s<0&&(s=4*t.strokeWidth),s=Math.max(s,.1);let n=t.fillWeight;n<0&&(n=t.strokeWidth/2);const a=s/4;for(const o of e){const e=E(o),i=e/s,h=Math.ceil(i)-1,c=e-h*s,l=(o[0][0]+o[1][0])/2-s/4,u=Math.min(o[0][1],o[1][1]);for(let e=0;e<h;e++){const o=u+c+e*s,i=l-a+2*Math.random()*a,h=o-a+2*Math.random()*a,E=this.helper.ellipse(i,h,n,n,t);r.push(...E.ops)}}return{type:"fillSketch",ops:r}}}class _{constructor(e){this.helper=e}fillPolygons(e,t){const r=l(e,t);return{type:"fillSketch",ops:this.dashedLine(r,t)}}dashedLine(e,t){const r=t.dashOffset<0?t.hachureGap<0?4*t.strokeWidth:t.hachureGap:t.dashOffset,s=t.dashGap<0?t.hachureGap<0?4*t.strokeWidth:t.hachureGap:t.dashGap,n=[];return e.forEach((e=>{const a=E(e),o=Math.floor(a/(r+s)),i=(a+s-o*(r+s))/2;let h=e[0],c=e[1];h[0]>c[0]&&(h=e[1],c=e[0]);const l=Math.atan((c[1]-h[1])/(c[0]-h[0]));for(let e=0;e<o;e++){const a=e*(r+s),o=a+r,c=[h[0]+a*Math.cos(l)+i*Math.cos(l),h[1]+a*Math.sin(l)+i*Math.sin(l)],u=[h[0]+o*Math.cos(l)+i*Math.cos(l),h[1]+o*Math.sin(l)+i*Math.sin(l)];n.push(...this.helper.doubleLineOps(c[0],c[1],u[0],u[1],t))}})),n}}class R{constructor(e){this.helper=e}fillPolygons(e,t){const r=t.hachureGap<0?4*t.strokeWidth:t.hachureGap,s=t.zigzagOffset<0?r:t.zigzagOffset,n=l(e,t=Object.assign({},t,{hachureGap:r+s}));return{type:"fillSketch",ops:this.zigzagLines(n,s,t)}}zigzagLines(e,t,r){const s=[];return e.forEach((e=>{const n=E(e),a=Math.round(n/(2*t));let o=e[0],i=e[1];o[0]>i[0]&&(o=e[1],i=e[0]);const h=Math.atan((i[1]-o[1])/(i[0]-o[0]));for(let e=0;e<a;e++){const n=2*e*t,a=2*(e+1)*t,i=Math.sqrt(2*Math.pow(t,2)),c=[o[0]+n*Math.cos(h),o[1]+n*Math.sin(h)],l=[o[0]+a*Math.cos(h),o[1]+a*Math.sin(h)],u=[c[0]+i*Math.cos(h+Math.PI/4),c[1]+i*Math.sin(h+Math.PI/4)];s.push(...this.helper.doubleLineOps(c[0],c[1],u[0],u[1],r),...this.helper.doubleLineOps(u[0],u[1],l[0],l[1],r))}})),s}}const g={};class M{constructor(e){this.seed=e}next(){return this.seed?(c.RANDOM.LCG_MASK&(this.seed=Math.imul(c.RANDOM.LCG_MULTIPLIER,this.seed)))/c.RANDOM.LCG_DIVISOR:Math.random()}}const m=0,S=1,I=2,T={A:7,a:7,C:6,c:6,H:1,h:1,L:2,l:2,M:2,m:2,Q:4,q:4,S:4,s:4,T:2,t:2,V:1,v:1,Z:0,z:0};function y(e,t){return e.type===t}function A(e){const t=[],r=function(e){const t=new Array;for(;""!==e;)if(e.match(/^([ \t\r\n,]+)/))e=e.substr(RegExp.$1.length);else if(e.match(/^([aAcChHlLmMqQsStTvVzZ])/))t[t.length]={type:m,text:RegExp.$1},e=e.substr(RegExp.$1.length);else{if(!e.match(/^(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)/))return[];t[t.length]={type:S,text:`${parseFloat(RegExp.$1)}`},e=e.substr(RegExp.$1.length)}return t[t.length]={type:I,text:""},t}(e);let s="BOD",n=0,a=r[n];for(;!y(a,I);){let o=0;const i=[];if("BOD"===s){if("M"!==a.text&&"m"!==a.text)return A("M0,0"+e);n++,o=T[a.text],s=a.text}else y(a,S)?o=T[s]:(n++,o=T[a.text],s=a.text);if(!(n+o<r.length))throw new Error("Path data ended short");for(let e=n;e<n+o;e++){const t=r[e];if(!y(t,S))throw new Error("Param not a number: "+s+","+t.text);i[i.length]=+t.text}if("number"!=typeof T[s])throw new Error("Bad segment: "+s);{const e={key:s,data:i};t.push(e),n+=o,a=r[n],"M"===s&&(s="L"),"m"===s&&(s="l")}}return t}function O(e){let t=0,r=0,s=0,n=0;const a=[];for(const{key:o,data:i}of e)switch(o){case"M":a.push({key:"M",data:[...i]}),[t,r]=i,[s,n]=i;break;case"m":t+=i[0],r+=i[1],a.push({key:"M",data:[t,r]}),s=t,n=r;break;case"L":a.push({key:"L",data:[...i]}),[t,r]=i;break;case"l":t+=i[0],r+=i[1],a.push({key:"L",data:[t,r]});break;case"C":a.push({key:"C",data:[...i]}),t=i[4],r=i[5];break;case"c":{const e=i.map(((e,s)=>s%2?e+r:e+t));a.push({key:"C",data:e}),t=e[4],r=e[5];break}case"Q":a.push({key:"Q",data:[...i]}),t=i[2],r=i[3];break;case"q":{const e=i.map(((e,s)=>s%2?e+r:e+t));a.push({key:"Q",data:e}),t=e[2],r=e[3];break}case"A":a.push({key:"A",data:[...i]}),t=i[5],r=i[6];break;case"a":t+=i[5],r+=i[6],a.push({key:"A",data:[i[0],i[1],i[2],i[3],i[4],t,r]});break;case"H":a.push({key:"H",data:[...i]}),t=i[0];break;case"h":t+=i[0],a.push({key:"H",data:[t]});break;case"V":a.push({key:"V",data:[...i]}),r=i[0];break;case"v":r+=i[0],a.push({key:"V",data:[r]});break;case"S":a.push({key:"S",data:[...i]}),t=i[2],r=i[3];break;case"s":{const e=i.map(((e,s)=>s%2?e+r:e+t));a.push({key:"S",data:e}),t=e[2],r=e[3];break}case"T":a.push({key:"T",data:[...i]}),t=i[0],r=i[1];break;case"t":t+=i[0],r+=i[1],a.push({key:"T",data:[t,r]});break;case"Z":case"z":a.push({key:"Z",data:[]}),t=s,r=n}return a}function L(e){const t=[];let r="",s=0,n=0,a=0,o=0,i=0,h=0;for(const{key:c,data:l}of e){switch(c){case"M":t.push({key:"M",data:[...l]}),[s,n]=l,[a,o]=l;break;case"C":t.push({key:"C",data:[...l]}),s=l[4],n=l[5],i=l[2],h=l[3];break;case"L":t.push({key:"L",data:[...l]}),[s,n]=l;break;case"H":s=l[0],t.push({key:"L",data:[s,n]});break;case"V":n=l[0],t.push({key:"L",data:[s,n]});break;case"S":{let e=0,a=0;"C"===r||"S"===r?(e=s+(s-i),a=n+(n-h)):(e=s,a=n),t.push({key:"C",data:[e,a,...l]}),i=l[0],h=l[1],s=l[2],n=l[3];break}case"T":{const[e,a]=l;let o=0,c=0;"Q"===r||"T"===r?(o=s+(s-i),c=n+(n-h)):(o=s,c=n);const u=s+2*(o-s)/3,E=n+2*(c-n)/3,p=e+2*(o-e)/3,f=a+2*(c-a)/3;t.push({key:"C",data:[u,E,p,f,e,a]}),i=o,h=c,s=e,n=a;break}case"Q":{const[e,r,a,o]=l,c=s+2*(e-s)/3,u=n+2*(r-n)/3,E=a+2*(e-a)/3,p=o+2*(r-o)/3;t.push({key:"C",data:[c,u,E,p,a,o]}),i=e,h=r,s=a,n=o;break}case"A":{const e=Math.abs(l[0]),r=Math.abs(l[1]),a=l[2],o=l[3],i=l[4],h=l[5],c=l[6];if(0===e||0===r)t.push({key:"C",data:[s,n,h,c,h,c]}),s=h,n=c;else if(s!==h||n!==c){C(s,n,h,c,e,r,a,o,i).forEach((function(e){t.push({key:"C",data:e})})),s=h,n=c}break}case"Z":t.push({key:"Z",data:[]}),s=a,n=o}r=c}return t}function N(e,t,r){return[e*Math.cos(r)-t*Math.sin(r),e*Math.sin(r)+t*Math.cos(r)]}function C(e,t,r,s,n,a,o,i,h,c){const l=(u=o,Math.PI*u/180);var u;let E=[],p=0,f=0,d=0,_=0;if(c)[p,f,d,_]=c;else{[e,t]=N(e,t,-l),[r,s]=N(r,s,-l);const o=(e-r)/2,c=(t-s)/2;let u=o*o/(n*n)+c*c/(a*a);u>1&&(u=Math.sqrt(u),n*=u,a*=u);const E=n*n,R=a*a,g=E*R-E*c*c-R*o*o,M=E*c*c+R*o*o,m=(i===h?-1:1)*Math.sqrt(Math.abs(g/M));d=m*n*c/a+(e+r)/2,_=m*-a*o/n+(t+s)/2,p=Math.asin(parseFloat(((t-_)/a).toFixed(9))),f=Math.asin(parseFloat(((s-_)/a).toFixed(9))),e<d&&(p=Math.PI-p),r<d&&(f=Math.PI-f),p<0&&(p=2*Math.PI+p),f<0&&(f=2*Math.PI+f),h&&p>f&&(p-=2*Math.PI),!h&&f>p&&(f-=2*Math.PI)}let R=f-p;if(Math.abs(R)>120*Math.PI/180){const e=f,t=r,i=s;f=h&&f>p?p+120*Math.PI/180*1:p+120*Math.PI/180*-1,E=C(r=d+n*Math.cos(f),s=_+a*Math.sin(f),t,i,n,a,o,0,h,[f,e,d,_])}R=f-p;const g=Math.cos(p),M=Math.sin(p),m=Math.cos(f),S=Math.sin(f),I=Math.tan(R/4),T=4/3*n*I,y=4/3*a*I,A=[e,t],O=[e+T*M,t-y*g],L=[r+T*S,s-y*m],P=[r,s];if(O[0]=2*A[0]-O[0],O[1]=2*A[1]-O[1],c)return[O,L,P].concat(E);{E=[O,L,P].concat(E);const e=[];for(let t=0;t<E.length;t+=3){const r=N(E[t][0],E[t][1],l),s=N(E[t+1][0],E[t+1][1],l),n=N(E[t+2][0],E[t+2][1],l);e.push([r[0],r[1],s[0],s[1],n[0],n[1]])}return e}}const P={randOffset:function(e,t){return $(e,t)},randOffsetWithRange:function(e,t,r){return V(e,t,r)},ellipse:function(e,t,r,s,n){const a=b(r,s,n);return H(e,t,n,a).opset},doubleLineOps:function(e,t,r,s,n){return K(e,t,r,s,n,!0)}};function D(e,t,r,s,n){return{type:"path",ops:K(e,t,r,s,n)}}function U(e,t,r){const s=(e||[]).length;if(s>2){const n=[];for(let t=0;t<s-1;t++)n.push(...K(e[t][0],e[t][1],e[t+1][0],e[t+1][1],r));return t&&n.push(...K(e[s-1][0],e[s-1][1],e[0][0],e[0][1],r)),{type:"path",ops:n}}return 2===s?D(e[0][0],e[0][1],e[1][0],e[1][1],r):{type:"path",ops:[]}}function G(e,t,r,s,n){return function(e,t){return U(e,!0,t)}([[e,t],[e+r,t],[e+r,t+s],[e,t+s]],n)}function k(e,t){if(e.length){const r="number"==typeof e[0][0]?[e]:e,s=Y(r[0],1*(1+t.roughness*c.DRAWING.CURVE_ROUGHNESS_MULTIPLIER),t),n=t.disableMultiStroke?[]:Y(r[0],c.DRAWING.MULTI_STROKE_OFFSET_MULTIPLIER*(1+t.roughness*c.DRAWING.MULTI_STROKE_ROUGHNESS_MULTIPLIER),W(t));for(let e=1;e<r.length;e++){const a=r[e];if(a.length){const e=Y(a,1*(1+t.roughness*c.DRAWING.CURVE_ROUGHNESS_MULTIPLIER),t),r=t.disableMultiStroke?[]:Y(a,c.DRAWING.MULTI_STROKE_OFFSET_MULTIPLIER*(1+t.roughness*c.DRAWING.MULTI_STROKE_ROUGHNESS_MULTIPLIER),W(t));for(const t of e)"move"!==t.op&&s.push(t);for(const e of r)"move"!==e.op&&n.push(e)}}return{type:"path",ops:s.concat(n)}}return{type:"path",ops:[]}}function b(e,t,r){const s=Math.sqrt(2*Math.PI*Math.sqrt((Math.pow(e/2,2)+Math.pow(t/2,2))/2)),n=Math.ceil(Math.max(r.curveStepCount,r.curveStepCount/Math.sqrt(c.RENDERING.CURVE_STEP_COUNT_BASE)*s)),a=2*Math.PI/n;let o=Math.abs(e/2),i=Math.abs(t/2);const h=1-r.curveFitting;return o+=$(o*h,r),i+=$(i*h,r),{increment:a,rx:o,ry:i}}function H(e,t,r,s){const[n,a]=B(s.increment,e,t,s.rx,s.ry,1,s.increment*V(c.RENDERING.ELLIPSE_INCREMENT_OFFSET_FACTOR,V(c.RENDERING.ELLIPSE_INCREMENT_OFFSET_RANGE,1,r),r),r);let o=Z(n,null,r);if(!r.disableMultiStroke&&0!==r.roughness){const[n]=B(s.increment,e,t,s.rx,s.ry,c.RENDERING.ELLIPSE_MULTI_STROKE_FACTOR,0,r),a=Z(n,null,r);o=o.concat(a)}return{estimatedPoints:a,opset:{type:"path",ops:o}}}function v(e,t,r,s,n,a,o,i,h){const l=e,u=t;let E=Math.abs(r/2),p=Math.abs(s/2);E+=$(E*c.RENDERING.ARC_RADIUS_OFFSET_FACTOR,h),p+=$(p*c.RENDERING.ARC_RADIUS_OFFSET_FACTOR,h);let f=n,d=a;for(;f<0;)f+=2*Math.PI,d+=2*Math.PI;d-f>2*Math.PI&&(f=0,d=2*Math.PI);const _=2*Math.PI/h.curveStepCount,R=Math.min(_/c.RENDERING.ARC_INCREMENT_DIVISOR,(d-f)/c.RENDERING.ARC_INCREMENT_DIVISOR),g=q(R,l,u,E,p,f,d,1,h);if(!h.disableMultiStroke){const e=q(R,l,u,E,p,f,d,c.RENDERING.ARC_MULTI_STROKE_FACTOR,h);g.push(...e)}return o&&(i?g.push(...K(l,u,l+E*Math.cos(f),u+p*Math.sin(f),h),...K(l,u,l+E*Math.cos(d),u+p*Math.sin(d),h)):g.push({op:"lineTo",data:[l,u]},{op:"lineTo",data:[l+E*Math.cos(f),u+p*Math.sin(f)]})),{type:"path",ops:g}}function F(e,t){const r=L(O(A(e))),s=[];let n=[0,0],a=[0,0];for(const{key:e,data:o}of r)switch(e){case"M":a=[o[0],o[1]],n=[o[0],o[1]];break;case"L":s.push(...K(a[0],a[1],o[0],o[1],t)),a=[o[0],o[1]];break;case"C":{const[e,r,n,i,h,c]=o;s.push(...J(e,r,n,i,h,c,a,t)),a=[h,c];break}case"Z":s.push(...K(a[0],a[1],n[0],n[1],t)),a=[n[0],n[1]]}return{type:"path",ops:s}}function w(e,t){const r=[];for(const s of e)if(s.length){const e=t.maxRandomnessOffset||0,n=s.length;if(n>2){r.push({op:"move",data:[s[0][0]+$(e,t),s[0][1]+$(e,t)]});for(let a=1;a<n;a++)r.push({op:"lineTo",data:[s[a][0]+$(e,t),s[a][1]+$(e,t)]})}}return{type:"fillPath",ops:r}}function x(e,t){return function(e,t){let r=e.fillStyle||"hachure";if(!g[r])switch(r){case"zigzag":g[r]||(g[r]=new p(t));break;case"cross-hatch":g[r]||(g[r]=new f(t));break;case"dots":g[r]||(g[r]=new d(t));break;case"dashed":g[r]||(g[r]=new _(t));break;case"zigzag-line":g[r]||(g[r]=new R(t));break;default:r="hachure",g[r]||(g[r]=new u(t))}return g[r]}(t,P).fillPolygons(e,t)}function W(e){const t=Object.assign({},e);return t.randomizer=void 0,e.seed&&(t.seed=e.seed+1),t}function z(e){return e.randomizer||(e.randomizer=new M(e.seed||0)),e.randomizer.next()}function V(e,t,r,s=1){return r.roughness*s*(z(r)*(t-e)+e)}function $(e,t,r=1){return V(-e,e,t,r)}function K(e,t,r,s,n,a=!1){const o=a?n.disableMultiStrokeFill:n.disableMultiStroke,i=j(e,t,r,s,n,!0,!1);if(o)return i;const h=j(e,t,r,s,n,!0,!0);return i.concat(h)}function j(e,t,r,s,n,a,o){const i=Math.pow(e-r,2)+Math.pow(t-s,2),h=Math.sqrt(i);let l=1;l=h<c.RENDERING.LINE_LENGTH_THRESHOLD_SHORT?1:h>c.RENDERING.LINE_LENGTH_THRESHOLD_LONG?c.RENDERING.ROUGHNESS_GAIN_LONG_LINES:c.RENDERING.ROUGHNESS_GAIN_COEFFICIENT*h+c.RENDERING.ROUGHNESS_GAIN_CONSTANT;let u=n.maxRandomnessOffset||0;u*u*c.RENDERING.OFFSET_SQUARED_MULTIPLIER>i&&(u=h/c.RENDERING.OFFSET_DIVISOR_LONG_LINES);const E=u/2,p=c.RENDERING.DIVERGE_POINT_BASE+z(n)*c.RENDERING.DIVERGE_POINT_RANGE;let f=n.bowing*n.maxRandomnessOffset*(s-t)/c.RENDERING.BOWING_DISPLACEMENT_DIVISOR,d=n.bowing*n.maxRandomnessOffset*(e-r)/c.RENDERING.BOWING_DISPLACEMENT_DIVISOR;f=$(f,n,l),d=$(d,n,l);const _=[],R=()=>$(E,n,l),g=()=>$(u,n,l),M=n.preserveVertices;return a&&(o?_.push({op:"move",data:[e+(M?0:R()),t+(M?0:R())]}):_.push({op:"move",data:[e+(M?0:$(u,n,l)),t+(M?0:$(u,n,l))]})),o?_.push({op:"bcurveTo",data:[f+e+(r-e)*p+R(),d+t+(s-t)*p+R(),f+e+2*(r-e)*p+R(),d+t+2*(s-t)*p+R(),r+(M?0:R()),s+(M?0:R())]}):_.push({op:"bcurveTo",data:[f+e+(r-e)*p+g(),d+t+(s-t)*p+g(),f+e+2*(r-e)*p+g(),d+t+2*(s-t)*p+g(),r+(M?0:g()),s+(M?0:g())]}),_}function Y(e,t,r){if(!e.length)return[];const s=[];s.push([e[0][0]+$(t,r),e[0][1]+$(t,r)]),s.push([e[0][0]+$(t,r),e[0][1]+$(t,r)]);for(let n=1;n<e.length;n++)s.push([e[n][0]+$(t,r),e[n][1]+$(t,r)]),n===e.length-1&&s.push([e[n][0]+$(t,r),e[n][1]+$(t,r)]);return Z(s,null,r)}function Z(e,t,r){const s=e.length,n=[];if(s>3){const a=[],o=1-r.curveTightness;n.push({op:"move",data:[e[1][0],e[1][1]]});for(let t=1;t+2<s;t++){const r=e[t];a[0]=[r[0],r[1]],a[1]=[r[0]+(o*e[t+1][0]-o*e[t-1][0])/6,r[1]+(o*e[t+1][1]-o*e[t-1][1])/6],a[2]=[e[t+1][0]+(o*e[t][0]-o*e[t+2][0])/6,e[t+1][1]+(o*e[t][1]-o*e[t+2][1])/6],a[3]=[e[t+1][0],e[t+1][1]],n.push({op:"bcurveTo",data:[a[1][0],a[1][1],a[2][0],a[2][1],a[3][0],a[3][1]]})}if(t&&2===t.length){const e=r.maxRandomnessOffset;n.push({op:"lineTo",data:[t[0]+$(e,r),t[1]+$(e,r)]})}}else 3===s?(n.push({op:"move",data:[e[1][0],e[1][1]]}),n.push({op:"bcurveTo",data:[e[1][0],e[1][1],e[2][0],e[2][1],e[2][0],e[2][1]]})):2===s&&n.push(...j(e[0][0],e[0][1],e[1][0],e[1][1],r,!0,!0));return n}function B(e,t,r,s,n,a,o,i){const h=[],c=[];if(0===i.roughness){e/=4,c.push([t+s*Math.cos(-e),r+n*Math.sin(-e)]);for(let a=0;a<=2*Math.PI;a+=e){const e=[t+s*Math.cos(a),r+n*Math.sin(a)];h.push(e),c.push(e)}c.push([t+s*Math.cos(0),r+n*Math.sin(0)]),c.push([t+s*Math.cos(e),r+n*Math.sin(e)])}else{const l=$(.5,i)-Math.PI/2;c.push([$(a,i)+t+.9*s*Math.cos(l-e),$(a,i)+r+.9*n*Math.sin(l-e)]);const u=2*Math.PI+l-.01;for(let o=l;o<u;o+=e){const e=[$(a,i)+t+s*Math.cos(o),$(a,i)+r+n*Math.sin(o)];h.push(e),c.push(e)}c.push([$(a,i)+t+s*Math.cos(l+2*Math.PI+.5*o),$(a,i)+r+n*Math.sin(l+2*Math.PI+.5*o)]),c.push([$(a,i)+t+.98*s*Math.cos(l+o),$(a,i)+r+.98*n*Math.sin(l+o)]),c.push([$(a,i)+t+.9*s*Math.cos(l+.5*o),$(a,i)+r+.9*n*Math.sin(l+.5*o)])}return[c,h]}function q(e,t,r,s,n,a,o,i,h){const c=a+$(.1,h),l=[];l.push([$(i,h)+t+.9*s*Math.cos(c-e),$(i,h)+r+.9*n*Math.sin(c-e)]);for(let a=c;a<=o;a+=e)l.push([$(i,h)+t+s*Math.cos(a),$(i,h)+r+n*Math.sin(a)]);return l.push([t+s*Math.cos(o),r+n*Math.sin(o)]),l.push([t+s*Math.cos(o),r+n*Math.sin(o)]),Z(l,null,h)}function J(e,t,r,s,n,a,o,i){const h=[],c=[i.maxRandomnessOffset||1,(i.maxRandomnessOffset||1)+.3];let l=[0,0];const u=i.disableMultiStroke?1:2,E=i.preserveVertices;for(let p=0;p<u;p++)0===p?h.push({op:"move",data:[o[0],o[1]]}):h.push({op:"move",data:[o[0]+(E?0:$(c[0],i)),o[1]+(E?0:$(c[0],i))]}),l=E?[n,a]:[n+$(c[p],i),a+$(c[p],i)],h.push({op:"bcurveTo",data:[e+$(c[p],i),t+$(c[p],i),r+$(c[p],i),s+$(c[p],i),l[0],l[1]]});return h}function Q(e){return[...e]}function X(e,t=0){const r=e.length;if(r<3)throw new Error("A curve must have at least three points.");const s=[];if(3===r)s.push(Q(e[0]),Q(e[1]),Q(e[2]),Q(e[2]));else{const r=[];r.push(e[0],e[0]);for(let t=1;t<e.length;t++)r.push(e[t]),t===e.length-1&&r.push(e[t]);const n=[],a=1-t;s.push(Q(r[0]));for(let e=1;e+2<r.length;e++){const t=r[e];n[0]=[t[0],t[1]],n[1]=[t[0]+(a*r[e+1][0]-a*r[e-1][0])/6,t[1]+(a*r[e+1][1]-a*r[e-1][1])/6],n[2]=[r[e+1][0]+(a*r[e][0]-a*r[e+2][0])/6,r[e+1][1]+(a*r[e][1]-a*r[e+2][1])/6],n[3]=[r[e+1][0],r[e+1][1]],s.push(n[1],n[2],n[3])}}return s}function ee(e,t){return Math.pow(e[0]-t[0],2)+Math.pow(e[1]-t[1],2)}function te(e,t,r){const s=ee(t,r);if(0===s)return ee(e,t);let n=((e[0]-t[0])*(r[0]-t[0])+(e[1]-t[1])*(r[1]-t[1]))/s;return n=Math.max(0,Math.min(1,n)),ee(e,re(t,r,n))}function re(e,t,r){return[e[0]+(t[0]-e[0])*r,e[1]+(t[1]-e[1])*r]}function se(e,t,r,s){const n=s||[];if(function(e,t){const r=e[t+0],s=e[t+1],n=e[t+2],a=e[t+3];let o=3*s[0]-2*r[0]-a[0];o*=o;let i=3*s[1]-2*r[1]-a[1];i*=i;let h=3*n[0]-2*a[0]-r[0];h*=h;let c=3*n[1]-2*a[1]-r[1];return c*=c,o<h&&(o=h),i<c&&(i=c),o+i}(e,t)<r){const r=e[t+0];if(n.length){(a=n[n.length-1],o=r,Math.sqrt(ee(a,o)))>1&&n.push(r)}else n.push(r);n.push(e[t+3])}else{const s=.5,a=e[t+0],o=e[t+1],i=e[t+2],h=e[t+3],c=re(a,o,s),l=re(o,i,s),u=re(i,h,s),E=re(c,l,s),p=re(l,u,s),f=re(E,p,s);se([a,c,E,f],0,r,n),se([f,p,u,h],0,r,n)}var a,o;return n}function ne(e,t){return ae(e,0,e.length,t)}function ae(e,t,r,s,n){const a=n||[],o=e[t],i=e[r-1];let h=0,c=1;for(let s=t+1;s<r-1;++s){const t=te(e[s],o,i);t>h&&(h=t,c=s)}return Math.sqrt(h)>s?(ae(e,t,c+1,s,a),ae(e,c,r,s,a)):(a.length||a.push(o),a.push(i)),a}function oe(e,t=.15,r){const s=[],n=(e.length-1)/3;for(let r=0;r<n;r++){se(e,3*r,t,s)}return r&&r>0?ae(s,0,s.length,r):s}const ie="none";class he{constructor(e){this.defaultOptions={maxRandomnessOffset:c.DRAWING.DEFAULT_MAX_RANDOMNESS_OFFSET,roughness:c.DRAWING.DEFAULT_ROUGHNESS,bowing:c.DRAWING.DEFAULT_BOWING,stroke:"#000",strokeWidth:c.DRAWING.DEFAULT_STROKE_WIDTH,curveTightness:c.DRAWING.DEFAULT_CURVE_TIGHTNESS,curveFitting:c.DRAWING.DEFAULT_CURVE_FITTING,curveStepCount:c.DRAWING.DEFAULT_CURVE_STEP_COUNT,fillStyle:"hachure",fillWeight:c.DRAWING.DEFAULT_FILL_WEIGHT,hachureAngle:c.DRAWING.DEFAULT_HACHURE_ANGLE,hachureGap:c.DRAWING.DEFAULT_HACHURE_GAP,dashOffset:c.DRAWING.DEFAULT_DASH_OFFSET,dashGap:c.DRAWING.DEFAULT_DASH_GAP,zigzagOffset:c.DRAWING.DEFAULT_ZIGZAG_OFFSET,seed:c.DRAWING.DEFAULT_SEED,disableMultiStroke:c.DRAWING.DEFAULT_DISABLE_MULTI_STROKE,disableMultiStrokeFill:c.DRAWING.DEFAULT_DISABLE_MULTI_STROKE_FILL,preserveVertices:c.DRAWING.DEFAULT_PRESERVE_VERTICES,fillShapeRoughnessGain:c.DRAWING.DEFAULT_FILL_SHAPE_ROUGHNESS_GAIN},this.config=e||{},this.config.options&&(this.defaultOptions=this._o(this.config.options))}static newSeed(){return Math.floor(Math.random()*c.RANDOM.SEED_UPPER_BOUND)}_o(e){return e?Object.assign({},this.defaultOptions,e):this.defaultOptions}_d(e,t,r){return{shape:e,sets:t||[],options:r||this.defaultOptions}}line(e,t,r,s,n){const a=this._o(n);return this._d("line",[D(e,t,r,s,a)],a)}rectangle(e,t,r,s,n){const a=this._o(n),o=[],i=G(e,t,r,s,a);if(a.fill){const n=[[e,t],[e+r,t],[e+r,t+s],[e,t+s]];"solid"===a.fillStyle?o.push(w([n],a)):o.push(x([n],a))}return a.stroke!==ie&&o.push(i),this._d("rectangle",o,a)}ellipse(e,t,r,s,n){const a=this._o(n),o=[],i=b(r,s,a),h=H(e,t,a,i);if(a.fill)if("solid"===a.fillStyle){const r=H(e,t,a,i).opset;r.type="fillPath",o.push(r)}else o.push(x([h.estimatedPoints],a));return a.stroke!==ie&&o.push(h.opset),this._d("ellipse",o,a)}circle(e,t,r,s){const n=this.ellipse(e,t,r,r,s);return n.shape="circle",n}linearPath(e,t){const r=this._o(t);return this._d("linearPath",[U(e,!1,r)],r)}arc(e,t,r,s,n,a,o=!1,i){const h=this._o(i),l=[],u=v(e,t,r,s,n,a,o,!0,h);if(o&&h.fill)if("solid"===h.fillStyle){const o=Object.assign({},h);o.disableMultiStroke=!0;const i=v(e,t,r,s,n,a,!0,!1,o);i.type="fillPath",l.push(i)}else l.push(function(e,t,r,s,n,a,o){const i=e,h=t;let l=Math.abs(r/2),u=Math.abs(s/2);l+=$(l*c.RENDERING.ARC_RADIUS_OFFSET_FACTOR,o),u+=$(u*c.RENDERING.ARC_RADIUS_OFFSET_FACTOR,o);let E=n,p=a;for(;E<0;)E+=2*Math.PI,p+=2*Math.PI;p-E>2*Math.PI&&(E=0,p=2*Math.PI);const f=(p-E)/o.curveStepCount,d=[];for(let e=E;e<=p;e+=f)d.push([i+l*Math.cos(e),h+u*Math.sin(e)]);return d.push([i+l*Math.cos(p),h+u*Math.sin(p)]),d.push([i,h]),x([d],o)}(e,t,r,s,n,a,h));return h.stroke!==ie&&l.push(u),this._d("arc",l,h)}curve(e,t){const r=this._o(t),s=[],n=k(e,r);if(r.fill&&r.fill!==ie)if("solid"===r.fillStyle){const t=k(e,Object.assign(Object.assign({},r),{disableMultiStroke:!0,roughness:r.roughness?r.roughness+r.fillShapeRoughnessGain:0}));s.push({type:"fillPath",ops:this._mergedShape(t.ops)})}else{const t=[],n=e;if(n.length){const e="number"==typeof n[0][0]?[n]:n;for(const s of e)s.length<3?t.push(...s):3===s.length?t.push(...oe(X([s[0],s[0],s[1],s[2]]),c.DRAWING.BEZIER_CURVE_POINTS,(1+r.roughness)/2)):t.push(...oe(X(s),c.DRAWING.BEZIER_CURVE_POINTS,(1+r.roughness)/2))}t.length&&s.push(x([t],r))}return r.stroke!==ie&&s.push(n),this._d("curve",s,r)}polygon(e,t){const r=this._o(t),s=[],n=U(e,!0,r);return r.fill&&("solid"===r.fillStyle?s.push(w([e],r)):s.push(x([e],r))),r.stroke!==ie&&s.push(n),this._d("polygon",s,r)}path(e,t){const r=this._o(t),s=[];if(!e)return this._d("path",s,r);e=(e||"").replace(/\n/g," ").replace(/(-\s)/g,"-").replace("/(ss)/g"," ");const n=r.fill&&"transparent"!==r.fill&&r.fill!==ie,a=r.stroke!==ie,o=!!(r.simplification&&r.simplification<1),i=function(e,t,r){const s=L(O(A(e))),n=[];let a=[],o=[0,0],i=[];const h=()=>{i.length>=4&&a.push(...oe(i,t)),i=[]},c=()=>{h(),a.length&&(n.push(a),a=[])};for(const{key:e,data:t}of s)switch(e){case"M":c(),o=[t[0],t[1]],a.push(o);break;case"L":h(),a.push([t[0],t[1]]);break;case"C":if(!i.length){const e=a.length?a[a.length-1]:o;i.push([e[0],e[1]])}i.push([t[0],t[1]]),i.push([t[2],t[3]]),i.push([t[4],t[5]]);break;case"Z":h(),a.push([o[0],o[1]])}if(c(),!r)return n;const l=[];for(const e of n){const t=ne(e,r);t.length&&l.push(t)}return l}(e,1,o?4-4*(r.simplification||1):(1+r.roughness)/2),h=F(e,r);if(n)if("solid"===r.fillStyle)if(1===i.length){const t=F(e,Object.assign(Object.assign({},r),{disableMultiStroke:!0,roughness:r.roughness?r.roughness+r.fillShapeRoughnessGain:0}));s.push({type:"fillPath",ops:this._mergedShape(t.ops)})}else s.push(w(i,r));else s.push(x(i,r));return a&&(o?i.forEach((e=>{s.push(U(e,!1,r))})):s.push(h)),this._d("path",s,r)}opsToPath(e,t){let r="";for(const s of e.ops){const e="number"==typeof t&&t>=0?s.data.map((e=>+e.toFixed(t))):s.data;switch(s.op){case"move":r+=`M${e[0]} ${e[1]} `;break;case"bcurveTo":r+=`C${e[0]} ${e[1]}, ${e[2]} ${e[3]}, ${e[4]} ${e[5]} `;break;case"lineTo":r+=`L${e[0]} ${e[1]} `}}return r.trim()}toPaths(e){const t=e.sets||[],r=e.options||this.defaultOptions,s=[];for(const e of t){let t=null;switch(e.type){case"path":t={d:this.opsToPath(e),stroke:r.stroke,strokeWidth:r.strokeWidth,fill:ie};break;case"fillPath":t={d:this.opsToPath(e),stroke:ie,strokeWidth:0,fill:r.fill||ie};break;case"fillSketch":t=this.fillSketch(e,r)}t&&s.push(t)}return s}fillSketch(e,t){let r=t.fillWeight;return r<0&&(r=t.strokeWidth/2),{d:this.opsToPath(e),stroke:t.fill||ie,strokeWidth:r,fill:ie}}_mergedShape(e){return e.filter(((e,t)=>0===t||"move"!==e.op))}}class ce{constructor(e){this.gen=new he(e),this.instanceId=Math.random().toString(36).substring(2,15),this.registerInstance()}registerInstance(){ce.instanceCount++,"undefined"==typeof FinalizationRegistry||ce.finalizationRegistry||(ce.finalizationRegistry=new FinalizationRegistry((e=>{this.handleInstanceFinalization(e)}))),ce.finalizationRegistry&&ce.finalizationRegistry.register(this,this.instanceId),1===ce.instanceCount&&this.startCleanupTimer()}handleInstanceFinalization(e){ce.instanceCount=Math.max(0,ce.instanceCount-1),0===ce.instanceCount&&ce.cleanupTimer&&(clearInterval(ce.cleanupTimer),ce.cleanupTimer=null,ce.errorCache.clear())}startCleanupTimer(){ce.cleanupTimer&&clearInterval(ce.cleanupTimer),ce.cleanupTimer=setInterval((()=>{this.cleanupErrorCache()}),ce.cacheCleanupInterval)}dispose(){ce.finalizationRegistry&&ce.finalizationRegistry.unregister(this),this.handleInstanceFinalization(this.instanceId)}static forceCleanup(){ce.cleanupTimer&&(clearInterval(ce.cleanupTimer),ce.cleanupTimer=null),ce.errorCache.clear(),ce.instanceCount=0}cleanupErrorCache(){const e=Date.now()-c.ERROR.MS_PER_MINUTE,t=Array.from(ce.errorCache.entries());for(const[r,s]of t)s.lastSeen<e&&ce.errorCache.delete(r);if(ce.errorCache.size>ce.maxErrorCacheSize){const e=Array.from(ce.errorCache.entries()).sort(((e,t)=>e[1].lastSeen-t[1].lastSeen));e.slice(0,e.length-ce.maxErrorCacheSize).forEach((([e])=>ce.errorCache.delete(e)))}}logError(e){if(!this.shouldLog())return;const t=`${e.method}:${e.error||"unknown"}`,r=Date.now(),s=ce.errorCache.get(t);if(s){s.count++,s.lastSeen=r;const e=r-s.context.timestamp;if(s.count/Math.max(1,e/c.ERROR.MS_PER_MINUTE)>ce.errorRateLimit)return}else ce.errorCache.set(t,{count:1,lastSeen:r,context:Object.assign(Object.assign({},e),{timestamp:r})});const n={method:e.method,error:e.error,timestamp:new Date(r).toISOString()};e.parameters&&(n.parameters=this.sanitizeParameters(e.parameters)),s&&s.count>1&&(n.occurrences=s.count),console.warn(`rough-native: ${e.method} failed`,n)}sanitizeParameters(e){if(Array.isArray(e))return{type:"array",length:e.length,sample:e.slice(0,c.ERROR.SAMPLE_SIZE_FOR_ARRAY_PARAMS)};if("object"==typeof e&&null!==e){const t={};for(const[r,s]of Object.entries(e))Array.isArray(s)?t[r]={type:"array",length:s.length}:t[r]="object"==typeof s&&null!==s?{type:"object",keys:Object.keys(s)}:s;return t}return e}shouldLog(){return"undefined"==typeof process||"production"!==process.env.NODE_ENV}draw(e){var t;try{if(!e)return this.logError({method:"draw",error:"drawable is null or undefined"}),this.createEmptyElement();const r=e.sets||[],s=e.options||this.getDefaultOptions(),n=[],a=null===(t=e.options)||void 0===t?void 0:t.fixedDecimalPlaceDigits;for(const t of r){if(!t){this.logError({method:"draw",error:"null drawing in drawable.sets"});continue}let r=null;try{switch(t.type){case"path":{const e=this.safeOpsToPath(t,a);if(!e){this.logError({method:"draw",error:"failed to generate path data",parameters:{drawingType:"path",drawing:t}});continue}r={props:Object.assign(Object.assign({d:e,stroke:s.stroke,strokeWidth:s.strokeWidth,fill:"none"},s.strokeLineDash&&{strokeDasharray:s.strokeLineDash.join(" ").trim()}),s.strokeLineDashOffset&&{strokeDashoffset:s.strokeLineDashOffset})};break}case"fillPath":{const n=this.safeOpsToPath(t,a);if(!n){this.logError({method:"draw",error:"failed to generate fill path data",parameters:{drawingType:"fillPath",drawing:t}});continue}r={props:Object.assign({d:n,stroke:"none",strokeWidth:0,fill:s.fill||""},"curve"===e.shape||"polygon"===e.shape?{fillRule:"evenodd"}:{})};break}case"fillSketch":r=this.safeFillSketch(t,s);break;default:this.logError({method:"draw",error:`unknown drawing type: ${t.type}`,parameters:{drawing:t}});continue}}catch(e){this.logError({method:"draw",error:`failed to process ${t.type} drawing: ${e}`,parameters:{drawingType:t.type,drawing:t}});continue}r&&this.validateElement(r)?n.push(r):r&&this.logError({method:"draw",error:"generated element failed validation",parameters:{element:r,drawingType:t.type}})}return{props:{},children:n}}catch(t){return this.logError({method:"draw",error:`draw method failed: ${t}`,parameters:{drawable:e}}),this.createEmptyElement()}}safeFillSketch(e,t){try{const r=this.safeOpsToPath(e,t.fixedDecimalPlaceDigits);if(!r)return null;let s=t.fillWeight;return s<0&&(s=t.strokeWidth/2),{props:Object.assign(Object.assign({d:r,stroke:t.fill||"",strokeWidth:s,fill:"none"},t.fillLineDash&&{strokeDasharray:t.fillLineDash.join(" ").trim()}),t.fillLineDashOffset&&{strokeDashoffset:t.fillLineDashOffset})}}catch(r){return this.logError({method:"safeFillSketch",error:`fillSketch generation failed: ${r}`,parameters:{drawing:e,options:t}}),null}}safeOpsToPath(e,t){try{return e&&e.ops&&Array.isArray(e.ops)?this.opsToPath(e,t):null}catch(r){return this.logError({method:"safeOpsToPath",error:`opsToPath conversion failed: ${r}`,parameters:{drawing:e,fixedDecimalPlaceDigits:t}}),null}}validateElement(e){return e&&"object"==typeof e&&e.props&&"object"==typeof e.props}createEmptyElement(){return{props:{},children:[]}}validateCoordinates(e){return e.every((e=>"number"==typeof e&&!isNaN(e)&&isFinite(e)))}validateDimensions(...e){return e.every((e=>"number"==typeof e&&!isNaN(e)&&isFinite(e)&&e>=0))}validatePoints(e){return Array.isArray(e)&&e.length>0&&e.every((e=>Array.isArray(e)&&e.length>=c.VALIDATION.MIN_POINT_ARRAY_LENGTH&&this.validateCoordinates([e[0],e[1]])))}validateAngles(e,t){return this.validateCoordinates([e,t])}validateCurvePoints(e){var t;return!(!Array.isArray(e)||0===e.length)&&("number"==typeof(null===(t=e[0])||void 0===t?void 0:t[0])?this.validatePoints(e):e.every((e=>this.validatePoints(e))))}get generator(){return this.gen}getDefaultOptions(){return this.gen.defaultOptions}opsToPath(e,t){return this.gen.opsToPath(e,t)}line(e,t,r,s,n){try{if(!this.validateCoordinates([e,t,r,s]))return this.logError({method:"line",error:"invalid coordinates",parameters:{x1:e,y1:t,x2:r,y2:s,options:n}}),this.createEmptyElement();const a=this.gen.line(e,t,r,s,n);return this.draw(a)}catch(a){return this.logError({method:"line",error:`generation failed: ${a}`,parameters:{x1:e,y1:t,x2:r,y2:s,options:n}}),this.createEmptyElement()}}rectangle(e,t,r,s,n){try{if(!this.validateCoordinates([e,t])||!this.validateDimensions(r,s))return this.logError({method:"rectangle",error:"invalid parameters",parameters:{x:e,y:t,width:r,height:s,options:n}}),this.createEmptyElement();const a=this.gen.rectangle(e,t,r,s,n);return this.draw(a)}catch(a){return this.logError({method:"rectangle",error:`generation failed: ${a}`,parameters:{x:e,y:t,width:r,height:s,options:n}}),this.createEmptyElement()}}ellipse(e,t,r,s,n){try{if(!this.validateCoordinates([e,t])||!this.validateDimensions(r,s))return this.logError({method:"ellipse",error:"invalid parameters",parameters:{x:e,y:t,width:r,height:s,options:n}}),this.createEmptyElement();const a=this.gen.ellipse(e,t,r,s,n);return this.draw(a)}catch(a){return this.logError({method:"ellipse",error:`generation failed: ${a}`,parameters:{x:e,y:t,width:r,height:s,options:n}}),this.createEmptyElement()}}circle(e,t,r,s){try{if(!this.validateCoordinates([e,t])||!this.validateDimensions(r))return this.logError({method:"circle",error:"invalid parameters",parameters:{x:e,y:t,diameter:r,options:s}}),this.createEmptyElement();const n=this.gen.circle(e,t,r,s);return this.draw(n)}catch(n){return this.logError({method:"circle",error:`generation failed: ${n}`,parameters:{x:e,y:t,diameter:r,options:s}}),this.createEmptyElement()}}linearPath(e,t){try{if(!this.validatePoints(e))return this.logError({method:"linearPath",error:"invalid points",parameters:{points:e,options:t}}),this.createEmptyElement();const r=this.gen.linearPath(e,t);return this.draw(r)}catch(r){return this.logError({method:"linearPath",error:`generation failed: ${r}`,parameters:{points:e,options:t}}),this.createEmptyElement()}}polygon(e,t){try{if(!this.validatePoints(e)||e.length<c.VALIDATION.MIN_POLYGON_POINTS)return this.logError({method:"polygon",error:"invalid points (need at least 3 points)",parameters:{points:e,options:t}}),this.createEmptyElement();const r=this.gen.polygon(e,t);return this.draw(r)}catch(r){return this.logError({method:"polygon",error:`generation failed: ${r}`,parameters:{points:e,options:t}}),this.createEmptyElement()}}arc(e,t,r,s,n,a,o=!1,i){try{if(!this.validateCoordinates([e,t])||!this.validateDimensions(r,s)||!this.validateAngles(n,a))return this.logError({method:"arc",error:"invalid parameters",parameters:{x:e,y:t,width:r,height:s,start:n,stop:a,closed:o,options:i}}),this.createEmptyElement();const h=this.gen.arc(e,t,r,s,n,a,o,i);return this.draw(h)}catch(h){return this.logError({method:"arc",error:`generation failed: ${h}`,parameters:{x:e,y:t,width:r,height:s,start:n,stop:a,closed:o,options:i}}),this.createEmptyElement()}}curve(e,t){try{if(!this.validateCurvePoints(e))return this.logError({method:"curve",error:"invalid points",parameters:{points:e,options:t}}),this.createEmptyElement();const r=this.gen.curve(e,t);return this.draw(r)}catch(r){return this.logError({method:"curve",error:`generation failed: ${r}`,parameters:{points:e,options:t}}),this.createEmptyElement()}}path(e,t){try{if(!e||"string"!=typeof e||e.trim().length===c.VALIDATION.MIN_PATH_STRING_LENGTH)return this.logError({method:"path",error:"invalid path data",parameters:{d:e,options:t}}),this.createEmptyElement();const r=this.gen.path(e,t);return this.draw(r)}catch(r){return this.logError({method:"path",error:`generation failed: ${r}`,parameters:{d:e,options:t}}),this.createEmptyElement()}}}ce.errorCache=new Map,ce.maxErrorCacheSize=c.ERROR.MAX_ERROR_CACHE_SIZE,ce.errorRateLimit=c.ERROR.ERROR_RATE_LIMIT_PER_MINUTE,ce.cacheCleanupInterval=c.ERROR.ERROR_CACHE_CLEANUP_INTERVAL_MS,ce.cleanupTimer=null,ce.instanceCount=0,ce.finalizationRegistry=null;const le=new class{constructor(){this.instances=new Map,this.listeners=new Set,this.nextId=0}createInstance(e){const t=`${c.REACT_HOOK.ID_PREFIX}${this.nextId++}`,r=new ce(e);return this.instances.set(t,r),this.notifyListeners(),t}getInstance(e){return this.instances.get(e)}updateInstance(e,t){const r=this.instances.get(e);r&&r.dispose();const s=new ce(t);this.instances.set(e,s),this.notifyListeners()}deleteInstance(e){const t=this.instances.get(e);t&&(t.dispose(),this.instances.delete(e),this.notifyListeners())}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}getSnapshot(){return new Map(this.instances)}notifyListeners(){this.listeners.forEach((e=>e()))}clear(){this.instances.forEach((e=>e.dispose())),this.instances.clear(),this.notifyListeners()}};const ue=new class{constructor(){this.cache=new Map,this.listeners=new Set,this.pendingGenerations=new Set,this.memoryMonitor=Ee.getInstance()}get maxCacheSize(){return this.memoryMonitor.getRecommendedCacheSize()*c.MEMORY.SHAPE_CACHE_MULTIPLIER}generateShape(e,t){if(this.cache.has(e))return this.cache.get(e);if(this.memoryMonitor.shouldAgressivelyCleanup()&&this.pendingGenerations.size>2)return null;if(this.pendingGenerations.has(e))return null;this.cache.size>=this.maxCacheSize&&this.performMemoryPressureCleanup(),this.pendingGenerations.add(e);try{const r=t();return this.cache.set(e,r),this.pendingGenerations.delete(e),this.notifyListeners(),r}catch(t){if(this.pendingGenerations.delete(e),!this.memoryMonitor.shouldAgressivelyCleanup()){const r={props:{},children:[],error:String(t)};this.cache.set(e,r)}return this.notifyListeners(),{props:{},children:[],error:String(t)}}}performMemoryPressureCleanup(){const e=this.memoryMonitor.getMemoryPressureLevel();if("high"===e){const e=Array.from(this.cache.entries()),t=Math.floor(e.length*c.MEMORY.HIGH_PRESSURE_KEEP_PERCENT),r=e.slice(-t);this.cache.clear(),r.forEach((([e,t])=>this.cache.set(e,t)))}else if("medium"===e){const e=Array.from(this.cache.entries()),t=Math.floor(e.length*c.MEMORY.MEDIUM_PRESSURE_KEEP_PERCENT),r=e.slice(-t);this.cache.clear(),r.forEach((([e,t])=>this.cache.set(e,t)))}}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}getSnapshot(){return new Map(this.cache)}notifyListeners(){this.listeners.forEach((e=>e()))}clearCache(){this.cache.clear(),this.pendingGenerations.clear(),this.notifyListeners()}};class Ee{constructor(){this.memoryPressureLevel="low",this.lastMemoryCheck=0,this.checkInterval=c.MEMORY.MEMORY_CHECK_INTERVAL_MS}static getInstance(){return Ee.instance||(Ee.instance=new Ee),Ee.instance}getMemoryPressureLevel(){const e=Date.now();return e-this.lastMemoryCheck>this.checkInterval&&(this.checkMemoryPressure(),this.lastMemoryCheck=e),this.memoryPressureLevel}checkMemoryPressure(){try{if("undefined"!=typeof global&&global.performance&&global.performance.memory){const e=global.performance.memory,t=e.usedJSHeapSize/e.jsHeapSizeLimit;return void(t>c.MEMORY.HIGH_MEMORY_PRESSURE_THRESHOLD?this.memoryPressureLevel="high":t>c.MEMORY.MEDIUM_MEMORY_PRESSURE_THRESHOLD?this.memoryPressureLevel="medium":this.memoryPressureLevel="low")}if("undefined"!=typeof performance&&performance.memory){const e=performance.memory,t=e.usedJSHeapSize/e.jsHeapSizeLimit;return void(t>c.MEMORY.HIGH_MEMORY_PRESSURE_THRESHOLD?this.memoryPressureLevel="high":t>c.MEMORY.MEDIUM_MEMORY_PRESSURE_THRESHOLD?this.memoryPressureLevel="medium":this.memoryPressureLevel="low")}if("undefined"!=typeof global){const e="undefined"!=typeof navigator?navigator.userAgent:"",t=/Android.*4\.|Android.*[0-3]\./i.test(e);return void(this.memoryPressureLevel=t?"high":"medium")}this.memoryPressureLevel="medium"}catch(e){this.memoryPressureLevel="medium"}}getRecommendedCacheSize(){switch(this.memoryPressureLevel){case"high":return c.MEMORY.CACHE_SIZE_HIGH_PRESSURE;case"medium":return c.MEMORY.CACHE_SIZE_MEDIUM_PRESSURE;case"low":return c.MEMORY.CACHE_SIZE_LOW_PRESSURE;default:return c.MEMORY.CACHE_SIZE_DEFAULT}}shouldAgressivelyCleanup(){return"high"===this.memoryPressureLevel}}const pe=new class{constructor(){this.cache=new WeakMap,this.cacheCount=0,this.cacheHits=0,this.cacheMisses=0,this.memoryMonitor=Ee.getInstance()}get maxCacheSize(){return this.memoryMonitor.getRecommendedCacheSize()}get(e,t){if("object"!=typeof e||"object"!=typeof t||null===e||null===t)return;const r=this.cache.get(e);if(r){const e=r.get(t);if(void 0!==e)return this.cacheHits++,e}this.cacheMisses++}set(e,t,r){if("object"!=typeof e||"object"!=typeof t||null===e||null===t)return;const s=this.maxCacheSize;if(this.cacheCount++,this.cacheCount>s&&(this.cache=new WeakMap,this.cacheCount=0,this.memoryMonitor.shouldAgressivelyCleanup()&&"undefined"!=typeof global&&global.gc))try{global.gc()}catch(e){}let n=this.cache.get(e);if(n||(n=new WeakMap,this.cache.set(e,n)),n.set(t,r),!this.memoryMonitor.shouldAgressivelyCleanup()){let s=this.cache.get(t);s||(s=new WeakMap,this.cache.set(t,s)),s.set(e,r)}}getStats(){return{hits:this.cacheHits,misses:this.cacheMisses,hitRate:this.cacheHits/(this.cacheHits+this.cacheMisses),memoryPressure:this.memoryMonitor.getMemoryPressureLevel(),maxCacheSize:this.maxCacheSize,currentCacheCount:this.cacheCount}}};function fe(e,t,r=0){if(e===t)return!0;if(r>c.REACT_HOOK.MAX_RECURSION_DEPTH)return!1;const s=typeof e;if(s!==typeof t)return!1;if(null===e||null===t||void 0===e||void 0===t)return e===t;if("object"!==s)return e===t;const n=pe.get(e,t);if(void 0!==n)return n;let a;if(e instanceof Date&&t instanceof Date)a=e.getTime()===t.getTime();else if(Array.isArray(e))if(Array.isArray(t)&&e.length===t.length){a=!0;for(let s=0;s<e.length;s++)if(!fe(e[s],t[s],r+1)){a=!1;break}}else a=!1;else if(Array.isArray(t))a=!1;else{const s=Object.keys(e),n=Object.keys(t);if(s.length!==n.length)a=!1;else{a=!0;const o=s.length>c.REACT_HOOK.KEY_LOOKUP_SET_THRESHOLD?new Set(n):n;for(const n of s){if(!(Array.isArray(o)?o.includes(n):o.has(n))||!fe(e[n],t[n],r+1)){a=!1;break}}}}return pe.set(e,t,a),a}function de(r,n){const a=t(r),o=t(r),i=t(n),h=t(!0);return s((()=>{if(h.current)return h.current=!1,!0;if(!n&&!i.current)return!fe(r,o.current);if(!n||!i.current||n.length!==i.current.length)return!0;for(let e=0;e<n.length;e++)if(!fe(n[e],i.current[e]))return!0;return!1}),n||[])&&(o.current=a.current,a.current=r,i.current=n),e((()=>()=>{a.current=null,o.current=null,i.current=void 0}),[]),a.current}function _e(t,r,s){const n=de(t,r);return e((()=>{if("development"===process.env.NODE_ENV&&s)try{const e="undefined"!=typeof performance?performance.memory:void 0;e&&e.usedJSHeapSize&&console.debug(`useDeepMemo[${s}]: ${(e.usedJSHeapSize/c.MEMORY.BYTES_TO_KB/c.MEMORY.KB_TO_MB).toFixed(2)}MB`)}catch(e){}})),n}const Re={getDeepEqualStats:()=>pe.getStats(),clearDeepEqualCache:()=>{pe.cache=new WeakMap},getRoughInstanceCount:()=>le.getSnapshot().size,getShapeCacheSize:()=>ue.getSnapshot().size,clearRoughInstances:()=>le.clear(),clearShapeCache:()=>ue.clearCache(),getMemoryPressure:()=>Ee.getInstance().getMemoryPressureLevel(),getRecommendedCacheSize:()=>Ee.getInstance().getRecommendedCacheSize(),forceMemoryCleanup:()=>{if(Ee.getInstance().shouldAgressivelyCleanup()&&(ue.clearCache(),pe.cache=new WeakMap,"undefined"!=typeof global&&global.gc))try{global.gc()}catch(e){}},clearAllCaches:()=>{pe.cache=new WeakMap,le.clear(),ue.clearCache()}};function ge(n){const a=t(null),o=de(n,[n]),i=r(le.subscribe.bind(le),le.getSnapshot.bind(le),le.getSnapshot.bind(le)),h=s((()=>(a.current?le.updateInstance(a.current,o):a.current=le.createInstance(o),le.getInstance(a.current))),[o,i]);if(e((()=>()=>{a.current&&(le.deleteInstance(a.current),a.current=null)}),[]),!h)throw new Error("Failed to create RoughReactNativeSVG instance");return h}function Me(e,t,n,a){const o=ge(a),i=de(t,[t]),h=de(n,[n]),c=s((()=>`${e}-${JSON.stringify(i)}-${JSON.stringify(h)}`),[e,i,h]),l=r(ue.subscribe.bind(ue),ue.getSnapshot.bind(ue),ue.getSnapshot.bind(ue));return s((()=>ue.generateShape(c,(()=>{switch(e){case"line":{const[e,t,r,s]=i;return o.line(e,t,r,s,h)}case"rectangle":{const[e,t,r,s]=i;return o.rectangle(e,t,r,s,h)}case"ellipse":{const[e,t,r,s]=i;return o.ellipse(e,t,r,s,h)}case"circle":{const[e,t,r]=i;return o.circle(e,t,r,h)}case"linearPath":{const e=i;return o.linearPath(e,h)}case"polygon":{const e=i;return o.polygon(e,h)}case"arc":{const[e,t,r,s,n,a,c]=i;return o.arc(e,t,r,s,n,a,c||!1,h)}case"curve":{const e=i;return o.curve(e,h)}case"path":{const e=i;return o.path(e,h)}default:throw new Error(`Unknown shape type: ${e}`)}}))),[c,o,e,i,h,l])||{props:{},children:[]}}function me(e,t){const n=ge(t),a=de(e,[e]),o=s((()=>`batch-${JSON.stringify(a)}`),[a]),i=r(ue.subscribe.bind(ue),ue.getSnapshot.bind(ue),ue.getSnapshot.bind(ue));return s((()=>ue.generateShape(o,(()=>a.map(((e,t)=>{try{const{type:t,params:r,options:s}=e;switch(t){case"line":{const[e,t,a,o]=r;return n.line(e,t,a,o,s)}case"rectangle":{const[e,t,a,o]=r;return n.rectangle(e,t,a,o,s)}case"ellipse":{const[e,t,a,o]=r;return n.ellipse(e,t,a,o,s)}case"circle":{const[e,t,a]=r;return n.circle(e,t,a,s)}case"linearPath":{const e=r;return n.linearPath(e,s)}case"polygon":{const e=r;return n.polygon(e,s)}case"arc":{const[e,t,a,o,i,h,c]=r;return n.arc(e,t,a,o,i,h,c||!1,s)}case"curve":{const e=r;return n.curve(e,s)}case"path":{const e=r;return n.path(e,s)}default:return{props:{},children:[]}}}catch(e){return{props:{},children:[],error:`Shape ${t} failed: ${String(e)}`}}}))))),[o,n,a,i])||[]}function Se(r){const n=t(void 0),a=t(null),o=s((()=>!(!r&&!n.current)&&(!r||!n.current||!fe(r,n.current))),[r]),i=s((()=>(a.current&&!o||(a.current&&a.current.dispose(),a.current=new ce(r),n.current=r),a.current)),[r,o]);return e((()=>()=>{a.current&&(a.current.dispose(),a.current=null)}),[]),i}var Ie={reactNativeSvg:e=>new ce(e),generator:e=>new he(e),newSeed:()=>he.newSeed()};export{Re as debugUtils,Ie as default,_e as useDeepMemoWithDebug,ge as useRough,Me as useRoughShape,me as useRoughShapes,Se as useStableRough};