svg-path-commander 2.0.9 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/.eslintrc.cjs +1 -0
  2. package/README.md +4 -4
  3. package/dist/svg-path-commander.cjs +1 -1
  4. package/dist/svg-path-commander.cjs.map +1 -1
  5. package/dist/svg-path-commander.d.ts +156 -39
  6. package/dist/svg-path-commander.js +1 -1
  7. package/dist/svg-path-commander.js.map +1 -1
  8. package/dist/svg-path-commander.mjs +869 -705
  9. package/dist/svg-path-commander.mjs.map +1 -1
  10. package/package.json +22 -24
  11. package/src/convert/pathToAbsolute.ts +1 -1
  12. package/src/convert/pathToCurve.ts +1 -1
  13. package/src/convert/pathToRelative.ts +1 -1
  14. package/src/index.ts +30 -26
  15. package/src/interface.ts +32 -32
  16. package/src/math/arcTools.ts +217 -0
  17. package/src/math/bezier.ts +261 -0
  18. package/src/math/cubicTools.ts +81 -0
  19. package/src/math/lineTools.ts +52 -0
  20. package/src/math/quadTools.ts +79 -0
  21. package/src/parser/isMoveCommand.ts +17 -0
  22. package/src/parser/parsePathString.ts +1 -1
  23. package/src/parser/scanSegment.ts +12 -3
  24. package/src/process/normalizePath.ts +1 -1
  25. package/src/process/replaceArc.ts +52 -0
  26. package/src/process/splitPath.ts +1 -1
  27. package/src/process/transformPath.ts +14 -34
  28. package/src/types.ts +5 -0
  29. package/src/util/distanceEpsilon.ts +3 -0
  30. package/src/util/getClosestPoint.ts +1 -1
  31. package/src/util/getPathBBox.ts +4 -3
  32. package/src/util/getPointAtLength.ts +3 -3
  33. package/src/util/getPropertiesAtLength.ts +2 -1
  34. package/src/util/getPropertiesAtPoint.ts +4 -1
  35. package/src/util/getTotalLength.ts +2 -2
  36. package/src/util/isPointInStroke.ts +2 -1
  37. package/src/util/pathFactory.ts +130 -0
  38. package/src/util/shapeToPathArray.ts +8 -4
  39. package/test/class.test.ts +501 -0
  40. package/test/fixtures/getMarkup.ts +17 -0
  41. package/{cypress → test}/fixtures/shapes.js +18 -18
  42. package/{cypress → test}/fixtures/simpleShapes.js +6 -6
  43. package/test/static.test.ts +304 -0
  44. package/tsconfig.json +9 -4
  45. package/{vite.config.ts → vite.config.mts} +10 -1
  46. package/vitest.config-ui.mts +26 -0
  47. package/vitest.config.mts +26 -0
  48. package/cypress/e2e/svg-path-commander.spec.ts +0 -868
  49. package/cypress/plugins/esbuild-istanbul.ts +0 -50
  50. package/cypress/plugins/tsCompile.ts +0 -34
  51. package/cypress/support/commands.ts +0 -37
  52. package/cypress/support/e2e.ts +0 -21
  53. package/cypress/test.html +0 -36
  54. package/src/util/pathLengthFactory.ts +0 -114
  55. package/src/util/segmentArcFactory.ts +0 -219
  56. package/src/util/segmentCubicFactory.ts +0 -114
  57. package/src/util/segmentLineFactory.ts +0 -45
  58. package/src/util/segmentQuadFactory.ts +0 -109
  59. /package/{cypress/fixtures/shapeObjects.js → test/fixtures/shapeObjects.ts} +0 -0
@@ -1,50 +0,0 @@
1
- // sources
2
- // * https://github.com/enketo/enketo-express/blob/master/tools/esbuild-plugin-istanbul.js
3
- 'use strict';
4
- import esbuild from 'esbuild';
5
- import { promises } from 'fs';
6
- import { createInstrumenter } from 'istanbul-lib-instrument';
7
- import { extname, sep } from 'path';
8
- import tsCompile from './tsCompile';
9
-
10
- // import Cypress settings
11
- const sourceFolder = 'src';
12
- const [name] = process.cwd().split(sep).slice(-1);
13
-
14
- const sourceFilter = `${name}${sep}${sourceFolder}`;
15
- const instrumenter = createInstrumenter({
16
- compact: false,
17
- esModules: true,
18
- preserveComments: true,
19
- autoWrap: true,
20
- });
21
-
22
- const createEsbuildIstanbulPlugin = (): esbuild.Plugin => {
23
- return {
24
- name: 'istanbul',
25
- setup(build: esbuild.PluginBuild) {
26
- build.onLoad(
27
- { filter: /\.(ts|tsx)$/ },
28
- async ({ path }: esbuild.OnLoadArgs): Promise<{ contents: string } & Record<string, any>> => {
29
-
30
- if (!path.includes(sourceFilter)) {
31
- // console.log("> compiling typescript %s for output build", path);
32
- const contents = await promises.readFile(path, 'utf8');
33
- return {
34
- contents: ['.ts', '.tsx'].includes(extname(path)) ? tsCompile(path).outputText : contents,
35
- };
36
- }
37
-
38
- // console.log("🧡 instrumenting %s for output coverage", path);
39
- const { outputText, sourceMap } = tsCompile(path);
40
-
41
- return {
42
- contents: instrumenter.instrumentSync(outputText, path, sourceMap),
43
- };
44
- },
45
- );
46
- },
47
- };
48
- };
49
-
50
- export default createEsbuildIstanbulPlugin;
@@ -1,34 +0,0 @@
1
- // compile.ts
2
- import TypeScript from 'typescript';
3
- import { basename } from 'path';
4
- import { RawSourceMap } from 'source-map';
5
- import { readFileSync } from 'fs';
6
-
7
- export default function tsCompile(
8
- path: string,
9
- ops?: Partial<TypeScript.TranspileOptions>,
10
- ): TypeScript.TranspileOutput & { sourceMap: RawSourceMap } {
11
- // Default options -- you could also perform a merge, or use the project tsconfig.json
12
- const options: TypeScript.TranspileOptions = Object.assign(
13
- {
14
- compilerOptions: {
15
- allowJs: true,
16
- esModuleInterop: true,
17
- removeComments: false,
18
- target: 99, // ESNext
19
- allowSyntheticDefaultImports: true,
20
- isolatedModules: true,
21
- noEmitHelpers: true,
22
- sourceMap: true,
23
- } as Partial<TypeScript.CompilerOptions>,
24
- },
25
- ops,
26
- );
27
- const contents = readFileSync(path, { encoding: 'utf8' });
28
- const { outputText, sourceMapText } = TypeScript.transpileModule(contents, options);
29
- const sourceMap: RawSourceMap = JSON.parse(sourceMapText || '');
30
- sourceMap.file = basename(path);
31
- sourceMap.sources = [basename(path)];
32
-
33
- return { outputText, sourceMap, sourceMapText };
34
- }
@@ -1,37 +0,0 @@
1
- /// <reference types="cypress" />
2
- // ***********************************************
3
- // This example commands.ts shows you how to
4
- // create various custom commands and overwrite
5
- // existing commands.
6
- //
7
- // For more comprehensive examples of custom
8
- // commands please read more here:
9
- // https://on.cypress.io/custom-commands
10
- // ***********************************************
11
- //
12
- //
13
- // -- This is a parent command --
14
- // Cypress.Commands.add('login', (email, password) => { ... })
15
- //
16
- //
17
- // -- This is a child command --
18
- // Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
19
- //
20
- //
21
- // -- This is a dual command --
22
- // Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
23
- //
24
- //
25
- // -- This will overwrite an existing command --
26
- // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
27
- //
28
- // declare global {
29
- // namespace Cypress {
30
- // interface Chainable {
31
- // login(email: string, password: string): Chainable<void>
32
- // drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
33
- // dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
34
- // visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
35
- // }
36
- // }
37
- // }
@@ -1,21 +0,0 @@
1
- // ***********************************************************
2
- // This example support/e2e.ts is processed and
3
- // loaded automatically before your test files.
4
- //
5
- // This is a great place to put global configuration and
6
- // behavior that modifies Cypress.
7
- //
8
- // You can change the location of this file or turn off
9
- // automatically serving support files with the
10
- // 'supportFile' configuration option.
11
- //
12
- // You can read more here:
13
- // https://on.cypress.io/configuration
14
- // ***********************************************************
15
-
16
- // Import commands.js using ES2015 syntax:
17
- import "./commands";
18
-
19
- // Alternatively you can use CommonJS syntax:
20
- // require('./commands')
21
- import "@cypress/code-coverage/support";
package/cypress/test.html DELETED
@@ -1,36 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
- <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
7
- <title>SVGPathCommander Path Tools</title>
8
- <meta name="description" content="SVGPathCommander Path Tools">
9
- <meta name="keywords" content="javascript,svg,svg path,svgpathcommander,path to absolute,path to relative, normalize path">
10
- <meta name="author" content="thednp">
11
- <link href="../docs/assets/style.css" rel="stylesheet">
12
- <link rel="shortcut icon" href="./assets/favicon.ico">
13
- <link rel="apple-touch-icon" href="./assets/apple-touch-icon.png">
14
- </head>
15
- <body>
16
- <h1><a href="https://github.com/thednp/svg-path-commander">
17
- <svg id="svg-path-commander" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1135 256" aria-label="SVGPathCommander - modern path processing tool" fill="currentColor">
18
- <path id="svg_" fill="orangered" d="M222.7 102.2l-1.7 1.6c-7.6 -10 -20.4 -14.3 -32.6 -11.6c-12 2.6 -20.9 12.5 -23.7 24.2c-2.9 12.1 -0.1 25.8 9.3 34.4c9.2 8.4 23.5 10.5 34.9 5.9c6.2 -2.5 11.2 -7.3 14 -13.4c2.4 -5.5 2.9 -11.2 2.9 -17.1l0.6 0.5h-29.6l0 -2.2h31.3c0 11.9 -2.5 24.5 -13.1 31.5c-10.8 7.2 -27 6.8 -37.9 0c-11.3 -7.1 -16.2 -20.4 -15.5 -33.3c0.8 -13.3 8 -25.6 20.5 -30.9c7 -3 15 -3.5 22.4 -1.7c7.5 1.7 13.5 6.3 18.2 12.1zM46.1 148.7l1.8 -1.6c6.3 9.8 19.2 13.8 30.3 11.2C83.6 157 89 153.5 91.1 148.1c2.2 -5.5 0.5 -11.3 -4.1 -14.8c-4.5 -3.4 -10.3 -5 -15.6 -6.5c-5.8 -1.7 -11.6 -3.3 -16.6 -6.7c-4.9 -3.4 -7.2 -8.7 -6.5 -14.6C49 99.9 52.8 95.1 57.7 92.4C63.5 89.2 70.5 88.6 77 89.5c6.5 1 12 4.3 16 9.5l-1.7 1.5C87.7 96 83.3 93 77.6 91.9C72 90.8 65.9 91 60.8 93.3c-5 2.2 -9.3 6.4 -10.1 11.9c-0.9 6 1.9 11 6.9 14.1c5.2 3.3 11.4 4.3 17.2 6c5.5 1.6 11.8 3.8 15.8 8c4 4.2 4.8 10.3 2.6 15.7c-2.1 5 -6.6 8.6 -11.6 10.4c-12.3 4.6 -28 0.1 -35.5 -10.7zM130 160.2h-2.7l-26.8 -70h2.6c2.9 7.7 5.8 15.5 8.8 23.2c4.3 11.4 8.6 22.8 13 34.3c0.5 1.4 1.1 2.9 1.6 4.3c0.1 0.2 0.2 0.4 0.2 0.6c0.5 1.4 1 2.7 1.6 4.1c0.3 0.8 1 1.9 1 2.7H128c0 -0.5 0.7 -1.7 0.9 -2.2c0.6 -1.4 1.1 -2.7 1.6 -4.1c0.1 -0.2 0.2 -0.5 0.3 -0.7c0.4 -1.1 0.9 -2.3 1.3 -3.4c1.8 -4.8 3.6 -9.6 5.5 -14.4c4.6 -12 9.1 -23.9 13.7 -35.9c1.1 -2.8 2.2 -5.7 3.2 -8.5h2.6l-27.1 70z"/>
19
- <path id="path-commander_" d="M628.2 158.3h-16.1l0 -53.1h15.2l0 6.8c3 -4.9 9.7 -7.7 15.2 -7.8c6.6 -0.1 13.5 2.8 15.9 9.3c0.7 -1.8 2.7 -3.4 4.2 -4.6c1.9 -1.5 4 -2.6 6.2 -3.5c4.4 -1.7 9.2 -1.9 13.7 -0.6c9 2.4 12.6 11.1 12.7 19.7c0.1 7.9 0 15.8 0 23.7c0 3.3 0 6.6 0 9.9H679c0 -10.3 0 -20.5 0 -30.8c0 -4.5 -1.5 -9.2 -6.6 -9.8c-5.6 -0.6 -10.7 3.2 -10.8 9c-0.1 5 0 10 0 14.9c0 5.5 0 11.1 0 16.6h-16.1c0 -10.3 0 -20.6 0 -30.8c0 -4.7 -1.8 -9.2 -7 -9.7c-5.4 -0.5 -10.3 3.3 -10.4 8.9c-0.1 5 0 10 0 15c0 5.7 0 11.3 0.1 16.9v0zM724.4 158.3h-16.1l0 -53.1h15.2c0 0.7 0.4 6.7 0.2 6.7c0.2 0 1.1 -1.4 1.2 -1.6c0.5 -0.5 1 -1.1 1.6 -1.5c1.2 -1 2.5 -1.8 3.9 -2.5c2.9 -1.4 6 -2.2 9.3 -2.1c3.2 0.1 6.5 0.8 9.2 2.5c1.3 0.8 2.5 1.8 3.4 3c0.4 0.4 2 3.8 2.3 3.8c0 0 1.5 -2.1 1.7 -2.3c0.7 -0.8 1.5 -1.6 2.4 -2.3c1.9 -1.5 4 -2.6 6.2 -3.5c4.4 -1.7 9.2 -1.9 13.7 -0.6c9 2.4 12.6 11.1 12.7 19.7c0.1 7.9 0 15.8 0 23.7c0 3.3 0 6.6 0 9.9h-16.1c0 -10.3 0 -20.5 0 -30.8c0 -4.5 -1.5 -9.2 -6.6 -9.8c-5.6 -0.6 -10.7 3.2 -10.8 9c-0.1 5 0 10 0 14.9c0 5.5 0 11.1 0 16.6h-16.1c0 -10.3 0 -20.6 0 -30.8c0 -4.7 -1.8 -9.2 -7 -9.7c-5.4 -0.5 -10.2 3.4 -10.3 8.9c-0.1 5 0 10 0 15.1c0 5.6 0 11.2 0 16.8v0zM415.2 158.3v-74h15.7c0 7.9 0 15.8 0 23.6c0 1.2 0.2 2.5 -0.1 3.7c3.1 -3.1 6.4 -5.5 10.7 -6.7c4.4 -1.2 9.4 -0.9 13.6 0.8c7.9 3.2 10 12.3 10.1 20c0 7.7 0 15.5 0 23.2c0 3.1 0 6.3 0 9.4h-16.1c0 -10.3 0 -20.7 0 -31c0 -4.7 -1.6 -9.2 -6.9 -9.7c-5.6 -0.6 -11.1 2.8 -11.2 8.8c-0.1 5 0 9.9 0 14.9c0 5.6 0 11.3 0 16.9c-5.3 0 -10.5 0 -15.8 0v0.1zM1047.8 130.9l-0.1 4.3H1011c-0.7 -3.1 -0.8 -5.9 0 -9c3.7 0 7.5 0 11.2 0c2.5 0 5 0 7.6 0c0.8 0 2.6 0.4 3.2 -0.1c-0.3 -5.1 -4.8 -8.4 -9.6 -8.6c-4.8 -0.2 -9.6 2 -11.6 6.5c-1.8 4.3 -1.8 9.3 0.1 13.6c1.8 4.1 5.7 6.6 9.9 7.4c2.7 0.6 5.8 0.6 8.5 0c2.9 -0.7 5.3 -2.3 7.6 -4l7.5 10.6c-7.9 6.7 -18.6 9.4 -28.7 7c-9.7 -2.3 -17.7 -9.1 -20.3 -18.8c-2.6 -9.5 -0.3 -20.7 6.6 -27.8c7.1 -7.3 18.4 -9.8 28 -6.5c5.1 1.7 9.4 5.1 12.4 9.6c1.3 2.1 2.4 4.3 3.1 6.7c0.4 1.5 0.8 3 1 4.6c0 1.5 0.5 2.9 0.3 4.5zM538.8 98.1L528.4 110c-4.7 -4.7 -10.4 -7.7 -17.2 -7.2c-6.4 0.4 -12.2 3.8 -15.3 9.5c-3.1 5.8 -3.4 13.1 -1.1 19.3c2.3 6.2 7.8 10.2 14.1 11.4c7.6 1.4 15.5 -0.6 20.9 -6.4l8.2 13c-3.6 4 -8.8 6.3 -13.9 7.8c-5.8 1.6 -11.8 2.2 -17.7 1.4c-10.9 -1.5 -20.8 -7.6 -26.1 -17.4C474.8 131.3 474.2 118 479 107.6c4.6 -10.1 13.8 -17.3 24.5 -19.7c6.6 -1.5 13.7 -1.4 20.1 0.6c2.9 0.9 5.8 2.1 8.4 3.8c1.3 0.8 2.6 1.8 3.8 2.8c1.1 0.8 2 2 3 3zM870.5 158.3v-53.1h15.2c0.1 2.1 0.3 4.3 0.3 6.4c0 -0.3 0.9 -1 1.1 -1.2c0.8 -0.8 1.7 -1.6 2.7 -2.3c1.8 -1.3 3.8 -2.3 5.9 -3c4.4 -1.5 9.3 -1.4 13.7 0c8.7 2.9 11.1 12.2 11.2 20.4c0 7.7 0 15.4 0 23.1c0 3.2 0 6.3 0 9.5h-16.1c0 -10.3 0 -20.6 0 -30.9c0 -4.7 -1.6 -9.2 -6.9 -9.7c-5.6 -0.6 -11.1 2.8 -11.2 8.8c-0.1 5 0 9.9 0 14.9c0 5.6 0 11.3 0 16.9c-5.3 0 -10.5 0 -15.8 0v0.2zM969.8 110.5V84.3h16.1l0 74H971c-0.1 -1.1 -0.2 -2.2 -0.2 -3.4c0 -0.6 -0.5 -2.2 0 -2.7c-2.7 2.7 -5.4 4.8 -9.1 6c-3.9 1.2 -7.9 1.6 -11.9 0.8c-7.2 -1.3 -13 -6.5 -16.2 -13c-6.7 -14 -2.6 -35.5 13.6 -40.9c4.1 -1.4 8.6 -1.5 12.8 -0.4c2 0.5 4 1.3 5.8 2.4c1 0.6 1.9 1.2 2.7 2c0.3 0.3 1.2 1.4 1.3 1.4zM345.4 111.1v-5.9h15.9l0 53.1h-16.2c0 -0.7 0.4 -6.2 0.1 -6.3c-0.3 -0.1 -3.1 2.8 -3.5 3.1c-1.6 1.2 -3.3 2.1 -5.1 2.8c-3.6 1.3 -7.4 1.7 -11.2 1C318 157.7 312 152.5 308.8 145.8c-6.7 -13.9 -2.7 -35 13.3 -40.5c4.2 -1.5 8.8 -1.5 13.1 -0.4c2 0.5 4 1.3 5.7 2.5c1 0.7 1.9 1.4 2.7 2.3c0.5 0.3 1.1 1.4 1.8 1.4zM840.5 111.4v-6.1h15.9l0 53.1h-16.2l0 -6.7c0.3 0.9 -2.7 3 -3.4 3.5c-1.6 1.2 -3.3 2.1 -5.1 2.8c-3.6 1.3 -7.4 1.7 -11.2 1c-7.4 -1.2 -13.4 -6.4 -16.6 -13.1c-6.7 -13.9 -2.7 -35 13.3 -40.5c4.2 -1.5 8.8 -1.5 13.1 -0.4c2 0.5 4 1.3 5.7 2.5c0.9 0.6 1.8 1.3 2.6 2.1c0.5 0.5 1.4 2 1.9 2.2c0.1 -0.1 0 -0.4 0 -0.4zM263 158.3h-17l0 -70c9.9 0 19.9 0 29.8 0c4.6 0 9 1 12.9 3.5c4.8 3 8.3 7.8 9.7 13.3c3.1 11.9 -3.3 25.4 -15.4 28.9c-3.7 1.1 -7.6 0.9 -11.4 0.9c-2.9 0 -5.7 0 -8.6 0v23.4zM1074.1 158.3H1058l0 -53.1h15.2c0.1 1.4 0.1 2.9 0.2 4.3c0 1.2 0.3 2.7 0.1 3.9c4.3 -7.3 13.7 -11.3 21.8 -8.3l-4.4 17.7c-2.3 -1.7 -6 -1.9 -8.7 -1.4c-2.8 0.5 -5.1 2 -6.6 4.5c-1.4 2.4 -1.4 5.1 -1.4 7.7c0 6.3 0 12.6 0 18.9c0 1.9 0 3.9 0 5.8h-0.1zM564.8 158.3c-11.5 -3.1 -20.1 -13 -20.5 -25.1c-0.2 -6.1 1.2 -12 4.6 -17c3.1 -4.5 7.5 -8 12.6 -10c10.9 -4.3 24.5 -2.1 32.8 6.4s10.1 22.6 4 32.9c-6.7 11.5 -20.9 16.1 -33.5 12.8zM395.8 158.3h-16c0 -8.6 0 -17.2 0 -25.8c0 -9.1 0 -18.2 0 -27.4c0 -4.5 0 -8.9 0 -13.4h16l0 66.6zM380.1 119.2h-9.7l0 -14h9.7l0 14zM958.2 146.1c6.1 0 10.4 -4.5 11.5 -10.2c1 -5.1 0.4 -11.3 -3.4 -15.1c-3.9 -3.9 -10.4 -4.5 -14.9 -1.3s-5.6 9.4 -5.1 14.6c0.6 6.4 5 12 11.9 12zM573.1 145.5c12.4 0 16.3 -17.3 7.9 -24.9c-4.1 -3.7 -10.5 -3.9 -15 -0.7c-4.5 3.3 -5.8 9.2 -5.1 14.4c0.8 6.3 5.8 11.2 12.2 11.2zM333.5 145.7c5.9 0 10.2 -3.8 11.6 -9.4c1.3 -5.3 0.5 -11.8 -3.5 -15.7c-3.9 -3.8 -10.7 -4 -15 -0.8c-4.4 3.3 -5.5 9.3 -4.9 14.4c0.7 6.4 5.2 11.5 11.8 11.5zM828.6 145.7c5.9 0 10.2 -3.8 11.6 -9.4c1.3 -5.3 0.5 -11.8 -3.5 -15.7c-3.9 -3.8 -10.7 -4 -15 -0.8c-4.4 3.3 -5.5 9.3 -4.9 14.4c0.7 6.4 5.2 11.5 11.8 11.5zM262.7 103.3V120c2.3 0 4.6 0 6.9 0c2.8 0 5.8 0.4 8.4 -1.2c4.4 -2.7 5.2 -9.7 1.5 -13.3c-2.5 -2.4 -5.6 -2.2 -8.8 -2.2c-0.6 0 -8 0 -8 0zM395.8 105.2h11.7l0 14h-11.7l0 -14z"/>
20
- <path id="subtext_" fill-opacity="0.6" d="M253.2 190.3c0 -5 5.2 -8.8 10 -7.5c3.9 1 4.6 4.9 4.6 8.3c0 5.1 0 10.2 0 15.3c0 0.9 0 1.9 0 2.8c0 0.6 -0.1 0.5 0.4 0.7c1.1 0.3 2.8 0 3.9 0c0.4 0 1.9 0.2 2.1 0c0.2 -0.2 0 -1.4 0 -1.7c0 -1.2 0 -2.4 0 -3.5c0 -3 0 -5.9 0 -8.9c0 -1.7 0 -3.5 0 -5.2c0.1 -4.7 3.8 -7.9 8.4 -7.8c7.3 0.1 6.2 8.6 6.2 13.8c0 2.9 0 5.8 0 8.7c0 1.1 0 2.3 0 3.4c0 0.2 -0.1 1.1 0 1.2c0.3 0.3 2.5 0 2.9 0c0.7 0 1.4 0 2.1 0c0.2 0 1.1 0.1 1.3 0c0.4 -0.4 0.1 -3.4 0.1 -4c0 -5 0 -10.1 0 -15.1c0 -3.7 -0.4 -8 -3 -10.9c-3.5 -4 -9.4 -3.6 -13.7 -1.4c-2.3 1.2 -4.1 3 -5.4 5.1c-1.4 -4.2 -4.9 -6.6 -9.2 -6.8c-3.9 -0.2 -9.1 2 -11 5.7c0 -1.3 0 -2.6 0 -3.9s0.2 -1.3 -1.1 -1.3c-1.6 0 -3.1 0 -4.7 0c-0.7 0 -0.5 -0.1 -0.7 0.4c-0.2 0.6 0 1.5 0 2.2c0 1.2 0 2.3 0 3.5c0 3.2 0 6.5 0 9.7c0 5.4 0 10.7 0 16.1c0 0.3 -0.1 0.6 0.1 0.7c0.3 0.2 1.3 0 1.6 0c0.8 0 1.7 0 2.5 0c0.5 0 1.9 0.2 2.1 -0.1c0.3 -0.4 0 -1.9 0 -2.4c0 -3.6 0 -7.1 0 -10.7c0 -1.5 0 -3 0 -4.6c0.2 -0.6 -0.1 -1.9 0.5 -1.8zM410.6 190.7c-0.4 -6.8 -5.4 -12.7 -12.2 -13.9c-6.9 -1.2 -13.9 2.1 -17.2 8.3c-3.3 6.1 -2.7 14.4 2 19.7c4.5 5.1 11.7 6.6 18.1 4.9c1.9 -0.5 3.8 -1.3 5.5 -2.4c0.6 -0.4 1.7 -1 2.1 -1.6c0.4 -0.7 0.3 0 0.1 -0.6c-0.3 -0.8 -1.2 -1.7 -1.7 -2.4c-0.4 -0.6 -0.9 -1.2 -1.3 -1.8c-2.3 2 -4.9 3.5 -8.1 3.7c-2.9 0.2 -6 -0.4 -8.4 -2.2c-4.6 -3.5 -5.3 -11.8 -1.9 -16.4c3.4 -4.5 11.3 -4.5 14.8 -0.1c0.5 0.7 2.3 3.8 1.3 4.3c-0.7 0.3 -2.3 0 -3.1 0c-3.4 0 -6.8 0 -10.3 0c-1.2 0 -2.5 0 -3.7 0c-1 0 -0.9 0 -1.1 1.2c-0.1 0.5 -0.4 3.6 0.1 3.9c0.4 0.3 1.8 0 2.3 0c3.1 0 6.3 0 9.4 0c3.6 0 7.2 0 10.7 0c0.4 0 2 0.2 2.2 0c0.5 -0.4 0.4 -4.1 0.4 -4.6zM816.1 190.7c-0.4 -6.8 -5.4 -12.7 -12.2 -13.9c-6.9 -1.2 -13.9 2.1 -17.2 8.3c-3.3 6.1 -2.7 14.4 2 19.7c4.5 5.1 11.6 6.6 18.1 4.9c1.9 -0.5 3.8 -1.3 5.5 -2.4c0.6 -0.4 1.7 -1 2.1 -1.6c0.4 -0.7 0.3 0 0.1 -0.6c-0.3 -0.8 -1.2 -1.7 -1.7 -2.4c-0.4 -0.6 -0.9 -1.2 -1.3 -1.8c-3.2 2.8 -7 4.2 -11.3 3.6c-4.2 -0.6 -7.6 -3.3 -8.7 -7.5c-0.9 -3.5 -0.6 -8.3 1.8 -11.2c2.3 -2.9 6.9 -3.9 10.4 -2.9c2 0.6 3.9 2 4.9 3.8c0.5 1 0.5 2 0.9 3c0.1 0.2 -0.1 0.3 0.1 0.4c0.1 0.1 0.6 0 0.8 0c-3.4 0 -6.9 0 -10.3 0c-2.2 0 -4.4 0 -6.6 0c-0.5 0 -1.3 -0.2 -1.8 0s-0.4 0.5 -0.5 1.1c-0.1 0.8 -0.5 2.9 -0.1 3.7c0.2 0.4 0 0.2 0.5 0.3c1.4 0.3 3 0 4.4 0c4.7 0 9.5 0 14.2 0c1.6 0 3.6 0.3 5.1 0c0.6 -0.1 0.4 0.2 0.5 -0.6c0.1 -0.6 0 -1.2 0.1 -1.8c0.1 -0.7 0.3 -1.4 0.2 -2.1zM944.1 223c8.9 2.7 19.9 0.4 22.8 -9.5c1.1 -3.7 0.8 -7.6 0.8 -11.4c0 -5.1 0 -10.2 0 -15.2c0 -2.1 0 -4.3 0 -6.4c0 -0.5 0.3 -2.7 0 -3.1c-0.2 -0.2 -1.5 0 -1.9 0c-1.3 0 -2.7 -0.1 -4 0c-0.2 0 -0.5 -0.1 -0.6 0.1c-0.2 0.2 0 1.2 0 1.4c0 0.5 -0.3 2.7 0.1 2.9c-0.8 -0.6 -1.5 -1.5 -2.3 -2.1c-1.1 -0.8 -2.2 -1.5 -3.5 -2c-2.4 -1 -5.1 -1.3 -7.7 -0.9c-5.1 0.8 -9.3 4 -11.7 8.5c-4.8 9.1 -0.3 22.1 10.1 24.7c2.8 0.7 5.7 0.7 8.5 -0.3c2.4 -0.8 5.3 -2.5 6.5 -4.9c-0.2 0.3 0 1.3 0 1.7c0 0.7 0 1.5 0 2.2c0 2.7 -0.6 5.4 -2.7 7.3c-4.4 4.2 -13.4 3 -17.8 -0.6c-0.7 1.4 -1.3 2.7 -2 4.1c-0.5 1 -0.5 0.9 0.6 1.5c1.6 0.8 3.2 1.5 4.8 2zM600.4 209.8c0.6 0 1.2 0 1.8 0c0.6 0 2.4 0.3 2.9 0c0.3 -0.3 0.1 -1.9 0.1 -2.4c0 -4.3 0 -8.5 0 -12.8c0 -3.8 -0.5 -7.6 2.9 -10.2c2.6 -2.1 7.4 -2.9 10.3 -0.8c2.2 1.6 2.3 4.8 2.3 7.2c0 3.7 0 7.4 0 11c0 1.9 0 3.9 0 5.8c0 0.5 -0.2 2 0.1 2.2c0.4 0.3 1.9 0 2.4 0c1.1 0 2.1 0 3.2 0c1 0 0.7 -0.5 0.7 -1.5c0 -4 0 -8.1 0 -12.1c0 -4.3 0.6 -9.4 -1 -13.4c-3.5 -8.9 -15.9 -7.6 -20.8 -0.5c-0.1 -5.1 0 -10.2 0 -15.3c0 -0.7 0.3 -2.1 0 -2.8c-0.2 -0.5 -1.1 -0.3 -1.7 -0.3c-0.8 0 -1.5 0 -2.3 0c-0.6 0 -1.5 -0.2 -2 0s-0.2 -0.1 -0.4 0.4c-0.3 1.4 0 3.3 0 4.7c0 2.8 0 5.5 0 8.3c0 6.7 0 13.4 0 20c0 4.1 0 8.2 0 12.4c0.5 0.1 1 0.1 1.5 0.1zM444.1 209.8c0.6 0 1.3 0 1.9 0c0.5 0 2.3 0.3 2.8 0c0.3 -0.3 0.1 -1.9 0.1 -2.4c0 -4.3 0 -8.5 0 -12.8c0 -3.9 -0.4 -7.9 3.3 -10.5c2.7 -1.9 7.6 -2.6 10.2 -0.3c1.9 1.7 2 4.7 2 7.1c0 3.7 0 7.5 0 11.2c0 2 0 4 0 6c0 0.4 -0.2 1.2 0 1.5c0.2 0.4 -0.1 0.1 0.4 0.3c0.9 0.2 2 0 2.9 0c0.7 0 2.1 0.3 2.8 0c0.4 -0.2 0.1 0.1 0.3 -0.3c0.1 -0.4 0 -1.2 0 -1.6c0 -4.2 0 -8.4 0 -12.6c0 -3.7 0.4 -7.9 -0.7 -11.5c-1.1 -3.7 -3.6 -6.2 -7.4 -7c-4.1 -0.9 -8.2 0.4 -11.4 3c-0.8 0.6 -1.7 1.5 -2.2 2.4c0.2 -0.4 0 -1.4 0 -1.8c0 -0.8 0.3 -2.2 0 -2.9c-0.2 -0.4 0 -0.3 -0.7 -0.3c-1 0 -2 0 -2.9 0c-0.6 0 -2.5 -0.3 -2.8 0.2c-0.3 0.4 0 1.9 0 2.4c0 7.7 0 15.4 0 23.1c0 2.3 0 4.6 0 6.9c0.4 -0.1 0.9 -0.1 1.4 -0.1zM901.2 209.8c0.6 0 1.2 0 1.8 0c0.6 0 2.4 0.3 2.9 0c0.3 -0.3 0.1 -1.9 0.1 -2.4c0 -4.3 0 -8.5 0 -12.8c0 -4 -0.4 -7.9 3.3 -10.5c2.6 -1.8 7.2 -2.5 9.9 -0.5c2.2 1.6 2.3 4.8 2.3 7.2c0 3.7 0 7.4 0 11c0 2 0 4 0 6c0 0.6 -0.2 1.8 0.2 2.1c0.5 0.3 2 0 2.6 0c1 0 2.1 0.2 3.1 0c0.5 -0.1 0.3 0.1 0.5 -0.2c0.2 -0.2 0 -1.1 0 -1.3c0 -4.1 0 -8.3 0 -12.4c0 -4.4 0.5 -9.4 -1.2 -13.5c-1.8 -4.3 -5.9 -6.1 -10.4 -5.9c-4.2 0.2 -8.1 2.6 -10.4 6.1c0.7 -1.1 0.2 -3.4 0.2 -4.6c0 -0.6 0.1 -0.6 -0.2 -0.8c-0.5 -0.3 -2 0 -2.6 0s-3.3 -0.3 -3.6 0.1c-0.2 0.3 0 1.7 0 2.2c0 7.7 0 15.4 0 23.1c0 2.4 0 4.8 0 7.1c0.5 0 1 0 1.5 0zM366.1 181.3c-7.4 -7.4 -19.8 -5.6 -24.4 4c-4.2 8.8 -0.9 21.6 9.2 24.5c5.4 1.6 11.5 0.1 15.1 -4.4c0 1.1 0 2.3 0 3.4s-0.2 1.1 1 1.1c1.4 0 2.8 0 4.2 0c0.3 0 1.1 0.1 1.3 -0.1c0.4 -0.5 0 -2.6 0 -3.2c0 -2.2 0 -4.3 0 -6.5c0 -11 0 -22 0 -32.9c0 -0.5 0.3 -2.9 0 -3.2c-0.3 -0.3 -2.4 0 -2.8 0c-1.2 0 -2.4 0 -3.6 0c-0.1 5.7 0 11.9 0 17.3zM503.1 205.6c2.8 3.5 7.9 5.1 12.2 4.7c5 -0.5 9.2 -3.7 11.5 -8.1c4.6 -8.7 1.3 -21.9 -8.9 -24.8c-5.1 -1.4 -11.8 0 -14.9 4.6c0.1 -0.2 0 -0.7 0 -0.9c0 -0.8 0 -1.6 0 -2.4c0 -1.2 0.2 -1.2 -1 -1.2c-1.4 0 -2.8 0 -4.2 0c-0.4 0 -1.1 -0.1 -1.3 0.1c-0.4 0.5 0 2.6 0 3.1c0 2.2 0 4.4 0 6.6c0 11 0 22 0 33c0 0.5 -0.3 2.8 0 3.2c0.3 0.3 2.4 0 2.8 0c1.2 0 2.4 0 3.6 0c0 -3.1 0 -6.2 0 -9.3c0 -2.1 0 -4.1 0 -6.2c0.2 -0.5 0.4 -2.2 0.2 -2.4zM660.1 206.3c3.2 3.2 8.2 4.6 12.7 3.8c4.8 -0.9 8.8 -4.4 10.8 -8.9c3.9 -8.8 0.5 -21.3 -9.5 -24c-4.9 -1.3 -11.6 0.1 -14.6 4.7c0.2 -0.3 0 -1.4 0 -1.7c0 -0.5 0.3 -2.1 0 -2.6s-2.7 -0.2 -3.3 -0.2c-0.5 0 -2.8 -0.3 -3.1 0.1c-0.1 0.2 0 1.2 0 1.4c0 6.1 0 12.3 0 18.4c0 7.2 0 14.4 0 21.5c0 1.1 0 2.1 0 3.2c0 0.3 -0.2 1.2 0 1.5c0.3 0.3 2.3 0.1 2.8 0.1c0.6 0 3.2 0.4 3.6 0c0.3 -0.3 0 -2.8 0 -3.2c0 -2.1 0 -4.2 0 -6.3c0 -2 0 -4.1 0 -6.1c0 -0.6 -0.2 -1.7 0 -2.3c-0.2 0 0.6 0.6 0.6 0.6zM826.6 209c4.2 1.7 9.5 2.1 13.6 0c4.4 -2.2 6.3 -6.5 5.1 -11.2c-1.1 -4.5 -6.2 -6.1 -10.1 -7.2c-1.7 -0.5 -3.7 -0.9 -5.2 -1.9c-1.8 -1.2 -2.4 -4.1 -0.5 -5.5c3.8 -3 9.6 -0.2 12.6 2.8c0.9 -1 1.8 -2 2.7 -3c0.2 -0.2 0.9 -0.8 0.9 -1c0.1 -0.7 -2.3 -2.2 -2.8 -2.6c-5 -3.3 -12.6 -3.8 -17.4 0c-5 3.8 -4.2 11.2 1 14.4c2.6 1.6 5.4 2.2 8.3 3c2 0.6 5 1.4 5.3 3.9c0.4 3.2 -2.9 4.7 -5.6 4.7c-3.3 -0.1 -6.6 -1.3 -8.5 -4.1c-1.2 1.1 -2.4 2.1 -3.7 3.2c-0.1 0.1 -0.6 0.4 -0.6 0.5c-0.1 0.3 0.7 1 0.9 1.3c1 1.1 2.4 2.1 4 2.7zM856.2 209c4.2 1.7 9.5 2.1 13.6 0c4.4 -2.2 6.3 -6.5 5.1 -11.2c-1.1 -4.5 -6.2 -6.1 -10.1 -7.2c-1.7 -0.5 -3.7 -0.9 -5.2 -1.9c-1.8 -1.2 -2.4 -4.1 -0.5 -5.5c3.8 -3 9.6 -0.2 12.6 2.8c0.9 -1 1.8 -2 2.7 -3c0.2 -0.2 0.9 -0.8 0.9 -1c0.1 -0.7 -2.3 -2.2 -2.8 -2.6c-5 -3.3 -12.6 -3.8 -17.4 0c-5 3.8 -4.2 11.2 1 14.4c2.6 1.6 5.4 2.2 8.3 3c2 0.6 5 1.4 5.3 3.9c0.4 3.2 -2.9 4.7 -5.6 4.7c-3.3 -0.1 -6.6 -1.3 -8.5 -4.1c-1.2 1.1 -2.4 2.1 -3.7 3.2c-0.1 0.1 -0.6 0.4 -0.6 0.5c-0.1 0.3 0.7 1 0.9 1.3c1 1.1 2.4 2.1 4 2.7zM778.7 180.6c-4.4 -4 -11.7 -5 -17.1 -2.8c-5.6 2.3 -9 7.9 -9.7 13.8c-0.7 6.2 1.8 12.5 6.9 16.2s11.8 3.4 17.2 0.6c1.5 -0.8 2.9 -1.8 4 -3.1c0.8 -1 0.9 -0.9 0.2 -1.8c-1 -1.2 -1.9 -2.4 -2.9 -3.5c-2.6 3.9 -7.6 6 -12.1 4.5c-4.4 -1.5 -7.1 -5.9 -7.3 -10.4c-0.1 -4.4 2.2 -9.2 6.6 -10.7c4.8 -1.7 9.9 0.4 12.8 4.5c0.8 -1 1.6 -2 2.4 -3c0.2 -0.3 1 -0.9 1 -1.3c0.2 -0.9 -1.5 -2.5 -2 -3zM545.4 177c-10.4 2.6 -14.1 15.8 -9.7 24.7c2.1 4.3 5.8 7.8 10.6 8.6c5 0.8 10.5 -1.2 13.6 -5.3c0 1 -0.5 4.4 0.2 4.8s2.6 0 3.4 0c0.5 0 2.4 0.3 2.8 0c0.2 -0.2 0 -1.5 0 -1.8c0 -1.7 0 -3.3 0 -5c0 -4.7 0 -9.4 0 -14.1c0 -3.5 0 -7.1 0 -10.6c0 -1 0.1 -1 -1 -1c-1.8 0 -3.6 0 -5.4 0c0 1 0 1.9 0 2.9c0 0.5 -0.2 2.1 0 2.3c-3 -5 -9.1 -6.8 -14.5 -5.5zM424 191.9c0 -6 6.2 -10 11.7 -7.8c0.3 -1.1 0.5 -2.2 0.8 -3.3c0.2 -0.8 0.4 -1.6 0.6 -2.5c0.1 -0.2 0.4 -0.9 0.3 -1.1c-0.2 -0.4 -2.4 -0.6 -2.8 -0.6c-1.5 -0.1 -3.1 0.2 -4.5 0.8c-2.7 1.1 -5.2 3.4 -6.3 6.1c0.3 -0.8 0.1 -2.1 0.1 -3c0 -0.5 0.3 -3 0 -3.3c-0.1 -0.1 -1.1 0 -1.3 0c-0.8 0 -1.6 0 -2.3 0c-0.5 0 -2.5 -0.3 -2.8 0c-0.1 0.1 0 1.1 0 1.3c0 1 0 2 0 2.9c0 2.9 0 5.9 0 8.8c0 5.9 0 11.8 0 17.6c0 0.3 -0.2 1.3 0 1.6c0.2 0.3 1.2 0.2 1.6 0.2c0.8 0 1.5 0 2.3 0c0.6 0 1.6 0.2 2.2 0c0.5 -0.2 0.4 -0.2 0.4 -0.9c-0.1 -5.5 0 -11.2 0 -16.8zM698.4 191.9c0 -6 6.2 -10 11.7 -7.8c0.3 -1.1 0.5 -2.2 0.8 -3.3c0.2 -0.8 0.4 -1.6 0.6 -2.5c0.1 -0.2 0.4 -0.9 0.3 -1.1c-0.2 -0.4 -2.4 -0.6 -2.8 -0.6c-1.5 -0.1 -3.1 0.2 -4.5 0.8c-2.7 1.1 -5.1 3.5 -6.3 6.2c0.4 -0.8 0.1 -2.1 0.1 -3c0 -0.5 0.3 -3 0 -3.3c-0.1 -0.1 -1.1 0 -1.3 0c-0.8 0 -1.6 0 -2.4 0c-0.4 0 -2.3 -0.3 -2.6 0c-0.2 0.2 0 1.2 0 1.4c0 1 0 1.9 0 2.9c0 3 0 6 0 9c0 5.8 0 11.6 0 17.4c0 0.3 -0.2 1.4 0 1.7c0.2 0.3 1.3 0.1 1.7 0.1c0.8 0 1.5 0 2.3 0c0.6 0 1.5 0.2 2 0s0.4 -0.2 0.4 -1c0 -5.6 0 -11.3 0 -16.9zM313.4 209.7c6.6 2 14.1 -0.1 18.4 -5.6c4.3 -5.7 4.5 -14.1 0.7 -20c-3.8 -6 -11.1 -8.5 -17.9 -7c-6.8 1.5 -11.7 7.6 -12.4 14.4c-0.4 4 0.4 8.1 2.6 11.5c1.8 2.9 5.1 5.8 8.6 6.7zM725 209.7c6.6 1.9 14 0 18.2 -5.5c4.5 -5.7 4.6 -14.2 0.8 -20.2c-3.8 -5.9 -10.9 -8.5 -17.7 -7c-6.8 1.4 -11.7 7.2 -12.6 14c-0.9 7.7 3.4 16.5 11.3 18.7zM1026.9 209.7c6.6 2 14.1 -0.1 18.4 -5.6c4.3 -5.7 4.5 -14.1 0.7 -20c-3.8 -6 -11.1 -8.5 -17.9 -7c-6.8 1.5 -11.7 7.6 -12.4 14.4c-0.4 4 0.4 8.1 2.6 11.5c1.8 2.9 5.1 5.8 8.6 6.7zM1065 209.7c6.6 2 14.1 -0.1 18.4 -5.6c4.3 -5.7 4.5 -14.1 0.7 -20c-3.8 -6 -11.1 -8.5 -17.9 -7c-6.8 1.5 -11.7 7.6 -12.4 14.4c-0.4 4 0.4 8.1 2.6 11.5c1.8 2.9 5.1 5.8 8.6 6.7zM1100.1 164c-1.9 0 -3.8 0 -5.6 0c-0.9 0 -0.8 0 -0.8 0.9c0 3.1 0 6.1 0 9.2c0 9.5 0 19.1 0 28.6c0 1.6 0 3.2 0 4.8c0 0.4 -0.3 1.9 0 2.3c0.4 0.5 3.3 0.1 4 0.1c0.3 0 2.2 0.2 2.4 0c0.1 -0.1 0 -0.3 0 -0.4c0.3 -0.8 0 -2.1 0 -2.9c0 -1.7 0 -3.5 0 -5.2c0 -4.7 0 -9.5 0 -14.2c0 -7.5 0 -15.1 0 -22.6c0 -0.3 0 -0.5 0 -0.6zM585.4 169c-0.8 0 -1.7 0 -2.5 0c-1 0 -2.5 -0.3 -3.5 0c-0.6 0.2 -0.4 0.1 -0.4 0.9c0 1.2 0 2.5 0 3.7c0 1 0.2 2.2 0 3.3c-0.1 0.6 0 0.5 -0.8 0.5c-1.3 0 -2.5 0 -3.8 0c-0.3 0 -1.9 -0.2 -2.2 0c-0.3 0.3 0 2.6 0 3.1c0 1 0 2.1 0 3.1c2.3 0 4.5 0 6.8 0c0 4.3 0 8.7 0 13c0 3 0 6 0 9c0 1 0 2 0 3c0 0.2 -0.1 1.1 0 1.3c0.2 0.3 2.4 0 2.8 0c0.7 0 1.5 0 2.2 0c0.2 0 1.2 0.1 1.4 0c0.1 -0.1 0 -0.8 0 -0.9c0 -0.9 0 -1.9 0 -2.8c0 -6 0 -11.9 0 -17.9c0 -1.2 0 -2.4 0 -3.5c0 -0.2 -0.1 -1.1 0 -1.2c0.2 -0.1 1.1 0 1.3 0c0.9 0 1.7 0 2.6 0c1.2 0 2.4 0 3.6 0c0 -0.9 0 -1.7 0 -2.6c0 -0.7 0 -1.4 0 -2.1c0 -0.3 0.1 -1.1 0 -1.3c-0.2 -0.4 -0.7 -0.2 -1.3 -0.2c-1.3 0 -2.6 0 -3.9 0c-0.3 0 -2.1 0.2 -2.3 0c-0.2 -0.2 0 -1.8 0 -2.1c0 -2.2 0 -4.3 0 -6.3zM889.8 177.3c-1.4 0 -2.8 0 -4.1 0c-0.5 0 -2 -0.2 -2.3 0.1c-0.2 0.3 0 1.6 0 2c0 1.2 0 2.5 0 3.7c0 7.1 0 14.1 0 21.2c0 1.2 0 2.5 0 3.7c0 0.3 -0.2 1.5 0 1.8s2.2 0.1 2.7 0.1c0.8 0 1.7 0 2.5 0c0.1 0 1.2 0.1 1.3 0c0.1 -0.2 0 -1.1 0 -1.3c0 -1.1 0 -2.3 0 -3.4c0 -3.4 0 -6.9 0 -10.3c-0.1 -5.9 -0.1 -11.8 -0.1 -17.6zM951.3 204.6c-5.3 0 -9.6 -4.3 -10.2 -9.4c-0.5 -4.4 1 -8.9 4.9 -11.4c3.7 -2.4 9.2 -1.6 12.4 1.3c3.3 3 4.1 8.1 2.8 12.3c-1.4 4.3 -5.3 7.2 -9.9 7.2zM356.5 205c-5.4 0 -9.1 -4.5 -9.8 -9.6c-0.6 -4.3 0.7 -9.2 4.4 -11.8c3.6 -2.5 8.9 -2.1 11.9 1.1c6 6.4 3.7 20.3 -6.5 20.3zM322 204.1c-2.7 1 -5.3 1 -7.9 -0.2c-2 -1 -3.7 -2.8 -4.6 -4.9c-1.7 -3.9 -1.5 -9.2 1.2 -12.6c2.7 -3.5 7.4 -4.8 11.5 -3.2c8.5 3.2 8.7 17.9 -0.2 20.9zM733.6 204.1c-2.7 1 -5.3 1 -7.9 -0.2c-2 -1 -3.7 -2.8 -4.6 -4.9c-1.7 -3.9 -1.5 -9.2 1.2 -12.6c2.7 -3.5 7.4 -4.8 11.5 -3.2c8.5 3.2 8.7 17.9 -0.2 20.9zM1035.5 204.1c-2.7 1 -5.3 1 -7.9 -0.2c-2 -1 -3.7 -2.8 -4.6 -4.9c-1.7 -3.9 -1.5 -9.2 1.2 -12.6c2.7 -3.5 7.4 -4.8 11.5 -3.2c8.5 3.2 8.7 17.9 -0.2 20.9zM1073.6 204.1c-2.7 1 -5.3 1 -7.9 -0.2c-2 -1 -3.7 -2.8 -4.6 -4.9c-1.7 -3.9 -1.5 -9.2 1.2 -12.6c2.7 -3.5 7.4 -4.8 11.5 -3.2c8.5 3.2 8.7 17.9 -0.2 20.9zM559.9 195.4c-0.7 5.1 -4.5 9.2 -9.9 9.2c-9.7 0 -12.9 -13.1 -6.6 -19.4c3 -3 8.2 -3.5 11.8 -1.2c3.7 2.4 5.3 7.1 4.7 11.4zM512.8 204.5c-2.5 0 -4.7 -0.6 -6.6 -2.4c-1.8 -1.6 -2.8 -3.9 -3.3 -6.2c-0.8 -4.3 0.6 -8.9 4.2 -11.5c3.7 -2.7 9.1 -2.3 12.4 0.9c6.2 6.1 2.8 19.2 -6.7 19.2zM669 204.5c-2.5 0 -4.7 -0.6 -6.6 -2.4c-1.8 -1.6 -2.8 -3.9 -3.3 -6.2c-0.8 -4.3 0.6 -8.9 4.2 -11.5c3.7 -2.7 9.1 -2.3 12.4 0.9c6.2 6.1 2.8 19.2 -6.7 19.2zM887.9 170c2.5 -0.4 3.5 -3.5 2.7 -5.6s-3.3 -2.7 -5.3 -2.2c-2.4 0.5 -3.6 3.4 -2.7 5.6c0.8 2.1 3.3 2.6 5.3 2.2zM1004.5 169c-0.8 0 -1.7 0 -2.5 0c-1 0 -2.5 -0.3 -3.5 0c-0.6 0.2 -0.4 0.1 -0.4 0.9c0 1.2 0 2.5 0 3.7c0 1 0.2 2.2 0 3.3c-0.1 0.6 0 0.5 -0.8 0.5c-1.3 0 -2.5 0 -3.8 0c-0.3 0 -1.9 -0.2 -2.2 0c-0.3 0.3 0 2.6 0 3.1c0 1 0 2.1 0 3.1c2.3 0 4.5 0 6.8 0c0 4.3 0 8.7 0 13c0 3 0 6 0 9c0 1 0 2 0 3c0 0.2 -0.1 1.1 0 1.3c0.2 0.3 2.4 0 2.8 0c0.7 0 1.5 0 2.2 0c0.2 0 1.2 0.1 1.4 0c0.1 -0.1 0 -0.8 0 -0.9c0 -0.9 0 -1.9 0 -2.8c0 -6 0 -11.9 0 -17.9c0 -1.2 0 -2.4 0 -3.5c0 -0.2 -0.1 -1.1 0 -1.2c0.2 -0.1 1.1 0 1.3 0c0.9 0 1.7 0 2.6 0c1.2 0 2.4 0 3.6 0c0 -0.9 0 -1.7 0 -2.6c0 -0.7 0 -1.4 0 -2.1c0 -0.3 0.1 -1.1 0 -1.3c-0.2 -0.4 -0.7 -0.2 -1.3 -0.2c-1.3 0 -2.6 0 -3.9 0c-0.3 0 -2.1 0.2 -2.3 0c-0.2 -0.2 0 -1.8 0 -2.1c0 -2.2 0 -4.2 0 -6.3z"/>
21
- </svg>
22
- </a></h1>
23
-
24
- <div class="row row-lg">
25
- <div class="col col-md-4 mx-auto">
26
- <div class="text-center">
27
- <svg id="test-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
28
- <path d="M0 0L0 0" fill="rgba(255,0,255,0.75)"></path>
29
- </svg>
30
- </div>
31
- </div>
32
- </div>
33
-
34
- </body>
35
-
36
- </html>
@@ -1,114 +0,0 @@
1
- import type { MSegment, PathArray } from '../types';
2
- import type { LengthFactory } from '../interface';
3
- import normalizePath from '../process/normalizePath';
4
- import segmentLineFactory from './segmentLineFactory';
5
- import segmentArcFactory from './segmentArcFactory';
6
- import segmentCubicFactory from './segmentCubicFactory';
7
- import segmentQuadFactory from './segmentQuadFactory';
8
-
9
- /**
10
- * Returns a {x,y} point at a given length
11
- * of a shape, the shape total length and
12
- * the shape minimum and maximum {x,y} coordinates.
13
- *
14
- * @param pathInput the `pathArray` to look into
15
- * @param distance the length of the shape to look at
16
- * @returns the path length, point, min & max
17
- */
18
- const pathLengthFactory = (pathInput: string | PathArray, distance?: number): LengthFactory => {
19
- const path = normalizePath(pathInput);
20
- const distanceIsNumber = typeof distance === 'number';
21
- let isM;
22
- let data = [] as number[];
23
- let pathCommand;
24
- let x = 0;
25
- let y = 0;
26
- let mx = 0;
27
- let my = 0;
28
- let seg;
29
- let MIN = [] as { x: number; y: number }[];
30
- let MAX = [] as { x: number; y: number }[];
31
- let length = 0;
32
- let min = { x: 0, y: 0 };
33
- let max = min;
34
- let point = min;
35
- let POINT = min;
36
- let LENGTH = 0;
37
-
38
- for (let i = 0, ll = path.length; i < ll; i += 1) {
39
- seg = path[i];
40
- [pathCommand] = seg;
41
- isM = pathCommand === 'M';
42
- data = !isM ? [x, y, ...(seg.slice(1) as number[])] : data;
43
-
44
- // this segment is always ZERO
45
- /* istanbul ignore else */
46
- if (isM) {
47
- // remember mx, my for Z
48
- [, mx, my] = seg as MSegment;
49
- min = { x: mx, y: my };
50
- max = min;
51
- length = 0;
52
-
53
- if (distanceIsNumber && distance < 0.001) {
54
- POINT = min;
55
- }
56
- } else if (pathCommand === 'L') {
57
- ({ length, min, max, point } = segmentLineFactory(
58
- ...(data as [number, number, number, number]),
59
- (distance || 0) - LENGTH,
60
- ));
61
- } else if (pathCommand === 'A') {
62
- ({ length, min, max, point } = segmentArcFactory(
63
- ...(data as [number, number, number, number, number, number, number, number, number]),
64
- (distance || 0) - LENGTH,
65
- ));
66
- } else if (pathCommand === 'C') {
67
- ({ length, min, max, point } = segmentCubicFactory(
68
- ...(data as [number, number, number, number, number, number, number]),
69
- (distance || 0) - LENGTH,
70
- ));
71
- } else if (pathCommand === 'Q') {
72
- ({ length, min, max, point } = segmentQuadFactory(
73
- ...(data as [number, number, number, number, number, number]),
74
- (distance || 0) - LENGTH,
75
- ));
76
- } else if (pathCommand === 'Z') {
77
- data = [x, y, mx, my];
78
- ({ length, min, max, point } = segmentLineFactory(
79
- ...(data as [number, number, number, number]),
80
- (distance || 0) - LENGTH,
81
- ));
82
- }
83
-
84
- if (distanceIsNumber && LENGTH < distance && LENGTH + length >= distance) {
85
- POINT = point;
86
- }
87
-
88
- MAX = [...MAX, max];
89
- MIN = [...MIN, min];
90
- LENGTH += length;
91
-
92
- [x, y] = pathCommand !== 'Z' ? (seg.slice(-2) as [number, number]) : [mx, my];
93
- }
94
-
95
- // native `getPointAtLength` behavior when the given distance
96
- // is higher than total length
97
- if (distanceIsNumber && distance >= LENGTH) {
98
- POINT = { x, y };
99
- }
100
-
101
- return {
102
- length: LENGTH,
103
- point: POINT,
104
- min: {
105
- x: Math.min(...MIN.map(n => n.x)),
106
- y: Math.min(...MIN.map(n => n.y)),
107
- },
108
- max: {
109
- x: Math.max(...MAX.map(n => n.x)),
110
- y: Math.max(...MAX.map(n => n.y)),
111
- },
112
- };
113
- };
114
- export default pathLengthFactory;
@@ -1,219 +0,0 @@
1
- import type { LengthFactory } from '../interface';
2
- import segmentLineFactory from './segmentLineFactory';
3
- import distanceSquareRoot from '../math/distanceSquareRoot';
4
-
5
- /**
6
- * Returns an angle value between two points.
7
- *
8
- * @param v0
9
- * @param v1
10
- * @returns a number representing an angle
11
- */
12
- const angleBetween = (v0: { x: number; y: number }, v1: { x: number; y: number }): number => {
13
- const { x: v0x, y: v0y } = v0;
14
- const { x: v1x, y: v1y } = v1;
15
- const p = v0x * v1x + v0y * v1y;
16
- const n = Math.sqrt((v0x ** 2 + v0y ** 2) * (v1x ** 2 + v1y ** 2));
17
- const sign = v0x * v1y - v0y * v1x < 0 ? -1 : 1;
18
- const angle = sign * Math.acos(p / n);
19
-
20
- return angle;
21
- };
22
-
23
- /**
24
- * Returns a {x,y} point at a given length, the total length and
25
- * the minimum and maximum {x,y} coordinates of a C (cubic-bezier) segment.
26
- *
27
- * @see https://github.com/MadLittleMods/svg-curve-lib/blob/master/src/js/svg-curve-lib.js
28
- *
29
- * @param x1 the starting x position
30
- * @param y1 the starting y position
31
- * @param RX x-radius of the arc
32
- * @param RY y-radius of the arc
33
- * @param angle x-axis-rotation of the arc
34
- * @param LAF large-arc-flag of the arc
35
- * @param SF sweep-flag of the arc
36
- * @param x the ending x position
37
- * @param y the ending y position
38
- * @param t the point distance
39
- * @returns the requested point
40
- */
41
- const getPointAtArcSegmentLength = (
42
- x1: number,
43
- y1: number,
44
- RX: number,
45
- RY: number,
46
- angle: number,
47
- LAF: number,
48
- SF: number,
49
- x: number,
50
- y: number,
51
- t: number,
52
- ): { x: number; y: number } => {
53
- const { abs, sin, cos, sqrt, PI } = Math;
54
- let rx = abs(RX);
55
- let ry = abs(RY);
56
- const xRot = ((angle % 360) + 360) % 360;
57
- const xRotRad = xRot * (PI / 180);
58
-
59
- if (x1 === x && y1 === y) {
60
- return { x: x1, y: y1 };
61
- }
62
-
63
- if (rx === 0 || ry === 0) {
64
- return segmentLineFactory(x1, y1, x, y, t).point;
65
- }
66
-
67
- const dx = (x1 - x) / 2;
68
- const dy = (y1 - y) / 2;
69
-
70
- const transformedPoint = {
71
- x: cos(xRotRad) * dx + sin(xRotRad) * dy,
72
- y: -sin(xRotRad) * dx + cos(xRotRad) * dy,
73
- };
74
-
75
- const radiiCheck = transformedPoint.x ** 2 / rx ** 2 + transformedPoint.y ** 2 / ry ** 2;
76
-
77
- if (radiiCheck > 1) {
78
- rx *= sqrt(radiiCheck);
79
- ry *= sqrt(radiiCheck);
80
- }
81
-
82
- const cSquareNumerator = rx ** 2 * ry ** 2 - rx ** 2 * transformedPoint.y ** 2 - ry ** 2 * transformedPoint.x ** 2;
83
-
84
- const cSquareRootDenom = rx ** 2 * transformedPoint.y ** 2 + ry ** 2 * transformedPoint.x ** 2;
85
-
86
- let cRadicand = cSquareNumerator / cSquareRootDenom;
87
- cRadicand = cRadicand < 0 ? 0 : cRadicand;
88
- const cCoef = (LAF !== SF ? 1 : -1) * sqrt(cRadicand);
89
- const transformedCenter = {
90
- x: cCoef * ((rx * transformedPoint.y) / ry),
91
- y: cCoef * (-(ry * transformedPoint.x) / rx),
92
- };
93
-
94
- const center = {
95
- x: cos(xRotRad) * transformedCenter.x - sin(xRotRad) * transformedCenter.y + (x1 + x) / 2,
96
- y: sin(xRotRad) * transformedCenter.x + cos(xRotRad) * transformedCenter.y + (y1 + y) / 2,
97
- };
98
-
99
- const startVector = {
100
- x: (transformedPoint.x - transformedCenter.x) / rx,
101
- y: (transformedPoint.y - transformedCenter.y) / ry,
102
- };
103
-
104
- const startAngle = angleBetween({ x: 1, y: 0 }, startVector);
105
-
106
- const endVector = {
107
- x: (-transformedPoint.x - transformedCenter.x) / rx,
108
- y: (-transformedPoint.y - transformedCenter.y) / ry,
109
- };
110
-
111
- let sweepAngle = angleBetween(startVector, endVector);
112
- if (!SF && sweepAngle > 0) {
113
- sweepAngle -= 2 * PI;
114
- } else if (SF && sweepAngle < 0) {
115
- sweepAngle += 2 * PI;
116
- }
117
- sweepAngle %= 2 * PI;
118
-
119
- const alpha = startAngle + sweepAngle * t;
120
- const ellipseComponentX = rx * cos(alpha);
121
- const ellipseComponentY = ry * sin(alpha);
122
-
123
- const point = {
124
- x: cos(xRotRad) * ellipseComponentX - sin(xRotRad) * ellipseComponentY + center.x,
125
- y: sin(xRotRad) * ellipseComponentX + cos(xRotRad) * ellipseComponentY + center.y,
126
- };
127
-
128
- // to be used later
129
- // point.ellipticalArcStartAngle = startAngle;
130
- // point.ellipticalArcEndAngle = startAngle + sweepAngle;
131
- // point.ellipticalArcAngle = alpha;
132
-
133
- // point.ellipticalArcCenter = center;
134
- // point.resultantRx = rx;
135
- // point.resultantRy = ry;
136
-
137
- return point;
138
- };
139
-
140
- /**
141
- * Returns a {x,y} point at a given length, the total length and
142
- * the shape minimum and maximum {x,y} coordinates of an A (arc-to) segment.
143
- *
144
- * @param X1 the starting x position
145
- * @param Y1 the starting y position
146
- * @param RX x-radius of the arc
147
- * @param RY y-radius of the arc
148
- * @param angle x-axis-rotation of the arc
149
- * @param LAF large-arc-flag of the arc
150
- * @param SF sweep-flag of the arc
151
- * @param X2 the ending x position
152
- * @param Y2 the ending y position
153
- * @param distance the point distance
154
- * @returns the segment length, point, min & max
155
- */
156
- const segmentArcFactory = (
157
- X1: number,
158
- Y1: number,
159
- RX: number,
160
- RY: number,
161
- angle: number,
162
- LAF: number,
163
- SF: number,
164
- X2: number,
165
- Y2: number,
166
- distance: number,
167
- ): LengthFactory => {
168
- const distanceIsNumber = typeof distance === 'number';
169
- let x = X1;
170
- let y = Y1;
171
- let LENGTH = 0;
172
- let prev = [x, y, LENGTH];
173
- let cur = [x, y] as [number, number];
174
- let t = 0;
175
- let POINT = { x: 0, y: 0 };
176
- let POINTS = [{ x, y }];
177
-
178
- if (distanceIsNumber && distance <= 0) {
179
- POINT = { x, y };
180
- }
181
-
182
- const sampleSize = 300;
183
- for (let j = 0; j <= sampleSize; j += 1) {
184
- t = j / sampleSize;
185
-
186
- ({ x, y } = getPointAtArcSegmentLength(X1, Y1, RX, RY, angle, LAF, SF, X2, Y2, t));
187
- POINTS = [...POINTS, { x, y }];
188
- LENGTH += distanceSquareRoot(cur, [x, y]);
189
- cur = [x, y];
190
-
191
- if (distanceIsNumber && LENGTH > distance && distance > prev[2]) {
192
- const dv = (LENGTH - distance) / (LENGTH - prev[2]);
193
-
194
- POINT = {
195
- x: cur[0] * (1 - dv) + prev[0] * dv,
196
- y: cur[1] * (1 - dv) + prev[1] * dv,
197
- };
198
- }
199
- prev = [x, y, LENGTH];
200
- }
201
-
202
- if (distanceIsNumber && distance >= LENGTH) {
203
- POINT = { x: X2, y: Y2 };
204
- }
205
-
206
- return {
207
- length: LENGTH,
208
- point: POINT,
209
- min: {
210
- x: Math.min(...POINTS.map(n => n.x)),
211
- y: Math.min(...POINTS.map(n => n.y)),
212
- },
213
- max: {
214
- x: Math.max(...POINTS.map(n => n.x)),
215
- y: Math.max(...POINTS.map(n => n.y)),
216
- },
217
- };
218
- };
219
- export default segmentArcFactory;
@@ -1,114 +0,0 @@
1
- import { LengthFactory } from 'src/interface';
2
- import distanceSquareRoot from '../math/distanceSquareRoot';
3
-
4
- /**
5
- * Returns a {x,y} point at a given length, the total length and
6
- * the minimum and maximum {x,y} coordinates of a C (cubic-bezier) segment.
7
- *
8
- * @param x1 the starting point X
9
- * @param y1 the starting point Y
10
- * @param c1x the first control point X
11
- * @param c1y the first control point Y
12
- * @param c2x the second control point X
13
- * @param c2y the second control point Y
14
- * @param x2 the ending point X
15
- * @param y2 the ending point Y
16
- * @param t a [0-1] ratio
17
- * @returns the point at cubic-bezier segment length
18
- */
19
- const getPointAtCubicSegmentLength = (
20
- x1: number,
21
- y1: number,
22
- c1x: number,
23
- c1y: number,
24
- c2x: number,
25
- c2y: number,
26
- x2: number,
27
- y2: number,
28
- t: number,
29
- ): { x: number; y: number } => {
30
- const t1 = 1 - t;
31
- return {
32
- x: t1 ** 3 * x1 + 3 * t1 ** 2 * t * c1x + 3 * t1 * t ** 2 * c2x + t ** 3 * x2,
33
- y: t1 ** 3 * y1 + 3 * t1 ** 2 * t * c1y + 3 * t1 * t ** 2 * c2y + t ** 3 * y2,
34
- };
35
- };
36
-
37
- /**
38
- * Returns the length of a C (cubic-bezier) segment
39
- * or an {x,y} point at a given length.
40
- *
41
- * @param x1 the starting point X
42
- * @param y1 the starting point Y
43
- * @param c1x the first control point X
44
- * @param c1y the first control point Y
45
- * @param c2x the second control point X
46
- * @param c2y the second control point Y
47
- * @param x2 the ending point X
48
- * @param y2 the ending point Y
49
- * @param distance the point distance
50
- * @returns the segment length, point, min & max
51
- */
52
- const segmentCubicFactory = (
53
- x1: number,
54
- y1: number,
55
- c1x: number,
56
- c1y: number,
57
- c2x: number,
58
- c2y: number,
59
- x2: number,
60
- y2: number,
61
- distance?: number,
62
- ): LengthFactory => {
63
- const distanceIsNumber = typeof distance === 'number';
64
- let x = x1;
65
- let y = y1;
66
- let LENGTH = 0;
67
- let prev = [x, y, LENGTH];
68
- let cur = [x, y] as [number, number];
69
- let t = 0;
70
- let POINT = { x: 0, y: 0 };
71
- let POINTS = [{ x, y }];
72
-
73
- if (distanceIsNumber && distance <= 0) {
74
- POINT = { x, y };
75
- }
76
-
77
- const sampleSize = 300;
78
- for (let j = 0; j <= sampleSize; j += 1) {
79
- t = j / sampleSize;
80
-
81
- ({ x, y } = getPointAtCubicSegmentLength(x1, y1, c1x, c1y, c2x, c2y, x2, y2, t));
82
- POINTS = [...POINTS, { x, y }];
83
- LENGTH += distanceSquareRoot(cur, [x, y]);
84
- cur = [x, y];
85
-
86
- if (distanceIsNumber && LENGTH > distance && distance > prev[2]) {
87
- const dv = (LENGTH - distance) / (LENGTH - prev[2]);
88
-
89
- POINT = {
90
- x: cur[0] * (1 - dv) + prev[0] * dv,
91
- y: cur[1] * (1 - dv) + prev[1] * dv,
92
- };
93
- }
94
- prev = [x, y, LENGTH];
95
- }
96
-
97
- if (distanceIsNumber && distance >= LENGTH) {
98
- POINT = { x: x2, y: y2 };
99
- }
100
-
101
- return {
102
- length: LENGTH,
103
- point: POINT,
104
- min: {
105
- x: Math.min(...POINTS.map(n => n.x)),
106
- y: Math.min(...POINTS.map(n => n.y)),
107
- },
108
- max: {
109
- x: Math.max(...POINTS.map(n => n.x)),
110
- y: Math.max(...POINTS.map(n => n.y)),
111
- },
112
- };
113
- };
114
- export default segmentCubicFactory;