diff --git a/README.md b/README.md index ec702a4..2bfc259 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,37 @@ For improved performance, use the minified version of `p5.brush.js` which bundle ``` Replace path_to with the actual path to the minified script in your project directory or the URL if you are using a CDN. +### Note for p5 instance mode + +By default, all p5.js functions are in the global namespace (i.e. bound to the window object), meaning you can call them simply ellipse(), fill(), etc. However, this might be inconvenient if you are mixing with other JS libraries (synchronously or asynchronously) or writing long programs of your own. p5.js currently supports a way around this problem called "instance mode". In instance mode, all p5 functions are bound up in a single variable instead of polluting your global namespace. + +If you plan to use p5 instance mode, you need to load p5.brush in a specific way: + + - Use `brush.instance()` before the setup and draw functions, pointing to your sketch id and the p5 function argument + Example: + ```javascript + let sketch = function(p) { + let x = 100; + let y = 100; + + // Register instance method here, sending your function arg p + brush.instance(p) + + p.setup = function() { + p.createCanvas(700, 410); + }; + + p.draw = function() { + p.background(0); + brush.fill("red", 75); + brush.rect(x, y, 50, 50); + }; + }; + + let myp5 = new p5(sketch); + ``` + +--- ## Features @@ -96,8 +127,9 @@ p5.brush.js provides a comprehensive API for creating complex drawings and effec | | brush.strokeWeight()| | | brush.colorCache() | | [Fill Operations](#fill-operations) | brush.fill() | | | brush.scaleBrushes()| | | brush.noFill() | | | brush.remove() | -| | brush.bleed() | | [Classes](#exposed-classes) | brush.Polygon() | -| | brush.fillTexture() | | | brush.Plot() | +| | brush.bleed() | | | brush.instance() | +| | brush.fillTexture() | | [Classes](#exposed-classes) | brush.Polygon() | +| | | | | brush.Plot() | | | | | | brush.Position() | --- @@ -834,21 +866,45 @@ This section covers functions for initializing the drawing system, preloading re --- -- `brush.load(canvasID, isInstanced)` - - **Description**: Initializes the drawing system and sets up the environment. If `canvasID` is not provided, the current window is used as the rendering context. If you want to load the library on a custom p5.Graphics element (or instanced canvas), you can do it by executing this function. +- `brush.load(canvasID)` + - **Description**: Initializes the drawing system and sets up the environment. If `canvasID` is not provided, the current window is used as the rendering context. If you want to load the library on a custom p5.Graphics element, you can do it by executing this function. - **Parameters**: - `canvasID` (string): Optional ID of the buffer/canvas element. If false, uses the window's rendering context. - - `isInstanced` (boolean): Use true if you want to use the p5 instance mode, and read below. + - **Example (load p5.brush on buffer)**: + ```javascript + function setup() { + createCanvas(400,400,WEBGL) + // Draw stuff to global canvas + brush.set("HB","black",1) + brush.rect(40,40,150,100) + // Force draw stuff to canvas + brush.reDraw() + + // Create buffer + let buffer = createGraphics(200,300) + brush.load(buffer) + brush.set("HB","black",1) + brush.rect(40,40,150,100) + // Force draw stuff to buffer + brush.reDraw() + + image(buffer,20,40) + + // Load p5.brush again on global canvas + brush.load() + } + ``` - **Note for Instance Mode**: If you want to use the p5 instance mode, you need to pass the proper variable as canvasID. ```javascript let sketch = function(p) { let x = 100; let y = 100; + // Register instance method here, sending your function arg p + brush.instance(p) + p.setup = function() { p.createCanvas(700, 410); - // Pass the p variable as canvasID like this - brush.load(p, true) }; p.draw = function() { @@ -857,9 +913,9 @@ This section covers functions for initializing the drawing system, preloading re brush.rect(x, y, 50, 50); }; }; - ``` -let myp5 = new p5(sketch); + let myp5 = new p5(sketch); + ``` --- @@ -904,6 +960,35 @@ let myp5 = new p5(sketch); --- +- `brush.instance(p)` + - **Description**: Execute before the setup() and draw() functions if you need to use p5 in instance mode + - **Parameters**: + - `p` (variable): Variable used as the function argument. See below + - **Example**: + ```javascript + let sketch = function(p) { + let x = 100; + let y = 100; + + // Register instance method here, sending your function arg p + brush.instance(p) + + p.setup = function() { + p.createCanvas(700, 410); + }; + + p.draw = function() { + p.background(0); + brush.fill("red", 75); + brush.rect(x, y, 50, 50); + }; + }; + + let myp5 = new p5(sketch); + ``` + +--- + [back to table](#table-of-functions) ### Exposed Classes diff --git a/p5.brush.js b/p5.brush.js index db4fc2f..edab1c3 100644 --- a/p5.brush.js +++ b/p5.brush.js @@ -86,6 +86,13 @@ */ let _isReady = false; + /** + * Flag to indicate if p5 is instanced or global mode. + * @type {boolean} + */ + let _isInstanced = false; + let _inst = false; + /** * Configures the drawing system with custom options. * @param {Object} [objct={}] - Optional configuration object. @@ -101,9 +108,11 @@ * If false, it uses the current window as the rendering context. * EXPORTED */ - function loadSystem (canvasID = false, instanced = false) { + function loadSystem (canvasID = false) { + let inst = (_isInstanced && canvasID) ? _inst : false; if (_isReady) _remove(false) // Set the renderer to the specified canvas or to the window if no ID is given + if (!canvasID && _isInstanced) canvasID = _inst; _r = (!canvasID) ? window.self : canvasID; if (!_isReady) { _isReady = true; @@ -111,7 +120,7 @@ globalScale(_r.width / 250) // Adjust standard brushes to match canvas } // Load color blending - Mix.load(instanced); + Mix.load(inst); } /** @@ -119,12 +128,12 @@ */ function _remove (a = true) { if (_isReady) { - Mix.mask.remove() - Mix.mask = null; - Mix.mask2.remove() - Mix.mask2 = null; - Mix.noBlend.remove() - Mix.noBlend = null; + Mix.masks[0].remove() + Mix.masks[0] = null; + Mix.masks[1].remove() + Mix.masks[1] = null; + Mix.masks[2].remove() + Mix.masks[2] = null; if (a) brush.load() } } @@ -147,11 +156,6 @@ if (!_isReady) loadSystem(); } - /** - * Automatically load the library before draw() - */ - p5.prototype.registerMethod('afterSetup', () => _ensureReady()); - // ============================================================================= // Section: Randomness and other auxiliary functions // ============================================================================= @@ -306,6 +310,11 @@ * Changes angles to degrees and between 0-360 */ toDegrees: (a) => (((_r.angleMode() === "radians") ? a * 180 / Math.PI : a) % 360 + 360) % 360, + + /** + * Calculates distance between two 2D points + */ + dist: (x1,y1,x2,y2) => Math.hypot(x2-x1, y2-y1) } // Perform the precalculation of trigonometric values for the R object R.preCalculation(); @@ -524,15 +533,36 @@ /** * Loads necessary resources and prepares the mask buffer and shader for colour blending. */ - load(instanced) { - // Create a buffer to be used as a mask. We use a 2D buffer for faster geometry drawing + load(inst) { + this.type = (_isInstanced && !inst) ? 0 : (!inst ? 1 : 2) + this.masks = [] + switch(this.type) { + case 0: + // Create a buffer to be used as a mask for blending + this.masks[0] = _r.createGraphics(_r.width,_r.height) + // WEBGL buffer for img brushes (image() is much quicker like this) + this.masks[1] = _r.createGraphics(_r.width,_r.height, _r.WEBGL) + // Create a buffer for noBlend brushes + this.masks[2] = _r.createGraphics(_r.width,_r.height) + break; + case 1: + this.masks[0] = createGraphics(_r.width,_r.height) + this.masks[1] = createGraphics(_r.width,_r.height, WEBGL) + this.masks[2] = createGraphics(_r.width,_r.height) + break; + case 2: + this.masks[0] = inst.createGraphics(inst.width, inst.height) + this.masks[1] = inst.createGraphics(inst.width, inst.height, inst.WEBGL) + this.masks[2] = inst.createGraphics(inst.width, inst.height) + break; + } - this.mask = instanced ? _r.createGraphics(_r.width,_r.height) : createGraphics(_r.width,_r.height) - this.mask.pixelDensity(_r.pixelDensity()); - this.mask.clear(); - this.mask.noSmooth(); - this.mask.angleMode(_r.DEGREES); - exports.mask = this.mask; + for (let mask of this.masks) { + mask.pixelDensity(_r.pixelDensity()); + mask.clear(); + mask.angleMode(_r.DEGREES); + mask.noSmooth(); + } // Load the spectral.js shader code only once if (!Mix.loaded) { @@ -541,19 +571,6 @@ // Create the shader program from the vertex and fragment shaders this.shader = _r.createShader(this.vert, this.frag); Mix.loaded = true; - - // Create a buffer for noBlend brushes - this.noBlend = instanced ? _r.createGraphics(_r.width,_r.height) : createGraphics(_r.width,_r.height) - this.noBlend.pixelDensity(_r.pixelDensity()); - this.noBlend.noSmooth(); - this.noBlend.clear(); - this.noBlend.angleMode(_r.DEGREES); - - // WEBGL buffer for img brushes (image() is much quicker like this) - this.mask2 = instanced ? _r.createGraphics(_r.width,_r.height, _r.WEBGL) : createGraphics(_r.width,_r.height, _r.WEBGL) - this.mask2.pixelDensity(_r.pixelDensity()); - this.mask2.clear(); - this.mask2.angleMode(_r.DEGREES); }, /** @@ -577,8 +594,8 @@ reDraw() { _r.push(); _r.translate(-Matrix.trans()[0],-Matrix.trans()[1]) - _r.image(Mix.noBlend, -_r.width/2, -_r.height/2) - Mix.noBlend.clear() + _r.image(Mix.masks[2], -_r.width/2, -_r.height/2) + Mix.masks[2].clear() _r.pop(); }, @@ -608,7 +625,7 @@ * @param {boolean} _isLast - Indicates if this is the last blend after setup and draw. * @param {boolean} _isLast - Indicates if this is the last blend after setup and draw. */ - blend (_color = false, _isLast = false, webgl_mask = false, _watercolor = false) { + blend (_color = false, _isLast = false, webgl_mask = false) { // Select between the two options: this.isBlending = webgl_mask ? this.blending1 : this.blending2; @@ -646,12 +663,12 @@ this.shader.setUniform('addColor', this.currentColor); // Source canvas this.shader.setUniform('source', _r._renderer); - // Bool to active watercolor blender vs marker blender - this.shader.setUniform('active', _watercolor); + // Bool to active watercolor blender vs marker blenderd + this.shader.setUniform('active', Mix.watercolor); // Random values for watercolor blender this.shader.setUniform('random', [R.random(),R.random(),R.random()]); // We select and apply the correct mask here - let mask = webgl_mask ? this.mask2 : this.mask; + let mask = webgl_mask ? this.masks[1] : this.masks[0]; this.shader.setUniform('mask', mask); // Draw a rectangle covering the whole canvas to apply the shader _r.fill(0,0,0,0); @@ -758,8 +775,9 @@ float n = psrdnoise(vVertTexCoord * 5., p, 10.0 * random.x, g); float n2 = psrdnoise(vVertTexCoord * 5., p, 10.0 * random.y, g); float n3 = psrdnoise(vVertTexCoord * 5., p, 10.0 * random.z, g); + float tt = abs(addColor.x - addColor.y - addColor.z); float n4 = 0.25 + 0.25 * psrdnoise(vVertTexCoord * 4., p, 3.0 * random.x, g); - pigment = vec4(generic_desaturate(addColor.xyz,n4).xyz + vec3(n,n2,n3) * 0.03, 1.0); + pigment = vec4(generic_desaturate(addColor.xyz,n4).xyz + vec3(n,n2,n3) * 0.03 * tt, 1.0); } else { pigment = vec4(addColor.xyz,1.0); } @@ -780,10 +798,19 @@ /** * Register methods after setup() and post draw() for belding last buffered color */ - p5.prototype.registerMethod('afterSetup', () => Mix.blend(false, true)); - p5.prototype.registerMethod('afterSetup', () => Mix.blend(false, true, true)); - p5.prototype.registerMethod('post', () => Mix.blend(false, true)); - p5.prototype.registerMethod('post', () => Mix.blend(false, true, true)); + function _registerMethods (p5p) { + p5p.registerMethod('afterSetup', () => Mix.blend(false, true)); + p5p.registerMethod('afterSetup', () => Mix.blend(false, true, true)); + p5p.registerMethod('post', () => Mix.blend(false, true)); + p5p.registerMethod('post', () => Mix.blend(false, true, true)); + } + if (typeof p5 !== "undefined") _registerMethods(p5.prototype); + function _instance (inst) { + _isInstanced = true; + _inst = inst; + _registerMethods(inst) + } + exports.instance = _instance // ============================================================================= // Section: FlowField @@ -1266,7 +1293,7 @@ */ line(x1,y1,x2,y2) { _ensureReady(); - let d = _r.dist(x1,y1,x2,y2) + let d = R.dist(x1,y1,x2,y2) if (d == 0) return; B.initializeDrawingState(x1, y1, d, false, false); let angle = _calculateAngle(x1,y1,x2,y2); @@ -1375,7 +1402,7 @@ // Blend Mode this.c = _r.color(this.c); // Select mask buffer for blend mode - this.mask = this.p.blend ? ((this.p.type === "image") ? Mix.mask2 : Mix.mask) : Mix.noBlend; + this.mask = this.p.blend ? ((this.p.type === "image") ? Mix.masks[1] : Mix.masks[0]) : Mix.masks[2]; Matrix.trans() // Set the blender this.mask.push(); @@ -1384,6 +1411,7 @@ this.mask.rotate(-Matrix.rotation) this.mask.scale(Scale.current) if (this.p.blend) { + Mix.watercolor = false; if (this.p.type !== "image") Mix.blend(this.c); else Mix.blend(this.c,false,true) if (!isTip) this.markerTip() @@ -1464,9 +1492,8 @@ * @param {number} pressure - The current pressure value. * @returns {number} The calculated alpha value. */ - calculateAlpha(pressure) { + calculateAlpha() { let opacity = (this.p.type !== "default" && this.p.type !== "spray") ? this.p.opacity / this.w : this.p.opacity; - //let pow = R.constrain(Math.pow(pressure, this.p.type === "marker" ? 0.7 : 1.5),0.75,1.3) return opacity; }, @@ -1885,6 +1912,22 @@ } H.isActive = curState; } + + erase (c = false, a = E.a) { + if (E.isActive || c) { + Mix.masks[2].push() + Mix.masks[2].noStroke() + let ccc = _r.color(c ? c : E.c) + ccc.setAlpha(a) + Mix.masks[2].fill(ccc) + Mix.masks[2].beginShape() + for (let p of this.vertices) { + Mix.masks[2].vertex(p.x,p.y) + } + Mix.masks[2].endShape(_r.CLOSE) + Mix.masks[2].pop() + } + } } /** @@ -1926,12 +1969,13 @@ _vertex(x+w,y); _vertex(x+w,y+h); _vertex(x,y+h); - _endShape(CLOSE) + _endShape(_r.CLOSE) } else { let p = new Polygon([[x,y],[x+w,y],[x+w,y+h],[x,y+h]]) p.fill(); p.hatch(); p.draw(); + p.erase(); } } @@ -2091,13 +2135,18 @@ let side = (max + min) * (isHatch ? 0.03 : ((F.isAnimated) ? 0.25 : bleed)); let linepoint = new Position(_x,_y); let numsteps = Math.round(this.length/_step); - let pside = 0, i = 0; - let side1 = side * R.random(0.7,1.3) + let pside = 0, i = 0, j = 0; + let side1 = side * R.random(0.6,1.5) for (let steps = 0; steps < numsteps; steps++) { linepoint.plotTo(this,_step,_step,1) pside += _step; + this.calcIndex(linepoint.plotted) + if (this.index >= j && linepoint.x) { + vertices.push([linepoint.x,linepoint.y]) + j++ + } if (pside >= side1 && linepoint.x) { - vertices[i] = [linepoint.x,linepoint.y] + vertices.push([linepoint.x,linepoint.y]) side1 = side * R.random(0.7,1.3), i++, pside = 0 } } @@ -2146,6 +2195,22 @@ this.pol.hatch() } } + + erase(x, y, scale) { + if (this.origin) x = this.origin[0], y = this.origin[1], scale = 1; + this.pol = this.genPol(x, y, scale, true) + Mix.masks[2].push() + Mix.masks[2].noStroke() + let ccc = _r.color(E.c) + ccc.setAlpha(E.a) + Mix.masks[2].fill(ccc) + Mix.masks[2].beginShape() + for (let p of this.pol.vertices) { + Mix.masks[2].vertex(p.x,p.y) + } + Mix.masks[2].endShape(_r.CLOSE) + Mix.masks[2].pop() + } } /** @@ -2177,9 +2242,11 @@ // Finalize the plot p.endPlot(angle2 + angle,1, true) // Fill / hatch / draw - p.fill(x - radius * R.sin(angle),y - radius * R.cos(-angle),1); - p.hatch(x - radius * R.sin(angle),y - radius * R.cos(-angle),1); - p.draw(x - radius * R.sin(angle),y - radius * R.cos(-angle),1); + let o = [x - radius * R.sin(angle),y - radius * R.cos(-angle),1] + p.fill(o[0],o[1]) + p.hatch(o[0],o[1]) + p.draw(o[0],o[1]) + p.erase(o[0],o[1]) } // Holds the array of vertices for the custom shape being defined. Each vertex includes position and optional pressure. @@ -2210,14 +2277,15 @@ /** * Finishes recording vertices for a custom shape and either closes it or leaves it open. * It also triggers the drawing of the shape with the active stroke(), fill() and hatch() states. - * @param {string} [a] - An optional argument to close the shape if set to CLOSE. + * @param {string} [a] - An optional argument to close the shape if set to _r.CLOSE. */ function _endShape(a) { - if (a === CLOSE) { + if (a === _r.CLOSE) { _strokeArray.push(_strokeArray[0]); // Close the shape by connecting the last vertex to the first _strokeArray.push(_strokeArray[1]); } - let plot = _createSpline(_strokeArray, _strokeOption, a === CLOSE ? true : false); // Create a new Plot with the recorded vertices and curvature option + // Create a new Plot with the recorded vertices and curvature option + let plot = (_strokeOption == 0 && !FF.isActive) ? new Polygon(_strokeArray) : _createSpline(_strokeArray, _strokeOption, a === _r.CLOSE ? true : false); if (F.isActive || H.isActive) { plot.fill(); // Fill the shape if the fill state is active plot.hatch(); // Hatch the shape if the hatch state is active @@ -2225,6 +2293,9 @@ if (B.isActive) { plot.draw(); // Draw the shape if the brush state is active } + if (E.isActive) { + plot.erase() + } _strokeArray = false; // Clear the array after the shape has been drawn } @@ -2282,8 +2353,8 @@ if (curvature > 0 && i < array_points.length - 2) { // Get the current and next points let p1 = array_points[i], p2 = array_points[i+1], p3 = array_points[i+2]; - // Calculate distances and angles between points - let d1 = dist(p1[0],p1[1],p2[0],p2[1]), d2 = dist(p2[0],p2[1],p3[0],p3[1]); + // Calculate distances and angles between points + let d1 = R.dist(p1[0],p1[1],p2[0],p2[1]), d2 = R.dist(p2[0],p2[1],p3[0],p3[1]); let a1 = _calculateAngle(p1[0],p1[1],p2[0],p2[1]), a2 = _calculateAngle(p2[0],p2[1],p3[0],p3[1]); // Calculate curvature based on the minimum distance let dd = curvature * Math.min(Math.min(d1,d2),0.5 * Math.min(d1,d2)), dmax = Math.max(d1,d2) @@ -2303,14 +2374,14 @@ let point3 = {x: p2[0] + dd * R.cos(-a2), y: p2[1] + dd * R.sin(-a2)} let point4 = {x: point3.x + dmax * R.cos(-a2+90), y: point3.y + dmax * R.sin(-a2+90)} let int = _intersectLines(point1,point2,point3,point4,true) - let radius = _r.dist(point1.x,point1.y,int.x,int.y) - let disti = _r.dist(point1.x,point1.y,point3.x,point3.y)/2 + let radius = R.dist(point1.x,point1.y,int.x,int.y) + let disti = R.dist(point1.x,point1.y,point3.x,point3.y)/2 let a3 = 2 * Math.asin( disti/radius ) * (180 / Math.PI); let s3 = 2 * Math.PI * radius * a3 / 360; let temp = _close ? (i === 0 ? 0 : s1-done) : s1-done; let temp2 = (i === array_points.length - 3) ? (_close ? pep - dd : s2) : 0; p.addSegment(a1,temp, p1[2],true) - p.addSegment(a1,s3, p1[2],true) + p.addSegment(a1,isNaN(s3) ? 0 : s3, p1[2],true) p.addSegment(a2,temp2, p2[2],true) done = dd; if (i === 0) pep = s1, pep2 = dd, tep = [point1.x,point1.y]; @@ -2322,7 +2393,7 @@ // If curvature is 0, simply create segments if (i === 0 && _close) array_points.pop() let p1 = array_points[i], p2 = array_points[i+1] - let d = _r.dist(p1[0],p1[1],p2[0],p2[1]); + let d = R.dist(p1[0],p1[1],p2[0],p2[1]); let a = _calculateAngle(p1[0],p1[1],p2[0],p2[1]); p.addSegment(a,d,1,true) if (i == array_points.length - 2) { @@ -2362,6 +2433,17 @@ * techniques for simulating watercolor paints. */ + // No docs for now + const E = { + erase(color = "white", alpha = 255) { + E.isActive = true + E.c = color; E.a = alpha; + }, + noErase() { + E.isActive = false + } + } + /** * Sets the fill color and opacity for subsequent drawing operations. * @param {number|p5.Color} a - The red component of the color or grayscale value, a CSS color string, or a p5.Color object. @@ -2371,6 +2453,7 @@ * EXPORTED */ function setFill(a,b,c,d) { + _ensureReady() F.opacity = (arguments.length < 4) ? ((arguments.length < 3) ? b : 1) : d; F.color = (arguments.length < 3) ? _r.color(a) : _r.color(a,b,c); F.isActive = true; @@ -2383,11 +2466,13 @@ * EXPORTED */ function setBleed(_i, _direction = "out") { + _ensureReady() F.bleed_strength = R.constrain(_i,0,0.6); F.direction = _direction } function setTexture(_texture = 0.4, _border = 0.4) { + _ensureReady() F.texture_strength = R.constrain(_texture, 0, 1); F.border_strength = R.constrain(_border, 0, 1); } @@ -2495,7 +2580,7 @@ this.midP = _center; this.size = -Infinity; for (let v of this.v) { - let temp_size = _r.dist(this.midP.x,this.midP.y,v.x,v.y) + let temp_size = R.dist(this.midP.x,this.midP.y,v.x,v.y) if (temp_size > this.size) this.size = temp_size; } // This calculates the bleed direction for the initial shape, for each of the vertices. @@ -2504,7 +2589,7 @@ for (let i = 0; i < this.v.length; i++) { const currentVertex = this.v[i] const nextVertex = this.v[(i + 1) % this.v.length]; - let side = p5.Vector.sub(nextVertex, currentVertex) + let side = nextVertex.copy().sub(currentVertex) let direction1 = side.copy(); direction1.rotate(90 * rotationFactor); let linea = { @@ -2544,7 +2629,7 @@ return modifier + (gaussianVariation - 0.5) * 0.1; }; // Reusable vector objects - let direction = new p5.Vector(); + let direction = _r.createVector() // Loop through each vertex to calculate the new position based on growth for (let i = 0; i < verticesToProcess; i++) { const currentVertex = this.v[i]; @@ -2566,7 +2651,7 @@ direction.rotate(rotationDegrees * Math.PI / 180); direction.mult(R.gaussian(0.5, 0.2) * R.random(0.6, 1.4) * sideMagnitude * mod); // Calculate the new vertex position - let newVertex = p5.Vector.lerp(currentVertex, nextVertex, R.constrain(R.gaussian(0.5,0.2),0.1,0.9)); + let newVertex = currentVertex.copy().lerp(nextVertex, R.constrain(R.gaussian(0.5,0.2),0.1,0.9)) newVertex.add(direction); // Add the new vertex and its modifier newVerts.push(newVertex); @@ -2594,13 +2679,14 @@ const texture = tex * 3; // Perform initial setup only once + Mix.watercolor = true; Matrix.trans(); Mix.blend(color,false,false,true) - Mix.mask.push(); - Mix.mask.noStroke(); - Mix.mask.translate(Matrix.translation[0] + _r.width/2, Matrix.translation[1] + _r.height/2); - Mix.mask.rotate(Matrix.rotation) - Mix.mask.scale(Scale.current) + Mix.masks[0].push(); + Mix.masks[0].noStroke(); + Mix.masks[0].translate(Matrix.translation[0] + _r.width/2, Matrix.translation[1] + _r.height/2); + Mix.masks[0].rotate(Matrix.rotation) + Mix.masks[0].scale(Scale.current) // Set the different polygons for texture let pol = this.grow() @@ -2627,7 +2713,7 @@ // Erase after each set of layers is drawn if (texture !== 0) pol.erase(texture, intensity); } - Mix.mask.pop(); + Mix.masks[0].pop(); } /** @@ -2639,18 +2725,18 @@ */ layer (_nr, _alpha, bool = true) { // Set fill and stroke properties once - Mix.mask.fill(255, 0, 0, _alpha); + Mix.masks[0].fill(255, 0, 0, _alpha); if (bool) { - Mix.mask.stroke(255, 0, 0, 0.5 + 1.5 * F.border_strength); - Mix.mask.strokeWeight(R.map(_nr, 0, 24, 6, 0.5)); + Mix.masks[0].stroke(255, 0, 0, 0.5 + 1.5 * F.border_strength); + Mix.masks[0].strokeWeight(R.map(_nr, 0, 24, 6, 0.5)); } else { - Mix.mask.noStroke(); + Mix.masks[0].noStroke(); } - Mix.mask.beginShape(); + Mix.masks[0].beginShape(); for(let v of this.v) { - Mix.mask.vertex(v.x, v.y); + Mix.masks[0].vertex(v.x, v.y); } - Mix.mask.endShape(_r.CLOSE); + Mix.masks[0].endShape(_r.CLOSE); } /** @@ -2662,17 +2748,24 @@ const halfSize = this.size / 2; const minSizeFactor = 0.025 * this.size; const maxSizeFactor = 0.19 * this.size; - Mix.mask.erase(3.5 * texture - R.map(intensity, 80, 120, 0.3, 1, true),0); + Mix.masks[0].erase(3.5 * texture - R.map(intensity, 80, 120, 0.3, 1, true),0); for (let i = 0; i < numCircles; i++) { const x = this.midP.x + R.gaussian(0, halfSize); const y = this.midP.y + R.gaussian(0, halfSize); const size = R.random(minSizeFactor, maxSizeFactor); - Mix.mask.circle(x, y, size); + Mix.masks[0].circle(x, y, size); } - Mix.mask.noErase(); + Mix.masks[0].noErase(); } } + function _end() { + Mix.blend(false, true) + Mix.blend(false, true, true) + } + + exports.end = _end + // ============================================================================= // Section: Standard Brushes // ============================================================================= @@ -2783,6 +2876,9 @@ exports.segment = _segment; // Moves to a specified point in the hand-drawn stroke. exports.endStroke = _endStroke; // Ends a hand-drawn stroke. + exports.erase = E.erase; + exports.noErase = E.noErase; + // HATCHING Operations exports.hatchArray = H.hatch; // Function to create hatched patterns within polygons. exports.hatch = hatch; diff --git a/p5.brush.min.js b/p5.brush.min.js index e178e72..d628384 100644 --- a/p5.brush.min.js +++ b/p5.brush.min.js @@ -1,2 +1,2 @@ /* p5.brush.js v1.0.5 - Alejandro Campos - MIT License */ -eval(function(p,a,c,k,e,r){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(1k(m,N){"6x"===3m 4h&&"4i"!==3m 6y?N(4h):"1k"===3m 4j&&4j.6z?4j(["4h"],N):(m=m||5p,N(m.3F={}))})(j,1k(m){1k N(a=!1,b=!1){Q&&Z(!1);h=a?a:6A.5p;Q||(Q=!0,u.5q(),aa(h.1z/5r));r.2Z(b)}1k Z(a=!0){Q&&(r.1d.3G(),r.1d=2p,r.2u.3G(),r.2u=2p,r.2f.3G(),r.2f=2p,a&&3F.2Z())}1k E(){Q||N()}1k ba(a,b,c,d,f=!1){1a g=a.x;a=a.y;1q l=b.x,n=b.y;b=c.x;c=c.y;1q q=d.x,t=d.y;1n(g===l&&a===n||b===q&&c===t)1c!1;d=l-g;l=n-a;n=q-b;t-=c;q=t*d-n*l;1n(0===q)1c!1;n=(n*(a-c)-t*(g-b))/q;b=(d*(a-c)-l*(g-b))/q;1c!f&&(0>b||13a.1l?3>3a.1l?b:1:d;v.1P=3>3a.1l?h.1P(a):h.1P(a,b,c);v.1i=!0}1k 4v(a,b="2m"){v.2j=e.2k(a,0,.6);v.5u=b}1k 4w(a=.4,b=.4){v.2I=e.2k(a,0,1);v.2J=e.2k(b,0,1)}1a h,Q=!1;2x.3p.3q("4x",()=>E());1x e={2y:()=>h.1g(),1g(a=0,b=1){1c 1===3a.1l?j.1D(j.2y(),0,1,0,a):j.1D(j.2y(),0,1,a,b)},1E(a,b){1c 1f.1K(j.1g(a,b))},2r(a=0,b=1){1x c=1-e.1g(),d=e.1g();1c 1f.3J(-2*1f.6D(c))*1f.1y(2*1f.2g*d)*b+a},6E(a){1a b,c,d=[];1j(b 6F a)1j(c=0;c<10*a[b];c++)d.1s(b);1c d[1f.1K(j.2y()*d.1l)]},1D(a,b,c,d,f,g=!1){a=d+(a-b)/(c-b)*(f-d);1c g?db;b++){1x c=b*a;e.c[b]=1f.1y(c);e.s[b]=1f.1w(c)}j.4y=!0}},6G:a=>!6H(a),2Q:a=>(("5w"===h.2z()?1X*a/1f.2g:a)%1u+1u)%1u};e.5v();1x w={2v:{},1M:{},1A:{},1o:{},4k:{}},y={2A:[0,0],39:0,1J(a=0){y.39=e.2Q(a)},1F(){1c j.2A=[h.4A.5x.4B[12],h.4A.5x.4B[13]]}};1q W=1;1q 5y=a=>W*=a;1x r={4C:!1,2R:!1,4D:!0,2a:1v 3L(3),2Z(a){j.1d=a?h.3b(h.1z,h.1G):3b(h.1z,h.1G);j.1d.3c(h.3c());j.1d.3r();j.1d.5z();j.1d.2z(h.4E);m.1d=j.1d;r.4C||(j.3M=j.3M.6I(\'#5A "5B.3N"\',j.3N()));j.2C=h.6J(j.5C,j.3M);r.4C=!0;j.2f=a?h.3b(h.1z,h.1G):3b(h.1z,h.1G);j.2f.3c(h.3c());j.2f.5z();j.2f.3r();j.2f.2z(h.4E);j.2u=a?h.3b(h.1z,h.1G,h.5D):3b(h.1z,h.1G,h.5D);j.2u.3c(h.3c());j.2u.3r();j.2u.2z(h.4E)},3O(a){a=a.6K;1a b=1v 3L(3);b[0]=a[0]/2n;b[1]=a[1]/2n;b[2]=a[2]/2n;1c b},3s(){h.1s();h.3d(-y.1F()[0],-y.1F()[1]);h.1T(r.2f,-h.1z/2,-h.1G/2);r.2f.3r();h.2P()},4F(){ca();k.1R("3e","6L",1);k.2S(-10,-10,-5,-5);da()},3P:1v 3L(3),3Q:1v 3L(3),3R:!1,3S:!1,1I(a=!1,b=!1,c=!1,d=!1){j.2R=c?j.3R:j.3S;j.2a=c?j.3P:j.3Q;1n(!j.2R)1n(a)j.2a=j.3O(a),c?(j.3R=!0,j.3P=j.2a):(j.3S=!0,j.3Q=j.2a);2w 1n(b){c||j.3s();1c}1n((a?j.3O(a):j.2a).5E()!==j.2a.5E()||b||!j.4D)j.3s(),j.2R&&(h.1s(),h.3d(-y.1F()[0],-y.1F()[1]),h.2C(j.2C),j.2C.3t("3T",j.2a),j.2C.3t("2y",h.4A),j.2C.3t("4G",d),j.2C.3t("1g",[e.1g(),e.1g(),e.1g()]),d=c?j.2u:j.1d,j.2C.3t("1d",d),h.1o(0,0,0,0),h.3u(),h.3U(-h.1z/2,-h.1G/2,h.1z,h.1G),h.2P(),d.3r()),b||(j.2a=j.3O(a),c?j.3P=j.2a:j.3Q=j.2a);b&&(j.2R=!1,c?j.3R=j.2R:j.3S=j.2R)},5C:"5F 5G 1m;5H 1b 5I;5H 1p 5J;3v 4B 5K,5L;5M 1p 1U;3V 5N(){6M=5L*5K*1L(5I,1);1U=5J;}",3M:\'5F 5G 1m;5M 1p 1U;3v 6N 2y,1d;3v 1L 3T;3v 1b 1g;3v 6O 4G;\\n #5A "5B.3N"\\n 1m v(1p v,1p x,1m y,2m 1p i){1p a=1p(v.x+v.y*.5,v.y),m=1K(a),d=5O(a);1m z=6P(d.y,d.x);1p r=1p(z,1.-z),f=m+r,e=m+1.,s=1p(m.x-m.y*.5,m.y),k=1p(s.x+r.x-r.y*.5,s.y+r.y),l=1p(s.x+.5,s.y+1.),g=v-s,o=v-k,t=v-l;1b u,c,C,D;1n(6Q(6R(x,1p(0)))){C=1b(s.x,k.x,l);D=1b(s.y,k.y,l.y);1n(x.x>0.)C=3w(1b(s.x,k.x,l),x.x);1n(x.y>0.)D=3w(1b(s.y,k.y,l.y),x.y);u=1K(C+.5*D+.5);c=1K(D+.5);}2w u=1b(m.x,f.x,e),c=1b(m.y,f.y,e.y);1b b=3w(u,4H.);b=3w((b*51.+2.)*b+c,4H.);b=3w((b*34.+10.)*b,4H.);1b h=b*.6S+y,E=1y(h),w=1w(h);1p A=1p(E.x,w),B=1p(E.y,w.y),F=1p(E.z,w.z);1b G=.8-1b(1V(g,g),1V(o,o),1V(t,t));G=1h(G,0.);1b H=G*G,I=H*H,J=1b(1V(A,g),1V(B,o),1V(F,t)),K=H*G,L=-8.*K*J;i=10.9*(I.x*A+L.x*g+(I.y*B+L.y*o)+(I.z*F+L.z*t));1c 10.9*1V(I,J);}1L v(1b v,1m f){1c 1L(5P(v,1b(1V(1b(.6T,.6U,.6V),v)),f),1);}1m f(1p v,1m x,1m y,1m f){1c 5O(1w(1V(v,1p(x,y)))*f);}3V 5N(){1L s=5Q(1d,1U);1n(s.x>0.){1p m=1p(12.4I,78.4J),k=1p(7.4I,58.4J),d=1p(17.4I,3.4J);1m x=f(1U,m.x,m.y,6W.4K)*2.-1.,y=f(1U,k.x,k.y,6X.4K)*2.-1.,l=f(1U,d.x,d.y,6Y.4K)*2.-1.;1x 1p z=1p(0);1p o;1L b;1n(4G){1m a=v(1U*5.,z,10.*1g.x,o),c=v(1U*5.,z,10.*1g.y,o),t=v(1U*5.,z,10.*1g.z,o),w=.25+.25*v(1U*4.,z,3.*1g.x,o);b=1L(v(3T.2T,w).2T+1b(a,c,t)*.3W,1);}2w b=1L(3T.2T,1);1n(s.w>.7){1m r=.5*(s.w-.7);b=b*(1.-r)-1L(.5)*r;}1b a=3X(5Q(2y,1U).2T,b.2T,.9*s.w);6Z=1L(a+.4L*1b(x,y,l),1);}}\',3N(){1c"1m 3Y(1m s){1c s<.70?s/12.92:2o((s+.3Z)/1.3Z,2.4);}1m 41(1m s){1c s<.71?s*12.92:1.3Z*2o(s,1./2.4)-.3Z;}1b 4M(1b s){1c 1b(3Y(s[0]),3Y(s[1]),3Y(s[2]));}1b 5R(1b s){1c 72(1b(41(s[0]),41(s[1]),41(s[2])),0.,1.);}3V 5S(1b e,2m 1m m,2m 1m s,2m 1m f,2m 1m r,2m 1m x,2m 1m v,2m 1m z){m=1C(e.x,1C(e.y,e.z));e-=m;s=1C(e.y,e.z);f=1C(e.x,e.z);r=1C(e.x,e.y);x=1C(1h(0.,e.x-e.z),1h(0.,e.x-e.y));v=1C(1h(0.,e.y-e.z),1h(0.,e.y-e.x));z=1C(1h(0.,e.z-e.y),1h(0.,e.z-e.x));}3V 4N(1b s,73 1m f[38]){1m e,o,m,x,v,w,z;5S(s,e,o,m,x,v,w,z);f[0]=1h(1e-4,e+o*.74+m*.76+x*.77+v*.79+w*.7a+z*.7b);f[1]=1h(1e-4,e+o*.7c+m*.7d+x*.7e+v*.7f+w*.7g+z*.7h);f[2]=1h(1e-4,e+o*.7i+m*.7j+x*.7k+v*.7l+w*.7m+z*.7n);f[3]=1h(1e-4,e+o*.7o+m*.7p+x*.7q+v*.7r+w*.7s+z*.7t);f[4]=1h(1e-4,e+o*.7u+m*.7v+x*.7w+v*.7x+w*.7y+z*.7z);f[5]=1h(1e-4,e+o*.7A+m*.7B+x*.7C+v*.7D+w*.7E+z*.7F);f[6]=1h(1e-4,e+o*.7G+m*.7H+x*.7I+v*.7J+w*.7K+z*.7L);f[7]=1h(1e-4,e+o*.7M+m*.7N+x*.7O+v*.7P+w*.7Q+z*.7R);f[8]=1h(1e-4,e+o*.7S+m*.7T+x*.7U+v*.7V+w*.7W+z*.7X);f[9]=1h(1e-4,e+o*.7Y+m*.7Z+x*.81+v*.82+w*.83+z*.84);f[10]=1h(1e-4,e+o*.86+m*.87+x*.88+v*.89+w*.8a+z*.8b);f[11]=1h(1e-4,e+o*.8c+m*.8d+x*.8e+v*.8f+w*.8g+z*.8h);f[12]=1h(1e-4,e+o*.8i+m*.8j+x*.8k+v*.8l+w*.8m+z*.8n);f[13]=1h(1e-4,e+o*.8o+m*.8p+x*.8q+v*.8r+w*.8s+z*.8t);f[14]=1h(1e-4,e+o*.8u+m*.8v+x*.8w+v*.8x+w*.8y+z*.8z);f[15]=1h(1e-4,e+o*.8A+m*.8B+x*.8C+v*.8D+w*.8E+z*.8F);f[16]=1h(1e-4,e+o*.8G+m*.8H+x*.8I+v*.8J+w*.8K+z*.8L);f[17]=1h(1e-4,e+o*.8M+m*.8N+x*.8O+v*.8P+w*.8Q+z*.8R);f[18]=1h(1e-4,e+o*.8S+m*.8T+x*.8U+v*.8V+w*.8W+z*.8X);f[19]=1h(1e-4,e+o*.8Y+m*.8Z+x*.91+v*.93+w*.94+z*.96);f[20]=1h(1e-4,e+o*.97+m*8.98-5+x*.99+v*.9a+w*.9b+z*.9c);f[21]=1h(1e-4,e+o*.9d+m*.9e+x*.9f+v*.9g+w*.9h+z*.9i);f[22]=1h(1e-4,e+o*.9j+m*.9k+x*.9l+v*.9m+w*.9n+z*.9o);f[23]=1h(1e-4,e+o*.9p+m*.9q+x*.9r+v*.9s+w*.9t+z*.9u);f[24]=1h(1e-4,e+o*.9v+m*.9w+x*.9x+v*.9y+w*.9z+z*.9A);f[25]=1h(1e-4,e+o*.9B+m*.9C+x*.9D+v*.9E+w*.9F+z*.9G);f[26]=1h(1e-4,e+o*.9H+m*.9I+x*.9J+v*.9K+w*.9L+z*.9M);f[27]=1h(1e-4,e+o*.9N+m*.9O+x*.9P+v*.9Q+w*.9R+z*.9S);f[28]=1h(1e-4,e+o*.9T+m*.9U+x*.9V+v*.9W+w*.9X+z*.9Y);f[29]=1h(1e-4,e+o*.9Z+m*.a0+x*.a1+v*.a2+w*.a3+z*.a4);f[30]=1h(1e-4,e+o*.a5+m*.a6+x*.a7+v*.a8+w*.a9+z*.ab);f[31]=1h(1e-4,e+o*.ac+m*.ad+x*.ae+v*.af+w*.ag+z*.ah);f[32]=1h(1e-4,e+o*.ai+m*.aj+x*.ak+v*.al+w*.am+z*.an);f[33]=1h(1e-4,e+o*.ao+m*.ap+x*.aq+v*.ar+w*.as+z*.at);f[34]=1h(1e-4,e+o*.au+m*.av+x*.aw+v*.ax+w*.ay+z*.az);f[35]=1h(1e-4,e+o*.aA+m*.aB+x*.aC+v*.aD+w*.aE+z*.aF);f[36]=1h(1e-4,e+o*.aG+m*.aH+x*.aI+v*.aJ+w*.aK+z*.aL);f[37]=1h(1e-4,e+o*.aM+m*.aN+x*.aO+v*.aP+w*.aQ+z*.aR);}1b 5T(1b e){aS f;f[0]=1b(3.aT,-1.aU,-.aV);f[1]=1b(-.aW,1.aX,.aY);f[2]=1b(.aZ,-.b0,1.b1);1m s=1V(f[0],e),m=1V(f[1],e),z=1V(f[2],e);1c 5R(1b(s,m,z));}1b 42(1m f[38]){1b e=1b(0);e+=f[0]*1b(6.b2-5,1.b3-6,.b4);e+=f[1]*1b(.b5,6.b6-6,.b7);e+=f[2]*1b(.b8,3.b9-5,.bb);e+=f[3]*1b(.bc,.bd,.be);e+=f[4]*1b(.bf,.bg,.bh);e+=f[5]*1b(.bi,.bj,.bk);e+=f[6]*1b(.bl,.bm,.bn);e+=f[7]*1b(.bo,.bp,.bq);e+=f[8]*1b(.br,.bs,.bt);e+=f[9]*1b(.bu,.bv,.bw);e+=f[10]*1b(.bx,.by,.bz);e+=f[11]*1b(.bA,.bB,.bC);e+=f[12]*1b(.bD,.bE,.bF);e+=f[13]*1b(.bG,.bH,.bI);e+=f[14]*1b(.bJ,.bK,.bL);e+=f[15]*1b(.bM,.bN,.bO);e+=f[16]*1b(.bP,.bQ,.bR);e+=f[17]*1b(.bS,.bT,.bU);e+=f[18]*1b(.bV,.bW,.bX);e+=f[19]*1b(.bY,.bZ,.c0);e+=f[20]*1b(.c1,.c2,.c3);e+=f[21]*1b(.c4,.c5,9.c6-5);e+=f[22]*1b(.c7,.c8,6.c9-5);e+=f[23]*1b(.cb,.cc,2.cd-5);e+=f[24]*1b(.ce,.cf,1.cg-5);e+=f[25]*1b(.ch,.ci,3.cj-6);e+=f[26]*1b(.ck,.cl,1.cm-6);e+=f[27]*1b(.cn,.co,0);e+=f[28]*1b(.cq,.cs,0);e+=f[29]*1b(.ct,.cu,0);e+=f[30]*1b(.cv,.cw,0);e+=f[31]*1b(.cx,.cy,0);e+=f[32]*1b(.cz,.cA,0);e+=f[33]*1b(.cB,.cC,0);e+=f[34]*1b(.cD,6.cE-5,0);e+=f[35]*1b(9.cF-5,3.cG-5,0);e+=f[36]*1b(4.cH-5,1.cI-5,0);e+=f[37]*1b(2e-5,7.cJ-6,0);1c e;}1m 5U(1m v,1m m,1m s){1m z=m*2o(s,2.);1c z/(v*2o(1.-s,2.)+z);}1b 3X(1b s,1b f,1m e){1b v=4M(s),m=4M(f);1m z[38],o[38];4N(v,z);4N(m,o);1m x=42(z)[1],w=42(o)[1];e=5U(x,w,e);1m r[38];1j(cK c=0;c<38;c++){1m y=(1.-e)*(2o(1.-z[c],2.)/(2.*z[c]))+e*(2o(1.-o[c],2.)/(2.*o[c]));r[c]=1.+y-3J(2o(y,2.)+2.*y);}1c 5T(42(r));}1L 3X(1L s,1L e,1m z){1c 1L(3X(s.2T,e.2T,z),5P(s.w,e.w,z));}"}};2x.3p.3q("4x",()=>r.1I(!1,!0));2x.3p.3q("4x",()=>r.1I(!1,!0,!0));2x.3p.3q("5V",()=>r.1I(!1,!0));2x.3p.3q("5V",()=>r.1I(!1,!0,!0));1x u={1i:!1,1Q:1v 4O,2h:"",5W(){1c 1f.1C(h.1z,h.1G)/cL},5q(){j.R=.4L*h.1z;j.5X=-1*h.1z;j.5Y=-1*h.1G;j.2s=1f.2D(2*h.1z/j.R);j.2E=1f.2D(2*h.1G/j.R);j.5Z()},60(){1c j.1Q.2K(j.2h).2v},4l(a=0){j.1Q.2K(j.2h).2v=j.1Q.2K(j.2h).5s(a,j.61())},61(){1a a=43(j.2s);1j(1a b=0;b=-a-y.1F()[0]&&j.x<=a-y.1F()[0]&&j.y>=-b-y.1F()[1]&&j.y<=b-y.1F()[1]}2U(){1c j.4c()&&u.1i?u.60()[j.4a][j.4b]:0}67(a,b,c=u.5W(),d=!0){1n(j.4c()){1a g;1n(!d){g=e.1y(-b);1q f=e.1w(-b)}1j(1a l=0;l{1x c="3e"===b.1r||"2F"===b.1r||"1T"===b.1r;c||"3f"===b.1r||(b.1r="4d");"1T"===b.1r&&(V.2V(b.1T.69),b.3g=()=>k.1d.1T(V.3y.2K(k.p.1T.69),-k.p.1Y/2,-k.p.1Y/2,k.p.1Y,k.p.1Y));b.1I=c&&!1!==b.1I||b.1I?!0:!1;k.1Q.1R(a,{3H:b,cT:[],cU:[]})},1R(a,b,c=1){k.4S(a);k.c=b;k.w=c;k.1i=!0},4S(a){k.2G=a},6a(a,b,c){0<3a.1l&&(k.c=2>3a.1l?a:[a,b,c]);k.1i=!0},6b(a){k.w=a},3n(a){k.cr=a},4T(){k.cr=2p},2S(a,b,c,d){E();1a f=h.2O(a,b,c,d);0!=f&&(k.4e(a,b,f,!1,!1),a=T(a,b,c,d),k.1S(a,!1))},4U(a,b,c,d){E();k.4e(a,b,c,!0,!1);k.1S(e.2Q(d),!1)},4V(a,b,c,d){E();k.4e(b,c,a.1l,!0,a);k.1S(d,!0)},2M(){j.p=j.1Q.2K(j.2G).3H;1c"4d"===j.p.1r||"3f"===j.p.1r?j.p.2M/j.w:j.p.2M},4e(a,b,c,d,f){j.1t=1v X(a,b);j.1l=c;j.4W=d;(j.2W=f)&&f.3z(0)},1S(a,b){b||(j.2t=a);j.4X();1x c=j.2M(),d=b?1f.2D(j.1l*a/c):1f.2D(j.1l/c);1j(1a f=0;f=k.cr[0]&&j.1t.x<=k.cr[2]&&j.1t.y>=k.cr[1]&&j.1t.y<=k.cr[3];1a a=.55*h.1z,b=.55*h.1G;1c j.1t.x>=-a-y.1F()[0]&&j.1t.x<=a-y.1F()[0]&&j.1t.y>=-b-y.1F()[1]&&j.1t.y<=b-y.1F()[1]},6d(a){1a b=j.w*j.p.2L*a+j.w*e.2r()*j.p.2L/3,c=j.p.1Y*e.1g(.9,1.1);a=j.p.5c/a;1j(1a d=0;da;a++)j.57(b*a/5,!1);2w 1n("2F"===k.p.1r||"1T"===k.p.1r)1j(1a c=1;5>c;c++)j.59(b*c/5,a,!1)}}},V={3y:1v 4O,2V(a){j.3y.1R(a,!1)},6i(a){a.d1();1j(1a b=0;b<4*a.1z*a.1G;b+=4){1a c=(a.2X[b]+a.2X[b+1]+a.2X[b+2])/3;a.2X[b]=a.2X[b+1]=a.2X[b+2]=2n;a.2X[b+3]=2n-c}a.d2()},2Z(){1j(1a a 1N j.3y.5e()){1a b=d3(a,()=>V.6i(b));j.3y.1R(a,b)}}},z={1i:!1,2q:[5,45,{}],1Z:!1,1A(a){1a b=z.2q[0],c=z.2q[1],d=z.2q[2],f=k.c,g=k.2G,l=k.w,n=k.1i;z.1Z&&k.1R(z.1Z[0],z.1Z[1],z.1Z[2]);c=e.2Q(c)%1X;1a q=3B,t=-3B,x=3B,A=-3B;1q p=K=>{1j(1a H 1N K.a)q=H[0]t?H[0]:t,x=H[1]A?H[1]:A};43.d4(a)||(a=[a]);1j(1q D 1N a)p(D);D=1v P([[q,x],[t,x],[t,A],[q,A]]);1a I=90>=c&&0<=c?x:A;1q B=d.4q?e.1D(d.4q,0,1,1,1.1,!0):1;p=[];1a L=0,C=b,G=K=>({3C:{x:q+C*K*e.1y(-c+90),y:I+C*K*e.1w(-c+90)},3D:{x:q+C*K*e.1y(-c+90)+e.1y(-c),y:I+C*K*e.1w(-c+90)+e.1w(-c)}});1j(;0H.x===Y.x?H.y-Y.y:H.x-Y.x);C*=B;L++}a=[];1j(1q M 1N p)"4i"!==3m M[0]&&a.1s(M);M=d.4p?d.4p:0;1j(J=0;J({x:c[0],y:c[1]}));b&&(j.5f=a);j.5g=j.5f.1D((c,d,f)=>[c,f[(d+1)%f.1l]])}4g(a){1a b=`${a.3C.x},${a.3C.y}-${a.3D.x},${a.3D.y}`;1n(j.3h&&j.3h[b])1c j.3h[b];1a c=[];1j(1a d 1N j.5g){1a f=ba(a.3C,a.3D,d[0],d[1]);!1!==f&&c.1s(f)}j.3h||(j.3h={});1c j.3h[b]=c}1S(a=!1,b,c){1a d=k.1i;a&&k.1R(a,b,c);1n(k.1i){E();1j(1a f 1N j.5g)k.2S(f[0].x,f[0].y,f[1].x,f[1].y)}k.1i=d}1o(a=!1,b,c,d,f,g){1a l=v.1i;a&&(4u(a,b),4v(c,g),4w(d,f));v.1i&&(E(),v.1o(j));v.1i=l}1A(a=!1,b,c){1a d=z.1i;a&&4o(a,b,c);z.1i&&(E(),z.1A(j));z.1i=d}}47 U{48(a){j.2N=[];j.2d=[];j.3i=[];j.1r=a;j.2t=0;j.3z(0);j.3j=!1}1O(a=0,b=0,c=1,d=!1){0f+g,0);j.2d.1s(a)}3o(a=0,b=1,c=!1){a=c?(a%1u+1u)%1u:e.2Q(a);j.2d.6j(-1);j.2d.1s(a);j.3i.1s(b)}1J(a){j.2t=e.2Q(a)}2c(a){1c a>j.1l?j.3i[j.3i.1l-1]:j.5h(j.3i,a)}2U(a){1n(a>j.1l)1c j.2d[j.2d.1l-1];j.3z(a);1c"1B"===j.1r?j.5h(j.2d,a)+j.2t:j.2d[j.2Y]+j.2t}5h(a,b){1a c=a[j.2Y];a=a[j.2Y+1];"4i"==3m a&&(a=c);1X<1f.4Q(a-c)&&(a>c?a=-(1u-a):c=-(1u-c));1c e.1D(b-j.5i,0,j.2N[j.2Y],c,a,!0)}3z(a){j.2Y=-1;1a b=j.5i=0;1j(;b<=a;)j.5i=b,b+=j.2N[j.2Y+1],j.2Y++}5j(a,b,c=1,d=!1){E();1q f=0,g=d8;1j(1q l 1N j.2N)l*=c,0!==l&&(f=1f.1h(f,l),g=1f.1C(g,l));c=k.2M();l=[];1q n=e.2k(v.2j,.d9,1);d=(f+g)*(d?.3W:v.5k?.25:n);a=1v X(a,b);b=1f.2D(j.1l/c);g=f=0;n=d*e.1g(.7,1.3);1j(1a q=0;q=n&&a.x&&(l[g]=[a.x,a.y],n=d*e.1g(.7,1.3),g++,f=0);j.3z(0);1c 1v P(l)}1S(a,b,c){k.1i&&(E(),j.2l&&(a=j.2l[0],b=j.2l[1],c=1),k.4V(j,a,b,c))}1o(a,b,c){v.1i&&(E(),j.2l&&(a=j.2l[0],b=j.2l[1],c=1),j.3j=j.5j(a,b,c),j.3j.1o())}1A(a,b,c){z.1i&&(E(),j.2l&&(a=j.2l[0],b=j.2l[1],c=1),j.3j=j.5j(a,b,c,!0),j.3j.1A())}}1a F=!1,R;1x v={1i:!1,5k:!1,1P:"#db",2i:80,2j:.dc,2I:.4,2J:.4,1o(a){j.5l=a;j.v=a.a.1D(c=>h.6k(c[0],c[1]));1x b=j.v.1l*e.1g(.4);v.m=j.v.1D((c,d)=>{c=e.1g(.8,1.2)*j.2j;1c dj.3l&&(j.3l=a);1n(f)1j(f="5w"===h.2z()?1f.2g/1X:1,g=0;g{1x D=e.2r(.5,.1);1c p+.1*(D-.5)};1a q=1v 2x.5n;1j(1a p=0;p=v.2j?.25:.75:j.m[p];I*=b;c.1s(t);d.1s(n(I));1q x=D.x-t.x,A=D.y-t.y;1a B=1f.3J(x*x+A*A);q.1R(x,A).dh();x=j.2t[p];A="2m"==v.5u?90:-90;A=(x?A:-A)+45*e.2r(0,.4);q.1J(A*1f.2g/1X);q.di(e.2r(.5,.2)*e.1g(.6,1.4)*B*I);t=2x.5n.dj(t,D,e.2k(e.2r(.5,.2),.1,.9));t.2V(q);c.1s(t);d.1s(n(I));f.1s(x,x)}h.2z(l);1c 1v 5m(c,d,j.3k,f)}1o(a,b,c){1a d=e.1D(v.2j,0,.15,.6,1,!0);1x f=24*d,g=b/5+c*b/6,l=b/4+c*b/3,n=b/7+c*b/3,q=b/5;c*=3;y.1F();r.1I(a,!1,!1,!0);r.1d.1s();r.1d.3u();r.1d.3d(y.2A[0]+h.1z/2,y.2A[1]+h.1G/2);r.1d.1J(y.39);r.1d.3x(W);a=j.1H();1a t=a.1H().1H(.9),x=t.1H(.75),A=j.1H(.6);1j(1a p=0;p35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(1k(m,P){"6D"===3b 4m&&"3F"!==3b 6E?P(4m):"1k"===3b 4n&&4n.6F?4n(["4m"],P):(m=m||5v,P(m.3G={}))})(j,1k(m){1k P(a=!1){1a b=U&&a?Y:!1;S&&ca(!1);!a&&U&&(a=Y);k=a?a:6G.5v;S||(S=!0,u.5w(),da(k.1x/5x));n.3c(b)}1k ca(a=!0){S&&(n.1g[0].3H(),n.1g[0]=2q,n.1g[1].3H(),n.1g[1]=2q,n.1g[2].3H(),n.1g[2]=2q,a&&3G.3c())}1k E(){S||P()}1k 4o(a,b,c,d,f=!1){1a g=a.x;a=a.y;1t l=b.x,p=b.y;b=c.x;c=c.y;1t q=d.x,t=d.y;1n(g===l&&a===p||b===q&&c===t)1c!1;d=l-g;l=p-a;p=q-b;t-=c;q=t*d-p*l;1n(0===q)1c!1;p=(p*(a-c)-t*(g-b))/q;b=(d*(a-c)-l*(g-b))/q;1c!f&&(0>b||1n.1J(!1,!0));a.3I("5y",()=>n.1J(!1,!0,!0));a.3I("5z",()=>n.1J(!1,!0));a.3I("5z",()=>n.1J(!1,!0,!0))}1k Q(a,b){E();u.1S.1T(a,{5A:b});u.2k=a;u.4t()}1k da(a){1j(1a b 1K 4u){1a c=h.1S.2N(b[0]).3J;c.2b*=a;c.2O*=a;c.2P*=a}4v=a}1k 4w(a=5,b=45,c={4x:!1,5B:!1,4y:!1}){z.1f=!0;z.2r=[a,b,c]}1k 4z(a=0){R=e.2n(a,0,1);F=[]}1k T(a,b,c){F.1q([a,b,c])}1k 4A(a){a===k.3e&&(F.1q(F[0]),F.1q(F[1]));a=0!=R||u.1f?4B(F,R,a===k.3e?!0:!1):1w O(F);1n(v.1f||z.1f)a.1o(),a.1B();h.1f&&a.1U();H.1f&&a.2d();F=!1}1k 4B(a,b=.5,c=!1){1a d=1w W(0===b?"2Q":"1D");1n(a&&03f.1l?3>3f.1l?b:1:d;v.1N=3>3f.1l?k.1N(a):k.1N(a,b,c);v.1f=!0}1k 4D(a,b="2o"){E();v.2m=e.2n(a,0,.6);v.5D=b}1k 4E(a=.4,b=.4){E();v.2L=e.2n(a,0,1);v.2M=e.2n(b,0,1)}1a k,S=!1,U=!1,Y=!1;1y e={2A:()=>k.1h(),1h(a=0,b=1){1c 1===3f.1l?j.1F(j.2A(),0,1,0,a):j.1F(j.2A(),0,1,a,b)},1G(a,b){1c 1d.1M(j.1h(a,b))},2t(a=0,b=1){1y c=1-e.1h(),d=e.1h();1c 1d.3K(-2*1d.6J(c))*1d.1C(2*1d.2j*d)*b+a},6K(a){1a b,c,d=[];1j(b 6L a)1j(c=0;c<10*a[b];c++)d.1q(b);1c d[1d.1M(j.2A()*d.1l)]},1F(a,b,c,d,f,g=!1){a=d+(a-b)/(c-b)*(f-d);1c g?db;b++){1y c=b*a;e.c[b]=1d.1C(c);e.s[b]=1d.1z(c)}j.4F=!0}},6M:a=>!5C(a),2R:a=>(("5F"===k.3g()?2a*a/1d.2j:a)%1v+1v)%1v,2y:(a,b,c,d)=>1d.6N(c-a,d-b)};e.5E();1y w={2x:{},1P:{},1B:{},1o:{},4q:{}},y={2C:[0,0],3d:0,1L(a=0){y.3d=e.2R(a)},1H(){1c j.2C=[k.4H.5G.4I[12],k.4H.5G.4I[13]]}};1t Z=1;1t 5H=a=>Z*=a;1y n={4J:!1,2S:!1,4K:!0,2f:1w 3M(3),3c(a){j.1r=U&&!a?0:a?2:1;j.1g=[];5I(j.1r){2T 0:j.1g[0]=k.2u(k.1x,k.1A);j.1g[1]=k.2u(k.1x,k.1A,k.4L);j.1g[2]=k.2u(k.1x,k.1A);3s;2T 1:j.1g[0]=2u(k.1x,k.1A);j.1g[1]=2u(k.1x,k.1A,4L);j.1g[2]=2u(k.1x,k.1A);3s;2T 2:j.1g[0]=a.2u(a.1x,a.1A),j.1g[1]=a.2u(a.1x,a.1A,a.4L),j.1g[2]=a.2u(a.1x,a.1A)}1j(1a b 1K j.1g)b.5J(k.5J()),b.4M(),b.3g(k.6O),b.6P();n.4J||(j.3N=j.3N.6Q(\'#5K "5L.3O"\',j.3O()));j.2D=k.6R(j.5M,j.3N);n.4J=!0},3P(a){a=a.6S;1a b=1w 3M(3);b[0]=a[0]/2g;b[1]=a[1]/2g;b[2]=a[2]/2g;1c b},3t(){k.1q();k.3h(-y.1H()[0],-y.1H()[1]);k.1V(n.1g[2],-k.1x/2,-k.1A/2);n.1g[2].4M();k.2s()},4N(){4p();h.1T("3i","5N",1);h.2U(-10,-10,-5,-5);4r()},3Q:1w 3M(3),3R:1w 3M(3),3S:!1,3T:!1,1J(a=!1,b=!1,c=!1){j.2S=c?j.3S:j.3T;j.2f=c?j.3Q:j.3R;1n(!j.2S)1n(a)j.2f=j.3P(a),c?(j.3S=!0,j.3Q=j.2f):(j.3T=!0,j.3R=j.2f);2z 1n(b){c||j.3t();1c}1n((a?j.3P(a):j.2f).5O()!==j.2f.5O()||b||!j.4K){j.3t();1n(j.2S){k.1q();k.3h(-y.1H()[0],-y.1H()[1]);k.2D(j.2D);j.2D.3u("2V",j.2f);j.2D.3u("2A",k.4H);j.2D.3u("4O",n.4P);j.2D.3u("1h",[e.1h(),e.1h(),e.1h()]);1a d=c?j.1g[1]:j.1g[0];j.2D.3u("1p",d);k.1o(0,0,0,0);k.2W();k.3U(-k.1x/2,-k.1A/2,k.1x,k.1A);k.2s();d.4M()}b||(j.2f=j.3P(a),c?j.3Q=j.2f:j.3R=j.2f)}b&&(j.2S=!1,c?j.3S=j.2S:j.3T=j.2S)},5M:"5P 5Q 1m;5R 1b 5S;5R 1s 5T;3v 4I 5U,5V;5W 1s 1W;3V 5X(){6T=5V*5U*1O(5S,1);1W=5T;}",3N:\'5P 5Q 1m;5W 1s 1W;3v 6U 2A,1p;3v 1O 2V;3v 1b 1h;3v 6V 4O;\\n #5K "5L.3O"\\n 1m v(1s v,1s x,1m y,2o 1s i){1s a=1s(v.x+v.y*.5,v.y),m=1M(a),d=5Y(a);1m z=6W(d.y,d.x);1s r=1s(z,1.-z),f=m+r,e=m+1.,s=1s(m.x-m.y*.5,m.y),k=1s(s.x+r.x-r.y*.5,s.y+r.y),l=1s(s.x+.5,s.y+1.),g=v-s,o=v-k,t=v-l;1b u,c,C,D;1n(6X(6Y(x,1s(0)))){C=1b(s.x,k.x,l);D=1b(s.y,k.y,l.y);1n(x.x>0.)C=3w(1b(s.x,k.x,l),x.x);1n(x.y>0.)D=3w(1b(s.y,k.y,l.y),x.y);u=1M(C+.5*D+.5);c=1M(D+.5);}2z u=1b(m.x,f.x,e),c=1b(m.y,f.y,e.y);1b b=3w(u,4Q.);b=3w((b*51.+2.)*b+c,4Q.);b=3w((b*34.+10.)*b,4Q.);1b h=b*.6Z+y,E=1C(h),w=1z(h);1s A=1s(E.x,w),B=1s(E.y,w.y),F=1s(E.z,w.z);1b G=.8-1b(1X(g,g),1X(o,o),1X(t,t));G=1i(G,0.);1b H=G*G,I=H*H,J=1b(1X(A,g),1X(B,o),1X(F,t)),K=H*G,L=-8.*K*J;i=10.9*(I.x*A+L.x*g+(I.y*B+L.y*o)+(I.z*F+L.z*t));1c 10.9*1X(I,J);}1O v(1b v,1m f){1c 1O(5Z(v,1b(1X(1b(.70,.71,.72),v)),f),1);}1m f(1s v,1m x,1m y,1m a){1c 5Y(1z(1X(v,1s(x,y)))*a);}3V 5X(){1O s=60(1p,1W);1n(s.x>0.){1s m=1s(12.4R,78.4S),k=1s(7.4R,58.4S),r=1s(17.4R,3.4S);1m x=f(1W,m.x,m.y,73.4T)*2.-1.,y=f(1W,k.x,k.y,74.4T)*2.-1.,d=f(1W,r.x,r.y,76.4T)*2.-1.;1y 1s z=1s(0);1s a;1O b;1n(4O){1m u=v(1W*5.,z,10.*1h.x,a),c=v(1W*5.,z,10.*1h.y,a),l=v(1W*5.,z,10.*1h.z,a),o=.25+.25*v(1W*4.,z,3.*1h.x,a);b=1O(v(2V.2X,o).2X+1b(u,c,l)*.3W*3X(2V.x-2V.y-2V.z),1);}2z b=1O(2V.2X,1);1n(s.w>.7){1m l=.5*(s.w-.7);b=b*(1.-l)-1O(.5)*l;}1b u=3Y(60(2A,1W).2X,b.2X,.9*s.w);77=1O(u+.4U*1b(x,y,d),1);}}\',3O(){1c"1m 3Z(1m s){1c s<.79?s/12.92:2p((s+.41)/1.41,2.4);}1m 42(1m s){1c s<.7a?s*12.92:1.41*2p(s,1./2.4)-.41;}1b 4V(1b s){1c 1b(3Z(s[0]),3Z(s[1]),3Z(s[2]));}1b 61(1b s){1c 7b(1b(42(s[0]),42(s[1]),42(s[2])),0.,1.);}3V 62(1b e,2o 1m m,2o 1m s,2o 1m f,2o 1m r,2o 1m x,2o 1m v,2o 1m z){m=1E(e.x,1E(e.y,e.z));e-=m;s=1E(e.y,e.z);f=1E(e.x,e.z);r=1E(e.x,e.y);x=1E(1i(0.,e.x-e.z),1i(0.,e.x-e.y));v=1E(1i(0.,e.y-e.z),1i(0.,e.y-e.x));z=1E(1i(0.,e.z-e.y),1i(0.,e.z-e.x));}3V 4W(1b s,7c 1m f[38]){1m e,o,m,x,v,w,z;62(s,e,o,m,x,v,w,z);f[0]=1i(1e-4,e+o*.7d+m*.7e+x*.7f+v*.7g+w*.7h+z*.7i);f[1]=1i(1e-4,e+o*.7j+m*.7k+x*.7l+v*.7m+w*.7n+z*.7o);f[2]=1i(1e-4,e+o*.7p+m*.7q+x*.7r+v*.7s+w*.7t+z*.7u);f[3]=1i(1e-4,e+o*.7v+m*.7w+x*.7x+v*.7y+w*.7z+z*.7A);f[4]=1i(1e-4,e+o*.7B+m*.7C+x*.7D+v*.7E+w*.7F+z*.7G);f[5]=1i(1e-4,e+o*.7H+m*.7I+x*.7J+v*.7K+w*.7L+z*.7M);f[6]=1i(1e-4,e+o*.7N+m*.7O+x*.7P+v*.7Q+w*.7R+z*.7S);f[7]=1i(1e-4,e+o*.7T+m*.7U+x*.7V+v*.7W+w*.7X+z*.7Y);f[8]=1i(1e-4,e+o*.7Z+m*.81+x*.82+v*.83+w*.84+z*.86);f[9]=1i(1e-4,e+o*.87+m*.88+x*.89+v*.8a+w*.8b+z*.8c);f[10]=1i(1e-4,e+o*.8d+m*.8e+x*.8f+v*.8g+w*.8h+z*.8i);f[11]=1i(1e-4,e+o*.8j+m*.8k+x*.8l+v*.8m+w*.8n+z*.8o);f[12]=1i(1e-4,e+o*.8p+m*.8q+x*.8r+v*.8s+w*.8t+z*.8u);f[13]=1i(1e-4,e+o*.8v+m*.8w+x*.8x+v*.8y+w*.8z+z*.8A);f[14]=1i(1e-4,e+o*.8B+m*.8C+x*.8D+v*.8E+w*.8F+z*.8G);f[15]=1i(1e-4,e+o*.8H+m*.8I+x*.8J+v*.8K+w*.8L+z*.8M);f[16]=1i(1e-4,e+o*.8N+m*.8O+x*.8P+v*.8Q+w*.8R+z*.8S);f[17]=1i(1e-4,e+o*.8T+m*.8U+x*.8V+v*.8W+w*.8X+z*.8Y);f[18]=1i(1e-4,e+o*.8Z+m*.91+x*.93+v*.94+w*.96+z*.97);f[19]=1i(1e-4,e+o*.98+m*.99+x*.9a+v*.9b+w*.9c+z*.9d);f[20]=1i(1e-4,e+o*.9e+m*8.9f-5+x*.9g+v*.9h+w*.9i+z*.9j);f[21]=1i(1e-4,e+o*.9k+m*.9l+x*.9m+v*.9n+w*.9o+z*.9p);f[22]=1i(1e-4,e+o*.9q+m*.9r+x*.9s+v*.9t+w*.9u+z*.9v);f[23]=1i(1e-4,e+o*.9w+m*.9x+x*.9y+v*.9z+w*.9A+z*.9B);f[24]=1i(1e-4,e+o*.9C+m*.9D+x*.9E+v*.9F+w*.9G+z*.9H);f[25]=1i(1e-4,e+o*.9I+m*.9J+x*.9K+v*.9L+w*.9M+z*.9N);f[26]=1i(1e-4,e+o*.9O+m*.9P+x*.9Q+v*.9R+w*.9S+z*.9T);f[27]=1i(1e-4,e+o*.9U+m*.9V+x*.9W+v*.9X+w*.9Y+z*.9Z);f[28]=1i(1e-4,e+o*.a0+m*.a1+x*.a2+v*.a3+w*.a4+z*.a5);f[29]=1i(1e-4,e+o*.a6+m*.a7+x*.a8+v*.a9+w*.ab+z*.ac);f[30]=1i(1e-4,e+o*.ad+m*.ae+x*.af+v*.ag+w*.ah+z*.ai);f[31]=1i(1e-4,e+o*.aj+m*.ak+x*.al+v*.am+w*.an+z*.ao);f[32]=1i(1e-4,e+o*.ap+m*.aq+x*.ar+v*.as+w*.at+z*.au);f[33]=1i(1e-4,e+o*.av+m*.aw+x*.ax+v*.ay+w*.az+z*.aA);f[34]=1i(1e-4,e+o*.aB+m*.aC+x*.aD+v*.aE+w*.aF+z*.aG);f[35]=1i(1e-4,e+o*.aH+m*.aI+x*.aJ+v*.aK+w*.aL+z*.aM);f[36]=1i(1e-4,e+o*.aN+m*.aO+x*.aP+v*.aQ+w*.aR+z*.aS);f[37]=1i(1e-4,e+o*.aT+m*.aU+x*.aV+v*.aW+w*.aX+z*.aY);}1b 63(1b e){aZ f;f[0]=1b(3.b0,-1.b1,-.b2);f[1]=1b(-.b3,1.b4,.b5);f[2]=1b(.b6,-.b7,1.b8);1m s=1X(f[0],e),m=1X(f[1],e),z=1X(f[2],e);1c 61(1b(s,m,z));}1b 43(1m f[38]){1b e=1b(0);e+=f[0]*1b(6.b9-5,1.bb-6,.bc);e+=f[1]*1b(.bd,6.be-6,.bf);e+=f[2]*1b(.bg,3.bh-5,.bi);e+=f[3]*1b(.bj,.bk,.bl);e+=f[4]*1b(.bm,.bn,.bo);e+=f[5]*1b(.bp,.bq,.br);e+=f[6]*1b(.bs,.bt,.bu);e+=f[7]*1b(.bv,.bw,.bx);e+=f[8]*1b(.by,.bz,.bA);e+=f[9]*1b(.bB,.bC,.bD);e+=f[10]*1b(.bE,.bF,.bG);e+=f[11]*1b(.bH,.bI,.bJ);e+=f[12]*1b(.bK,.bL,.bM);e+=f[13]*1b(.bN,.bO,.bP);e+=f[14]*1b(.bQ,.bR,.bS);e+=f[15]*1b(.bT,.bU,.bV);e+=f[16]*1b(.bW,.bX,.bY);e+=f[17]*1b(.bZ,.c0,.c1);e+=f[18]*1b(.c2,.c3,.c4);e+=f[19]*1b(.c5,.c6,.c7);e+=f[20]*1b(.c8,.c9,.cb);e+=f[21]*1b(.cc,.cd,9.ce-5);e+=f[22]*1b(.cf,.cg,6.ch-5);e+=f[23]*1b(.ci,.cj,2.ck-5);e+=f[24]*1b(.cl,.cm,1.cn-5);e+=f[25]*1b(.co,.cq,3.cs-6);e+=f[26]*1b(.ct,.cu,1.cv-6);e+=f[27]*1b(.cw,.cx,0);e+=f[28]*1b(.cy,.cz,0);e+=f[29]*1b(.cA,.cB,0);e+=f[30]*1b(.cC,.cD,0);e+=f[31]*1b(.cE,.cF,0);e+=f[32]*1b(.cG,.cH,0);e+=f[33]*1b(.cI,.cJ,0);e+=f[34]*1b(.cK,6.cL-5,0);e+=f[35]*1b(9.cM-5,3.cN-5,0);e+=f[36]*1b(4.cO-5,1.cP-5,0);e+=f[37]*1b(2e-5,7.cQ-6,0);1c e;}1m 64(1m v,1m m,1m s){1m z=m*2p(s,2.);1c z/(v*2p(1.-s,2.)+z);}1b 3Y(1b s,1b f,1m e){1b v=4V(s),m=4V(f);1m z[38],o[38];4W(v,z);4W(m,o);1m x=43(z)[1],w=43(o)[1];e=64(x,w,e);1m r[38];1j(cR c=0;c<38;c++){1m y=(1.-e)*(2p(1.-z[c],2.)/(2.*z[c]))+e*(2p(1.-o[c],2.)/(2.*o[c]));r[c]=1.+y-3K(2p(y,2.)+2.*y);}1c 63(43(r));}1O 3Y(1O s,1O e,1m z){1c 1O(3Y(s.2X,e.2X,z),5Z(s.w,e.w,z));}"}};"3F"!==3b 66&&4s(66.cS);m.cT=1k(a){U=!0;Y=a;4s(a)};1y u={1f:!1,1S:1w 4X,2k:"",67(){1c 1d.1E(k.1x,k.1A)/cU},5w(){j.R=.4U*k.1x;j.68=-1*k.1x;j.69=-1*k.1A;j.2v=1d.2E(2*k.1x/j.R);j.2F=1d.2E(2*k.1A/j.R);j.6a()},6b(){1c j.1S.2N(j.2k).2x},4t(a=0){j.1S.2N(j.2k).2x=j.1S.2N(j.2k).5A(a,j.6c())},6c(){1a a=46(j.2v);1j(1a b=0;b=-a-y.1H()[0]&&j.x<=a-y.1H()[0]&&j.y>=-b-y.1H()[1]&&j.y<=b-y.1H()[1]}2Y(){1c j.4d()&&u.1f?u.6b()[j.4b][j.4c]:0}6h(a,b,c=u.67(),d=!0){1n(j.4d()){1a g;1n(!d){g=e.1C(-b);1t f=e.1z(-b)}1j(1a l=0;l{1y c="3i"===b.1r||"2G"===b.1r||"1V"===b.1r;c||"3j"===b.1r||(b.1r="4e");"1V"===b.1r&&(X.2Z(b.1V.6j),b.3k=()=>h.1p.1V(X.3y.2N(h.p.1V.6j),-h.p.2b/2,-h.p.2b/2,h.p.2b,h.p.2b));b.1J=c&&!1!==b.1J||b.1J?!0:!1;h.1S.1T(a,{3J:b,d2:[],d3:[]})},1T(a,b,c=1){h.50(a);h.c=b;h.w=c;h.1f=!0},50(a){h.2K=a},6k(a,b,c){0<3f.1l&&(h.c=2>3f.1l?a:[a,b,c]);h.1f=!0},6l(a){h.w=a},3q(a){h.cr=a},52(){h.cr=2q},2U(a,b,c,d){E();1a f=e.2y(a,b,c,d);0!=f&&(h.4f(a,b,f,!1,!1),a=V(a,b,c,d),h.1U(a,!1))},53(a,b,c,d){E();h.4f(a,b,c,!0,!1);h.1U(e.2R(d),!1)},54(a,b,c,d){E();h.4f(b,c,a.1l,!0,a);h.1U(d,!0)},2P(){j.p=j.1S.2N(j.2K).3J;1c"4e"===j.p.1r||"3j"===j.p.1r?j.p.2P/j.w:j.p.2P},4f(a,b,c,d,f){j.1u=1w aa(a,b);j.1l=c;j.56=d;(j.39=f)&&f.3l(0)},1U(a,b){b||(j.2w=a);j.57();1y c=j.2P(),d=b?1d.2E(j.1l*a/c):1d.2E(j.1l/c);1j(1a f=0;f=h.cr[0]&&j.1u.x<=h.cr[2]&&j.1u.y>=h.cr[1]&&j.1u.y<=h.cr[3];1a a=.55*k.1x,b=.55*k.1A;1c j.1u.x>=-a-y.1H()[0]&&j.1u.x<=a-y.1H()[0]&&j.1u.y>=-b-y.1H()[1]&&j.1u.y<=b-y.1H()[1]},6n(a){1a b=j.w*j.p.2O*a+j.w*e.2t()*j.p.2O/3,c=j.p.2b*e.1h(.9,1.1);a=j.p.5k/a;1j(1a d=0;da;a++)j.5f(b*a/5,!1);2z 1n("2G"===h.p.1r||"1V"===h.p.1r)1j(1a c=1;5>c;c++)j.5g(b*c/5,a,!1)}}},X={3y:1w 4X,2Z(a){j.3y.1T(a,!1)},6s(a){a.d8();1j(1a b=0;b<4*a.1x*a.1A;b+=4){1a c=(a.3a[b]+a.3a[b+1]+a.3a[b+2])/3;a.3a[b]=a.3a[b+1]=a.3a[b+2]=2g;a.3a[b+3]=2g-c}a.d9()},3c(){1j(1a a 1K j.3y.5m()){1a b=db(a,()=>X.6s(b));j.3y.1T(a,b)}}},z={1f:!1,2r:[5,45,{}],2c:!1,1B(a){1a b=z.2r[0],c=z.2r[1],d=z.2r[2],f=h.c,g=h.2K,l=h.w,p=h.1f;z.2c&&h.1T(z.2c[0],z.2c[1],z.2c[2]);c=e.2R(c)%2a;1a q=3A,t=-3A,x=3A,A=-3A;1t r=L=>{1j(1a I 1K L.a)q=I[0]t?I[0]:t,x=I[1]A?I[1]:A};46.dc(a)||(a=[a]);1j(1t D 1K a)r(D);D=1w O([[q,x],[t,x],[t,A],[q,A]]);1a J=90>=c&&0<=c?x:A;1t B=d.4y?e.1F(d.4y,0,1,1,1.1,!0):1;r=[];1a M=0,C=b,G=L=>({3B:{x:q+C*L*e.1C(-c+90),y:J+C*L*e.1z(-c+90)},3C:{x:q+C*L*e.1C(-c+90)+e.1C(-c),y:J+C*L*e.1z(-c+90)+e.1z(-c)}});1j(;0I.x===ba.x?I.y-ba.y:I.x-ba.x);C*=B;M++}a=[];1j(1t N 1K r)"3F"!==3b N[0]&&a.1q(N);N=d.4x?d.4x:0;1j(K=0;K({x:c[0],y:c[1]}));b&&(j.3D=a);j.5n=j.3D.1F((c,d,f)=>[c,f[(d+1)%f.1l]])}4g(a){1a b=`${a.3B.x},${a.3B.y}-${a.3C.x},${a.3C.y}`;1n(j.3m&&j.3m[b])1c j.3m[b];1a c=[];1j(1a d 1K j.5n){1a f=4o(a.3B,a.3C,d[0],d[1]);!1!==f&&c.1q(f)}j.3m||(j.3m={});1c j.3m[b]=c}1U(a=!1,b,c){1a d=h.1f;a&&h.1T(a,b,c);1n(h.1f){E();1j(1a f 1K j.5n)h.2U(f[0].x,f[0].y,f[1].x,f[1].y)}h.1f=d}1o(a=!1,b,c,d,f,g){1a l=v.1f;a&&(4C(a,b),4D(c,g),4E(d,f));v.1f&&(E(),v.1o(j));v.1f=l}1B(a=!1,b,c){1a d=z.1f;a&&4w(a,b,c);z.1f&&(E(),z.1B(j));z.1f=d}2d(a=!1,b=H.a){1n(H.1f||a){n.1g[2].1q();n.1g[2].2W();a=k.1N(a?a:H.c);a.5j(b);n.1g[2].1o(a);n.1g[2].4h();1j(1a c 1K j.3D)n.1g[2].4i(c.x,c.y);n.1g[2].4j(k.3e);n.1g[2].2s()}}}48 W{49(a){j.2Q=[];j.2i=[];j.3n=[];j.1r=a;j.2w=0;j.3l(0);j.2I=!1}1Q(a=0,b=0,c=1,d=!1){0f+g,0);j.2i.1q(a)}3r(a=0,b=1,c=!1){a=c?(a%1v+1v)%1v:e.2R(a);j.2i.6t(-1);j.2i.1q(a);j.3n.1q(b)}1L(a){j.2w=e.2R(a)}2h(a){1c a>j.1l?j.3n[j.3n.1l-1]:j.5o(j.3n,a)}2Y(a){1n(a>j.1l)1c j.2i[j.2i.1l-1];j.3l(a);1c"1D"===j.1r?j.5o(j.2i,a)+j.2w:j.2i[j.2J]+j.2w}5o(a,b){1a c=a[j.2J];a=a[j.2J+1];"3F"==3b a&&(a=c);2a<1d.3X(a-c)&&(a>c?a=-(1v-a):c=-(1v-c));1c e.1F(b-j.5p,0,j.2Q[j.2J],c,a,!0)}3l(a){j.2J=-1;1a b=j.5p=0;1j(;b<=a;)j.5p=b,b+=j.2Q[j.2J+1],j.2J++}4k(a,b,c=1,d=!1){E();1t f=0,g=dg;1j(1t l 1K j.2Q)l*=c,0!==l&&(f=1d.1i(f,l),g=1d.1E(g,l));c=h.2P();l=[];1t p=e.2n(v.2m,.dh,1);d=(f+g)*(d?.3W:v.5q?.25:p);a=1w aa(a,b);b=1d.2E(j.1l/c);p=g=f=0;1a q=d*e.1h(.6,1.5);1j(1a t=0;t=p&&a.x&&(l.1q([a.x,a.y]),p++),f>=q&&a.x&&(l.1q([a.x,a.y]),q=d*e.1h(.7,1.3),g++,f=0);j.3l(0);1c 1w O(l)}1U(a,b,c){h.1f&&(E(),j.1R&&(a=j.1R[0],b=j.1R[1],c=1),h.54(j,a,b,c))}1o(a,b,c){v.1f&&(E(),j.1R&&(a=j.1R[0],b=j.1R[1],c=1),j.2I=j.4k(a,b,c),j.2I.1o())}1B(a,b,c){z.1f&&(E(),j.1R&&(a=j.1R[0],b=j.1R[1],c=1),j.2I=j.4k(a,b,c,!0),j.2I.1B())}2d(a,b,c){j.1R&&(a=j.1R[0],b=j.1R[1],c=1);j.2I=j.4k(a,b,c,!0);n.1g[2].1q();n.1g[2].2W();a=k.1N(H.c);a.5j(H.a);n.1g[2].1o(a);n.1g[2].4h();1j(1a d 1K j.2I.3D)n.1g[2].4i(d.x,d.y);n.1g[2].4j(k.3e);n.1g[2].2s()}}1a F=!1,R;1y H={2d(a="5N",b=2g){H.1f=!0;H.c=a;H.a=b},4l(){H.1f=!1}},v={1f:!1,5q:!1,1N:"#di",2l:80,2m:.dj,2L:.4,2M:.4,1o(a){j.5r=a;j.v=a.a.1F(c=>k.5s(c[0],c[1]));1y b=j.v.1l*e.1h(.4);v.m=j.v.1F((c,d)=>{c=e.1h(.8,1.2)*j.2m;1c dj.3p&&(j.3p=a);1n(f)1j(f="5F"===k.3g()?1d.2j/2a:1,g=0;g{1y D=e.2t(.5,.1);1c r+.1*(D-.5)};1a q=k.5s();1j(1a r=0;r=v.2m?.25:.75:j.m[r];J*=b;c.1q(t);d.1q(p(J));1t x=D.x-t.x,A=D.y-t.y;1a B=1d.3K(x*x+A*A);q.1T(x,A).dn();x=j.2w[r];A="2o"==v.5D?90:-90;A=(x?A:-A)+45*e.2t(0,.4);q.1L(A*1d.2j/2a);q.do(e.2t(.5,.2)*e.1h(.6,1.4)*B*J);t=t.5u().dp(D,e.2n(e.2t(.5,.2),.1,.9));t.2Z(q);c.1q(t);d.1q(p(J));f.1q(x,x)}k.3g(l);1c 1w 5t(c,d,j.3o,f)}1o(a,b,c){1a d=e.1F(v.2m,0,.15,.6,1,!0);1y f=24*d,g=b/5+c*b/6,l=b/4+c*b/3,p=b/7+c*b/3,q=b/5;c*=3;n.4P=!0;y.1H();n.1J(a,!1,!1,!0);n.1g[0].1q();n.1g[0].2W();n.1g[0].3h(y.2C[0]+k.1x/2,y.2C[1]+k.1A/2);n.1g[0].1L(y.3d);n.1g[0].3x(Z);a=j.1I();1a t=a.1I().1I(.9),x=t.1I(.75),A=j.1I(.6);1j(1a r=0;r