[
  {
    "path": ".gitignore",
    "content": "\nexamples/.DS_Store\nexamples/data/.DS_Store\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2019 Jongmin Kim\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Leon Sans\nLeon Sans is a geometric sans-serif typeface made with code in 2019 by Jongmin Kim. It allows to change font weight dynamically and to create custom animations, effects or shapes in the Canvas element of HTML5. He designed the font to celebrate his newborn baby Leon.\n\nThere are live examples at https://leon-kim.com/examples/\n\nAnd website at https://leon-kim.com/\n\n[![Video Label](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/leon-youtube.jpg)](https://youtu.be/sb7v-d-R11E?hl=en&fs=1&cc_load_policy=1)\n\n![uppercase](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/screenshot/upper.gif)\n\n![lowercase](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/screenshot/lower.gif)\n\n![number](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/screenshot/number-special.gif)\n\n![latin upper](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/screenshot/latin-upper.gif)\n\n![latin lower](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/screenshot/latin-lower.gif)\n\n\n## What is special?\nThe font is made with code, it has coordinate values of the drawing points for each glyph. With the coordinate values, you can create custom shapes, effects or animations.\n\n![Drawing animation](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/screenshot/drawing.gif)\n- [Drawing animation](https://leon-kim.com/examples/#canvas-basic)\n\n![Weight change](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/screenshot/weight.gif)\n- [Weight change](https://leon-kim.com/examples/#canvas-basic)\n\n![Wave](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/screenshot/wave.gif)\n- [Wave](https://leon-kim.com/examples/#wave)\n\n![Metaball](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/screenshot/metaball.gif)\n- [Metaball](https://leon-kim.com/examples/#metaball-pixi)\n\n![Plant](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/screenshot/plant.gif)\n- [Plant](https://leon-kim.com/examples/#plants-pixi)\n\n![Colorful](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/screenshot/colorful.gif)\n- [Colorful](https://leon-kim.com/examples/#colorful)\n\n![Color pattern](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/screenshot/colorpattern.gif)\n- [Color pattern](https://leon-kim.com/examples/#color-pattern)\n\n\n## Usage\nDownload the minified js file in dist folder and include it in your html.\n```html\n<script src=\"js/leon.js\"></script>\n```\n\nGenerate LeonSans and draw it in the Canvas element of HTML5.\n```javascript\n\nlet leon, canvas, ctx;\n\nconst sw = 800;\nconst sh = 600;\nconst pixelRatio = 2;\n\nfunction init() {\n    canvas = document.createElement('canvas');\n    document.body.appendChild(canvas);\n    ctx = canvas.getContext(\"2d\");\n\n    canvas.width = sw * pixelRatio;\n    canvas.height = sh * pixelRatio;\n    canvas.style.width = sw + 'px';\n    canvas.style.height = sh + 'px';\n    ctx.scale(pixelRatio, pixelRatio);\n\n    leon = new LeonSans({\n        text: 'The quick brown\\nfox jumps over\\nthe lazy dog',\n        color: ['#000000'],\n        size: 80,\n        weight: 200\n    });\n\n    requestAnimationFrame(animate);\n}\n\nfunction animate(t) {\n    requestAnimationFrame(animate);\n\n    ctx.clearRect(0, 0, sw, sh);\n\n    const x = (sw - leon.rect.w) / 2;\n    const y = (sh - leon.rect.h) / 2;\n    leon.position(x, y);\n\n    leon.draw(ctx);\n}\n\nwindow.onload = () => {\n    init();\n};\n```\n\nFor the drawing animation, include TweenMax (JS animation library) in your html.\n```html\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js\"></script>\n```\n\nAnd update all the drawing values from 0 to 1\n```javascript\nlet i, total = leon.drawing.length;\nfor (i = 0; i < total; i++) {\n    TweenMax.fromTo(leon.drawing[i], 1.6, {\n        value: 0\n    }, {\n        delay: i * 0.05,\n        value: 1,\n        ease: Power4.easeOut\n    });\n}\n```\n\n\n\n### Option list\n\n| Name                 | Type     | Description                                                                                                                                                                                                     |\n| -------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `text`               | string   | The text that needs to be shown.                                                    |\n| `size`               | integer   | The size of the text.                                                              |\n| `weight`              | number   | The weight of the font: `1 - 900`. [Default: `1`] |\n| `color`           | array  | The colors of each characters. [Default: `['#000000']`]                                                                                                                                                                 |\n| `colorful`              | array  | The colors for colorful effect. [Default: `['#c5d73f', '#9d529c', '#49a9db', '#fec330', '#5eb96e', '#fc5356', '#f38f31']`]                            |\n| `tracking`            | integer | The spacing between the characters of a block of text.  [Default: `0`]                                                                                                                                                            |\n| `leading` | integer | The distance between each line of text.  [Default: `0`]           |\n| `align` | string | How the text content of the element is horizontally aligned: `left, center, right`. [Default: `left`]   |\n| `pathGap`            | number  | The gap between each coordinate of the points on a line of each character: `0 - 1`. [Default: `0.5`]                                                                                  |\n| `amplitude`        | number  | The amplitude of the wave effect: `0 - 1`. [Default: `0.5`]  |\n| `maxWidth`       | number  | The width of the text sentence.  |\n| `breakWord`        | boolean  | Words break when reaching the end of a line. [Default: `false`]     |\n| `fps`        | number  | The FPS for the wave effect. [Default: `30`]     |\n| `isPath`        | boolean  | `true` to get the coordinate values of the points on a line of each character. [Default: `false`]     |\n| `isWave`        | boolean  | `true` for the wave effect. [Default: `false`]     |\n\n\n### Properties\n\n| Name                 | Type     | Description                                                                                                                                                                                                     |\n| -------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `lineWidth`               | number   | The thickness of lines of the character.                                                    |\n| `scale`               | number   | The scale of the character. `scale` is `1` when the font size is `500`.    |\n| `drawing`              | array   | The drawing object values for each character. `0` is the beginning of the animation, `1` is the end of the animation state. |\n| `data`           | array  | An object of the raw data for the text.                       |\n| `paths`              | array  | The coordinate values of the points on a line of each character.        |\n| `drawingPaths`            | array | The coordinate values of the points on a line of each character to draw the drawing animation in WebGL. It has 1px distance of each path.  |\n| `wavePaths` | array | The coordinate values of the points on a line for the wave effect.    |\n| `rect` | Object | The size of the text and its position: `{x: x position, y: y position, w: width, h: height}`.|\n\n\n### Methods\n\n| Name                         | Description                                                                                                                                                                                                                                                              |\n| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| `on()`      | Add `update` event. |\n| `off()`                     | Remove `update` event.  |\n| `position(x, y)`                    | Set the position of the text.  |\n| `updateDrawingPaths()`     | Update paths for drawing in WebGL (PIXI.js). It's very expensive, only call when it needs.  |\n| `drawPixi(graphics)` | Draw text in WebGL with PIXI.js. |\n| `draw(ctx)`                | Draw text in the Canvas element. |\n| `drawColorful(ctx)`                | Draw the colorful effect. |\n| `wave(ctx, t)`                | Draw the wave effect. |\n| `pattern(ctx, w, h)`                | Draw rectangle shapes at each path point |\n| `grid(ctx)`                | Draw grid for each type. |\n| `point(ctx)`                | Draw circles at each drawing point and lines for each type. |\n| `box(ctx)`                | Draw outline box for the text. |\n| `reset()`                  | Reset all the values.  |\n| `dispose()`                  | Dispose.  |\n\n"
  },
  {
    "path": "dist/leon.js",
    "content": "/*!\n * VERSION: 1.6.5\n * DATE: 2020-09-20\n * https://leon-sans.com\n *\n * @license Copyright (c) 2019-2020, Jongmin Kim. All rights reserved.\n **/\nvar LeonSans=function(t){var r={};function i(e){if(r[e])return r[e].exports;var a=r[e]={i:e,l:!1,exports:{}};return t[e].call(a.exports,a,a.exports,i),a.l=!0,a.exports}return i.m=t,i.c=r,i.d=function(t,r,e){i.o(t,r)||Object.defineProperty(t,r,{enumerable:!0,get:e})},i.r=function(t){\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(t,\"__esModule\",{value:!0})},i.t=function(t,r){if(1&r&&(t=i(t)),8&r)return t;if(4&r&&\"object\"==typeof t&&t&&t.__esModule)return t;var e=Object.create(null);if(i.r(e),Object.defineProperty(e,\"default\",{enumerable:!0,value:t}),2&r&&\"string\"!=typeof t)for(var a in t)i.d(e,a,function(r){return t[r]}.bind(null,a));return e},i.n=function(t){var r=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(r,\"a\",r),r},i.o=function(t,r){return Object.prototype.hasOwnProperty.call(t,r)},i.p=\"\",i(i.s=0)}([function(t,r,i){var e=i(1).default;t.exports=e},function(t,r,i){\"use strict\";i.r(r),i.d(r,\"default\",(function(){return Zt}));var e=1,a=2*Math.PI;function s(t,r){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,e=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,a=.49*t.rect.w*r,s=.49*(t.rect.h+220)*r;return{x:i,y:e,w:a,h:s}}function n(t,r,i){return{x:t/2,y:(r-130*.49*i)/2}}function l(t,r,i){return{r:r,cr:i,fr1:1,fr2:.78,gx1:t.ratio.x1,gx2:t.ratio.x2,gy1:t.ratio.y1,gy2:t.ratio.y2}}function f(t,r,i,e,a){var s=(e-a)/(r-i)*(t-i)+a;return s<a?s=a:s>e&&(s=e),s}function o(t){var r,i,e,a,s,n,l,o,h,y,d,c=t.typo.p.length,p=[];for(r=0;r<c;r++)for(a=(s=t.typo.p[r]).cv.length,i=0;i<a;i++){if(l=(n=s.cv[i]).addRect(t.rect),o=s.d,y=(h=t.pointsLength.lengths[r])/t.pointsLength.max,d=0,r>0)for(e=0;e<r;e++)d+=t.pointsLength.lengths[e]/t.pointsLength.max;y+=d,p.push({pos:l,drawing:t.drawing,direction:o,lengths:h,maxDrawing:y,minDrawing:d,closePath:n.ratio.c,stroke:(t,r)=>{var i=f(r.drawing.value,r.maxDrawing,r.minDrawing,1,0);if(i>0&&\"a\"!=r.pos.type){var e=r.lengths*i;t.setLineDash([r.lengths]),t.lineDashOffset=r.direction*(e+r.lengths),t.stroke()}}})}return p}function h(t,r){var i,e,a=t.length,s=[];for(i=0;i<a;i++)e=t[i].addRect(r.rect),s.push(e);return s}function y(t,r){var i,e,s,n=r.lines.length;for(i=0;i<n;i++)\"a\"==(s=(e=r.lines[i]).pos).type?(t.beginPath(),t.arc(s.x,s.y,s.radius*e.drawing.value,0,a),t.fill(),t.closePath()):\"m\"==s.type?(t.beginPath(),t.moveTo(s.x,s.y)):\"l\"==s.type?(t.lineTo(s.x,s.y),e.stroke(t,e)):\"b\"==s.type&&(t.bezierCurveTo(s.x,s.y,s.x2,s.y2,s.x3,s.y3),e.stroke(t,e))}function d(t,r){t.save(),t.lineWidth=1;var i,e=r.lines.length;for(i=0;i<e;i++)p(t,r.lines[i]);for(t.restore(),t.save(),t.lineWidth=1,e=r.typo.p.length,i=0;i<e;i++)c(t,r.typo.p[i],r);t.restore()}function c(t,r,i){var e,s,n,l=r.v.length;for(e=0;e<l;e++)n=(s=r.cv[e]).addRect(i.rect),\"b\"==s.type?(t.fillStyle=\"#ff2a00\",t.beginPath(),t.arc(n.x3+(n.x3-n.x2),n.y3+(n.y3-n.y2),1.5,0,a),t.fill(),t.beginPath(),t.arc(n.x2,n.y2,1.5,0,a),t.fill(),t.beginPath(),t.moveTo(n.x2,n.y2),t.lineTo(n.x3,n.y3),t.lineTo(n.x3+(n.x3-n.x2),n.y3+(n.y3-n.y2)),t.stroke(),t.beginPath(),t.fillStyle=\"#ffffff\",t.arc(n.x3,n.y3,2.5,0,a),t.fill(),t.stroke()):(t.beginPath(),t.fillStyle=\"#ffffff\",t.strokeStyle=\"#ff2a00\",t.arc(n.x,n.y,2.5,0,a),t.fill(),t.stroke())}function p(t,r){var i=r.pos;\"a\"!=i.type&&(\"m\"==i.type?(t.strokeStyle=\"#ff2a00\",t.beginPath(),t.moveTo(i.x,i.y)):\"l\"==i.type?t.lineTo(i.x,i.y):\"b\"==i.type&&t.bezierCurveTo(i.x,i.y,i.x2,i.y2,i.x3,i.y3),t.stroke())}function v(t,r){t.save(),t.beginPath(),t.lineWidth=1,t.strokeStyle=\"#aaaaaa\";var i,e,a=r.guide.length;for(i=0;i<a;i++)e=r.rect.y+r.grid[i],t.moveTo(r.rect.x,e),t.lineTo(r.rect.x+r.rect.w,e);t.stroke(),t.lineWidth=1,t.beginPath(),t.strokeStyle=\"#aaaaaa\",t.rect(r.rect.x,r.rect.y,r.rect.w,r.rect.h),t.stroke(),t.restore()}var x,u=Math.cos,g=Math.sin;function b(t,r,i,e,s,n){var l,f,o,h,y,d=r.wavePaths.length,c=function(t,r){return 120*t*r}(e,i),p=[];for(t.beginPath(),l=0;l<d;l++){if(f=r.wavePaths[l],n){var v=Math.random()*c-c/2,x=Math.random()*c-c/2;f.rx=f.x+v*u(f.rotation),f.ry=f.y+v*g(f.rotation),f.sx=f.x+v,f.sy=f.y+x}\"a\"==f.type?p.push(f):1==f.start?t.moveTo(f.x,f.y):f.fix?t.lineTo(f.x,f.y):s<110?(o=r.wavePaths[l-1])&&(h=o.x+.5*(f.x-o.x),y=o.y+.5*(f.y-o.y),t.quadraticCurveTo(h,y,f.rx,f.ry)):t.lineTo(f.rx,f.ry)}for(t.stroke(),l=0;l<p.length;l++)f=p[l],t.beginPath(),t.arc(f.x,f.y,f.radius,0,a),t.fill()}function S(t,r,i,e){var s,n,l=Math.round(r.paths.length*r.drawing.value),f=i/2,o=i/3,h=e/2;for(s=0;s<l;s++)1==(n=r.paths[s]).num?t.fillStyle=\"#ff00c5\":t.fillStyle=\"#ff95f8\",\"a\"==n.type?(t.beginPath(),t.arc(n.x,n.y,o,0,a),t.fill()):(t.beginPath(),t.save(),t.translate(n.x,n.y),t.rotate(n.rotation),t.fillRect(-f,-h,i,e),t.restore())}function m(t,r,i,e){var a=e.length,s=(r+a*(Math.abs(r/10|0)+1))%a;if(Array.isArray(e[s])){var n,l=1/((a=e[s].length)+1),f=t.createLinearGradient(i.rect.x,i.rect.y,i.rect.x,i.rect.y+i.rect.h);for(f.addColorStop(l,e[s][0]),n=0;n<a;n++)f.addColorStop(l*(n+1),e[s][n]);f.addColorStop(l*(a+1),e[s][a-1]),t.strokeStyle=f,t.fillStyle=f}else t.strokeStyle=e[s],t.fillStyle=e[s]}function O(t,r){var i,e,a=t.typo.p.length,s=[],n=[],l=0;for(e=0;e<a;e++)l+=(i=J(t,t.typo.p[e].v,r)).l,s.push(i.v),n.push(i.l);return{max:l,lines:s,lengths:n}}function J(t,r,i){var e,a,s,n,l,f,o=r.length,h=[],y=0;for(e=0;e<o;e++)s={},l=(a=r[e]).convert(t,i),0==e||\"a\"==a.type?(s.x1=l.x,s.y1=l.y,s.distance=0,s.radius=l.radius):(n=f.convert(t,i),\"b\"==f.type?(s.x1=n.x3,s.y1=n.y3):(s.x1=n.x,s.y1=n.y),s.x2=l.x,s.y2=l.y,\"b\"==a.type?(s.x3=l.x2,s.y3=l.y2,s.x4=l.x3,s.y4=l.y3,s.distance=N(s.x1,s.y1,s.x2,s.y2,s.x3,s.y3,s.x4,s.y4)):s.distance=w(s.x1,s.y1,s.x2,s.y2)),s.type=a.type,s.rotation=a.ratio.r,s.pat=a.ratio.p,s.fix=a.ratio.f,s.vt=a.ratio.v,h.push(s),y+=s.distance,f=a;return{v:h,l:y}}function N(t,r,i,e,a,s,n,l,f){var o,h,y,d,c=f||40,p=0,v=t,x=r;for(y=1;y<c;y++)o=(d=_(y/c,t,r,i,e,a,s,n,l)).x-v,h=d.y-x,p+=Math.sqrt(o*o+h*h),v=d.x,x=d.y;return o=n-v,h=l-x,p+=Math.sqrt(o*o+h*h)}function _(t,r,i,e,a,s,n,l,f){return r+=(e-r)*t,i+=(a-i)*t,{x:(r+=((e+=(s-e)*t)-r)*t)+((e+=((s+=(l-s)*t)-e)*t)-r)*t,y:(i+=((a+=(n-a)*t)-i)*t)+((a+=((n+=(f-n)*t)-a)*t)-i)*t}}function w(t,r,i,e){var a=i-t,s=e-r;return Math.sqrt(a*a+s*s)}var P,W=-1;function k(t){var r=function(){++W==P&&(W=0);return x[W]}();t.fillStyle=r,t.strokeStyle=r}function D(t,r,i,e,a,s){var n=i/e,l=f(a.drawing.value,s+n,s,1,0);if(1==r.direction&&(l=f(1-a.drawing.value,s,s+n,1,0)),l>0){var o=i*l;t.setLineDash([i]),t.lineDashOffset=r.direction*(o+i),t.stroke()}return n}function T(t,r,i,e){var a,s;if(1==r.drawing.value)for(a=r.lines.length,s=0;s<a;s++)I(t,r.lines[s],i,e);else for(a=r.drawingPaths.length*r.drawing.value,s=0;s<a;s++)R(t,r.drawingPaths[s],i,e,r.drawing.value)}function I(t,r,i,e){var a=r.pos;\"a\"==a.type?(t.lineStyle(0,e,0),t.beginFill(e),t.drawCircle(a.x,a.y,a.radius),t.endFill()):\"m\"==a.type?(t.lineStyle(i,e,1),t.moveTo(a.x,a.y)):\"l\"==a.type?t.lineTo(a.x,a.y):\"b\"==a.type&&t.bezierCurveTo(a.x,a.y,a.x2,a.y2,a.x3,a.y3),r.closePath&&t.closePath()}function R(t,r,i,e,a){\"a\"==r.type?(t.lineStyle(0,e,0),t.beginFill(e),t.drawCircle(r.x,r.y,r.radius*a),t.endFill()):1==r.start?(t.lineStyle(i,e,1),t.moveTo(r.x,r.y)):t.lineTo(r.x,r.y,1)}function F(t,r,i){var e=i.length,a=(t+e*(Math.abs(t/10|0)+1))%e;if(!Array.isArray(i[a]))return i[a]}function M(t,r){var i,e,a,s=[];for(i=0;i<6;i++)e=10*i+20,a=10*i+90,s[i]={x1:.49*e*r,x2:.49*(t.rect.w-2*e)*r,y1:.49*a*r,y2:.49*(t.rect.h-a)*r-10*i*.49*r};return s}function G(t,r){var i,e=[],a=[98,340,815];for(i=0;i<3;i++)e[i]=.49*a[i]*r;return e}function z(t){Object.assign(this,t)}function L(t){this.type=t[0],this.x=t[1]||0,this.y=t[2]||0,\"b\"==this.type?(this.x2=t[3]||0,this.y2=t[4]||0,this.x3=t[5]||0,this.y3=t[6]||0,null==t[7]?this.ratio={x:1,y:1,r:0,p:0,f:0,c:0,v:0}:(this.ratio={},this.ratio.x=null==t[7].x?1:t[7].x,this.ratio.y=null==t[7].y?1:t[7].y,this.ratio.r=t[7].r||0,this.ratio.p=t[7].p||0,this.ratio.f=t[7].f||0,this.ratio.c=t[7].c||0,this.ratio.v=t[7].v||0)):null==t[3]?this.ratio={x:1,y:1,r:0,p:0,f:0,c:0,v:0}:(this.ratio={},this.ratio.x=null==t[3].x?1:t[3].x,this.ratio.y=null==t[3].y?1:t[3].y,this.ratio.r=t[3].r||0,this.ratio.p=t[3].p||0,this.ratio.f=t[3].f||0,this.ratio.c=t[3].c||0,this.ratio.v=t[3].v||0)}function j(t,r,i,e){var a=r.range.r*i.x,s=(r.range.gx2-r.range.gx1)*a+r.range.gx1,n=(r.range.fr2-r.range.fr1)*a+r.range.fr1;return r.center.x+(t-s)*e.scale*n}function C(t,r,i,e){var a=r.range.r*i.y,s=(r.range.gy2-r.range.gy1)*a+r.range.gy1,n=(r.range.fr2-r.range.fr1)*a+r.range.fr1;return r.center.y+(t-s)*e.scale*n}Object.assign(z.prototype,{addRect:function(t){var r=new z(this);return r.x=this.x+t.x,r.y=this.y+t.y,r.x2=this.x2+t.x,r.y2=this.y2+t.y,r.x3=this.x3+t.x,r.y3=this.y3+t.y,r.rx=this.rx+t.x,r.ry=this.ry+t.y,r.sx=this.sx+t.x,r.sy=this.sy+t.y,r.radius<.5&&(r.radius=.5),r}}),Object.assign(L.prototype,{convert:function(t,r){var i=j(this.x,t,this.ratio,r),e=C(this.y,t,this.ratio,r),a=j(this.x2,t,this.ratio,r),s=C(this.y2,t,this.ratio,r),n=j(this.x3,t,this.ratio,r),l=C(this.y3,t,this.ratio,r),f=function(t,r,i){var e=0;\"a\"==t&&(e=r.range.cr*i.scale*i.fontRatio);return e}(this.type,t,r),o=new z(this);return o.x=i,o.y=e,o.x2=a,o.y2=s,o.x3=n,o.y3=l,o.radius=f,o}});var A=null;function q(t,r,i,e){var a,s,n,l,f,o=r.pointsLength.lines,h=t.scale,y=o.length,d=[],c=[],p=[];for(a=0;a<y;a++)l=o[a],A=null,d.push(X(l,i,h));for(y=d.length,a=0;a<y;a++){for(s=(f=d[a]).length,p=[],n=0;n<s;n++)(l=f[n]).rotation!=V&&(e&&l.pat||p.push(l));1==r.typo.p[a].d&&p.reverse(),p.length>0&&(p[0].start=1,Array.prototype.push.apply(c,p))}return c}function X(t,r,i){var e,a,s,n,l,o,h,y=t.length,d=[],c=1,p=1;for(r>-1&&(p=f(r,1,0,80,10)*i),e=0;e<y;e++)if(\"a\"==(n=t[e]).type)d.push(new z({x:n.x1,y:n.y1,rotation:0,type:\"a\",pat:n.pat,fix:n.fix,radius:n.radius}));else if(0==n.distance)null!=(h=E(l=new z({x:n.x1,y:n.y1,rotation:n.rotation,type:n.type,pat:n.pat,fix:n.fix}),A,n,1))&&(c&&(h.type=\"m\",c=0),d.push(h)),A=new z(l);else for((s=Math.ceil(n.distance/p))<3&&(s=3),n.vt&&(s=2),a=1;a<s;a++)o=a/(s-1),l=\"b\"==n.type?B(n,o):new z({x:n.x1+(n.x2-n.x1)*o,y:n.y1+(n.y2-n.y1)*o,type:n.type}),0!=n.rotation&&1==o&&(l.rotation=n.rotation),n.pat&&1==o&&(l.pat=n.pat),n.fix&&1==o&&(l.fix=n.fix),s>0&&null!=(h=E(l,A,n,o))&&(c&&(h.type=\"m\",c=0),d.push(h)),A=new z(l);return d}function E(t,r,i,e){if(t.type=i.type,t.distance=i.distance,t.num=e,r&&null==t.rotation){var a=t.x-r.x,s=t.y-r.y,n=Math.atan2(a,s);t.rotation=-n}else t.rotation=t.rotation;return t.rotation==V?null:t}function B(t,r){var i=H(t.x1,t.x2,t.x3,t.x4,r),e=H(t.y1,t.y2,t.y3,t.y4,r),a=K(t.x1,t.x2,t.x3,t.x4,r),s=K(t.y1,t.y2,t.y3,t.y4,r);return new z({x:i,y:e,rotation:-Math.atan2(a,s)})}function H(t,r,i,e,a){var s=a*a;return t+(3*-t+a*(3*t-t*a))*a+(3*r+a*(-6*r+3*r*a))*a+(3*i-3*i*a)*s+e*(s*a)}function K(t,r,i,e,a){return 3*a*a*(3*r-t-3*i+e)+6*a*(t-2*r+i)+3*(-t+r)}var Q=Math.PI/180*180,U=Math.PI/180*90,V=-100;function Y(t,r,i,e,a,s,n,l){var f,o=[],h=l.length;for(f=0;f<h;f++)o.push({d:l[f].d,v:Z(l[f].v,r,i)});return{rect:{w:t,h:824,fw:r,fh:i},ratio:{x1:e,x2:a,y1:s,y2:n},p:o,clone:()=>{for(var l=[],f=0;f<o.length;f++)l[f]={d:o[f].d,v:o[f].v};return{rect:{w:t,h:824,fw:r,fh:i},ratio:{x1:e,x2:a,y1:s,y2:n},p:l}}}}function Z(t,r,i){var e,a,s=t.length,n=r/2,l=i/2,f=[];for(a=0;a<s;a++)(e=t[a])[1]-=n,e[2]-=l,\"b\"==e[0]&&(e[3]-=n,e[4]-=l,e[5]-=n,e[6]-=l),f.push(new L(e));return f}function $(t,r,i,e){var a=t-i,s=r-e;return-Math.atan2(a,s)}function tt(t,r,i,e,a,s,n,l,f){var o=K(t,i,a,n,f),h=K(r,e,s,l,f);return-Math.atan2(o,h)}var rt=[{d:-1,v:[[\"m\",0,352,{x:.55,y:.3,r:$(0,352,143.5,0)}],[\"l\",143.5,0,{r:$(0,352,143.5,0),f:1}],[\"l\",146.5,0,{r:$(290,352,146.5,0),f:1,v:1}],[\"l\",290,352,{x:.55,y:.3,f:1}]]},{d:-1,v:[[\"m\",47,237,{r:U,p:1}],[\"l\",243,237,{r:U,p:1,f:1}]]}],it=[{d:1,v:[[\"m\",293.1,320.1,{r:tt(293.1,320.1,262.2,345,222.8,360,180,360,0),f:1}],[\"b\",262.2,345,222.8,360,180,360],[\"b\",80.6,360,0,279.4,0,180],[\"b\",0,80.6,80.6,0,180,0],[\"b\",222.8,0,262.2,15,293.1,39.9]]}],et=[{d:-1,v:[[\"m\",95,352,{r:U,f:1}],[\"b\",191.6,352,270,271.6,270,175,{r:Q}],[\"b\",270,78.4,191.6,0,95,0,{r:U}],[\"l\",0,0,{r:Q,f:1}],[\"l\",0,352,{r:Q,f:1}],[\"l\",95,352,{r:U,f:1}]]}],at=[{d:-1,v:[[\"m\",192,0,{x:0,r:U}],[\"l\",0,0,{r:Q,f:1,x:.5}],[\"l\",0,352,{f:1,x:.5}],[\"l\",192,352,{x:0,r:U,f:1}]]},{d:-1,v:[[\"m\",0,164,{r:U,p:1,x:.5}],[\"l\",180,164,{x:0,r:U,f:1}]]}],st=[{d:1,v:[[\"m\",202,180,{r:U,f:1}],[\"l\",352,180,{f:1}],[\"b\",352,279.4,279.4,360,180,360,{r:U}],[\"b\",80.6,360,0,279.4,0,180,{r:Q}],[\"b\",0,80.6,80.6,0,180,0,{r:U}],[\"b\",222.8,0,262.1,14.9,293,39.9]]}],nt=[{d:-1,v:[[\"m\",0,0,{y:0,r:Q}],[\"l\",0,352,{y:0,r:Q,f:1}]]},{d:-1,v:[[\"m\",232,0,{y:0,r:Q}],[\"l\",232,352,{y:0,r:Q,f:1}]]},{d:-1,v:[[\"m\",0,164,{r:U,p:1}],[\"l\",232,164,{r:U,f:1,p:1}]]}],lt=[{d:1,v:[[\"m\",0,352,{y:0,r:Q,f:1}],[\"l\",0,0,{y:0,r:Q}]]}],ft=[{d:1,v:[[\"m\",0,311,{r:tt(0,311,16.2,341.6,49.3,356,86,356,0),f:1}],[\"b\",16.2,341.6,49.3,356,86,356,{r:U}],[\"b\",133.5,356,172,317.5,172,270],[\"l\",172.5,0,{y:0,r:Q}]]}],ot=[{d:-1,v:[[\"m\",0,352,{y:0,r:Q}],[\"l\",0,0,{r:Q,f:1}],[\"l\",3,0,{r:Q,p:1,f:1,v:1}],[\"l\",247,351,{r:Q,p:1,f:1}],[\"l\",250,351,{r:Q,f:1,v:1}],[\"l\",250,0,{y:0,r:Q,f:1}]]}],ht=[{d:1,v:[[\"m\",360,180,{r:Q,p:1,f:1}],[\"b\",360,279.4,279.4,360,180,360,{r:U}],[\"b\",80.6,360,0,279.4,0,180,{r:Q}],[\"b\",0,80.6,80.6,0,180,0,{r:U}],[\"b\",279.4,0,360,80.6,360,180,{r:Q,c:1}]]}],yt=[{d:1,v:[[\"m\",0,295.4,{r:tt(0,295.4,17.6,332.1,58.3,360,110.3,360,0),f:1}],[\"b\",17.6,332.1,58.3,360,110.3,360],[\"b\",173.9,360,223.8,329.6,224,271],[\"b\",224.2,214.7,180.7,189.6,112.4,173.3],[\"b\",47.3,157.7,10.9,130.6,12,84.4],[\"b\",13.3,29.8,57.3,0,114.8,0],[\"b\",158.4,0,196.5,20.5,212,51.3]]}],dt=[{d:1,v:[[\"m\",250,0,{y:0,r:Q}],[\"l\",250,231,{r:Q}],[\"b\",250,300,194,356,125,356,{r:U}],[\"b\",56,356,0,300,0,231,{r:Q}],[\"l\",0,0,{y:0,r:Q}]]}],ct=[{d:-1,v:[[\"m\",0,0,{x:.6,y:.3,r:$(0,0,135,186)}],[\"l\",135,186,{r:Q,f:1}],[\"l\",270,0,{x:.6,y:.3,f:1}]]},{d:-1,v:[[\"m\",135,186,{r:Q,p:1}],[\"l\",135,352,{y:0,f:1}]]}],pt={A:Y(620,290,352,0,0,0,0,JSON.parse(JSON.stringify(rt))),B:Y(596,209,352,-10,-10,0,0,[{d:1,v:[[\"m\",0,164,{r:U,p:1}],[\"l\",116,164,{r:U,p:1,f:1}],[\"b\",167.4,164,209,205.6,209,257,{r:Q}],[\"b\",209,308.4,167.4,352,116,352,{r:U}],[\"l\",0,352,{r:Q,f:1}],[\"l\",0,0,{r:Q,f:1}],[\"l\",116,0,{r:U}],[\"b\",161.3,0,198,36.7,198,82,{r:Q}],[\"b\",198,127.3,161.3,164,116,164,{r:U}]]}]),C:Y(700,293.1,360,0,0,0,0,JSON.parse(JSON.stringify(it))),D:Y(721,270,352,-10,-10,0,0,JSON.parse(JSON.stringify(et))),E:Y(520,192,352,-5,-80,0,0,JSON.parse(JSON.stringify(at))),F:Y(510,192,352,-5,-80,0,0,[{d:-1,v:[[\"m\",192,0,{x:0,r:U}],[\"l\",0,0,{r:Q,f:1,x:.5}],[\"l\",0,352,{y:0,f:1,x:.5}]]},{d:-1,v:[[\"m\",0,164,{r:U,p:1,x:.5}],[\"l\",180,164,{x:0,r:U,f:1}]]}]),G:Y(840,352,360,0,0,0,0,JSON.parse(JSON.stringify(st))),H:Y(684,232,352,0,0,0,0,JSON.parse(JSON.stringify(nt))),I:Y(249,0,352,0,0,0,0,JSON.parse(JSON.stringify(lt))),J:Y(472,172.5,355.5,10,20,-2,-2,JSON.parse(JSON.stringify(ft))),K:Y(616,232,352,-10,-20,0,0,[{d:-1,v:[[\"m\",0,0,{y:0,r:Q}],[\"l\",0,352,{y:0,r:Q,f:1}]]},{d:-1,v:[[\"m\",212,0,{x:.7,y:.7,r:$(212,0,0,162.5)}],[\"l\",0,162.5,{r:U,p:1}],[\"l\",0,165.5,{r:U,p:1,v:1}],[\"l\",232,352,{x:.7,y:.7,f:1}]]}]),L:Y(529,192,352,-10,-20,0,0,[{d:-1,v:[[\"m\",0,0,{y:0}],[\"l\",0,352,{f:1}],[\"l\",192,352,{x:0,f:1}]]}]),M:Y(885,330,352,0,0,0,0,[{d:-1,v:[[\"m\",0,352,{y:0,r:Q}],[\"l\",0,0,{r:Q,f:1}],[\"l\",3,0,{r:Q,p:1,f:1,v:1}],[\"l\",163.5,330,{r:$(163.5,330,163.5,330),f:1}],[\"l\",166.5,330,{r:$(166.5,330,327,0),f:1,v:1}],[\"l\",327,0,{r:Q,p:1,f:1}],[\"l\",330,0,{r:Q,f:1,v:1}],[\"l\",330,352,{y:0,r:Q,f:1}]]}]),N:Y(721,250,352,0,0,0,0,JSON.parse(JSON.stringify(ot))),O:Y(850,360,360,0,0,0,0,JSON.parse(JSON.stringify(ht))),P:Y(568,210,352,-10,-10,-.5,-.5,[{d:1,v:[[\"m\",0,352,{y:0,f:1}],[\"l\",0,0,{f:1}],[\"l\",117,0,{r:U}],[\"b\",168.4,0,210,41.6,210,93,{r:Q}],[\"b\",210,144.4,168.4,186,117,186,{r:U}],[\"l\",0,186,{r:U,p:1}]]}]),Q:Y(850,360,360,0,0,0,0,[{d:-1,v:[[\"m\",360,180,{r:U,p:1,f:1}],[\"b\",360,80.6,279.4,0,180,0,{r:U}],[\"b\",80.6,0,0,80.6,0,180,{r:Q}],[\"b\",0,279.4,80.6,360,180,360,{r:U}],[\"b\",279.4,360,360,279.4,360,180,{r:Q,c:1,f:1}]]},{d:-1,v:[[\"m\",222,222,{x:.5,y:.5,r:$(222,222,360,360)}],[\"l\",360,360,{x:.5,y:.5,f:1}]]}]),R:Y(634,232,352,-10,-10,-.5,-.5,[{d:-1,v:[[\"m\",0,186,{r:U,p:1}],[\"l\",139,186,{r:U}],[\"b\",190.4,186,232,144.4,232,93,{r:Q}],[\"b\",232,41.6,190.4,0,139,0,{r:U}],[\"l\",0,0,{r:Q,f:1}],[\"l\",0,352,{y:0,f:1}]]},{d:-1,v:[[\"m\",139,186,{p:1,r:$(139,186,232,352)}],[\"l\",232,352,{x:.5,y:.39,f:1}]]}]),S:Y(560,224,360,0,0,0,0,JSON.parse(JSON.stringify(yt))),T:Y(568,232,352,0,0,-.5,-.5,[{d:-1,v:[[\"m\",0,0,{x:0,r:U}],[\"l\",232,0,{x:0,r:U,f:1}]]},{d:-1,v:[[\"m\",116,0,{r:Q,p:1}],[\"l\",116,352,{y:0,r:Q,f:1}]]}]),U:Y(712,250,355,0,0,-.5,-.5,JSON.parse(JSON.stringify(dt))),V:Y(650,270,352,0,0,0,0,[{d:-1,v:[[\"m\",0,0,{x:.6,y:.1,r:$(0,0,133.5,352)}],[\"l\",133.5,352,{r:$(0,0,133.5,352),f:1}],[\"l\",136.5,352,{r:$(136.5,352,270,0),f:1,v:1}],[\"l\",270,0,{x:.6,y:.1,f:1}]]}]),W:Y(894,390,352,0,0,0,0,[{d:-1,v:[[\"m\",0,0,{x:.6,y:.05,r:$(0,0,84.5,352)}],[\"l\",84.5,352,{r:$(0,0,84.5,352),f:1}],[\"l\",87.5,352,{r:$(87.5,352,193.5,0),f:1,v:1}],[\"l\",193.5,0,{r:$(87.5,352,193.5,0),f:1}],[\"l\",196.5,0,{r:$(196.5,0,302.5,352),f:1,v:1}],[\"l\",302.5,352,{r:$(196.5,0,302.5,352),f:1}],[\"l\",305.5,352,{r:$(305.5,352,390,0),f:1,v:1}],[\"l\",390,0,{x:.6,y:.05,f:1}]]}]),X:Y(660,270,352,0,0,0,-7,[{d:-1,v:[[\"m\",10,0,{x:.5,y:.3,r:$(10,0,270,352)}],[\"l\",270,352,{x:.5,y:.5,f:1}]]},{d:-1,v:[[\"m\",260,0,{x:.5,y:.3,r:$(260,0,0,352)}],[\"l\",0,352,{x:.5,y:.5,f:1}]]}]),Y:Y(673,270,352,0,0,0,0,JSON.parse(JSON.stringify(ct))),Z:Y(558,232,352,0,-5,0,0,[{d:-1,v:[[\"m\",8,0,{x:0,r:U}],[\"l\",224,0,{r:U,f:1}],[\"l\",224,3,{r:Q,p:1,v:1}],[\"l\",0,349,{r:Q,p:1}],[\"l\",0,352,{r:U,f:1,v:1}],[\"l\",232,352,{x:0,r:U,f:1}]]}])},vt=[{d:-1,v:[[\"m\",232,8,{y:-3.4,r:Q}],[\"l\",232,116,{r:V}],[\"b\",232,180.1,180.1,232,116,232,{r:U}],[\"b\",51.9,232,0,180.1,0,116,{r:Q}],[\"b\",0,51.9,51.9,0,116,0,{r:U}],[\"b\",180.1,0,232,51.9,232,116,{r:Q}],[\"l\",232,224,{y:-.1,r:Q,f:1}]]}],xt=[{d:1,v:[[\"m\",212.1,182.9,{r:tt(212.1,182.9,191.1,213.2,156.1,233.1,116.5,233.1,0),f:1}],[\"b\",191.1,213.2,156.1,233.1,116.5,233.1,{r:U}],[\"b\",52.4,233.1,.5,181.2,.5,117.1,{r:Q}],[\"b\",.5,53,52.4,1.1,116.5,1.1,{r:U}],[\"b\",156.1,1.1,191.1,21,212.1,51.3]]}],ut=[{d:-1,v:[[\"m\",232,0,{y:0}],[\"l\",232,239,{r:V}],[\"b\",232,303.1,180.1,355,116,355,{r:U}],[\"b\",51.9,355,0,303.1,0,239,{r:Q}],[\"b\",0,174.9,51.9,123,116,123,{r:U}],[\"b\",180.1,123,232,174.9,232,239,{r:Q}],[\"l\",232,352,{y:0,f:1}]]}],gt=[{d:1,v:[[\"m\",211.6,182.9,{r:tt(211.6,182.9,191.1,213.2,156.1,233.1,116.5,233.1,0),f:1}],[\"b\",191.1,213.2,156.1,233.1,116.5,233.1,{r:U}],[\"b\",52.4,233.1,.5,181.2,.5,117.1,{r:Q}],[\"b\",.5,53,52.4,1.1,116.5,1.1,{r:U}],[\"b\",176.4,1.1,224.9,47.2,225.5,106.1,{r:Q}],[\"l\",.5,106.1,{r:Q,p:1}]]}],bt=[{d:-1,v:[[\"m\",232,5,{y:-2.8}],[\"l\",232,116,{r:V}],[\"b\",232,180.1,180.1,232,116,232,{r:U}],[\"b\",51.9,232,0,180.1,0,116,{r:Q}],[\"b\",0,51.9,51.9,0,116,0,{r:U}],[\"b\",180.1,0,232,51.9,232,116,{r:Q}],[\"l\",232,222],[\"b\",234.5,300.3,180.2,338.5,116,338,{y:.64,r:U}],[\"b\",76.2,337.7,36.6,320.7,15.7,290.1,{y:.64,f:1}]]}],St=[{d:-1,v:[[\"m\",0,0,{y:0,r:Q}],[\"l\",0,352,{y:0,f:1}]]},{d:-1,v:[[\"m\",0,214,{r:V}],[\"b\",0,163.7,40.7,123,91,123,{r:U}],[\"b\",141.3,123,182,163.7,182,214,{r:Q}],[\"l\",182,352,{y:0,f:1}]]}],mt=[{d:-1,v:[[\"m\",0,130,{y:-3.3}],[\"l\",0,352,{y:0,f:1}]]},{d:-1,v:[[\"m\",0,214,{y:0,r:Q,p:1}],[\"b\",0,163.7,40.7,123,91,123,{r:U}],[\"b\",141.3,123,182,163.7,182,214,{r:Q}],[\"l\",182,352,{y:0,f:1}]]}],Ot=[{d:1,v:[[\"m\",232,116,{r:Q,p:1,f:1}],[\"b\",232,180.1,180.1,232,116,232,{r:U}],[\"b\",51.9,232,0,180.1,0,116,{r:Q}],[\"b\",0,51.9,51.9,0,116,0,{r:U}],[\"b\",180.1,0,232,51.9,232,116,{r:Q,c:1}]]}],Jt=[{d:1,v:[[\"m\",0,295.4*.642,{r:tt(0,295.4*.642,11.2992,332.1*.642,58.3*.642,231.12,70.8126,231.12,0),f:1}],[\"b\",11.2992,332.1*.642,58.3*.642,231.12,70.8126,231.12],[\"b\",173.9*.642,231.12,223.8*.642,329.6*.642,143.808,173.982],[\"b\",143.9364,137.8374,116.0094,121.7232,112.4*.642,173.3*.642],[\"b\",30.3666,101.2434,10.9*.642,130.6*.642,12*.642,54.1848],[\"b\",8.5386,29.8*.642,36.7866,0,73.7016,0],[\"b\",101.6928,0,126.153,13.161,136.104,51.3*.642]]}],Nt=[{d:-1,v:[[\"m\",0,130,{y:-3}],[\"l\",0,265,{r:Q}],[\"b\",0,315.3,40.7,356,91,356,{r:U}],[\"b\",141.3,356,182,315.3,182,265,{r:Q,p:1,f:1}]]},{d:-1,v:[[\"m\",182,130,{y:-3}],[\"l\",182,352,{y:0,f:1}]]}],_t=[{d:-1,v:[[\"m\",225.5,0,{y:-3,r:$(225.5,0,116.3,248.8)}],[\"l\",116.3,248.8,{x:.5,y:.64}],[\"b\",71.8,349.6,0,331.5,0,331.5,{x:.5,y:.64,r:tt(0,331.5,71.8,349.6,116.3,248.8,0,331.5,0),f:1}]]},{d:-1,v:[[\"m\",3.2,0,{y:-3,r:$(3.2,0,125.7,226.6)}],[\"l\",125.7,226.6,{p:1,f:1}]]}],wt={a:Y(600,232,232,10,2,-64,-64,JSON.parse(JSON.stringify(vt))),b:Y(600,232,352,-10,-2,0,0,[{d:-1,v:[[\"m\",0,0,{y:0,r:Q}],[\"l\",0,239,{r:V}],[\"b\",0,303.1,51.9,355,116,355,{r:U}],[\"b\",180.1,355,232,303.1,232,239,{r:Q}],[\"b\",232,174.9,180.1,123,116,123,{r:U}],[\"b\",51.9,123,0,174.9,0,239,{r:Q}],[\"l\",0,352,{y:0,r:Q,f:1}]]}]),c:Y(520,212.1,233.1,2,-10,-64,-64,JSON.parse(JSON.stringify(xt))),d:Y(600,232,352,10,2,0,0,JSON.parse(JSON.stringify(ut))),e:Y(570,225.5,233.1,0,0,-64,-64,JSON.parse(JSON.stringify(gt))),f:Y(356,232,352,-40,-40,0,0,[{d:-1,v:[[\"m\",166.6,33,{x:.5,r:tt(166.6,33,159.3,13.1,139.2,0,116.9,0,0)}],[\"b\",159.3,13.1,139.2,0,116.9,0,{r:U}],[\"b\",88.2,0,65,23.2,65,51.9,{r:Q}],[\"l\",65,352,{y:0,f:1}]]},{d:-1,v:[[\"m\",0,130,{x:0,r:U}],[\"l\",154,130,{x:0,f:1}]]}]),g:Y(600,232,338,10,2,-117,-117,JSON.parse(JSON.stringify(bt))),h:Y(520,182,352,0,0,0,0,JSON.parse(JSON.stringify(St))),i:Y(200,0,352,0,0,0,0,[{d:1,v:[[\"a\",0,90,{y:-3}]]},{d:1,v:[[\"m\",0,352,{y:0,f:1}],[\"l\",0,130,{y:-3}]]}]),j:Y(220,115.9,352,-60,-60,0,0,[{d:1,v:[[\"a\",0,90,{y:-3}]]},{d:1,v:[[\"m\",-115.9,444,{x:.4,y:.63,r:tt(-115.9,444,12.6-115.9,454.4,29.6-115.9,460.2,-70,461.2,0),f:1}],[\"b\",12.6-115.9,454.4,29.6-115.9,460.2,-70,461.2,{x:.4,y:.63,r:U}],[\"b\",84.5-115.9,463.5,0,435.1,0,396.4,{x:.4,y:.63,r:Q}],[\"l\",0,130,{y:-3}]]}]),k:Y(450,164,352,-10,-10,0,0,[{d:-1,v:[[\"m\",0,0,{y:0,r:Q}],[\"l\",0,352,{y:0,f:1}]]},{d:-1,v:[[\"m\",160,130,{x:.7,y:0,r:$(164,130,0,234.5),f:1}],[\"l\",0,234.5,{r:U,p:1}],[\"l\",0,237.5,{r:U,p:1,v:1}],[\"l\",164,352,{x:.7,y:.7,f:1}]]}]),l:Y(200,0,352,0,0,0,0,[{d:1,v:[[\"m\",0,352,{y:0,f:1}],[\"l\",0,0,{y:0}]]}]),m:Y(740,300,352,0,0,0,0,[{d:-1,v:[[\"m\",0,130,{y:-3.6}],[\"l\",0,352,{y:0,f:1}]]},{d:-1,v:[[\"m\",0,198,{y:0,r:Q,p:1}],[\"b\",0,156.6,33.6,123,75,123,{r:U}],[\"b\",116.4,123,150,156.6,150,198,{r:Q}],[\"l\",150,352,{y:0,f:1}]]},{d:-1,v:[[\"m\",150,198,{y:0,r:Q,p:1}],[\"b\",150,156.6,183.6,123,225,123,{r:U}],[\"b\",266.4,123,300,156.6,300,198,{r:Q}],[\"l\",300,352,{y:0,f:1}]]}]),n:Y(520,182,352,0,0,0,0,JSON.parse(JSON.stringify(mt))),o:Y(580,232,232,0,0,-64,-64,JSON.parse(JSON.stringify(Ot))),p:Y(600,232,338,-10,-2,-117,-117,[{d:-1,v:[[\"m\",0,5,{y:-2.8}],[\"l\",0,116,{r:V}],[\"b\",0,180.1,51.9,232,116,232,{r:U}],[\"b\",180.1,232,232,180.1,232,116,{r:Q}],[\"b\",232,51.9,180.1,0,116,0,{r:U}],[\"b\",51.9,0,0,51.9,0,116,{r:Q}],[\"l\",0,338,{y:0,f:1}]]}]),q:Y(600,232,338,10,2,-117,-117,[{d:-1,v:[[\"m\",232,5,{y:-2.8}],[\"l\",232,116,{r:V}],[\"b\",232,180.1,180.1,232,116,232,{r:U}],[\"b\",51.9,232,0,180.1,0,116,{r:Q}],[\"b\",0,51.9,51.9,0,116,0,{r:U}],[\"b\",180.1,0,232,51.9,232,116,{r:Q}],[\"l\",232,338,{y:0,f:1}]]}]),r:Y(340,119.2,352,-20,-20,0,0,[{d:-1,v:[[\"m\",0,130,{y:-3.3}],[\"l\",0,352,{y:0,f:1}]]},{d:-1,v:[[\"m\",0,181,{r:Q,p:1}],[\"b\",0,181,41.9,101.2,119.2,128.5,{x:0,y:2,r:tt(119.2,128.5,41.9,101.2,0,181,119.2,128.5,0),f:1}]]}]),s:Y(400,143.808,231.12,0,0,-64,-64,JSON.parse(JSON.stringify(Jt))),t:Y(356,232,352,-30,-30,0,0,[{d:-1,v:[[\"m\",65,0,{y:0}],[\"l\",65,304.2],[\"b\",65,332.9,88.2,356.1,116.9,356.1,{r:U}],[\"b\",139.2,356.1,159.3,343,166.6,317.1,{x:0,f:1}]]},{d:-1,v:[[\"m\",0,130,{x:0,r:U}],[\"l\",154,130,{x:0,f:1}]]}]),u:Y(520,182,352,0,0,0,0,JSON.parse(JSON.stringify(Nt))),v:Y(500,200,352,0,0,0,0,[{d:-1,v:[[\"m\",0,130,{x:.6,y:-3,r:$(0,130,98.5,352)}],[\"l\",98.5,352,{r:$(0,130,98.5,352),f:1}],[\"l\",101.5,352,{r:$(101.5,352,200,130),f:1,v:1}],[\"l\",200,130,{x:.6,y:-3,f:1}]]}]),w:Y(700,310,352,0,0,0,0,[{d:-1,v:[[\"m\",0,130,{x:.6,y:-3,r:$(0,130,76.5,352)}],[\"l\",76.5,352,{r:$(0,130,76.5,352),f:1}],[\"l\",79.5,352,{r:$(79.5,352,153.5,130),f:1,v:1}],[\"l\",153.5,130,{y:1,r:$(79.5,352,153.5,130),f:1}],[\"l\",156.5,130,{y:1,r:$(156.5,130,231.5,352),f:1,v:1}],[\"l\",231.5,352,{r:$(156.5,130,231.5,352),f:1}],[\"l\",234.5,352,{r:$(234.5,352,310,130),f:1,v:1}],[\"l\",310,130,{x:.6,y:-3,f:1}]]}]),x:Y(490,210,352,0,0,0,-7,[{d:-1,v:[[\"m\",10,130,{x:.5,y:-1,r:$(10,130,210,352)}],[\"l\",210,352,{x:.5,y:.5,f:1}]]},{d:-1,v:[[\"m\",200,130,{x:.5,y:-1,r:$(200,130,0,352)}],[\"l\",0,352,{x:.5,y:.5,f:1}]]}]),y:Y(500,225.5,331.5,10,10,-119,-119,JSON.parse(JSON.stringify(_t))),z:Y(420,172,352,0,0,0,0,[{d:-1,v:[[\"m\",6,130,{x:-.5,y:1,r:U}],[\"l\",166,130,{x:1.8,y:1,r:U,f:1}],[\"l\",166,133,{x:1.8,y:1,r:Q,p:1,v:1}],[\"l\",0,349,{x:1.7,r:Q,p:1}],[\"l\",0,352,{x:1.7,r:U,f:1,v:1}],[\"l\",172,352,{x:-.4,r:U,f:1}]]}])},Pt={0:Y(660,270,360,0,0,0,0,[{d:1,v:[[\"m\",270,180,{r:Q,p:1,f:1}],[\"b\",270,279.4,209.6,360,135,360,{r:U}],[\"b\",60.4,360,0,279.4,0,180,{r:Q}],[\"b\",0,80.6,60.4,0,135,0,{r:U}],[\"b\",209.6,0,270,80.6,270,180,{r:Q,c:1}]]}]),1:Y(380,76,352,15,15,0,0,[{d:-1,v:[[\"m\",0,51,{x:-2,y:2,r:$(0,51,73,0)}],[\"l\",73,0,{r:Q,p:1}],[\"l\",76,0,{r:Q,f:1,v:1}],[\"l\",76,352,{y:0,f:1}]]}]),2:Y(580,210,356,0,0,2,2,[{d:-1,v:[[\"m\",3.9,68.8,{x:1.2,y:1.2,r:tt(3.9,68.8,16.7,29,54.2,3.1,98.2,.2,0)}],[\"b\",16.7,29,54.2,3.1,98.2,.2],[\"b\",151.8,-3.3,208.5,38.3,198.9,100.1],[\"b\",197.1,111.8,196.4,142.4,101.5,235.2],[\"b\",11.4,323.2,0,353,0,353,{r:V}],[\"l\",0,353,{r:U,p:1}],[\"l\",0,356,{r:U,f:1,v:1}],[\"l\",210,356,{x:-.5,f:1}]]}]),3:Y(580,222.1,360,0,0,0,0,[{d:-1,v:[[\"m\",10.7,66.3,{r:tt(10.7,66.3,11.2,64.8,11.7,63.3,12.3,61.8,0)}],[\"b\",11.2,64.8,11.7,63.3,12.3,61.8,{r:V}],[\"b\",25.8,25.9,64.5,0,110.1,0,{r:U}],[\"b\",167,0,213.1,40.3,213.1,90,{r:Q}],[\"b\",213.1,139.7,167,180,110.1,179.9,{r:U,f:1}],[\"l\",100.1,179.9,{x:-5,y:1,r:U,f:1}],[\"l\",110.1,180,{r:U,p:1}],[\"b\",172,180,222.1,220.3,222.1,270,{r:Q}],[\"b\",222.1,319.7,172,360,110.1,360,{r:U}],[\"b\",56.9,360,12.4,330.2,1,290.3,{f:1}]]}]),4:Y(596,236,352,0,0,0,0,[{d:1,v:[[\"m\",175,352,{y:0,f:1}],[\"l\",175,0,{f:1}],[\"l\",172,0,{r:U,p:1,v:1}],[\"l\",0,273,{r:Q,p:1}],[\"l\",0,276,{r:U,f:1,v:1}],[\"l\",236,276,{x:-.5}]]}]),5:Y(596,208.5,356,0,-5,-2,-2,[{d:1,v:[[\"m\",0,295.7,{r:tt(0,295.7,15.3,333.8,52.2,356.2,97.5,356,0),f:1}],[\"b\",15.3,333.8,52.2,356.2,97.5,356,{r:U}],[\"b\",159.1,355.7,206.1,306.9,208.5,240.8,{r:Q}],[\"b\",210.9,173.9,162.7,120.8,97.5,125.6,{r:U}],[\"b\",59.4,128.4,25.5,145.8,5.6,176.4,{f:1}],[\"l\",5.6,176.4,{r:V}],[\"l\",5.6-3,176.4,{r:Q,p:1,v:1}],[\"l\",11.5,0,{r:U,f:1}],[\"l\",193.5,0,{x:-.5}]]}]),6:Y(596,215.8,360,0,-2,0,0,[{d:1,v:[[\"m\",7.6,272.3,{r:Q,p:1,f:1}],[\"b\",6.4,265.8,5.8,259.1,5.8,252.2,{r:Q}],[\"b\",5.8,192.6,52.8,144.2,110.8,144.2,{r:U}],[\"b\",168.7,144.2,215.8,192.6,215.8,252.2,{r:Q}],[\"b\",215.8,311.9,168.7,360,110.8,360,{r:U}],[\"b\",59.5,360,16.8,322.4,7.6,272.4,{r:V}],[\"b\",7.6,272.4,-44.1,8.8,122.2,.2],[\"b\",165.5,-2.1,193.8,21,212.1,56.4]]}]),7:Y(540,213,352,0,0,0,0,[{d:-1,v:[[\"m\",0,0,{x:0,r:U}],[\"l\",213,0,{r:U,f:1}],[\"l\",213,.1,{r:V}],[\"l\",72.7,352,{y:.1,f:1}]]}]),8:Y(596,224,360,0,0,0,0,[{d:1,v:[[\"m\",112,180,{r:Q,p:1,f:1}],[\"b\",50.1,180,0,220.3,0,270,{r:Q}],[\"b\",0,319.7,50.1,360,112,360,{r:U}],[\"b\",173.9,360,224,319.7,224,270,{r:Q}],[\"b\",224,220.3,173.9,180,112,180,{r:U}],[\"b\",55.1,180,9,139.7,9,90,{r:Q}],[\"b\",9,40.3,55.1,0,112,0,{r:U}],[\"b\",168.9,0,215,40.3,215,90,{r:Q}],[\"b\",215,139.7,168.9,180,112,180,{r:Q,p:1,f:1}]]}]),9:Y(596,215.8,360,0,-2,0,0,[{d:-1,v:[[\"m\",208.2,88,{r:Q,p:1,f:1}],[\"b\",209.4,94.5,210,101.2,210,108,{r:Q}],[\"b\",210,167.6,163,216,105,216,{r:U}],[\"b\",47,216,-0,167.6,0,108,{r:Q}],[\"b\",0,48.4,47,-0,105,0,{r:U}],[\"b\",156.3,0,199,37.8,208.2,87.8,{r:V}],[\"b\",208.2,87.8,259.8,351.4,93.5,360],[\"b\",50.3,362.3,21.9,339.2,3.6,303.8,{f:1}]]}])},Wt={\" \":Y(336,0,0,0,0,0,0,[{d:1,v:[]}]),tofu:Y(672,232,352,0,0,0,0,[{d:-1,v:[[\"m\",0,0,{r:Q}],[\"l\",232,0,{r:Q,f:1}],[\"l\",232,352,{r:Q,f:1}],[\"l\",0,352,{r:Q,f:1}],[\"l\",0,0,{r:Q,p:1,f:1,c:1}]]},{d:1,v:[[\"m\",0,0,{r:Q,p:1,f:1}],[\"l\",232,352,{r:V}]]}]),\"?\":Y(520,190.348,360,0,-5,0,0,[{d:1,v:[[\"a\",89.174,356]]},{d:-1,v:[[\"m\",0,87.8,{r:tt(0,87.8,12,-2.3,99.1,0,0,87.8,0)}],[\"b\",0,87.8,12,-2.3,99.1,0,{r:U}],[\"b\",186.2,2.4,204.5,75.2,180.9,121.4],[\"b\",157.3,167.6,119.7,178.3,97.4,223.2],[\"b\",90.5,237.1,88.1,249.8,88,260.8,{r:Q,f:1}]]}]),\"¿\":Y(520,190.348,360,0,-5,0,0,[{d:1,v:[[\"a\",101.174,93]]},{d:-1,v:[[\"m\",190.3,361,{r:tt(190.3,361,178.3,451.1,91.2,448.8,190.3,361,0)}],[\"b\",190.3,361,178.3,451.1,91.2,448.8,{r:U}],[\"b\",4.1,446.4,-14.2,373.6,9.4,327.4],[\"b\",33,281.2,70.6,270.5,92.9,225.6],[\"b\",99.8,211.7,102.2,199,102.3,188,{r:Q,f:1}]]}]),\"!\":Y(465,8,355,0,-5,0,0,[{d:1,v:[[\"a\",4,356]]},{d:-1,v:[[\"m\",4,0,{y:0}],[\"l\",4,260.8,{f:1}]]}]),\"¡\":Y(465,8,355,0,-5,0,0,[{d:1,v:[[\"a\",4,93]]},{d:-1,v:[[\"m\",4,188],[\"l\",4,448.8,{f:1,y:.3}]]}]),$:Y(568,224,360,0,0,0,0,[{d:-1,v:[[\"m\",212,51.3,{r:tt(0,295.4,17.6,332.1,58.3,360,110.3,360,0),f:1}],[\"b\",196.5,20.5,158.4,0,114.8,0],[\"b\",57.3,0,13.3,29.8,12,84.4],[\"b\",10.9,130.6,47.3,157.7,112.4,173.3],[\"b\",180.7,189.6,224.2,214.7,224,271],[\"b\",223.8,329.6,173.9,360,110.3,360],[\"b\",58.3,360,17.6,332.1,0,295.4,{f:1}]]},{d:-1,v:[[\"m\",112,-30,{y:0}],[\"l\",112,390,{y:0,f:1}]]}]),\"@\":Y(820,343.425,360,0,0,-30,-30,[{d:-1,v:[[\"m\",251.9,92.9,{r:$(251.9,92.9,238.5,181.7)}],[\"l\",238.5,181.7,{r:V}],[\"b\",227.8,236,194.7,267.2,143.7,259.2],[\"b\",99.1,252.2,87.7,208.5,90.1,177.5],[\"b\",92.5,148.4,118.1,91,183.3,99.1],[\"b\",251,107.5,238.5,181.7,238.5,181.7,{r:V}],[\"l\",232.5,221.5],[\"b\",232.5,221.5,227.2,257.6,256,263.6],[\"b\",284.9,269.7,309,241.3,309,241.3,{r:V}],[\"b\",309,241.3,343.4,209,343.4,146.7],[\"b\",343.4,84.3,297.4,3.5,178.6,.1],[\"b\",59.7,-3.4,-5.3,105.2,.3,203.4],[\"b\",6.1,303.7,93.2,354.5,175.5,359.5],[\"b\",175.5,359.5,246.5,364.9,302.7,339.8,{f:1}]]}]),\"#\":Y(760,314,352,0,0,0,0,[{d:-1,v:[[\"m\",117,0,{y:0,r:$(117,0,47,352)}],[\"l\",47,352,{y:0,f:1}]]},{d:-1,v:[[\"m\",267,0,{y:0,r:$(267,0,197,352)}],[\"l\",197,352,{y:0,f:1}]]},{d:-1,v:[[\"m\",24,117,{x:0,r:U}],[\"l\",314,117,{x:0,f:1}]]},{d:-1,v:[[\"m\",0,235,{x:0,r:U}],[\"l\",290,235,{x:0,f:1}]]}]),\"%\":Y(920,388,360,0,0,0,0,[{d:-1,v:[[\"m\",307.1,5.1,{x:0,y:0,r:$(307.1,5.1,80.9,354.9)}],[\"l\",80.9,354.9,{x:0,y:0,f:1}]]},{d:-1,v:[[\"m\",146,73,{r:Q,p:1}],[\"b\",146,113.3,113.3,146,73,146,{r:U}],[\"b\",32.7,146,0,113.3,0,73,{r:Q}],[\"b\",0,32.7,32.7,0,73,0,{r:U}],[\"b\",113.3,0,146,32.7,146,73,{r:Q,c:1,f:1}]]},{d:-1,v:[[\"m\",388,287,{r:Q,p:1}],[\"b\",388,327.3,355.3,360,315,360,{r:U}],[\"b\",274.7,360,242,327.3,242,287,{r:Q}],[\"b\",242,246.7,274.7,214,315,214,{r:U}],[\"b\",355.3,214,388,246.7,388,287,{r:Q,c:1,f:1}]]}]),\"^\":Y(596,176,352,0,0,0,0,[{d:-1,v:[[\"m\",0,150,{r:$(0,150,86.5,0)}],[\"l\",86.5,0,{r:$(0,150,86.5,0),f:1}],[\"l\",89.5,0,{r:$(89.5,0,176,150),f:1,v:1}],[\"l\",176,150,{f:1}]]}]),\"·\":Y(231,8,355,0,0,0,0,[{d:1,v:[[\"a\",4,183.5]]}]),\"×\":Y(712,176.8,176.8,0,0,0,0,[{d:-1,v:[[\"m\",0,0,{x:0,y:0,r:$(0,0,176.8,176.8)}],[\"l\",176.8,176.8,{x:0,y:0,f:1}]]},{d:-1,v:[[\"m\",176.8,0,{x:0,y:0,r:$(176.8,0,0,176.88)}],[\"l\",0,176.8,{x:0,y:0,f:1}]]}]),\"÷\":Y(712,188,0,0,0,0,0,[{d:1,v:[[\"a\",94,110]]},{d:1,v:[[\"a\",94,-110]]},{d:-1,v:[[\"m\",0,0,{x:0,y:0,r:U}],[\"l\",188,0,{x:0,y:0,f:1}]]}]),\"«\":Y(896,310,236,0,0,0,0,[{d:1,v:[[\"m\",150,236,{r:$(150,236,0,119.5),f:1}],[\"l\",0,119.5,{r:$(150,236,0,119.5),f:1}],[\"l\",0,116.5,{r:$(0,116.5,150,0),f:1,v:1}],[\"l\",150,0]]},{d:1,v:[[\"m\",310,236,{r:$(310,236,160,119.5),f:1}],[\"l\",160,119.5,{r:$(310,236,160,119.5),f:1}],[\"l\",160,116.5,{r:$(160,116.5,310,0),f:1,v:1}],[\"l\",310,0]]}]),\"»\":Y(896,310,236,0,0,0,0,[{d:1,v:[[\"m\",0,236,{r:$(0,236,150,119.5),f:1}],[\"l\",150,119.5,{r:$(0,236,0,119.5),f:1}],[\"l\",150,116.5,{r:$(150,116.5,0,0),f:1,v:1}],[\"l\",0,0]]},{d:1,v:[[\"m\",160,236,{r:$(160,236,310,119.5),f:1}],[\"l\",310,119.5,{r:$(0,236,0,119.5),f:1}],[\"l\",310,116.5,{r:$(310,116.5,160,0),f:1,v:1}],[\"l\",160,0]]}]),\"&\":Y(660,259.191,360,0,0,0,0,[{d:1,v:[[\"m\",257.9,355,{x:.5,y:.5,r:$(257.9,355,52.8,135.3),f:1}],[\"l\",52.8,135.3],[\"b\",52.8,135.3,-2.2,79.5,46.6,26.7],[\"b\",46.6,26.7,68.1,0,101.8,0,{r:U}],[\"b\",137.2,0,174.1,21.1,181.2,65.3],[\"b\",188.6,111.7,142.6,142.9,108.9,162.9],[\"b\",75.2,182.8,40.8,211.4,40.8,211.4,{r:V}],[\"b\",35,217.1,-34.7,273.7,22.2,330.5],[\"b\",22.2,330.5,48.1,360,93.4,360,{r:U}],[\"b\",138.6,360,212.2,322,259.2,200.5]]}]),\"*\":Y(558,183.597,212,0,0,0,0,[{d:-1,v:[[\"m\",91.8,0,{x:0,y:0}],[\"l\",91.8,212,{x:0,y:0,f:1}]]},{d:-1,v:[[\"m\",0,53,{x:0,y:0,r:$(0,53,183.6,159)}],[\"l\",183.6,159,{x:0,y:0,f:1}]]},{d:-1,v:[[\"m\",0,159,{x:0,y:0,r:$(0,159,183.6,53)}],[\"l\",183.6,53,{x:0,y:0,f:1}]]}]),\"+\":Y(712,250,250,0,0,0,0,[{d:-1,v:[[\"m\",125,0,{x:0,y:0}],[\"l\",125,250,{x:0,y:0,f:1}]]},{d:-1,v:[[\"m\",0,125,{x:0,y:0,r:U}],[\"l\",250,125,{x:0,y:0,f:1}]]}]),\"=\":Y(712,216,86,0,0,0,0,[{d:-1,v:[[\"m\",0,0,{x:0,y:0,r:U}],[\"l\",216,0,{x:0,y:0,f:1}]]},{d:-1,v:[[\"m\",0,86,{x:0,y:0,r:U}],[\"l\",216,86,{x:0,y:0,f:1}]]}]),\"-\":Y(712,188,0,0,0,0,0,[{d:-1,v:[[\"m\",0,0,{x:0,y:0,r:U}],[\"l\",188,0,{x:0,y:0,f:1}]]}]),_:Y(481,235,400,0,0,0,0,[{d:-1,v:[[\"m\",0,400,{x:0,y:0,r:U}],[\"l\",235,400,{x:0,y:0,f:1}]]}]),\":\":Y(231,8,355,0,0,0,0,[{d:1,v:[[\"a\",4,183.5]]},{d:1,v:[[\"a\",4,353.5]]}]),\";\":Y(231,8,355,0,0,0,0,[{d:1,v:[[\"a\",4,183.5]]},{d:-1,v:[[\"m\",4,350,{x:0,y:2,r:$(4,350,-6,430)}],[\"l\",-6,430,{x:0,y:.5,f:1}]]}]),\".\":Y(231,8,355,0,0,0,0,[{d:1,v:[[\"a\",4,353.5]]}]),\",\":Y(231,10,355,10,10,0,0,[{d:-1,v:[[\"m\",10,350,{x:0,y:2,r:$(10,350,0,430)}],[\"l\",0,430,{x:0,y:.5,f:1}]]}]),\"'\":Y(173,0,360,0,0,0,0,[{d:-1,v:[[\"m\",0,0,{x:0,y:0}],[\"l\",0,80,{x:0,y:0,f:1}]]}]),'\"':Y(297,60,360,0,0,0,0,[{d:-1,v:[[\"m\",0,0,{x:-1.5,y:0}],[\"l\",0,80,{x:-1.5,y:0,f:1}]]},{d:-1,v:[[\"m\",60,0,{x:-1.5,y:0}],[\"l\",60,80,{x:-1.5,y:0,f:1}]]}]),\"~\":Y(731,199.391,47.063,0,0,0,0,[{d:1,v:[[\"m\",199.4,20.7,{x:0,y:0,r:tt(199.4,20.7,187.6,36.6,168.2,47.1,148.2,47.1,0),f:1}],[\"b\",187.6,36.6,168.2,47.1,148.2,47.1,{x:0,y:0,r:U}],[\"b\",129.1,47.1,112.1,36.6,95.3,25.5,{x:0,y:0}],[\"b\",76.8,13.2,59.1,0,39.6,0,{x:0,y:0,r:U}],[\"b\",22.3,0,10.9,8.9,0,20,{x:0,y:0}]]}]),\"(\":Y(365,107.865,360,0,0,0,0,[{d:1,v:[[\"m\",107.9,360,{y:.8,r:tt(107.9,360,39.7,321.1,0,259.8,0,182.9,0),f:1}],[\"b\",39.7,321.1,0,259.8,0,182.9,{y:.8,r:Q}],[\"b\",0,100.2,39.7,38.9,107.9,0,{y:.8}]]}]),\")\":Y(365,107.865,360,0,0,0,0,[{d:-1,v:[[\"m\",0,0,{y:.8,r:tt(0,0,68.2,38.9,107.9,100.2,107.9,177,0)}],[\"b\",68.2,38.9,107.9,100.2,107.9,177,{y:.8,r:Q}],[\"b\",107.9,259.8,68.2,321.1,0,360,{y:.8,f:1}]]}]),\"{\":Y(385,107.865,360,0,0,0,0,[{d:1,v:[[\"m\",94.5,360,{x:-.5,r:U}],[\"l\",77.9,360,{x:-.5}],[\"b\",57.4,360,37,343,37,310.7,{x:-.5}],[\"l\",37,233.4,{x:-.5}],[\"b\",37,207.9,24.3,183.7,3.8,180.7,{x:-.5,r:U}],[\"l\",3.8,179.8,{x:-.5,r:U,p:1}],[\"b\",24.3,176.8,37,153.1,37,126.7,{x:-.5}],[\"l\",37,49.4,{x:-.5}],[\"b\",37,17.1,57.4,.1,77.9,.1,{x:-.5}],[\"l\",94.5,.1,{x:-.5}]]}]),\"}\":Y(385,107.865,360,0,0,0,0,[{d:-1,v:[[\"m\",13.4,.1,{x:-.5,r:U}],[\"l\",30,.1,{x:-.5}],[\"b\",50.4,.1,70.8,17.1,70.8,49.4,{x:-.5}],[\"l\",70.8,126.7,{x:-.5}],[\"b\",70.8,153.1,83.6,176.8,104,179.8,{x:-.5,r:U}],[\"l\",104,180.7,{x:-.5,r:U,p:1}],[\"b\",83.6,183.7,70.8,207.9,70.8,233.4,{x:-.5}],[\"l\",70.8,310.7,{x:-.5}],[\"b\",70.8,343,50.4,360,30,360,{x:-.5}],[\"l\",13.4,360,{x:-.5}]]}]),\"[\":Y(365,66,352,0,0,0,0,[{d:-1,v:[[\"m\",66,0,{x:-1,r:U}],[\"l\",0,0,{r:Q,f:1}],[\"l\",0,352,{r:Q,f:1}],[\"l\",66,352,{x:-1,f:1}]]}]),\"]\":Y(365,66,352,0,0,0,0,[{d:-1,v:[[\"m\",0,0,{x:-1,r:U}],[\"l\",66,0,{r:Q,f:1}],[\"l\",66,352,{r:Q,f:1}],[\"l\",0,352,{x:-1,f:1}]]}]),\"<\":Y(423,90,352,0,0,0,0,[{d:-1,v:[[\"m\",90,0,{x:-1,y:.3,r:$(90,0,0,176)}],[\"l\",0,176,{r:Q,f:1}],[\"l\",90,352,{x:-1,y:.3,f:1}]]}]),\">\":Y(423,90,352,0,0,0,0,[{d:-1,v:[[\"m\",0,0,{x:-1,y:.3,r:$(0,0,90,176)}],[\"l\",90,176,{r:Q,f:1}],[\"l\",0,352,{x:-1,y:.3,f:1}]]}]),\"/\":Y(433,130,352,0,0,0,0,[{d:1,v:[[\"m\",0,352,{r:$(0,352,130,0),f:1,y:0}],[\"l\",130,0,{y:0}]]}]),\"þ\":Y(600,232,338,-10,-2,-117,-117,[{d:-1,v:[[\"m\",0,-106,{y:0}],[\"l\",0,116,{r:V}],[\"b\",0,180.1,51.9,232,116,232,{r:U}],[\"b\",180.1,232,232,180.1,232,116,{r:Q}],[\"b\",232,51.9,180.1,0,116,0,{r:U}],[\"b\",51.9,0,0,51.9,0,116,{r:Q}],[\"l\",0,338,{y:0,f:1}]]}]),\"Þ\":Y(520,162,352,-5,-70,0,0,[{d:-1,v:[[\"m\",0,0,{x:0,y:0,r:Q}],[\"l\",0,352,{x:0,y:0,r:Q,f:1}]]},{d:1,v:[[\"m\",0,281.6,{x:0,r:U,f:1,p:1}],[\"l\",57,281.6,{x:-.5,r:U,f:1}],[\"b\",115,281.6,162,233.4,162,175.4,{x:-.5,r:Q}],[\"b\",162,117.4,115,70.4,57,70.4,{x:-.5,r:U}],[\"l\",0,70.4,{x:0,r:U,f:1,p:1}]]}]),\"ß\":Y(596,209,352,-10,-10,0,0,[{d:1,v:[[\"m\",0,348.3,{r:Q,f:1,x:0,y:0}],[\"l\",0,104.3,{x:0}],[\"b\",0,46,36,0,98.9,0,{x:0}],[\"b\",145.2,0,191,27.9,191,81,{x:1}],[\"b\",191,110.7,165.6,131.8,151.8,140.9],[\"l\",140,148.8],[\"b\",120.6,161.7,110.8,172.8,110.8,185.5],[\"b\",110.8,206.7,131.6,213.8,140,217.5],[\"b\",190.6,241.1,211,262.7,211,289.6],[\"b\",211,329.5,174.8,352,142.5,352],[\"b\",97.3,352,75.2,319.7,72.3,289.3]]}])};function kt(t,r){var i=t,e=-60+r;return[{d:-1,v:[[\"m\",-40+i,e,{x:0,y:0,r:$(-40+i,e,0+i,60+e)}],[\"l\",0+i,60+e,{x:0,y:0,f:1}]]}]}function Dt(t,r){var i=t,e=-60+r;return[{d:-1,v:[[\"m\",40+i,e,{x:0,y:0,r:$(40+i,e,0+i,60+e)}],[\"l\",0+i,60+e,{x:0,y:0,f:1}]]}]}function Tt(t,r){var i=-68+t,e=0+r;return[{d:-1,v:[[\"m\",0+i,50+e,{r:$(0+i,50+e,66.5+i,0+e),y:0,x:0}],[\"l\",66.5+i,0+e,{r:$(0+i,50+e,66.5+i,0+e),y:0,x:0,f:1}],[\"l\",69.5+i,0+e,{r:$(69.5+i,0+e,136+i,50+e),y:0,x:0,f:1,v:1}],[\"l\",136+i,50+e,{y:0,x:0,f:1}]]}]}function It(t,r){var i=t-76.24,e=r;return[{d:1,v:[[\"m\",159.52+i,16.56+e,{x:-1,y:-.2,r:tt(159.52+i,16.56+e,150.08+i,29.28+e,134.56+i,37.68+e,118.56+i,37.68+e,0),f:1}],[\"b\",150.08+i,29.28+e,134.56+i,37.68+e,118.56+i,37.68+e,{x:-1,y:-.2,r:U}],[\"b\",103.28+i,37.68+e,89.68+i,29.28+e,76.24+i,20.4+e,{x:-1,y:-.2}],[\"b\",61.44+i,10.56+e,47.28+i,0+e,31.68+i,0+e,{x:-1,y:-.2,r:U}],[\"b\",17.84+i,0+e,8.72+i,7.12+e,0+i,16+e,{x:-1,y:-.2}]]}]}function Rt(t,r){return[{d:1,v:[[\"a\",-50+t,r,{x:0,y:0}]]},{d:1,v:[[\"a\",50+t,r,{x:0,y:0}]]}]}function Ft(t,r){var i=t-57,e=r;return[{d:1,v:[[\"m\",112.7+i,0+e,{r:tt(112.7+i,0+e+i,10.1+e,110.1+i,19.3+e,105+i,27.7+e,0),x:0,y:0,f:1}],[\"b\",112.7+i,10.1+e,110.1+i,19.3+e,105+i,27.7+e,{x:0,y:0}],[\"b\",99.8+i,36.1+e,92.9+i,42.8+e,84.3+i,47.7+e,{x:0,y:0}],[\"b\",75.7+i,52.6+e,66.7+i,55+e,57.3+i,55+e,{x:0,y:0}],[\"b\",47.5+i,55+e,38.3+i,52.6+e,29.6+i,47.7+e,{x:0,y:0}],[\"b\",20.8+i,42.8+e,13.8+i,36.1+e,8.5+i,27.7+e,{x:0,y:0}],[\"b\",3.2+i,19.3+e,.5+i,10.1+e,.5+i,0+e,{x:0,y:0}]]}]}function Mt(t,r){var i=88+t,e=-116+r;return[{d:1,v:[[\"m\",116+i,58+e,{r:Q,p:1,f:1}],[\"b\",116+i,90.05+e,90.05+i,116+e,58+i,116+e,{r:U}],[\"b\",25.95+i,116+e,0+i,90.05+e,0+i,58+e,{r:Q}],[\"b\",0+i,25.95+e,25.95+i,0+e,58+i,0+e,{r:U}],[\"b\",90.05+i,0+e,116+i,25.95+e,116+i,58+e,{r:Q,c:1}]]}]}function Gt(t,r){return[{d:1,v:[[\"m\",t-40,r,{x:0,y:1,r:U}],[\"l\",100+t,r,{x:0,y:1,f:1}]]}]}function zt(t,r){return[{d:-1,v:[[\"m\",t,r,{p:1}],[\"b\",9.3+t,11.6+r,15.6+t,27.1+r,15.6+t,40.9+r],[\"b\",15.6+t,83.3+r,-18.2+t,107.8+r,-59.5+t,107.8+r],[\"b\",-70.9+t,107.8+r,-82.9+t,106.2+r,-93.7+t,102.7+r,{x:.5,f:1}]]}]}function Lt(t,r){return[{d:-1,v:[[\"m\",t,r,{p:1}],[\"b\",-19.6+t,14.8+r,-42.2+t,37.9+r,-42.2+t,64.1+r],[\"b\",-42.2+t,100.3+r,30.2-42.2+t,118.8+r,21.4+t,118.8+r],[\"b\",68.3-42.2+t,118.8+r,72.9-42.2+t,118.4+r,35.2+t,117.6+r,{x:.5,f:1}]]}]}function jt(t,r){return[{d:1,v:[[\"a\",t,r,{x:0,y:0}]]}]}function Ct(t,r){var i=-68+t,e=r;return[{d:-1,v:[[\"m\",0+i,e,{r:$(0+i,e,66.5+i,50+e),y:0,x:0}],[\"l\",66.5+i,50+e,{r:$(0+i,e,66.5+i,50+e),y:0,x:0,f:1}],[\"l\",69.5+i,50+e,{r:$(69.5+i,50+e,136+i,e),y:0,x:0,f:1,v:1}],[\"l\",136+i,e,{y:0,x:0,f:1}]]}]}function At(t,r){return[{d:1,v:[[\"m\",t-50,r,{x:0,y:0}],[\"l\",t+50,r,{x:0,y:0,f:1}]]}]}var qt,Xt,Et=[{d:1,v:[[\"m\",0,352,{y:0,f:1}],[\"l\",0,130,{y:-3}]]}],Bt=[{d:1,v:[[\"m\",-115.9,444,{x:.4,y:.63,r:tt(-115.9,444,12.6-115.9,454.4,29.6-115.9,460.2,-70,461.2,0),f:1}],[\"b\",12.6-115.9,454.4,29.6-115.9,460.2,-70,461.2,{x:.4,y:.63,r:U}],[\"b\",84.5-115.9,463.5,0,435.1,0,396.4,{x:.4,y:.63,r:Q}],[\"l\",0,130,{y:-3}]]}],Ht={\"Æ\":Y(996,426,352,0,0,0,0,[{d:-1,v:[[\"m\",426,0,{x:0,r:U}],[\"l\",234,0,{x:.5,f:1,r:$(234,0,0,352)}],[\"l\",0,352,{x:.5,y:.5,f:1}]]},{d:-1,v:[[\"m\",234,0,{x:.5,p:1}],[\"l\",234,352,{f:1,x:.5}],[\"l\",426,352,{f:1,x:0}]]},{d:-1,v:[[\"m\",76.4,237,{r:U,p:1}],[\"l\",234,237,{f:1,r:U,p:1}]]},{d:-1,v:[[\"m\",234,164,{r:U,p:1,x:.5}],[\"l\",414,164,{f:1,x:0}]]}]),\"æ\":Y(1e3,457.5,232,0,0,-64,-64,[{d:-1,v:[[\"m\",232,8,{y:-3.4,r:Q}],[\"l\",232,116,{r:V}],[\"b\",232,180.1,180.1,232,116,232,{r:U}],[\"b\",51.9,232,0,180.1,0,116,{r:Q}],[\"b\",0,51.9,51.9,0,116,0,{r:U}],[\"b\",180.1,0,232,51.9,232,116,{r:Q}],[\"l\",232,224,{y:-.1,r:Q,f:1}]]},{d:1,v:[[\"m\",443.6,182.9,{r:tt(443.6,182.9,423.1,213.2,388.1,233.1,348.5,233.1,0),f:1}],[\"b\",423.1,213.2,388.1,233.1,348.5,233.1,{r:U}],[\"b\",284.4,233.1,232.5,181.2,232.5,117.1,{r:Q}],[\"b\",232.5,53,284.4,1.1,348.5,1.1,{r:U}],[\"b\",408.4,1.1,456.9,47.2,457.5,106.1,{r:Q}],[\"l\",232.5,106.1,{r:Q,p:1}]]}]),\"À\":Y(620,290,352,0,0,0,0,JSON.parse(JSON.stringify(rt)).concat(kt(145,-50))),\"Á\":Y(620,290,352,0,0,0,0,JSON.parse(JSON.stringify(rt)).concat(Dt(145,-50))),\"Â\":Y(620,290,352,0,0,0,0,JSON.parse(JSON.stringify(rt)).concat(Tt(145,-100))),\"Ã\":Y(620,290,352,0,0,0,0,JSON.parse(JSON.stringify(rt)).concat(It(145,-90))),\"Ä\":Y(620,290,352,0,0,0,0,JSON.parse(JSON.stringify(rt)).concat(Rt(145,-70))),\"Å\":Y(620,290,352,0,0,0,0,JSON.parse(JSON.stringify(rt)).concat(Mt(0,0))),\"Ă\":Y(620,290,352,0,0,0,0,JSON.parse(JSON.stringify(rt)).concat(Ft(145,-110))),\"Ą\":Y(620,290,352,0,0,0,0,JSON.parse(JSON.stringify(rt)).concat(Lt(290,352))),\"à\":Y(600,232,232,10,2,-64,-64,JSON.parse(JSON.stringify(vt)).concat(kt(116,-60))),\"á\":Y(600,232,232,10,2,-64,-64,JSON.parse(JSON.stringify(vt)).concat(Dt(116,-60))),\"â\":Y(600,232,232,10,2,-64,-64,JSON.parse(JSON.stringify(vt)).concat(Tt(116,-110))),\"ã\":Y(600,232,232,10,2,-64,-64,JSON.parse(JSON.stringify(vt)).concat(It(116,-100))),\"ä\":Y(600,232,232,10,2,-64,-64,JSON.parse(JSON.stringify(vt)).concat(Rt(116,-80))),\"å\":Y(600,232,232,10,2,-64,-64,JSON.parse(JSON.stringify(vt)).concat(Mt(-30,0))),\"ă\":Y(600,232,232,10,2,-64,-64,JSON.parse(JSON.stringify(vt)).concat(Ft(116,-120))),\"ą\":Y(600,232,232,10,2,-64,-64,JSON.parse(JSON.stringify(vt)).concat(Lt(232,224))),\"Ć\":Y(700,293.1,360,0,0,0,0,JSON.parse(JSON.stringify(it)).concat(kt(180,-60))),\"Ĉ\":Y(700,293.1,360,0,0,0,0,JSON.parse(JSON.stringify(it)).concat(Tt(180,-110))),\"Ċ\":Y(700,293.1,360,0,0,0,0,JSON.parse(JSON.stringify(it)).concat(jt(180,-80))),\"Č\":Y(700,293.1,360,0,0,0,0,JSON.parse(JSON.stringify(it)).concat(Ct(180,-110))),\"Ç\":Y(700,293.1,360,0,0,0,0,JSON.parse(JSON.stringify(it)).concat(zt(180,360))),\"ć\":Y(520,212.1,233.1,2,-10,-64,-64,JSON.parse(JSON.stringify(xt)).concat(kt(116.5,-68.9))),\"ĉ\":Y(520,212.1,233.1,2,-10,-64,-64,JSON.parse(JSON.stringify(xt)).concat(Tt(116.5,-118.9))),\"ċ\":Y(520,212.1,233.1,2,-10,-64,-64,JSON.parse(JSON.stringify(xt)).concat(jt(116.5,-88.9))),\"č\":Y(520,212.1,233.1,2,-10,-64,-64,JSON.parse(JSON.stringify(xt)).concat(Ct(116.5,-118.9))),\"ç\":Y(520,212.1,233.1,2,-10,-64,-64,JSON.parse(JSON.stringify(xt)).concat(zt(116.5,233.1))),\"Đ\":Y(721,270,352,-10,-10,0,0,JSON.parse(JSON.stringify(et)).concat(Gt(0,176))),\"Ď\":Y(721,270,352,-10,-10,0,0,JSON.parse(JSON.stringify(et)).concat(Ct(100,-110))),\"ď\":Y(600,232,352,10,2,0,0,JSON.parse(JSON.stringify(ut)).concat((qt=300,Xt=0,[{d:-1,v:[[\"m\",qt,Xt,{x:0,y:0}],[\"l\",qt,80+Xt,{x:0,y:0,f:1}]]}]))),\"đ\":Y(600,232,352,10,2,0,0,JSON.parse(JSON.stringify(ut)).concat(Gt(180,40))),\"È\":Y(520,192,352,-5,-80,0,0,JSON.parse(JSON.stringify(at)).concat(kt(96,-60))),\"É\":Y(520,192,352,-5,-80,0,0,JSON.parse(JSON.stringify(at)).concat(Dt(96,-60))),\"Ê\":Y(520,192,352,-5,-80,0,0,JSON.parse(JSON.stringify(at)).concat(Tt(96,-110))),\"Ë\":Y(520,192,352,-5,-80,0,0,JSON.parse(JSON.stringify(at)).concat(Rt(96,-80))),\"Ē\":Y(520,192,352,-5,-80,0,0,JSON.parse(JSON.stringify(at)).concat(At(96,-80))),\"Ĕ\":Y(520,192,352,-5,-80,0,0,JSON.parse(JSON.stringify(at)).concat(Ft(96,-120))),\"Ė\":Y(520,192,352,-5,-80,0,0,JSON.parse(JSON.stringify(at)).concat(jt(96,-80))),\"Ě\":Y(520,192,352,-5,-80,0,0,JSON.parse(JSON.stringify(at)).concat(Ct(96,-110))),\"è\":Y(570,225.5,233.1,0,0,-64,-64,JSON.parse(JSON.stringify(gt)).concat(kt(112,-60))),\"é\":Y(570,225.5,233.1,0,0,-64,-64,JSON.parse(JSON.stringify(gt)).concat(Dt(112,-60))),\"ê\":Y(570,225.5,233.1,0,0,-64,-64,JSON.parse(JSON.stringify(gt)).concat(Tt(112,-110))),\"ë\":Y(570,225.5,233.1,0,0,-64,-64,JSON.parse(JSON.stringify(gt)).concat(Rt(112,-80))),\"ē\":Y(570,225.5,233.1,0,0,-64,-64,JSON.parse(JSON.stringify(gt)).concat(At(112,-80))),\"ĕ\":Y(570,225.5,233.1,0,0,-64,-64,JSON.parse(JSON.stringify(gt)).concat(Ft(112,-120))),\"ė\":Y(570,225.5,233.1,0,0,-64,-64,JSON.parse(JSON.stringify(gt)).concat(jt(112,-90))),\"ě\":Y(570,225.5,233.1,0,0,-64,-64,JSON.parse(JSON.stringify(gt)).concat(Ct(112,-120))),\"Ĝ\":Y(840,352,360,0,0,0,0,JSON.parse(JSON.stringify(st)).concat(Tt(180,-110))),\"Ğ\":Y(840,352,360,0,0,0,0,JSON.parse(JSON.stringify(st)).concat(Ft(180,-120))),\"Ġ\":Y(840,352,360,0,0,0,0,JSON.parse(JSON.stringify(st)).concat(jt(180,-80))),\"Ģ\":Y(840,352,360,0,0,0,0,JSON.parse(JSON.stringify(st)).concat(zt(180,360))),\"ĝ\":Y(600,232,338,10,2,-117,-117,JSON.parse(JSON.stringify(bt)).concat(Tt(116,-118.9))),\"ğ\":Y(600,232,338,10,2,-117,-117,JSON.parse(JSON.stringify(bt)).concat(Ft(116,-120))),\"ġ\":Y(600,232,338,10,2,-117,-117,JSON.parse(JSON.stringify(bt)).concat(jt(116,-90))),\"ģ\":Y(600,232,338,10,2,-117,-117,JSON.parse(JSON.stringify(bt)).concat(Dt(116,-70))),\"Ĥ\":Y(684,232,352,0,0,0,0,JSON.parse(JSON.stringify(nt)).concat(Tt(116,-110))),\"ĥ\":Y(520,182,352,0,0,0,0,JSON.parse(JSON.stringify(St)).concat(Tt(91,-110))),\"Ì\":Y(249,0,352,0,0,0,0,JSON.parse(JSON.stringify(lt)).concat(kt(0,-60))),\"Í\":Y(249,0,352,0,0,0,0,JSON.parse(JSON.stringify(lt)).concat(Dt(0,-60))),\"Î\":Y(249,0,352,0,0,0,0,JSON.parse(JSON.stringify(lt)).concat(Tt(0,-110))),\"Ï\":Y(249,0,352,0,0,0,0,JSON.parse(JSON.stringify(lt)).concat(Rt(0,-80))),\"ì\":Y(200,0,352,0,0,0,0,JSON.parse(JSON.stringify(Et)).concat(kt(0,70))),\"í\":Y(200,0,352,0,0,0,0,JSON.parse(JSON.stringify(Et)).concat(Dt(0,70))),\"î\":Y(200,0,352,0,0,0,0,JSON.parse(JSON.stringify(Et)).concat(Tt(0,10))),\"ï\":Y(200,0,352,0,0,0,0,JSON.parse(JSON.stringify(Et)).concat(Rt(0,50))),\"Ĵ\":Y(472,172.5,355.5,10,20,-2,-2,JSON.parse(JSON.stringify(ft)).concat(Tt(172.5,-110))),\"ĵ\":Y(220,115.9,352,-60,-60,0,0,JSON.parse(JSON.stringify(Bt)).concat(Tt(0,20))),\"Ñ\":Y(721,250,352,0,0,0,0,JSON.parse(JSON.stringify(ot)).concat(It(125,-100))),\"ñ\":Y(520,182,352,0,0,0,0,JSON.parse(JSON.stringify(mt)).concat(It(91,30))),\"Ò\":Y(850,360,360,0,0,0,0,JSON.parse(JSON.stringify(ht)).concat(kt(180,-60))),\"Ó\":Y(850,360,360,0,0,0,0,JSON.parse(JSON.stringify(ht)).concat(Dt(180,-60))),\"Ô\":Y(850,360,360,0,0,0,0,JSON.parse(JSON.stringify(ht)).concat(Tt(180,-110))),\"Õ\":Y(850,360,360,0,0,0,0,JSON.parse(JSON.stringify(ht)).concat(It(180,-100))),\"Ö\":Y(850,360,360,0,0,0,0,JSON.parse(JSON.stringify(ht)).concat(Rt(180,-80))),\"Ø\":Y(850,360,360,0,0,0,0,JSON.parse(JSON.stringify(ht)).concat([{d:1,v:[[\"m\",0,360,{r:$(0,360,360,0),f:1,x:0,y:1}],[\"l\",360,0,{x:0,y:1}]]}])),\"ò\":Y(580,232,232,0,0,-64,-64,JSON.parse(JSON.stringify(Ot)).concat(kt(116,-60))),\"ó\":Y(580,232,232,0,0,-64,-64,JSON.parse(JSON.stringify(Ot)).concat(Dt(116,-60))),\"ô\":Y(580,232,232,0,0,-64,-64,JSON.parse(JSON.stringify(Ot)).concat(Tt(116,-110))),\"õ\":Y(580,232,232,0,0,-64,-64,JSON.parse(JSON.stringify(Ot)).concat(It(116,-100))),\"ö\":Y(580,232,232,0,0,-64,-64,JSON.parse(JSON.stringify(Ot)).concat(Rt(116,-80))),\"ø\":Y(580,232,232,0,0,-64,-64,JSON.parse(JSON.stringify(Ot)).concat([{d:1,v:[[\"m\",0,232,{r:$(0,232,232,0),f:1,x:0,y:1}],[\"l\",232,0,{x:0,y:1}]]}])),\"Ŝ\":Y(560,224,360,0,0,0,0,JSON.parse(JSON.stringify(yt)).concat(Tt(112.4,-110))),\"ŝ\":Y(400,143.808,231.12,0,0,-64,-64,JSON.parse(JSON.stringify(Jt)).concat(Tt(112.4*.642,-110))),\"Ş\":Y(560,224,360,0,0,0,0,JSON.parse(JSON.stringify(yt)).concat(zt(110.3,360))),\"ş\":Y(400,143.808,231.12,0,0,-64,-64,JSON.parse(JSON.stringify(Jt)).concat(zt(70.8126,231.12))),\"Ù\":Y(712,250,355,0,0,-.5,-.5,JSON.parse(JSON.stringify(dt)).concat(kt(125,-50))),\"Ú\":Y(712,250,355,0,0,-.5,-.5,JSON.parse(JSON.stringify(dt)).concat(Dt(125,-50))),\"Û\":Y(712,250,355,0,0,-.5,-.5,JSON.parse(JSON.stringify(dt)).concat(Tt(125,-100))),\"Ŭ\":Y(712,250,355,0,0,-.5,-.5,JSON.parse(JSON.stringify(dt)).concat(Ft(125,-110))),\"Ü\":Y(712,250,355,0,0,-.5,-.5,JSON.parse(JSON.stringify(dt)).concat(Rt(125,-70))),\"ù\":Y(520,182,352,0,0,0,0,JSON.parse(JSON.stringify(Nt)).concat(kt(91,70))),\"ú\":Y(520,182,352,0,0,0,0,JSON.parse(JSON.stringify(Nt)).concat(Dt(91,70))),\"û\":Y(520,182,352,0,0,0,0,JSON.parse(JSON.stringify(Nt)).concat(Tt(91,20))),\"ŭ\":Y(520,182,352,0,0,0,0,JSON.parse(JSON.stringify(Nt)).concat(Ft(91,10))),\"ü\":Y(520,182,352,0,0,0,0,JSON.parse(JSON.stringify(Nt)).concat(Rt(91,50))),\"Ý\":Y(673,270,352,0,0,0,0,JSON.parse(JSON.stringify(ct)).concat(Dt(135,-60))),\"ý\":Y(500,225.5,331.5,10,10,-119,-119,JSON.parse(JSON.stringify(_t)).concat(Dt(116.3,-60))),\"ÿ\":Y(500,225.5,331.5,10,10,-119,-119,JSON.parse(JSON.stringify(_t)).concat(Rt(116.3,-90)))},Kt=Object.assign({},pt,wt,Pt,Wt,Ht);function Qt(t){var r=(Kt[t]||Kt.tofu).clone();return r.v=t,r}function Ut(t,r,i,e){var a;return a=t.indexOf(\"\\n\")>0?t.split(\"\\n\"):t.indexOf(\"\\\\n\")>0?t.split(\"\\\\n\"):[t],0==i?function(t){var r,i=[],e=t.length;for(r=0;r<e;r++)i[r]=t[r].split(\"\");return i}(a):e?function(t,r,i){var e,a,n,l,f,o,h,y,d=0,c=0,p=[];for(n=t.length,a=0;a<n;a++){for(h=t[a],d=0,0,p[c]=[],f=h.length,l=0;l<f;l++)y=h[l],e=Qt(y),o=s(e,r),d+=o.w,p[c].push(y),d>=i&&(c+=1,d=o.w,p[c]=[]);c+=1}var v=[];for(n=p.length,a=0;a<n;a++)(e=p[a]).length>0&&(\" \"==e[0]&&e.shift(),\" \"==e[e.length-1]&&e.pop(),e.length>0&&v.push(e));return v}(a,r,i):function(t,r,i){var e,a,n,l,f,o,h,y,d,c,p=0,v=0,x=0,u=[];for(y=t.length,f=0;f<y;f++){for(e=t[f].split(\" \"),u[x]=[],d=e.length,o=0;o<d;o++){for(v=0,a=e[o],c=a.length,h=0;h<c;h++)n=Qt(a[h]),l=s(n,r),v+=l.w;n=Qt(\" \"),l=s(n,r),v+=l.w,(p+=v)>i&&(p=v,u[x+=1]=[]),u[x].push(a)}x+=1,p=0}y=u.length;var g=[];for(f=0;f<y;f++)(n=u[f].join(\" \").split(\"\")).length>0&&g.push(n);return g}(a,r,i)}function Vt(t,r){return{c:(t-r)/2,r:t-r,l:0}}class Yt{constructor(){this.lineWidth_=1,this.drawing_=[],this.data_=null,this.paths_=null,this.lines_=null,this.rect_={x:0,y:0,w:0,h:0},this.align_=\"left\",this.scale_=1,this.fontRatio_=1}get data(){return this.data_}get paths(){return this.paths_}get lines(){return this.lines_}set lines(t){this.lines_=t}get lineWidth(){return this.lineWidth_}get fontRatio(){return this.fontRatio_}get scale(){return this.scale_}get rect(){return this.rect_}get drawing(){return this.drawing_}set align(t){this.align_!=t&&(this.align_=t,this.setPosition())}get align(){return this.align_}position(t,r){return(this.rect_.x!=t||this.rect_.y!=r)&&(this.rect_.x=t,this.rect_.y=r,this.setPosition(),!0)}setPosition(){var t,r,i,e,a=this.data_.length;for(t=0;t<a;t++)(r=this.data_[t]).rect.x=r.originPos.x+this.rect_.x+(i=this.align_,e=r.alignGapX,\"center\"==i?e.c:\"right\"==i?e.r:e.l),r.rect.y=r.originPos.y+this.rect_.y}updateDrawingPaths(){var t,r,i=this.data_.length;for(t=0;t<i;t++)(r=this.data_[t]).drawingPaths=h(q(this,r,-1,!1),r)}updatePatternPaths(t){var r,i,e=this.data_.length;for(r=0;r<e;r++)(i=this.data_[r]).rawPaths=q(this,i,t,!0)}updateWavePaths(t){var r,i,e=this.data_.length;for(r=0;r<e;r++)(i=this.data_[r]).rawWavePaths=q(this,i,t,!1)}updateGuide(){var t,r,i=this.data_.length;for(t=0;t<i;t++)(r=this.data_[t]).guide=M(r.typo,this.scale),r.grid=G(r.typo,this.scale)}update(t,r,i,a,f,o,h){var y=function(t){return(70-e)/(900-e)*(t-e)+e}(a),d=function(t){return 1/(80-e)*(t-e)}(y),c=function(t){return 54/(80-e)*(t-e)+4}(y),p=function(t){return t/500}(f),v=function(t,r){return 50*t*r}(o,p),x=function(t,r){return 50*t*r}(h,p),u=function(t){return(.78-1)*t+1}(d);this.fontRatio_=u,this.scale_=p,this.lineWidth_=function(t,r){var i=t*r;return i<1&&(i=1),i}(y,p);var g,b,S,m,J,N,_,w,P,W=Ut(t,p,r,i),k=W.length,D=k-1,T=0,I=0,R=0,F=0,M=0,G=0,z=[];for(g=0;g<k;g++){for(m=(S=(J=W[g]).length)-1,T=0,R=0,z[g]={tw:0,arr:[]},b=0;b<S;b++)T+=(w=s(N=Qt(_=J[b]),p)).w,I=w.h,b<m&&(T+=v),g<D&&(I+=x),w.x=R,w.y=F,P={x:R,y:F},z[g].arr[b]={str:_,typo:N,rect:w,originPos:P,center:n(w.w,w.h,p),range:l(N,d,c)},R=T;F+=I,z[g].tw=T,M=Math.max(M,T),G+=I}this.rect_.w=M,this.rect_.h=G,this.drawing_=[];var L,j,C=[];for(var A of z)for(var q of(L=Vt(M,A.tw),A.arr))for(var X of(q.alignGapX=L,q.pointsLength=O(q,this),C.push(q),j={value:1},this.drawing_.push(j),q.drawing=j,q.typo.p))for(var E of(X.cv=[],X.v))X.cv.push(E.convert(q,this));this.data_=C,this.setPosition()}updatePathsForRect(){var t,r,i=this.data_.length,e=[];for(t=0;t<i;t++)(r=this.data_[t]).rawWavePaths&&(r.wavePaths=h(r.rawWavePaths,r)),r.rawPaths&&(r.paths=h(r.rawPaths,r),Array.prototype.push.apply(e,r.paths));this.paths_=e}updateLinesForRect(){var t,r,i=this.data_.length;for(t=0;t<i;t++)(r=this.data_[t]).lines=o(r)}reset(){this.lineWidth_=1,this.drawing_=[],this.data_=null,this.paths_=null,this.lines_=null,this.rect_={x:0,y:0,w:0,h:0},this.align_=\"left\",this.scale_=1,this.fontRatio_=1}}class Zt extends class{constructor(){this.handlers_={update:{listeners:[]}}}on(t,r){return\"function\"!=typeof r?(console.error(\"The listener callback must be a function, the given type is \".concat(typeof r)),!1):\"string\"!=typeof t?(console.error(\"The event name must be a string, the given type is \".concat(typeof t)),!1):(void 0===this.handlers_[t]&&(this.handlers_[t]={listeners:[]}),void this.handlers_[t].listeners.push(r))}off(t,r){if(void 0===this.handlers_[t])return console.error(\"This event: \".concat(t,\" does not exist\")),!1;this.handlers_[t].listeners=this.handlers_[t].listeners.filter(t=>t.toString()!==r.toString())}dispatch(t,r){this.handlers_[t].listeners.forEach(t=>{t(r)})}}{constructor(){var{text:t=\"\",size:r=500,weight:i=e,color:a=[\"#000000\"],colorful:s=[\"#c5d73f\",\"#9d529c\",\"#49a9db\",\"#fec330\",\"#5eb96e\",\"#fc5356\",\"#f38f31\"],tracking:n=0,leading:l=0,align:f=\"left\",pathGap:o=.5,amplitude:h=.5,width:y=0,breakWord:d=!1,fps:c=30,isPath:p=!1,isWave:v=!1}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};super(),this.size_=r,this.weight_=i,this.color_=a,this.colorful_=function(t){for(var r,i,e=t.slice(),a=e.length,s=a;s--;)r=Math.random()*a|0,i=e[s],e[s]=e[r],e[r]=i;return e}(s),this.tracking_=n,this.leading_=l,this.pathGap_=o,this.amplitude_=h,this.width_=y,this.breakWord_=d,this.fps_=c,this.fpsTime_=1e3/this.fps_,this.isPath_=p,this.isWave_=v,this.model=new Yt,this.str_=null,this.time_=null,this.isFps_=!1,this.isForceRander_=!1,this.updateID_=0,this.dPathsID_=null,this.pPathsID_=null,this.wPathsID_=null,this.guideID_=null,this.text=t,this.model.align=f}on(t,r){super.on(t,r),this.update()}off(t,r){super.off(t,r)}get text(){return this.str_}set text(t){this.str_!=t&&(this.str_=t,this.update())}get size(){return this.size_}set size(t){this.size_!=t&&(this.size_=t,this.update(),this.isForceRander_=!0)}get weight(){return this.weight_}set weight(t){t<e?t=e:t>900&&(t=900),this.weight_!=t&&(this.weight_=t,this.update(),this.isForceRander_=!0)}get color(){return this.color_}set color(t){this.color_!=t&&(this.color_=t)}get tracking(){return this.tracking_}set tracking(t){this.tracking_!=t&&(this.tracking_=t,this.update(),this.isForceRander_=!0)}get leading(){return this.leading_}set leading(t){this.leading_!=t&&(this.leading_=t,this.update(),this.isForceRander_=!0)}get align(){return this.model.align}set align(t){this.model.align!=t&&(this.model.align=t,this.updateID_++,this.updateSignal())}get pathGap(){return this.pathGap_}set pathGap(t){this.pathGap_!=t&&(this.pathGap_=t,this.updatePatternPaths(!0),this.updateWavePaths(!0),this.isForceRander_=!0)}get amplitude(){return this.amplitude_}set amplitude(t){this.amplitude_=t}get rect(){return this.model.rect}set maxWidth(t){this.width_!=t&&(this.width_=t,this.update())}get maxWidth(){return this.width_}set breakWord(t){this.breakWord_!=t&&(this.breakWord_=t,this.update())}get breakWord(){return this.breakWord_}get isPath(){return this.isPath_}set isPath(t){this.isPath_=t,this.updatePatternPaths(!0)}get isWave(){return this.isWave_}set isWave(t){this.isWave_=t,this.updateWavePaths(!0)}get fps(){return this.fps_}set fps(t){this.fps_=t,this.fpsTime_=1e3/this.fps_}get lineWidth(){return this.model.lineWidth}get scale(){return this.model.scale}get drawing(){return this.model.drawing}get data(){return this.model.data}get paths(){return this.model.paths}get drawingPaths(){return this.model.drawingPaths}get wavePaths(){return this.model.wavePaths}position(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;this.model.position(t,r)&&(this.updateID_++,this.updateSignal())}update(){this.updateID_++,this.model.update(this.str_,this.width_,this.breakWord_,this.weight_,this.size_,this.tracking_,this.leading_),this.isPath_||this.isWave_?(this.updatePatternPaths(),this.updateWavePaths()):this.updateSignal()}updateGuide(){this.guideID_!=this.updateID_&&(this.guideID_=this.updateID_,this.model.updateGuide())}updateDrawingPaths(){this.dPathsID_!=this.updateID_&&(this.dPathsID_=this.updateID_,this.model.updateDrawingPaths())}updatePatternPaths(t){this.isPath_&&(t||this.pPathsID_!=this.updateID_)&&(this.pPathsID_=this.updateID_,this.model.updatePatternPaths(this.pathGap_),this.isForceRander_=!0,this.updateSignal())}updateWavePaths(t){this.isWave_&&(t||this.wPathsID_!=this.updateID_)&&(this.wPathsID_=this.updateID_,this.model.updateWavePaths(this.pathGap_),this.isForceRander_=!0,this.updateSignal())}updateSignal(){this.model.updateLinesForRect(),this.model.updatePathsForRect(),this.dispatch(\"update\",this.model)}reset(){this.size_=500,this.weight_=e,this.color_=[\"#000000\"],this.tracking_=0,this.leading_=0,this.pathGap_=.5,this.amplitude_=.5,this.width_=0,this.breakWord_=!1,this.fps_=30,this.fpsTime_=1e3/this.fps_,this.isPath_=!1,this.isWave_=!1,this.str_=null,this.time_=null,this.isFps_=!1,this.isForceRander_=!1,this.updateID_=0,this.dPathsID_=null,this.pPathsID_=null,this.wPathsID_=null,this.guideID_=null,this.model.reset()}dispose(){this.reset(),this.model=null}drawPixi(t){var r,i,e,a=this.model.data.length;for(r=0;r<a;r++)i=this.model.data[r],e=F(r,0,this.color_),T(t,i,this.lineWidth,e)}draw(t){t.lineWidth=this.lineWidth;var r,i,e=this.model.data.length;for(r=0;r<e;r++)m(t,r,i=this.model.data[r],this.color_),y(t,i)}drawColorful(t){t.lineWidth=this.lineWidth,function(t,r,i){W=-1,P=(x=i).length;var e,s,n,l,f,o,h,y,d,c,p=r.data.length;for(e=0;e<p;e++)for(y=(s=r.data[e]).pointsLength.max,c=0,l=s.lines.length,h=null,n=0;n<l;n++)\"a\"==(o=(f=s.lines[n]).pos).type?(k(t),t.beginPath(),t.arc(o.x,o.y,o.radius*s.drawing.value,0,a),t.fill(),t.closePath()):\"m\"==o.type?h=o:\"l\"==o.type?((d=w(h.x,h.y,o.x,o.y))/r.scale>10&&(k(t),t.beginPath(),h&&t.moveTo(h.x,h.y),t.lineTo(o.x,o.y),c+=D(t,f,d,y,s,c)),h=o):\"b\"==o.type&&((d=N(h.x,h.y,o.x,o.y,o.x2,o.y2,o.x3,o.y3))/r.scale>10&&(k(t),t.beginPath(),h&&t.moveTo(h.x,h.y),t.bezierCurveTo(o.x,o.y,o.x2,o.y2,o.x3,o.y3),c+=D(t,f,d,y,s,c)),h={x:o.x3,y:o.y3})}(t,this.model,this.colorful_)}wave(t,r){(t.lineWidth=this.lineWidth,r)&&(this.time_||(this.time_=r),r-this.time_>this.fpsTime_||this.isForceRander_?(this.time_=r,this.isFps_=!0):this.isFps_=!1);this.isForceRander_=!1;var i,e,a=this.model.data.length;for(i=0;i<a;i++)m(t,i,e=this.model.data[i],this.color_),b(t,e,this.model.scale,this.amplitude_,this.weight_,this.isFps_)}pattern(t,r,i){var e,a=r*this.model.scale,s=i*this.model.scale,n=this.model.data.length;for(e=0;e<n;e++)S(t,this.model.data[e],a,s)}grid(t){this.updateGuide();var r,i=this.model.data.length;for(r=0;r<i;r++)v(t,this.model.data[r])}point(t){var r,i=this.model.data.length;for(r=0;r<i;r++)d(t,this.model.data[r])}box(t){t.lineWidth=1,t.beginPath(),t.strokeStyle=\"#0b90dc\",t.rect(this.model.rect.x,this.model.rect.y,this.model.rect.w,this.model.rect.h),t.stroke()}}}]);\n"
  },
  {
    "path": "examples/all.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\">\n    <title>Leon Sans - All</title>\n\n    <style>\n        html, body {\n            width: 100%;\n            height: 100%;\n            overflow: hidden;\n            outline: 0;\n            margin: 0;\n            padding: 0;\n            background-color: #f0f0f0;\n            cursor: move;\n        }\n    </style>\n\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js\"></script>\n</head>\n\n<body>\n    <script src=\"../dist/leon.js\"></script>\n    <script src=\"js/util.js\"></script>\n    <script>\n        let leon, controll;\n\n        function init() {\n            generateCanvas();\n\n            controll = {\n                align: {},\n                box: false,\n                grids: false,\n                points: false,\n                drawing: () => {\n                    let i, total = leon.drawing.length;\n                    for (i = 0; i < total; i++) {\n                        TweenMax.killTweensOf(leon.drawing[i]);\n                        TweenMax.fromTo(leon.drawing[i], 2, {\n                            value: 0\n                        }, {\n                            value: 1,\n                            ease: Power3.easeOut\n                        });\n                    }\n                }\n            };        \n\n            leon = new LeonSans({\n                text: 'abcdefghijklmn\\nopqrstuvwxyz\\nABCDEFGHIJK\\nLMNOPQRST\\nUVWXYZ\\n0123456789\\n?!$^&*@#%:;\\n(){}[]<>«»~_\\n\\'\"·+=-×÷¿¡,.\\nÀÁÂÃÄÅĂĄÆ\\nÞßĆĈĊČÇĤÝ\\nĎĐÈÉÊËĒĔĖĚ\\nĜĞĠĢÙÚÛÜŬ\\nŜŞĴÑÌÍÎÏ\\nàáâãåäăąæ\\nþćĉċčçĥýÿ\\nďđèéêëēĕėě\\nĝğġģùúûüŭ\\nŝşĵñìíîï',\n                color: ['#342f2e'],\n                size: getSize(90),\n                weight: 200,\n                tracking: 2,\n                leading: 2, \n                align: 'center'\n            });\n\n            const gui = new dat.GUI();\n             gui.add(leon, 'text');\n            gui.add(leon, 'size', 20, 1000);\n            gui.add(leon, 'weight', 1, 900);\n            gui.add(leon, 'tracking', -3, 10);\n            gui.add(leon, 'leading', -8, 10);\n            gui.add(controll, 'drawing');\n            gui.add(controll, 'box');\n            gui.add(controll, 'grids');\n            gui.add(controll, 'points');\n\n            requestAnimationFrame(animate);\n        }\n\n        function animate(t) {\n            requestAnimationFrame(animate);\n\n            ctx.clearRect(0, 0, sw, sh);\n\n            const x = (sw - leon.rect.w) / 2;\n            let y = (sh - leon.rect.h) / 2;\n            if (y < 0) y = 0;\n            leon.position(x + moveX, y + moveY);\n\n            ctx.save();\n            if (controll.grids) leon.grid(ctx);\n            if (controll.box) leon.box(ctx);\n            ctx.restore();\n\n            ctx.save();\n            leon.draw(ctx);\n            ctx.restore();\n\n            if (controll.points) {\n                ctx.save();\n                leon.point(ctx);\n                ctx.restore();\n            }\n        }\n\n        window.onload = () => {\n            init();\n        };\n    </script>\n</body>\n\n</html>"
  },
  {
    "path": "examples/canvas-basic.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\">\n    <title>Leon Sans - Canvas Basic</title>\n\n    <style>\n        html, body {\n            width: 100%;\n            height: 100%;\n            overflow: hidden;\n            outline: 0;\n            margin: 0;\n            padding: 0;\n            background-color: #f0f0f0;\n            cursor: move;\n        }\n    </style>\n\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js\"></script>\n</head>\n\n<body>\n    <script src=\"../dist/leon.js\"></script>\n    <script src=\"js/util.js\"></script>\n    <script>\n        let leon, controll;\n\n        function init() {\n            generateCanvas();\n\n            controll = {\n                color: {},\n                align: {},\n                drawing: () => {\n                    let i, total = leon.drawing.length;\n                    for (i = 0; i < total; i++) {\n                        TweenMax.killTweensOf(leon.drawing[i]);\n                        TweenMax.fromTo(leon.drawing[i], 1.6, {\n                            value: 0\n                        }, {\n                            delay: i * 0.05,\n                            value: 1,\n                            ease: Power4.easeOut\n                        });\n                    }\n                }\n            };\n\n            leon = new LeonSans({\n                text: 'The quick brown\\nfox jumps over\\nthe lazy dog',\n                color: ['#342f2e'],\n                size: getSize(120),\n                weight: 300\n            });\n\n            const gui = new dat.GUI();\n            gui.add(leon, 'text');\n            gui.add(leon, 'size', 20, 1000);\n            gui.add(leon, 'weight', 1, 900);\n            gui.add(leon, 'tracking', -3, 10);\n            gui.add(leon, 'leading', -8, 10);\n            const alignControll = gui.add(controll, 'align', [ 'left', 'center', 'right'] );\n            gui.add(leon, 'maxWidth', 0, 2000);\n            gui.add(leon, 'breakWord');\n            gui.add(controll, 'drawing');\n            const colorControll = gui.add(controll, 'color', [ 'black', 'white', 'yellow', 'red - blue', 'mixed'] );\n\n            alignControll.onChange((value) => {\n                leon.align = value;\n            });\n            alignControll.setValue('left');\n\n            colorControll.onChange((value) => {\n                if (value == 'black') {\n                    document.body.style.backgroundColor = '#f0f0f0';\n                    leon.color = ['#342f2e'];\n                } else if (value == 'white') {\n                    document.body.style.backgroundColor = '#000000';\n                    leon.color = ['#ffffff'];\n                } else if (value == 'yellow') {\n                    document.body.style.backgroundColor = '#57c4e2';\n                    leon.color = ['#ffd93c'];\n                } else if (value == 'red - blue') {\n                    document.body.style.backgroundColor = '#ffffff';\n                    leon.color = [['#ff94a7', '#1c7dd1']];\n                } else if (value == 'mixed') {\n                    document.body.style.backgroundColor = '#ffffff';\n                    leon.color = ['#ff5892', '#7bc92f', ['#3eda4e', '#f4bf14', '#fa314c', '#074aee'], '#ffd93c', '#c0008b'];\n                }\n            });\n            colorControll.setValue('black');\n            \n            requestAnimationFrame(animate);\n        }\n\n        function animate(t) {\n            requestAnimationFrame(animate);\n\n            ctx.clearRect(0, 0, sw, sh);\n\n            const x = (sw - leon.rect.w) / 2;\n            const y = (sh - leon.rect.h) / 2;\n            leon.position(x + moveX, y + moveY);\n\n            leon.draw(ctx);\n        }\n\n        window.onload = () => {\n            init();\n        };\n    </script>\n</body>\n\n</html>"
  },
  {
    "path": "examples/color-pattern.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\">\n    <title>LeonSans - Color Pattern</title>\n\n    <style>\n        html, body {\n            width: 100%;\n            height: 100%;\n            overflow: hidden;\n            outline: 0;\n            margin: 0;\n            padding: 0;\n            background-color: #121212;\n            cursor: move;\n        }\n    </style>\n\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js\"></script>\n</head>\n\n<body>\n    <script src=\"../dist/leon.js\"></script>\n    <script src=\"js/util.js\"></script>\n    <script>\n        const speed = 10;\n        const fps = 1000 / 30;\n        const PI2 = 2 * Math.PI;\n        let cValue = 0, mode;\n        let leon, controll, time;\n\n        function init() {\n            generateCanvas();\n            \n            controll = {\n                size: 200,\n                pathGap: 0,\n                patternWidth: 2,\n                visual: {},\n                drawing: () => {\n                    let i, total = leon.drawing.length;\n                    for (i = 0; i < total; i++) {\n                        TweenMax.killTweensOf(leon.drawing[i]);\n                        TweenMax.fromTo(leon.drawing[i], 2, {\n                            value: 0\n                        }, {\n                            delay: i * 0.1,\n                            value: 1,\n                            ease: Power4.easeOut\n                        });\n                    }\n                }\n            };\n\n            leon = new LeonSans({\n                text: 'abcdefg',\n                size: getSize(200),\n                weight: 500,\n                pathGap: -1,\n                isPath: true\n            });\n\n            const gui = new dat.GUI();\n            gui.add(leon, 'text');\n            gui.add(leon, 'size', 10, 1000);\n            const weightControll = gui.add(controll, 'patternWidth', 1, 100);\n            gui.add(controll, 'drawing');\n            const visControll = gui.add(controll, 'pathGap', [ '-1', '0'] );\n\n            visControll.onChange((value) => {\n                mode = value;\n                if (mode == '-1') {\n                    weightControll.setValue(40);\n                    leon.pathGap = -1;\n                    leon.tracking = 1;\n                } else if (mode == '0') {\n                    weightControll.setValue(40);\n                    leon.pathGap = 0;\n                    leon.tracking = 1;\n                }\n            });\n            visControll.setValue('-1');\n\n            requestAnimationFrame(animate);\n        }\n\n        function update() {\n            ctx.clearRect(0, 0, sw, sh);\n            ctx.lineWidth = 0.2;\n            const w = controll.patternWidth * leon.scale;\n            const total = leon.data.length;\n            let i, p, pos, no = 0; \n            let d, j, j_total;\n\n            for (i = 0; i < total; i++) {\n                d = leon.data[i].paths;\n                j_total = Math.round(d.length * leon.drawing[i].value);\n                for (j = 0; j < j_total; j++) {\n                    pos = d[j];\n                    ctx.fillStyle = randomColor(no);\n                    ctx.strokeStyle = randomColor(no);\n                    ctx.beginPath();\n                    ctx.arc(pos.x, pos.y, w, 0, PI2);\n                    ctx.stroke();\n                    no += 1;\n                }\n            }\n\n            cValue -= speed;\n        }\n\n        function randomColor(no) {\n            return \"hsl(\" + (no + cValue) + ',' + '70%,' + '50%)';\n        }\n\n        function animate(t) {\n            requestAnimationFrame(animate);\n\n            const x = (sw - leon.rect.w) / 2;\n            const y = (sh - leon.rect.h) / 2;\n            leon.position(x + moveX, y + moveY);\n\n            if (t) {\n                if (!time) time = t;\n                if (t - time > fps) {\n                    time = t;\n                    update();\n                }\n            }\n        }\n\n        window.onload = () => {\n            init();\n        };\n    </script>\n</body>\n\n</html>"
  },
  {
    "path": "examples/colorful.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\">\n    <title>Leon Sans - Colorful</title>\n\n    <style>\n        html,\n        body {\n            width: 100%;\n            height: 100%;\n            overflow: hidden;\n            outline: 0;\n            margin: 0;\n            padding: 0;\n            background-color: #f0f0f0;\n            cursor: move;\n        }\n    </style>\n\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js\"></script>\n</head>\n\n<body>\n    <script src=\"../dist/leon.js\"></script>\n    <script src=\"js/util.js\"></script>\n    <script>\n        let leon, controll;\n\n        function init() {\n            generateCanvas();\n\n            controll = {\n                color: {},\n                roundCap: true,\n                multiply: true,\n                drawing: () => {\n                    let i, total = leon.drawing.length;\n                    for (i = 0; i < total; i++) {\n                        TweenMax.killTweensOf(leon.drawing[i]);\n                        TweenMax.fromTo(leon.drawing[i], 2, {\n                            value: 0\n                        }, {\n                            value: 1,\n                            ease: Cubic.easeOut\n                        });\n                    }\n                }\n            };\n\n            leon = new LeonSans({\n                text: 'The quick brown\\nfox jumps over\\nthe lazy dog',\n                color: ['#000000'],\n                size: getSize(120),\n                weight: 500\n            });\n\n            const gui = new dat.GUI();\n            gui.add(leon, 'text');\n            gui.add(leon, 'size', 20, 300);\n            gui.add(leon, 'weight', 1, 900);\n            gui.add(leon, 'tracking', -3, 10);\n            gui.add(leon, 'leading', -8, 10);\n            gui.add(controll, 'drawing');\n            const roundCapControll = gui.add(controll, 'roundCap');\n            const multiplyControll = gui.add(controll, 'multiply');\n\n            roundCapControll.onChange((value) => {\n                if (value) {\n                    ctx.lineCap = \"round\";\n                } else {\n                    ctx.lineCap = \"butt\";\n                }\n            });\n\n            multiplyControll.onChange((value) => {\n                if (value) {\n                    ctx.globalCompositeOperation = 'multiply';\n                } else {\n                    ctx.globalCompositeOperation = 'source-over';\n                }\n            });\n            \n            requestAnimationFrame(animate);\n\n            roundCapControll.setValue(true);\n            multiplyControll.setValue(true);\n        }\n\n        function animate(t) {\n            requestAnimationFrame(animate);\n\n            ctx.clearRect(0, 0, sw, sh);\n\n            const x = (sw - leon.rect.w) / 2;\n            const y = (sh - leon.rect.h) / 2;\n            leon.position(x + moveX, y + moveY);\n\n            leon.drawColorful(ctx);\n        }\n\n        window.onload = () => {\n            init();\n        };\n    </script>\n</body>\n\n</html>"
  },
  {
    "path": "examples/gradient.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\">\n    <title>Leon Sans - Gradient</title>\n\n    <style>\n        html, body {\n            width: 100%;\n            height: 100%;\n            overflow: hidden;\n            outline: 0;\n            margin: 0;\n            padding: 0;\n            background-color: #f0f0f0;\n            cursor: move;\n        }\n    </style>\n\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js\"></script>\n</head>\n\n<body>\n    <script src=\"../dist/leon.js\"></script>\n    <script src=\"js/util.js\"></script>\n    <script>\n        let leon, controll;\n\n        function init() {\n            generateCanvas();\n\n            controll = {\n                box: false,\n                grids: false,\n                points: false,\n                drawing: () => {\n                    let i, total = leon.drawing.length;\n                    for (i = 0; i < total; i++) {\n                        TweenMax.killTweensOf(leon.drawing[i]);\n                        TweenMax.fromTo(leon.drawing[i], 2, {\n                            value: 0\n                        }, {\n                            value: 1,\n                            ease: Power4.easeOut\n                        });\n                    }\n                }\n            };\n\n            leon = new LeonSans({\n                text: 'mug',\n                color: [\n                    ['#64d3ce', '#2a92ce'],\n                    ['#e7c4c4', '#aae898', '#e1ea73', '#ff8974'],\n                    ['#fd46aa', '#8ad781']\n                ],\n                size: getSize(500),\n                weight: 140\n            });\n\n            const gui = new dat.GUI();\n            gui.add(leon, 'text');\n            gui.add(leon, 'size', 20, 1000);\n            gui.add(leon, 'weight', 1, 900);\n            gui.add(controll, 'drawing');\n            gui.add(controll, 'box');\n            gui.add(controll, 'grids');\n            gui.add(controll, 'points');\n                        \n            requestAnimationFrame(animate);\n        }\n\n        function animate(t) {\n            requestAnimationFrame(animate);\n\n            ctx.clearRect(0, 0, sw, sh);\n\n            const x = (sw - leon.rect.w) / 2;\n            const y = (sh - leon.rect.h) / 2;\n            leon.position(x + moveX, y + moveY);\n\n            ctx.save();\n            if (controll.grids) leon.grid(ctx);\n            if (controll.box) leon.box(ctx);\n            ctx.restore();\n\n            ctx.save();\n            leon.draw(ctx);\n            ctx.restore();\n\n            if (controll.points) {\n                ctx.save();\n                leon.point(ctx);\n                ctx.restore();\n            }\n        }\n\n        window.onload = () => {\n            init();\n        };\n    </script>\n</body>\n\n</html>"
  },
  {
    "path": "examples/grid.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\">\n    <title>Leon Sans - Grids</title>\n\n    <style>\n        html, body {\n            width: 100%;\n            height: 100%;\n            overflow: hidden;\n            outline: 0;\n            margin: 0;\n            padding: 0;\n            background-color: #f0f0f0;\n            cursor: move;\n        }\n    </style>\n\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js\"></script>\n</head>\n\n<body>\n    <script src=\"../dist/leon.js\"></script>\n    <script src=\"js/util.js\"></script>\n    <script>\n        let leon, controll;\n\n        function init() {\n            generateCanvas();\n\n            controll = {\n                box: true,\n                grids: true,\n                points: true,\n            };\n\n            leon = new LeonSans({\n                text: 'Ttypog',\n                color: ['#342f2e'],\n                size: getSize(300),\n                weight: 400\n            });\n\n            const gui = new dat.GUI();\n            gui.add(leon, 'text');\n            gui.add(leon, 'size', 100, 1000);\n            gui.add(leon, 'weight', 1, 900);\n            gui.add(leon, 'tracking', -3, 10);\n            gui.add(leon, 'leading', -8, 10);\n            gui.add(controll, 'box');\n            gui.add(controll, 'grids');\n            gui.add(controll, 'points');\n\n            requestAnimationFrame(animate);\n        }\n\n        function animate(t) {\n            requestAnimationFrame(animate);\n\n            ctx.clearRect(0, 0, sw, sh);\n\n            const x = (sw - leon.rect.w) / 2;\n            const y = (sh - leon.rect.h) / 2;\n            leon.position(x + moveX, y + moveY);\n\n            ctx.save();\n            if (controll.grids) leon.grid(ctx);\n            if (controll.box) leon.box(ctx);\n            ctx.restore();\n\n            ctx.save();\n            leon.draw(ctx);\n            ctx.restore();\n\n            if (controll.points) {\n                ctx.save();\n                leon.point(ctx);\n                ctx.restore();\n            }\n        }\n\n        window.onload = () => {\n            init();\n        };\n    </script>\n</body>\n\n</html>"
  },
  {
    "path": "examples/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\">\n    <title>Leon Sans examples</title>\n    <meta name=\"mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <meta name=\"apple-mobile-web-app-title\" content=\"Leon Sans examples\">\n    <meta name=\"description\" content=\"Leon Sans is a geometric sans-serif typeface made with code in 2019 by Jongmin Kim.\">\n    <meta itemprop=\"name\" content=\"Leon Sans examples\" />\n    <meta itemprop=\"description\" content=\"Leon Sans is a geometric sans-serif typeface made with code in 2019 by Jongmin Kim.\"/>\n    <meta itemprop=\"image\" content=\"https://leon-kim.com/img/share.png\" />\n    <meta property=\"og:site_name\" content=\"Leon Sans examples\" />\n    <meta property=\"og:type\" content=\"website\" />\n    <meta property=\"og:title\" content=\"Leon Sans examples\" />\n    <meta property=\"og:url\" content=\"https://leon-kim.com\" />\n    <meta property=\"og:image\" content=\"https://leon-kim.com/img/share.png\" />\n    <meta property=\"og:description\" content=\"Leon Sans is a geometric sans-serif typeface made with code in 2019 by Jongmin Kim.\" />\n\n    <style>\n        html,\n        body {\n            outline: 0;\n            margin: 0;\n            padding: 0;\n            height: 100%;\n            color: #ffffff;\n            font-size: 14px;\n            line-height: 30px;\n            -webkit-text-size-adjust: 100%;\n            font-family: 'Helvetica', sans-serif;\n            font-weight: 400;\n        }\n\n        #menu-m {\n            position: fixed;\n            z-index: 4;\n            width: 60px;\n            height: 56px;\n            left: 0;\n            top: 0;\n            background-color: #222222;\n            cursor: pointer;\n        }\n\n        #menu-m > p {\n            display: block;\n            width: 30px;\n            height: 2px;\n            background-color: #ffffff;\n            position: absolute;\n            left: 15px;\n        }\n        #menu-m > p:nth-child(1) {\n            top: 5px;\n        }\n        #menu-m > p:nth-child(2) {\n            top: 12px;\n        }\n        #menu-m > p:nth-child(3) {\n            top: 19px;\n        }\n\n        #menu-bg {\n            position: fixed;\n            z-index: 2;\n            width: 100%;\n            height: 100%;\n            left: 0;\n            top: 0;\n            background-color:rgba(0,0,0,0.3);\n            display: none;\n        }\n\n        #menu {\n            position: fixed;\n            z-index: 6;\n            left: 0px;\n            width: 170px;\n            height: 100%;\n            overflow-y: auto;\n            overflow-x: hidden;\n            background-color: #222222;\n        }\n        #menu.show {\n            transform: translate(170px, 0);\n        }\n\n        #header {\n            margin: 0;\n        }\n\n        #version {\n            font-size: 9px;\n            line-height: 9px;\n            color: rgba(255,255,255,0.5);\n            padding: 0 0 0 20px;\n        }\n\n        #list {\n            margin: -10px 0 20px 0;\n        }\n\n        h2 {\n            font-size: 18px;\n            font-weight: 400;\n            margin: 40px 0 6px 0;\n            padding: 0 0 0 20px;\n        }\n\n        h2 > a {\n            font-size: 12px;\n        }\n        .item {\n            padding: 0 0 0 20px;\n            display: block;\n        }\n\n        .item:hover {\n            opacity: 1;\n            background-color: #000;\n        }\n\n        .item.selected {\n            opacity: 1;\n            background-color: #000;\n        }\n\n        a {\n            color: #ffffff;\n            opacity: 0.6;\n            text-decoration: none;\n        }\n\n        #iframe {\n            position: absolute;\n            border: 0px;\n            right: 0;\n            right: 0;\n            width: calc(100% - 170px);\n            height: 100%;\n            overflow: auto;\n        }\n\n        @media (max-width: 600px) {\n            #iframe {\n                width: 100%;\n            }\n            #menu {\n                left: -170px;\n            }\n        }\n    </style>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js\"></script>\n    <script src=\"../dist/leon.js\"></script>\n</head>\n\n<body>\n    <div id=\"menu-m\">\n        <p></p>\n        <p></p>\n        <p></p>\n    </div>\n    <div id=\"menu-bg\"></div>\n    <div id=\"menu\">\n        <canvas id=\"header\"></canvas>\n        <div id=\"version\">VERSION 1.5</div>\n        <div id=\"list\">\n            <h2>Canvas</h2>\n            <a class=\"item\" href=\"all.html\" target=\"iframe\">all</a>\n            <a class=\"item\" href=\"canvas-basic.html\" target=\"iframe\">basic</a>\n            <a class=\"item\" href=\"gradient.html\" target=\"iframe\">gradient</a>\n            <a class=\"item\" href=\"grid.html\" target=\"iframe\">grid</a>\n            <a class=\"item\" href=\"pattern.html\" target=\"iframe\">pattern</a>\n            <a class=\"item\" href=\"wave.html\" target=\"iframe\">wave</a>\n            <a class=\"item\" href=\"colorful.html\" target=\"iframe\">colorful</a>\n            <a class=\"item\" href=\"color-pattern.html\" target=\"iframe\">color pattern</a>\n            <h2>WebGL <a href=\"https://www.pixijs.com/\" target=\"_blank\">(PIXI.js)</a></h2>\n            <a class=\"item\" href=\"webgl-basic-pixi.html\" target=\"iframe\">basic</a>\n            <a class=\"item\" href=\"metaball-pixi.html\" target=\"iframe\">metaball</a>\n            <a class=\"item\" href=\"morphing-pixi.html\" target=\"iframe\">morphing</a>\n            <a class=\"item\" href=\"plants-pixi.html\" target=\"iframe\">plants</a>\n            <a class=\"item\" href=\"mask-tiling-pixi.html\" target=\"iframe\">mask + tiling</a>\n        </div>\n    </div>\n    <iframe id=\"iframe\" name=\"iframe\" allowfullscreen=\"\" allowvr=\"\" onmousewheel=\"\"></iframe>\n\n    <script>\n        window.onload = () => {\n\n            let isShow = false;\n            const menuM = document.getElementById('menu-m');\n            const menuBg = document.getElementById('menu-bg');\n            const menu = document.getElementById('menu');\n            menuM.addEventListener( 'click', (event) => {\n                onClickMenu();\n            });\n            menuBg.addEventListener( 'click', (event) => {\n                onClickMenu();\n            });\n\n            function onClickMenu() {\n                isShow = !isShow;\n                if (isShow) {\n                    menuBg.style.display = 'block';\n                    menu.className = 'show';\n                } else {\n                    menuBg.style.display = 'none';\n                    menu.className = '';\n                }\n            }\n\n\n            const sw = 170;\n            const sh = 50;\n            const iframe = document.getElementById('iframe');\n            const canvas = document.getElementById('header');\n            const ctx = canvas.getContext(\"2d\");\n            canvas.width = sw * 2;\n            canvas.height = sh * 2;\n            canvas.style.width = sw + 'px'\n            canvas.style.height = sh + 'px'\n            ctx.scale(2, 2);\n\n            const leon = new LeonSans({\n                text: 'Leon Sans',\n                color: ['#ffffff'],\n                size: 26,\n                weight: 300\n            });\n            leon.on('update', (model) => {  \n                ctx.clearRect(0, 0, sw, sh);\n                leon.position(20, 20);\n                leon.draw(ctx);\n            });\n\n            const list = document.getElementById('list');\n            const arr = list.getElementsByClassName('item');\n            const total = arr.length;\n            const links = {};\n            let cur = null;\n            let i;\n            for (i = 0; i < total; i++) {\n                const vv = arr[i].href.split('/');\n                const name = vv[vv.length - 1].split('.')[0];\n                links[name] = arr[i];\n\n                arr[i].addEventListener( 'click', (event) => {\n                    const vv = event.target.href.split('/');\n                    const name = vv[vv.length - 1].split('.')[0];\n                    checkMenu(name);\n                });\n            }\n\n            if (window.location.hash !== '') {\n                const name = window.location.hash.substring(1);\n                const url = name + '.html';\n                iframe.src = url;\n                checkMenu(name);\n            } else {\n                const name = 'all';\n                iframe.src = name + '.html';\n                checkMenu(name);\n            }\n            \n            function checkMenu(name) {\n                if (cur) links[cur].classList.remove('selected');\n                cur = name;\n                links[cur].classList.add('selected');\n                window.location.hash = name;\n                iframe.focus();\n            };\n        };\n    </script>\n</body>\n\n</html>"
  },
  {
    "path": "examples/js/util.js",
    "content": "const pixelRatio = 2;\nlet isDown = false, moveX = 0, moveY = 0, offsetX = 0, offsetY = 0;\nlet canvas, ctx;\nlet renderer, stage;\nlet sw = document.body.clientWidth;\nlet sh = document.body.clientHeight;\n\nfunction generateCanvas() {\n    canvas = document.createElement('canvas');\n    document.body.appendChild(canvas);\n    ctx = canvas.getContext(\"2d\");\n\n    window.addEventListener('resize', canvasResize, false);\n    canvasResize();\n\n    moveEvent(canvas);\n}\n\nfunction canvasResize() {\n    sw = document.body.clientWidth;\n    sh = document.body.clientHeight;\n\n    canvas.width = sw * pixelRatio;\n    canvas.height = sh * pixelRatio;\n    canvas.style.width = sw + 'px';\n    canvas.style.height = sh + 'px';\n    ctx.scale(pixelRatio, pixelRatio);\n}\n\nfunction generatePixi(bgcolor) {\n    renderer = new PIXI.Renderer({\n        width: sw,\n        height: sh,\n        antialias: true,\n        transparent: false,\n        autoDensity: true,\n        resolution: pixelRatio,//window.devicePixelRatio > 1 ? 2 : 1,\n        powerPreference: \"high-performance\",\n        backgroundColor: bgcolor\n    });\n    document.body.appendChild(renderer.view);\n    stage = new PIXI.Container();\n\n    window.addEventListener('resize', pixiResize, false);\n    pixiResize();\n\n    moveEvent(renderer.view);\n}\n\nfunction pixiResize() {\n    sw = document.body.clientWidth;\n    sh = document.body.clientHeight;\n\n    renderer.resize(sw, sh);\n}\n\nfunction moveEvent(canvas) {\n    const hammer = new Hammer(canvas);\n    hammer.add(new Hammer.Pan({direction: Hammer.DIRECTION_ALL, threshold: 0}));\n    hammer.on(\"pan\", (e) => {                \n        moveX = e.deltaX + offsetX;\n        moveY = e.deltaY + offsetY;\n        if (e.isFinal) {\n            offsetX = moveX;\n            offsetY = moveY;\n        }\n    });\n}\n\nfunction getSize(size) {\n    let ratio = Math.sqrt(sw * sw + sh * sh) / 1800;\n    if (ratio > 1) ratio = 1;\n    else if (ratio < 0.5) ratio = 0.5;\n    return size * ratio;\n}"
  },
  {
    "path": "examples/mask-tiling-pixi.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\">\n    <title>Leon Sans - MASK + Tiling PIXI</title>\n\n    <style>\n        html,\n        body {\n            width: 100%;\n            height: 100%;\n            overflow: hidden;\n            outline: 0;\n            margin: 0;\n            padding: 0;\n            cursor: move;\n        }\n    </style>\n\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.0.4/pixi.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js\"></script>\n</head>\n\n<body>\n    <script src=\"../dist/leon.js\"></script>\n    <script src=\"js/util.js\"></script>\n    <script>\n        let container, loader, textures = [];\n        let tiling = [], cur = -1;\n        let leon, controll;\n\n        function init() {\n            generatePixi(0x000000);\n\n            container = new PIXI.Container();\n            stage.addChild(container);\n\n            loader = new PIXI.Loader();\n            loader.add('tile1', 'data/tile1.png')\n            .add('tile2', 'data/tile2.png')\n            .add('tile3', 'data/tile3.png')\n            .add('tile4', 'data/tile4.png')\n            .add('tile5', 'data/tile5.png')\n            .add('tile6', 'data/tile6.png');\n\n            loader.load((loader, resources) => {\n                textures.push(resources.tile1.texture);\n                textures.push(resources.tile2.texture);\n                textures.push(resources.tile3.texture);\n                textures.push(resources.tile4.texture);\n                textures.push(resources.tile5.texture);\n                textures.push(resources.tile6.texture);\n                textures = shuffle(textures);\n\n                loaded();\n            });\n        }\n\n\n        function loaded() {\n            controll = {\n                align: {},\n            };\n\n            leon = new LeonSans({\n                text: '012\\n345',\n                size: getSize(400),\n                weight: 900,\n                tracking: 1,\n                leading: -1,\n                align: 'center'\n            });\n            leon.on('update', (model) => {  \n                update();\n            });\n\n            const gui = new dat.GUI();\n            gui.add(leon, 'text');\n            gui.add(leon, 'size', 10, 1000);\n            gui.add(leon, 'weight', 1, 900);\n\n            requestAnimationFrame(animate);\n        }\n\n\n        function update() {\n            while(container.children[0]) { \n                container.removeChild(container.children[0]);\n            }\n            \n            const total = leon.data.length;\n            let i, d, color, line, pos;\n            let j, j_total, lineW = leon.lineWidth;\n\n            let graphics, tilingSprite;\n\n            tiling = [];\n\n            for (i = 0; i < total; i++) {\n                d = leon.data[i];\n\n                graphics = new PIXI.Graphics();\n                container.addChild(graphics);\n\n                tilingSprite = new PIXI.TilingSprite(\n                    textures[getNum()],\n                    d.rect.w * 2,\n                    d.rect.h * 2\n                );\n                tilingSprite.x = d.rect.x - d.rect.w /2;\n                tilingSprite.y = d.rect.y - d.rect.h / 2;\n                tilingSprite.tileScale.x = tilingSprite.tileScale.y = leon.scale * 0.5;\n                \n                container.addChild(tilingSprite);\n\n                tilingSprite.mask = graphics;\n                tiling.push({\n                    item: tilingSprite,\n                    x: (Math.random() * 2 + 1 - 2) * 2,\n                    y: (Math.random() * 2 + 1 - 2) * 2\n                });\n\n                j_total = d.lines.length;\n                for (j = 0; j < j_total; j++) {\n                    line = d.lines[j];\n                    pos = d.lines[j].pos;\n\n                    if (pos.type == 'a') {\n                        graphics.lineStyle(0, color, 0);\n                        graphics.beginFill(color);\n                        graphics.drawCircle(pos.x, pos.y, pos.radius);\n                        graphics.endFill();\n                    } else if (pos.type == 'm') {\n                        graphics.lineStyle(lineW, color, 1);\n                        graphics.moveTo(pos.x, pos.y);\n                    } else if (pos.type == 'l') {\n                        graphics.lineTo(pos.x, pos.y);\n                    } else if (pos.type == 'b') {\n                        graphics.bezierCurveTo(pos.x, pos.y, pos.x2, pos.y2, pos.x3, pos.y3);\n                    }\n                    if (line.closePath) {\n                        graphics.closePath();\n                    }\n                }\n                \n            }\n        }\n\n        function animate(t) {\n            requestAnimationFrame(animate);\n\n            const x = (sw - leon.rect.w) / 2;\n            const y = (sh - leon.rect.h) / 2;\n            leon.position(x + moveX, y + moveY);\n\n            const total = tiling.length;\n            let i, p;\n            for (i = 0; i < total; i++) {\n                p = tiling[i];\n                p.item.tilePosition.x += p.x * leon.scale;\n                p.item.tilePosition.y += p.y * leon.scale;\n            }\n\n            renderer.render(stage);\n        }\n\n        function getNum() {\n            cur += 1;\n            if (cur == textures.length) {\n                cur = 0;\n            }\n            return cur;\n        }\n\n        function shuffle(oldArray) {\n            var newArray = oldArray.slice(),\n                len = newArray.length,\n                i = len, p, t;\n            while (i--) {\n                p = (Math.random()*len) | 0;\n                t = newArray[i];\n                newArray[i] = newArray[p];\n                newArray[p] = t;\n            }\n            return newArray;\n        }\n\n        window.onload = () => {\n            init();\n        };\n    </script>\n</body>\n\n</html>"
  },
  {
    "path": "examples/metaball-pixi.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\">\n    <title>Leon Sans - Metaball PIXI</title>\n    <style>\n        html,\n        body {\n            width: 100%;\n            height: 100%;\n            overflow: hidden;\n            outline: 0;\n            margin: 0;\n            padding: 0;\n            cursor: move;\n        }\n    </style>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.0.4/pixi.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js\"></script>\n</head>\n\n<body>\n    <script src=\"../dist/leon.js\"></script>\n    <script src=\"js/util.js\"></script>\n    <script>\n        let container, texture, particleCon;\n        let leon, controll, weightControll;\n        const particleTotal = 10000;\n        let particles = [];\n        \n        function init() {\n            generatePixi(0x000000);\n\n            texture = PIXI.Texture.from('data/drop-alpha.png');\n            particleCon = new PIXI.ParticleContainer(particleTotal, {\n                vertices: false,\n                scale: true,\n                position: true,\n                rotation: false,\n                uvs: false,\n                alpha: false\n            });\n            stage.addChild(particleCon);\n\n            let p, i;\n            for (i = 0; i < particleTotal; i++) {\n                p = new PIXI.Sprite(texture);\n                p.x = sw / 2;\n                p.y = sh / 2;\n                p.anchor.set(0.5);\n                p.scale.x = p.scale.y = 0;\n                particleCon.addChild(p);\n                particles.push(p);\n            }\n\n            const blurFilter = new PIXI.filters.BlurFilter();\n            blurFilter.blur = 10;\n            blurFilter.autoFit = true;\n\n            const fragSource = [\n                    'precision mediump float;',\n                    'varying vec2 vTextureCoord;',\n                    'uniform sampler2D uSampler;',\n                    'uniform float threshold;',\n                    'uniform float mr;',\n                    'uniform float mg;',\n                    'uniform float mb;',\n                    'void main(void)',\n                    '{',\n                    '    vec4 color = texture2D(uSampler, vTextureCoord);',\n                    '    vec3 mcolor = vec3(mr, mg, mb);',\n                    '    if (color.a > threshold) {',\n                    '       gl_FragColor = vec4(mcolor, 1.0);',\n                    '    } else {',\n                    '       gl_FragColor = vec4(vec3(0.0), 0.0);',\n                    '    }',\n                    '}'\n                ].join('\\n');\n\n            const uniformsData = {\n                threshold: 0.5,\n                mr: 255.0/255.0,\n                mg: 255.0/255.0,\n                mb: 255.0/255.0,\n            };\n\n            const thresholdFilter = new PIXI.Filter(null, fragSource, uniformsData);\n            stage.filters = [blurFilter, thresholdFilter];\n            stage.filterArea = renderer.screen;\n\n            controll = {\n                weight: 3,\n                color: {},\n                outline: true,\n                drawing: () => {\n                    let i;\n                    for (i = 0; i < particleTotal; i++) {\n                        TweenMax.killTweensOf(particles[i].scale);\n                        TweenMax.set(particles[i].scale, {\n                            x: 0,\n                            y: 0\n                        });\n                        TweenMax.to(particles[i].scale, 3, {\n                            delay: 0.001 * i,\n                            x: particles[i].saveScale,\n                            y: particles[i].saveScale,\n                            ease: Circ.easeOut\n                        });\n                    }\n                }\n            };\n\n            leon = new LeonSans({\n                text: 'TOP\\n678',\n                size: getSize(400),\n                weight: 700,\n                pathGap: -1,\n                isPath: true,\n                tracking: 0\n            });\n            leon.on('update', (model) => {  \n                update();\n            });\n            \n            const gui = new dat.GUI();\n            gui.add(leon, 'text');\n            const sizeControll = gui.add(leon, 'size', 200, 1000);\n            gui.add(leon, 'tracking', -6, 10);\n            gui.add(leon, 'leading', -8, 10);\n            weightControll = gui.add(controll, 'weight', 1, 9);\n            gui.add(controll, 'drawing');\n            const colorControll = gui.add(controll, 'color', [ 'white', 'black', 'red'] );\n\n            sizeControll.onChange((value) => {\n                sizeWeight();\n            });\n\n            weightControll.onChange((value) => {\n                update();\n            });\n\n            colorControll.onChange((value) => {\n                if (value == 'white') {\n                    renderer.backgroundColor = 0x000000;\n                    uniformsData.mr = 255.0/255.0;\n                    uniformsData.mg = 255.0/255.0;\n                    uniformsData.mb = 255.0/255.0;\n                } else if (value == 'black') {\n                    renderer.backgroundColor = 0xffffff;\n                    uniformsData.mr = 0.0/255.0;\n                    uniformsData.mg = 0.0/255.0;\n                    uniformsData.mb = 0.0/255.0;\n                }  else if (value == 'red') {\n                    renderer.backgroundColor = 0xe4c143;\n                    uniformsData.mr = 244.0/255.0;\n                    uniformsData.mg = 46.0/255.0;\n                    uniformsData.mb = 33.0/255.0;\n                } \n            });\n            colorControll.setValue('white');\n\n            requestAnimationFrame(animate);\n\n            sizeWeight();\n\n            TweenMax.delayedCall(0.1, () => {\n                controll.drawing();\n            });            \n        }\n\n        function sizeWeight() {\n            let w;\n            if (leon.size > 400) {\n                w = (1.5 - 3) / (1000 - 400) * (leon.size - 400) + 3;\n            } else {\n                w = (3 - 6) / (400 - 200) * (leon.size - 200) + 6;\n            }\n            weightControll.setValue(w);\n        }\n\n        function update() {\n            const total = leon.paths.length;\n            const sw2 = sw / 2;\n            const sh2 = sh / 2;\n            let i, p, pos, scale; \n            for (i = 0; i < particleTotal; i++) {\n                p = particles[i];\n                TweenMax.killTweensOf(p.scale);\n                if (i < total) {\n                    pos = leon.paths[i];\n                    if (pos.type == 'a') {\n                        scale = controll.weight * 0.025* leon.scale;\n                    } else {\n                        scale = controll.weight * 0.01* leon.scale;\n                    }\n                    p.saveScale = scale;\n                    p.x = pos.x;\n                    p.y = pos.y;\n                    p.scale.x = p.scale.y = scale;\n                } else {\n                    p.saveScale = 0;\n                    p.x = -1000;\n                    p.y = -1000;\n                    p.scale.x = p.scale.y = 0;                   \n                }\n            }        \n        }\n\n        function animate(t) {\n            requestAnimationFrame(animate);\n\n            const x = (sw - leon.rect.w) / 2;\n            const y = (sh - leon.rect.h) / 2;\n            leon.position(x + moveX, y + moveY);\n\n            renderer.render(stage);\n        }\n\n        window.onload = () => {\n            init();\n        };\n    </script>\n</body>\n\n</html>"
  },
  {
    "path": "examples/morphing-pixi.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\">\n    <title>Leon Sans - Morphing PIXI</title>\n\n    <style>\n        html,\n        body {\n            width: 100%;\n            height: 100%;\n            overflow: hidden;\n            outline: 0;\n            margin: 0;\n            padding: 0;\n            cursor: move;\n        }\n    </style>\n\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.0.4/pixi.min.js\"></script>\n    <script src=\"https://cdn.jsdelivr.net/npm/pixi-filters@latest/dist/pixi-filters.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js\"></script>\n</head>\n\n<body>\n    <script src=\"../dist/leon.js\"></script>\n    <script src=\"js/util.js\"></script>\n    <script>\n        let container, texture, particleCon;\n        let leon, controll;\n        const particleTotal = 5000;\n        let particles = [];\n        let myText = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789?!$^&*(){}[]<>~:;,.\\'\"+=-_@#%'.split('');\n        const textTotal = myText.length;\n        let curText = -1;\n        let DELAY_TIME = 0.8;\n\n        function init() {\n            generatePixi(0xfec82e);\n\n            myText = shuffle(myText);\n\n            texture = PIXI.Texture.from('data/drop-alpha.png');\n\n            particleCon = new PIXI.ParticleContainer(particleTotal, {\n                vertices: false,\n                scale: true,\n                position: true,\n                rotation: false,\n                uvs: false,\n                alpha: false\n            });\n            stage.addChild(particleCon);\n\n            let p, i;\n            for (i = 0; i < particleTotal; i++) {\n                p = new PIXI.Sprite(texture);\n                p.x = sw / 2;\n                p.y = sh / 2;\n                p.anchor.set(0.5);\n                p.scale.x = p.scale.y = 0;\n                particleCon.addChild(p);\n                particles.push(p);\n            }\n\n            const blurFilter = new PIXI.filters.BlurFilter();\n            blurFilter.blur = 10;\n            blurFilter.autoFit = true;\n\n            const fragSource = [\n                    'precision mediump float;',\n                    'varying vec2 vTextureCoord;',\n                    'uniform sampler2D uSampler;',\n                    'uniform float threshold;',\n                    'uniform float mr;',\n                    'uniform float mg;',\n                    'uniform float mb;',\n                    'void main(void)',\n                    '{',\n                    '    vec4 color = texture2D(uSampler, vTextureCoord);',\n                    '    vec3 mcolor = vec3(mr, mg, mb);',\n                    '    if (color.a > threshold) {',\n                    '       gl_FragColor = vec4(mcolor, 1.0);',\n                    '    } else {',\n                    '       gl_FragColor = vec4(vec3(0.0), 0.0);',\n                    '    }',\n                    '}'\n                ].join('\\n');\n\n            const uniformsData = {\n                threshold: 0.5,\n                mr: 255.0/255.0,\n                mg: 255.0/255.0,\n                mb: 255.0/255.0,\n            };\n\n            const thresholdFilter = new PIXI.Filter(null, fragSource, uniformsData );\n\n            const outlineFilterBlue = new PIXI.filters.OutlineFilter(1, 0x000000);\n\n            stage.filters = [blurFilter, thresholdFilter, outlineFilterBlue];\n            stage.filterArea = renderer.screen;\n\n            controll = {\n                weight: 6,\n                outline: true\n            };\n\n            leon = new LeonSans({\n                text: '',\n                size: 600,\n                weight: 700,\n                pathGap: -1,\n                isPath: true\n            });\n            leon.on('update', (data) => {  \n                update(data);\n            });\n            \n            const gui = new dat.GUI();\n            gui.add(leon, 'size', 400, 1000);\n            gui.add(controll, 'weight', 3, 9);\n            const otControll = gui.add(controll, 'outline');\n            otControll.onChange((value) => {\n                if (value) {\n                    stage.filters = [blurFilter, thresholdFilter, outlineFilterBlue];\n                } else {\n                    stage.filters = [blurFilter, thresholdFilter];\n                }\n            });\n\n            requestAnimationFrame(animate);\n\n            showText();\n        }\n\n        function nextText() {\n            TweenMax.killDelayedCallsTo(showText);\n            TweenMax.delayedCall(DELAY_TIME, showText);\n        }\n\n        function showText() {\n            curText += 1;\n            if (curText == textTotal) curText = 0;\n            leon.text = myText[curText];\n            nextText();\n        }\n\n        function shuffle(oldArray) {\n            var newArray = oldArray.slice(),\n                len = newArray.length,\n                i = len, p, t;\n            while (i--) {\n                p = (Math.random()*len) | 0;\n                t = newArray[i];\n                newArray[i] = newArray[p];\n                newArray[p] = t;\n            }\n            return newArray;\n        }\n\n        function update(model) {\n            const total = model.paths.length;\n            const sw2 = sw / 2;\n            const sh2 = sh / 2;\n            let i, p, pos, scale; \n            for (i = 0; i < particleTotal; i++) {\n                p = particles[i];\n                TweenMax.killTweensOf(p);\n                if (i < total) {\n                    pos = model.paths[i];\n                    if (pos.type == 'a') {\n                        scale = controll.weight * 0.02* leon.scale;\n                    } else {\n                        scale = controll.weight * 0.01* leon.scale;\n                    }\n                    TweenMax.to(p, 0.4, {\n                        x: sw2, \n                        y: sh2,\n                        ease: Sine.easeIn\n                    });\n                    TweenMax.to(p, 0.5, {\n                        delay: 0.3,\n                        x: pos.x, \n                        y: pos.y,\n                        ease: Expo.easeOut\n                    });\n                    TweenMax.to(p.scale, 0.5, {\n                        delay: 0.3,\n                        x: scale, \n                        y: scale,\n                        ease: Expo.easeOut\n                    });\n                } else {\n                    TweenMax.to(p, 0.3, {\n                        x: sw2, \n                        y: sh2,\n                        ease: Sine.easeIn\n                    });\n                    TweenMax.to(p.scale, 0.3, {\n                        x: 0, \n                        y: 0,\n                        ease: Sine.easeIn\n                    });\n                   \n                }\n            }\n        }\n\n        function animate(t) {\n            requestAnimationFrame(animate);\n\n            const x = (sw - leon.rect.w) / 2;\n            const y = (sh - leon.rect.h) / 2;\n            leon.position(x, y);\n\n            renderer.render(stage);\n        }\n\n        window.onload = () => {\n            init();\n        };\n\n    </script>\n</body>\n\n</html>"
  },
  {
    "path": "examples/pattern.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\">\n    <title>Leon Sans - Pattern</title>\n\n    <style>\n        html, body {\n            width: 100%;\n            height: 100%;\n            overflow: hidden;\n            outline: 0;\n            margin: 0;\n            padding: 0;\n            background-color: #502c8d;\n            cursor: move;\n        }\n    </style>\n\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js\"></script>\n</head>\n\n<body>\n    <script src=\"../dist/leon.js\"></script>\n    <script src=\"js/util.js\"></script>\n    <script>\n        let leon, controll;\n\n        function init() {\n            generateCanvas();\n\n            controll = {\n                color: {},\n                align: {},\n                patternWidth: 40,\n                patternHeight: 10,\n                drawing: () => {\n                    let i, total = leon.drawing.length;\n                    for (i = 0; i < total; i++) {\n                        TweenMax.killTweensOf(leon.drawing[i]);\n                        TweenMax.fromTo(leon.drawing[i], 2, {\n                            value: 0\n                        }, {\n                            delay: i * 0.05,\n                            value: 1,\n                            ease: Power4.easeOut\n                        });\n                    }\n                }\n            };\n\n            leon = new LeonSans({\n                text: 'The quick brown\\nfox jumps over\\nthe lazy dog',\n                size: getSize(120),\n                weight: 400,\n                isPath: true,\n                pathGap: 0.2\n            });\n\n            const gui = new dat.GUI();\n            gui.add(leon, 'text');\n            gui.add(leon, 'size', 20, 300);\n            gui.add(leon, 'pathGap', 0, 1);\n            gui.add(controll, 'patternWidth', 1, 200);\n            gui.add(controll, 'patternHeight', 1, 100);\n            gui.add(controll, 'drawing');\n\n            requestAnimationFrame(animate);\n        }\n\n        function animate(t) {\n            requestAnimationFrame(animate);\n\n            ctx.clearRect(0, 0, sw, sh);\n\n            const x = (sw - leon.rect.w) / 2;\n            const y = (sh - leon.rect.h) / 2;\n            leon.position(x + moveX, y + moveY);\n\n            leon.pattern(ctx, controll.patternWidth, controll.patternHeight);\n        }\n\n        window.onload = () => {\n            init();\n        };\n    </script>\n</body>\n\n</html>"
  },
  {
    "path": "examples/plants-pixi.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\">\n    <title>Leon Sans - Plants PIXI</title>\n    <style>\n        html,\n        body {\n            width: 100%;\n            height: 100%;\n            overflow: hidden;\n            outline: 0;\n            margin: 0;\n            padding: 0;\n            cursor: move;\n        }\n    </style>\n\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.0.4/pixi.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js\"></script>\n</head>\n\n<body>\n    <script src=\"../dist/leon.js\"></script>\n    <script src=\"js/util.js\"></script>\n    <script>\n        let container, loader, resource;\n        let leafs = [], flowers = [];\n        let leon, controll;\n        const tintLeaf = [\n            0xFFFFFF,\n            0xFFFF00,\n            0xccff00,\n            0x00ff1e,\n            0xffb300,\n            0xa2ff00\n        ];\n        const tintFlower = [\n            0xFFFFFF,\n            0xffeea1,\n            0xffa1a1,\n            0xeca1ff,\n            0xa1dbff,\n            0xffa1d6,\n            0xd2ffa1,\n        ];\n\n        function init() {\n            generatePixi(0xf0f0f0);\n\n            container = new PIXI.Container();\n            stage.addChild(container);\n\n            loader = new PIXI.Loader();\n            loader.add('branch_long', 'data/branch_long.png')\n            .add('branch_circle', 'data/branch_circle.png')\n            .add('flower1', 'data/flower1.png')\n            .add('flower2', 'data/flower2.png')\n            .add('flower3', 'data/flower3.png')\n            .add('leaf1', 'data/leaf1.png')\n            .add('leaf2', 'data/leaf2.png');\n\n            loader.load((loader, resources) => {\n                resource = resources;\n\n                flowers.push('flower1');\n                flowers.push('flower2');\n                flowers.push('flower3');\n\n                leafs.push('leaf1');\n                leafs.push('leaf1');\n                leafs.push('leaf2');\n\n                loaded();\n            });            \n        }\n\n        function loaded() {\n            controll = {\n                color: {},\n            };\n\n            leon = new LeonSans({\n                text: 'ONE',\n                size: getSize(500),\n                weight: 1,\n                pathGap: -1,\n                tracking: 0,\n                isPath: true\n            });\n            leon.on('update', (data) => {  \n                update(data);\n            });\n\n            const gui = new dat.GUI();\n            gui.add(leon, 'text');\n            gui.add(leon, 'tracking', -3, 10);\n\n            window.addEventListener('resize', resize, false);\n            requestAnimationFrame(animate);\n        }\n\n        function resize() {\n            sw = document.body.clientWidth;\n            sh = document.body.clientHeight;\n\n            renderer.resize(sw, sh);\n        }\n\n        function update() {\n            while(container.children[0]) { \n                TweenMax.killTweensOf(container.children[0]);\n                container.removeChild(container.children[0]);\n            }\n\n            let points, saveFlowers = [], saveLeafs = [];\n            let total = leon.model.data.length;\n            let i, j, j_total, d, pos;\n            for (i = 0; i < total; i++) {\n                d = leon.model.data[i];\n                j_total = d.paths.length;\n                points = [];\n                for (j = 0; j < j_total; j++) {\n                    pos = d.paths[j];\n\n                    if (pos.type == 'a') {\n                        const dot = new PIXI.Sprite(resource.branch_circle.texture);\n                        dot.anchor.set(0.5);\n                        dot.x = pos.x;\n                        dot.y = pos.y;\n                        const scale = 0.15 * leon.scale;\n                        dot.scale.x = dot.scale.y = scale;\n                        container.addChild(dot);  \n                    } else if (pos.start == 1) {\n                        if (points.length > 0) {\n                            addBranch(points);\n                        }\n                        points = [];\n                        points.push(new PIXI.Point(pos.x, pos.y));\n                    } else { \n                        points.push(new PIXI.Point(pos.x, pos.y));\n                    }\n\n                    if (Math.random() > 0.99) {\n                        saveFlowers.push(pos);\n                    }\n\n                    if (Math.random() > 0.84) {\n                        saveLeafs.push(pos);\n                    }\n                }\n\n                if (points.length > 0) {\n                    addBranch(points);\n                }\n            }\n\n            function addBranch(points) {\n                const branch = new PIXI.SimpleRope(resource.branch_long.texture, points);\n                container.addChild(branch);  \n            }\n\n            total = saveLeafs.length;\n            for (i = 0; i < total; i++) {\n                pos = saveLeafs[i];\n                d = leafs[Math.floor(0.5 + (Math.random()*(leafs.length-1)))];\n                const leaf = new PIXI.Sprite(resource[d].texture);\n                leaf.anchor.set(0.5, 1);\n                leaf.x = pos.x;\n                leaf.y = pos.y;\n                const scale = 0.1 * (0.2 + Math.random() * (1.2 - 0.2)) * leon.scale;\n                leaf.scale.x = leaf.scale.y = 0;\n                leaf.rotation = (pos.rotation + (90 * (Math.PI / 180)) * (Math.random() > 0.5 ? 1 : -1)) + (Math.random() * (Math.PI / 2) - (Math.PI / 4));\n                container.addChild(leaf);\n                leaf.tint = tintLeaf[Math.floor(0.5 + (Math.random()*(tintLeaf.length-1)))];     \n                TweenMax.to(leaf.scale, 0.8, {\n                    delay: 0.004 * i,\n                    x: scale,\n                    y: scale,\n                    ease: Power3.easeOut\n                });\n            }\n\n            total = saveFlowers.length;\n            for (i = 0; i < total; i++) {\n                pos = saveFlowers[i];\n                d = flowers[Math.floor(0.5 + (Math.random()*(flowers.length-1)))];\n                const flower = new PIXI.Sprite(resource[d].texture);\n                flower.anchor.set(0.5);\n                flower.x = pos.x;\n                flower.y = pos.y;\n                const scale = 0.04 * (0.6 + Math.random() * (1.2 - 0.6)) * leon.scale;\n                flower.scale.x = flower.scale.y = 0;\n                flower.rotation = Math.random() * Math.PI * 2;\n                container.addChild(flower);\n                flower.tint = tintFlower[Math.floor(0.5 + (Math.random()*(tintFlower.length-1)))];    \n                TweenMax.to(flower.scale, 0.8, {\n                    delay: 0.05 * i + 0.6,\n                    x: scale,\n                    y: scale,\n                    ease: Power3.easeOut\n                });\n            }\n        }\n\n        function animate(t) {\n            requestAnimationFrame(animate);\n\n            const x = (sw - leon.rect.w) / 2;\n            const y = (sh - leon.rect.h) / 2;\n            leon.position(x + moveX, y + moveY);\n\n            renderer.render(stage);\n        }\n\n        window.onload = () => {\n            init();\n        };\n    </script>\n</body>\n\n</html>"
  },
  {
    "path": "examples/wave.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\">\n    <title>Leon Sans - Wave</title>\n\n    <style>\n        html, body {\n            width: 100%;\n            height: 100%;\n            overflow: hidden;\n            outline: 0;\n            margin: 0;\n            padding: 0;\n            background-color: #000000;\n            cursor: move;\n        }\n    </style>\n\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js\"></script>\n</head>\n\n<body>\n    <script src=\"../dist/leon.js\"></script>\n    <script src=\"js/util.js\"></script>\n    <script>\n        let leon, controll;\n\n        function init() {\n            generateCanvas();\n\n            const controll = {\n                color: {},\n                align: {},\n            };\n\n            leon = new LeonSans({\n                text: 'The quick brown\\nfox jumps over\\nthe lazy dog',\n                color: ['#ffffff'],\n                size: getSize(120),\n                weight: 1,\n                isWave: true,\n                pathGap: 0.3,\n                amplitude: 0.5,\n                fps: 30\n            });\n\n            const gui = new dat.GUI();\n            gui.add(leon, 'text');\n            gui.add(leon, 'size', 20, 300);\n            gui.add(leon, 'weight', 1, 300);\n            gui.add(leon, 'pathGap', 0, 1);\n            gui.add(leon, 'amplitude', 0, 1);\n            gui.add(leon, 'fps', 10, 60);\n\n            requestAnimationFrame(animate);\n        }\n\n        function animate(t) {\n            requestAnimationFrame(animate);\n\n            ctx.clearRect(0, 0, sw, sh);\n\n            const x = (sw - leon.rect.w) / 2;\n            const y = (sh - leon.rect.h) / 2;\n            leon.position(x + moveX, y + moveY);\n\n            leon.wave(ctx, t);\n        }\n\n        window.onload = () => {\n            init();\n        };\n    </script>\n</body>\n\n</html>"
  },
  {
    "path": "examples/webgl-basic-pixi.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\">\n    <title>Leon Sans - WebGL Basic PIXI</title>\n\n    <style>\n        html, body {\n            width: 100%;\n            height: 100%;\n            overflow: hidden;\n            outline: 0;\n            margin: 0;\n            padding: 0;\n            cursor: move;\n        }\n    </style>\n\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.0.4/pixi.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js\"></script>\n</head>\n\n<body>\n    <script src=\"../dist/leon.js\"></script>\n    <script src=\"js/util.js\"></script>\n    <script>\n        let graphics;\n        let leon, controll;\n\n        function init() {\n            generatePixi(0x000000);\n\n            graphics = new PIXI.Graphics();\n            stage.addChild(graphics);\n\n            controll = {\n                color: {},\n                align: {},\n                drawing: () => {\n                    leon.updateDrawingPaths();\n\n                    let i, total = leon.drawing.length;\n                    for (i = 0; i < total; i++) {\n                        TweenMax.killTweensOf(leon.drawing[i]);\n                        TweenMax.fromTo(leon.drawing[i], 1.6, {\n                            value: 0\n                        }, {\n                            delay: i * 0.05,\n                            value: 1,\n                            ease: Power4.easeOut\n                        });\n                    }\n                },\n            };\n\n            leon = new LeonSans({\n                text: 'The quick brown\\nfox jumps over\\nthe lazy dog',\n                color: [0xffffff],\n                size: getSize(120),\n                weight: 300\n            });\n\n            const gui = new dat.GUI();\n            gui.add(leon, 'text');\n            gui.add(leon, 'size', 10, 2000);\n            gui.add(leon, 'weight', 1, 900);\n            gui.add(leon, 'tracking', -3, 10);\n            gui.add(leon, 'leading', -8, 10);\n            const alignControll = gui.add(controll, 'align', [ 'left', 'center', 'right'] );\n            gui.add(leon, 'maxWidth', 0, 2000);\n            gui.add(leon, 'breakWord');\n            gui.add(controll, 'drawing');\n            const colorControll = gui.add(controll, 'color', [ 'black', 'white', 'yellow' , 'mixed'] );\n\n            alignControll.onChange((value) => {\n                leon.align = value;\n            });\n            alignControll.setValue('left');\n\n            colorControll.onChange((value) => {\n                if (value == 'black') {\n                    renderer.backgroundColor = 0xf0f0f0;\n                    leon.color = [0x342f2e];\n                } else if (value == 'white') {\n                    renderer.backgroundColor = 0x000000;\n                    leon.color = [0xffffff];\n                } else if (value == 'yellow') {\n                    renderer.backgroundColor = 0x57c4e2;\n                    leon.color = [0xffd93c];\n                } else if (value == 'mixed') {\n                    document.body.style.backgroundColor = '#ffffff';\n                    leon.color = [0xff5892, 0xbc92f, 0xffd93c, 0xc0008b];\n                }\n            });\n            colorControll.setValue('white');\n\n            requestAnimationFrame(animate);\n        }\n\n        function animate(t) {\n            requestAnimationFrame(animate);\n\n            const x = (sw - leon.rect.w) / 2;\n            const y = (sh - leon.rect.h) / 2;\n            leon.position(x + moveX, y + moveY);\n\n            graphics.clear();\n            leon.drawPixi(graphics);\n\n            renderer.render(stage);\n        }\n\n        window.onload = () => {\n            init();\n        };\n    </script>\n</body>\n\n</html>"
  },
  {
    "path": "src/core/align.js",
    "content": "export function setAlignGapX(sw, tw) {\n    return {\n        c: (sw - tw) / 2,\n        r: sw - tw,\n        l: 0\n    };\n}\n\nexport function getAlignGapX(align, alignGapX) {\n    if (align == 'center') {\n        return alignGapX.c;\n    } else if (align == 'right') {\n        return alignGapX.r;\n    } else {\n        return alignGapX.l;\n    }\n}"
  },
  {
    "path": "src/core/dispatcher.js",
    "content": "export class Dispatcher {\n    constructor() {\n        this.handlers_ = {\n            update: {\n                listeners: []\n            }\n        };\n    }\n\n    on(event, callback) {\n        if (typeof callback !== 'function') {\n            console.error(`The listener callback must be a function, the given type is ${typeof callback}`);\n            return false;\n        }\n\n        if (typeof event !== 'string') {\n            console.error(`The event name must be a string, the given type is ${typeof event}`);\n            return false;\n        }\n\n        if (this.handlers_[event] === undefined) {\n            this.handlers_[event] = {\n                listeners: []\n            };\n        }\n\n        this.handlers_[event].listeners.push(callback);\n    }\n\n    off(event, callback) {\n        if (this.handlers_[event] === undefined) {\n            console.error(`This event: ${event} does not exist`);\n            return false;\n        }\n\n        this.handlers_[event].listeners = this.handlers_[event].listeners.filter(listener => {\n            return listener.toString() !== callback.toString();\n        });\n    }\n\n    dispatch(event, data) {\n        this.handlers_[event].listeners.forEach((listener) => {\n            listener(data);\n        });\n    }\n}"
  },
  {
    "path": "src/core/group.js",
    "content": "import {\n    getRect\n} from './util.js';\nimport {\n    typo\n} from '../font/index.js';\n\nexport function getTextGroup(text, scale, width, isBreakAll) {\n    let group;\n    if (text.indexOf('\\n') > 0) {\n        group = text.split('\\n');\n    } else if (text.indexOf('\\\\n') > 0) {\n        group = text.split('\\\\n');\n    } else {\n        group = [text];\n    }\n    if (width == 0) return keepAll(group);\n    else if (isBreakAll) return breakAll(group, scale, width);\n    else return breakWord(group, scale, width);\n}\n\nfunction keepAll(group) {\n    const textGroup = [];\n    const total = group.length;\n    let i;\n    for (i = 0; i < total; i++) {\n        textGroup[i] = group[i].split('');\n    }\n    return textGroup;\n}\n\nfunction breakWord(group, scale, width) {\n    let g2, g3, t, m_rect,\n        tw = 0,\n        tw2 = 0,\n        i, j, k,\n        total, j_total, k_total,\n        index = 0;\n    const tg = [];\n    total = group.length;\n    for (i = 0; i < total; i++) {\n        g2 = group[i].split(' ');\n        tg[index] = [];\n        j_total = g2.length;\n        for (j = 0; j < j_total; j++) {\n            tw2 = 0;\n            g3 = g2[j];\n            k_total = g3.length;\n            for (k = 0; k < k_total; k++) {\n                t = typo(g3[k]);\n                m_rect = getRect(t, scale);\n                tw2 += m_rect.w;\n            }\n            t = typo(' ');\n            m_rect = getRect(t, scale);\n            tw2 += m_rect.w;\n            tw += tw2;\n            if (tw > width) {\n                index += 1;\n                tw = tw2;\n                tg[index] = [];\n            }\n            tg[index].push(g3);\n        }\n        index += 1;\n        tw = 0;\n    }\n\n    total = tg.length;\n    const textGroup = [];\n    for (i = 0; i < total; i++) {\n        t = tg[i].join(' ').split('');\n        if (t.length > 0) {\n            textGroup.push(t);\n        }\n    }\n\n    return textGroup;\n}\n\nfunction breakAll(group, scale, width) {\n    let t,\n        i, total,\n        j, j_total,\n        m_rect,\n        g2, g3,\n        tw = 0,\n        index = 0,\n        tx = 0;\n    const tg = [];\n\n    total = group.length;\n    for (i = 0; i < total; i++) {\n        g2 = group[i];\n        tw = 0;\n        tx = 0;\n        tg[index] = [];\n        j_total = g2.length;\n        for (j = 0; j < j_total; j++) {\n            g3 = g2[j];\n            t = typo(g3);\n            m_rect = getRect(t, scale);\n            tw += m_rect.w;\n            tg[index].push(g3);\n            if (tw >= width) {\n                index += 1;\n                tw = m_rect.w;\n                tg[index] = [];\n            }\n        }\n        index += 1;\n    }\n\n    const textGroup = [];\n    total = tg.length;\n    for (i = 0; i < total; i++) {\n        t = tg[i];\n        if (t.length > 0) {\n            if (t[0] == ' ') t.shift();\n            if (t[t.length - 1] == ' ') t.pop();\n            if (t.length > 0) textGroup.push(t);\n        }\n    }\n    return textGroup;\n}"
  },
  {
    "path": "src/core/guide.js",
    "content": "import {\n    RECT_RATIO\n} from './util.js';\n\n/**\n * @name getGuide\n * @property {Object} - typo data object from 'font/index.js'\n * @property {Number} - scale\n * @returns {Object} the guide pos array\n * @description get a guide pos\n */\nexport function getGuide(d, scale) {\n    let guide = [],\n        ggap = 10,\n        i, gvx, gvy;\n    for (i = 0; i < 6; i++) {\n        gvx = (ggap * i) + 20;\n        gvy = (ggap * i) + 90;\n        guide[i] = {\n            x1: (gvx * RECT_RATIO) * scale,\n            x2: ((d.rect.w - (gvx * 2)) * RECT_RATIO) * scale,\n            y1: (gvy * RECT_RATIO) * scale,\n            y2: (((d.rect.h - gvy) * RECT_RATIO) * scale) - ((i * ggap * RECT_RATIO) * scale),\n        };\n    }\n\n    return guide;\n}\n\n/**\n * @name getGuide\n * @property {Object} - typo data object from 'font/index.js'\n * @property {Number} - scale\n * @returns {Object} the guide pos array\n * @description get a guide pos\n */\nexport function getGrid(d, scale) {\n    let grid = [],\n        i, gvy = [98, 340, 815];\n    for (i = 0; i < 3; i++) {\n        grid[i] = (gvy[i] * RECT_RATIO) * scale;\n    }\n\n    return grid;\n}"
  },
  {
    "path": "src/core/length.js",
    "content": "export function getLengths(item, model) {\n    const total = item.typo.p.length;\n    let c, p,\n        arr = [],\n        lt = [],\n        max = 0,\n        i;\n    for (i = 0; i < total; i++) {\n        p = item.typo.p[i];\n        c = getEachPath(item, p.v, model);\n        max += c.l;\n        arr.push(c.v);\n        lt.push(c.l);\n    }\n    return {\n        max: max,\n        lines: arr,\n        lengths: lt\n    };\n}\n\nfunction getEachPath(item, points, model) {\n    const total = points.length;\n    let i, p,\n        line, cp1, cp2, prev,\n        lines = [],\n        length = 0;\n\n    for (i = 0; i < total; i++) {\n        p = points[i];\n        line = {};\n        cp2 = p.convert(item, model);\n\n        if (i == 0 || p.type == 'a') {\n            line.x1 = cp2.x;\n            line.y1 = cp2.y;\n            line.distance = 0;\n            line.radius = cp2.radius;\n        } else {\n            cp1 = prev.convert(item, model);\n\n            if (prev.type == 'b') {\n                line.x1 = cp1.x3;\n                line.y1 = cp1.y3;\n            } else {\n                line.x1 = cp1.x;\n                line.y1 = cp1.y;\n            }\n\n            line.x2 = cp2.x;\n            line.y2 = cp2.y;\n\n            if (p.type == 'b') {\n                line.x3 = cp2.x2;\n                line.y3 = cp2.y2;\n                line.x4 = cp2.x3;\n                line.y4 = cp2.y3;\n                line.distance = cubicBezierLength(line.x1, line.y1, line.x2, line.y2, line.x3, line.y3, line.x4, line.y4);\n            } else {\n                line.distance = distance(line.x1, line.y1, line.x2, line.y2);\n            }\n        }\n\n        line.type = p.type;\n        line.rotation = p.ratio.r;\n        line.pat = p.ratio.p;\n        line.fix = p.ratio.f;\n        line.vt = p.ratio.v;\n\n        lines.push(line);\n        length += line.distance;\n\n        prev = p;\n    }\n\n    return {\n        v: lines,\n        l: length\n    };\n}\n\nexport function cubicBezierLength(x1, y1, x2, y2, x3, y3, x4, y4, sampleCount) {\n    const ptCount = sampleCount || 40;\n    let totDist = 0;\n    let lastX = x1;\n    let lastY = y1;\n    let dx, dy, i, pt;\n    for (i = 1; i < ptCount; i++) {\n        pt = cubicQxy(i / ptCount, x1, y1, x2, y2, x3, y3, x4, y4);\n        dx = pt.x - lastX;\n        dy = pt.y - lastY;\n        totDist += Math.sqrt(dx * dx + dy * dy);\n        lastX = pt.x;\n        lastY = pt.y;\n    }\n    dx = x4 - lastX;\n    dy = y4 - lastY;\n    totDist += Math.sqrt(dx * dx + dy * dy);\n    return totDist;\n}\n\nfunction cubicQxy(t, x1, y1, x2, y2, x3, y3, x4, y4) {\n    x1 += (x2 - x1) * t;\n    x2 += (x3 - x2) * t;\n    x3 += (x4 - x3) * t;\n    x1 += (x2 - x1) * t;\n    x2 += (x3 - x2) * t;\n    y1 += (y2 - y1) * t;\n    y2 += (y3 - y2) * t;\n    y3 += (y4 - y3) * t;\n    y1 += (y2 - y1) * t;\n    y2 += (y3 - y2) * t;\n    return {\n        x: x1 + (x2 - x1) * t,\n        y: y1 + (y2 - y1) * t\n    };\n}\n\nexport function distance(x1, y1, x2, y2) {\n    const a = (x2 - x1),\n        b = (y2 - y1);\n    return Math.sqrt(a * a + b * b);\n}"
  },
  {
    "path": "src/core/model.js",
    "content": "import {\n    getFontW,\n    getWeightRatio,\n    getCircleRound,\n    getScale,\n    getTracking,\n    getLeading,\n    getFontRatio,\n    getLineW,\n    getRect,\n    getCenter,\n    getRange,\n    getLines,\n    addRectToPaths,\n} from './util.js';\nimport {\n    getGuide,\n    getGrid\n} from './guide.js';\nimport {\n    getTextGroup\n} from './group.js';\nimport {\n    setAlignGapX,\n    getAlignGapX\n} from './align.js';\nimport {\n    typo\n} from '../font/index.js';\nimport {\n    getLengths\n} from './length.js';\nimport {\n    getPaths\n} from './paths.js';\n\n\nexport class Model {\n    constructor() {\n        this.lineWidth_ = 1;\n        this.drawing_ = [];\n        this.data_ = null;\n        this.paths_ = null;\n        this.lines_ = null;\n        this.rect_ = {\n            x: 0,\n            y: 0,\n            w: 0,\n            h: 0\n        };\n        this.align_ = 'left';\n        this.scale_ = 1;\n        this.fontRatio_ = 1;\n    }\n\n    get data() {\n        return this.data_;\n    }\n\n    get paths() {\n        return this.paths_;\n    }\n\n    get lines() {\n        return this.lines_;\n    }\n\n    set lines(v) {\n        this.lines_ = v;\n    }\n\n    get lineWidth() {\n        return this.lineWidth_;\n    }\n\n    get fontRatio() {\n        return this.fontRatio_;\n    }\n\n    get scale() {\n        return this.scale_;\n    }\n\n    get rect() {\n        return this.rect_;\n    }\n\n    get drawing() {\n        return this.drawing_;\n    }\n\n    set align(v) {\n        if (this.align_ != v) {\n            this.align_ = v;\n            this.setPosition();\n        }\n    }\n\n    get align() {\n        return this.align_;\n    }\n\n    position(x, y) {\n        if (this.rect_.x != x || this.rect_.y != y) {\n            this.rect_.x = x;\n            this.rect_.y = y;\n            this.setPosition();\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    setPosition() {\n        const total = this.data_.length;\n        let i, d;\n        for (i = 0; i < total; i++) {\n            d = this.data_[i];\n            d.rect.x = d.originPos.x + this.rect_.x + getAlignGapX(this.align_, d.alignGapX);\n            d.rect.y = d.originPos.y + this.rect_.y;\n        }\n    }\n\n    updateDrawingPaths() {\n        const total = this.data_.length;\n        let i, d;\n        for (i = 0; i < total; i++) {\n            d = this.data_[i];\n            d.drawingPaths = addRectToPaths(getPaths(this, d, -1, false), d);\n        }\n    }\n\n    updatePatternPaths(pathGap) {\n        const total = this.data_.length;\n        let i, d;\n        for (i = 0; i < total; i++) {\n            d = this.data_[i];\n            d.rawPaths = getPaths(this, d, pathGap, true);\n        }\n    }\n\n    updateWavePaths(pathGap) {\n        const total = this.data_.length;\n        let i, d;\n        for (i = 0; i < total; i++) {\n            d = this.data_[i];\n            d.rawWavePaths = getPaths(this, d, pathGap, false);\n        }\n    }\n\n    updateGuide() {\n        const total = this.data_.length;\n        let i, d;\n        for (i = 0; i < total; i++) {\n            d = this.data_[i];\n            d.guide = getGuide(d.typo, this.scale);\n            d.grid = getGrid(d.typo, this.scale);\n        }\n    }\n\n    update(text, width, breakWord, weight, size, tracking, leading) {\n        const fontW = getFontW(weight);\n        const weightRatio = getWeightRatio(fontW);\n        const circleRound = getCircleRound(fontW);\n        const scale = getScale(size);\n        const m_tracking = getTracking(tracking, scale);\n        const m_leading = getLeading(leading, scale);\n        const fontRatio = getFontRatio(weightRatio);\n\n        this.fontRatio_ = fontRatio;\n        this.scale_ = scale;\n        this.lineWidth_ = getLineW(fontW, scale);\n\n        const textGroup = getTextGroup(text, scale, width, breakWord);\n\n        let total = textGroup.length;\n        const total2 = total - 1;\n        let i, j, j_total, j_total2,\n            gt,\n            t, str,\n            m_rect,\n            s_pos,\n            tw = 0,\n            th = 0,\n            tx = 0,\n            ty = 0,\n            maxW = 0,\n            maxH = 0,\n            tmp = [];\n        for (i = 0; i < total; i++) {\n            gt = textGroup[i];\n            j_total = gt.length;\n            j_total2 = j_total - 1;\n            tw = 0;\n            tx = 0;\n            tmp[i] = {\n                tw: 0,\n                arr: []\n            };\n            for (j = 0; j < j_total; j++) {\n                str = gt[j];\n                t = typo(str);\n                m_rect = getRect(t, scale);\n                tw += m_rect.w;\n                th = m_rect.h;\n                if (j < j_total2) {\n                    tw += m_tracking;\n                }\n                if (i < total2) {\n                    th += m_leading;\n                }\n                m_rect.x = tx;\n                m_rect.y = ty;\n                s_pos = {\n                    x: tx,\n                    y: ty\n                };\n\n                tmp[i].arr[j] = {\n                    str: str,\n                    typo: t,\n                    rect: m_rect,\n                    originPos: s_pos,\n                    center: getCenter(m_rect.w, m_rect.h, scale),\n                    range: getRange(t, weightRatio, circleRound)\n                };\n\n                tx = tw;\n            }\n            ty += th;\n            tmp[i].tw = tw;\n            maxW = Math.max(maxW, tw);\n            maxH += th;\n        }\n\n        this.rect_.w = maxW;\n        this.rect_.h = maxH;\n\n        this.drawing_ = [];\n        const arr = [];\n        let aGapX, drawing;\n        for (const a of tmp) {\n            aGapX = setAlignGapX(maxW, a.tw);\n            for (const b of a.arr) {\n                b.alignGapX = aGapX;\n                b.pointsLength = getLengths(b, this);\n                arr.push(b);\n                drawing = {\n                    value: 1\n                };\n                this.drawing_.push(drawing);\n                b.drawing = drawing;\n\n                // add converted Vector\n                for (const c of b.typo.p) {\n                    c.cv = [];\n                    for (const d of c.v) {\n                        c.cv.push(d.convert(b, this));\n                    }\n                }\n            }\n        }\n\n        this.data_ = arr;\n        this.setPosition();\n    }\n\n    updatePathsForRect() {\n        const total = this.data_.length;\n        const paths = [];\n        let i, d;\n        for (i = 0; i < total; i++) {\n            d = this.data_[i];\n            if (d.rawWavePaths) {\n                d.wavePaths = addRectToPaths(d.rawWavePaths, d);\n            }\n            if (d.rawPaths) {\n                d.paths = addRectToPaths(d.rawPaths, d);\n                Array.prototype.push.apply(paths, d.paths);\n            }\n        }\n\n        this.paths_ = paths;\n    }\n\n    updateLinesForRect() {\n        const total = this.data_.length;\n        let i, d;\n        for (i = 0; i < total; i++) {\n            d = this.data_[i];\n            d.lines = getLines(d);\n        }\n    }\n\n    reset() {\n        this.lineWidth_ = 1;\n        this.drawing_ = [];\n        this.data_ = null;\n        this.paths_ = null;\n        this.lines_ = null;\n        this.rect_ = {\n            x: 0,\n            y: 0,\n            w: 0,\n            h: 0\n        };\n        this.align_ = 'left';\n        this.scale_ = 1;\n        this.fontRatio_ = 1;\n    }\n}"
  },
  {
    "path": "src/core/paths.js",
    "content": "import {\n    getCurrent\n} from './util.js';\nimport {\n    ROTATE_NONE\n} from '../font/util.js';\nimport {\n    Point\n} from './point.js';\n\nlet prevPoint = null;\n\n/**\n * @name getPaths\n * @property {Model} model - mode.js\n * @property {Object} data - data object\n * @property {Number} pathGap \n * @returns {Array} Returns paths array\n * @description get a guide pos\n */\nexport function getPaths(model, data, pathGap, isPattern) {\n    const lines = data.pointsLength.lines;\n    const scale = model.scale;\n    let total = lines.length,\n        i, j_total, j,\n        line, lg, direction,\n        arr = [],\n        paths = [],\n        paths2 = [];\n\n\n    for (i = 0; i < total; i++) {\n        line = lines[i];\n        prevPoint = null;\n        arr.push(getDotPos(line, pathGap, scale));\n    }\n\n    total = arr.length;\n    for (i = 0; i < total; i++) {\n        lg = arr[i];\n        j_total = lg.length;\n\n        paths2 = [];\n        for (j = 0; j < j_total; j++) {\n            line = lg[j];\n            if (line.rotation != ROTATE_NONE) {\n                if (isPattern) {\n                    // If the 'p' value of the font data is 1, it's not included in the pattern paths.\n                    if (!line.pat) {\n                        paths2.push(line);\n                    }\n                } else {\n                    paths2.push(line);\n                }\n            }\n        }\n        direction = data.typo.p[i].d;\n        if (direction == 1) {\n            paths2.reverse();\n        }\n\n        if (paths2.length > 0) {\n            paths2[0].start = 1;\n            Array.prototype.push.apply(paths, paths2);\n        }\n    }\n\n    return paths;\n}\n\nfunction getDotPos(lines, pathGap, scale) {\n    const total = lines.length;\n    let i, j, j_total;\n    let line;\n    let curPoint;\n    let num, pp;\n    let arr = [];\n    let isFirst = 1;\n    let pgap = 1;\n    if (pathGap > -1) pgap = getCurrent(pathGap, 1, 0, 80, 10) * scale;\n\n    for (i = 0; i < total; i++) {\n        line = lines[i];\n\n        if (line.type == 'a') {\n            arr.push(new Point({\n                x: line.x1,\n                y: line.y1,\n                rotation: 0,\n                type: 'a',\n                pat: line.pat,\n                fix: line.fix,\n                radius: line.radius\n            }));\n        } else if (line.distance == 0) {\n            // it should be type m\n            curPoint = new Point({\n                x: line.x1,\n                y: line.y1,\n                rotation: line.rotation,\n                type: line.type,\n                pat: line.pat,\n                fix: line.fix\n            });\n            pp = setPointValues(curPoint, prevPoint, line, 1);\n            if (pp != null) {\n                if (isFirst) {\n                    pp.type = 'm';\n                    isFirst = 0;\n                }\n                arr.push(pp);\n            }\n            prevPoint = new Point(curPoint); //Object.assign({}, curPoint)\n        } else {\n            j_total = Math.ceil(line.distance / pgap);\n\n            if (j_total < 3) j_total = 3;\n            if (line.vt) j_total = 2;\n\n            for (j = 1; j < j_total; j++) {\n                num = j / (j_total - 1);\n                if (line.type == 'b') {\n                    curPoint = getCubicBezierXYatT(line, num);\n                } else {\n                    curPoint = new Point({\n                        x: line.x1 + ((line.x2 - line.x1) * num),\n                        y: line.y1 + ((line.y2 - line.y1) * num),\n                        type: line.type\n                    });\n                }\n\n                if (line.rotation != 0 && num == 1) curPoint.rotation = line.rotation;\n\n                if (line.pat && num == 1) curPoint.pat = line.pat;\n\n                if (line.fix && num == 1) curPoint.fix = line.fix;\n\n                if (j_total > 0) {\n                    pp = setPointValues(curPoint, prevPoint, line, num);\n                    if (pp != null) {\n                        if (isFirst) {\n                            pp.type = 'm';\n                            isFirst = 0;\n                        }\n                        arr.push(pp);\n                    }\n                }\n                prevPoint = new Point(curPoint); //Object.assign({}, curPoint)\n            }\n        }\n    }\n    return arr;\n}\n\nfunction setPointValues(cur, prev, line, num) {\n    cur.type = line.type;\n    cur.distance = line.distance;\n    cur.num = num;\n\n    if (!prev || cur.rotation != null) {\n        cur.rotation = cur.rotation;\n    } else {\n        const dx = cur.x - prev.x;\n        const dy = cur.y - prev.y;\n        const rad = Math.atan2(dx, dy);\n        cur.rotation = -rad;\n    }\n\n    if (cur.rotation == ROTATE_NONE) {\n        return null;\n    } else {\n        return cur;\n    }\n}\n\nfunction getCubicBezierXYatT(line, t) {\n    const x = CubicN(line.x1, line.x2, line.x3, line.x4, t);\n    const y = CubicN(line.y1, line.y2, line.y3, line.y4, t);\n    const tx = bezierTangent(line.x1, line.x2, line.x3, line.x4, t);\n    const ty = bezierTangent(line.y1, line.y2, line.y3, line.y4, t);\n    const rotation = -Math.atan2(tx, ty);\n\n    return new Point({\n        x: x,\n        y: y,\n        rotation: rotation\n    });\n}\n\nfunction CubicN(a, b, c, d, t) {\n    const t2 = t * t;\n    const t3 = t2 * t;\n    return a + (-a * 3 + t * (3 * a - a * t)) * t + (3 * b + t * (-6 * b + b * 3 * t)) * t + (c * 3 - c * 3 * t) * t2 + d * t3;\n}\n\n//http://qaru.site/questions/10657973/quadratic-curve-with-rope-pattern\n//https://stackoverflow.com/questions/32322966/quadratic-curve-with-rope-pattern\nexport function bezierTangent(a, b, c, d, t) {\n    return (3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b));\n}"
  },
  {
    "path": "src/core/point.js",
    "content": "export function Point(mp) {\n    Object.assign(this, mp);\n}\n\nObject.assign(Point.prototype, {\n    addRect: function (rect) {\n        const vv = new Point(this);\n        vv.x = this.x + rect.x;\n        vv.y = this.y + rect.y;\n        vv.x2 = this.x2 + rect.x;\n        vv.y2 = this.y2 + rect.y;\n        vv.x3 = this.x3 + rect.x;\n        vv.y3 = this.y3 + rect.y;\n        vv.rx = this.rx + rect.x;\n        vv.ry = this.ry + rect.y;\n        vv.sx = this.sx + rect.x;\n        vv.sy = this.sy + rect.y;\n        if (vv.radius < 0.5) vv.radius = 0.5;\n        return vv;\n    }\n});"
  },
  {
    "path": "src/core/util.js",
    "content": "const DEFAULT_FONT_SIZE = 500;\nexport const MIN_FONT_WEIGHT = 1;\nexport const MAX_FONT_WEIGHT = 900;\nconst MAX_LINE_WIDTH = 70;\nconst FONT_WEIGHT_LIMIT = 80;\nconst FR_1 = 1;\nconst FR_2 = 0.78;\nexport const RECT_RATIO = 0.49;\nconst MAX_SHAKE = 120;\nexport const PI2 = 2 * Math.PI;\n\nexport function getAmplitude(amplitude, scale) {\n    return (MAX_SHAKE * amplitude) * scale;\n}\n\nexport function getFontW(weight) {\n    return (MAX_LINE_WIDTH - MIN_FONT_WEIGHT) / (MAX_FONT_WEIGHT - MIN_FONT_WEIGHT) * (weight - MIN_FONT_WEIGHT) + MIN_FONT_WEIGHT;\n}\n\nexport function getWeightRatio(fontW) {\n    return (1) / (FONT_WEIGHT_LIMIT - MIN_FONT_WEIGHT) * (fontW - MIN_FONT_WEIGHT);\n}\n\nexport function getCircleRound(fontW) {\n    return (58 - 4) / (FONT_WEIGHT_LIMIT - MIN_FONT_WEIGHT) * (fontW - MIN_FONT_WEIGHT) + 4;\n}\n\nexport function getScale(size) {\n    return size / DEFAULT_FONT_SIZE;\n}\n\nexport function getLineW(fontW, scale) {\n    let lw = fontW * scale;\n    if (lw < 1) lw = 1;\n    //if (weight == 1) lw = 1\n    return lw;\n}\n\nexport function getTracking(tracking, scale) {\n    return tracking * 50 * scale;\n}\n\nexport function getLeading(leading, scale) {\n    return leading * 50 * scale;\n}\n\nexport function getFontRatio(weightRatio) {\n    return (FR_2 - FR_1) * weightRatio + FR_1;\n}\n\nexport function getRect(d, scale, x = 0, y = 0) {\n    const w = (d.rect.w * RECT_RATIO) * scale;\n    const h = ((d.rect.h + 220) * RECT_RATIO) * scale;\n    return {\n        x: x,\n        y: y,\n        w: w,\n        h: h\n    };\n}\n\n/**\n * @name getGap\n * @property {Object} - typo data object from 'font/index.js'\n * @property {Number} - weightRatio\n * @returns {Object} the gap x and y\n * @description get a typo gap from thin to bold weight\n */\n/*\nexport function getGap(d, weightRatio) {\n    const gx1 = d.ratio.x1\n    const gx2 = d.ratio.x2\n    const gy1 = d.ratio.y1\n    const gy2 = d.ratio.y2\n    const x = (gx2 - gx1) * weightRatio + gx1\n    const y = (gy2 - gy1) * weightRatio + gy1\n    return {\n        x: x,\n        y: y\n    }\n}\n*/\n\n/**\n * @name getCenter\n * @property {Number} - typo rect width\n * @property {Number} - typo rect height\n * @property {Number} - typo scale\n * @returns {Object} center position x and y\n * @description get a center position of a typo\n */\nexport function getCenter(w, h, scale) {\n    const x = w / 2;\n    const y = (h - ((220 - 90) * RECT_RATIO * scale)) / 2;\n    return {\n        x: x,\n        y: y\n    };\n}\n\n/**\n * @name getRange\n * @property {Object} - typo data object from 'font/index.js'\n * @property {Number} - weightRatio\n * @property {Number} - circleRound\n * @returns {Object} ratio range\n * @description save ratio range to control each line's coordinate \n */\nexport function getRange(d, weightRatio, circleRound) {\n    const gx1 = d.ratio.x1;\n    const gx2 = d.ratio.x2;\n    const gy1 = d.ratio.y1;\n    const gy2 = d.ratio.y2;\n    return {\n        r: weightRatio,\n        cr: circleRound,\n        fr1: FR_1,\n        fr2: FR_2,\n        gx1: gx1,\n        gx2: gx2,\n        gy1: gy1,\n        gy2: gy2,\n    };\n}\n\nexport function getCurrent(v, vmax, vmin, max, min) {\n    let value = (max - min) / (vmax - vmin) * (v - vmin) + min;\n    if (value < min) value = min;\n    else if (value > max) value = max;\n    return value;\n}\n\nexport function getLines(data) {\n    const total = data.typo.p.length;\n    const lines = [];\n    let i, j, k, j_total;\n    let d2, d3, cp, dir, lt, ltRatio, prevRatio;\n    for (i = 0; i < total; i++) {\n        d2 = data.typo.p[i];\n        j_total = d2.cv.length;\n        for (j = 0; j < j_total; j++) {\n            d3 = d2.cv[j];\n            // add current position to all points\n            cp = d3.addRect(data.rect);\n            dir = d2.d;\n            lt = data.pointsLength.lengths[i];\n            ltRatio = lt / data.pointsLength.max;\n            prevRatio = 0;\n            if (i > 0) {\n                for (k = 0; k < i; k++) {\n                    prevRatio += (data.pointsLength.lengths[k] / data.pointsLength.max);\n                }\n            }\n            ltRatio += prevRatio;\n\n            lines.push({\n                pos: cp,\n                drawing: data.drawing,\n                direction: dir,\n                lengths: lt,\n                maxDrawing: ltRatio,\n                minDrawing: prevRatio,\n                closePath: d3.ratio.c,\n                stroke: (ctx, d) => {\n                    let dv = getCurrent(d.drawing.value, d.maxDrawing, d.minDrawing, 1, 0);\n                    //if (d.direction == 1) {\n                    //    dv = getCurrent(1 - d.drawing.value, d.minDrawing, d.maxDrawing, 1, 0);\n                    //}\n                    if (dv > 0 && d.pos.type != 'a') {\n                        const frac = d.lengths * dv;\n                        ctx.setLineDash([d.lengths]);\n                        ctx.lineDashOffset = d.direction * (frac + d.lengths);\n                        ctx.stroke();\n                    }\n                },\n            });\n        }\n    }\n\n    return lines;\n}\n\n\nexport function addRectToPaths(path, data) {\n    const total = path.length;\n    const arr = [];\n    let i, cp, p;\n    for (i = 0; i < total; i++) {\n        p = path[i];\n        cp = p.addRect(data.rect);\n        arr.push(cp);\n    }\n    return arr;\n}\n\nexport function randomBrightColor() {\n    return \"hsl(\" + 360 * Math.random() + ',' +\n        '100%,' +\n        '50%)';\n}\n\nexport function shuffle(oldArray) {\n    let newArray = oldArray.slice(),\n        len = newArray.length,\n        i = len,\n        p, t;\n    while (i--) {\n        p = (Math.random() * len) | 0;\n        t = newArray[i];\n        newArray[i] = newArray[p];\n        newArray[p] = t;\n    }\n    return newArray;\n}"
  },
  {
    "path": "src/core/vector.js",
    "content": "import {\n    Point\n} from './point.js';\n\nexport function Vector(mp) {\n    this.type = mp[0];\n\n    this.x = mp[1] || 0;\n    this.y = mp[2] || 0;\n\n    if (this.type == 'b') {\n        this.x2 = mp[3] || 0;\n        this.y2 = mp[4] || 0;\n        this.x3 = mp[5] || 0;\n        this.y3 = mp[6] || 0;\n        if (mp[7] == null) {\n            this.ratio = {\n                x: 1,\n                y: 1,\n                r: 0, // rotation : if the rotation is ROTATE_NONE, it will hide in the 'pattern' and 'paths'\n                p: 0, // 1 is hide the point in the pattern paths\n                f: 0, // 1 is fixed position for wave paths\n                c: 0, // 1 is close path for PIXI bug - graphics.closePath()\n                v: 0 // 1 is vertex, it's only for the vertex shape like V, W, A\n            };\n        } else {\n            this.ratio = {};\n            this.ratio.x = (mp[7].x == null) ? 1 : mp[7].x;\n            this.ratio.y = (mp[7].y == null) ? 1 : mp[7].y;\n            this.ratio.r = mp[7].r || 0;\n            this.ratio.p = mp[7].p || 0;\n            this.ratio.f = mp[7].f || 0;\n            this.ratio.c = mp[7].c || 0;\n            this.ratio.v = mp[7].v || 0;\n        }\n    } else {\n        if (mp[3] == null) {\n            this.ratio = {\n                x: 1,\n                y: 1,\n                r: 0,\n                p: 0,\n                f: 0,\n                c: 0,\n                v: 0\n            };\n        } else {\n            this.ratio = {};\n            this.ratio.x = (mp[3].x == null) ? 1 : mp[3].x;\n            this.ratio.y = (mp[3].y == null) ? 1 : mp[3].y;\n            this.ratio.r = mp[3].r || 0;\n            this.ratio.p = mp[3].p || 0;\n            this.ratio.f = mp[3].f || 0;\n            this.ratio.c = mp[3].c || 0;\n            this.ratio.v = mp[3].v || 0;\n        }\n    }\n}\n\nObject.assign(Vector.prototype, {\n    convert: function (pos, model) {\n        const x = convertX(this.x, pos, this.ratio, model);\n        const y = convertY(this.y, pos, this.ratio, model);\n        const x2 = convertX(this.x2, pos, this.ratio, model);\n        const y2 = convertY(this.y2, pos, this.ratio, model);\n        const x3 = convertX(this.x3, pos, this.ratio, model);\n        const y3 = convertY(this.y3, pos, this.ratio, model);\n        const rd = convertR(this.type, pos, model);\n\n        const vv = new Point(this);\n        vv.x = x;\n        vv.y = y;\n        vv.x2 = x2;\n        vv.y2 = y2;\n        vv.x3 = x3;\n        vv.y3 = y3;\n        vv.radius = rd;\n\n        return vv;\n    }\n});\n\nfunction convertR(type, pos, model) {\n    let rd = 0;\n    if (type == 'a') rd = pos.range.cr * model.scale * model.fontRatio;\n    return rd;\n}\n\nfunction convertX(x, pos, ratio, model) {\n    const rr = pos.range.r * ratio.x;\n    const gx = (pos.range.gx2 - pos.range.gx1) * rr + pos.range.gx1;\n    const fr = (pos.range.fr2 - pos.range.fr1) * rr + pos.range.fr1;\n    return pos.center.x + (((x - gx)) * model.scale * fr); // + pos.rect.x\n}\n\nfunction convertY(y, pos, ratio, model) {\n    const rr = pos.range.r * ratio.y;\n    const gy = (pos.range.gy2 - pos.range.gy1) * rr + pos.range.gy1;\n    const fr = (pos.range.fr2 - pos.range.fr1) * rr + pos.range.fr1;\n    return pos.center.y + (((y - gy)) * model.scale * fr); // + pos.rect.y\n}"
  },
  {
    "path": "src/draw/canvas/color.js",
    "content": "export function Color(ctx, no, data, color) {\n    let c_total = color.length;\n    const cur = (no + (c_total * (Math.abs((no / 10) | 0) + 1))) % c_total;\n    if (Array.isArray(color[cur])) {\n        c_total = color[cur].length;\n        const vv = 1 / (c_total + 1);\n        const g = ctx.createLinearGradient(data.rect.x, data.rect.y, data.rect.x, data.rect.y + data.rect.h);\n        let i;\n        g.addColorStop(vv, color[cur][0]);\n        for (i = 0; i < c_total; i++) {\n            g.addColorStop(vv * (i + 1), color[cur][i]);\n        }\n        g.addColorStop(vv * (c_total + 1), color[cur][c_total - 1]);\n        ctx.strokeStyle = g;\n        ctx.fillStyle = g;\n    } else {\n        ctx.strokeStyle = color[cur];\n        ctx.fillStyle = color[cur];\n    }\n}"
  },
  {
    "path": "src/draw/canvas/colorful.js",
    "content": "import {\n    PI2,\n    getCurrent\n} from '../../core/util.js';\nimport {\n    cubicBezierLength,\n    distance\n} from '../../core/length.js';\n\nlet colorArr;\nlet curColor = -1;\nlet colorTotal;\nconst MIN_DISTANCE = 10;\n\nexport function Colorful(ctx, model, colors) {\n    curColor = -1;\n    colorArr = colors;\n    colorTotal = colorArr.length;\n    const total = model.data.length;\n    let i, d, j, j_total, line, pos, prev;\n    let max, length, prevRatio;\n    for (i = 0; i < total; i++) {\n        d = model.data[i];\n        max = d.pointsLength.max;\n        prevRatio = 0;\n        j_total = d.lines.length;\n        prev = null;\n        for (j = 0; j < j_total; j++) {\n            line = d.lines[j];\n            pos = line.pos;\n            if (pos.type == 'a') {\n                setColor(ctx);\n                ctx.beginPath();\n                ctx.arc(pos.x, pos.y, pos.radius * d.drawing.value, 0, PI2);\n                ctx.fill();\n                ctx.closePath();\n            } else if (pos.type == 'm') {\n                prev = pos;\n            } else if (pos.type == 'l') {\n                length = distance(prev.x, prev.y, pos.x, pos.y);\n                if (length / model.scale > MIN_DISTANCE) {\n                    // ignore short distance paths\n                    setColor(ctx);\n                    ctx.beginPath();\n                    if (prev) ctx.moveTo(prev.x, prev.y);\n                    ctx.lineTo(pos.x, pos.y);\n                    prevRatio += draw(ctx, line, length, max, d, prevRatio);\n                }\n                prev = pos;\n            } else if (pos.type == 'b') {\n                length = cubicBezierLength(prev.x, prev.y, pos.x, pos.y, pos.x2, pos.y2, pos.x3, pos.y3);\n                if (length / model.scale > MIN_DISTANCE) {\n                    setColor(ctx);\n                    ctx.beginPath();\n                    if (prev) ctx.moveTo(prev.x, prev.y);\n                    ctx.bezierCurveTo(pos.x, pos.y, pos.x2, pos.y2, pos.x3, pos.y3);\n                    prevRatio += draw(ctx, line, length, max, d, prevRatio);\n                }\n                prev = {\n                    x: pos.x3,\n                    y: pos.y3\n                };\n            }\n        }\n    }\n}\n\nfunction setColor(ctx) {\n    const color = getColor();\n    ctx.fillStyle = color;\n    ctx.strokeStyle = color;\n}\n\nfunction getColor() {\n    curColor++;\n    if (curColor == colorTotal) curColor = 0;\n    return colorArr[curColor];\n}\n\nfunction draw(ctx, line, length, max, d, prevRatio) {\n    const ltRatio = length / max;\n    let dv = getCurrent(d.drawing.value, prevRatio + ltRatio, prevRatio, 1, 0);\n    if (line.direction == 1) {\n        dv = getCurrent(1 - d.drawing.value, prevRatio, prevRatio + ltRatio, 1, 0);\n    }\n    if (dv > 0) {\n        const frac = length * dv;\n        ctx.setLineDash([length]);\n        ctx.lineDashOffset = line.direction * (frac + length);\n        ctx.stroke();\n    }\n    return ltRatio;\n}"
  },
  {
    "path": "src/draw/canvas/grids.js",
    "content": "export function Grids(ctx, data) {\n    ctx.save();\n\n    ctx.beginPath();\n    ctx.lineWidth = 1;\n    ctx.strokeStyle = \"#aaaaaa\";\n    let i, total = data.guide.length,\n        grid;\n    for (i = 0; i < total; i++) {\n        grid = data.rect.y + data.grid[i];\n        ctx.moveTo(data.rect.x, grid);\n        ctx.lineTo(data.rect.x + data.rect.w, grid);\n    }\n    ctx.stroke();\n\n    ctx.lineWidth = 1;\n    ctx.beginPath();\n    ctx.strokeStyle = \"#aaaaaa\";\n    ctx.rect(data.rect.x, data.rect.y, data.rect.w, data.rect.h);\n    ctx.stroke();\n\n    ctx.restore();\n}"
  },
  {
    "path": "src/draw/canvas/lines.js",
    "content": "import {\n    PI2\n} from '../../core/util.js';\n\nexport function Lines(ctx, data) {\n    const total = data.lines.length;\n    let i, d, pos;\n    for (i = 0; i < total; i++) {\n        d = data.lines[i];\n        pos = d.pos;\n        if (pos.type == 'a') {\n            ctx.beginPath();\n            ctx.arc(pos.x, pos.y, pos.radius * d.drawing.value, 0, PI2);\n            ctx.fill();\n            ctx.closePath();\n        } else if (pos.type == 'm') {\n            ctx.beginPath();\n            ctx.moveTo(pos.x, pos.y);\n        } else if (pos.type == 'l') {\n            ctx.lineTo(pos.x, pos.y);\n            d.stroke(ctx, d);\n        } else if (pos.type == 'b') {\n            ctx.bezierCurveTo(pos.x, pos.y, pos.x2, pos.y2, pos.x3, pos.y3);\n            d.stroke(ctx, d);\n        }\n    }\n}\n"
  },
  {
    "path": "src/draw/canvas/pattern.js",
    "content": "import {\n    PI2\n} from '../../core/util.js';\n\nexport function Pattern(ctx, data, w, h) {\n    const total = Math.round(data.paths.length * data.drawing.value);\n    const w2 = w / 2;\n    const w3 = w / 3;\n    const h2 = h / 2;\n    let i, p;\n    for (i = 0; i < total; i++) {\n        p = data.paths[i];\n        if (p.num == 1) {\n            ctx.fillStyle = \"#ff00c5\";\n        } else {\n            ctx.fillStyle = \"#ff95f8\";\n        }\n        if (p.type == 'a') {\n            ctx.beginPath();\n            ctx.arc(p.x, p.y, w3, 0, PI2);\n            ctx.fill();\n        } else {\n            ctx.beginPath();\n            ctx.save();\n            ctx.translate(p.x, p.y);\n            ctx.rotate(p.rotation);\n            ctx.fillRect(-w2, -h2, w, h);\n            ctx.restore();\n        }\n    }\n}"
  },
  {
    "path": "src/draw/canvas/points.js",
    "content": "import {\n    PI2\n} from '../../core/util.js';\n\nexport function Points(ctx, data) {\n    ctx.save();\n    ctx.lineWidth = 1;\n    let total = data.lines.length;\n    let i;\n    for (i = 0; i < total; i++) {\n        eachLine_(ctx, data.lines[i]);\n    }\n    ctx.restore();\n\n    ctx.save();\n    ctx.lineWidth = 1;\n    total = data.typo.p.length;\n    for (i = 0; i < total; i++) {\n        eachPoint_(ctx, data.typo.p[i], data);\n    }\n    ctx.restore();\n}\n\nfunction eachPoint_(ctx, p, data) {\n    const total = p.v.length;\n    let i, mp, cp;\n    for (i = 0; i < total; i++) {\n        mp = p.cv[i];\n        cp = mp.addRect(data.rect);\n        if (mp.type == 'b') {\n            ctx.fillStyle = \"#ff2a00\";\n            ctx.beginPath();\n            ctx.arc(cp.x3 + (cp.x3 - cp.x2), cp.y3 + (cp.y3 - cp.y2), 1.5, 0, PI2);\n            ctx.fill();\n            ctx.beginPath();\n            ctx.arc(cp.x2, cp.y2, 1.5, 0, PI2);\n            ctx.fill();\n            ctx.beginPath();\n            ctx.moveTo(cp.x2, cp.y2);\n            ctx.lineTo(cp.x3, cp.y3);\n            ctx.lineTo(cp.x3 + (cp.x3 - cp.x2), cp.y3 + (cp.y3 - cp.y2));\n            ctx.stroke();\n            ctx.beginPath();\n            ctx.fillStyle = \"#ffffff\";\n            ctx.arc(cp.x3, cp.y3, 2.5, 0, PI2);\n            ctx.fill();\n            ctx.stroke();\n        } else {\n            ctx.beginPath();\n            ctx.fillStyle = \"#ffffff\";\n            ctx.strokeStyle = \"#ff2a00\";\n            ctx.arc(cp.x, cp.y, 2.5, 0, PI2);\n            ctx.fill();\n            ctx.stroke();\n        }\n    }\n}\n\nfunction eachLine_(ctx, d) {\n    const pos = d.pos;\n    if (pos.type != 'a') {\n        if (pos.type == 'm') {\n            ctx.strokeStyle = \"#ff2a00\";\n            ctx.beginPath();\n            ctx.moveTo(pos.x, pos.y);\n        } else if (pos.type == 'l') {\n            ctx.lineTo(pos.x, pos.y);\n        } else if (pos.type == 'b') {\n            ctx.bezierCurveTo(pos.x, pos.y, pos.x2, pos.y2, pos.x3, pos.y3);\n        }\n        ctx.stroke();\n    }\n}"
  },
  {
    "path": "src/draw/canvas/wave.js",
    "content": "import {\n    PI2,\n    getAmplitude\n} from '../../core/util.js';\n\nconst THIN_LIMIT = 110;\nconst COS = Math.cos;\nconst SIN = Math.sin;\n\nexport function Wave(ctx, data, scale, amplitude, weight, fps) {\n    const total = data.wavePaths.length;\n    const m_amplitude = getAmplitude(amplitude, scale);\n    let i, p, prev, qx, qy, saveDot = [];\n\n    ctx.beginPath();\n    for (i = 0; i < total; i++) {\n        p = data.wavePaths[i];\n        if (fps) {\n            const ranx = (Math.random() * m_amplitude) - (m_amplitude / 2);\n            const rany = (Math.random() * m_amplitude) - (m_amplitude / 2);\n            p.rx = p.x + ranx * COS(p.rotation);\n            p.ry = p.y + ranx * SIN(p.rotation);\n            p.sx = p.x + ranx;\n            p.sy = p.y + rany;\n        }\n\n        if (p.type == 'a') {\n            saveDot.push(p);\n        } else if (p.start == 1) {\n            ctx.moveTo(p.x, p.y);\n        } else if (p.fix) {\n            ctx.lineTo(p.x, p.y);\n        } else {\n            if (weight < THIN_LIMIT) {\n                prev = data.wavePaths[i - 1];\n                if (prev) {\n                    qx = prev.x + ((p.x - prev.x) * 0.5);\n                    qy = prev.y + ((p.y - prev.y) * 0.5);\n                    ctx.quadraticCurveTo(qx, qy, p.rx, p.ry);\n                }\n            } else {\n                ctx.lineTo(p.rx, p.ry);\n            }\n        }\n    }\n    ctx.stroke();\n\n    for (i = 0; i < saveDot.length; i++) {\n        p = saveDot[i];\n        ctx.beginPath();\n        ctx.arc(p.x, p.y, p.radius, 0, PI2);\n        ctx.fill();\n    }\n}"
  },
  {
    "path": "src/draw/pixi/color.js",
    "content": "export function PixiColor(no, data, color) {\n    let c_total = color.length;\n    const cur = (no + (c_total * (Math.abs((no / 10) | 0) + 1))) % c_total;\n    if (Array.isArray(color[cur])) {\n        /*\n        c_total = color[cur].length;\n        const vv = 1 / (c_total - 1);\n        const g = ctx.createLinearGradient(data.rect.x, data.rect.y, data.rect.x, data.rect.y + data.rect.h);\n        let i;\n        for (i = 0; i < c_total; i++) {\n            g.addColorStop(vv * i, color[cur][i]);\n        }\n        ctx.strokeStyle = g;\n        ctx.fillStyle = g;\n        */\n        /*\n        c_total = color[cur].length;\n        const vv = 1 / (c_total - 1);\n        const c = document.createElement(\"canvas\");\n        const ctx = c.getContext(\"2d\");\n        const g = ctx.createLinearGradient(0, 0, data.rect.w, data.rect.h);\n        let i;\n        for (i = 0; i < c_total; i++) {\n            g.addColorStop(vv * i, color[cur][i]);\n        }\n        ctx.fillStyle = g;\n        ctx.fillRect(0, 0, data.rect.w, data.rect.h);\n        return new PIXI.Texture.from(c);\n        */\n    } else {\n        return color[cur];\n    }\n}"
  },
  {
    "path": "src/draw/pixi/lines.js",
    "content": "export function PixiLines(graphics, data, lineW, color) {\n    let total, i;\n    if (data.drawing.value == 1) {\n        total = data.lines.length;\n        for (i = 0; i < total; i++) {\n            eachLine_(graphics, data.lines[i], lineW, color);\n        }\n    } else {\n        total = data.drawingPaths.length * data.drawing.value;\n        for (i = 0; i < total; i++) {\n            \n            eachPath_(graphics, data.drawingPaths[i], lineW, color, data.drawing.value);\n        }\n    }\n}\n\nfunction eachLine_(graphics, data, lineW, color) {\n    const pos = data.pos;\n    if (pos.type == 'a') {\n        graphics.lineStyle(0, color, 0);\n        graphics.beginFill(color);\n        graphics.drawCircle(pos.x, pos.y, pos.radius);\n        graphics.endFill();\n    } else if (pos.type == 'm') {\n        graphics.lineStyle(lineW, color, 1);\n        graphics.moveTo(pos.x, pos.y);\n    } else if (pos.type == 'l') {\n        graphics.lineTo(pos.x, pos.y);\n    } else if (pos.type == 'b') {\n        graphics.bezierCurveTo(pos.x, pos.y, pos.x2, pos.y2, pos.x3, pos.y3);\n    }\n    if (data.closePath) {\n        graphics.closePath();\n    }\n}\n\nfunction eachPath_(graphics, pos, lineW, color, dValue) {\n    if (pos.type == 'a') {\n        graphics.lineStyle(0, color, 0);\n        graphics.beginFill(color);\n        graphics.drawCircle(pos.x, pos.y, pos.radius * dValue);\n        graphics.endFill();\n    } else {\n        if (pos.start == 1) {\n            graphics.lineStyle(lineW, color, 1);\n            graphics.moveTo(pos.x, pos.y);\n        } else {\n            graphics.lineTo(pos.x, pos.y, 1);\n        }\n    }\n}"
  },
  {
    "path": "src/font/index.js",
    "content": "import {\n    UPPER\n} from './upper.js';\nimport {\n    LOWER\n} from './lower.js';\nimport {\n    NUMBER\n} from './number.js';\nimport {\n    SPECIAL\n} from './special.js';\nimport {\n    LATIN\n} from './latin.js';\nimport {\n    TOFU\n} from './util.js';\n\nconst DATA = Object.assign({}, UPPER, LOWER, NUMBER, SPECIAL, LATIN);\n\nexport function typo(v) {\n    const t = DATA[v] || DATA[TOFU];\n    const clone = t.clone();\n    clone.v = v;\n    return clone;\n}"
  },
  {
    "path": "src/font/latin.js",
    "content": "import {\n    generateFontData,\n    ROTATE_HORIZONTAL,\n    ROTATE_VERTICAL,\n    ROTATE_NONE,\n    getR,\n    getCurveR\n} from './util.js';\nimport {\n    getLatin1,\n    getLatin2,\n    getLatin3,\n    getLatin4,\n    getLatin5,\n    getLatin6,\n    getLatin7,\n    getLatin8,\n    getLatin9,\n    getLatin10,\n    getLatin11,\n    getLatin12,\n    getLatin13,\n    getLatin14\n} from './latinutil.js';\nimport {\n    DATA_UA,\n    DATA_UC,\n    DATA_UD,\n    DATA_UE,\n    DATA_UG,\n    DATA_UH,\n    DATA_UI,\n    DATA_UJ,\n    DATA_UN,\n    DATA_UO,\n    DATA_US,\n    DATA_UU,\n    DATA_UY\n} from './upper.js';\nimport {\n    DATA_LA,\n    DATA_LC,\n    DATA_LD,\n    DATA_LE,\n    DATA_LG,\n    DATA_LH,\n    DATA_LN,\n    DATA_LO,\n    DATA_LS,\n    DATA_LU,\n    DATA_LY\n} from './lower.js';\n\nconst DATA_LI = [{\n    d: 1,\n    v: [\n        ['m', 0, 352, {\n            y: 0,\n            f: 1\n        }],\n        ['l', 0, 130, {\n            y: -3\n        }],\n    ]\n}];\n\nconst DATA_LJ = [{\n    d: 1,\n    v: [\n        ['m', 0 - 115.9, 317 + 127, {\n            x: 0.4,\n            y: 0.63,\n            r: getCurveR(0 - 115.9, 317 + 127, 12.6 - 115.9, 327.4 + 127, 29.6 - 115.9, 333.2 + 127, 45.9 - 115.9, 334.2 + 127, 0),\n            f: 1\n        }],\n        ['b', 12.6 - 115.9, 327.4 + 127, 29.6 - 115.9, 333.2 + 127, 45.9 - 115.9, 334.2 + 127, {\n            x: 0.4,\n            y: 0.63,\n            r: ROTATE_VERTICAL\n        }],\n        ['b', 84.5 - 115.9, 336.5 + 127, 0, 308.1 + 127, 0, 269.4 + 127, {\n            x: 0.4,\n            y: 0.63,\n            r: ROTATE_HORIZONTAL\n        }],\n        ['l', 0, 0 + 127 + 3, {\n            y: -3\n        }],\n    ]\n}];\n\nexport const LATIN = {\n    'Æ': generateFontData(\n        996, 426, 352,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 426.0, 0.0, {\n                    x: 0,\n                    r: ROTATE_VERTICAL\n                }],\n                ['l', 234.0, 0.0, {\n                    x: 0.5,\n                    f: 1,\n                    r: getR(234.0, 0.0, .0, 352.0),\n                }],\n                ['l', 0.0, 352.0, {\n                    x: 0.5,\n                    y: 0.5,\n                    f: 1\n                }],\n            ]\n        }, {\n            d: -1,\n            v: [\n                ['m', 234.0, 0.0, {\n                    x: 0.5,\n                    p: 1,\n                }],\n                ['l', 234.0, 352.0, {\n                    f: 1,\n                    x: 0.5\n                }],\n                ['l', 426.0, 352.0, {\n                    f: 1,\n                    x: 0\n                }]\n            ]\n        }, {\n            d: -1,\n            v: [\n                ['m', 76.4, 237.0, {\n                    r: ROTATE_VERTICAL,\n                    p: 1,\n                }],\n                ['l', 234.0, 237.0, {\n                    f: 1,\n                    r: ROTATE_VERTICAL,\n                    p: 1,\n                }]\n            ]\n        }, {\n            d: -1,\n            v: [\n                ['m', 234.0, 164.0, {\n                    r: ROTATE_VERTICAL,\n                    p: 1,\n                    x: 0.5\n                }],\n                ['l', 414.0, 164.0, {\n                    f: 1,\n                    x: 0\n                }]\n            ]\n        }]\n    ),\n    'æ': generateFontData(\n        1000, 232 + 225.5, 232,\n        0, 0, -64, -64,\n        [{\n            d: -1,\n            v: [\n                ['m', 232, 8, {\n                    y: -3.4,\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['l', 232, 116, {\n                    r: ROTATE_NONE\n                }],\n                ['b', 232, 180.1, 180.1, 232, 116, 232, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 51.9, 232, 0, 180.1, 0, 116, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 0, 51.9, 51.9, 0, 116, 0, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 180.1, 0, 232, 51.9, 232, 116, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['l', 232, 224, {\n                    y: -0.1,\n                    r: ROTATE_HORIZONTAL,\n                    f: 1\n                }]\n            ]\n        }, {\n            d: 1,\n            v: [\n                ['m', 211.6 + 232, 182.9, {\n                    r: getCurveR(211.6 + 232, 182.9, 191.1 + 232, 213.2, 156.1 + 232, 233.1, 116.5 + 232, 233.1, 0),\n                    f: 1\n                }],\n                ['b', 191.1 + 232, 213.2, 156.1 + 232, 233.1, 116.5 + 232, 233.1, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 52.4 + 232, 233.1, 0.5 + 232, 181.2, 0.5 + 232, 117.1, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 0.5 + 232, 53, 52.4 + 232, 1.1, 116.5 + 232, 1.1, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 176.4 + 232, 1.1, 224.9 + 232, 47.2, 225.5 + 232, 106.1, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['l', 0.5 + 232, 106.1, {\n                    r: ROTATE_HORIZONTAL,\n                    p: 1\n                }],\n            ]\n        }]\n    ),\n    'À': generateFontData(\n        620, 290, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UA)).concat(getLatin1(145, -50))\n    ),\n    'Á': generateFontData(\n        620, 290, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UA)).concat(getLatin2(145, -50))\n    ),\n    'Â': generateFontData(\n        620, 290, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UA)).concat(getLatin3(145, -100))\n    ),\n    'Ã': generateFontData(\n        620, 290, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UA)).concat(getLatin4(145, -90))\n    ),\n    'Ä': generateFontData(\n        620, 290, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UA)).concat(getLatin5(145, -70))\n    ),\n    'Å': generateFontData(\n        620, 290, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UA)).concat(getLatin7(0, 0))\n    ),\n    'Ă': generateFontData(\n        620, 290, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UA)).concat(getLatin6(145, -110))\n    ),\n    'Ą': generateFontData(\n        620, 290, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UA)).concat(getLatin10(290, 352))\n    ),\n    'à': generateFontData(\n        600, 232, 232,\n        10, 2, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LA)).concat(getLatin1(116, -60))\n    ),\n    'á': generateFontData(\n        600, 232, 232,\n        10, 2, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LA)).concat(getLatin2(116, -60))\n    ),\n    'â': generateFontData(\n        600, 232, 232,\n        10, 2, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LA)).concat(getLatin3(116, -110))\n    ),\n    'ã': generateFontData(\n        600, 232, 232,\n        10, 2, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LA)).concat(getLatin4(116, -100))\n    ),\n    'ä': generateFontData(\n        600, 232, 232,\n        10, 2, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LA)).concat(getLatin5(116, -80))\n    ),\n    'å': generateFontData(\n        600, 232, 232,\n        10, 2, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LA)).concat(getLatin7(-30, 0))\n    ),\n    'ă': generateFontData(\n        600, 232, 232,\n        10, 2, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LA)).concat(getLatin6(116, -120))\n    ),\n    'ą': generateFontData(\n        600, 232, 232,\n        10, 2, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LA)).concat(getLatin10(232, 224))\n    ),\n    'Ć': generateFontData(\n        700, 293.1, 360,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UC)).concat(getLatin1(180, -60))\n    ),\n    'Ĉ': generateFontData(\n        700, 293.1, 360,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UC)).concat(getLatin3(180, -110))\n    ),\n    'Ċ': generateFontData(\n        700, 293.1, 360,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UC)).concat(getLatin11(180, -80))\n    ),\n    'Č': generateFontData(\n        700, 293.1, 360,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UC)).concat(getLatin12(180, -110))\n    ),\n    'Ç': generateFontData(\n        700, 293.1, 360,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UC)).concat(getLatin9(180, 360))\n    ),\n    'ć': generateFontData(\n        520, 212.1, 233.1,\n        2, -10, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LC)).concat(getLatin1(116.5, 1.1 - 70))\n    ),\n    'ĉ': generateFontData(\n        520, 212.1, 233.1,\n        2, -10, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LC)).concat(getLatin3(116.5, 1.1 - 120))\n    ),\n    'ċ': generateFontData(\n        520, 212.1, 233.1,\n        2, -10, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LC)).concat(getLatin11(116.5, 1.1 - 90))\n    ),\n    'č': generateFontData(\n        520, 212.1, 233.1,\n        2, -10, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LC)).concat(getLatin12(116.5, 1.1 - 120))\n    ),\n    'ç': generateFontData(\n        520, 212.1, 233.1,\n        2, -10, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LC)).concat(getLatin9(116.5, 233.1))\n    ),\n    'Đ': generateFontData(\n        721, 270, 352,\n        -10, -10, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UD)).concat(getLatin8(0, 352 / 2))\n    ),\n    'Ď': generateFontData(\n        721, 270, 352,\n        -10, -10, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UD)).concat(getLatin12(100, -110))\n    ),\n    'ď': generateFontData(\n        600, 232, 352,\n        10, 2, 0, 0,\n        JSON.parse(JSON.stringify(DATA_LD)).concat(getLatin13(300, 0))\n    ),\n    'đ': generateFontData(\n        600, 232, 352,\n        10, 2, 0, 0,\n        JSON.parse(JSON.stringify(DATA_LD)).concat(getLatin8(180, 40))\n    ),\n    'È': generateFontData(\n        520, 192, 352,\n        -5, -80, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UE)).concat(getLatin1(96, -60))\n    ),\n    'É': generateFontData(\n        520, 192, 352,\n        -5, -80, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UE)).concat(getLatin2(96, -60))\n    ),\n    'Ê': generateFontData(\n        520, 192, 352,\n        -5, -80, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UE)).concat(getLatin3(96, -110))\n    ),\n    'Ë': generateFontData(\n        520, 192, 352,\n        -5, -80, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UE)).concat(getLatin5(96, -80))\n    ),\n    'Ē': generateFontData(\n        520, 192, 352,\n        -5, -80, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UE)).concat(getLatin14(96, -80))\n    ),\n    'Ĕ': generateFontData(\n        520, 192, 352,\n        -5, -80, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UE)).concat(getLatin6(96, -120))\n    ),\n    'Ė': generateFontData(\n        520, 192, 352,\n        -5, -80, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UE)).concat(getLatin11(96, -80))\n    ),\n    'Ě': generateFontData(\n        520, 192, 352,\n        -5, -80, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UE)).concat(getLatin12(96, -110))\n    ),\n    'è': generateFontData(\n        570, 225.5, 233.1,\n        0, 0, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LE)).concat(getLatin1(112, -60))\n    ),\n    'é': generateFontData(\n        570, 225.5, 233.1,\n        0, 0, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LE)).concat(getLatin2(112, -60))\n    ),\n    'ê': generateFontData(\n        570, 225.5, 233.1,\n        0, 0, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LE)).concat(getLatin3(112, -110))\n    ),\n    'ë': generateFontData(\n        570, 225.5, 233.1,\n        0, 0, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LE)).concat(getLatin5(112, -80))\n    ),\n    'ē': generateFontData(\n        570, 225.5, 233.1,\n        0, 0, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LE)).concat(getLatin14(112, -80))\n    ),\n    'ĕ': generateFontData(\n        570, 225.5, 233.1,\n        0, 0, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LE)).concat(getLatin6(112, -120))\n    ),\n    'ė': generateFontData(\n        570, 225.5, 233.1,\n        0, 0, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LE)).concat(getLatin11(112, -90))\n    ),\n    'ě': generateFontData(\n        570, 225.5, 233.1,\n        0, 0, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LE)).concat(getLatin12(112, -120))\n    ),\n    'Ĝ': generateFontData(\n        840, 352, 360,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UG)).concat(getLatin3(180, -110))\n    ),\n    'Ğ': generateFontData(\n        840, 352, 360,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UG)).concat(getLatin6(180, -120))\n    ),\n    'Ġ': generateFontData(\n        840, 352, 360,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UG)).concat(getLatin11(180, -80))\n    ),\n    'Ģ': generateFontData(\n        840, 352, 360,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UG)).concat(getLatin9(180, 360))\n    ),\n    'ĝ': generateFontData(\n        600, 232, 338,\n        10, 2, -117, -117,\n        JSON.parse(JSON.stringify(DATA_LG)).concat(getLatin3(116, 1.1 - 120))\n    ),\n    'ğ': generateFontData(\n        600, 232, 338,\n        10, 2, -117, -117,\n        JSON.parse(JSON.stringify(DATA_LG)).concat(getLatin6(116, -120))\n    ),\n    'ġ': generateFontData(\n        600, 232, 338,\n        10, 2, -117, -117,\n        JSON.parse(JSON.stringify(DATA_LG)).concat(getLatin11(116, -90))\n    ),\n    'ģ': generateFontData(\n        600, 232, 338,\n        10, 2, -117, -117,\n        JSON.parse(JSON.stringify(DATA_LG)).concat(getLatin2(116, -70))\n    ),\n    'Ĥ': generateFontData(\n        684, 232, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UH)).concat(getLatin3(232 / 2, -110))\n    ),\n    'ĥ': generateFontData(\n        520, 182, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_LH)).concat(getLatin3(182 / 2, -110))\n    ),\n    'Ì': generateFontData(\n        249, 0, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UI)).concat(getLatin1(0, -60))\n    ),\n    'Í': generateFontData(\n        249, 0, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UI)).concat(getLatin2(0, -60))\n    ),\n    'Î': generateFontData(\n        249, 0, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UI)).concat(getLatin3(0, -110))\n    ),\n    'Ï': generateFontData(\n        249, 0, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UI)).concat(getLatin5(0, -80))\n    ),\n    'ì': generateFontData(\n        200, 0, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_LI)).concat(getLatin1(0, -60 + 130))\n    ),\n    'í': generateFontData(\n        200, 0, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_LI)).concat(getLatin2(0, -60 + 130))\n    ),\n    'î': generateFontData(\n        200, 0, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_LI)).concat(getLatin3(0, -120 + 130))\n    ),\n    'ï': generateFontData(\n        200, 0, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_LI)).concat(getLatin5(0, -80 + 130))\n    ),\n    'Ĵ': generateFontData(\n        472, 172.5, 355.5,\n        10, 20, -2, -2,\n        JSON.parse(JSON.stringify(DATA_UJ)).concat(getLatin3(172.5, -110))\n    ),\n    'ĵ': generateFontData(\n        220, 115.9, 352,\n        -60, -60, 0, 0,\n        JSON.parse(JSON.stringify(DATA_LJ)).concat(getLatin3(0, -110 + 130))\n    ),\n    'Ñ': generateFontData(\n        721, 250, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UN)).concat(getLatin4(250 / 2, -100))\n    ),\n    'ñ': generateFontData(\n        520, 182, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_LN)).concat(getLatin4(182 / 2, -100 + 130))\n    ),\n    'Ò': generateFontData(\n        850, 360, 360,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UO)).concat(getLatin1(180, -60))\n    ),\n    'Ó': generateFontData(\n        850, 360, 360,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UO)).concat(getLatin2(180, -60))\n    ),\n    'Ô': generateFontData(\n        850, 360, 360,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UO)).concat(getLatin3(180, -110))\n    ),\n    'Õ': generateFontData(\n        850, 360, 360,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UO)).concat(getLatin4(180, -100))\n    ),\n    'Ö': generateFontData(\n        850, 360, 360,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UO)).concat(getLatin5(180, -80))\n    ),\n    'Ø': generateFontData(\n        850, 360, 360,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UO)).concat([{\n            d: 1,\n            v: [\n                ['m', 0, 360, {\n                    r: getR(0, 360, 360, 0),\n                    f: 1,\n                    x: 0,\n                    y: 1\n                }],\n                ['l', 360, 0, {\n                    x: 0,\n                    y: 1\n                }]\n            ]\n        }])\n    ),\n    'ò': generateFontData(\n        580, 232, 232,\n        0, 0, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LO)).concat(getLatin1(116, -60))\n    ),\n    'ó': generateFontData(\n        580, 232, 232,\n        0, 0, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LO)).concat(getLatin2(116, -60))\n    ),\n    'ô': generateFontData(\n        580, 232, 232,\n        0, 0, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LO)).concat(getLatin3(116, -110))\n    ),\n    'õ': generateFontData(\n        580, 232, 232,\n        0, 0, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LO)).concat(getLatin4(116, -100))\n    ),\n    'ö': generateFontData(\n        580, 232, 232,\n        0, 0, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LO)).concat(getLatin5(116, -80))\n    ),\n    'ø': generateFontData(\n        580, 232, 232,\n        0, 0, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LO)).concat([{\n            d: 1,\n            v: [\n                ['m', 0, 232, {\n                    r: getR(0, 232, 232, 0),\n                    f: 1,\n                    x: 0,\n                    y: 1\n                }],\n                ['l', 232, 0, {\n                    x: 0,\n                    y: 1\n                }]\n            ]\n        }])\n    ),\n    'Ŝ': generateFontData(\n        560, 224, 360,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_US)).concat(getLatin3(112.4, -110))\n    ),\n    'ŝ': generateFontData(\n        400, 224 * 0.642, 360 * 0.642,\n        0, 0, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LS)).concat(getLatin3(112.4 * 0.642, -110))\n    ),\n    'Ş': generateFontData(\n        560, 224, 360,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_US)).concat(getLatin9(110.3, 360))\n    ),\n    'ş': generateFontData(\n        400, 224 * 0.642, 360 * 0.642,\n        0, 0, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LS)).concat(getLatin9(110.3 * 0.642, 360 * 0.642))\n    ),\n    'Ù': generateFontData(\n        712, 250, 355,\n        0, 0, -0.5, -0.5,\n        JSON.parse(JSON.stringify(DATA_UU)).concat(getLatin1(125, -50))\n    ),\n    'Ú': generateFontData(\n        712, 250, 355,\n        0, 0, -0.5, -0.5,\n        JSON.parse(JSON.stringify(DATA_UU)).concat(getLatin2(125, -50))\n    ),\n    'Û': generateFontData(\n        712, 250, 355,\n        0, 0, -0.5, -0.5,\n        JSON.parse(JSON.stringify(DATA_UU)).concat(getLatin3(125, -100))\n    ),\n    'Ŭ': generateFontData(\n        712, 250, 355,\n        0, 0, -0.5, -0.5,\n        JSON.parse(JSON.stringify(DATA_UU)).concat(getLatin6(125, -110))\n    ),\n    'Ü': generateFontData(\n        712, 250, 355,\n        0, 0, -0.5, -0.5,\n        JSON.parse(JSON.stringify(DATA_UU)).concat(getLatin5(125, -70))\n    ),\n    'ù': generateFontData(\n        520, 182, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_LU)).concat(getLatin1(91, -60 + 130))\n    ),\n    'ú': generateFontData(\n        520, 182, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_LU)).concat(getLatin2(91, -60 + 130))\n    ),\n    'û': generateFontData(\n        520, 182, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_LU)).concat(getLatin3(91, -110 + 130))\n    ),\n    'ŭ': generateFontData(\n        520, 182, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_LU)).concat(getLatin6(91, -120 + 130))\n    ),\n    'ü': generateFontData(\n        520, 182, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_LU)).concat(getLatin5(91, -80 + 130))\n    ),\n    'Ý': generateFontData(\n        673, 270, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UY)).concat(getLatin2(135, -60))\n    ),\n    'ý': generateFontData(\n        500, 225.5, 331.5,\n        10, 10, -119, -119,\n        JSON.parse(JSON.stringify(DATA_LY)).concat(getLatin2(116.3, -60))\n    ),\n    'ÿ': generateFontData(\n        500, 225.5, 331.5,\n        10, 10, -119, -119,\n        JSON.parse(JSON.stringify(DATA_LY)).concat(getLatin5(116.3, -90))\n    ),\n};"
  },
  {
    "path": "src/font/latinutil.js",
    "content": "import {\n    ROTATE_HORIZONTAL,\n    ROTATE_VERTICAL,\n    VERTEX_GAP2,\n    getR,\n    getCurveR\n} from './util.js';\n\n//À\nexport function getLatin1(x, y) {\n    const tx = x;\n    const ty = -60 + y;\n    return [{\n        d: -1,\n        v: [\n            ['m', -40 + tx, ty, {\n                x: 0,\n                y: 0,\n                r: getR(-40 + tx, ty, 0 + tx, 60 + ty)\n            }],\n            ['l', 0 + tx, 60 + ty, {\n                x: 0,\n                y: 0,\n                f: 1\n            }],\n        ]\n    }];\n}\n//Á\nexport function getLatin2(x, y) {\n    const tx = x;\n    const ty = -60 + y;\n    return [{\n        d: -1,\n        v: [\n            ['m', 40 + tx, ty, {\n                x: 0,\n                y: 0,\n                r: getR(40 + tx, ty, 0 + tx, 60 + ty)\n            }],\n            ['l', 0 + tx, 60 + ty, {\n                x: 0,\n                y: 0,\n                f: 1\n            }],\n        ]\n    }];\n}\n//Â\nexport function getLatin3(x, y) {\n    const tx = -68 + x;\n    const ty = 0 + y;\n    return [{\n        d: -1,\n        v: [\n            ['m', 0 + tx, 50 + ty, {\n                r: getR(0 + tx, 50 + ty, 68 - VERTEX_GAP2 + tx, 0 + ty),\n                y: 0,\n                x: 0\n            }],\n            ['l', 68 - VERTEX_GAP2 + tx, 0 + ty, {\n                r: getR(0 + tx, 50 + ty, 68 - VERTEX_GAP2 + tx, 0 + ty),\n                y: 0,\n                x: 0,\n                f: 1,\n            }],\n            ['l', 68 + VERTEX_GAP2 + tx, 0 + ty, {\n                r: getR(68 + VERTEX_GAP2 + tx, 0 + ty, 68 + 68 + tx, 50 + ty),\n                y: 0,\n                x: 0,\n                f: 1,\n                v: 1\n            }],\n            ['l', 68 + 68 + tx, 50 + ty, {\n                y: 0,\n                x: 0,\n                f: 1\n            }]\n        ]\n    }];\n}\n//Ã\nexport function getLatin4(x, y) {\n    const tx = x - 76.24;\n    const ty = y;\n    return [{\n        d: 1,\n        v: [\n            ['m', 159.52 + tx, 16.56 + ty, {\n                x: -1,\n                y: -0.2,\n                r: getCurveR(159.52 + tx, 16.56 + ty, 150.08 + tx, 29.28 + ty, 134.56 + tx, 37.68 + ty, 118.56 + tx, 37.68 + ty, 0),\n                f: 1\n            }],\n            ['b', 150.08 + tx, 29.28 + ty, 134.56 + tx, 37.68 + ty, 118.56 + tx, 37.68 + ty, {\n                x: -1,\n                y: -0.2,\n                r: ROTATE_VERTICAL\n            }],\n            ['b', 103.28 + tx, 37.68 + ty, 89.68 + tx, 29.28 + ty, 76.24 + tx, 20.4 + ty, {\n                x: -1,\n                y: -0.2\n            }],\n            ['b', 61.44 + tx, 10.56 + ty, 47.28 + tx, 0 + ty, 31.68 + tx, 0 + ty, {\n                x: -1,\n                y: -0.2,\n                r: ROTATE_VERTICAL\n            }],\n            ['b', 17.84 + tx, 0 + ty, 8.72 + tx, 7.12 + ty, 0 + tx, 16 + ty, {\n                x: -1,\n                y: -0.2\n            }],\n        ]\n    }];\n}\n//Ä\nexport function getLatin5(x, y) {\n    return [{\n        d: 1,\n        v: [\n            ['a', -50 + x, y, {\n                x: 0,\n                y: 0\n            }],\n        ]\n    }, {\n        d: 1,\n        v: [\n            ['a', 50 + x, y, {\n                x: 0,\n                y: 0\n            }],\n        ]\n    }];\n}\n//Ŭ\nexport function getLatin6(x, y) {\n    const tx = x - 57;\n    const ty = y;\n    return [{\n        d: 1,\n        v: [\n            ['m', 112.7 + tx, 0.0 + ty, {\n                r: getCurveR(112.7 + tx, 0.0 + ty + tx, 10.1 + ty, 110.1 + tx, 19.3 + ty, 105.0 + tx, 27.7 + ty, 0),\n                x: 0,\n                y: 0,\n                f: 1\n            }],\n            ['b', 112.7 + tx, 10.1 + ty, 110.1 + tx, 19.3 + ty, 105.0 + tx, 27.7 + ty, {\n                x: 0,\n                y: 0,\n            }],\n            ['b', 99.8 + tx, 36.1 + ty, 92.9 + tx, 42.8 + ty, 84.3 + tx, 47.7 + ty, {\n                x: 0,\n                y: 0,\n            }],\n            ['b', 75.7 + tx, 52.6 + ty, 66.7 + tx, 55.0 + ty, 57.3 + tx, 55.0 + ty, {\n                x: 0,\n                y: 0,\n            }],\n            ['b', 47.5 + tx, 55.0 + ty, 38.3 + tx, 52.6 + ty, 29.6 + tx, 47.7 + ty, {\n                x: 0,\n                y: 0,\n            }],\n            ['b', 20.8 + tx, 42.8 + ty, 13.8 + tx, 36.1 + ty, 8.5 + tx, 27.7 + ty, {\n                x: 0,\n                y: 0,\n            }],\n            ['b', 3.2 + tx, 19.3 + ty, 0.5 + tx, 10.1 + ty, 0.5 + tx, 0.0 + ty, {\n                x: 0,\n                y: 0,\n            }],\n        ]\n    }];\n}\n//Å\nexport function getLatin7(x, y) {\n    const tx = 88 + x;\n    const ty = -116 + y;\n    const scale = 0.5;\n    return [{\n        d: 1,\n        v: [\n            ['m', 232 * scale + tx, 116 * scale + ty, {\n                r: ROTATE_HORIZONTAL,\n                p: 1,\n                f: 1\n            }],\n            ['b', 232 * scale + tx, 180.1 * scale + ty, 180.1 * scale + tx, 232 * scale + ty, 116 * scale + tx, 232 * scale + ty, {\n                r: ROTATE_VERTICAL\n            }],\n            ['b', 51.9 * scale + tx, 232 * scale + ty, 0 * scale + tx, 180.1 * scale + ty, 0 * scale + tx, 116 * scale + ty, {\n                r: ROTATE_HORIZONTAL\n            }],\n            ['b', 0 * scale + tx, 51.9 * scale + ty, 51.9 * scale + tx, 0 * scale + ty, 116 * scale + tx, 0 * scale + ty, {\n                r: ROTATE_VERTICAL\n            }],\n            ['b', 180.1 * scale + tx, 0 * scale + ty, 232 * scale + tx, 51.9 * scale + ty, 232 * scale + tx, 116 * scale + ty, {\n                r: ROTATE_HORIZONTAL,\n                c: 1\n            }],\n        ]\n    }]\n}\n//Ð\nexport function getLatin8(x, y) {\n    return [{\n        d: 1,\n        v: [\n            ['m', x - 40, y, {\n                x: 0,\n                y: 1,\n                r: ROTATE_VERTICAL\n            }],\n            ['l', 100 + x, y, {\n                x: 0,\n                y: 1,\n                f: 1\n            }],\n        ]\n    }]\n}\n//Ç\nexport function getLatin9(x, y) {\n    return [{\n        d: -1,\n        v: [\n            ['m', x, y, {\n                p: 1\n            }],\n            ['b', 9.3 + x, 11.6 + y, 15.6 + x, 27.1 + y, 15.6 + x, 40.9 + y],\n            ['b', 15.6 + x, 83.3 + y, -18.2 + x, 107.8 + y, -59.5 + x, 107.8 + y],\n            ['b', -70.9 + x, 107.8 + y, -82.9 + x, 106.2 + y, -93.7 + x, 102.7 + y, {\n                x: 0.5,\n                f: 1\n            }],\n        ]\n    }]\n}\n//Ą\nexport function getLatin10(x, y) {\n    return [{\n        d: -1,\n        v: [\n            ['m', x, y, {\n                p: 1\n            }],\n            ['b', 22.6 - 42.2 + x, 14.8 + y, -42.2 + x, 37.9 + y, -42.2 + x, 64.1 + y],\n            ['b', -42.2 + x, 100.3 + y, 30.2 - 42.2 + x, 118.8 + y, 63.6 - 42.2 + x, 118.8 + y],\n            ['b', 68.3 - 42.2 + x, 118.8 + y, 72.9 - 42.2 + x, 118.4 + y, 77.4 - 42.2 + x, 117.6 + y, {\n                x: 0.5,\n                f: 1\n            }],\n        ]\n    }]\n}\n\n//Ċ\nexport function getLatin11(x, y) {\n    return [{\n        d: 1,\n        v: [\n            ['a', x, y, {\n                x: 0,\n                y: 0\n            }],\n        ]\n    }];\n}\n\n//Č\nexport function getLatin12(x, y) {\n    const tx = -68 + x;\n    const ty = y;\n    return [{\n        d: -1,\n        v: [\n            ['m', 0 + tx, ty, {\n                r: getR(0 + tx, ty, 68 - VERTEX_GAP2 + tx, 50 + ty),\n                y: 0,\n                x: 0\n            }],\n            ['l', 68 - VERTEX_GAP2 + tx, 50 + ty, {\n                r: getR(0 + tx, ty, 68 - VERTEX_GAP2 + tx, 50 + ty),\n                y: 0,\n                x: 0,\n                f: 1,\n            }],\n            ['l', 68 + VERTEX_GAP2 + tx, 50 + ty, {\n                r: getR(68 + VERTEX_GAP2 + tx, 50 + ty, 68 + 68 + tx, ty),\n                y: 0,\n                x: 0,\n                f: 1,\n                v: 1\n            }],\n            ['l', 68 + 68 + tx, ty, {\n                y: 0,\n                x: 0,\n                f: 1\n            }]\n        ]\n    }];\n}\n\n//ď\nexport function getLatin13(x, y) {\n    return [{\n        d: -1,\n        v: [\n            ['m', x, y, {\n                x: 0,\n                y: 0\n            }],\n            ['l', x, 80 + y, {\n                x: 0,\n                y: 0,\n                f: 1\n            }],\n        ]\n    }];\n}\n//Ē\nexport function getLatin14(x, y) {\n    return [{\n        d: 1,\n        v: [\n            ['m', x - 50, y, {\n                x: 0,\n                y: 0\n            }],\n            ['l', x + 50, y, {\n                x: 0,\n                y: 0,\n                f: 1\n            }],\n        ]\n    }];\n}"
  },
  {
    "path": "src/font/lower.js",
    "content": "import {\n    generateFontData,\n    ROTATE_HORIZONTAL,\n    ROTATE_VERTICAL,\n    ROTATE_NONE,\n    VERTEX_GAP,\n    VERTEX_GAP2,\n    getR,\n    getCurveR\n} from './util.js';\n\nexport const DATA_LA = [{\n    d: -1,\n    v: [\n        ['m', 232, 8, {\n            y: -3.4,\n            r: ROTATE_HORIZONTAL\n        }],\n        ['l', 232, 116, {\n            r: ROTATE_NONE\n        }],\n        ['b', 232, 180.1, 180.1, 232, 116, 232, {\n            r: ROTATE_VERTICAL\n        }],\n        ['b', 51.9, 232, 0, 180.1, 0, 116, {\n            r: ROTATE_HORIZONTAL\n        }],\n        ['b', 0, 51.9, 51.9, 0, 116, 0, {\n            r: ROTATE_VERTICAL\n        }],\n        ['b', 180.1, 0, 232, 51.9, 232, 116, {\n            r: ROTATE_HORIZONTAL\n        }],\n        ['l', 232, 224, {\n            y: -0.1,\n            r: ROTATE_HORIZONTAL,\n            f: 1\n        }]\n    ]\n}];\n\nexport const DATA_LC = [{\n    d: 1,\n    v: [\n        ['m', 212.1, 182.9, {\n            r: getCurveR(212.1, 182.9, 191.1, 213.2, 156.1, 233.1, 116.5, 233.1, 0),\n            f: 1\n        }],\n        ['b', 191.1, 213.2, 156.1, 233.1, 116.5, 233.1, {\n            r: ROTATE_VERTICAL\n        }],\n        ['b', 52.4, 233.1, 0.5, 181.2, 0.5, 117.1, {\n            r: ROTATE_HORIZONTAL\n        }],\n        ['b', 0.5, 53, 52.4, 1.1, 116.5, 1.1, {\n            r: ROTATE_VERTICAL\n        }],\n        ['b', 156.1, 1.1, 191.1, 21, 212.1, 51.3],\n    ]\n}];\n\nexport const DATA_LD = [{\n    d: -1,\n    v: [\n        ['m', 232, 0, {\n            y: 0\n        }],\n        ['l', 232, 116 + 123, {\n            r: ROTATE_NONE\n        }],\n        ['b', 232, 180.1 + 123, 180.1, 232 + 123, 116, 232 + 123, {\n            r: ROTATE_VERTICAL\n        }],\n        ['b', 51.9, 232 + 123, 0, 180.1 + 123, 0, 116 + 123, {\n            r: ROTATE_HORIZONTAL\n        }],\n        ['b', 0, 51.9 + 123, 51.9, 0 + 123, 116, 0 + 123, {\n            r: ROTATE_VERTICAL\n        }],\n        ['b', 180.1, 0 + 123, 232, 51.9 + 123, 232, 116 + 123, {\n            r: ROTATE_HORIZONTAL\n        }],\n        ['l', 232, 352, {\n            y: 0,\n            f: 1\n        }],\n    ]\n}];\n\nexport const DATA_LE = [{\n    d: 1,\n    v: [\n        ['m', 211.6, 182.9, {\n            r: getCurveR(211.6, 182.9, 191.1, 213.2, 156.1, 233.1, 116.5, 233.1, 0),\n            f: 1\n        }],\n        ['b', 191.1, 213.2, 156.1, 233.1, 116.5, 233.1, {\n            r: ROTATE_VERTICAL\n        }],\n        ['b', 52.4, 233.1, 0.5, 181.2, 0.5, 117.1, {\n            r: ROTATE_HORIZONTAL\n        }],\n        ['b', 0.5, 53, 52.4, 1.1, 116.5, 1.1, {\n            r: ROTATE_VERTICAL\n        }],\n        ['b', 176.4, 1.1, 224.9, 47.2, 225.5, 106.1, {\n            r: ROTATE_HORIZONTAL\n        }],\n        ['l', 0.5, 106.1, {\n            r: ROTATE_HORIZONTAL,\n            p: 1\n        }],\n    ]\n}];\n\nexport const DATA_LG = [{\n    d: -1,\n    v: [\n        ['m', 232, 5, {\n            y: -2.8\n        }],\n        ['l', 232, 116, {\n            r: ROTATE_NONE\n        }],\n        ['b', 232, 180.1, 180.1, 232, 116, 232, {\n            r: ROTATE_VERTICAL\n        }],\n        ['b', 51.9, 232, 0, 180.1, 0, 116, {\n            r: ROTATE_HORIZONTAL\n        }],\n        ['b', 0, 51.9, 51.9, 0, 116, 0, {\n            r: ROTATE_VERTICAL\n        }],\n        ['b', 180.1, 0, 232, 51.9, 232, 116, {\n            r: ROTATE_HORIZONTAL\n        }],\n        ['l', 232, 222],\n        ['b', 234.5, 300.3, 180.2, 338.5, 116, 338, {\n            y: 0.64,\n            r: ROTATE_VERTICAL\n        }],\n        ['b', 76.2, 337.7, 36.6, 320.7, 15.7, 290.1, {\n            y: 0.64,\n            f: 1\n        }],\n    ]\n}];\n\nexport const DATA_LH = [{\n    d: -1,\n    v: [\n        ['m', 0, 0, {\n            y: 0,\n            r: ROTATE_HORIZONTAL\n        }],\n        ['l', 0, 352, {\n            y: 0,\n            f: 1\n        }],\n    ]\n}, {\n    d: -1,\n    v: [\n        ['m', 0, 91 + 123, {\n            r: ROTATE_NONE\n        }],\n        ['b', 0, 40.7 + 123, 40.7, 0 + 123, 91, 0 + 123, {\n            r: ROTATE_VERTICAL\n        }],\n        ['b', 141.3, 0 + 123, 182, 40.7 + 123, 182, 91 + 123, {\n            r: ROTATE_HORIZONTAL\n        }],\n        ['l', 182, 352, {\n            y: 0,\n            f: 1\n        }],\n    ]\n}];\n\n\nexport const DATA_LN = [{\n    d: -1,\n    v: [\n        ['m', 0, 130, {\n            y: -3.3\n        }],\n        ['l', 0, 352, {\n            y: 0,\n            f: 1\n        }],\n    ]\n}, {\n    d: -1,\n    v: [\n        ['m', 0, 91 + 123, {\n            y: 0,\n            r: ROTATE_HORIZONTAL,\n            p: 1\n        }],\n        ['b', 0, 40.7 + 123, 40.7, 0 + 123, 91, 0 + 123, {\n            r: ROTATE_VERTICAL\n        }],\n        ['b', 141.3, 0 + 123, 182, 40.7 + 123, 182, 91 + 123, {\n            r: ROTATE_HORIZONTAL\n        }],\n        ['l', 182, 352, {\n            y: 0,\n            f: 1\n        }],\n    ]\n}];\n\nexport const DATA_LO = [{\n    d: 1,\n    v: [\n        ['m', 232, 116, {\n            r: ROTATE_HORIZONTAL,\n            p: 1,\n            f: 1\n        }],\n        ['b', 232, 180.1, 180.1, 232, 116, 232, {\n            r: ROTATE_VERTICAL\n        }],\n        ['b', 51.9, 232, 0, 180.1, 0, 116, {\n            r: ROTATE_HORIZONTAL\n        }],\n        ['b', 0, 51.9, 51.9, 0, 116, 0, {\n            r: ROTATE_VERTICAL\n        }],\n        ['b', 180.1, 0, 232, 51.9, 232, 116, {\n            r: ROTATE_HORIZONTAL,\n            c: 1\n        }],\n    ]\n}];\n\nexport const DATA_LS = [{\n    d: 1,\n    v: [\n        ['m', 0 * 0.642, 295.4 * 0.642, {\n            r: getCurveR(0 * 0.642, 295.4 * 0.642, 17.6 * 0.642, 332.1 * 0.642, 58.3 * 0.642, 360 * 0.642, 110.3 * 0.642, 360 * 0.642, 0),\n            f: 1\n        }],\n        ['b', 17.6 * 0.642, 332.1 * 0.642, 58.3 * 0.642, 360 * 0.642, 110.3 * 0.642, 360 * 0.642],\n        ['b', 173.9 * 0.642, 360 * 0.642, 223.8 * 0.642, 329.6 * 0.642, 224 * 0.642, 271 * 0.642],\n        ['b', 224.2 * 0.642, 214.7 * 0.642, 180.7 * 0.642, 189.6 * 0.642, 112.4 * 0.642, 173.3 * 0.642],\n        ['b', 47.3 * 0.642, 157.7 * 0.642, 10.9 * 0.642, 130.6 * 0.642, 12 * 0.642, 84.4 * 0.642],\n        ['b', 13.3 * 0.642, 29.8 * 0.642, 57.3 * 0.642, 0 * 0.642, 114.8 * 0.642, 0 * 0.642],\n        ['b', 158.4 * 0.642, 0 * 0.642, 196.5 * 0.642, 20.5 * 0.642, 212 * 0.642, 51.3 * 0.642],\n    ]\n}];\n\nexport const DATA_LU = [{\n        d: -1,\n        v: [\n            ['m', 0, 130, {\n                y: -3\n            }],\n            ['l', 0, 0 + 265, {\n                r: ROTATE_HORIZONTAL\n            }],\n            ['b', 0, 50.3 + 265, 40.7, 91 + 265, 91, 91 + 265, {\n                r: ROTATE_VERTICAL\n            }],\n            ['b', 141.3, 91 + 265, 182, 50.3 + 265, 182, 0 + 265, {\n                r: ROTATE_HORIZONTAL,\n                p: 1,\n                f: 1,\n            }],\n        ]\n    },\n    {\n        d: -1,\n        v: [\n            ['m', 182, 130, {\n                y: -3\n            }],\n            ['l', 182, 352, {\n                y: 0,\n                f: 1\n            }],\n        ]\n    }\n];\n\nexport const DATA_LY = [{\n        d: -1,\n        v: [\n            ['m', 225.5, 0, {\n                y: -3,\n                r: getR(225.5, 0, 116.3, 248.8)\n            }],\n            ['l', 116.3, 248.8, {\n                x: 0.5,\n                y: 0.64\n            }],\n            ['b', 71.8, 349.6, 0, 331.5, 0, 331.5, {\n                x: 0.5,\n                y: 0.64,\n                r: getCurveR(0, 331.5, 71.8, 349.6, 116.3, 248.8, 0, 331.5, 0),\n                f: 1\n            }],\n        ]\n    },\n    {\n        d: -1,\n        v: [\n            ['m', 3.2, 0, {\n                y: -3,\n                r: getR(3.2, 0, 125.7, 226.6)\n            }],\n            ['l', 125.7, 226.6, {\n                p: 1,\n                f: 1\n            }],\n        ]\n    }\n];\n\nexport const LOWER = {\n    'a': generateFontData(\n        600, 232, 232,\n        10, 2, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LA))\n    ),\n    'b': generateFontData(\n        600, 232, 352,\n        -10, -2, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 0, 0, {\n                    y: 0,\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['l', 0, 116 + 123, {\n                    r: ROTATE_NONE\n                }],\n                ['b', 0, 180.1 + 123, 51.9, 232 + 123, 116, 232 + 123, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 180.1, 232 + 123, 232, 180.1 + 123, 232, 116 + 123, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 232, 51.9 + 123, 180.1, 0 + 123, 116, 0 + 123, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 51.9, 0 + 123, 0, 51.9 + 123, 0, 116 + 123, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['l', 0, 352, {\n                    y: 0,\n                    r: ROTATE_HORIZONTAL,\n                    f: 1\n                }]\n\n            ]\n        }, ]\n    ),\n    'c': generateFontData(\n        520, 212.1, 233.1,\n        2, -10, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LC))\n    ),\n    'd': generateFontData(\n        600, 232, 352,\n        10, 2, 0, 0,\n        JSON.parse(JSON.stringify(DATA_LD))\n    ),\n    'e': generateFontData(\n        570, 225.5, 233.1,\n        0, 0, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LE))\n    ),\n    'f': generateFontData(\n        356, 232, 352,\n        -40, -40, 0, 0,\n        [{\n                d: -1,\n                v: [\n                    ['m', 166.6, 33, {\n                        x: 0.5,\n                        r: getCurveR(166.6, 33, 159.3, 13.1, 139.2, 0, 116.9, 0, 0)\n                    }],\n                    ['b', 159.3, 13.1, 139.2, 0, 116.9, 0, {\n                        r: ROTATE_VERTICAL\n                    }],\n                    ['b', 88.2, 0, 65, 23.2, 65, 51.9, {\n                        r: ROTATE_HORIZONTAL\n                    }],\n                    ['l', 65, 352, {\n                        y: 0,\n                        f: 1\n                    }],\n                ]\n            },\n            {\n                d: -1,\n                v: [\n                    ['m', 0, 130, {\n                        x: 0,\n                        r: ROTATE_VERTICAL\n                    }],\n                    ['l', 154, 130, {\n                        x: 0,\n                        f: 1\n                    }],\n                ]\n            }\n        ]\n    ),\n    'g': generateFontData(\n        600, 232, 338,\n        10, 2, -117, -117,\n        JSON.parse(JSON.stringify(DATA_LG))\n    ),\n    'h': generateFontData(\n        520, 182, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_LH))\n    ),\n    'i': generateFontData(\n        200, 0, 352,\n        0, 0, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['a', 0, 90, {\n                    y: -3\n                }],\n            ]\n        }, {\n            d: 1,\n            v: [\n                ['m', 0, 352, {\n                    y: 0,\n                    f: 1\n                }],\n                ['l', 0, 130, {\n                    y: -3\n                }],\n            ]\n        }]\n    ),\n    'j': generateFontData(\n        220, 115.9, 352,\n        -60, -60, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['a', 0, 90, {\n                    y: -3\n                }],\n            ]\n        }, {\n            d: 1,\n            v: [\n                ['m', 0 - 115.9, 317 + 127, {\n                    x: 0.4,\n                    y: 0.63,\n                    r: getCurveR(0 - 115.9, 317 + 127, 12.6 - 115.9, 327.4 + 127, 29.6 - 115.9, 333.2 + 127, 45.9 - 115.9, 334.2 + 127, 0),\n                    f: 1\n                }],\n                ['b', 12.6 - 115.9, 327.4 + 127, 29.6 - 115.9, 333.2 + 127, 45.9 - 115.9, 334.2 + 127, {\n                    x: 0.4,\n                    y: 0.63,\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 84.5 - 115.9, 336.5 + 127, 115.9 - 115.9, 308.1 + 127, 115.9 - 115.9, 269.4 + 127, {\n                    x: 0.4,\n                    y: 0.63,\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['l', 115.9 - 115.9, 0 + 127 + 3, {\n                    y: -3\n                }],\n            ]\n        }]\n    ),\n    'k': generateFontData(\n        450, 164, 352,\n        -10, -10, 0, 0,\n        [{\n                d: -1,\n                v: [\n                    ['m', 0, 0, {\n                        y: 0,\n                        r: ROTATE_HORIZONTAL\n                    }],\n                    ['l', 0, 352, {\n                        y: 0,\n                        f: 1\n                    }],\n                ]\n            },\n            {\n                d: -1,\n                v: [\n                    ['m', 160, 130, {\n                        x: 0.7,\n                        y: 0,\n                        r: getR(164, 130, 0, 106 + 130 - VERTEX_GAP2),\n                        f: 1\n                    }],\n                    ['l', 0, 106 + 130 - VERTEX_GAP2, {\n                        r: ROTATE_VERTICAL,\n                        p: 1\n                    }],\n                    ['l', 0, 106 + 130 + VERTEX_GAP2, {\n                        r: ROTATE_VERTICAL,\n                        p: 1,\n                        v: 1\n                    }],\n                    ['l', 164, 352, {\n                        x: 0.7,\n                        y: 0.7,\n                        f: 1\n                    }],\n                ]\n            }\n        ]\n    ),\n    'l': generateFontData(\n        200, 0, 352,\n        0, 0, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['m', 0, 352, {\n                    y: 0,\n                    f: 1\n                }],\n                ['l', 0, 0, {\n                    y: 0\n                }],\n            ]\n        }]\n    ),\n    'm': generateFontData(\n        740, 150 + 150, 352,\n        0, 0, 0, 0,\n        [{\n                d: -1,\n                v: [\n                    ['m', 0, 130, {\n                        y: -3.6\n                    }],\n                    ['l', 0, 352, {\n                        y: 0,\n                        f: 1\n                    }],\n                ]\n            },\n            {\n                d: -1,\n                v: [\n                    ['m', 0, 75 + 123, {\n                        y: 0,\n                        r: ROTATE_HORIZONTAL,\n                        p: 1\n                    }],\n                    ['b', 0, 33.6 + 123, 33.6, 0 + 123, 75, 0 + 123, {\n                        r: ROTATE_VERTICAL\n                    }],\n                    ['b', 116.4, 0 + 123, 150, 33.6 + 123, 150, 75 + 123, {\n                        r: ROTATE_HORIZONTAL\n                    }],\n                    ['l', 150, 352, {\n                        y: 0,\n                        f: 1\n                    }],\n                ]\n            },\n            {\n                d: -1,\n                v: [\n                    ['m', 0 + 150, 75 + 123, {\n                        y: 0,\n                        r: ROTATE_HORIZONTAL,\n                        p: 1\n                    }],\n                    ['b', 0 + 150, 33.6 + 123, 33.6 + 150, 0 + 123, 75 + 150, 0 + 123, {\n                        r: ROTATE_VERTICAL\n                    }],\n                    ['b', 116.4 + 150, 0 + 123, 150 + 150, 33.6 + 123, 150 + 150, 75 + 123, {\n                        r: ROTATE_HORIZONTAL\n                    }],\n                    ['l', 150 + 150, 352, {\n                        y: 0,\n                        f: 1\n                    }],\n                ]\n            }\n\n        ]\n    ),\n    'n': generateFontData(\n        520, 182, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_LN))\n    ),\n    'o': generateFontData(\n        580, 232, 232,\n        0, 0, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LO))\n    ),\n    'p': generateFontData(\n        600, 232, 338,\n        -10, -2, -117, -117,\n        [{\n            d: -1,\n            v: [\n                ['m', 0, 5, {\n                    y: -2.8\n                }],\n                ['l', 0, 116, {\n                    r: ROTATE_NONE\n                }],\n                ['b', 0, 180.1, 51.9, 232, 116, 232, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 180.1, 232, 232, 180.1, 232, 116, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 232, 51.9, 180.1, 0, 116, 0, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 51.9, 0, 0, 51.9, 0, 116, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['l', 0, 338, {\n                    y: 0,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    'q': generateFontData(\n        600, 232, 338,\n        10, 2, -117, -117,\n        [{\n            d: -1,\n            v: [\n                ['m', 232, 5, {\n                    y: -2.8\n                }],\n                ['l', 232, 116, {\n                    r: ROTATE_NONE\n                }],\n                ['b', 232, 180.1, 180.1, 232, 116, 232, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 51.9, 232, 0, 180.1, 0, 116, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 0, 51.9, 51.9, 0, 116, 0, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 180.1, 0, 232, 51.9, 232, 116, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['l', 232, 338, {\n                    y: 0,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    'r': generateFontData(\n        340, 119.2, 352,\n        -20, -20, 0, 0,\n        [{\n                d: -1,\n                v: [\n                    ['m', 0, 130, {\n                        y: -3.3\n                    }],\n                    ['l', 0, 352, {\n                        y: 0,\n                        f: 1\n                    }],\n                ]\n            },\n            {\n                d: -1,\n                v: [\n                    ['m', 0, 57 + 124, {\n                        r: ROTATE_HORIZONTAL,\n                        p: 1,\n                    }],\n                    ['b', 0, 57 + 124, 41.9, -22.8 + 124, 119.2, 4.5 + 124, {\n                        x: 0,\n                        y: 2,\n                        r: getCurveR(119.2, 4.5 + 124, 41.9, -22.8 + 124, 0, 57 + 124, 119.2, 4.5 + 124, 0),\n                        f: 1\n                    }],\n                ]\n            }\n\n        ]\n    ),\n    's': generateFontData(\n        400, 224 * 0.642, 360 * 0.642,\n        0, 0, -64, -64,\n        JSON.parse(JSON.stringify(DATA_LS))\n    ),\n    't': generateFontData(\n        356, 232, 352,\n        -30, -30, 0, 0,\n        [{\n                d: -1,\n                v: [\n                    ['m', 65, 0, {\n                        y: 0\n                    }],\n                    ['l', 65, 298.2 + 6],\n                    ['b', 65, 326.9 + 6, 88.2, 350.1 + 6, 116.9, 350.1 + 6, {\n                        r: ROTATE_VERTICAL\n                    }],\n                    ['b', 139.2, 350.1 + 6, 159.3, 337 + 6, 166.6, 317.1, {\n                        x: 0,\n                        f: 1\n                    }]\n                ]\n            },\n            {\n                d: -1,\n                v: [\n                    ['m', 0, 130, {\n                        x: 0,\n                        r: ROTATE_VERTICAL\n                    }],\n                    ['l', 154, 130, {\n                        x: 0,\n                        f: 1\n                    }],\n                ]\n            }\n        ]\n    ),\n    'u': generateFontData(\n        520, 182, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_LU))\n    ),\n    'v': generateFontData(\n        500, 200, 352,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 0, 130, {\n                    x: 0.6,\n                    y: -3,\n                    r: getR(0, 130, 100 - VERTEX_GAP2, 352)\n                }],\n                ['l', 100 - VERTEX_GAP2, 352, {\n                    r: getR(0, 130, 100 - VERTEX_GAP2, 352),\n                    f: 1\n                }],\n                ['l', 100 + VERTEX_GAP2, 352, {\n                    r: getR(100 + VERTEX_GAP2, 352, 200, 130),\n                    f: 1,\n                    v: 1\n                }],\n                ['l', 200, 130, {\n                    x: 0.6,\n                    y: -3,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    'w': generateFontData(\n        700, 310, 352,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 0, 130, {\n                    x: 0.6,\n                    y: -3,\n                    r: getR(0, 130, 78 - VERTEX_GAP2, 352)\n                }],\n                ['l', 78 - VERTEX_GAP2, 352, {\n                    r: getR(0, 130, 78 - VERTEX_GAP2, 352),\n                    f: 1\n                }],\n                ['l', 78 + VERTEX_GAP2, 352, {\n                    r: getR(78 + VERTEX_GAP2, 352, 155 - VERTEX_GAP2, 130),\n                    f: 1,\n                    v: 1\n                }],\n                ['l', 155 - VERTEX_GAP2, 130, {\n                    y: 1,\n                    r: getR(78 + VERTEX_GAP2, 352, 155 - VERTEX_GAP2, 130),\n                    f: 1\n                }],\n                ['l', 155 + VERTEX_GAP2, 130, {\n                    y: 1,\n                    r: getR(155 + VERTEX_GAP2, 130, 233 - VERTEX_GAP2, 352),\n                    f: 1,\n                    v: 1\n                }],\n                ['l', 233 - VERTEX_GAP2, 352, {\n                    r: getR(155 + VERTEX_GAP2, 130, 233 - VERTEX_GAP2, 352),\n                    f: 1\n                }],\n                ['l', 233 + VERTEX_GAP2, 352, {\n                    r: getR(233 + VERTEX_GAP2, 352, 310, 130),\n                    f: 1,\n                    v: 1\n                }],\n                ['l', 310, 130, {\n                    x: 0.6,\n                    y: -3,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    'x': generateFontData(\n        490, 210, 352,\n        0, 0, 0, -7,\n        [{\n                d: -1,\n                v: [\n                    ['m', 10, 130, {\n                        x: 0.5,\n                        y: -1,\n                        r: getR(10, 130, 210, 352)\n                    }],\n                    ['l', 210, 352, {\n                        x: 0.5,\n                        y: 0.5,\n                        f: 1\n                    }]\n                ]\n            },\n            {\n                d: -1,\n                v: [\n                    ['m', 200, 130, {\n                        x: 0.5,\n                        y: -1,\n                        r: getR(200, 130, 0, 352)\n                    }],\n                    ['l', 0, 352, {\n                        x: 0.5,\n                        y: 0.5,\n                        f: 1\n                    }]\n                ]\n            }\n        ]\n    ),\n    'y': generateFontData(\n        500, 225.5, 331.5,\n        10, 10, -119, -119,\n        JSON.parse(JSON.stringify(DATA_LY))\n    ),\n    'z': generateFontData( // 232, 224\n        420, 172, 352,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 6, 130, {\n                    x: -0.5,\n                    y: 1,\n                    r: ROTATE_VERTICAL,\n                }],\n                ['l', 166, 130, {\n                    x: 1.8,\n                    y: 1,\n                    r: ROTATE_VERTICAL,\n                    f: 1\n                }],\n                ['l', 166, 130 + VERTEX_GAP, {\n                    x: 1.8,\n                    y: 1,\n                    r: ROTATE_HORIZONTAL,\n                    p: 1,\n                    v: 1\n                }],\n                ['l', 0, 352 - VERTEX_GAP, {\n                    x: 1.7,\n                    r: ROTATE_HORIZONTAL,\n                    p: 1\n                }],\n                ['l', 0, 352, {\n                    x: 1.7,\n                    r: ROTATE_VERTICAL,\n                    f: 1,\n                    v: 1\n                }],\n                ['l', 172, 352, {\n                    x: -0.4,\n                    r: ROTATE_VERTICAL,\n                    f: 1\n                }]\n            ]\n        }]\n    )\n};"
  },
  {
    "path": "src/font/number.js",
    "content": "import {\n    generateFontData,\n    ROTATE_HORIZONTAL,\n    ROTATE_VERTICAL,\n    ROTATE_NONE,\n    VERTEX_GAP,\n    getR,\n    getCurveR\n} from './util.js';\n\nexport const NUMBER = {\n    '0': generateFontData(\n        660, 270, 360,\n        0, 0, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['m', 270, 180, {\n                    r: ROTATE_HORIZONTAL,\n                    p: 1,\n                    f: 1\n                }],\n                ['b', 270, 279.4, 209.6, 360, 135, 360, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 60.4, 360, 0, 279.4, 0, 180, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 0, 80.6, 60.4, 0, 135, 0, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 209.6, 0, 270, 80.6, 270, 180, {\n                    r: ROTATE_HORIZONTAL,\n                    c: 1\n                }],\n            ]\n        }]\n    ),\n    '1': generateFontData(\n        380, 76, 352,\n        15, 15, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 0, 51, {\n                    x: -2,\n                    y: 2,\n                    r: getR(0, 51, 76 - VERTEX_GAP, 0)\n                }],\n                ['l', 76 - VERTEX_GAP, 0, {\n                    r: ROTATE_HORIZONTAL,\n                    p: 1\n                }],\n                ['l', 76, 0, {\n                    r: ROTATE_HORIZONTAL,\n                    f: 1,\n                    v: 1\n                }],\n                ['l', 76, 352, {\n                    y: 0,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '2': generateFontData(\n        580, 210, 356,\n        0, 0, 2, 2,\n        [{\n            d: -1,\n            v: [\n                ['m', 3.9, 68.8, {\n                    x: 1.2,\n                    y: 1.2,\n                    r: getCurveR(3.9, 68.8, 16.7, 29, 54.2, 3.1, 98.2, 0.2, 0)\n                }],\n                ['b', 16.7, 29, 54.2, 3.1, 98.2, 0.2],\n                ['b', 151.8, -3.3, 208.5, 38.3, 198.9, 100.1],\n                ['b', 197.1, 111.8, 196.4, 142.4, 101.5, 235.2],\n                ['b', 11.4, 323.2, 0, 356 - VERTEX_GAP, 0, 356 - VERTEX_GAP, {\n                    r: ROTATE_NONE\n                }],\n                ['l', 0, 356 - VERTEX_GAP, {\n                    r: ROTATE_VERTICAL,\n                    p: 1\n                }],\n                ['l', 0, 356, {\n                    r: ROTATE_VERTICAL,\n                    f: 1,\n                    v: 1\n                }],\n                ['l', 210, 356, {\n                    x: -0.5,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '3': generateFontData(\n        580, 222.1, 360,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 10.7, 66.3, {\n                    r: getCurveR(10.7, 66.3, 11.2, 64.8, 11.7, 63.3, 12.3, 61.8, 0)\n                }],\n                ['b', 11.2, 64.8, 11.7, 63.3, 12.3, 61.8, {\n                    r: ROTATE_NONE\n                }],\n                ['b', 25.8, 25.9, 64.5, 0, 110.1, 0, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 167, 0, 213.1, 40.3, 213.1, 90, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 213.1, 139.7, 167, 180, 110.1, 179.9, {\n                    r: ROTATE_VERTICAL,\n                    f: 1\n                }],\n                ['l', 100.1, 179.9, {\n                    x: -5,\n                    y: 1,\n                    r: ROTATE_VERTICAL,\n                    f: 1\n                }],\n                ['l', 110.1, 180, {\n                    r: ROTATE_VERTICAL,\n                    p: 1\n                }],\n                ['b', 172, 180, 222.1, 220.3, 222.1, 270, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 222.1, 319.7, 172, 360, 110.1, 360, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 56.9, 360, 12.4, 330.2, 1, 290.3, {\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '4': generateFontData(\n        596, 236, 352,\n        0, 0, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['m', 175, 352, {\n                    y: 0,\n                    f: 1\n                }],\n                ['l', 175, 0, {\n                    f: 1\n                }],\n                ['l', 175 - VERTEX_GAP, 0, {\n                    r: ROTATE_VERTICAL,\n                    p: 1,\n                    v: 1\n                }],\n                ['l', 0, 276 - VERTEX_GAP, {\n                    r: ROTATE_HORIZONTAL,\n                    p: 1\n                }],\n                ['l', 0, 276, {\n                    r: ROTATE_VERTICAL,\n                    f: 1,\n                    v: 1\n                }],\n                ['l', 236, 276, {\n                    x: -0.5\n                }],\n            ]\n        }]\n    ),\n    '5': generateFontData(\n        596, 208.5, 356,\n        0, -5, -2, -2,\n        [{\n            d: 1,\n            v: [\n                ['m', 0, 295.7, {\n                    r: getCurveR(0, 295.7, 15.3, 333.8, 52.2, 356.2, 97.5, 356, 0),\n                    f: 1\n                }],\n                ['b', 15.3, 333.8, 52.2, 356.2, 97.5, 356, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 159.1, 355.7, 206.1, 306.9, 208.5, 240.8, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 210.9, 173.9, 162.7, 120.8, 97.5, 125.6, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 59.4, 128.4, 25.5, 145.8, 5.6, 176.4, {\n                    f: 1\n                }],\n                ['l', 5.6, 176.4, {\n                    r: ROTATE_NONE\n                }],\n                ['l', 5.6 - VERTEX_GAP, 176.4, {\n                    r: ROTATE_HORIZONTAL,\n                    p: 1,\n                    v: 1\n                }],\n                ['l', 11.5, 0, {\n                    r: ROTATE_VERTICAL,\n                    f: 1\n                }],\n                ['l', 193.5, 0, {\n                    x: -0.5\n                }],\n            ]\n        }]\n    ),\n    '6': generateFontData(\n        596, 215.8, 360,\n        0, -2, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['m', 7.6, 272.3, {\n                    r: ROTATE_HORIZONTAL,\n                    p: 1,\n                    f: 1\n                }],\n                ['b', 6.4, 265.8, 5.8, 259.1, 5.8, 252.2, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 5.8, 192.6, 52.8, 144.2, 110.8, 144.2, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 168.7, 144.2, 215.8, 192.6, 215.8, 252.2, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 215.8, 311.9, 168.7, 360, 110.8, 360, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 59.5, 360, 16.8, 322.4, 7.6, 272.4, {\n                    r: ROTATE_NONE\n                }],\n                ['b', 7.6, 272.4, -44.1, 8.8, 122.2, 0.2],\n                ['b', 165.5, -2.1, 193.8, 21, 212.1, 56.4],\n            ]\n        }]\n    ),\n    '7': generateFontData(\n        540, 213, 352,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 0, 0, {\n                    x: 0,\n                    r: ROTATE_VERTICAL\n                }],\n                ['l', 213, 0, {\n                    r: ROTATE_VERTICAL,\n                    f: 1\n                }],\n                ['l', 213, 0.1, {\n                    r: ROTATE_NONE\n                }],\n                ['l', 72.7, 352, {\n                    y: 0.1,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '8': generateFontData(\n        596, 224, 360,\n        0, 0, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['m', 112, 180, {\n                    r: ROTATE_HORIZONTAL,\n                    p: 1,\n                    f: 1\n                }],\n                ['b', 50.1, 180, 0, 220.3, 0, 270, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 0, 319.7, 50.1, 360, 112, 360, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 173.9, 360, 224, 319.7, 224, 270, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 224, 220.3, 173.9, 180, 112, 180, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 55.1, 180, 9, 139.7, 9, 90, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 9, 40.3, 55.1, 0, 112, 0, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 168.9, 0, 215, 40.3, 215, 90, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 215, 139.7, 168.9, 180, 112, 180, {\n                    r: ROTATE_HORIZONTAL,\n                    p: 1,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '9': generateFontData(\n        596, 215.8, 360,\n        0, -2, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 208.2, 88, {\n                    r: ROTATE_HORIZONTAL,\n                    p: 1,\n                    f: 1\n                }],\n                ['b', 209.4, 94.5, 210, 101.2, 210, 108, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 210, 167.6, 163, 216, 105, 216, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 47, 216, -0, 167.6, 0, 108, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 0, 48.4, 47, -0, 105, 0, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 156.3, 0, 199, 37.8, 208.2, 87.8, {\n                    r: ROTATE_NONE\n                }],\n                ['b', 208.2, 87.8, 259.8, 351.4, 93.5, 360],\n                ['b', 50.3, 362.3, 21.9, 339.2, 3.6, 303.8, {\n                    f: 1\n                }],\n            ]\n        }]\n    )\n};"
  },
  {
    "path": "src/font/special.js",
    "content": "import {\n    generateFontData,\n    ROTATE_HORIZONTAL,\n    ROTATE_VERTICAL,\n    ROTATE_NONE,\n    getR,\n    getCurveR,\n    VERTEX_GAP2\n} from './util.js';\n\nexport const SPECIAL = {\n    ' ': generateFontData(\n        336, 0, 0,\n        0, 0, 0, 0,\n        [{\n            d: 1,\n            v: []\n        }]\n    ),\n    'tofu': generateFontData(\n        672, 232, 352,\n        0, 0, 0, 0,\n        [{\n                //c: 'square',\n                d: -1,\n                v: [\n                    ['m', 0, 0, {\n                        r: ROTATE_HORIZONTAL\n                    }],\n                    ['l', 232, 0, {\n                        r: ROTATE_HORIZONTAL,\n                        f: 1\n                    }],\n                    ['l', 232, 352, {\n                        r: ROTATE_HORIZONTAL,\n                        f: 1\n                    }],\n                    ['l', 0, 352, {\n                        r: ROTATE_HORIZONTAL,\n                        f: 1\n                    }],\n                    ['l', 0, 0, {\n                        r: ROTATE_HORIZONTAL,\n                        p: 1,\n                        f: 1,\n                        c: 1\n                    }],\n                ]\n            },\n            {\n                d: 1,\n                v: [\n                    ['m', 0, 0, {\n                        r: ROTATE_HORIZONTAL,\n                        p: 1,\n                        f: 1\n                    }],\n                    ['l', 232, 352, {\n                        r: ROTATE_NONE\n                    }],\n                ]\n            }\n        ]\n    ),\n    '?': generateFontData(\n        520, 190.348, 360,\n        0, -5, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['a', 190.348 / 2 - 6, 356],\n            ]\n        }, {\n            d: -1,\n            v: [\n                ['m', 0, 87.8, {\n                    r: getCurveR(0, 87.8, 12, -2.3, 99.1, 0, 0, 87.8, 0)\n\n                }],\n                ['b', 0, 87.8, 12, -2.3, 99.1, 0, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 186.2, 2.4, 204.5, 75.2, 180.9, 121.4],\n                ['b', 157.3, 167.6, 119.7, 178.3, 97.4, 223.2],\n                ['b', 90.5, 237.1, 88.1, 249.8, 88, 260.8, {\n                    r: ROTATE_HORIZONTAL,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '¿': generateFontData(\n        520, 190.348, 360,\n        0, -5, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['a', 190.348 / 2 + 6, 356 - 451 + 188],\n            ]\n        }, {\n            d: -1,\n            v: [\n                ['m', 190.3, 173.0 + 188, {\n                    r: getCurveR(190.3, 173.0 + 188, 178.3, 263.1 + 188, 91.2, 260.8 + 188, 190.3, 173.0 + 188, 0)\n\n                }],\n                ['b', 190.3, 173.0 + 188, 178.3, 263.1 + 188, 91.2, 260.8 + 188, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 4.1, 258.4 + 188, -14.2, 185.6 + 188, 9.4, 139.4 + 188],\n                ['b', 33.0, 93.2 + 188, 70.6, 82.5 + 188, 92.9, 37.6 + 188],\n                ['b', 99.8, 23.7 + 188, 102.2, 11.0 + 188, 102.3, 0.0 + 188, {\n                    r: ROTATE_HORIZONTAL,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '!': generateFontData(\n        465, 8, 355,\n        0, -5, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['a', 8 / 2, 356],\n            ]\n        }, {\n            d: -1,\n            v: [\n                ['m', 4, 0, {\n                    y: 0\n                }],\n                ['l', 4, 260.8, {\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '¡': generateFontData(\n        465, 8, 355,\n        0, -5, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['a', 8 / 2, 356 - 451 + 188],\n            ]\n        }, {\n            d: -1,\n            v: [\n                ['m', 4, 0 + 188],\n                ['l', 4, 260.8 + 188, {\n                    f: 1,\n                    y: 0.3\n                }],\n            ]\n        }]\n    ),\n    '$': generateFontData(\n        568, 224, 360,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 212, 51.3, {\n                    r: getCurveR(0, 295.4, 17.6, 332.1, 58.3, 360, 110.3, 360, 0),\n                    f: 1\n                }],\n                ['b', 196.5, 20.5, 158.4, 0, 114.8, 0],\n                ['b', 57.3, 0, 13.3, 29.8, 12, 84.4],\n                ['b', 10.9, 130.6, 47.3, 157.7, 112.4, 173.3],\n                ['b', 180.7, 189.6, 224.2, 214.7, 224, 271],\n                ['b', 223.8, 329.6, 173.9, 360, 110.3, 360],\n                ['b', 58.3, 360, 17.6, 332.1, 0, 295.4, {\n                    f: 1\n                }],\n            ]\n        }, {\n            d: -1,\n            v: [\n                ['m', 112, 0 - 30, {\n                    y: 0\n                }],\n                ['l', 112, 360 + 30, {\n                    y: 0,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '@': generateFontData(\n        820, 343.425, 360,\n        0, 0, -30, -30,\n        [{\n            d: -1,\n            v: [\n                ['m', 251.9, 92.9, {\n                    r: getR(251.9, 92.9, 238.5, 181.7)\n                }],\n                ['l', 238.5, 181.7, {\n                    r: ROTATE_NONE\n                }],\n                ['b', 227.8, 236, 194.7, 267.2, 143.7, 259.2],\n                ['b', 99.1, 252.2, 87.7, 208.5, 90.1, 177.5],\n                ['b', 92.5, 148.4, 118.1, 91, 183.3, 99.1],\n                ['b', 251, 107.5, 238.5, 181.7, 238.5, 181.7, {\n                    r: ROTATE_NONE\n                }],\n                ['l', 232.5, 221.5],\n                ['b', 232.5, 221.5, 227.2, 257.6, 256, 263.6],\n                ['b', 284.9, 269.7, 309, 241.3, 309, 241.3, {\n                    r: ROTATE_NONE\n                }],\n                ['b', 309, 241.3, 343.4, 209, 343.4, 146.7],\n                ['b', 343.4, 84.3, 297.4, 3.5, 178.6, 0.1],\n                ['b', 59.7, -3.4, -5.3, 105.2, 0.3, 203.4],\n                ['b', 6.1, 303.7, 93.2, 354.5, 175.5, 359.5],\n                ['b', 175.5, 359.5, 246.5, 364.9, 302.7, 339.8, {\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '#': generateFontData(\n        760, 290 + 24, 352,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 70 + 47, 0, {\n                    y: 0,\n                    r: getR(70 + 47, 0, 0 + 47, 352)\n                }],\n                ['l', 0 + 47, 352, {\n                    y: 0,\n                    f: 1\n                }],\n            ]\n        }, {\n            d: -1,\n            v: [\n                ['m', 70 + 150 + 47, 0, {\n                    y: 0,\n                    r: getR(70 + 150 + 47, 0, 0 + 150 + 47, 352)\n                }],\n                ['l', 0 + 150 + 47, 352, {\n                    y: 0,\n                    f: 1\n                }],\n            ]\n        }, {\n            d: -1,\n            v: [\n                ['m', 0 + 24, 117, {\n                    x: 0,\n                    r: ROTATE_VERTICAL\n                }],\n                ['l', 290 + 24, 117, {\n                    x: 0,\n                    f: 1\n                }],\n            ]\n        }, {\n            d: -1,\n            v: [\n                ['m', 0, 352 - 117, {\n                    x: 0,\n                    r: ROTATE_VERTICAL\n                }],\n                ['l', 290, 352 - 117, {\n                    x: 0,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '%': generateFontData(\n        920, 352 + 36, 360,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 289.1 + 18, 5.1, {\n                    x: 0,\n                    y: 0,\n                    r: getR(289.1 + 18, 5.1, 62.9 + 18, 354.9)\n                }],\n                ['l', 62.9 + 18, 354.9, {\n                    x: 0,\n                    y: 0,\n                    f: 1\n                }],\n            ]\n        }, {\n            d: -1,\n            v: [\n                ['m', 146, 73, {\n                    r: ROTATE_HORIZONTAL,\n                    p: 1,\n                }],\n                ['b', 146, 113.3, 113.3, 146, 73, 146, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 32.7, 146, 0, 113.3, 0, 73, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 0, 32.7, 32.7, 0, 73, 0, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 113.3, 0, 146, 32.7, 146, 73, {\n                    r: ROTATE_HORIZONTAL,\n                    c: 1,\n                    f: 1\n                }],\n            ]\n        }, {\n            d: -1,\n            v: [\n                ['m', 352 + 36, 287, {\n                    r: ROTATE_HORIZONTAL,\n                    p: 1,\n                }],\n                ['b', 352 + 36, 327.3, 319.3 + 36, 360, 279 + 36, 360, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 238.7 + 36, 360, 206 + 36, 327.3, 206 + 36, 287, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 206 + 36, 246.7, 238.7 + 36, 214, 279 + 36, 214, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 319.3 + 36, 214, 352 + 36, 246.7, 352 + 36, 287, {\n                    r: ROTATE_HORIZONTAL,\n                    c: 1,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '^': generateFontData(\n        596, 88 + 88, 352,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 0, 150, {\n                    r: getR(0, 150, 88 - VERTEX_GAP2, 0)\n                }],\n                ['l', 88 - VERTEX_GAP2, 0, {\n                    r: getR(0, 150, 88 - VERTEX_GAP2, 0),\n                    f: 1\n                }],\n                ['l', 88 + VERTEX_GAP2, 0, {\n                    r: getR(88 + VERTEX_GAP2, 0, 88 + 88, 150),\n                    f: 1,\n                    v: 1\n                }],\n                ['l', 88 + 88, 150, {\n                    f: 1\n                }]\n            ]\n        }]\n    ),\n    '·': generateFontData(\n        231, 8, 355,\n        0, 0, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['a', 8 / 2, 355 - 1.5 - 170],\n            ]\n        }]\n    ),\n    '×': generateFontData(\n        712, 176.8, 176.8,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 0, 0, {\n                    x: 0,\n                    y: 0,\n                    r: getR(0, 0, 176.8, 176.8),\n                }],\n                ['l', 176.8, 176.8, {\n                    x: 0,\n                    y: 0,\n                    f: 1\n                }],\n            ]\n        }, {\n            d: -1,\n            v: [\n                ['m', 176.8, 0, {\n                    x: 0,\n                    y: 0,\n                    r: getR(176.8, 0, 0, 176.88),\n                }],\n                ['l', 0, 176.8, {\n                    x: 0,\n                    y: 0,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '÷': generateFontData(\n        712, 188, 0,\n        0, 0, 0, 0,\n        [{\n                d: 1,\n                v: [\n                    ['a', (188 / 2), 110],\n                ]\n            }, {\n                d: 1,\n                v: [\n                    ['a', (188 / 2), -110],\n                ]\n            },\n            {\n                d: -1,\n                v: [\n                    ['m', 0, 0, {\n                        x: 0,\n                        y: 0,\n                        r: ROTATE_VERTICAL\n                    }],\n                    ['l', 188, 0, {\n                        x: 0,\n                        y: 0,\n                        f: 1\n                    }],\n                ]\n            }\n        ]\n    ),\n    '«': generateFontData(\n        896, 310, 236,\n        0, 0, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['m', 150, 236, {\n                    r: getR(150, 236, 0, 118 + VERTEX_GAP2),\n                    f: 1\n                }],\n                ['l', 0, 118 + VERTEX_GAP2, {\n                    r: getR(150, 236, 0, 118 + VERTEX_GAP2),\n                    f: 1\n                }],\n                ['l', 0, 118 - VERTEX_GAP2, {\n                    r: getR(0, 118 - VERTEX_GAP2, 150, 0),\n                    f: 1,\n                    v: 1\n                }],\n                ['l', 150, 0]\n            ]\n        }, {\n            d: 1,\n            v: [\n                ['m', 150 + 160, 236, {\n                    r: getR(150 + 160, 236, 0 + 160, 118 + VERTEX_GAP2),\n                    f: 1\n                }],\n                ['l', 0 + 160, 118 + VERTEX_GAP2, {\n                    r: getR(150 + 160, 236, 0 + 160, 118 + VERTEX_GAP2),\n                    f: 1\n                }],\n                ['l', 0 + 160, 118 - VERTEX_GAP2, {\n                    r: getR(0 + 160, 118 - VERTEX_GAP2, 150 + 160, 0),\n                    f: 1,\n                    v: 1\n                }],\n                ['l', 150 + 160, 0]\n            ]\n        }]\n    ),\n    '»': generateFontData(\n        896, 310, 236,\n        0, 0, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['m', 0, 236, {\n                    r: getR(0, 236, 150, 118 + VERTEX_GAP2),\n                    f: 1\n                }],\n                ['l', 150, 118 + VERTEX_GAP2, {\n                    r: getR(0, 236, 0, 118 + VERTEX_GAP2),\n                    f: 1\n                }],\n                ['l', 150, 118 - VERTEX_GAP2, {\n                    r: getR(150, 118 - VERTEX_GAP2, 0, 0),\n                    f: 1,\n                    v: 1\n                }],\n                ['l', 0, 0]\n            ]\n        }, {\n            d: 1,\n            v: [\n                ['m', 0 + 160, 236, {\n                    r: getR(0 + 160, 236, 150 + 160, 118 + VERTEX_GAP2),\n                    f: 1\n                }],\n                ['l', 150 + 160, 118 + VERTEX_GAP2, {\n                    r: getR(0, 236, 0, 118 + VERTEX_GAP2),\n                    f: 1\n                }],\n                ['l', 150 + 160, 118 - VERTEX_GAP2, {\n                    r: getR(150 + 160, 118 - VERTEX_GAP2, 0 + 160, 0),\n                    f: 1,\n                    v: 1\n                }],\n                ['l', 0 + 160, 0]\n            ]\n        }]\n    ),\n    '&': generateFontData(\n        660, 259.191, 360,\n        0, 0, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['m', 257.9, 355, {\n                    x: 0.5,\n                    y: 0.5,\n                    r: getR(257.9, 355, 52.8, 135.3),\n                    f: 1\n                }],\n                ['l', 52.8, 135.3],\n                ['b', 52.8, 135.3, -2.2, 79.5, 46.6, 26.7],\n                ['b', 46.6, 26.7, 68.1, 0, 101.8, 0, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 137.2, 0, 174.1, 21.1, 181.2, 65.3],\n                ['b', 188.6, 111.7, 142.6, 142.9, 108.9, 162.9],\n                ['b', 75.2, 182.8, 40.8, 211.4, 40.8, 211.4, {\n                    r: ROTATE_NONE\n                }],\n                ['b', 35, 217.1, -34.7, 273.7, 22.2, 330.5],\n                ['b', 22.2, 330.5, 48.1, 360, 93.4, 360, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 138.6, 360, 212.2, 322, 259.2, 200.5],\n            ]\n        }]\n    ),\n    '*': generateFontData(\n        558, 183.597, 212,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 91.8, 0, {\n                    x: 0,\n                    y: 0\n                }],\n                ['l', 91.8, 212, {\n                    x: 0,\n                    y: 0,\n                    f: 1\n                }],\n            ]\n        }, {\n            d: -1,\n            v: [\n                ['m', 0, 53, {\n                    x: 0,\n                    y: 0,\n                    r: getR(0, 53, 183.6, 159)\n                }],\n                ['l', 183.6, 159, {\n                    x: 0,\n                    y: 0,\n                    f: 1\n                }],\n            ]\n        }, {\n            d: -1,\n            v: [\n                ['m', 0, 159, {\n                    x: 0,\n                    y: 0,\n                    r: getR(0, 159, 183.6, 53)\n                }],\n                ['l', 183.6, 53, {\n                    x: 0,\n                    y: 0,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '+': generateFontData(\n        712, 250, 250,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 125, 0, {\n                    x: 0,\n                    y: 0,\n                }],\n                ['l', 125, 250, {\n                    x: 0,\n                    y: 0,\n                    f: 1\n                }],\n            ]\n        }, {\n            d: -1,\n            v: [\n                ['m', 0, 125, {\n                    x: 0,\n                    y: 0,\n                    r: ROTATE_VERTICAL\n                }],\n                ['l', 250, 125, {\n                    x: 0,\n                    y: 0,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '=': generateFontData(\n        712, 216, 86,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 0, 0, {\n                    x: 0,\n                    y: 0,\n                    r: ROTATE_VERTICAL\n                }],\n                ['l', 216, 0, {\n                    x: 0,\n                    y: 0,\n                    f: 1\n                }],\n            ]\n        }, {\n            d: -1,\n            v: [\n                ['m', 0, 86, {\n                    x: 0,\n                    y: 0,\n                    r: ROTATE_VERTICAL\n                }],\n                ['l', 216, 86, {\n                    x: 0,\n                    y: 0,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '-': generateFontData(\n        712, 188, 0,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 0, 0, {\n                    x: 0,\n                    y: 0,\n                    r: ROTATE_VERTICAL\n                }],\n                ['l', 188, 0, {\n                    x: 0,\n                    y: 0,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '_': generateFontData(\n        481, 235, 400,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 0, 400, {\n                    x: 0,\n                    y: 0,\n                    r: ROTATE_VERTICAL\n                }],\n                ['l', 235, 400, {\n                    x: 0,\n                    y: 0,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    ':': generateFontData(\n        231, 8, 355,\n        0, 0, 0, 0,\n        [{\n                d: 1,\n                v: [\n                    ['a', 8 / 2, 355 - 1.5 - 170],\n                ]\n            },\n            {\n                d: 1,\n                v: [\n                    ['a', 8 / 2, 355 - 1.5],\n                ]\n            }\n        ]\n    ),\n    ';': generateFontData(\n        231, 8, 355,\n        0, 0, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['a', 8 / 2, 355 - 1.5 - 170],\n            ]\n        }, {\n            d: -1,\n            v: [\n                ['m', 8 / 2, 350, {\n                    x: 0,\n                    y: 2,\n                    r: getR(8 / 2, 350, 8 / 2 - 10, 80 + 350)\n                }],\n                ['l', 8 / 2 - 10, 80 + 350, {\n                    x: 0,\n                    y: 0.5,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '.': generateFontData(\n        231, 8, 355,\n        0, 0, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['a', 8 / 2, 355 - 1.5],\n            ]\n        }]\n    ),\n    ',': generateFontData(\n        231, 10, 355,\n        10, 10, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 10, 350, {\n                    x: 0,\n                    y: 2,\n                    r: getR(10, 350, 0, 80 + 350)\n                }],\n                ['l', 0, 80 + 350, {\n                    x: 0,\n                    y: 0.5,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    \"'\": generateFontData(\n        173, 0, 360,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 0, 0, {\n                    x: 0,\n                    y: 0\n                }],\n                ['l', 0, 80, {\n                    x: 0,\n                    y: 0,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '\"': generateFontData(\n        297, 60, 360,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 0, 0, {\n                    x: -1.5,\n                    y: 0\n                }],\n                ['l', 0, 80, {\n                    x: -1.5,\n                    y: 0,\n                    f: 1\n                }],\n            ]\n        }, {\n            d: -1,\n            v: [\n                ['m', 60, 0, {\n                    x: -1.5,\n                    y: 0\n                }],\n                ['l', 60, 80, {\n                    x: -1.5,\n                    y: 0,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '~': generateFontData(\n        731, 199.391, 47.063,\n        0, 0, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['m', 199.4, 20.7, {\n                    x: 0,\n                    y: 0,\n                    r: getCurveR(199.4, 20.7, 187.6, 36.6, 168.2, 47.1, 148.2, 47.1, 0),\n                    f: 1\n                }],\n                ['b', 187.6, 36.6, 168.2, 47.1, 148.2, 47.1, {\n                    x: 0,\n                    y: 0,\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 129.1, 47.1, 112.1, 36.6, 95.3, 25.5, {\n                    x: 0,\n                    y: 0\n                }],\n                ['b', 76.8, 13.2, 59.1, 0, 39.6, 0, {\n                    x: 0,\n                    y: 0,\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 22.3, 0, 10.9, 8.9, 0, 20, {\n                    x: 0,\n                    y: 0\n                }],\n            ]\n        }]\n    ),\n    '(': generateFontData(\n        365, 107.865, 360,\n        0, 0, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['m', 107.9, 360, {\n                    y: 0.8,\n                    r: getCurveR(107.9, 360, 39.7, 321.1, 0, 259.8, 0, 182.9, 0),\n                    f: 1\n                }],\n                ['b', 39.7, 321.1, 0, 259.8, 0, 182.9, {\n                    y: 0.8,\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 0, 100.2, 39.7, 38.9, 107.9, 0, {\n                    y: 0.8\n                }],\n            ]\n        }]\n    ),\n    ')': generateFontData(\n        365, 107.865, 360,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 0, 0, {\n                    y: 0.8,\n                    r: getCurveR(0, 0, 68.2, 38.9, 107.9, 100.2, 107.9, 177, 0)\n                }],\n                ['b', 68.2, 38.9, 107.9, 100.2, 107.9, 177, {\n                    y: 0.8,\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 107.9, 259.8, 68.2, 321.1, 0, 360, {\n                    y: 0.8,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '{': generateFontData(\n        385, 107.865, 360,\n        0, 0, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['m', 94.5, 360, {\n                    x: -0.5,\n                    r: ROTATE_VERTICAL\n                }],\n                ['l', 77.9, 360, {\n                    x: -0.5\n                }],\n                ['b', 57.4, 360, 37, 343, 37, 310.7, {\n                    x: -0.5\n                }],\n                ['l', 37, 233.4, {\n                    x: -0.5\n                }],\n                ['b', 37, 207.9, 24.3, 183.7, 3.8, 180.7, {\n                    x: -0.5,\n                    r: ROTATE_VERTICAL\n                }],\n                ['l', 3.8, 179.8, {\n                    x: -0.5,\n                    r: ROTATE_VERTICAL,\n                    p: 1\n                }],\n                ['b', 24.3, 176.8, 37, 153.1, 37, 126.7, {\n                    x: -0.5\n                }],\n                ['l', 37, 49.4, {\n                    x: -0.5\n                }],\n                ['b', 37, 17.1, 57.4, 0.1, 77.9, 0.1, {\n                    x: -0.5\n                }],\n                ['l', 94.5, 0.1, {\n                    x: -0.5,\n                }],\n            ]\n        }]\n    ),\n    '}': generateFontData(\n        385, 107.865, 360,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 13.4, 0.1, {\n                    x: -0.5,\n                    r: ROTATE_VERTICAL\n                }],\n                ['l', 30, 0.1, {\n                    x: -0.5\n                }],\n                ['b', 50.4, 0.1, 70.8, 17.1, 70.8, 49.4, {\n                    x: -0.5\n                }],\n                ['l', 70.8, 126.7, {\n                    x: -0.5\n                }],\n                ['b', 70.8, 153.1, 83.6, 176.8, 104, 179.8, {\n                    x: -0.5,\n                    r: ROTATE_VERTICAL\n                }],\n                ['l', 104, 180.7, {\n                    x: -0.5,\n                    r: ROTATE_VERTICAL,\n                    p: 1\n                }],\n                ['b', 83.6, 183.7, 70.8, 207.9, 70.8, 233.4, {\n                    x: -0.5\n                }],\n                ['l', 70.8, 310.7, {\n                    x: -0.5\n                }],\n                ['b', 70.8, 343, 50.4, 360, 30, 360, {\n                    x: -0.5\n                }],\n                ['l', 13.4, 360, {\n                    x: -0.5\n                }],\n            ]\n        }]\n    ),\n    '[': generateFontData(\n        365, 66, 352,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 66, 0, {\n                    x: -1,\n                    r: ROTATE_VERTICAL\n                }],\n                ['l', 0, 0, {\n                    r: ROTATE_HORIZONTAL,\n                    f: 1\n                }],\n                ['l', 0, 352, {\n                    r: ROTATE_HORIZONTAL,\n                    f: 1\n                }],\n                ['l', 66, 352, {\n                    x: -1,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    ']': generateFontData(\n        365, 66, 352,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 0, 0, {\n                    x: -1,\n                    r: ROTATE_VERTICAL\n                }],\n                ['l', 66, 0, {\n                    r: ROTATE_HORIZONTAL,\n                    f: 1\n                }],\n                ['l', 66, 352, {\n                    r: ROTATE_HORIZONTAL,\n                    f: 1\n                }],\n                ['l', 0, 352, {\n                    x: -1,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '<': generateFontData(\n        423, 90, 352,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 90, 0, {\n                    x: -1,\n                    y: 0.3,\n                    r: getR(90, 0, 0, 176)\n                }],\n                ['l', 0, 176, {\n                    r: ROTATE_HORIZONTAL,\n                    f: 1\n                }],\n                ['l', 90, 352, {\n                    x: -1,\n                    y: 0.3,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '>': generateFontData(\n        423, 90, 352,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 0, 0, {\n                    x: -1,\n                    y: 0.3,\n                    r: getR(0, 0, 90, 176)\n                }],\n                ['l', 90, 176, {\n                    r: ROTATE_HORIZONTAL,\n                    f: 1\n                }],\n                ['l', 0, 352, {\n                    x: -1,\n                    y: 0.3,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    '/': generateFontData(\n        433, 130, 352,\n        0, 0, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['m', 0, 352, {\n                    r: getR(0, 352, 130, 0),\n                    f: 1,\n                    y: 0\n                }],\n                ['l', 130, 0, {\n                    y: 0\n                }]\n            ]\n        }]\n    ),\n    'þ': generateFontData(\n        600, 232, 338,\n        -10, -2, -117, -117,\n        [{\n            d: -1,\n            v: [\n                ['m', 0, -106, {\n                    y: 0\n                }],\n                ['l', 0, 116, {\n                    r: ROTATE_NONE\n                }],\n                ['b', 0, 180.1, 51.9, 232, 116, 232, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 180.1, 232, 232, 180.1, 232, 116, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 232, 51.9, 180.1, 0, 116, 0, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 51.9, 0, 0, 51.9, 0, 116, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['l', 0, 338, {\n                    y: 0,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    'Þ': generateFontData(\n        520, 162, 352,\n        -5, -70, 0, 0,\n        [{\n                d: -1,\n                v: [\n                    ['m', 0, 0, {\n                        x: 0,\n                        y: 0,\n                        r: ROTATE_HORIZONTAL,\n                    }],\n                    ['l', 0, 352, {\n                        x: 0,\n                        y: 0,\n                        r: ROTATE_HORIZONTAL,\n                        f: 1\n                    }],\n                ]\n            },\n            {\n                d: 1,\n                v: [\n                    ['m', 0, 281.6, {\n                        x: 0,\n                        r: ROTATE_VERTICAL,\n                        f: 1,\n                        p: 1\n                    }],\n                    ['l', 57, 281.6, {\n                        x: -0.5,\n                        r: ROTATE_VERTICAL,\n                        f: 1\n                    }],\n                    ['b', 115.0, 281.6, 162.0, 233.4, 162.0, 175.4, {\n                        x: -0.5,\n                        r: ROTATE_HORIZONTAL\n                    }],\n                    ['b', 162.0, 117.4, 115.0, 70.4, 57.0, 70.4, {\n                        x: -0.5,\n                        r: ROTATE_VERTICAL\n                    }],\n                    ['l', 0, 70.4, {\n                        x: 0,\n                        r: ROTATE_VERTICAL,\n                        f: 1,\n                        p: 1\n                    }],\n                ]\n            }\n        ]\n    ),\n    'ß': generateFontData(\n        596, 209, 352,\n        -10, -10, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['m', 0.0, 348.3, {\n                    r: ROTATE_HORIZONTAL,\n                    f: 1,\n                    x: 0,\n                    y: 0\n                }],\n                ['l', 0.0, 104.3, {\n                    x: 0\n                }],\n                ['b', 0.0, 46.0, 36.0, 0.0, 98.9, 0.0, {\n                    x: 0\n                }],\n                ['b', 145.2, 0.0, 191.0, 27.9, 191.0, 81.0, {\n                    x: 1\n                }],\n                ['b', 191.0, 110.7, 165.6, 131.8, 151.8, 140.9],\n                ['l', 140.0, 148.8],\n                ['b', 120.6, 161.7, 110.8, 172.8, 110.8, 185.5],\n                ['b', 110.8, 206.7, 131.6, 213.8, 140.0, 217.5],\n                //['l', 163.7, 228.6],\n                ['b', 190.6, 241.1, 211.0, 262.7, 211.0, 289.6],\n                ['b', 211.0, 329.5, 174.8, 352.0, 142.5, 352.0],\n                ['b', 97.3, 352.0, 75.2, 319.7, 72.3, 289.3],\n            ]\n        }]\n    ),\n};"
  },
  {
    "path": "src/font/upper.js",
    "content": "import {\n    generateFontData,\n    ROTATE_HORIZONTAL,\n    ROTATE_VERTICAL,\n    VERTEX_GAP,\n    VERTEX_GAP2,\n    getR,\n    getCurveR\n} from './util.js';\n\nexport const DATA_UA = [{\n        d: -1,\n        v: [\n            ['m', 0, 352, {\n                x: 0.55,\n                y: 0.3,\n                r: getR(0, 352, 145 - VERTEX_GAP2, 0),\n            }],\n            ['l', 145 - VERTEX_GAP2, 0, {\n                r: getR(0, 352, 145 - VERTEX_GAP2, 0),\n                f: 1\n            }],\n            ['l', 145 + VERTEX_GAP2, 0, {\n                r: getR(290, 352, 145 + VERTEX_GAP2, 0),\n                f: 1,\n                v: 1\n            }],\n            ['l', 290, 352, {\n                x: 0.55,\n                y: 0.3,\n                f: 1\n            }],\n        ]\n    },\n    {\n        d: -1,\n        v: [\n            ['m', 47, 237, {\n                r: ROTATE_VERTICAL,\n                p: 1\n            }],\n            ['l', 243, 237, {\n                r: ROTATE_VERTICAL,\n                p: 1,\n                f: 1,\n            }],\n        ]\n    }\n];\n\nexport const DATA_UC = [{\n    d: 1,\n    v: [\n        ['m', 293.1, 320.1, {\n            r: getCurveR(293.1, 320.1, 262.2, 345, 222.8, 360, 180, 360, 0),\n            f: 1\n        }],\n        ['b', 262.2, 345, 222.8, 360, 180, 360],\n        ['b', 80.6, 360, 0, 279.4, 0, 180],\n        ['b', 0, 80.6, 80.6, 0, 180, 0],\n        ['b', 222.8, 0, 262.2, 15, 293.1, 39.9],\n    ]\n}];\n\nexport const DATA_UD = [{\n    d: -1,\n    v: [\n        ['m', 95, 352, {\n            r: ROTATE_VERTICAL,\n            f: 1\n        }],\n        ['b', 191.6, 352, 270, 271.6, 270, 175, {\n            r: ROTATE_HORIZONTAL\n        }],\n        ['b', 270, 78.4, 191.6, 0, 95, 0, {\n            r: ROTATE_VERTICAL\n        }],\n        ['l', 0, 0, {\n            r: ROTATE_HORIZONTAL,\n            f: 1\n        }],\n        ['l', 0, 352, {\n            r: ROTATE_HORIZONTAL,\n            f: 1\n        }],\n        ['l', 95, 352, {\n            r: ROTATE_VERTICAL,\n            f: 1\n        }],\n    ]\n}];\n\nexport const DATA_UE = [{\n        d: -1,\n        v: [\n            ['m', 192, 0, {\n                x: 0,\n                r: ROTATE_VERTICAL,\n            }],\n            ['l', 0, 0, {\n                r: ROTATE_HORIZONTAL,\n                f: 1,\n                x: 0.5\n            }],\n            ['l', 0, 352, {\n                f: 1,\n                x: 0.5\n            }],\n            ['l', 192, 352, {\n                x: 0,\n                r: ROTATE_VERTICAL,\n                f: 1\n            }],\n        ]\n    },\n    {\n        d: -1,\n        v: [\n            ['m', 0, 164, {\n                r: ROTATE_VERTICAL,\n                p: 1,\n                x: 0.5\n            }],\n            ['l', 180, 164, {\n                x: 0,\n                r: ROTATE_VERTICAL,\n                f: 1\n            }],\n        ]\n    }\n];\n\nexport const DATA_UG = [{\n    d: 1,\n    v: [\n        ['m', 202, 180, {\n            r: ROTATE_VERTICAL,\n            f: 1\n        }],\n        ['l', 352, 180, {\n            f: 1\n        }],\n        ['b', 352, 279.4, 279.4, 360, 180, 360, {\n            r: ROTATE_VERTICAL\n        }],\n        ['b', 80.6, 360, 0, 279.4, 0, 180, {\n            r: ROTATE_HORIZONTAL\n        }],\n        ['b', 0, 80.6, 80.6, 0, 180, 0, {\n            r: ROTATE_VERTICAL\n        }],\n        ['b', 222.8, 0, 262.1, 14.9, 293, 39.9],\n    ]\n}];\n\nexport const DATA_UH = [{\n        d: -1,\n        v: [\n            ['m', 0, 0, {\n                y: 0,\n                r: ROTATE_HORIZONTAL\n            }],\n            ['l', 0, 352, {\n                y: 0,\n                r: ROTATE_HORIZONTAL,\n                f: 1\n            }],\n        ]\n    },\n    {\n        d: -1,\n        v: [\n            ['m', 232, 0, {\n                y: 0,\n                r: ROTATE_HORIZONTAL\n            }],\n            ['l', 232, 352, {\n                y: 0,\n                r: ROTATE_HORIZONTAL,\n                f: 1\n            }],\n        ]\n    },\n    {\n        d: -1,\n        v: [\n            ['m', 0, 164, {\n                r: ROTATE_VERTICAL,\n                p: 1\n            }],\n            ['l', 232, 164, {\n                r: ROTATE_VERTICAL,\n                f: 1,\n                p: 1\n            }],\n        ]\n    }\n];\n\nexport const DATA_UI = [{\n    d: 1,\n    v: [\n        ['m', 0, 352, {\n            y: 0,\n            r: ROTATE_HORIZONTAL,\n            f: 1\n        }],\n        ['l', 0, 0, {\n            y: 0,\n            r: ROTATE_HORIZONTAL\n        }],\n    ]\n}];\n\nexport const DATA_UJ = [{\n    d: 1,\n    v: [\n        ['m', 0, 310.5 + 0.5, {\n            r: getCurveR(0, 310.5 + 0.5, 16.2, 341.1 + 0.5, 49.3, 355.5 + 0.5, 86, 355.5 + 0.5, 0),\n            f: 1\n        }],\n        ['b', 16.2, 341.1 + 0.5, 49.3, 355.5 + 0.5, 86, 355.5 + 0.5, {\n            r: ROTATE_VERTICAL\n        }],\n        ['b', 133.5, 355.5 + 0.5, 172, 317 + 0.5, 172, 269.5 + 0.5],\n        ['l', 172.5, 0, {\n            y: 0,\n            r: ROTATE_HORIZONTAL\n        }],\n    ]\n}];\n\nexport const DATA_UN = [{\n    d: -1,\n    v: [\n        ['m', 0, 352, {\n            y: 0,\n            r: ROTATE_HORIZONTAL\n        }],\n        ['l', 0, 0, {\n            r: ROTATE_HORIZONTAL,\n            f: 1\n        }],\n        ['l', 0 + VERTEX_GAP, 0, {\n            r: ROTATE_HORIZONTAL,\n            p: 1,\n            f: 1,\n            v: 1\n        }],\n        ['l', 250 - VERTEX_GAP, 351, {\n            r: ROTATE_HORIZONTAL,\n            p: 1,\n            f: 1\n        }],\n        ['l', 250, 351, {\n            r: ROTATE_HORIZONTAL,\n            f: 1,\n            v: 1\n        }],\n        ['l', 250, 0, {\n            y: 0,\n            r: ROTATE_HORIZONTAL,\n            f: 1\n        }],\n    ]\n}];\n\nexport const DATA_UO = [{\n    d: 1,\n    v: [\n        ['m', 360, 180, {\n            r: ROTATE_HORIZONTAL,\n            p: 1,\n            f: 1\n        }],\n        ['b', 360, 279.4, 279.4, 360, 180, 360, {\n            r: ROTATE_VERTICAL\n        }],\n        ['b', 80.6, 360, 0, 279.4, 0, 180, {\n            r: ROTATE_HORIZONTAL\n        }],\n        ['b', 0, 80.6, 80.6, 0, 180, 0, {\n            r: ROTATE_VERTICAL\n        }],\n        ['b', 279.4, 0, 360, 80.6, 360, 180, {\n            r: ROTATE_HORIZONTAL,\n            c: 1\n        }],\n    ]\n}];\n\nexport const DATA_US = [{\n    d: 1,\n    v: [\n        ['m', 0, 295.4, {\n            r: getCurveR(0, 295.4, 17.6, 332.1, 58.3, 360, 110.3, 360, 0),\n            f: 1\n        }],\n        ['b', 17.6, 332.1, 58.3, 360, 110.3, 360],\n        ['b', 173.9, 360, 223.8, 329.6, 224, 271],\n        ['b', 224.2, 214.7, 180.7, 189.6, 112.4, 173.3],\n        ['b', 47.3, 157.7, 10.9, 130.6, 12, 84.4],\n        ['b', 13.3, 29.8, 57.3, 0, 114.8, 0],\n        ['b', 158.4, 0, 196.5, 20.5, 212, 51.3],\n    ]\n}];\n\nexport const DATA_UU = [{\n    d: 1,\n    v: [\n        ['m', 250, 0, {\n            y: 0,\n            r: ROTATE_HORIZONTAL\n        }],\n        ['l', 250, 230 + 1, {\n            r: ROTATE_HORIZONTAL\n        }],\n        ['b', 250, 299 + 1, 194, 355 + 1, 125, 355 + 1, {\n            r: ROTATE_VERTICAL\n        }],\n        ['b', 56, 355 + 1, 0, 299 + 1, 0, 230 + 1, {\n            r: ROTATE_HORIZONTAL\n        }],\n        ['l', 0, 0, {\n            y: 0,\n            r: ROTATE_HORIZONTAL\n        }],\n    ]\n}];\n\nexport const DATA_UY = [{\n        d: -1,\n        v: [\n            ['m', 0, 0, {\n                x: 0.6,\n                y: 0.3,\n                r: getR(0, 0, 135, 186),\n            }],\n            ['l', 135, 186, {\n                r: ROTATE_HORIZONTAL,\n                f: 1\n            }],\n            ['l', 270, 0, {\n                x: 0.6,\n                y: 0.3,\n                f: 1\n            }]\n        ]\n    },\n    {\n        d: -1,\n        v: [\n            ['m', 135, 186, {\n                r: ROTATE_HORIZONTAL,\n                p: 1\n            }],\n            ['l', 135, 352, {\n                y: 0,\n                f: 1\n            }],\n        ]\n    }\n];\n\nexport const UPPER = {\n    'A': generateFontData(\n        620, 290, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UA))\n    ),\n    'B': generateFontData(\n        596, 209, 352,\n        -10, -10, 0, 0,\n        [{\n            d: 1,\n            v: [\n                ['m', 0, 164, {\n                    r: ROTATE_VERTICAL,\n                    p: 1\n                }],\n                ['l', 116, 164, {\n                    r: ROTATE_VERTICAL,\n                    p: 1,\n                    f: 1\n                }],\n                ['b', 167.4, 164, 209, 205.6, 209, 257, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 209, 308.4, 167.4, 352, 116, 352, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['l', 0, 352, {\n                    r: ROTATE_HORIZONTAL,\n                    f: 1\n                }],\n                ['l', 0, 0, {\n                    r: ROTATE_HORIZONTAL,\n                    f: 1\n                }],\n                ['l', 116, 0, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 161.3, 0, 198, 36.7, 198, 82, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 198, 127.3, 161.3, 164, 116, 164, {\n                    r: ROTATE_VERTICAL\n                }]\n            ]\n        }]\n    ),\n    'C': generateFontData(\n        700, 293.1, 360,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UC))\n    ),\n    'D': generateFontData(\n        721, 270, 352,\n        -10, -10, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UD))\n    ),\n    'E': generateFontData(\n        520, 192, 352,\n        -5, -80, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UE))\n    ),\n    'F': generateFontData(\n        510, 192, 352,\n        -5, -80, 0, 0,\n        [{\n                d: -1,\n                v: [\n                    ['m', 192, 0, {\n                        x: 0,\n                        r: ROTATE_VERTICAL,\n                    }],\n                    ['l', 0, 0, {\n                        r: ROTATE_HORIZONTAL,\n                        f: 1,\n                        x: 0.5\n                    }],\n                    ['l', 0, 352, {\n                        y: 0,\n                        f: 1,\n                        x: 0.5\n                    }],\n                ]\n            },\n            {\n                d: -1,\n                v: [\n                    ['m', 0, 164, {\n                        r: ROTATE_VERTICAL,\n                        p: 1,\n                        x: 0.5\n                    }],\n                    ['l', 180, 164, {\n                        x: 0,\n                        r: ROTATE_VERTICAL,\n                        f: 1\n                    }],\n                ]\n            }\n        ]\n    ),\n    'G': generateFontData(\n        840, 352, 360,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UG))\n    ),\n    'H': generateFontData(\n        684, 232, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UH))\n    ),\n    'I': generateFontData(\n        249, 0, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UI))\n    ),\n    'J': generateFontData(\n        472, 172.5, 355.5,\n        10, 20, -2, -2,\n        JSON.parse(JSON.stringify(DATA_UJ))\n    ),\n    'K': generateFontData(\n        616, 232, 352,\n        -10, -20, 0, 0,\n        [{\n                d: -1,\n                v: [\n                    ['m', 0, 0, {\n                        y: 0,\n                        r: ROTATE_HORIZONTAL\n                    }],\n                    ['l', 0, 352, {\n                        y: 0,\n                        r: ROTATE_HORIZONTAL,\n                        f: 1\n                    }],\n                ]\n            },\n            {\n                d: -1,\n                v: [\n                    ['m', 212, 0, {\n                        x: 0.7,\n                        y: 0.7,\n                        r: getR(212, 0, 0, 164 - VERTEX_GAP2),\n                    }],\n                    ['l', 0, 164 - VERTEX_GAP2, {\n                        r: ROTATE_VERTICAL,\n                        p: 1\n                    }],\n                    ['l', 0, 164 + VERTEX_GAP2, {\n                        r: ROTATE_VERTICAL,\n                        p: 1,\n                        v: 1\n                    }],\n                    ['l', 232, 352, {\n                        x: 0.7,\n                        y: 0.7,\n                        f: 1\n                    }],\n                ]\n            }\n        ]\n    ),\n    'L': generateFontData(\n        529, 192, 352,\n        -10, -20, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 0, 0, {\n                    y: 0\n                }],\n                ['l', 0, 352, {\n                    f: 1\n                }],\n                ['l', 192, 352, {\n                    x: 0,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    'M': generateFontData(\n        885, 330, 352,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 0, 352, {\n                    y: 0,\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['l', 0, 0, {\n                    r: ROTATE_HORIZONTAL,\n                    f: 1\n                }],\n                ['l', 0 + VERTEX_GAP, 0, {\n                    r: ROTATE_HORIZONTAL,\n                    p: 1,\n                    f: 1,\n                    v: 1\n                }],\n                ['l', 165 - VERTEX_GAP2, 330, {\n                    r: getR(165 - VERTEX_GAP2, 330, 165 - VERTEX_GAP2, 330),\n                    f: 1\n                }],\n                ['l', 165 + VERTEX_GAP2, 330, {\n                    r: getR(165 + VERTEX_GAP2, 330, 330 - VERTEX_GAP, 0),\n                    f: 1,\n                    v: 1\n                }],\n                ['l', 330 - VERTEX_GAP, 0, {\n                    r: ROTATE_HORIZONTAL,\n                    p: 1,\n                    f: 1\n                }],\n                ['l', 330, 0, {\n                    r: ROTATE_HORIZONTAL,\n                    f: 1,\n                    v: 1\n                }],\n                ['l', 330, 352, {\n                    y: 0,\n                    r: ROTATE_HORIZONTAL,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    'N': generateFontData(\n        721, 250, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UN))\n    ),\n    'O': generateFontData(\n        850, 360, 360,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UO))\n    ),\n    'P': generateFontData(\n        568, 210, 352,\n        -10, -10, -0.5, -0.5,\n        [{\n            d: 1,\n            v: [\n                ['m', 0, 352, {\n                    y: 0,\n                    f: 1\n                }],\n                ['l', 0, 0, {\n                    f: 1\n                }],\n                ['l', 117, 0, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['b', 168.4, 0, 210, 41.6, 210, 93, {\n                    r: ROTATE_HORIZONTAL\n                }],\n                ['b', 210, 144.4, 168.4, 186, 117, 186, {\n                    r: ROTATE_VERTICAL\n                }],\n                ['l', 0, 186, {\n                    r: ROTATE_VERTICAL,\n                    p: 1\n                }],\n            ]\n        }]\n    ),\n    'Q': generateFontData(\n        850, 360, 360,\n        0, 0, 0, 0,\n        [{\n                d: -1,\n                v: [\n                    ['m', 360, 180, {\n                        r: ROTATE_VERTICAL,\n                        p: 1,\n                        f: 1\n                    }],\n                    ['b', 360, 80.6, 279.4, 0, 180, 0, {\n                        r: ROTATE_VERTICAL\n                    }],\n                    ['b', 80.6, 0, 0, 80.6, 0, 180, {\n                        r: ROTATE_HORIZONTAL\n                    }],\n                    ['b', 0, 279.4, 80.6, 360, 180, 360, {\n                        r: ROTATE_VERTICAL\n                    }],\n                    ['b', 279.4, 360, 360, 279.4, 360, 180, {\n                        r: ROTATE_HORIZONTAL,\n                        c: 1,\n                        f: 1\n                    }],\n                ]\n            },\n            {\n                d: -1,\n                v: [\n                    ['m', 222, 222, {\n                        x: 0.5,\n                        y: 0.5,\n                        r: getR(222, 222, 360, 360),\n                    }],\n                    ['l', 360, 360, {\n                        x: 0.5,\n                        y: 0.5,\n                        f: 1\n                    }]\n                ]\n            }\n        ]\n    ),\n    'R': generateFontData(\n        634, 232, 352,\n        -10, -10, -0.5, -0.5,\n        [{\n                d: -1,\n                v: [\n                    ['m', 0, 186, {\n                        r: ROTATE_VERTICAL,\n                        p: 1\n                    }],\n                    ['l', 139, 186, {\n                        r: ROTATE_VERTICAL\n                    }],\n                    ['b', 190.4, 186, 232, 144.4, 232, 93, {\n                        r: ROTATE_HORIZONTAL\n                    }],\n                    ['b', 232, 41.6, 190.4, 0, 139, 0, {\n                        r: ROTATE_VERTICAL\n                    }],\n                    ['l', 0, 0, {\n                        r: ROTATE_HORIZONTAL,\n                        f: 1\n                    }],\n                    ['l', 0, 352, {\n                        y: 0,\n                        f: 1\n                    }],\n                ]\n            },\n            {\n                d: -1,\n                v: [\n                    ['m', 139, 186, {\n                        p: 1,\n                        r: getR(139, 186, 232, 352),\n                    }],\n                    ['l', 232, 352, {\n                        x: 0.5,\n                        y: 0.39,\n                        f: 1\n                    }],\n                ]\n            }\n        ]\n    ),\n    'S': generateFontData(\n        560, 224, 360,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_US))\n    ),\n    'T': generateFontData(\n        568, 232, 352,\n        0, 0, -0.5, -0.5,\n        [{\n                d: -1,\n                v: [\n                    ['m', 0, 0, {\n                        x: 0,\n                        r: ROTATE_VERTICAL\n                    }],\n                    ['l', 232, 0, {\n                        x: 0,\n                        r: ROTATE_VERTICAL,\n                        f: 1\n                    }],\n                ]\n            },\n            {\n                d: -1,\n                v: [\n                    ['m', 116, 0, {\n                        r: ROTATE_HORIZONTAL,\n                        p: 1\n                    }],\n                    ['l', 116, 352, {\n                        y: 0,\n                        r: ROTATE_HORIZONTAL,\n                        f: 1\n                    }],\n                ]\n            }\n        ]\n    ),\n    'U': generateFontData(\n        712, 250, 355,\n        0, 0, -0.5, -0.5,\n        JSON.parse(JSON.stringify(DATA_UU))\n    ),\n    'V': generateFontData(\n        650, 270, 352,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 0, 0, {\n                    x: 0.6,\n                    y: 0.1,\n                    r: getR(0, 0, 135 - VERTEX_GAP2, 352),\n                }],\n                ['l', 135 - VERTEX_GAP2, 352, {\n                    r: getR(0, 0, 135 - VERTEX_GAP2, 352),\n                    f: 1\n                }],\n                ['l', 135 + VERTEX_GAP2, 352, {\n                    r: getR(135 + VERTEX_GAP2, 352, 270, 0),\n                    f: 1,\n                    v: 1\n                }],\n                ['l', 270, 0, {\n                    x: 0.6,\n                    y: 0.1,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    'W': generateFontData(\n        894, 390, 352,\n        0, 0, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 0, 0, {\n                    x: 0.6,\n                    y: 0.05,\n                    r: getR(0, 0, 86 - VERTEX_GAP2, 352),\n                }],\n                ['l', 86 - VERTEX_GAP2, 352, {\n                    r: getR(0, 0, 86 - VERTEX_GAP2, 352),\n                    f: 1\n                }],\n                ['l', 86 + VERTEX_GAP2, 352, {\n                    r: getR(86 + VERTEX_GAP2, 352, 195 - VERTEX_GAP2, 0),\n                    f: 1,\n                    v: 1\n                }],\n                ['l', 195 - VERTEX_GAP2, 0, {\n                    r: getR(86 + VERTEX_GAP2, 352, 195 - VERTEX_GAP2, 0),\n                    f: 1\n                }],\n                ['l', 195 + VERTEX_GAP2, 0, {\n                    r: getR(195 + VERTEX_GAP2, 0, 304 - VERTEX_GAP2, 352),\n                    f: 1,\n                    v: 1\n                }],\n                ['l', 304 - VERTEX_GAP2, 352, {\n                    r: getR(195 + VERTEX_GAP2, 0, 304 - VERTEX_GAP2, 352),\n                    f: 1\n                }],\n                ['l', 304 + VERTEX_GAP2, 352, {\n                    r: getR(304 + VERTEX_GAP2, 352, 390, 0),\n                    f: 1,\n                    v: 1\n                }],\n                ['l', 390, 0, {\n                    x: 0.6,\n                    y: 0.05,\n                    f: 1\n                }],\n            ]\n        }]\n    ),\n    'X': generateFontData(\n        660, 270, 352,\n        0, 0, 0, -7,\n        [{\n                d: -1,\n                v: [\n                    ['m', 10, 0, {\n                        x: 0.5,\n                        y: 0.3,\n                        r: getR(10, 0, 270, 352),\n                    }],\n                    ['l', 270, 352, {\n                        x: 0.5,\n                        y: 0.5,\n                        f: 1\n                    }]\n                ]\n            },\n            {\n                d: -1,\n                v: [\n                    ['m', 260, 0, {\n                        x: 0.5,\n                        y: 0.3,\n                        r: getR(260, 0, 0, 352),\n                    }],\n                    ['l', 0, 352, {\n                        x: 0.5,\n                        y: 0.5,\n                        f: 1\n                    }]\n                ]\n            }\n        ]\n    ),\n    'Y': generateFontData(\n        673, 270, 352,\n        0, 0, 0, 0,\n        JSON.parse(JSON.stringify(DATA_UY))\n    ),\n    'Z': generateFontData(\n        558, 232, 352,\n        0, -5, 0, 0,\n        [{\n            d: -1,\n            v: [\n                ['m', 8, 0, {\n                    x: 0,\n                    r: ROTATE_VERTICAL\n                }],\n                ['l', 224, 0, {\n                    r: ROTATE_VERTICAL,\n                    f: 1\n                }],\n                ['l', 224, 0 + VERTEX_GAP, {\n                    r: ROTATE_HORIZONTAL,\n                    p: 1,\n                    v: 1\n                }],\n                ['l', 0, 352 - VERTEX_GAP, {\n                    r: ROTATE_HORIZONTAL,\n                    p: 1\n                }],\n                ['l', 0, 352, {\n                    r: ROTATE_VERTICAL,\n                    f: 1,\n                    v: 1\n                }],\n                ['l', 232, 352, {\n                    x: 0,\n                    r: ROTATE_VERTICAL,\n                    f: 1\n                }]\n            ]\n        }]\n    )\n};"
  },
  {
    "path": "src/font/util.js",
    "content": "import {\n    Vector\n} from '../core/vector.js';\nimport {\n    bezierTangent\n} from '../core/paths.js';\n\nexport const ROTATE_HORIZONTAL = 180 * (Math.PI / 180);\nexport const ROTATE_VERTICAL = 90 * (Math.PI / 180);\nexport const ROTATE_NONE = -100;\nexport const VERTEX_GAP = 3;\nexport const VERTEX_GAP2 = VERTEX_GAP / 2;\nexport const TOFU = 'tofu';\nconst FONT_HEIGHT = 824;\n\nexport function generateFontData(w, fw, fh, x1, x2, y1, y2, path) {\n    const arr = [];\n    const total = path.length;   \n    let i; \n    for (i = 0; i < total; i++) {\n        arr.push({\n            d: path[i].d,\n            v: setCenter(path[i].v, fw, fh)\n        });\n    }\n\n    return {\n        rect: {\n            w: w,\n            h: FONT_HEIGHT,\n            fw: fw,\n            fh: fh\n        },\n        ratio: {\n            x1: x1,\n            x2: x2,\n            y1: y1,\n            y2: y2,\n        },\n        p: arr,\n        clone: () => {\n            const arr2 = [];\n            for (let i = 0; i < arr.length; i++) {\n                arr2[i] = {\n                    d: arr[i].d,\n                    v: arr[i].v\n                };\n            }\n            const v = {\n                rect: {\n                    w: w,\n                    h: FONT_HEIGHT,\n                    fw: fw,\n                    fh: fh\n                },\n                ratio: {\n                    x1: x1,\n                    x2: x2,\n                    y1: y1,\n                    y2: y2,\n                },\n                p: arr2,\n            };\n            return v;\n        }\n    };\n}\n\nfunction setCenter(arr, fw, fh) {\n    const total = arr.length;\n    const cx = fw / 2;\n    const cy = fh / 2;\n    let mp, i, ct = [];\n\n    for (i = 0; i < total; i++) {\n        mp = arr[i];\n        mp[1] -= cx;\n        mp[2] -= cy;\n        if (mp[0] == 'b') {\n            mp[3] -= cx;\n            mp[4] -= cy;\n            mp[5] -= cx;\n            mp[6] -= cy;\n        }\n        ct.push(new Vector(mp));\n    }\n\n    return ct;\n}\n\nexport function getR(x1, y1, x2, y2) {\n    const x = x1 - x2;\n    const y = y1 - y2;\n    return -Math.atan2(x, y);\n}\n\nexport function getCurveR(x1, y1, x2, y2, x3, y3, x4, y4, t) {\n    const x = bezierTangent(x1, x2, x3, x4, t);\n    const y = bezierTangent(y1, y2, y3, y4, t);\n    return -Math.atan2(x, y);\n}"
  },
  {
    "path": "src/index.js",
    "content": "const LeonSans = require('./leonsans').default;\nmodule.exports = LeonSans;"
  },
  {
    "path": "src/leonsans.js",
    "content": "/*!\n * VERSION: 1.6.3\n * DATE: 2019-09-13\n * https://leon-sans.com\n *\n * @license Copyright (c) 2019, Jongmin Kim. All rights reserved.\n **/\nimport {\n    Dispatcher\n} from './core/dispatcher.js';\nimport {\n    MIN_FONT_WEIGHT,\n    MAX_FONT_WEIGHT,\n    shuffle\n} from './core/util.js';\nimport {\n    Lines\n} from './draw/canvas/lines.js';\nimport {\n    Points\n} from './draw/canvas/points.js';\nimport {\n    Grids\n} from './draw/canvas/grids.js';\nimport {\n    Wave\n} from './draw/canvas/wave.js';\nimport {\n    Pattern\n} from './draw/canvas/pattern.js';\nimport {\n    Color\n} from './draw/canvas/color.js';\nimport {\n    Colorful\n} from './draw/canvas/colorful.js';\nimport {\n    PixiLines\n} from './draw/pixi/lines.js';\nimport {\n    PixiColor\n} from './draw/pixi/color.js';\nimport {\n    Model\n} from './core/model.js';\n\n\nexport default class LeonSans extends Dispatcher {\n    constructor({\n        text = '',\n        size = 500,\n        weight = MIN_FONT_WEIGHT,\n        color = ['#000000'],\n        colorful = ['#c5d73f', '#9d529c', '#49a9db', '#fec330', '#5eb96e', '#fc5356', '#f38f31'],\n        tracking = 0,\n        leading = 0,\n        align = 'left',\n        pathGap = 0.5,\n        amplitude = 0.5,\n        width = 0,\n        breakWord = false,\n        fps = 30,\n        isPath = false,\n        isWave = false,\n    } = {}) {\n        super();\n\n        this.size_ = size;\n        this.weight_ = weight;\n        this.color_ = color;\n        this.colorful_ = shuffle(colorful);\n        this.tracking_ = tracking;\n        this.leading_ = leading;\n        this.pathGap_ = pathGap;\n        this.amplitude_ = amplitude;\n        this.width_ = width;\n        this.breakWord_ = breakWord;\n        this.fps_ = fps;\n        this.fpsTime_ = 1000 / this.fps_;\n        this.isPath_ = isPath;\n        this.isWave_ = isWave;\n\n        this.model = new Model();\n\n        this.str_ = null;\n\n        this.time_ = null;\n        this.isFps_ = false;\n        this.isForceRander_ = false;\n\n        this.updateID_ = 0;\n        this.dPathsID_ = null;\n        this.pPathsID_ = null;\n        this.wPathsID_ = null;\n        this.guideID_ = null;\n\n        this.text = text;\n\n        this.model.align = align;\n    }\n\n    on(event, callback) {\n        super.on(event, callback);\n        this.update();\n    }\n\n    off(event, callback) {\n        super.off(event, callback);\n    }\n\n    get text() {\n        return this.str_;\n    }\n\n    set text(str) {\n        if (this.str_ == str) return;\n        this.str_ = str;\n        this.update();\n    }\n\n    get size() {\n        return this.size_;\n    }\n\n    set size(v) {\n        if (this.size_ == v) return;\n        this.size_ = v;\n        this.update();\n        this.isForceRander_ = true;\n    }\n\n    get weight() {\n        return this.weight_;\n    }\n\n    set weight(v) {\n        if (v < MIN_FONT_WEIGHT) {\n            v = MIN_FONT_WEIGHT;\n        } else if (v > MAX_FONT_WEIGHT) {\n            v = MAX_FONT_WEIGHT;\n        }\n        if (this.weight_ == v) return;\n        this.weight_ = v;\n        this.update();\n        this.isForceRander_ = true;\n    }\n\n    get color() {\n        return this.color_;\n    }\n\n    set color(v) {\n        if (this.color_ == v) return;\n        this.color_ = v;\n    }\n\n    get tracking() {\n        return this.tracking_;\n    }\n\n    set tracking(v) {\n        if (this.tracking_ == v) return;\n        this.tracking_ = v;\n        this.update();\n        this.isForceRander_ = true;\n    }\n\n    get leading() {\n        return this.leading_;\n    }\n\n    set leading(v) {\n        if (this.leading_ == v) return;\n        this.leading_ = v;\n        this.update();\n        this.isForceRander_ = true;\n    }\n\n    get align() {\n        return this.model.align;\n    }\n\n    set align(v) {\n        if (this.model.align != v) {\n            this.model.align = v;\n            this.updateID_++;\n            this.updateSignal();\n        }\n    }\n\n    get pathGap() {\n        return this.pathGap_;\n    }\n\n    set pathGap(v) {\n        if (this.pathGap_ != v) {\n            this.pathGap_ = v;\n            this.updatePatternPaths(true);\n            this.updateWavePaths(true);\n            this.isForceRander_ = true;\n        }\n    }\n\n    get amplitude() {\n        return this.amplitude_;\n    }\n\n    set amplitude(v) {\n        this.amplitude_ = v;\n    }\n\n    get rect() {\n        return this.model.rect;\n    }\n\n    set maxWidth(v) {\n        if (this.width_ == v) return;\n        this.width_ = v;\n        this.update();\n    }\n\n    get maxWidth() {\n        return this.width_;\n    }\n\n    set breakWord(v) {\n        if (this.breakWord_ == v) return;\n        this.breakWord_ = v;\n        this.update();\n    }\n\n    get breakWord() {\n        return this.breakWord_;\n    }\n\n    get isPath() {\n        return this.isPath_;\n    }\n\n    set isPath(v) {\n        this.isPath_ = v;\n        this.updatePatternPaths(true);\n    }\n\n    get isWave() {\n        return this.isWave_;\n    }\n\n    set isWave(v) {\n        this.isWave_ = v;\n        this.updateWavePaths(true);\n    }\n\n    get fps() {\n        return this.fps_;\n    }\n\n    set fps(v) {\n        this.fps_ = v;\n        this.fpsTime_ = 1000 / this.fps_;\n    }\n\n    get lineWidth() {\n        return this.model.lineWidth;\n    }\n\n    get scale() {\n        return this.model.scale;\n    }\n\n    get drawing() {\n        return this.model.drawing;\n    }\n\n    get data() {\n        return this.model.data;\n    }\n\n    get paths() {\n        return this.model.paths;\n    }\n\n    get drawingPaths() {\n        return this.model.drawingPaths;\n    }\n\n    get wavePaths() {\n        return this.model.wavePaths;\n    }\n\n    position(x = 0, y = 0) {\n        if (this.model.position(x, y)) {\n            this.updateID_++;\n            this.updateSignal();\n        }\n    }\n\n    update() {\n        this.updateID_++;\n\n        this.model.update(\n            this.str_,\n            this.width_,\n            this.breakWord_,\n            this.weight_,\n            this.size_,\n            this.tracking_,\n            this.leading_\n        );\n\n        if (this.isPath_ || this.isWave_) {\n            this.updatePatternPaths();\n            this.updateWavePaths();\n        } else {\n            this.updateSignal();\n        }\n    }\n\n    updateGuide() {\n        if (this.guideID_ != this.updateID_) {\n            this.guideID_ = this.updateID_;\n            this.model.updateGuide();\n        }\n    }\n\n    /**\n     * Update paths for drawing in WebGL (PIXI.js). It's very expensive, only call when it needs.\n     */\n    updateDrawingPaths() {\n        if (this.dPathsID_ != this.updateID_) {\n            this.dPathsID_ = this.updateID_;\n            this.model.updateDrawingPaths();\n        }\n    }\n\n    /**\n     * Update paths for pattern\n     * @param {boolean} force - Force execution\n     */\n    updatePatternPaths(force) {\n        if (this.isPath_ && (force || this.pPathsID_ != this.updateID_)) {\n            this.pPathsID_ = this.updateID_;\n            this.model.updatePatternPaths(this.pathGap_);\n            this.isForceRander_ = true;\n            this.updateSignal();\n        }\n    }\n\n    /**\n     * Update paths for wave effect\n     * @param {boolean} force - Force execution\n     */\n    updateWavePaths(force) {\n        if (this.isWave_ && (force || this.wPathsID_ != this.updateID_)) {\n            this.wPathsID_ = this.updateID_;\n            this.model.updateWavePaths(this.pathGap_);\n            this.isForceRander_ = true;\n            this.updateSignal();\n        }\n    }\n\n    updateSignal() {\n        this.model.updateLinesForRect();\n        this.model.updatePathsForRect();\n        this.dispatch('update', this.model);\n    }\n\n    reset() {\n        this.size_ = 500;\n        this.weight_ = MIN_FONT_WEIGHT;\n        this.color_ = ['#000000'];\n        this.tracking_ = 0;\n        this.leading_ = 0;\n        this.pathGap_ = 0.5;\n        this.amplitude_ = 0.5;\n        this.width_ = 0;\n        this.breakWord_ = false;\n        this.fps_ = 30;\n        this.fpsTime_ = 1000 / this.fps_;\n        this.isPath_ = false;\n        this.isWave_ = false;\n\n        this.str_ = null;\n\n        this.time_ = null;\n        this.isFps_ = false;\n        this.isForceRander_ = false;\n\n        this.updateID_ = 0;\n        this.dPathsID_ = null;\n        this.pPathsID_ = null;\n        this.wPathsID_ = null;\n        this.guideID_ = null;\n\n        this.model.reset();\n    }\n\n    dispose() {\n        this.reset();\n        this.model = null;\n    }\n\n    /**\n     * Draw text in WebGL with PIXI.js\n     * @param {PIXI.Graphics} graphics\n     */\n    drawPixi(graphics) {\n        const total = this.model.data.length;\n        let i, d, color;\n        for (i = 0; i < total; i++) {\n            d = this.model.data[i];\n            color = PixiColor(i, d, this.color_);\n            PixiLines(graphics, d, this.lineWidth, color);\n        }\n    }\n\n    /**\n     * Draw text in the Canvas element.\n     * @param {CanvasRenderingContext2D} ctx\n     */\n    draw(ctx) {\n        ctx.lineWidth = this.lineWidth;\n        const total = this.model.data.length;\n        let i, d;\n        for (i = 0; i < total; i++) {\n            d = this.model.data[i];\n            Color(ctx, i, d, this.color_);\n            Lines(ctx, d);\n        }\n    }\n\n    /**\n     * Draw the colorful effect.\n     * @param {CanvasRenderingContext2D} ctx\n     */\n    drawColorful(ctx) {\n        ctx.lineWidth = this.lineWidth;\n        Colorful(ctx, this.model, this.colorful_);\n    }\n\n    /**\n     * Draw the wave effect.\n     * @param {CanvasRenderingContext2D} ctx\n     * @param {DOMHighResTimeStamp} t time stemp from requestAnimationFrame()\n     */\n    wave(ctx, t) {\n        ctx.lineWidth = this.lineWidth;\n\n        if (t) {\n            if (!this.time_) this.time_ = t;\n            const p = t - this.time_;\n            if (p > this.fpsTime_ || this.isForceRander_) {\n                this.time_ = t;\n                this.isFps_ = true;\n            } else {\n                this.isFps_ = false;\n            }\n        }\n        this.isForceRander_ = false;\n\n        const total = this.model.data.length;\n        let i, d;\n        for (i = 0; i < total; i++) {\n            d = this.model.data[i];\n            Color(ctx, i, d, this.color_);\n            Wave(ctx, d, this.model.scale, this.amplitude_, this.weight_, this.isFps_);\n        }\n    }\n\n    /**\n     * Draw rectangle shapes at each path point.\n     * @param {CanvasRenderingContext2D} ctx\n     * @param {number} w pattern width\n     * @param {number} h pattern height\n     */\n    pattern(ctx, w, h) {\n        const tw = w * this.model.scale;\n        const th = h * this.model.scale;\n\n        const total = this.model.data.length;\n        let i, d;\n        for (i = 0; i < total; i++) {\n            d = this.model.data[i];\n            Pattern(ctx, d, tw, th);\n        }\n    }\n\n    /**\n     * Draw grid for each type.\n     * @param {CanvasRenderingContext2D} ctx\n     */\n    grid(ctx) {\n        this.updateGuide();\n\n        const total = this.model.data.length;\n        let i, d;\n        for (i = 0; i < total; i++) {\n            d = this.model.data[i];\n            Grids(ctx, d);\n        }\n    }\n\n    /**\n     * Draw circles at each drawing point and lines for each type.\n     * @param {CanvasRenderingContext2D} ctx\n     */\n    point(ctx) {\n        const total = this.model.data.length;\n        let i, d;\n        for (i = 0; i < total; i++) {\n            d = this.model.data[i];\n            Points(ctx, d);\n        }\n    }\n\n    /**\n     * Draw outline box for the text.\n     * @param {CanvasRenderingContext2D} ctx\n     * @private\n     */\n    box(ctx) {\n        ctx.lineWidth = 1;\n        ctx.beginPath();\n        ctx.strokeStyle = \"#0b90dc\";\n        ctx.rect(this.model.rect.x, this.model.rect.y, this.model.rect.w, this.model.rect.h);\n        ctx.stroke();\n    }\n}"
  }
]