@thednp/tween 0.0.5 → 0.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.
- package/AGENTS.md +112 -0
- package/CHANGELOG.md +96 -0
- package/README.md +2 -0
- package/dist/preact/preact.d.mts +1 -1
- package/dist/preact/preact.mjs +3 -5
- package/dist/preact/preact.mjs.map +1 -1
- package/dist/react/react.d.mts +1 -1
- package/dist/react/react.mjs +3 -5
- package/dist/react/react.mjs.map +1 -1
- package/dist/solid/solid.d.mts +1 -1
- package/dist/solid/solid.mjs +2 -4
- package/dist/solid/solid.mjs.map +1 -1
- package/dist/svelte/svelte.mjs.map +1 -1
- package/dist/svelte/tween.svelte.d.ts +1 -1
- package/dist/svelte/tween.svelte.js +2 -4
- package/dist/tween/index.d.mts +4 -18
- package/dist/tween/index.d.mts.map +1 -1
- package/dist/tween/index.mjs +18 -67
- package/dist/tween/index.mjs.map +1 -1
- package/dist/tween.min.js +4 -4
- package/dist/tween.min.js.map +1 -1
- package/dist/vanjs/vanjs.d.mts +56 -0
- package/dist/vanjs/vanjs.d.mts.map +1 -0
- package/dist/vanjs/vanjs.mjs +234 -0
- package/dist/vanjs/vanjs.mjs.map +1 -0
- package/dist/vue/vue.d.mts +1 -1
- package/dist/vue/vue.mjs +2 -4
- package/dist/vue/vue.mjs.map +1 -1
- package/package.json +25 -16
package/dist/tween.min.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tween.min.js","names":[],"sources":["../src/Easing.ts","../src/Util.ts","../src/extend/array.ts","../src/extend/path.ts","../src/extend/object.ts","../src/extend/transform.ts","../src/Now.ts","../src/Runtime.ts","../src/Tween.ts","../src/Timeline.ts","../package.json"],"sourcesContent":["// Easing.ts\nimport type { EasingFunction, EasingFunctionGroup } from \"./types.d.ts\";\n\n/**\n * The Ease class provides a collection of easing functions for use with tween.js.\n */\n\nexport const Easing = Object.freeze({\n Linear: Object.freeze<EasingFunctionGroup & { None: EasingFunction }>({\n None(amount: number): number {\n return amount;\n },\n In(amount: number): number {\n return amount;\n },\n Out(amount: number): number {\n return amount;\n },\n InOut(amount: number): number {\n return amount;\n },\n }),\n\n Quadratic: Object.freeze(\n <EasingFunctionGroup> {\n In(amount: number): number {\n return amount * amount;\n },\n Out(amount: number): number {\n return amount * (2 - amount);\n },\n InOut(amount: number): number {\n if ((amount *= 2) < 1) {\n return 0.5 * amount * amount;\n }\n\n return -0.5 * (--amount * (amount - 2) - 1);\n },\n },\n ),\n\n Cubic: Object.freeze(\n <EasingFunctionGroup> {\n In(amount: number): number {\n return amount * amount * amount;\n },\n Out(amount: number): number {\n return --amount * amount * amount + 1;\n },\n InOut(amount: number): number {\n if ((amount *= 2) < 1) {\n return 0.5 * amount * amount * amount;\n }\n return 0.5 * ((amount -= 2) * amount * amount + 2);\n },\n },\n ),\n\n Quartic: Object.freeze(\n <EasingFunctionGroup> {\n In(amount: number): number {\n return amount * amount * amount * amount;\n },\n Out(amount: number): number {\n return 1 - --amount * amount * amount * amount;\n },\n InOut(amount: number): number {\n if ((amount *= 2) < 1) {\n return 0.5 * amount * amount * amount * amount;\n }\n\n return -0.5 * ((amount -= 2) * amount * amount * amount - 2);\n },\n },\n ),\n\n Quintic: Object.freeze(\n <EasingFunctionGroup> {\n In(amount: number): number {\n return amount * amount * amount * amount * amount;\n },\n Out(amount: number): number {\n return --amount * amount * amount * amount * amount + 1;\n },\n InOut(amount: number): number {\n if ((amount *= 2) < 1) {\n return 0.5 * amount * amount * amount * amount * amount;\n }\n\n return 0.5 * ((amount -= 2) * amount * amount * amount * amount + 2);\n },\n },\n ),\n\n Sinusoidal: Object.freeze(\n <EasingFunctionGroup> {\n In(amount: number): number {\n return 1 - Math.sin(((1.0 - amount) * Math.PI) / 2);\n },\n Out(amount: number): number {\n return Math.sin((amount * Math.PI) / 2);\n },\n InOut(amount: number): number {\n return 0.5 * (1 - Math.sin(Math.PI * (0.5 - amount)));\n },\n },\n ),\n\n Exponential: Object.freeze(\n <EasingFunctionGroup> {\n In(amount: number): number {\n return amount === 0 ? 0 : Math.pow(1024, amount - 1);\n },\n Out(amount: number): number {\n return amount === 1 ? 1 : 1 - Math.pow(2, -10 * amount);\n },\n InOut(amount: number): number {\n if (amount === 0) {\n return 0;\n }\n\n if (amount === 1) {\n return 1;\n }\n\n if ((amount *= 2) < 1) {\n return 0.5 * Math.pow(1024, amount - 1);\n }\n\n return 0.5 * (-Math.pow(2, -10 * (amount - 1)) + 2);\n },\n },\n ),\n\n Circular: Object.freeze(\n <EasingFunctionGroup> {\n In(amount: number): number {\n return 1 - Math.sqrt(1 - amount * amount);\n },\n Out(amount: number): number {\n return Math.sqrt(1 - --amount * amount);\n },\n InOut(amount: number): number {\n if ((amount *= 2) < 1) {\n return -0.5 * (Math.sqrt(1 - amount * amount) - 1);\n }\n return 0.5 * (Math.sqrt(1 - (amount -= 2) * amount) + 1);\n },\n },\n ),\n\n Elastic: Object.freeze(\n <EasingFunctionGroup> {\n In(amount: number): number {\n if (amount === 0) {\n return 0;\n }\n\n if (amount === 1) {\n return 1;\n }\n\n return (\n -Math.pow(2, 10 * (amount - 1)) *\n Math.sin((amount - 1.1) * 5 * Math.PI)\n );\n },\n Out(amount: number): number {\n if (amount === 0) {\n return 0;\n }\n\n if (amount === 1) {\n return 1;\n }\n return (\n Math.pow(2, -10 * amount) * Math.sin((amount - 0.1) * 5 * Math.PI) + 1\n );\n },\n InOut(amount: number): number {\n if (amount === 0) {\n return 0;\n }\n\n if (amount === 1) {\n return 1;\n }\n\n amount *= 2;\n\n if (amount < 1) {\n return (\n -0.5 *\n Math.pow(2, 10 * (amount - 1)) *\n Math.sin((amount - 1.1) * 5 * Math.PI)\n );\n }\n\n return (\n 0.5 *\n Math.pow(2, -10 * (amount - 1)) *\n Math.sin((amount - 1.1) * 5 * Math.PI) +\n 1\n );\n },\n },\n ),\n\n Back: Object.freeze(\n <EasingFunctionGroup> {\n In(amount: number): number {\n const s = 1.70158;\n return amount === 1 ? 1 : amount * amount * ((s + 1) * amount - s);\n },\n Out(amount: number): number {\n const s = 1.70158;\n return amount === 0\n ? 0\n : --amount * amount * ((s + 1) * amount + s) + 1;\n },\n InOut(amount: number): number {\n const s = 1.70158 * 1.525;\n if ((amount *= 2) < 1) {\n return 0.5 * (amount * amount * ((s + 1) * amount - s));\n }\n return 0.5 * ((amount -= 2) * amount * ((s + 1) * amount + s) + 2);\n },\n },\n ),\n\n Bounce: Object.freeze(\n <EasingFunctionGroup> {\n In(amount: number): number {\n return 1 - Easing.Bounce.Out(1 - amount);\n },\n Out(amount: number): number {\n if (amount < 1 / 2.75) {\n return 7.5625 * amount * amount;\n } else if (amount < 2 / 2.75) {\n return 7.5625 * (amount -= 1.5 / 2.75) * amount + 0.75;\n } else if (amount < 2.5 / 2.75) {\n return 7.5625 * (amount -= 2.25 / 2.75) * amount + 0.9375;\n } else {\n return 7.5625 * (amount -= 2.625 / 2.75) * amount + 0.984375;\n }\n },\n InOut(amount: number): number {\n if (amount < 0.5) {\n return Easing.Bounce.In(amount * 2) * 0.5;\n }\n return Easing.Bounce.Out(amount * 2 - 1) * 0.5 + 0.5;\n },\n },\n ),\n\n pow(power = 4): EasingFunctionGroup {\n power = power < Number.EPSILON ? Number.EPSILON : power;\n power = power > 10000 ? 10000 : power;\n return {\n In(amount: number): number {\n return amount ** power;\n },\n Out(amount: number): number {\n return 1 - (1 - amount) ** power;\n },\n InOut(amount: number): number {\n if (amount < 0.5) {\n return (amount * 2) ** power / 2;\n }\n return (1 - (2 - amount * 2) ** power) / 2 + 0.5;\n },\n };\n },\n});\n","import type { DeepObject, DeepPartial, TweenProps } from \"./types.d.ts\";\nimport { type Tween } from \"./Tween.ts\";\nimport { type Timeline } from \"./Timeline.ts\";\n\n// Util.ts\nexport const isString = (value: unknown): value is string =>\n typeof value === \"string\";\n\nexport const isNumber = (value: unknown): value is number =>\n typeof value === \"number\";\n\nexport const isArray = (value: unknown): value is Array<unknown> =>\n Array.isArray(value);\n\nexport const isFunction = (value: unknown): value is () => unknown =>\n typeof value === \"function\";\n\nexport const isObject = (\n value: unknown,\n): value is Record<string, never> =>\n value !== null && value !== undefined && typeof value === \"object\" &&\n Object.getPrototypeOf(value) === Object.prototype;\n\nexport const isPlainObject = (\n value: unknown,\n): value is Record<string, never> => isObject(value) && !isArray(value);\n\nexport const isDeepObject = (value: unknown): value is DeepObject =>\n isPlainObject(value) && Object.values(value).some(isPlainObject);\n\nexport const isServer = typeof window === \"undefined\";\n\nconst instanceMethods = [\n \"play\",\n \"label\",\n \"start\",\n \"stop\",\n \"pause\",\n \"resume\",\n \"reverse\",\n \"use\",\n \"clear\",\n \"from\",\n \"to\",\n \"easing\",\n \"delay\",\n \"yoyo\",\n \"repeat\",\n \"update\",\n \"repeatDelay\",\n \"onStart\",\n \"onUpdate\",\n \"onComplete\",\n \"onStop\",\n \"onRepeat\",\n];\n\n/**\n * SSR helper to speed up UI frameworks render.\n *\n * Why:\n * - skip validation\n * - skip ministore creation\n * - allow free-form configuration for signal based frameworks\n */\nconst dummyInstance: Record<string, typeof dummyMethod> = {};\n// istanbul ignore next @preserve\n// const dummyMethod = () => dummyInstance;\nfunction dummyMethod(this: typeof dummyInstance) {\n return this;\n}\n\nfor (let i = 0; i < instanceMethods.length; i++) {\n dummyInstance[instanceMethods[i]] = dummyMethod;\n}\n\nexport { dummyInstance };\n\n/**\n * Utility to round numbers to a specified number of decimals.\n * @param n Input number value\n * @param round Number of decimals\n * @returns The rounded number\n */\nexport const roundTo = (n: number, round: number) => {\n const pow = round >= 1 ? 10 ** round : 1;\n return round > 0 ? Math.round(n * pow) / pow : Math.round(n);\n};\n\nexport const objectHasProp = <T extends object>(obj: T, prop: keyof T) =>\n Object.prototype.hasOwnProperty.call(obj, prop);\n\nconst isUnsafeKey = (key: string): boolean =>\n key === \"__proto__\" || key === \"constructor\" || key === \"prototype\";\n\n/**\n * A small utility to deep assign up to one level deep nested objects.\n * This is to prevent breaking reactivity of miniStore.\n *\n * **NOTE** - This doesn't perform ANY check and expects objects values\n * to be validated beforehand.\n * @param target The target to assign values to\n * @param source The source object to assign values from\n */\nexport function deepAssign<T extends TweenProps>(\n target: T,\n source: T,\n): void {\n const keys = Object.keys(source) as (keyof T)[];\n let i = 0;\n const len = keys.length;\n\n while (i < len) {\n const key = keys[i++];\n // prevent prototype pollution\n // istanbul ignore next @preserve\n if (isUnsafeKey(key as string) || !objectHasProp(source, key)) {\n continue;\n }\n const targetVal = target[key];\n const sourceVal = source[key];\n\n if (isArray(sourceVal)) {\n // Handle arrays (number[], TransformArray, MorphPathArray)\n const targetArr = targetVal as unknown[];\n let j = 0;\n const arLen = sourceVal.length;\n\n while (j < arLen) {\n const sourceItem = sourceVal[j];\n\n if (isArray(sourceItem)) {\n // Nested array (e.g., TransformStep, MorphPathSegment)\n // if (!isArray(targetArr[j])) {\n // targetArr[j] = [];\n // }\n const targetItem = targetArr[j] as unknown[];\n let k = 0;\n const itemLen = sourceItem.length;\n while (k < itemLen) {\n targetItem[k] = sourceItem[k];\n k++;\n }\n } else {\n // Primitive in array (e.g., number[] like rgb)\n targetArr[j] = sourceItem;\n }\n j++;\n }\n } else if (objectHasProp(target, key) && isObject(sourceVal)) {\n // Handle nested objects (BaseTweenProps)\n deepAssign(targetVal as never, sourceVal as never);\n } else {\n // Primitive value (number)\n target[key] = sourceVal;\n }\n }\n}\n\n/**\n * Creates a new object with the same structure of a target object / array\n * without its proxy elements / properties, only their values.\n *\n * **NOTE** - The utility is useful to create deep clones as well.\n *\n * @param value An object / array with proxy elements\n * @returns the object / array value without proxy elements\n */\nexport const deproxy = <T>(value: T): T => {\n if (isArray(value)) {\n return value.map(deproxy) as T;\n }\n\n if (isPlainObject(value)) {\n const result: Record<string, unknown> = {};\n for (const key in value) {\n // istanbul ignore else @preserve\n if (objectHasProp(value, key)) {\n result[key] = deproxy(value[key]);\n }\n }\n return result as T;\n }\n\n return value;\n};\n\n/**\n * Test values validity or their compatibility with the validated ones\n * in the state. This is something we don't want to do in the runtime\n * update loop.\n * @param this The Tween/Timeline instance\n * @param target The target object to validate\n * @param reference The reference state value\n * @returns void\n */\nexport function validateValues<T extends TweenProps>(\n this: Timeline | Tween,\n target: Partial<T> | DeepPartial<T>,\n reference?: T,\n) {\n const errors = this.getErrors();\n\n if (!isPlainObject(target) || Object.keys(target).length === 0) {\n errors.set(\"init\", \"Initialization value is empty or not an object.\");\n return;\n }\n\n const keys = Object.keys(target);\n\n // skip if from()/to() was used before one another\n // we don't want to validate props invalidated!\n if (reference && keys.some((key) => errors.has(key))) {\n return;\n }\n\n // Validate every value\n let i = 0;\n while (i < keys.length) {\n const key = keys[i++];\n const refValue = reference?.[key];\n const value = target[key];\n\n // everything else is either number or not supported\n if (isNumber(value)) {\n // no error there\n // this.removeError(key);\n continue; // good value\n }\n\n if (value === undefined || value === null) {\n errors.set(key, `Property \"${key}\" is null/undefined.`);\n continue;\n }\n\n if (reference && refValue === undefined) {\n errors.set(key, `Property \"${key}\" doesn't exist in state yet.`);\n continue;\n }\n\n // allow validators to override default validation behavior\n const validator = this.getValidator(key);\n if (validator) {\n const [valid, reason] = validator(key, value, refValue as never);\n if (valid) errors.delete(key);\n else errors.set(key, reason as string);\n continue;\n }\n\n if (reference && isNumber(refValue)) {\n // istanbul ignore else @preserve\n if (!isNumber(value)) {\n errors.set(key, `Property \"${key}\" is not a number.`);\n }\n // only validators can revalidate\n // this case can never be covered\n // else this.removeError(key);\n\n continue;\n }\n\n // Any value here is either not valid or not supported yet\n errors.set(\n key,\n `Property \"${key}\" of type \"${\n isArray(value) ? \"array\" : typeof value\n }\" is not supported yet.`,\n );\n }\n errors.delete(\"init\");\n}\n","// src/extend/array.ts\nimport { isArray, isNumber } from \"../Util.ts\";\nimport { InterpolatorFunction, ValidationResultEntry } from \"../types.ts\";\n\n/**\n * Interpolates two `Array<number>` values.\n *\n * **NOTE**: Values my be validated first!\n *\n * @param target The target `Array<number>` value of the state object\n * @param start The start `Array<number>` value\n * @param end The end `Array<number>` value\n * @param t The progress value\n * @returns The interpolated `Array<number>` value.\n */\nexport const interpolateArray: InterpolatorFunction<number[]> = <\n T extends number[],\n>(\n target: T,\n start: T,\n end: T,\n t: number,\n) => {\n const len = end.length;\n let i = 0;\n\n while (i < len) {\n target[i] = start[i] + (end[i] - start[i]) * t;\n i += 1;\n }\n\n return target;\n};\n\n/**\n * Check if a value is a valid `Array<number>` for interpolation.\n * @param target The array to check\n * @returns `true` is value is array and all elements are numbers\n */\nexport const isValidArray = <T extends number[]>(\n target: unknown,\n): target is T => isArray(target) && target.every(isNumber);\n\n/**\n * Check if an `Array<number>` is valid and compatible with a reference.\n *\n * @param target The incoming value `from()` / `to()`\n * @param ref The state reference value\n * @returns [boolean, reason] tuple with validation state as boolean and,\n * if not valid, a reason why it's not valid\n */\nexport const validateArray = <T extends number[]>(\n propName: string,\n target: unknown,\n ref?: T,\n): ValidationResultEntry => {\n // istanbul ignore if @preserve\n if (!isArray(target)) {\n return [false, `Property \"${String(propName)}\" is not Array.`];\n }\n // istanbul ignore if @preserve\n if (!isValidArray(target)) {\n return [\n false,\n `Property \"${String(propName)}\" is not a valid Array<number>.`,\n ];\n }\n\n if (ref && ref.length !== target.length) {\n return [\n false,\n `Property \"${\n String(propName)\n }\" is expecting an array of ${ref.length} numbers.`,\n ];\n }\n\n return [true];\n};\n\n/**\n * Config for .use(propName, arrayConfig)\n */\nexport const arrayConfig = {\n interpolate: interpolateArray,\n validate: validateArray,\n};\n","// src/extend/path.ts\nimport { isArray, isNumber } from \"../Util.ts\";\n\nimport type {\n InterpolatorFunction,\n MorphPathArray,\n MorphPathSegment,\n PathLike,\n ValidationResultEntry,\n} from \"../types.ts\";\n\nimport { roundTo } from \"../Util.ts\";\n\n/**\n * Iterates a `PathArray` value and concatenates the values into a string to return it.\n *\n * **NOTE**: Segment values are rounded to 4 decimals by default.\n * @param path A source PathArray\n * @param round An optional parameter to round segment values to a number of decimals\n * @returns A valid HTML `description` (d) path string value\n */\nexport function pathToString(path: MorphPathArray, round = 4) {\n const pathLen = path.length;\n let segment = path[0];\n let result = \"\";\n let i = 0;\n let segLen = 0;\n\n while (i < pathLen) {\n segment = path[i++];\n segLen = segment.length;\n result += segment[0];\n\n let j = 1;\n\n while (j < segLen) {\n result += roundTo(segment[j++] as number, round);\n if (j !== segLen) result += \" \";\n }\n }\n\n return result;\n}\n\n/**\n * Interpolate `PathArray` values.\n *\n * **NOTE**: these values must be validated first!\n * @param target - The target PathArray value\n * @param start - A starting PathArray value\n * @param end - An ending PathArray value\n * @param t - The progress value\n * @returns The interpolated PathArray value\n */\nexport const interpolatePath: InterpolatorFunction<MorphPathSegment[]> = <\n T extends MorphPathSegment[],\n>(\n target: T,\n start: T,\n end: T,\n t: number,\n): T => {\n const segCount = end.length;\n let i = 0;\n\n while (i < segCount) {\n const targetSeg = target[i];\n const startSeg = start[i];\n const endSeg = end[i];\n\n if (targetSeg[0] === \"Z\") {\n i++;\n continue;\n } else if (targetSeg[0] === \"C\") {\n targetSeg[1] = startSeg[1]! + (endSeg[1]! - startSeg[1]!) * t;\n targetSeg[2] = startSeg[2]! + (endSeg[2]! - startSeg[2]!) * t;\n targetSeg[3] = startSeg[3]! + (endSeg[3]! - startSeg[3]!) * t;\n targetSeg[4] = startSeg[4]! + (endSeg[4]! - startSeg[4]!) * t;\n targetSeg[5] = startSeg[5]! + (endSeg[5]! - startSeg[5]!) * t;\n targetSeg[6] = startSeg[6]! + (endSeg[6]! - startSeg[6]!) * t;\n } else { // M / L\n targetSeg[1] = startSeg[1]! + (endSeg[1]! - startSeg[1]!) * t;\n targetSeg[2] = startSeg[2]! + (endSeg[2]! - startSeg[2]!) * t;\n }\n i++;\n }\n\n return target as T;\n};\n\nconst supportedPathCommands = [\"M\", \"L\", \"C\", \"Z\"] as const;\n\n/**\n * Check if an array of arrays is potentially a PathArray\n * @param target The incoming value `constructor()` `from()` / `to()`\n * @returns `true` when array is potentially a PathArray\n */\nexport const isPathLike = (\n value: unknown,\n): value is PathLike =>\n isArray(value) &&\n value.some((seg) =>\n isArray(seg) && supportedPathCommands.includes(seg[0] as never)\n );\n\n/**\n * Check if an array of arrays is a valid PathArray for interpolation\n * @param target The incoming value `from()` / `to()`\n * @returns `true` when array is valid\n */\nexport const isValidPath = (value: unknown): value is MorphPathArray =>\n isPathLike(value) && value.length > 1 && value.every(isArray) &&\n value.every(([cmd, ...values]) =>\n supportedPathCommands.includes(cmd as MorphPathSegment[0]) && (\n ([\"M\", \"L\"].includes(cmd as MorphPathSegment[0]) &&\n (values as number[]).length === 2 &&\n values.every(isNumber)) ||\n (\"C\" === cmd && (values as number[]).length === 6 &&\n values.every(isNumber)) ||\n (\"Z\" === cmd && (values as number[]).length === 0)\n )\n );\n\n/**\n * Validate a `PathArray` and check if it's compatible with a reference.\n *\n * **NOTE**: Path interpolation only works when both paths have:\n * - Identical segments structure (same number and order of M/L/C/Z path commands)\n * - Corresponding coordinates to interpolate\n * Complex morphs require preprocessing (e.g. KUTE.js, Flubber)\n *\n * @example\n * // simple shapes\n * const linePath1 = [[\"M\", 0, 0],[\"L\", 50, 50]]\n * const linePath2 = [[\"M\",50,50],[\"L\",150,150]]\n * const curvePath1 = [[\"M\", 0, 0],[\"C\",15,15, 35, 35, 50, 50]]\n * const curvePath2 = [[\"M\",50,50],[\"C\",50,50,100,100,150,150]]\n *\n * // closed shapes\n * const closedLinePath1 = [[\"M\", 0, 0],[\"L\", 50, 50],[\"Z\"]]\n * const closedLinePath2 = [[\"M\",50,50],[\"L\",150,150],[\"Z\"]]\n * const closedCurvePath1 = [[\"M\", 0, 0],[\"C\",15,15, 35, 35, 50, 50],[\"Z\"]]\n * const closedCurvePath2 = [[\"M\",50,50],[\"C\",50,50,100,100,150,150],[\"Z\"]]\n *\n * // composit shapes (multi-path)\n * const compositPath1 = [\n * [\"M\", 0, 0],[\"L\",50,50],\n * [\"M\",50,50],[\"C\",50,50,100,100,150,150],\n * ]\n * const compositPath2 = [\n * [\"M\",50,50],[\"L\",150,150],\n * [\"M\", 0, 0],[\"C\", 15, 15,35,35,50,50],\n * ]\n *\n * @param target The incoming value `from()` / `to()`\n * @param ref The state reference value\n * @returns a tuple with validation result as a `boolean` and,\n * if not valid, a reason why value isn't\n */\nexport const validatePath = <T extends MorphPathArray>(\n propName: string,\n target: unknown,\n ref?: T,\n): ValidationResultEntry => {\n // ref is state[prop] and is already validated on initialization\n if (!isValidPath(target)) {\n return [false, `Property \"${propName}\" is not a valid PathArray.`];\n }\n\n if (ref) {\n if (ref.length !== target.length) {\n return [\n false,\n `Property \"${propName}\" is expecting an array of ${ref.length} path segments, got ${target.length}.`,\n ];\n }\n\n let i = 0;\n const len = ref.length;\n while (i < len) {\n const refSeg = ref[i];\n const targetSeg = target[i];\n const refCmd = refSeg[0];\n const targetCmd = targetSeg[0];\n const refLen = refSeg.length;\n const targetLen = targetSeg.length;\n\n if (refCmd !== targetCmd || refLen !== targetLen) {\n return [\n false,\n `Property \"${propName}\" mismatch at index ${i}. ` +\n `Segments don't match:\\n` +\n `> segment: \"[${targetCmd}, ${targetSeg.slice(1)}]\"\\n` +\n `> reference: \"[${refCmd}, ${refSeg.slice(1)}]\"`,\n ];\n }\n i++;\n }\n }\n\n return [true];\n};\n\n/**\n * Config for .use(propName, pathArrayConfig)\n */\nexport const pathArrayConfig = {\n interpolate: interpolatePath,\n validate: validatePath,\n};\n","// src/extend/object.ts\nimport type {\n BaseTweenProps,\n InterpolatorFunction,\n ValidationResultEntry,\n} from \"../types.ts\";\nimport { isNumber, isPlainObject } from \"../Util.ts\";\n\n/**\n * Single-level `Record<string, number>` object interpolate function.\n *\n * **NOTE**: values must be validated first!\n *\n * Input: single-level nested object\n *\n * Output: interpolated flat object with same structure\n *\n * @example\n * const initialValues = { translate : { x: 0, y: 0 } };\n * // we will need to validate the value of `translate`\n *\n * @param target The target value of the state object\n * @param start The start value of the object\n * @param end The end value of the object\n * @param t The progress value\n * @returns The interpolated flat object with same structure.\n */\nexport const interpolateObject: InterpolatorFunction<BaseTweenProps> = <\n T extends BaseTweenProps,\n>(\n target: T,\n start: T,\n end: T,\n t: number,\n): T => {\n // Iterate over end keys (we only interpolate what's in end)\n const keys = Object.keys(end) as (keyof T)[];\n let i = 0;\n\n while (i < keys.length) {\n const key = keys[i++];\n const endVal = end[key];\n const startVal = start[key];\n\n target[key] = (startVal + (endVal - startVal) * t) as T[keyof T];\n }\n\n return target;\n};\n\n/**\n * Validate a plain `Record<string, number>` object and compare its compatibility\n * with a reference object.\n * @param propName The property name to which this object belongs to\n * @param target The target object itself\n * @param ref A reference object to compare our target to\n * @returns A [boolean, string?] tuple which represents [validity, \"reason why not valid\"]\n */\nexport const validateObject = (\n propName: string,\n target: unknown,\n ref?: BaseTweenProps,\n): ValidationResultEntry => {\n if (!isPlainObject(target)) {\n return [false, `Property \"${propName}\" must be a plain object.`];\n }\n\n const keys = Object.keys(target);\n let i = 0;\n const iLen = keys.length;\n\n while (i < iLen) {\n const key = keys[i++];\n const value = target[key];\n\n if (value === null || value === undefined) {\n return [\n false,\n `Property \"${key}\" from \"${propName}\" is null/undefined.`,\n ];\n }\n\n // We never want to go down that route\n // if (isPlainObject(value)) {}\n\n if (!isNumber(value)) {\n return [\n false,\n `Property \"${key}\" from \"${propName}\" must be a number.` +\n `${\n isPlainObject(value)\n ? \" Deeper nested objects are not supported.\"\n : ` Unsupported value: \"${typeof value}\".`\n }`,\n ];\n }\n\n if (ref) {\n if (ref[key] === undefined) {\n return [\n false,\n `Property \"${key}\" in \"${propName}\" doesn't exist in the reference object.`,\n ];\n }\n }\n }\n\n return [true];\n};\n\n/**\n * Config for .use(propName, objectConfig)\n */\nexport const objectConfig = {\n interpolate: interpolateObject,\n validate: validateObject,\n};\n","// src/extend/transform.ts\nimport type {\n InterpolatorFunction,\n TransformArray,\n TransformLike,\n TransformStep,\n TransformStepInternal,\n ValidationResultEntry,\n Vec3,\n} from \"../types.ts\";\nimport { isArray, isNumber } from \"../Util.ts\";\n\n/**\n * Returns a valid CSS transform string either with transform functions (Eg.: `translate(15px) rotate(25deg)`)\n * or `matrix(...)` / `matrix3d(...)`.\n * When the `toMatrix` parameter is `true` it will create a DOMMatrix instance, apply transform\n * steps and return a `matrix(...)` or `matrix3d(...)` string value.\n * @param steps An array of TransformStep\n * @param toMatrix An optional parameter to modify the function output\n * @returns The valid CSS transform string value\n */\nexport const transformToString = (steps: TransformStep[], toMatrix = false) => {\n if (toMatrix) {\n const matrix = new DOMMatrix();\n const len = steps.length;\n let i = 0;\n\n while (i < len) {\n const step = steps[i++];\n\n switch (step[0]) {\n case \"perspective\": {\n const m2 = new DOMMatrix();\n m2.m34 = -1 / step[1];\n matrix.multiplySelf(m2);\n break;\n }\n case \"translate\": {\n matrix.translateSelf(step[1], step[2] || 0, step[3] || 0);\n break;\n }\n case \"rotate\": {\n matrix.rotateSelf(step[1], step[2] || 0, step[3] || 0);\n break;\n }\n case \"rotateAxisAngle\": {\n matrix.rotateAxisAngleSelf(step[1], step[2], step[3], step[4]);\n break;\n }\n case \"scale\": {\n matrix.scaleSelf(step[1], step[2] || 1, step[3] || 1);\n break;\n }\n case \"skewX\": {\n matrix.skewXSelf(step[1]);\n break;\n }\n case \"skewY\": {\n matrix.skewYSelf(step[1]);\n break;\n }\n }\n }\n\n return matrix.toString();\n }\n // Return CSS transform string\n const len = steps.length;\n let i = 0;\n let stringOutput = \"\";\n\n while (i < len) {\n const step = steps[i++];\n\n switch (step[0]) {\n case \"perspective\": {\n stringOutput += ` perspective(${step[1]}px)`;\n break;\n }\n case \"translate\": {\n stringOutput += ` translate3d(${step[1]}px, ${step[2] || 0}px, ${\n step[3] || 0\n }px)`;\n break;\n }\n case \"rotate\": {\n const [rx, ry, rz] = step.slice(1) as Vec3;\n\n if (typeof rx === \"number\" && ry === undefined && rz === undefined) {\n stringOutput += ` rotate(${step[1]}deg)`;\n } else {\n stringOutput += ` rotateX(${step[1]}deg)`;\n // istanbul ignore else @preserve\n if (step[2] !== undefined) stringOutput += ` rotateY(${step[2]}deg)`;\n // istanbul ignore else @preserve\n if (step[3] !== undefined) stringOutput += ` rotateZ(${step[3]}deg)`;\n }\n break;\n }\n case \"rotateAxisAngle\": {\n stringOutput += ` rotate3d(${step[1]}, ${step[2]}, ${step[3]}, ${\n step[4]\n }deg)`;\n break;\n }\n case \"scale\": {\n stringOutput += ` scale(${step[1]}, ${step[2] || step[1]}, ${\n step[3] || 1\n })`;\n break;\n }\n case \"skewX\": {\n stringOutput += ` skewX(${step[1]}deg)`;\n break;\n }\n case \"skewY\": {\n stringOutput += ` skewY(${step[1]}deg)`;\n break;\n }\n }\n }\n\n return stringOutput.slice(1);\n};\n\n/**\n * Convert euler rotation to axis angle.\n * All values are degrees.\n * @param x rotateX value\n * @param y rotateY value\n * @param z rotateZ value\n * @returns The axis angle tuple [vectorX, vectorY, vectorZ, angle]\n */\nexport const eulerToAxisAngle = (\n x: number,\n y: number,\n z: number,\n): [number, number, number, number] => {\n // Convert to quaternion first\n const quat = eulerToQuaternion(x, y, z);\n\n // Then convert quaternion to axis-angle\n return quaternionToAxisAngle(quat);\n};\n\n/**\n * Convert euler rotation tuple to quaternion.\n * All values are degrees.\n * @param x The rotateX value\n * @param y The rotateY value\n * @param z The rotateZ value\n * @returns The rotation quaternion\n */\nconst eulerToQuaternion = (\n x: number,\n y: number,\n z: number,\n): [number, number, number, number] => {\n const cx = Math.cos(x / 2);\n const sx = Math.sin(x / 2);\n const cy = Math.cos(y / 2);\n const sy = Math.sin(y / 2);\n const cz = Math.cos(z / 2);\n const sz = Math.sin(z / 2);\n\n return [\n cx * cy * cz + sx * sy * sz,\n sx * cy * cz - cx * sy * sz,\n cx * sy * cz + sx * cy * sz,\n cx * cy * sz - sx * sy * cz,\n ];\n};\n\n/**\n * Convert euler rotation tuple to axis angle.\n * All values are degrees.\n * @param q The rotation quaternion\n * @returns The axis angle tuple [vectorX, vectorY, vectorZ, angle]\n */\nconst quaternionToAxisAngle = (\n q: [number, number, number, number],\n): [number, number, number, number] => {\n const [w, x, y, z] = q;\n\n // Normalize\n const len = Math.sqrt(x * x + y * y + z * z);\n\n if (len < 0.0001) {\n // No rotation\n return [0, 0, 1, 0];\n }\n\n const angle = 2 * Math.acos(Math.max(-1, Math.min(1, w)));\n\n return [x / len, y / len, z / len, angle];\n};\n\n/**\n * Interpolates arrays of `TransformStep`s → returns interpolated `TransformStep`s.\n *\n * **NOTE** - Like `PathArray`, these values are required to have same length,\n * structure and must be validated beforehand.\n * @example\n * const a1: TransformArray = [\n * [\"translate\", 0, 0], // [translateX, translateY]\n * [\"rotate\", 0], // [rotateZ]\n * [\"rotate\", 0, 0], // [rotateX, rotateY]\n * [\"rotateAxisAngle\", 0, 0, 0, 0], // [originX, originY, originZ, angle]\n * [\"scale\", 1], // [scale]\n * [\"scale\", 1, 1], // [scaleX, scaleY]\n * [\"perspective\", 800], // [length]\n * ];\n * const a2: TransformArray = [\n * [\"translate\", 50, 50],\n * [\"rotate\", 45],\n * [\"rotate\", 45, 45],\n * [\"rotateAxisAngle\", 1, 0, 0, 45],\n * [\"scale\", 1.5],\n * [\"scale\", 1.5, 1.2],\n * [\"perspective\", 400],\n * ];\n *\n * @param target The target `TransformArray` of the state object\n * @param start The start `TransformArray`\n * @param end The end `TransformArray`\n * @param t The progress value\n * @returns The interpolated `TransformArray`\n */\nexport const interpolateTransform: InterpolatorFunction<TransformStep[]> = <\n T extends TransformStepInternal[],\n>(\n target: T,\n start: T,\n end: T,\n t: number,\n): T => {\n const len = end.length;\n let i = 0;\n\n while (i < len) {\n const targetStep = target[i];\n const startStep = start[i];\n const endStep = end[i];\n\n switch (targetStep[0]) {\n case \"translate\":\n case \"rotate\":\n case \"scale\":\n case \"rotateAxisAngle\":\n targetStep[1] = startStep[1] + (endStep[1] - startStep[1]) * t;\n\n typeof endStep[2] === \"number\" &&\n (targetStep[2] = startStep[2]! + (endStep[2]! - startStep[2]!) * t);\n\n typeof endStep[3] === \"number\" &&\n (targetStep[3] = startStep[3]! + (endStep[3]! - startStep[3]!) * t);\n\n typeof endStep[4] === \"number\" &&\n (targetStep[4] = startStep[4]! + (endStep[4]! - startStep[4]!) * t);\n\n break;\n case \"skewX\":\n case \"skewY\":\n case \"perspective\":\n targetStep[1] = startStep[1] + (endStep[1] - startStep[1]) * t;\n\n break;\n }\n i++;\n }\n\n return target as T;\n};\n\nconst supportedTransform = [\n \"perspective\",\n \"translate\",\n \"rotate\",\n \"rotateAxisAngle\",\n \"scale\",\n \"skewX\",\n \"skewY\",\n] as const;\n\n/**\n * Check if a value is potentially a `TransformArray`.\n * @param target The incoming value `constructor()` `from()` / `to()`\n * @returns `true` when array is potentially a PathArray\n */\nexport const isTransformLike = (value: unknown): value is TransformLike =>\n isArray(value) &&\n value.some(\n (step) => isArray(step) && supportedTransform.includes(step[0] as never),\n );\n\n/**\n * Check if a value is a valid `TransformArray` for interpolation.\n * @param target The incoming value `from()` / `to()`\n * @returns a tuple with validation result as a `boolean` and,\n * if not valid, a reason why value isn't\n */\nexport const isValidTransformArray = (\n value: unknown,\n): value is TransformArray =>\n isTransformLike(value) &&\n value.every(\n ([fn, ...values]) =>\n supportedTransform.includes(fn as TransformStep[0]) &&\n (([\"translate\", \"rotate\", \"scale\"].includes(fn as TransformStep[0]) &&\n values.length > 0 &&\n values.length <= 3 &&\n values.every(isNumber)) ||\n (\"rotateAxisAngle\" === fn &&\n (values as number[]).length === 4 &&\n values.every(isNumber)) ||\n ([\"skewX\", \"skewY\", \"perspective\"].includes(fn as string) &&\n (values as number[]).length === 1 &&\n isNumber((values as number[])[0]))),\n );\n\n/**\n * Validator for `TransformArray` that checks\n * structure + parameter counts, and if provided,\n * the compatibility with a reference value.\n */\nexport const validateTransform = (\n propName: string,\n target: unknown,\n ref?: TransformArray,\n): ValidationResultEntry => {\n if (!isValidTransformArray(target)) {\n return [false, `Property \"${propName}\" must be an array of TransformStep.`];\n }\n\n if (ref) {\n if (ref.length !== target.length) {\n return [\n false,\n `Property \"${propName}\" is expecting an array of ${ref.length} transform steps, got ${target.length}.`,\n ];\n }\n\n let i = 0;\n const len = target.length;\n\n while (i < len) {\n const step = target[i] as [string, ...Vec3];\n const refStep = ref[i] as [string, ...Vec3];\n const fn = step[0];\n const fnRef = refStep[0];\n\n // istanbul ignore else @preserve\n if (refStep) {\n if (fnRef !== fn || refStep.length !== step.length) {\n return [\n false,\n `Property \"${propName}\" mismatch at index ${i}\":\\n` +\n `> step: [\"${fn}\", ${step.slice(1)}]\\n` +\n `> reference: [\"${fnRef}\", ${refStep.slice(1)}]`,\n ];\n }\n }\n i++;\n }\n }\n\n return [true];\n};\n\n/**\n * Config for .use(\"transform\", transformConfig)\n */\nexport const transformConfig = {\n interpolate: interpolateTransform,\n validate: validateTransform,\n};\n","let _nowFunc = () => globalThis.performance.now();\n\nexport const now = (): number => {\n return _nowFunc();\n};\n\nexport function setNow(nowFunction: typeof _nowFunc) {\n _nowFunc = nowFunction;\n}\n","// Runtime.ts\nimport type { AnimationItem, TweenProps } from \"./types.d.ts\";\nimport { now } from \"./Now.ts\";\n\n/**\n * The runtime queue\n */\nexport const Queue: AnimationItem[] = new Array(0);\n\nlet rafID = 0;\nlet queueLength = 0;\n\n/**\n * The hot update loop updates all items in the queue,\n * and stops automatically when there are no items left.\n * @param t execution time (performance.now)\n */\nexport function Runtime(t = now()) {\n let i = 0;\n // queueLength = Queue.length;\n while (i < queueLength) {\n if (Queue[i]?.update(t)) {\n i += 1;\n } else {\n Queue.splice(i, 1);\n queueLength--;\n }\n }\n\n if (queueLength === 0) {\n cancelAnimationFrame(rafID);\n rafID = 0;\n } else rafID = requestAnimationFrame(Runtime);\n}\n\n/**\n * Add a new item to the update loop.\n * If it's the first item, it will also start the update loop.\n * @param newItem Tween / Timeline\n */\nexport function addToQueue<T extends TweenProps>(\n newItem: AnimationItem<T>,\n): void {\n // istanbul ignore else @preserve\n if (Queue.includes(newItem as AnimationItem<never>)) return;\n // Queue.push(item);\n Queue[queueLength++] = newItem as AnimationItem<never>;\n // istanbul ignore else @preserve\n if (!rafID) Runtime();\n}\n\n/**\n * Remove item from the update loop.\n * @param newItem Tween / Timeline\n */\nexport function removeFromQueue<T extends TweenProps>(\n removedItem: AnimationItem<T>,\n): void {\n const idx = Queue.indexOf(removedItem as AnimationItem<never>);\n // istanbul ignore else @preserve\n if (idx > -1) {\n Queue.splice(idx, 1);\n queueLength--;\n }\n}\n","// Tween.ts\nimport type {\n DeepPartial,\n EasingFunction,\n InterpolatorFunction,\n PropConfig,\n TweenCallback,\n TweenProps,\n TweenRuntime,\n TweenUpdateCallback,\n ValidationFunction,\n} from \"./types.d.ts\";\nimport {\n deepAssign,\n deproxy,\n isArray,\n isObject,\n validateValues,\n} from \"./Util.ts\";\nimport { addToQueue, removeFromQueue } from \"./Runtime.ts\";\nimport { now } from \"./Now.ts\";\n\n/**\n * Lightweight tween engine for interpolating values over time.\n * Supports numbers and via extensions it enxtends to arrays\n * (e.g. RGB, points), nested objects, and SVG path morphing.\n *\n * @template T - The type of the target object (usually a plain object with numeric properties)\n *\n * @example\n * ```ts\n * const tween = new Tween({ x: 0, opacity: 1 })\n * .to({ x: 300, opacity: 0 })\n * .duration(1.5)\n * .easing(Easing.Elastic.Out)\n * .start();\n * ```\n *\n * @param initialValues The initial values object\n */\nexport class Tween<T extends TweenProps = TweenProps> {\n state: T;\n private _state: T;\n private _startIsSet = false;\n private _repeat = 0;\n private _yoyo = false;\n private _reversed = false;\n private _initialRepeat = 0;\n private _startFired = false;\n private _propsStart: Partial<T> = {};\n private _propsEnd: Partial<T> = {};\n private _isPlaying = false;\n private _duration = 1000;\n private _delay = 0;\n private _pauseStart = 0;\n private _repeatDelay = 0;\n private _startTime: number = 0;\n private _errors = new Map<string | \"init\", string>();\n private _interpolators = new Map<string | keyof T, InterpolatorFunction>();\n private _validators = new Map<string | keyof T, ValidationFunction>();\n private _easing: EasingFunction = (t) => t;\n private _onUpdate?: TweenUpdateCallback<T>;\n private _onComplete?: TweenCallback<T>;\n private _onStart?: TweenCallback<T>;\n private _onStop?: TweenCallback<T>;\n private _onPause?: TweenCallback<T>;\n private _onResume?: TweenCallback<T>;\n private _onRepeat?: TweenCallback<T>;\n private _runtime: (TweenRuntime<T>)[] = [];\n /**\n * Creates a new Tween instance.\n * @param initialValues - The initial state of the animated object\n */\n constructor(initialValues: T) {\n // we must initialize state to allow isValidState to work from here\n this.state = {} as T;\n validateValues.call(this as unknown as Tween, initialValues);\n if (this._errors.size) {\n // we temporarily store initialValues reference here\n this._state = initialValues;\n } else {\n // or set values right away\n this.state = initialValues;\n this._state = deproxy(initialValues);\n }\n\n return this;\n }\n\n // GETTERS FIRST\n /**\n * A boolean that returns `true` when tween is playing.\n */\n get isPlaying(): boolean {\n return this._isPlaying;\n }\n\n /**\n * A boolean that returns `true` when tween is paused.\n */\n get isPaused(): boolean {\n return this._pauseStart > 0;\n }\n\n /**\n * A boolean that returns `true` when initial values are valid.\n */\n get isValidState(): boolean {\n return Object.keys(this.state).length > 0;\n }\n\n /**\n * A boolean that returns `true` when all values are valid.\n */\n get isValid(): boolean {\n return this._errors.size === 0;\n }\n\n /**\n * Returns the configured duration in seconds.\n */\n getDuration() {\n return this._duration / 1000;\n }\n\n /**\n * Returns the total duration in seconds. It's calculated as a sum of\n * the delay, duration multiplied by repeat value, repeat delay multiplied\n * by repeat value.\n */\n get totalDuration() {\n const repeat = this._initialRepeat;\n return (\n this._delay +\n this._duration * (repeat + 1) +\n this._repeatDelay * repeat\n ) / 1000;\n }\n\n /**\n * Returns the validator configured for a given property.\n */\n getValidator(propName: string) {\n return this._validators.get(propName);\n }\n\n /**\n * Returns the errors Map, mainly used by external validators.\n */\n getErrors() {\n return this._errors;\n }\n\n /**\n * Starts the tween (adds it to the global update loop).\n * Triggers `onStart` if set.\n * @param time - Optional explicit start time (defaults to `now()`)\n * @param overrideStart - If true, resets starting values even if already set\n * @returns this\n */\n start(time = now(), overrideStart = false) {\n if (this._isPlaying) return this;\n if (this._pauseStart) return this.resume();\n if (!this.isValid) {\n this._report();\n return this;\n }\n // micro-optimization - don't reset state if never started\n if (this._startTime && !overrideStart) this._resetState();\n\n // istanbul ignore else @preserve\n if (!this._startIsSet || /* istanbul ignore next */ overrideStart) {\n this._startIsSet = true;\n\n this._setProps(\n this.state,\n this._propsStart,\n this._propsEnd,\n overrideStart,\n );\n }\n this._isPlaying = true;\n this._startTime = time;\n this._startTime += this._delay;\n\n addToQueue(this);\n return this;\n }\n\n /**\n * Starts the tween from current values.\n * @param time - Optional explicit start time (defaults to `now()`)\n * @returns this\n */\n startFromLast(time = now()) {\n return this.start(time, true);\n }\n\n /**\n * Immediately stops the tween and removes it from the update loop.\n * Triggers `onStop` if set.\n * @returns this\n */\n stop() {\n if (!this._isPlaying) return this;\n removeFromQueue(this);\n this._isPlaying = false;\n this._repeat = this._initialRepeat;\n this._reversed = false;\n\n this._onStop?.(this.state);\n return this;\n }\n\n /**\n * Reverses playback direction and mirrors current time position.\n * @returns this\n */\n reverse(): this {\n // istanbul ignore next @preserve\n if (!this._isPlaying) return this;\n\n const currentTime = now();\n const elapsed = currentTime - this._startTime;\n this._startTime = currentTime - (this._duration - elapsed);\n this._reversed = !this._reversed;\n\n // istanbul ignore else @preserve\n if (this._initialRepeat > 0) {\n this._repeat = this._initialRepeat - this._repeat;\n }\n\n return this;\n }\n\n /**\n * Pause playback and capture the pause time.\n * @param time - Time of pause\n * @returns this\n */\n pause(time = now()): this {\n if (!this._isPlaying) return this;\n\n this._pauseStart = time;\n this._isPlaying = false;\n this._onPause?.(this.state);\n\n return this;\n }\n\n /**\n * Resume playback and reset the pause time.\n * @param time - Time of pause\n * @returns this\n */\n resume(time = now()): this {\n if (!this._pauseStart) return this;\n\n this._startTime += time - this._pauseStart;\n this._pauseStart = 0;\n this._isPlaying = true;\n this._onResume?.(this.state);\n\n addToQueue(this);\n\n return this;\n }\n\n /**\n * Sets the starting values for properties.\n * @param startValues - Partial object with starting values\n * @returns this\n */\n from(startValues: Partial<T> | DeepPartial<T>) {\n if (!this.isValidState || this.isPlaying) return this;\n\n this._evaluate(startValues);\n if (this.isValid) {\n Object.assign(this._propsStart, startValues);\n this._startIsSet = false;\n }\n\n return this;\n }\n\n /**\n * Sets the ending values for properties.\n * @param endValues - Partial object with target values\n * @returns this\n */\n to(endValues: Partial<T> | DeepPartial<T>) {\n if (!this.isValidState || this.isPlaying) return this;\n\n this._evaluate(endValues);\n if (this.isValid) {\n this._propsEnd = endValues as T;\n this._startIsSet = false;\n }\n\n return this;\n }\n\n /**\n * Sets the duration of the tween in seconds.\n * Internally it's converted to milliseconds.\n * @param duration - Time in seconds\n * @default 1 second\n * @returns this\n */\n duration(seconds = 1) {\n this._duration = seconds * 1000;\n return this;\n }\n\n /**\n * Sets the delay in seconds before the tween starts.\n * Internally it's converted to milliseconds.\n * @param delay - Time in seconds\n * @default 0 seconds\n * @returns this\n */\n delay(seconds = 0) {\n this._delay = seconds * 1000;\n return this;\n }\n\n /**\n * Sets how many times to repeat.\n * @param times - How many times to repeat\n * @default 0 times\n * @returns this\n */\n repeat(times = 0) {\n this._repeat = times;\n this._initialRepeat = times;\n return this;\n }\n\n /**\n * Sets a number of seconds to delay the animation\n * after each repeat.\n * @param seconds - How many seconds to delay\n * @default 0 seconds\n * @returns this\n */\n repeatDelay(seconds = 0) {\n this._repeatDelay = seconds * 1000;\n return this;\n }\n\n /**\n * Sets to tween from end to start values.\n * The easing is also goes backwards.\n * This requires repeat value of at least 1.\n * @param yoyo - When `true` values are reversed on every uneven repeat\n * @default false\n * @returns this\n */\n yoyo(yoyo = false) {\n this._yoyo = yoyo;\n return this;\n }\n\n /**\n * Sets the easing function.\n * @param easing - Function that maps progress [0,1] → eased progress [0,1]\n * @default linear\n * @returns this\n */\n easing(easing: EasingFunction = (t: number) => t) {\n this._easing = easing;\n return this;\n }\n\n /**\n * Registers a callback fired when `.start()` is called.\n * @param callback - Receives state at start time\n * @returns this\n */\n onStart(callback: TweenCallback<T>) {\n this._onStart = callback;\n return this;\n }\n\n /**\n * Registers a callback fired on every frame.\n * @param callback - Receives current state, elapsed (0–1)\n * @returns this\n */\n onUpdate(callback?: TweenUpdateCallback<T>) {\n this._onUpdate = callback;\n return this;\n }\n\n /**\n * Registers a callback fired when the tween reaches progress = 1.\n * @param callback - Receives final state\n * @returns this\n */\n onComplete(callback: TweenCallback<T>) {\n this._onComplete = callback;\n return this;\n }\n\n /**\n * Registers a callback fired when `.stop()` is called.\n * @param callback - Receives state at stop time\n * @returns this\n */\n onStop(callback: TweenCallback<T>) {\n this._onStop = callback;\n return this;\n }\n\n /**\n * Registers a callback fired when `pause()` was called.\n */\n onPause(cb: TweenCallback<T>) {\n this._onPause = cb;\n return this;\n }\n\n /**\n * Registers a callback fired when `.resume()` was called.\n */\n onResume(cb: TweenCallback<T>) {\n this._onResume = cb;\n return this;\n }\n\n /**\n * Registers a callback that is invoked **every time** one full cycle\n * (repeat iteration) * of the tween has completed — but **before**\n * the next repeat begins (if any remain).\n *\n * This is different from `onComplete`, which only fires once at the\n * very end of the entire tween (after all repeats are finished).\n */\n onRepeat(cb?: TweenCallback<T>) {\n this._onRepeat = cb;\n return this;\n }\n\n /**\n * Manually advances the tween to the given time.\n * @param time - Current absolute time (performance.now style)\n *\n * @returns `true` if the tween is still playing after the update, `false`\n * otherwise.\n */\n update(time = now()) {\n // istanbul ignore else\n if (!this._isPlaying) return false;\n\n // istanbul ignore else\n if (time < this._startTime) return true;\n\n // istanbul ignore else\n if (!this._startFired) {\n this._onStart?.(this.state);\n this._startFired = true;\n }\n\n const reversed = this._reversed;\n const state = this.state;\n const runtime = this._runtime;\n let progress = (time - this._startTime) / this._duration;\n // some limits are in good order for reverse\n // if (progress < 0) progress = 0;\n if (progress > 1) progress = 1;\n\n // super cheap yoyo\n let eased = this._easing(reversed ? 1 - progress : progress);\n eased = reversed ? 1 - eased : eased;\n\n const len = runtime.length;\n let i = 0;\n while (i < len) {\n const prop = runtime[i++];\n const targetObject = prop[0];\n const property = prop[1];\n const interpolator = prop[2];\n const startVal = reversed ? prop[4] : prop[3];\n const endVal = reversed ? prop[3] : prop[4];\n\n if (typeof endVal === \"number\") {\n state[property as keyof T] =\n ((startVal as number) + (endVal - (startVal as number)) * eased) as T[\n keyof T\n ];\n } else {\n interpolator(\n targetObject as never,\n startVal as never,\n endVal as never,\n eased,\n );\n }\n }\n\n this._onUpdate?.(state, progress);\n\n // istanbul ignore else\n if (progress === 1) {\n if (this._repeat === 0) {\n this._isPlaying = false;\n this._repeat = this._initialRepeat;\n this._reversed = false;\n this._onComplete?.(state);\n return false;\n }\n // istanbul ignore else @preserve\n if (this._repeat !== Infinity) this._repeat--;\n // istanbul ignore else @preserve\n if (this._yoyo) this._reversed = !reversed;\n this._startTime = time;\n this._startTime += this._repeatDelay;\n this._onRepeat?.(state);\n return true;\n }\n\n return true;\n }\n\n /**\n * Public method to register an extension for a given property.\n *\n * **NOTES**\n * - the extension will validate the initial values once `.use()` is called.\n * - the `.use()` method must be called before `.to()` / `.from()`.\n *\n * @param property The property name\n * @param extension The extension object\n * @returns this\n *\n * @example\n *\n * const tween = new Tween({ myProp: { x: 0, y: 0 } });\n * tween.use(\"myProp\", objectConfig);\n */\n use(property: string, { interpolate, validate }: PropConfig): this {\n // istanbul ignore else\n if (interpolate && !this._interpolators.has(property)) {\n this._interpolators.set(property, interpolate);\n }\n if (validate && !this._validators.has(property)) {\n this._validators.set(property, validate);\n }\n this._evaluate();\n return this;\n }\n\n /**\n * Internal method to reset state to initial values.\n * @internal\n */\n private _resetState() {\n deepAssign(this.state, this._state);\n }\n\n /**\n * Reset starting values, end values and runtime.\n */\n clear() {\n this._propsStart = {} as T;\n this._propsEnd = {} as T;\n this._runtime.length = 0;\n this._startTime = 0;\n this._pauseStart = 0;\n this._repeat = 0;\n this._initialRepeat = 0;\n return this;\n }\n\n /**\n * Internal method to handle instrumentation of start and end values for interpolation.\n * @internal\n */\n private _setProps(\n obj: T,\n propsStart: Partial<T>,\n propsEnd: Partial<T>,\n overrideStartingValues: boolean,\n ): void {\n const endKeys = Object.keys(propsEnd) as (keyof T)[];\n const len = endKeys.length;\n this._runtime.length = 0;\n let rtLen = 0;\n let i = 0;\n\n while (i < len) {\n const property = endKeys[i++];\n\n // Save the starting value, but only once unless override is requested.\n // istanbul ignore else\n if (\n typeof propsStart[property] === \"undefined\" ||\n overrideStartingValues\n ) {\n const objValue = obj[property] as T[keyof T];\n\n // Update start property value\n if (isObject(objValue) || isArray(objValue)) {\n propsStart[property] = deproxy(objValue);\n } else {\n // number\n propsStart[property] = objValue;\n }\n\n // Pre-register interpolator\n const interpolator = this._interpolators.get(property) || null;\n\n // Store all values needed for interpolation\n this._runtime[rtLen++] = [\n objValue,\n property,\n interpolator,\n propsStart[property] as T[keyof T],\n propsEnd[property] as T[keyof T],\n ] as TweenRuntime<T>;\n }\n }\n }\n\n /**\n * Internal method to handle validation of initial values, start and end values.\n * @internal\n */\n private _evaluate(newObj?: Partial<T> | DeepPartial<T>) {\n // the reference of the initialization state is stored here\n // istanbul ignore else @preserve\n if (!this.isValidState) {\n const temp = this._state;\n validateValues.call(this as unknown as Tween, temp);\n // istanbul ignore else @preserve\n if (this.isValid) {\n this.state = temp;\n this._state = deproxy(temp);\n }\n } else if (newObj) {\n validateValues.call(this as unknown as Tween, newObj, this._state);\n }\n return this;\n }\n\n /**\n * Internal method to provide feedback on validation issues.\n * @internal\n */\n private _report() {\n // istanbul ignore else @preserve\n if (!this.isValid) {\n const message = [\n \"[Tween] failed validation:\",\n \"- \" + Array.from(this._errors.values()).join(\"\\n- \"),\n ];\n\n console.warn(message.join(\"\\n\"));\n }\n return this;\n }\n}\n","// Timeline.ts\nimport type {\n DeepPartial,\n InterpolatorFunction,\n Position,\n PropConfig,\n TimelineCallback,\n TimelineEntry,\n TimelineEntryConfig,\n TweenProps,\n ValidationFunction,\n} from \"./types.d.ts\";\nimport { addToQueue, removeFromQueue } from \"./Runtime.ts\";\nimport {\n deepAssign,\n deproxy,\n isArray,\n isObject,\n validateValues,\n} from \"./Util.ts\";\nimport { now } from \"./Now.ts\";\n\n/**\n * Timeline orchestrates multiple tweens with scheduling, overlaps, labels and repeat.\n * Supports numbers and via extensions it enxtends to arrays\n * (e.g. RGB, points), nested objects, and SVG path morphing.\n *\n * @template T - Type of the animated state object\n *\n * @example\n * ```ts\n * const tl = new Timeline({ x: 0, opacity: 0 })\n * .to({ x: 300, duration: 1.2 })\n * .to({ opacity: 1, duration: 0.8 }, \"-=0.4\")\n * .play();\n * ```\n *\n * @param initialValues The initial values object\n */\nexport class Timeline<T extends TweenProps = TweenProps> {\n public state: T;\n private _state: T;\n private _entries: TimelineEntry<T>[] = [];\n private _labels = new Map<string, number>();\n private _progress = 0;\n private _duration = 0;\n private _yoyo = false;\n private _reversed = false;\n private _time = 0;\n private _pauseTime = 0;\n private _lastTime = 0;\n private _isPlaying = false;\n private _repeat = 0;\n private _repeatDelay = 0;\n private _repeatDelayStart = 0;\n private _initialRepeat = 0;\n private _errors = new Map<string | \"init\", string>();\n private _interpolators = new Map<string | keyof T, InterpolatorFunction>();\n private _validators = new Map<string | keyof T, ValidationFunction>();\n private _onStart?: TimelineCallback<T>;\n private _onStop?: TimelineCallback<T>;\n private _onPause?: TimelineCallback<T>;\n private _onResume?: TimelineCallback<T>;\n private _onUpdate?: TimelineCallback<T>;\n private _onComplete?: TimelineCallback<T>;\n private _onRepeat?: TimelineCallback<T>;\n\n /**\n * Creates a new Timeline instance.\n * @param initialValues - The initial state of the animated object\n */\n constructor(initialValues: T) {\n // we must initialize state to allow isValidState to work from here\n this.state = {} as T;\n validateValues.call(this as Timeline, initialValues);\n if (this._errors.size) {\n // we temporarily store initialValues reference here\n this._state = initialValues;\n } else {\n this.state = initialValues;\n this._state = { ...initialValues };\n }\n\n return this;\n }\n\n // GETTERS FIRST\n /**\n * Returns the current [0-1] progress value.\n */\n get progress() {\n return this._progress;\n }\n\n /**\n * Returns the total duration in seconds.\n */\n get duration() {\n return this._duration / 1000;\n }\n\n /**\n * Returns the total duration in seconds, which is a sum of all entries duration\n * multiplied by repeat value and repeat delay multiplied by repeat value.\n */\n get totalDuration() {\n const repeat = this._initialRepeat;\n return (\n this._duration * (repeat + 1) +\n this._repeatDelay * repeat\n ) / 1000;\n }\n\n /**\n * A boolean that returns `true` when timeline is playing.\n */\n get isPlaying(): boolean {\n return this._isPlaying;\n }\n\n /**\n * A boolean that returns `true` when timeline is paused.\n */\n get isPaused(): boolean {\n return !this._isPlaying && this._pauseTime > 0;\n }\n\n /**\n * A boolean that returns `true` when initial values are valid.\n */\n get isValidState(): boolean {\n return Object.keys(this.state).length > 0;\n }\n\n /**\n * A boolean that returns `true` when all values are valid.\n */\n get isValid(): boolean {\n return this._errors.size === 0;\n }\n\n /**\n * Returns the validator configured for a given property.\n */\n getValidator(propName: string) {\n return this._validators.get(propName);\n }\n\n /**\n * Returns the errors Map, mainly used by external validators.\n */\n getErrors() {\n return this._errors;\n }\n\n /**\n * Starts or resumes playback from the beginning (or current time if resumed).\n * Triggers the `onStart` callback if set.\n * @param startTime - Optional explicit start timestamp (defaults to now)\n * @returns this\n */\n play(time = now()): this {\n if (this._pauseTime) return this.resume();\n if (this._isPlaying) return this;\n if (!this.isValid) {\n this._report();\n return this;\n }\n if (this._time) this._resetState();\n this._isPlaying = true;\n this._lastTime = time;\n this._time = 0;\n this._onStart?.(this.state, 0);\n\n addToQueue(this);\n return this;\n }\n\n /**\n * Pauses playback (preserves current time).\n * Triggers the `onPause` callback if set.\n * @returns this\n */\n pause(time = now()): this {\n if (!this._isPlaying) return this;\n this._isPlaying = false;\n this._pauseTime = time;\n this._onPause?.(this.state, this.progress);\n return this;\n }\n\n /**\n * Resumes from paused state (adjusts internal clock).\n * Triggers the `onResume` callback if set.\n\n * @param time - Optional current timestamp (defaults to now)\n * @returns this\n */\n resume(time = now()): this {\n if (this._isPlaying) return this;\n this._isPlaying = true;\n const dif = time - this._pauseTime;\n this._pauseTime = 0;\n this._lastTime += dif;\n this._onResume?.(this.state, this.progress);\n\n addToQueue(this);\n return this;\n }\n\n /**\n * Reverses playback direction and mirrors current time position.\n * @returns this\n */\n reverse(): this {\n if (!this._isPlaying) return this;\n\n this._reversed = !this._reversed;\n this._time = this._duration - this._time;\n\n // istanbul ignore else @preserve\n if (this._initialRepeat > 0) {\n this._repeat = this._initialRepeat - this._repeat;\n }\n\n return this;\n }\n\n /**\n * Jumps to a specific time or label. When playback is reversed\n * the time is adjusted.\n * @param pointer - Seconds or label name\n * @returns this\n */\n seek(pointer: number | string): this {\n const elapsed = this._resolvePosition(pointer);\n\n this._time = elapsed;\n return this;\n }\n\n /**\n * Stops playback, resets time to 0, and restores initial state.\n * Triggers the `onStop` callback if set.\n * @returns this\n */\n stop(): this {\n if (!this._isPlaying) return this;\n this._isPlaying = false;\n this._time = 0;\n this._pauseTime = 0;\n this._repeat = this._initialRepeat;\n this._reversed = false;\n removeFromQueue(this);\n this._onStop?.(this.state, this._progress);\n return this;\n }\n\n /**\n * Sets the number of times the timeline should repeat.\n * @param count - Number of repeats (0 = once, Infinity = loop forever)\n * @returns this\n */\n repeat(count = 0): this {\n this._repeat = count;\n this._initialRepeat = count;\n return this;\n }\n\n /**\n * Sets a number of seconds to delay the animation\n * after each repeat.\n * @param amount - How many seconds to delay\n * @default 0 seconds\n * @returns this\n */\n repeatDelay(amount = 0) {\n this._repeatDelay = amount * 1000;\n return this;\n }\n\n /**\n * Sets to Timeline entries to tween from end to start values.\n * The easing is also goes backwards.\n * This requires repeat value of at least 1.\n * @param yoyo - When `true` values are reversed\n * @default false\n * @returns this\n */\n yoyo(yoyo = false) {\n this._yoyo = yoyo;\n return this;\n }\n\n /**\n * Adds a named time position for use in `.seek(\"label\")`.\n * @param name - Label identifier\n * @param position - Time offset or relative position\n * @returns this\n */\n label(name: string, position?: Position): this {\n this._labels.set(name, this._resolvePosition(position));\n return this;\n }\n\n /**\n * Adds a new tween entry to the timeline.\n * @param config - Values to animate + duration, easing, etc.\n * @param position - Start offset: number, \"+=0.5\", \"-=0.3\", or label name\n * @returns this (chainable)\n */\n to(\n {\n duration = 1,\n easing = (t) => t,\n ...values\n }: (Partial<T> | DeepPartial<T>) & TimelineEntryConfig,\n position: Position = \"+=0\",\n ): this {\n if (!this.isValidState || this._isPlaying) return this;\n\n this._evaluate(values as Partial<T> | DeepPartial<T>);\n if (this.isValid) {\n const startTime = this._resolvePosition(position);\n const to = values as Partial<T> | DeepPartial<T>;\n const from = {} as Partial<T>;\n const entryDuration = duration * 1000;\n const runtime = [] as TimelineEntry<T>[\"runtime\"];\n\n this._entries.push({\n from,\n to,\n runtime,\n startTime,\n duration: entryDuration,\n easing,\n isActive: false,\n });\n\n const endTime = startTime + entryDuration;\n this._duration = Math.max(this._duration, endTime);\n }\n return this;\n }\n\n /**\n * Registers a callback fired when playback begins.\n */\n onStart(cb: TimelineCallback<T>): this {\n this._onStart = cb;\n return this;\n }\n\n /**\n * Registers a callback fired when `pause()` was called.\n */\n onPause(cb: TimelineCallback<T>): this {\n this._onPause = cb;\n return this;\n }\n\n /**\n * Registers a callback fired when `.play()` / `.resume()` was called.\n */\n onResume(cb: TimelineCallback<T>): this {\n this._onResume = cb;\n return this;\n }\n\n /**\n * Registers a callback fired on explicit `.stop()`.\n */\n onStop(cb: TimelineCallback<T>): this {\n this._onStop = cb;\n return this;\n }\n\n /**\n * Registers a callback fired every frame.\n */\n onUpdate(cb: TimelineCallback<T>): this {\n this._onUpdate = cb;\n return this;\n }\n\n /**\n * Registers a callback fired when timeline naturally completes.\n */\n onComplete(cb: TimelineCallback<T>): this {\n this._onComplete = cb;\n return this;\n }\n\n /**\n * Registers a callback fired when `.play()` / `.resume()` was called.\n */\n onRepeat(cb?: TimelineCallback<T>) {\n this._onRepeat = cb;\n return this;\n }\n\n /**\n * Public method to register an extension for a given property.\n *\n * **NOTES**\n * - the extension will validate the initial values once `.use()` is called.\n * - the `.use()` method must be called before `.to()`.\n *\n * @param property The property name\n * @param extension The extension object\n * @returns this\n *\n * @example\n *\n * const timeline = new Timeline({ myProp: { x: 0, y: 0 } });\n * timeline.use(\"myProp\", objectConfig);\n */\n use(property: string, { interpolate, validate }: PropConfig): this {\n // istanbul ignore else\n if (interpolate && !this._interpolators.has(property)) {\n this._interpolators.set(property, interpolate);\n }\n if (validate && !this._validators.has(property)) {\n this._validators.set(property, validate);\n }\n this._evaluate();\n return this;\n }\n\n /**\n * Manually advances the timeline to the given time.\n * @param time - Current absolute time (performance.now style)\n *\n * @returns `true` if the timeline is still playing after the update, `false`\n * otherwise.\n */\n update(time = now()) {\n if (!this._isPlaying) return false;\n\n if (this._repeatDelayStart) {\n if (time - this._repeatDelayStart < this._repeatDelay) {\n this._lastTime = time; // Update lastTime to prevent delta accumulation\n return true;\n }\n // Delay complete\n this._repeatDelayStart = 0;\n }\n\n const delta = time - this._lastTime;\n const reversed = this._reversed;\n this._lastTime = time;\n this._time += delta;\n\n this._progress = this._time > this._duration\n ? 1\n : this._time / this._duration;\n\n const entries = this._entries;\n const state = this.state;\n const entriesLen = entries.length;\n let i = 0;\n\n while (i < entriesLen) {\n const entry = entries[i++];\n\n // reverse start time\n const startTime = !reversed\n ? entry.startTime\n : this._duration - entry.startTime - entry.duration;\n\n const localTime = this._time - startTime;\n\n // Calculate local time within the entry's duration\n let tweenElapsed = localTime / entry.duration;\n // some limits are in good order for reverse\n if (tweenElapsed > 1) tweenElapsed = 1;\n if (tweenElapsed < 0) tweenElapsed = 0;\n\n // Only build runtime once on first activation\n if (!entry.isActive && tweenElapsed > 0 && tweenElapsed < 1) {\n // istanbul ignore else @preserve\n if (entry.runtime.length === 0) {\n this._setEntry(entry, state);\n }\n entry.isActive = true;\n }\n\n // istanbul ignore else @preserve\n if (entry.isActive) {\n // super cheap yoyo\n let easedValue = entry.easing(\n reversed ? 1 - tweenElapsed : tweenElapsed,\n );\n easedValue = reversed ? 1 - easedValue : easedValue;\n const runtime = entry.runtime;\n\n const runtimeLen = runtime.length;\n let j = 0;\n while (j < runtimeLen) {\n const prop = runtime[j++];\n const targetObject = prop[0];\n const property = prop[1];\n const interpolator = prop[2];\n const startVal = reversed ? prop[4] : prop[3];\n const endVal = reversed ? prop[3] : prop[4];\n\n if (typeof endVal === \"number\") {\n state[property as keyof T] = ((startVal as number) +\n (endVal - (startVal as number)) * easedValue) as T[keyof T];\n } else {\n interpolator(\n targetObject as never,\n startVal as never,\n endVal as never,\n easedValue,\n );\n }\n }\n if (tweenElapsed === 1) entry.isActive = false;\n }\n }\n\n this._onUpdate?.(state, this._progress);\n\n // istanbul ignore else\n if (this._progress === 1) {\n // istanbul ignore else\n if (this._repeat === 0) {\n this._isPlaying = false;\n this._repeat = this._initialRepeat;\n this._reversed = false;\n this._onComplete?.(state, 1);\n this._resetState(true);\n\n return false;\n }\n\n // istanbul ignore else @preserve\n if (this._repeat !== Infinity) this._repeat--;\n if (this._yoyo) this._reversed = !reversed;\n\n this._time = 0;\n this._resetState();\n this._onRepeat?.(state, this.progress);\n\n if (this._repeatDelay > 0) this._repeatDelayStart = time;\n\n return true;\n }\n\n return true;\n }\n\n /**\n * Public method to clear all entries, labels and reset timers to zero\n * or initial value (repeat).\n */\n clear() {\n this._entries.length = 0;\n this._duration = 0;\n this._labels.clear();\n this._time = 0;\n this._progress = 0;\n this._pauseTime = 0;\n this._lastTime = 0;\n this._repeatDelay = 0;\n this._repeat = this._initialRepeat;\n this._repeatDelayStart = 0;\n this._reversed = false;\n return this;\n }\n\n /**\n * Internal method to handle instrumentation of start and end values for interpolation\n * of a tween entry. Only called once per entry on first activation.\n * @internal\n */\n private _setEntry(entry: TimelineEntry<T>, state: T) {\n const from = entry.from as Partial<T>;\n const to = entry.to as Partial<T>;\n const keysTo = Object.keys(to) as (keyof T)[];\n const keyLen = keysTo.length;\n entry.runtime = new Array(keyLen);\n let rtLen = 0;\n let j = 0;\n\n while (j < keyLen) {\n const key = keysTo[j++];\n const objValue = state[key] as T[keyof T];\n\n // Capture current state value for 'from'\n if (isObject(objValue) || isArray(objValue)) {\n from[key] = deproxy(objValue);\n } else {\n // number\n from[key] = objValue;\n }\n\n const interpolator = this._interpolators.get(key) || null;\n\n // Push tuple\n entry.runtime[rtLen++] = [\n objValue,\n key,\n interpolator,\n from[key] as T[keyof T],\n to[key] as T[keyof T],\n ] as TimelineEntry<T>[\"runtime\"][0];\n }\n }\n\n /**\n * Internal method to revert state to initial values and reset entry flags.\n * @internal\n */\n private _resetState(isComplete = false) {\n let i = 0;\n const entriesLen = this._entries.length;\n while (i < entriesLen) {\n const entry = this._entries[i++];\n entry.isActive = false;\n }\n if (!isComplete) {\n deepAssign(this.state, this._state);\n }\n }\n\n /**\n * Internal method to resolve the position relative to the current duration\n * or a set value in seconds.\n * @internal\n */\n private _resolvePosition(pos?: Position): number {\n if (typeof pos === \"number\") {\n return Math.min(this._duration, Math.max(0, pos * 1000));\n }\n\n // istanbul ignore else @preserve\n if (typeof pos === \"string\") {\n // First try label\n const labelTime = this._labels.get(pos);\n if (labelTime !== undefined) return labelTime;\n\n // Then relative\n // istanbul ignore else @preserve\n if (pos.startsWith(\"+=\") || pos.startsWith(\"-=\")) {\n let offset = parseFloat(pos.slice(2));\n if (isNaN(offset)) offset = 0;\n offset *= 1000;\n return pos.startsWith(\"+=\")\n ? this._duration + offset\n : Math.max(0, this._duration - offset);\n }\n }\n\n // Fallback to current duration\n return this._duration;\n }\n\n /**\n * Internal method to handle validation of initial values and entries values.\n * @internal\n */\n private _evaluate(newObj?: Partial<T> | DeepPartial<T>) {\n // the reference of the initialization state is stored here\n // istanbul ignore else @preserve\n if (!this.isValidState) {\n const temp = this._state;\n validateValues.call(this as Timeline, temp);\n // istanbul ignore else @preserve\n if (this.isValid) {\n this.state = temp;\n this._state = deproxy(temp);\n }\n } else if (newObj) {\n validateValues.call(this as Timeline, newObj, this._state);\n }\n return this;\n }\n\n /**\n * Internal method to provide feedback on validation issues.\n * @internal\n */\n private _report() {\n // istanbul ignore else @preserve\n if (!this.isValid) {\n const message = [\n \"[Timeline] failed validation:\",\n \"- \" + Array.from(this._errors.values()).join(\"\\n- \"),\n ].join(\"\\n\");\n\n console.warn(message);\n }\n return this;\n }\n}\n",""],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tween.min.js","names":[],"sources":["../src/Easing.ts","../src/Util.ts","../src/extend/array.ts","../node_modules/.pnpm/svg-path-commander@2.2.1/node_modules/svg-path-commander/dist/util.js","../src/extend/path.ts","../src/extend/object.ts","../src/extend/transform.ts","../src/Now.ts","../src/Runtime.ts","../src/Tween.ts","../src/Timeline.ts","../package.json"],"sourcesContent":["// Easing.ts\nimport type { EasingFunction, EasingFunctionGroup } from \"./types.d.ts\";\n\n/**\n * The Ease class provides a collection of easing functions for use with tween.js.\n */\n\nexport const Easing = Object.freeze({\n Linear: Object.freeze<EasingFunctionGroup & { None: EasingFunction }>({\n None(amount: number): number {\n return amount;\n },\n In(amount: number): number {\n return amount;\n },\n Out(amount: number): number {\n return amount;\n },\n InOut(amount: number): number {\n return amount;\n },\n }),\n\n Quadratic: Object.freeze(\n <EasingFunctionGroup> {\n In(amount: number): number {\n return amount * amount;\n },\n Out(amount: number): number {\n return amount * (2 - amount);\n },\n InOut(amount: number): number {\n if ((amount *= 2) < 1) {\n return 0.5 * amount * amount;\n }\n\n return -0.5 * (--amount * (amount - 2) - 1);\n },\n },\n ),\n\n Cubic: Object.freeze(\n <EasingFunctionGroup> {\n In(amount: number): number {\n return amount * amount * amount;\n },\n Out(amount: number): number {\n return --amount * amount * amount + 1;\n },\n InOut(amount: number): number {\n if ((amount *= 2) < 1) {\n return 0.5 * amount * amount * amount;\n }\n return 0.5 * ((amount -= 2) * amount * amount + 2);\n },\n },\n ),\n\n Quartic: Object.freeze(\n <EasingFunctionGroup> {\n In(amount: number): number {\n return amount * amount * amount * amount;\n },\n Out(amount: number): number {\n return 1 - --amount * amount * amount * amount;\n },\n InOut(amount: number): number {\n if ((amount *= 2) < 1) {\n return 0.5 * amount * amount * amount * amount;\n }\n\n return -0.5 * ((amount -= 2) * amount * amount * amount - 2);\n },\n },\n ),\n\n Quintic: Object.freeze(\n <EasingFunctionGroup> {\n In(amount: number): number {\n return amount * amount * amount * amount * amount;\n },\n Out(amount: number): number {\n return --amount * amount * amount * amount * amount + 1;\n },\n InOut(amount: number): number {\n if ((amount *= 2) < 1) {\n return 0.5 * amount * amount * amount * amount * amount;\n }\n\n return 0.5 * ((amount -= 2) * amount * amount * amount * amount + 2);\n },\n },\n ),\n\n Sinusoidal: Object.freeze(\n <EasingFunctionGroup> {\n In(amount: number): number {\n return 1 - Math.sin(((1.0 - amount) * Math.PI) / 2);\n },\n Out(amount: number): number {\n return Math.sin((amount * Math.PI) / 2);\n },\n InOut(amount: number): number {\n return 0.5 * (1 - Math.sin(Math.PI * (0.5 - amount)));\n },\n },\n ),\n\n Exponential: Object.freeze(\n <EasingFunctionGroup> {\n In(amount: number): number {\n return amount === 0 ? 0 : Math.pow(1024, amount - 1);\n },\n Out(amount: number): number {\n return amount === 1 ? 1 : 1 - Math.pow(2, -10 * amount);\n },\n InOut(amount: number): number {\n if (amount === 0) {\n return 0;\n }\n\n if (amount === 1) {\n return 1;\n }\n\n if ((amount *= 2) < 1) {\n return 0.5 * Math.pow(1024, amount - 1);\n }\n\n return 0.5 * (-Math.pow(2, -10 * (amount - 1)) + 2);\n },\n },\n ),\n\n Circular: Object.freeze(\n <EasingFunctionGroup> {\n In(amount: number): number {\n return 1 - Math.sqrt(1 - amount * amount);\n },\n Out(amount: number): number {\n return Math.sqrt(1 - --amount * amount);\n },\n InOut(amount: number): number {\n if ((amount *= 2) < 1) {\n return -0.5 * (Math.sqrt(1 - amount * amount) - 1);\n }\n return 0.5 * (Math.sqrt(1 - (amount -= 2) * amount) + 1);\n },\n },\n ),\n\n Elastic: Object.freeze(\n <EasingFunctionGroup> {\n In(amount: number): number {\n if (amount === 0) {\n return 0;\n }\n\n if (amount === 1) {\n return 1;\n }\n\n return (\n -Math.pow(2, 10 * (amount - 1)) *\n Math.sin((amount - 1.1) * 5 * Math.PI)\n );\n },\n Out(amount: number): number {\n if (amount === 0) {\n return 0;\n }\n\n if (amount === 1) {\n return 1;\n }\n return (\n Math.pow(2, -10 * amount) * Math.sin((amount - 0.1) * 5 * Math.PI) + 1\n );\n },\n InOut(amount: number): number {\n if (amount === 0) {\n return 0;\n }\n\n if (amount === 1) {\n return 1;\n }\n\n amount *= 2;\n\n if (amount < 1) {\n return (\n -0.5 *\n Math.pow(2, 10 * (amount - 1)) *\n Math.sin((amount - 1.1) * 5 * Math.PI)\n );\n }\n\n return (\n 0.5 *\n Math.pow(2, -10 * (amount - 1)) *\n Math.sin((amount - 1.1) * 5 * Math.PI) +\n 1\n );\n },\n },\n ),\n\n Back: Object.freeze(\n <EasingFunctionGroup> {\n In(amount: number): number {\n const s = 1.70158;\n return amount === 1 ? 1 : amount * amount * ((s + 1) * amount - s);\n },\n Out(amount: number): number {\n const s = 1.70158;\n return amount === 0\n ? 0\n : --amount * amount * ((s + 1) * amount + s) + 1;\n },\n InOut(amount: number): number {\n const s = 1.70158 * 1.525;\n if ((amount *= 2) < 1) {\n return 0.5 * (amount * amount * ((s + 1) * amount - s));\n }\n return 0.5 * ((amount -= 2) * amount * ((s + 1) * amount + s) + 2);\n },\n },\n ),\n\n Bounce: Object.freeze(\n <EasingFunctionGroup> {\n In(amount: number): number {\n return 1 - Easing.Bounce.Out(1 - amount);\n },\n Out(amount: number): number {\n if (amount < 1 / 2.75) {\n return 7.5625 * amount * amount;\n } else if (amount < 2 / 2.75) {\n return 7.5625 * (amount -= 1.5 / 2.75) * amount + 0.75;\n } else if (amount < 2.5 / 2.75) {\n return 7.5625 * (amount -= 2.25 / 2.75) * amount + 0.9375;\n } else {\n return 7.5625 * (amount -= 2.625 / 2.75) * amount + 0.984375;\n }\n },\n InOut(amount: number): number {\n if (amount < 0.5) {\n return Easing.Bounce.In(amount * 2) * 0.5;\n }\n return Easing.Bounce.Out(amount * 2 - 1) * 0.5 + 0.5;\n },\n },\n ),\n\n pow(power = 4): EasingFunctionGroup {\n power = power < Number.EPSILON ? Number.EPSILON : power;\n power = power > 10000 ? 10000 : power;\n return {\n In(amount: number): number {\n return amount ** power;\n },\n Out(amount: number): number {\n return 1 - (1 - amount) ** power;\n },\n InOut(amount: number): number {\n if (amount < 0.5) {\n return (amount * 2) ** power / 2;\n }\n return (1 - (2 - amount * 2) ** power) / 2 + 0.5;\n },\n };\n },\n});\n","import type { DeepObject, DeepPartial, TweenProps } from \"./types.d.ts\";\nimport { type Tween } from \"./Tween.ts\";\nimport { type Timeline } from \"./Timeline.ts\";\n\n// Util.ts\nexport const isString = (value: unknown): value is string =>\n typeof value === \"string\";\n\nexport const isNumber = (value: unknown): value is number =>\n typeof value === \"number\";\n\nexport const isArray = (value: unknown): value is Array<unknown> =>\n Array.isArray(value);\n\nexport const isFunction = (value: unknown): value is () => unknown =>\n typeof value === \"function\";\n\nexport const isObject = (value: unknown): value is Record<string, never> =>\n value !== null &&\n value !== undefined &&\n typeof value === \"object\" &&\n Object.getPrototypeOf(value) === Object.prototype;\n\nexport const isPlainObject = (value: unknown): value is Record<string, never> =>\n isObject(value) && !isArray(value);\n\nexport const isDeepObject = (value: unknown): value is DeepObject =>\n isPlainObject(value) && Object.values(value).some(isPlainObject);\n\nexport const isServer = typeof window === \"undefined\";\n\nconst instanceMethods = [\n \"play\",\n \"label\",\n \"start\",\n \"stop\",\n \"pause\",\n \"resume\",\n \"reverse\",\n \"use\",\n \"clear\",\n \"from\",\n \"to\",\n \"easing\",\n \"delay\",\n \"yoyo\",\n \"repeat\",\n \"update\",\n \"repeatDelay\",\n \"onStart\",\n \"onUpdate\",\n \"onComplete\",\n \"onStop\",\n \"onRepeat\",\n];\n\n/**\n * SSR helper to speed up UI frameworks render.\n *\n * Why:\n * - skip validation\n * - skip ministore creation\n * - allow free-form configuration for signal based frameworks\n */\nconst dummyInstance: Record<string, typeof dummyMethod> = {};\n// istanbul ignore next @preserve\n// const dummyMethod = () => dummyInstance;\nfunction dummyMethod(this: typeof dummyInstance) {\n return this;\n}\n\nfor (let i = 0; i < instanceMethods.length; i++) {\n dummyInstance[instanceMethods[i]] = dummyMethod;\n}\n\nexport { dummyInstance };\n\nexport const objectHasProp = <T extends object>(obj: T, prop: keyof T) =>\n Object.prototype.hasOwnProperty.call(obj, prop);\n\nconst isUnsafeKey = (key: string): boolean =>\n key === \"__proto__\" || key === \"constructor\" || key === \"prototype\";\n\n/**\n * A small utility to deep assign up to one level deep nested objects.\n * This is to prevent breaking reactivity of miniStore.\n *\n * **NOTE** - This doesn't perform ANY check and expects objects values\n * to be validated beforehand.\n * @param target The target to assign values to\n * @param source The source object to assign values from\n */\nexport function deepAssign<T extends TweenProps>(target: T, source: T): void {\n const keys = Object.keys(source) as (keyof T)[];\n let i = 0;\n const len = keys.length;\n\n while (i < len) {\n const key = keys[i++];\n // prevent prototype pollution\n // istanbul ignore next @preserve\n if (isUnsafeKey(key as string) || !objectHasProp(source, key)) {\n continue;\n }\n const targetVal = target[key];\n const sourceVal = source[key];\n\n if (isArray(sourceVal)) {\n // Handle arrays (number[], TransformArray, MorphPathArray)\n const targetArr = targetVal as unknown[];\n let j = 0;\n const arLen = sourceVal.length;\n\n while (j < arLen) {\n const sourceItem = sourceVal[j];\n\n if (isArray(sourceItem)) {\n // Nested array (e.g., TransformStep, MorphPathSegment)\n // if (!isArray(targetArr[j])) {\n // targetArr[j] = [];\n // }\n const targetItem = targetArr[j] as unknown[];\n let k = 0;\n const itemLen = sourceItem.length;\n while (k < itemLen) {\n targetItem[k] = sourceItem[k];\n k++;\n }\n } else {\n // Primitive in array (e.g., number[] like rgb)\n targetArr[j] = sourceItem;\n }\n j++;\n }\n } else if (objectHasProp(target, key) && isObject(sourceVal)) {\n // Handle nested objects (BaseTweenProps)\n deepAssign(targetVal as never, sourceVal as never);\n } else {\n // Primitive value (number)\n target[key] = sourceVal;\n }\n }\n}\n\n/**\n * Creates a new object with the same structure of a target object / array\n * without its proxy elements / properties, only their values.\n *\n * **NOTE** - The utility is useful to create deep clones as well.\n *\n * @param value An object / array with proxy elements\n * @returns the object / array value without proxy elements\n */\nexport const deproxy = <T>(value: T): T => {\n if (isArray(value)) {\n return value.map(deproxy) as T;\n }\n\n if (isPlainObject(value)) {\n const result: Record<string, unknown> = {};\n for (const key in value) {\n // istanbul ignore else @preserve\n if (objectHasProp(value, key)) {\n result[key] = deproxy(value[key]);\n }\n }\n return result as T;\n }\n\n return value;\n};\n\n/**\n * Test values validity or their compatibility with the validated ones\n * in the state. This is something we don't want to do in the runtime\n * update loop.\n * @param this The Tween/Timeline instance\n * @param target The target object to validate\n * @param reference The reference state value\n * @returns void\n */\nexport function validateValues<T extends TweenProps>(\n this: Timeline | Tween,\n target: Partial<T> | DeepPartial<T>,\n reference?: T,\n) {\n const errors = this.getErrors();\n\n if (!isPlainObject(target) || Object.keys(target).length === 0) {\n errors.set(\"init\", \"Initialization value is empty or not an object.\");\n return;\n }\n\n const keys = Object.keys(target);\n\n // skip if from()/to() was used before one another\n // we don't want to validate props invalidated!\n if (reference && keys.some((key) => errors.has(key))) {\n return;\n }\n\n // Validate every value\n let i = 0;\n while (i < keys.length) {\n const key = keys[i++];\n const refValue = reference?.[key];\n const value = target[key];\n\n // everything else is either number or not supported\n if (isNumber(value)) {\n // no error there\n // this.removeError(key);\n continue; // good value\n }\n\n if (value === undefined || value === null) {\n errors.set(key, `Property \"${key}\" is null/undefined.`);\n continue;\n }\n\n if (reference && refValue === undefined) {\n errors.set(key, `Property \"${key}\" doesn't exist in state yet.`);\n continue;\n }\n\n // allow validators to override default validation behavior\n const validator = this.getValidator(key);\n if (validator) {\n const [valid, reason] = validator(key, value, refValue as never);\n if (valid) errors.delete(key);\n else errors.set(key, reason as string);\n continue;\n }\n\n if (reference && isNumber(refValue)) {\n // istanbul ignore else @preserve\n if (!isNumber(value)) {\n errors.set(key, `Property \"${key}\" is not a number.`);\n }\n // only validators can revalidate\n // this case can never be covered\n // else this.removeError(key);\n\n continue;\n }\n\n // Any value here is either not valid or not supported yet\n errors.set(\n key,\n `Property \"${key}\" of type \"${\n isArray(value) ? \"array\" : typeof value\n }\" is not supported yet.`,\n );\n }\n errors.delete(\"init\");\n}\n","// src/extend/array.ts\nimport { isArray, isNumber } from \"../Util.ts\";\nimport { InterpolatorFunction, ValidationResultEntry } from \"../types.ts\";\n\n/**\n * Interpolates two `Array<number>` values.\n *\n * **NOTE**: Values my be validated first!\n *\n * @param target The target `Array<number>` value of the state object\n * @param start The start `Array<number>` value\n * @param end The end `Array<number>` value\n * @param t The progress value\n * @returns The interpolated `Array<number>` value.\n */\nexport const interpolateArray: InterpolatorFunction<number[]> = <\n T extends number[],\n>(\n target: T,\n start: T,\n end: T,\n t: number,\n) => {\n const len = end.length;\n let i = 0;\n\n while (i < len) {\n target[i] = start[i] + (end[i] - start[i]) * t;\n i += 1;\n }\n\n return target;\n};\n\n/**\n * Check if a value is a valid `Array<number>` for interpolation.\n * @param target The array to check\n * @returns `true` is value is array and all elements are numbers\n */\nexport const isValidArray = <T extends number[]>(\n target: unknown,\n): target is T => isArray(target) && target.every(isNumber);\n\n/**\n * Check if an `Array<number>` is valid and compatible with a reference.\n *\n * @param target The incoming value `from()` / `to()`\n * @param ref The state reference value\n * @returns [boolean, reason] tuple with validation state as boolean and,\n * if not valid, a reason why it's not valid\n */\nexport const validateArray = <T extends number[]>(\n propName: string,\n target: unknown,\n ref?: T,\n): ValidationResultEntry => {\n // istanbul ignore if @preserve\n if (!isArray(target)) {\n return [false, `Property \"${String(propName)}\" is not Array.`];\n }\n // istanbul ignore if @preserve\n if (!isValidArray(target)) {\n return [\n false,\n `Property \"${String(propName)}\" is not a valid Array<number>.`,\n ];\n }\n\n if (ref && ref.length !== target.length) {\n return [\n false,\n `Property \"${\n String(propName)\n }\" is expecting an array of ${ref.length} numbers.`,\n ];\n }\n\n return [true];\n};\n\n/**\n * Config for .use(propName, arrayConfig)\n */\nexport const arrayConfig = {\n interpolate: interpolateArray,\n validate: validateArray,\n};\n","/*!\n* SVGPathCommander v2.2.1 (http://thednp.github.io/svg-path-commander)\n* Copyright 2026 © thednp\n* Licensed under MIT (https://github.com/thednp/svg-path-commander/blob/master/LICENSE)\n*/\nimport CSSMatrix from \"@thednp/dommatrix\";\n//#region src/math/midPoint.ts\n/**\n* Returns the coordinates of a specified distance\n* ratio between two points.\n*\n* @param a the first point coordinates\n* @param b the second point coordinates\n* @param t the ratio\n* @returns the midpoint coordinates\n*/\nconst midPoint = ([ax, ay], [bx, by], t) => {\n\treturn [ax + (bx - ax) * t, ay + (by - ay) * t];\n};\n//#endregion\n//#region src/math/distanceSquareRoot.ts\n/**\n* Returns the square root of the distance\n* between two given points.\n*\n* @param a the first point coordinates\n* @param b the second point coordinates\n* @returns the distance value\n*/\nconst distanceSquareRoot = (a, b) => {\n\treturn Math.sqrt((a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]));\n};\n//#endregion\n//#region src/math/lineTools.ts\n/**\n* Returns length for line segments (MoveTo, LineTo).\n*\n* @param x1 the starting point X\n* @param y1 the starting point Y\n* @param x2 the ending point X\n* @param y2 the ending point Y\n* @returns the line segment length\n*/\nconst getLineLength = (x1, y1, x2, y2) => {\n\treturn distanceSquareRoot([x1, y1], [x2, y2]);\n};\n/**\n* Returns a point along the line segments (MoveTo, LineTo).\n*\n* @param x1 the starting point X\n* @param y1 the starting point Y\n* @param x2 the ending point X\n* @param y2 the ending point Y\n* @param distance the distance to point in [0-1] range\n* @returns the point at length\n*/\nconst getPointAtLineLength = (x1, y1, x2, y2, distance) => {\n\tlet point = {\n\t\tx: x1,\n\t\ty: y1\n\t};\n\tif (typeof distance === \"number\") {\n\t\tconst length = distanceSquareRoot([x1, y1], [x2, y2]);\n\t\tif (distance <= 0) point = {\n\t\t\tx: x1,\n\t\t\ty: y1\n\t\t};\n\t\telse if (distance >= length) point = {\n\t\t\tx: x2,\n\t\t\ty: y2\n\t\t};\n\t\telse {\n\t\t\tconst [x, y] = midPoint([x1, y1], [x2, y2], distance / length);\n\t\t\tpoint = {\n\t\t\t\tx,\n\t\t\t\ty\n\t\t\t};\n\t\t}\n\t}\n\treturn point;\n};\n/**\n* Returns bounding box for line segments (MoveTo, LineTo).\n*\n* @param x1 the starting point X\n* @param y1 the starting point Y\n* @param x2 the ending point X\n* @param y2 the ending point Y\n* @returns the bounding box for line segments\n*/\nconst getLineBBox = (x1, y1, x2, y2) => {\n\tconst { min, max } = Math;\n\treturn [\n\t\tmin(x1, x2),\n\t\tmin(y1, y2),\n\t\tmax(x1, x2),\n\t\tmax(y1, y2)\n\t];\n};\nconst lineTools = {\n\tgetLineBBox,\n\tgetLineLength,\n\tgetPointAtLineLength\n};\n//#endregion\n//#region src/math/arcTools.ts\n/**\n* Returns the Arc segment length.\n* @param rx radius along X axis\n* @param ry radius along Y axis\n* @param theta the angle in radians\n* @returns the arc length\n*/\nconst arcLength = (rx, ry, theta) => {\n\tconst halfTheta = theta / 2;\n\tconst sinHalfTheta = Math.sin(halfTheta);\n\tconst cosHalfTheta = Math.cos(halfTheta);\n\tconst term1 = rx ** 2 * sinHalfTheta ** 2;\n\tconst term2 = ry ** 2 * cosHalfTheta ** 2;\n\tconst length = Math.sqrt(term1 + term2) * theta;\n\treturn Math.abs(length);\n};\n/**\n* Find point on ellipse at given angle around ellipse (theta);\n* @param cx the center X\n* @param cy the center Y\n* @param rx the radius X\n* @param ry the radius Y\n* @param alpha the arc rotation angle in radians\n* @param theta the arc sweep angle in radians\n* @returns a point around ellipse at given angle\n*/\nconst arcPoint = (cx, cy, rx, ry, alpha, theta) => {\n\tconst { sin, cos } = Math;\n\tconst cosA = cos(alpha);\n\tconst sinA = sin(alpha);\n\tconst x = rx * cos(theta);\n\tconst y = ry * sin(theta);\n\treturn [cx + cosA * x - sinA * y, cy + sinA * x + cosA * y];\n};\n/**\n* Returns the angle between two points.\n* @param v0 starting point\n* @param v1 ending point\n* @returns the angle in radian\n*/\nconst angleBetween = (v0, v1) => {\n\tconst { x: v0x, y: v0y } = v0;\n\tconst { x: v1x, y: v1y } = v1;\n\tconst p = v0x * v1x + v0y * v1y;\n\tconst n = Math.sqrt((v0x ** 2 + v0y ** 2) * (v1x ** 2 + v1y ** 2));\n\treturn (v0x * v1y - v0y * v1x < 0 ? -1 : 1) * Math.acos(p / n);\n};\n/**\n* Returns the following properties for an Arc segment: center, start angle,\n* end angle, and radiuses on X and Y axis.\n*\n* @param x1 the starting point X\n* @param y1 the starting point Y\n* @param RX the radius on X axis\n* @param RY the radius on Y axis\n* @param angle the ellipse rotation in degrees\n* @param LAF the large arc flag\n* @param SF the sweep flag\n* @param x2 the ending point X\n* @param y2 the ending point Y\n* @returns properties specific to Arc segments\n*/\nconst getArcProps = (x1, y1, RX, RY, angle, LAF, SF, x, y) => {\n\tconst { abs, sin, cos, sqrt, PI } = Math;\n\tlet rx = abs(RX);\n\tlet ry = abs(RY);\n\tconst xRotRad = (angle % 360 + 360) % 360 * (PI / 180);\n\tif (x1 === x && y1 === y) return {\n\t\trx,\n\t\try,\n\t\tstartAngle: 0,\n\t\tendAngle: 0,\n\t\tcenter: {\n\t\t\tx,\n\t\t\ty\n\t\t}\n\t};\n\tif (rx === 0 || ry === 0) return {\n\t\trx,\n\t\try,\n\t\tstartAngle: 0,\n\t\tendAngle: 0,\n\t\tcenter: {\n\t\t\tx: (x + x1) / 2,\n\t\t\ty: (y + y1) / 2\n\t\t}\n\t};\n\tconst dx = (x1 - x) / 2;\n\tconst dy = (y1 - y) / 2;\n\tconst transformedPoint = {\n\t\tx: cos(xRotRad) * dx + sin(xRotRad) * dy,\n\t\ty: -sin(xRotRad) * dx + cos(xRotRad) * dy\n\t};\n\tconst radiiCheck = transformedPoint.x ** 2 / rx ** 2 + transformedPoint.y ** 2 / ry ** 2;\n\tif (radiiCheck > 1) {\n\t\trx *= sqrt(radiiCheck);\n\t\try *= sqrt(radiiCheck);\n\t}\n\tlet cRadicand = (rx ** 2 * ry ** 2 - rx ** 2 * transformedPoint.y ** 2 - ry ** 2 * transformedPoint.x ** 2) / (rx ** 2 * transformedPoint.y ** 2 + ry ** 2 * transformedPoint.x ** 2);\n\tcRadicand = cRadicand < 0 ? 0 : cRadicand;\n\tconst cCoef = (LAF !== SF ? 1 : -1) * sqrt(cRadicand);\n\tconst transformedCenter = {\n\t\tx: cCoef * (rx * transformedPoint.y / ry),\n\t\ty: cCoef * (-(ry * transformedPoint.x) / rx)\n\t};\n\tconst center = {\n\t\tx: cos(xRotRad) * transformedCenter.x - sin(xRotRad) * transformedCenter.y + (x1 + x) / 2,\n\t\ty: sin(xRotRad) * transformedCenter.x + cos(xRotRad) * transformedCenter.y + (y1 + y) / 2\n\t};\n\tconst startVector = {\n\t\tx: (transformedPoint.x - transformedCenter.x) / rx,\n\t\ty: (transformedPoint.y - transformedCenter.y) / ry\n\t};\n\tconst startAngle = angleBetween({\n\t\tx: 1,\n\t\ty: 0\n\t}, startVector);\n\tlet sweepAngle = angleBetween(startVector, {\n\t\tx: (-transformedPoint.x - transformedCenter.x) / rx,\n\t\ty: (-transformedPoint.y - transformedCenter.y) / ry\n\t});\n\tif (!SF && sweepAngle > 0) sweepAngle -= 2 * PI;\n\telse if (SF && sweepAngle < 0) sweepAngle += 2 * PI;\n\tsweepAngle %= 2 * PI;\n\treturn {\n\t\tcenter,\n\t\tstartAngle,\n\t\tendAngle: startAngle + sweepAngle,\n\t\trx,\n\t\try\n\t};\n};\n/**\n* Returns the length of an Arc segment.\n*\n* @param x1 the starting point X\n* @param y1 the starting point Y\n* @param c1x the first control point X\n* @param c1y the first control point Y\n* @param c2x the second control point X\n* @param c2y the second control point Y\n* @param x2 the ending point X\n* @param y2 the ending point Y\n* @returns the length of the Arc segment\n*/\nconst getArcLength = (x1, y1, RX, RY, angle, LAF, SF, x, y) => {\n\tconst { rx, ry, startAngle, endAngle } = getArcProps(x1, y1, RX, RY, angle, LAF, SF, x, y);\n\treturn arcLength(rx, ry, endAngle - startAngle);\n};\n/**\n* Returns a point along an Arc segment at a given distance.\n*\n* @param x1 the starting point X\n* @param y1 the starting point Y\n* @param RX the radius on X axis\n* @param RY the radius on Y axis\n* @param angle the ellipse rotation in degrees\n* @param LAF the large arc flag\n* @param SF the sweep flag\n* @param x2 the ending point X\n* @param y2 the ending point Y\n* @param distance the distance along the arc\n* @returns a point along the Arc segment\n*/\nconst getPointAtArcLength = (x1, y1, RX, RY, angle, LAF, SF, x, y, distance) => {\n\tlet point = {\n\t\tx: x1,\n\t\ty: y1\n\t};\n\tconst { center, rx, ry, startAngle, endAngle } = getArcProps(x1, y1, RX, RY, angle, LAF, SF, x, y);\n\tif (typeof distance === \"number\") {\n\t\tconst length = arcLength(rx, ry, endAngle - startAngle);\n\t\tif (distance <= 0) point = {\n\t\t\tx: x1,\n\t\t\ty: y1\n\t\t};\n\t\telse if (distance >= length) point = {\n\t\t\tx,\n\t\t\ty\n\t\t};\n\t\telse {\n\t\t\tif (x1 === x && y1 === y) return {\n\t\t\t\tx,\n\t\t\t\ty\n\t\t\t};\n\t\t\tif (rx === 0 || ry === 0) return getPointAtLineLength(x1, y1, x, y, distance);\n\t\t\tconst { PI, cos, sin } = Math;\n\t\t\tconst sweepAngle = endAngle - startAngle;\n\t\t\tconst xRotRad = (angle % 360 + 360) % 360 * (PI / 180);\n\t\t\tconst alpha = startAngle + sweepAngle * (distance / length);\n\t\t\tconst ellipseComponentX = rx * cos(alpha);\n\t\t\tconst ellipseComponentY = ry * sin(alpha);\n\t\t\tpoint = {\n\t\t\t\tx: cos(xRotRad) * ellipseComponentX - sin(xRotRad) * ellipseComponentY + center.x,\n\t\t\t\ty: sin(xRotRad) * ellipseComponentX + cos(xRotRad) * ellipseComponentY + center.y\n\t\t\t};\n\t\t}\n\t}\n\treturn point;\n};\n/**\n* Returns the extrema for an Arc segment in the following format:\n* [MIN_X, MIN_Y, MAX_X, MAX_Y]\n*\n* @see https://github.com/herrstrietzel/svg-pathdata-getbbox\n*\n* @param x1 the starting point X\n* @param y1 the starting point Y\n* @param RX the radius on X axis\n* @param RY the radius on Y axis\n* @param angle the ellipse rotation in degrees\n* @param LAF the large arc flag\n* @param SF the sweep flag\n* @param x2 the ending point X\n* @param y2 the ending point Y\n* @returns the extrema of the Arc segment\n*/\nconst getArcBBox = (x1, y1, RX, RY, angle, LAF, SF, x, y) => {\n\tconst { center, rx, ry, startAngle, endAngle } = getArcProps(x1, y1, RX, RY, angle, LAF, SF, x, y);\n\tconst deltaAngle = endAngle - startAngle;\n\tconst { min, max, tan, atan2, PI } = Math;\n\tconst { x: cx, y: cy } = center;\n\tconst alpha = angle * PI / 180;\n\tconst tangent = tan(alpha);\n\t/**\n\t* find min/max from zeroes of directional derivative along x and y\n\t* along x axis\n\t*/\n\tconst theta = atan2(-ry * tangent, rx);\n\tconst angle1 = theta;\n\tconst angle2 = theta + PI;\n\tconst angle3 = atan2(ry, rx * tangent);\n\tconst angle4 = angle3 + PI;\n\tconst xArray = [x];\n\tconst yArray = [y];\n\tlet xMin = min(x1, x);\n\tlet xMax = max(x1, x);\n\tlet yMin = min(y1, y);\n\tlet yMax = max(y1, y);\n\tconst pP2 = arcPoint(cx, cy, rx, ry, alpha, endAngle - deltaAngle * 1e-5);\n\tconst pP3 = arcPoint(cx, cy, rx, ry, alpha, endAngle - deltaAngle * .99999);\n\t/**\n\t* expected extremes\n\t* if leaving inner bounding box\n\t* (between segment start and end point)\n\t* otherwise exclude elliptic extreme points\n\t*/\n\tif (pP2[0] > xMax || pP3[0] > xMax) {\n\t\tconst p1 = arcPoint(cx, cy, rx, ry, alpha, angle1);\n\t\txArray.push(p1[0]);\n\t\tyArray.push(p1[1]);\n\t}\n\tif (pP2[0] < xMin || pP3[0] < xMin) {\n\t\tconst p2 = arcPoint(cx, cy, rx, ry, alpha, angle2);\n\t\txArray.push(p2[0]);\n\t\tyArray.push(p2[1]);\n\t}\n\tif (pP2[1] < yMin || pP3[1] < yMin) {\n\t\tconst p4 = arcPoint(cx, cy, rx, ry, alpha, angle4);\n\t\txArray.push(p4[0]);\n\t\tyArray.push(p4[1]);\n\t}\n\tif (pP2[1] > yMax || pP3[1] > yMax) {\n\t\tconst p3 = arcPoint(cx, cy, rx, ry, alpha, angle3);\n\t\txArray.push(p3[0]);\n\t\tyArray.push(p3[1]);\n\t}\n\txMin = min.apply([], xArray);\n\tyMin = min.apply([], yArray);\n\txMax = max.apply([], xArray);\n\tyMax = max.apply([], yArray);\n\treturn [\n\t\txMin,\n\t\tyMin,\n\t\txMax,\n\t\tyMax\n\t];\n};\nconst arcTools = {\n\tangleBetween,\n\tarcLength,\n\tarcPoint,\n\tgetArcBBox,\n\tgetArcLength,\n\tgetArcProps,\n\tgetPointAtArcLength\n};\n//#endregion\n//#region src/math/bezier.ts\n/**\n* Tools from bezier.js by Mike 'Pomax' Kamermans\n* @see https://github.com/Pomax/bezierjs\n*/\nconst Tvalues = [\n\t-.06405689286260563,\n\t.06405689286260563,\n\t-.1911188674736163,\n\t.1911188674736163,\n\t-.3150426796961634,\n\t.3150426796961634,\n\t-.4337935076260451,\n\t.4337935076260451,\n\t-.5454214713888396,\n\t.5454214713888396,\n\t-.6480936519369755,\n\t.6480936519369755,\n\t-.7401241915785544,\n\t.7401241915785544,\n\t-.820001985973903,\n\t.820001985973903,\n\t-.8864155270044011,\n\t.8864155270044011,\n\t-.9382745520027328,\n\t.9382745520027328,\n\t-.9747285559713095,\n\t.9747285559713095,\n\t-.9951872199970213,\n\t.9951872199970213\n];\nconst Cvalues = [\n\t.12793819534675216,\n\t.12793819534675216,\n\t.1258374563468283,\n\t.1258374563468283,\n\t.12167047292780339,\n\t.12167047292780339,\n\t.1155056680537256,\n\t.1155056680537256,\n\t.10744427011596563,\n\t.10744427011596563,\n\t.09761865210411388,\n\t.09761865210411388,\n\t.08619016153195327,\n\t.08619016153195327,\n\t.0733464814110803,\n\t.0733464814110803,\n\t.05929858491543678,\n\t.05929858491543678,\n\t.04427743881741981,\n\t.04427743881741981,\n\t.028531388628933663,\n\t.028531388628933663,\n\t.0123412297999872,\n\t.0123412297999872\n];\n/**\n* @param points\n* @returns\n*/\nconst deriveBezier = (points) => {\n\tconst dpoints = [];\n\tfor (let p = points, d = p.length, c = d - 1; d > 1; d -= 1, c -= 1) {\n\t\tconst list = [];\n\t\tfor (let j = 0; j < c; j += 1) list.push({\n\t\t\tx: c * (p[j + 1].x - p[j].x),\n\t\t\ty: c * (p[j + 1].y - p[j].y),\n\t\t\tt: 0\n\t\t});\n\t\tdpoints.push(list);\n\t\tp = list;\n\t}\n\treturn dpoints;\n};\n/**\n* @param points\n* @param t\n*/\nconst computeBezier = (points, t) => {\n\tif (t === 0) {\n\t\tpoints[0].t = 0;\n\t\treturn points[0];\n\t}\n\tconst order = points.length - 1;\n\tif (t === 1) {\n\t\tpoints[order].t = 1;\n\t\treturn points[order];\n\t}\n\tconst mt = 1 - t;\n\tlet p = points;\n\tif (order === 0) {\n\t\tpoints[0].t = t;\n\t\treturn points[0];\n\t}\n\tif (order === 1) return {\n\t\tx: mt * p[0].x + t * p[1].x,\n\t\ty: mt * p[0].y + t * p[1].y,\n\t\tt\n\t};\n\tconst mt2 = mt * mt;\n\tconst t2 = t * t;\n\tlet a = 0;\n\tlet b = 0;\n\tlet c = 0;\n\tlet d = 0;\n\tif (order === 2) {\n\t\tp = [\n\t\t\tp[0],\n\t\t\tp[1],\n\t\t\tp[2],\n\t\t\t{\n\t\t\t\tx: 0,\n\t\t\t\ty: 0\n\t\t\t}\n\t\t];\n\t\ta = mt2;\n\t\tb = mt * t * 2;\n\t\tc = t2;\n\t} else if (order === 3) {\n\t\ta = mt2 * mt;\n\t\tb = mt2 * t * 3;\n\t\tc = mt * t2 * 3;\n\t\td = t * t2;\n\t}\n\treturn {\n\t\tx: a * p[0].x + b * p[1].x + c * p[2].x + d * p[3].x,\n\t\ty: a * p[0].y + b * p[1].y + c * p[2].y + d * p[3].y,\n\t\tt\n\t};\n};\nconst calculateBezier = (derivativeFn, t) => {\n\tconst d = derivativeFn(t);\n\tconst l = d.x * d.x + d.y * d.y;\n\treturn Math.sqrt(l);\n};\nconst bezierLength = (derivativeFn) => {\n\tconst z = .5;\n\tconst len = Tvalues.length;\n\tlet sum = 0;\n\tfor (let i = 0, t; i < len; i++) {\n\t\tt = z * Tvalues[i] + z;\n\t\tsum += Cvalues[i] * calculateBezier(derivativeFn, t);\n\t}\n\treturn z * sum;\n};\n/**\n* Returns the length of CubicBezier / Quad segment.\n* @param curve cubic / quad bezier segment\n*/\nconst getBezierLength = (curve) => {\n\tconst points = [];\n\tfor (let idx = 0, len = curve.length, step = 2; idx < len; idx += step) points.push({\n\t\tx: curve[idx],\n\t\ty: curve[idx + 1]\n\t});\n\tconst dpoints = deriveBezier(points);\n\treturn bezierLength((t) => {\n\t\treturn computeBezier(dpoints[0], t);\n\t});\n};\nconst CBEZIER_MINMAX_EPSILON = 1e-8;\n/**\n* Returns the most extreme points in a Quad Bezier segment.\n* @param A an array which consist of X/Y values\n*/\nconst minmaxQ = ([v1, cp, v2]) => {\n\tconst min = Math.min(v1, v2);\n\tconst max = Math.max(v1, v2);\n\tif (cp >= v1 ? v2 >= cp : v2 <= cp) return [min, max];\n\tconst E = (v1 * v2 - cp * cp) / (v1 - 2 * cp + v2);\n\treturn E < min ? [E, max] : [min, E];\n};\n/**\n* Returns the most extreme points in a Cubic Bezier segment.\n* @param A an array which consist of X/Y values\n* @see https://github.com/kpym/SVGPathy/blob/acd1a50c626b36d81969f6e98e8602e128ba4302/lib/box.js#L127\n*/\nconst minmaxC = ([v1, cp1, cp2, v2]) => {\n\tconst K = v1 - 3 * cp1 + 3 * cp2 - v2;\n\tif (Math.abs(K) < 1e-8) {\n\t\tif (v1 === v2 && v1 === cp1) return [v1, v2];\n\t\treturn minmaxQ([\n\t\t\tv1,\n\t\t\t-.5 * v1 + 1.5 * cp1,\n\t\t\tv1 - 3 * cp1 + 3 * cp2\n\t\t]);\n\t}\n\tconst T = -v1 * cp2 + v1 * v2 - cp1 * cp2 - cp1 * v2 + cp1 * cp1 + cp2 * cp2;\n\tif (T <= 0) return [Math.min(v1, v2), Math.max(v1, v2)];\n\tconst S = Math.sqrt(T);\n\tlet min = Math.min(v1, v2);\n\tlet max = Math.max(v1, v2);\n\tconst L = v1 - 2 * cp1 + cp2;\n\tfor (let R = (L + S) / K, i = 1; i <= 2; R = (L - S) / K, i++) if (R > 0 && R < 1) {\n\t\tconst Q = v1 * (1 - R) * (1 - R) * (1 - R) + cp1 * 3 * (1 - R) * (1 - R) * R + cp2 * 3 * (1 - R) * R * R + v2 * R * R * R;\n\t\tif (Q < min) min = Q;\n\t\tif (Q > max) max = Q;\n\t}\n\treturn [min, max];\n};\nconst bezierTools = {\n\tbezierLength,\n\tcalculateBezier,\n\tCBEZIER_MINMAX_EPSILON,\n\tcomputeBezier,\n\tCvalues,\n\tderiveBezier,\n\tgetBezierLength,\n\tminmaxC,\n\tminmaxQ,\n\tTvalues\n};\n//#endregion\n//#region src/math/cubicTools.ts\n/**\n* Returns a point at a given length of a CubicBezier segment.\n*\n* @param x1 the starting point X\n* @param y1 the starting point Y\n* @param c1x the first control point X\n* @param c1y the first control point Y\n* @param c2x the second control point X\n* @param c2y the second control point Y\n* @param x2 the ending point X\n* @param y2 the ending point Y\n* @param t a [0-1] ratio\n* @returns the point at cubic-bezier segment length\n*/\nconst getPointAtCubicSegmentLength = ([x1, y1, c1x, c1y, c2x, c2y, x2, y2], t) => {\n\tconst t1 = 1 - t;\n\treturn {\n\t\tx: t1 ** 3 * x1 + 3 * t1 ** 2 * t * c1x + 3 * t1 * t ** 2 * c2x + t ** 3 * x2,\n\t\ty: t1 ** 3 * y1 + 3 * t1 ** 2 * t * c1y + 3 * t1 * t ** 2 * c2y + t ** 3 * y2\n\t};\n};\n/**\n* Returns the length of a CubicBezier segment.\n*\n* @param x1 the starting point X\n* @param y1 the starting point Y\n* @param c1x the first control point X\n* @param c1y the first control point Y\n* @param c2x the second control point X\n* @param c2y the second control point Y\n* @param x2 the ending point X\n* @param y2 the ending point Y\n* @returns the CubicBezier segment length\n*/\nconst getCubicLength = (x1, y1, c1x, c1y, c2x, c2y, x2, y2) => {\n\treturn getBezierLength([\n\t\tx1,\n\t\ty1,\n\t\tc1x,\n\t\tc1y,\n\t\tc2x,\n\t\tc2y,\n\t\tx2,\n\t\ty2\n\t]);\n};\n/**\n* Returns the point along a CubicBezier segment at a given distance.\n*\n* @param x1 the starting point X\n* @param y1 the starting point Y\n* @param c1x the first control point X\n* @param c1y the first control point Y\n* @param c2x the second control point X\n* @param c2y the second control point Y\n* @param x2 the ending point X\n* @param y2 the ending point Y\n* @param distance the distance to look at\n* @returns the point at CubicBezier length\n*/\nconst getPointAtCubicLength = (x1, y1, c1x, c1y, c2x, c2y, x2, y2, distance) => {\n\tconst distanceIsNumber = typeof distance === \"number\";\n\tlet point = {\n\t\tx: x1,\n\t\ty: y1\n\t};\n\tif (distanceIsNumber) {\n\t\tconst currentLength = getBezierLength([\n\t\t\tx1,\n\t\t\ty1,\n\t\t\tc1x,\n\t\t\tc1y,\n\t\t\tc2x,\n\t\t\tc2y,\n\t\t\tx2,\n\t\t\ty2\n\t\t]);\n\t\tif (distance <= 0) {} else if (distance >= currentLength) point = {\n\t\t\tx: x2,\n\t\t\ty: y2\n\t\t};\n\t\telse point = getPointAtCubicSegmentLength([\n\t\t\tx1,\n\t\t\ty1,\n\t\t\tc1x,\n\t\t\tc1y,\n\t\t\tc2x,\n\t\t\tc2y,\n\t\t\tx2,\n\t\t\ty2\n\t\t], distance / currentLength);\n\t}\n\treturn point;\n};\n/**\n* Returns the bounding box of a CubicBezier segment in the following format:\n* [MIN_X, MIN_Y, MAX_X, MAX_Y]\n*\n* @param x1 the starting point X\n* @param y1 the starting point Y\n* @param c1x the first control point X\n* @param c1y the first control point Y\n* @param c2x the second control point X\n* @param c2y the second control point Y\n* @param x2 the ending point X\n* @param y2 the ending point Y\n* @returns the extrema of the CubicBezier segment\n*/\nconst getCubicBBox = (x1, y1, c1x, c1y, c2x, c2y, x2, y2) => {\n\tconst cxMinMax = minmaxC([\n\t\tx1,\n\t\tc1x,\n\t\tc2x,\n\t\tx2\n\t]);\n\tconst cyMinMax = minmaxC([\n\t\ty1,\n\t\tc1y,\n\t\tc2y,\n\t\ty2\n\t]);\n\treturn [\n\t\tcxMinMax[0],\n\t\tcyMinMax[0],\n\t\tcxMinMax[1],\n\t\tcyMinMax[1]\n\t];\n};\nconst cubicTools = {\n\tgetCubicBBox,\n\tgetCubicLength,\n\tgetPointAtCubicLength,\n\tgetPointAtCubicSegmentLength\n};\n//#endregion\n//#region src/math/quadTools.ts\n/**\n* Returns the {x,y} coordinates of a point at a\n* given length of a quadratic-bezier segment.\n*\n* @see https://github.com/substack/point-at-length\n*\n* @param x1 the starting point X\n* @param y1 the starting point Y\n* @param cx the control point X\n* @param cy the control point Y\n* @param x2 the ending point X\n* @param y2 the ending point Y\n* @param t a [0-1] ratio\n* @returns the requested {x,y} coordinates\n*/\nconst getPointAtQuadSegmentLength = ([x1, y1, cx, cy, x2, y2], t) => {\n\tconst t1 = 1 - t;\n\treturn {\n\t\tx: t1 ** 2 * x1 + 2 * t1 * t * cx + t ** 2 * x2,\n\t\ty: t1 ** 2 * y1 + 2 * t1 * t * cy + t ** 2 * y2\n\t};\n};\n/**\n* Returns the length of a QuadraticBezier segment.\n*\n* @param x1 the starting point X\n* @param y1 the starting point Y\n* @param cx the control point X\n* @param cy the control point Y\n* @param x2 the ending point X\n* @param y2 the ending point Y\n* @returns the QuadraticBezier segment length\n*/\nconst getQuadLength = (x1, y1, cx, cy, x2, y2) => {\n\treturn getBezierLength([\n\t\tx1,\n\t\ty1,\n\t\tcx,\n\t\tcy,\n\t\tx2,\n\t\ty2\n\t]);\n};\n/**\n* Returns the point along a QuadraticBezier segment at a given distance.\n*\n* @param x1 the starting point X\n* @param y1 the starting point Y\n* @param cx the control point X\n* @param cy the control point Y\n* @param x2 the ending point X\n* @param y2 the ending point Y\n* @param distance the distance to look at\n* @returns the point at QuadraticBezier length\n*/\nconst getPointAtQuadLength = (x1, y1, cx, cy, x2, y2, distance) => {\n\tconst distanceIsNumber = typeof distance === \"number\";\n\tlet point = {\n\t\tx: x1,\n\t\ty: y1\n\t};\n\tif (distanceIsNumber) {\n\t\tconst currentLength = getBezierLength([\n\t\t\tx1,\n\t\t\ty1,\n\t\t\tcx,\n\t\t\tcy,\n\t\t\tx2,\n\t\t\ty2\n\t\t]);\n\t\tif (distance <= 0) {} else if (distance >= currentLength) point = {\n\t\t\tx: x2,\n\t\t\ty: y2\n\t\t};\n\t\telse point = getPointAtQuadSegmentLength([\n\t\t\tx1,\n\t\t\ty1,\n\t\t\tcx,\n\t\t\tcy,\n\t\t\tx2,\n\t\t\ty2\n\t\t], distance / currentLength);\n\t}\n\treturn point;\n};\n/**\n* Returns the bounding box of a QuadraticBezier segment in the following format:\n* [MIN_X, MIN_Y, MAX_X, MAX_Y]\n*\n* @param x1 the starting point X\n* @param y1 the starting point Y\n* @param cx the control point X\n* @param cy the control point Y\n* @param x2 the ending point X\n* @param y2 the ending point Y\n* @returns the extrema of the QuadraticBezier segment\n*/\nconst getQuadBBox = (x1, y1, cx, cy, x2, y2) => {\n\tconst cxMinMax = minmaxQ([\n\t\tx1,\n\t\tcx,\n\t\tx2\n\t]);\n\tconst cyMinMax = minmaxQ([\n\t\ty1,\n\t\tcy,\n\t\ty2\n\t]);\n\treturn [\n\t\tcxMinMax[0],\n\t\tcyMinMax[0],\n\t\tcxMinMax[1],\n\t\tcyMinMax[1]\n\t];\n};\nconst quadTools = {\n\tgetPointAtQuadLength,\n\tgetPointAtQuadSegmentLength,\n\tgetQuadBBox,\n\tgetQuadLength\n};\n//#endregion\n//#region src/math/polygonTools.ts\n/**\n* d3-polygon-area\n* @see https://github.com/d3/d3-polygon\n*\n* Returns the area of a polygon.\n*\n* @param polygon Array of [x, y]\n* @returns Signed area\n*/\nconst polygonArea = (polygon) => {\n\tconst n = polygon.length;\n\tlet i = -1;\n\tlet a;\n\tlet b = polygon[n - 1];\n\tlet area = 0;\n\twhile (++i < n) {\n\t\ta = b;\n\t\tb = polygon[i];\n\t\tarea += a[1] * b[0] - a[0] * b[1];\n\t}\n\treturn area / 2;\n};\n/**\n* d3-polygon-length\n* https://github.com/d3/d3-polygon\n*\n* Returns the perimeter of a polygon.\n*\n* @param polygon an array of coordinates\n* @returns the polygon length\n*/\nconst polygonLength = (polygon) => {\n\treturn polygon.reduce((length, point, i) => {\n\t\tif (i) return length + distanceSquareRoot(polygon[i - 1], point);\n\t\treturn 0;\n\t}, 0);\n};\n/**\n* Computes the centroid (geometric center) of a polygon.\n* Uses average of all endpoint coordinates (robust for polygons and curves).\n*\n* @param polygon A polygon with consists of [x, y] tuples\n* @returns [x, y] centroid\n*/\nconst polygonCentroid = (polygon) => {\n\tif (polygon.length === 0) return [0, 0];\n\tlet sumX = 0;\n\tlet sumY = 0;\n\tfor (const [x, y] of polygon) {\n\t\tsumX += x;\n\t\tsumY += y;\n\t}\n\tconst count = polygon.length;\n\treturn [sumX / count, sumY / count];\n};\nconst polygonTools = {\n\tpolygonArea,\n\tpolygonLength,\n\tpolygonCentroid\n};\n//#endregion\n//#region src/math/rotateVector.ts\n/**\n* Returns an {x,y} vector rotated by a given\n* angle in radian.\n*\n* @param x the initial vector x\n* @param y the initial vector y\n* @param rad the radian vector angle\n* @returns the rotated vector\n*/\nconst rotateVector = (x, y, rad) => {\n\tconst { sin, cos } = Math;\n\treturn {\n\t\tx: x * cos(rad) - y * sin(rad),\n\t\ty: x * sin(rad) + y * cos(rad)\n\t};\n};\n//#endregion\n//#region src/math/roundTo.ts\n/**\n* Rounds a number to the specified number of decimal places.\n*\n* @param n - The number to round\n* @param round - Number of decimal places\n* @returns The rounded number\n*/\nconst roundTo = (n, round) => {\n\tconst pow = round >= 1 ? 10 ** round : 1;\n\treturn round > 0 ? Math.round(n * pow) / pow : Math.round(n);\n};\n//#endregion\n//#region src/parser/paramsCount.ts\n/** Segment params length */\nconst paramsCounts = {\n\ta: 7,\n\tc: 6,\n\th: 1,\n\tl: 2,\n\tm: 2,\n\tr: 4,\n\tq: 4,\n\ts: 4,\n\tt: 2,\n\tv: 1,\n\tz: 0\n};\n//#endregion\n//#region src/parser/finalizeSegment.ts\n/**\n* Breaks the parsing of a pathString once a segment is finalized.\n*\n* @param path - The PathParser instance\n*/\nconst finalizeSegment = (path) => {\n\tlet pathCommand = path.pathValue[path.segmentStart];\n\tlet relativeCommand = pathCommand.toLowerCase();\n\tconst { data } = path;\n\twhile (data.length >= paramsCounts[relativeCommand]) {\n\t\tif (relativeCommand === \"m\" && data.length > 2) {\n\t\t\tpath.segments.push([pathCommand].concat(data.splice(0, 2)));\n\t\t\trelativeCommand = \"l\";\n\t\t\tpathCommand = pathCommand === \"m\" ? \"l\" : \"L\";\n\t\t} else path.segments.push([pathCommand].concat(data.splice(0, paramsCounts[relativeCommand])));\n\t\tif (!paramsCounts[relativeCommand]) break;\n\t}\n};\n//#endregion\n//#region src/util/error.ts\n/** Error prefix used in all SVGPathCommander TypeError messages. */\nconst error = \"SVGPathCommanderError\";\n//#endregion\n//#region src/parser/scanFlag.ts\n/**\n* Validates an A (arc-to) specific path command value.\n* Usually a `large-arc-flag` or `sweep-flag`.\n*\n* @param path - The PathParser instance\n*/\nconst scanFlag = (path) => {\n\tconst { index, pathValue } = path;\n\tconst code = pathValue.charCodeAt(index);\n\tif (code === 48) {\n\t\tpath.param = 0;\n\t\tpath.index += 1;\n\t\treturn;\n\t}\n\tif (code === 49) {\n\t\tpath.param = 1;\n\t\tpath.index += 1;\n\t\treturn;\n\t}\n\tpath.err = `${error}: invalid Arc flag \"${pathValue[index]}\", expecting 0 or 1 at index ${index}`;\n};\n//#endregion\n//#region src/parser/isDigit.ts\n/**\n* Checks if a character is a digit.\n*\n* @param code the character to check\n* @returns check result\n*/\nconst isDigit = (code) => {\n\treturn code >= 48 && code <= 57;\n};\n//#endregion\n//#region src/parser/invalidPathValue.ts\n/** Error message prefix used when a path string cannot be parsed. */\nconst invalidPathValue = \"Invalid path value\";\n//#endregion\n//#region src/parser/scanParam.ts\n/**\n* Validates every character of the path string,\n* every path command, negative numbers or floating point numbers.\n*\n* @param path - The PathParser instance\n*/\nconst scanParam = (path) => {\n\tconst { max, pathValue, index: start } = path;\n\tlet index = start;\n\tlet zeroFirst = false;\n\tlet hasCeiling = false;\n\tlet hasDecimal = false;\n\tlet hasDot = false;\n\tlet ch;\n\tif (index >= max) {\n\t\tpath.err = `${error}: ${invalidPathValue} at index ${index}, \"pathValue\" is missing param`;\n\t\treturn;\n\t}\n\tch = pathValue.charCodeAt(index);\n\tif (ch === 43 || ch === 45) {\n\t\tindex += 1;\n\t\tch = pathValue.charCodeAt(index);\n\t}\n\tif (!isDigit(ch) && ch !== 46) {\n\t\tpath.err = `${error}: ${invalidPathValue} at index ${index}, \"${pathValue[index]}\" is not a number`;\n\t\treturn;\n\t}\n\tif (ch !== 46) {\n\t\tzeroFirst = ch === 48;\n\t\tindex += 1;\n\t\tch = pathValue.charCodeAt(index);\n\t\tif (zeroFirst && index < max) {\n\t\t\tif (ch && isDigit(ch)) {\n\t\t\t\tpath.err = `${error}: ${invalidPathValue} at index ${start}, \"${pathValue[start]}\" illegal number`;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\twhile (index < max && isDigit(pathValue.charCodeAt(index))) {\n\t\t\tindex += 1;\n\t\t\thasCeiling = true;\n\t\t}\n\t\tch = pathValue.charCodeAt(index);\n\t}\n\tif (ch === 46) {\n\t\thasDot = true;\n\t\tindex += 1;\n\t\twhile (isDigit(pathValue.charCodeAt(index))) {\n\t\t\tindex += 1;\n\t\t\thasDecimal = true;\n\t\t}\n\t\tch = pathValue.charCodeAt(index);\n\t}\n\tif (ch === 101 || ch === 69) {\n\t\tif (hasDot && !hasCeiling && !hasDecimal) {\n\t\t\tpath.err = `${error}: ${invalidPathValue} at index ${index}, \"${pathValue[index]}\" invalid float exponent`;\n\t\t\treturn;\n\t\t}\n\t\tindex += 1;\n\t\tch = pathValue.charCodeAt(index);\n\t\tif (ch === 43 || ch === 45) index += 1;\n\t\tif (index < max && isDigit(pathValue.charCodeAt(index))) while (index < max && isDigit(pathValue.charCodeAt(index))) index += 1;\n\t\telse {\n\t\t\tpath.err = `${error}: ${invalidPathValue} at index ${index}, \"${pathValue[index]}\" invalid integer exponent`;\n\t\t\treturn;\n\t\t}\n\t}\n\tpath.index = index;\n\tpath.param = +path.pathValue.slice(start, index);\n};\n//#endregion\n//#region src/parser/isSpace.ts\n/**\n* Checks if the character is a space.\n*\n* @param ch the character to check\n* @returns check result\n*/\nconst isSpace = (ch) => {\n\treturn [\n\t\t5760,\n\t\t6158,\n\t\t8192,\n\t\t8193,\n\t\t8194,\n\t\t8195,\n\t\t8196,\n\t\t8197,\n\t\t8198,\n\t\t8199,\n\t\t8200,\n\t\t8201,\n\t\t8202,\n\t\t8239,\n\t\t8287,\n\t\t12288,\n\t\t65279,\n\t\t10,\n\t\t13,\n\t\t8232,\n\t\t8233,\n\t\t32,\n\t\t9,\n\t\t11,\n\t\t12,\n\t\t160\n\t].includes(ch);\n};\n//#endregion\n//#region src/parser/skipSpaces.ts\n/**\n* Points the parser to the next character in the\n* path string every time it encounters any kind of\n* space character.\n*\n* @param path - The PathParser instance\n*/\nconst skipSpaces = (path) => {\n\tconst { pathValue, max } = path;\n\twhile (path.index < max && isSpace(pathValue.charCodeAt(path.index))) path.index += 1;\n};\n//#endregion\n//#region src/parser/isPathCommand.ts\n/**\n* Checks if the character is a path command.\n*\n* @param code the character to check\n* @returns check result\n*/\nconst isPathCommand = (code) => {\n\tswitch (code | 32) {\n\t\tcase 109:\n\t\tcase 122:\n\t\tcase 108:\n\t\tcase 104:\n\t\tcase 118:\n\t\tcase 99:\n\t\tcase 115:\n\t\tcase 113:\n\t\tcase 116:\n\t\tcase 97: return true;\n\t\tdefault: return false;\n\t}\n};\n//#endregion\n//#region src/parser/isDigitStart.ts\n/**\n* Checks if the character is or belongs to a number.\n* [0-9]|+|-|.\n*\n* @param code the character to check\n* @returns check result\n*/\nconst isDigitStart = (code) => {\n\treturn isDigit(code) || code === 43 || code === 45 || code === 46;\n};\n//#endregion\n//#region src/parser/isArcCommand.ts\n/**\n* Checks if the character is an A (arc-to) path command.\n*\n* @param code the character to check\n* @returns check result\n*/\nconst isArcCommand = (code) => {\n\treturn (code | 32) === 97;\n};\n//#endregion\n//#region src/parser/isMoveCommand.ts\n/**\n* Checks if the character is a MoveTo command.\n*\n* @param code the character to check\n* @returns check result\n*/\nconst isMoveCommand = (code) => {\n\tswitch (code | 32) {\n\t\tcase 109:\n\t\tcase 77: return true;\n\t\tdefault: return false;\n\t}\n};\n//#endregion\n//#region src/parser/scanSegment.ts\n/**\n* Scans every character in the path string to determine\n* where a segment starts and where it ends.\n*\n* @param path - The PathParser instance\n*/\nconst scanSegment = (path) => {\n\tconst { max, pathValue, index, segments } = path;\n\tconst cmdCode = pathValue.charCodeAt(index);\n\tconst reqParams = paramsCounts[pathValue[index].toLowerCase()];\n\tpath.segmentStart = index;\n\tif (!isPathCommand(cmdCode)) {\n\t\tpath.err = `${error}: ${invalidPathValue} \"${pathValue[index]}\" is not a path command at index ${index}`;\n\t\treturn;\n\t}\n\tconst lastSegment = segments[segments.length - 1];\n\tif (!isMoveCommand(cmdCode) && lastSegment?.[0]?.toLocaleLowerCase() === \"z\") {\n\t\tpath.err = `${error}: ${invalidPathValue} \"${pathValue[index]}\" is not a MoveTo path command at index ${index}`;\n\t\treturn;\n\t}\n\tpath.index += 1;\n\tskipSpaces(path);\n\tpath.data = [];\n\tif (!reqParams) {\n\t\tfinalizeSegment(path);\n\t\treturn;\n\t}\n\tfor (;;) {\n\t\tfor (let i = reqParams; i > 0; i -= 1) {\n\t\t\tif (isArcCommand(cmdCode) && (i === 3 || i === 4)) scanFlag(path);\n\t\t\telse scanParam(path);\n\t\t\tif (path.err.length) return;\n\t\t\tpath.data.push(path.param);\n\t\t\tskipSpaces(path);\n\t\t\tif (path.index < max && pathValue.charCodeAt(path.index) === 44) {\n\t\t\t\tpath.index += 1;\n\t\t\t\tskipSpaces(path);\n\t\t\t}\n\t\t}\n\t\tif (path.index >= path.max) break;\n\t\tif (!isDigitStart(pathValue.charCodeAt(path.index))) break;\n\t}\n\tfinalizeSegment(path);\n};\n//#endregion\n//#region src/parser/pathParser.ts\n/**\n* The `PathParser` is used by the `parsePathString` static method\n* to generate a `pathArray`.\n*\n* @param pathString - The SVG path string to parse\n*/\nvar PathParser = class {\n\tconstructor(pathString) {\n\t\tthis.segments = [];\n\t\tthis.pathValue = pathString;\n\t\tthis.max = pathString.length;\n\t\tthis.index = 0;\n\t\tthis.param = 0;\n\t\tthis.segmentStart = 0;\n\t\tthis.data = [];\n\t\tthis.err = \"\";\n\t}\n};\n//#endregion\n//#region src/parser/parsePathString.ts\n/**\n* Parses a path string value and returns an array\n* of segments we like to call `PathArray`.\n*\n* If parameter value is already a `PathArray`,\n* return a clone of it.\n\n* @example\n* parsePathString(\"M 0 0L50 50\")\n* // => [[\"M\",0,0],[\"L\",50,50]]\n*\n* @param pathInput the string to be parsed\n* @returns the resulted `pathArray` or error string\n*/\nconst parsePathString = (pathInput) => {\n\tif (typeof pathInput !== \"string\") return pathInput.slice(0);\n\tconst path = new PathParser(pathInput);\n\tskipSpaces(path);\n\twhile (path.index < path.max && !path.err.length) scanSegment(path);\n\tif (!path.err.length) {\n\t\tif (path.segments.length)\n /**\n\t\t* force absolute first M\n\t\t* getPathBBox calculation requires first segment to be absolute\n\t\t* @see https://github.com/thednp/svg-path-commander/pull/49\n\t\t*/\n\t\tpath.segments[0][0] = \"M\";\n\t} else throw TypeError(path.err);\n\treturn path.segments;\n};\n//#endregion\n//#region src/process/absolutizeSegment.ts\n/**\n* Returns an absolute segment of a `PathArray` object.\n*\n* @param segment the segment object\n* @param index the segment index\n* @param lastX the last known X value\n* @param lastY the last known Y value\n* @returns the absolute segment\n*/\nconst absolutizeSegment = (segment, index, lastX, lastY) => {\n\tconst [pathCommand] = segment;\n\tconst absCommand = pathCommand.toUpperCase();\n\tif (index === 0 || absCommand === pathCommand) return segment;\n\tif (absCommand === \"A\") return [\n\t\tabsCommand,\n\t\tsegment[1],\n\t\tsegment[2],\n\t\tsegment[3],\n\t\tsegment[4],\n\t\tsegment[5],\n\t\tsegment[6] + lastX,\n\t\tsegment[7] + lastY\n\t];\n\telse if (absCommand === \"V\") return [absCommand, segment[1] + lastY];\n\telse if (absCommand === \"H\") return [absCommand, segment[1] + lastX];\n\telse if (absCommand === \"L\") return [\n\t\tabsCommand,\n\t\tsegment[1] + lastX,\n\t\tsegment[2] + lastY\n\t];\n\telse {\n\t\tconst absValues = [];\n\t\tconst seglen = segment.length;\n\t\tfor (let j = 1; j < seglen; j += 1) absValues.push(segment[j] + (j % 2 ? lastX : lastY));\n\t\treturn [absCommand].concat(absValues);\n\t}\n};\n//#endregion\n//#region src/process/iterate.ts\n/**\n* Iterates over a `PathArray`, executing a callback for each segment.\n* The callback can:\n* - Read current position (`x`, `y`)\n* - Modify the segment (return new segment)\n* - Stop early (return `false`)\n*\n* The iterator maintains accurate current point (`x`, `y`) and subpath start (`mx`, `my`)\n* while correctly handling relative/absolute commands, including H/V and Z.\n*\n* **Important**: If the callback returns a new segment with more coordinates (e.g., Q → C),\n* the path length may increase, and iteration will continue over new segments.\n*\n* @template T - Specific PathArray type (e.g., CurveArray, PolylineArray)\n* @param path - The source `PathArray` to iterate over\n* @param iterator - Callback function for each segment\n* @param iterator.segment - Current path segment\n* @param iterator.index - Index of current segment\n* @param iterator.x - Current X position (after applying relative offset)\n* @param iterator.y - Current Y position (after applying relative offset)\n* @returns The modified `path` (or original if no changes)\n*\n* @example\n* iterate(path, (seg, i, x, y) => {\n* if (seg[0] === 'L') return ['C', x, y, seg[1], seg[2], seg[1], seg[2]];\n* });\n*/\nconst iterate = (path, iterator) => {\n\tlet x = 0;\n\tlet y = 0;\n\tlet mx = 0;\n\tlet my = 0;\n\tlet i = 0;\n\twhile (i < path.length) {\n\t\tconst segment = path[i];\n\t\tconst [pathCommand] = segment;\n\t\tconst absCommand = pathCommand.toUpperCase();\n\t\tconst isRelative = absCommand !== pathCommand;\n\t\tconst iteratorResult = iterator(segment, i, x, y);\n\t\tif (iteratorResult === false) break;\n\t\tif (absCommand === \"Z\") {\n\t\t\tx = mx;\n\t\t\ty = my;\n\t\t} else if (absCommand === \"H\") x = segment[1] + (isRelative ? x : 0);\n\t\telse if (absCommand === \"V\") y = segment[1] + (isRelative ? y : 0);\n\t\telse {\n\t\t\tconst segLen = segment.length;\n\t\t\tx = segment[segLen - 2] + (isRelative ? x : 0);\n\t\t\ty = segment[segLen - 1] + (isRelative ? y : 0);\n\t\t\tif (absCommand === \"M\") {\n\t\t\t\tmx = x;\n\t\t\t\tmy = y;\n\t\t\t}\n\t\t}\n\t\tif (iteratorResult) path[i] = iteratorResult;\n\t\ti += 1;\n\t}\n\treturn path;\n};\n//#endregion\n//#region src/convert/pathToAbsolute.ts\n/**\n* Parses a path string value or object and returns an array\n* of segments, all converted to absolute values.\n*\n* @param pathInput - The path string or PathArray\n* @returns The resulted PathArray with absolute values\n*\n* @example\n* ```ts\n* pathToAbsolute('M10 10l80 80')\n* // => [['M', 10, 10], ['L', 90, 90]]\n* ```\n*/\nconst pathToAbsolute = (pathInput) => {\n\treturn iterate(parsePathString(pathInput), absolutizeSegment);\n};\n//#endregion\n//#region src/process/relativizeSegment.ts\n/**\n* Returns a relative segment of a `PathArray` object.\n*\n* @param segment the segment object\n* @param index the segment index\n* @param lastX the last known X value\n* @param lastY the last known Y value\n* @returns the relative segment\n*/\nconst relativizeSegment = (segment, index, lastX, lastY) => {\n\tconst [pathCommand] = segment;\n\tconst relCommand = pathCommand.toLowerCase();\n\tif (index === 0 || pathCommand === relCommand) return segment;\n\tif (relCommand === \"a\") return [\n\t\trelCommand,\n\t\tsegment[1],\n\t\tsegment[2],\n\t\tsegment[3],\n\t\tsegment[4],\n\t\tsegment[5],\n\t\tsegment[6] - lastX,\n\t\tsegment[7] - lastY\n\t];\n\telse if (relCommand === \"v\") return [relCommand, segment[1] - lastY];\n\telse if (relCommand === \"h\") return [relCommand, segment[1] - lastX];\n\telse if (relCommand === \"l\") return [\n\t\trelCommand,\n\t\tsegment[1] - lastX,\n\t\tsegment[2] - lastY\n\t];\n\telse {\n\t\tconst relValues = [];\n\t\tconst seglen = segment.length;\n\t\tfor (let j = 1; j < seglen; j += 1) relValues.push(segment[j] - (j % 2 ? lastX : lastY));\n\t\treturn [relCommand].concat(relValues);\n\t}\n};\n//#endregion\n//#region src/convert/pathToRelative.ts\n/**\n* Parses a path string value or object and returns an array\n* of segments, all converted to relative values.\n*\n* @param pathInput - The path string or PathArray\n* @returns The resulted PathArray with relative values\n*\n* @example\n* ```ts\n* pathToRelative('M10 10L90 90')\n* // => [['M', 10, 10], ['l', 80, 80]]\n* ```\n*/\nconst pathToRelative = (pathInput) => {\n\treturn iterate(parsePathString(pathInput), relativizeSegment);\n};\n//#endregion\n//#region src/process/arcToCubic.ts\n/**\n* Converts A (arc-to) segments to C (cubic-bezier-to).\n*\n* For more information of where this math came from visit:\n* http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes\n*\n* @param X1 the starting x position\n* @param Y1 the starting y position\n* @param RX x-radius of the arc\n* @param RY y-radius of the arc\n* @param angle x-axis-rotation of the arc\n* @param LAF large-arc-flag of the arc\n* @param SF sweep-flag of the arc\n* @param X2 the ending x position\n* @param Y2 the ending y position\n* @param recursive the parameters needed to split arc into 2 segments\n* @returns the resulting cubic-bezier segment(s)\n*/\nconst arcToCubic = (X1, Y1, RX, RY, angle, LAF, SF, X2, Y2, recursive) => {\n\tlet x1 = X1;\n\tlet y1 = Y1;\n\tlet rx = RX;\n\tlet ry = RY;\n\tlet x2 = X2;\n\tlet y2 = Y2;\n\tconst d120 = Math.PI * 120 / 180;\n\tconst rad = Math.PI / 180 * (+angle || 0);\n\tlet res = [];\n\tlet xy;\n\tlet f1;\n\tlet f2;\n\tlet cx;\n\tlet cy;\n\tif (!recursive) {\n\t\txy = rotateVector(x1, y1, -rad);\n\t\tx1 = xy.x;\n\t\ty1 = xy.y;\n\t\txy = rotateVector(x2, y2, -rad);\n\t\tx2 = xy.x;\n\t\ty2 = xy.y;\n\t\tconst x = (x1 - x2) / 2;\n\t\tconst y = (y1 - y2) / 2;\n\t\tlet h = x * x / (rx * rx) + y * y / (ry * ry);\n\t\tif (h > 1) {\n\t\t\th = Math.sqrt(h);\n\t\t\trx *= h;\n\t\t\try *= h;\n\t\t}\n\t\tconst rx2 = rx * rx;\n\t\tconst ry2 = ry * ry;\n\t\tconst k = (LAF === SF ? -1 : 1) * Math.sqrt(Math.abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x)));\n\t\tcx = k * rx * y / ry + (x1 + x2) / 2;\n\t\tcy = k * -ry * x / rx + (y1 + y2) / 2;\n\t\tf1 = Math.asin(((y1 - cy) / ry * 10 ** 9 >> 0) / 10 ** 9);\n\t\tf2 = Math.asin(((y2 - cy) / ry * 10 ** 9 >> 0) / 10 ** 9);\n\t\tf1 = x1 < cx ? Math.PI - f1 : f1;\n\t\tf2 = x2 < cx ? Math.PI - f2 : f2;\n\t\tif (f1 < 0) f1 = Math.PI * 2 + f1;\n\t\tif (f2 < 0) f2 = Math.PI * 2 + f2;\n\t\tif (SF && f1 > f2) f1 -= Math.PI * 2;\n\t\tif (!SF && f2 > f1) f2 -= Math.PI * 2;\n\t} else [f1, f2, cx, cy] = recursive;\n\tlet df = f2 - f1;\n\tif (Math.abs(df) > d120) {\n\t\tconst f2old = f2;\n\t\tconst x2old = x2;\n\t\tconst y2old = y2;\n\t\tf2 = f1 + d120 * (SF && f2 > f1 ? 1 : -1);\n\t\tx2 = cx + rx * Math.cos(f2);\n\t\ty2 = cy + ry * Math.sin(f2);\n\t\tres = arcToCubic(x2, y2, rx, ry, angle, 0, SF, x2old, y2old, [\n\t\t\tf2,\n\t\t\tf2old,\n\t\t\tcx,\n\t\t\tcy\n\t\t]);\n\t}\n\tdf = f2 - f1;\n\tconst c1 = Math.cos(f1);\n\tconst s1 = Math.sin(f1);\n\tconst c2 = Math.cos(f2);\n\tconst s2 = Math.sin(f2);\n\tconst t = Math.tan(df / 4);\n\tconst hx = 4 / 3 * rx * t;\n\tconst hy = 4 / 3 * ry * t;\n\tconst m1 = [x1, y1];\n\tconst m2 = [x1 + hx * s1, y1 - hy * c1];\n\tconst m3 = [x2 + hx * s2, y2 - hy * c2];\n\tconst m4 = [x2, y2];\n\tm2[0] = 2 * m1[0] - m2[0];\n\tm2[1] = 2 * m1[1] - m2[1];\n\tif (recursive) return [\n\t\tm2[0],\n\t\tm2[1],\n\t\tm3[0],\n\t\tm3[1],\n\t\tm4[0],\n\t\tm4[1]\n\t].concat(res);\n\tres = [\n\t\tm2[0],\n\t\tm2[1],\n\t\tm3[0],\n\t\tm3[1],\n\t\tm4[0],\n\t\tm4[1]\n\t].concat(res);\n\tconst newres = [];\n\tfor (let i = 0, ii = res.length; i < ii; i += 1) newres[i] = i % 2 ? rotateVector(res[i - 1], res[i], rad).y : rotateVector(res[i], res[i + 1], rad).x;\n\treturn newres;\n};\n//#endregion\n//#region src/process/quadToCubic.ts\n/**\n* Converts a Q (quadratic-bezier) segment to C (cubic-bezier).\n*\n* @param x1 curve start x\n* @param y1 curve start y\n* @param qx control point x\n* @param qy control point y\n* @param x2 curve end x\n* @param y2 curve end y\n* @returns the cubic-bezier segment\n*/\nconst quadToCubic = (x1, y1, qx, qy, x2, y2) => {\n\tconst r13 = 1 / 3;\n\tconst r23 = 2 / 3;\n\treturn [\n\t\tr13 * x1 + r23 * qx,\n\t\tr13 * y1 + r23 * qy,\n\t\tr13 * x2 + r23 * qx,\n\t\tr13 * y2 + r23 * qy,\n\t\tx2,\n\t\ty2\n\t];\n};\n//#endregion\n//#region src/process/lineToCubic.ts\n/**\n* Converts an L (line-to) segment to C (cubic-bezier).\n*\n* @param x1 line start x\n* @param y1 line start y\n* @param x2 line end x\n* @param y2 line end y\n* @returns the cubic-bezier segment\n*/\nconst lineToCubic = (x1, y1, x2, y2) => {\n\tconst c1 = midPoint([x1, y1], [x2, y2], 1 / 3);\n\tconst c2 = midPoint([x1, y1], [x2, y2], 2 / 3);\n\treturn [\n\t\tc1[0],\n\t\tc1[1],\n\t\tc2[0],\n\t\tc2[1],\n\t\tx2,\n\t\ty2\n\t];\n};\n//#endregion\n//#region src/process/segmentToCubic.ts\n/**\n* Converts any segment to C (cubic-bezier).\n*\n* @param segment the source segment\n* @param params the source segment parameters\n* @returns the cubic-bezier segment\n*/\nconst segmentToCubic = (segment, params) => {\n\tconst pathCommand = segment[0];\n\tconst values = segment.slice(1).map(Number);\n\tconst [x, y] = values;\n\tconst { x1: px1, y1: py1 } = params;\n\tif (!\"TQ\".includes(pathCommand)) {\n\t\tparams.qx = null;\n\t\tparams.qy = null;\n\t}\n\tif (pathCommand === \"M\") {\n\t\tparams.mx = x;\n\t\tparams.my = y;\n\t\tparams.x = x;\n\t\tparams.y = y;\n\t\treturn segment;\n\t} else if (pathCommand === \"A\") return [\"C\"].concat(arcToCubic(px1, py1, values[0], values[1], values[2], values[3], values[4], values[5], values[6]));\n\telse if (pathCommand === \"Q\") {\n\t\tparams.qx = x;\n\t\tparams.qy = y;\n\t\treturn [\"C\"].concat(quadToCubic(px1, py1, values[0], values[1], values[2], values[3]));\n\t} else if (pathCommand === \"L\") return [\"C\"].concat(lineToCubic(px1, py1, x, y));\n\telse if (pathCommand === \"Z\") return [\"C\"].concat(lineToCubic(px1, py1, params.mx, params.my));\n\treturn segment;\n};\n//#endregion\n//#region src/process/normalizeSegment.ts\n/**\n* Normalizes a single segment of a `pathArray` object.\n*\n* @param segment the segment object\n* @param params the normalization parameters\n* @returns the normalized segment\n*/\nconst normalizeSegment = (segment, params) => {\n\tconst [pathCommand] = segment;\n\tconst absCommand = pathCommand.toUpperCase();\n\tconst isRelative = pathCommand !== absCommand;\n\tconst { x1: px1, y1: py1, x2: px2, y2: py2, x, y } = params;\n\tconst values = segment.slice(1);\n\tlet absValues = values.map((n, j) => n + (isRelative ? j % 2 ? y : x : 0));\n\tif (!\"TQ\".includes(absCommand)) {\n\t\tparams.qx = null;\n\t\tparams.qy = null;\n\t}\n\tif (absCommand === \"A\") {\n\t\tabsValues = values.slice(0, -2).concat(values[5] + (isRelative ? x : 0), values[6] + (isRelative ? y : 0));\n\t\treturn [\"A\"].concat(absValues);\n\t} else if (absCommand === \"H\") return [\n\t\t\"L\",\n\t\tsegment[1] + (isRelative ? x : 0),\n\t\tpy1\n\t];\n\telse if (absCommand === \"V\") return [\n\t\t\"L\",\n\t\tpx1,\n\t\tsegment[1] + (isRelative ? y : 0)\n\t];\n\telse if (absCommand === \"L\") return [\n\t\t\"L\",\n\t\tsegment[1] + (isRelative ? x : 0),\n\t\tsegment[2] + (isRelative ? y : 0)\n\t];\n\telse if (absCommand === \"M\") return [\n\t\t\"M\",\n\t\tsegment[1] + (isRelative ? x : 0),\n\t\tsegment[2] + (isRelative ? y : 0)\n\t];\n\telse if (absCommand === \"C\") return [\"C\"].concat(absValues);\n\telse if (absCommand === \"S\") {\n\t\tconst x1 = px1 * 2 - px2;\n\t\tconst y1 = py1 * 2 - py2;\n\t\tparams.x1 = x1;\n\t\tparams.y1 = y1;\n\t\treturn [\n\t\t\t\"C\",\n\t\t\tx1,\n\t\t\ty1\n\t\t].concat(absValues);\n\t} else if (absCommand === \"T\") {\n\t\tconst qx = px1 * 2 - (params.qx ? params.qx : 0);\n\t\tconst qy = py1 * 2 - (params.qy ? params.qy : 0);\n\t\tparams.qx = qx;\n\t\tparams.qy = qy;\n\t\treturn [\n\t\t\t\"Q\",\n\t\t\tqx,\n\t\t\tqy\n\t\t].concat(absValues);\n\t} else if (absCommand === \"Q\") {\n\t\tconst [nqx, nqy] = absValues;\n\t\tparams.qx = nqx;\n\t\tparams.qy = nqy;\n\t\treturn [\"Q\"].concat(absValues);\n\t} else if (absCommand === \"Z\") return [\"Z\"];\n\treturn segment;\n};\n//#endregion\n//#region src/parser/paramsParser.ts\n/**\n* Default parser parameters object used to track position state\n* while iterating through path segments.\n*/\nconst paramsParser = {\n\tmx: 0,\n\tmy: 0,\n\tx1: 0,\n\ty1: 0,\n\tx2: 0,\n\ty2: 0,\n\tx: 0,\n\ty: 0,\n\tqx: null,\n\tqy: null\n};\n//#endregion\n//#region src/convert/pathToCurve.ts\n/**\n* Parses a path string or PathArray and returns a new one\n* in which all segments are converted to cubic-bezier.\n*\n* @param pathInput - The path string or PathArray\n* @returns The resulted CurveArray with all segments as cubic beziers\n*\n* @example\n* ```ts\n* pathToCurve('M10 50q15 -25 30 0')\n* // => [['M', 10, 50], ['C', 25, 25, 40, 50, 40, 50]]\n* ```\n*/\nconst pathToCurve = (pathInput) => {\n\tconst params = { ...paramsParser };\n\tconst path = parsePathString(pathInput);\n\treturn iterate(path, (seg, index, lastX, lastY) => {\n\t\tparams.x = lastX;\n\t\tparams.y = lastY;\n\t\tconst normalSegment = normalizeSegment(seg, params);\n\t\tif (normalSegment[0] === \"M\") {\n\t\t\tparams.mx = normalSegment[1];\n\t\t\tparams.my = normalSegment[2];\n\t\t}\n\t\tlet result = segmentToCubic(normalSegment, params);\n\t\tif (result[0] === \"C\" && result.length > 7) {\n\t\t\tpath.splice(index + 1, 0, [\"C\"].concat(result.slice(7)));\n\t\t\tresult = result.slice(0, 7);\n\t\t}\n\t\tconst seglen = result.length;\n\t\tparams.x1 = +result[seglen - 2];\n\t\tparams.y1 = +result[seglen - 1];\n\t\tparams.x2 = +result[seglen - 4] || params.x1;\n\t\tparams.y2 = +result[seglen - 3] || params.y1;\n\t\treturn result;\n\t});\n};\n//#endregion\n//#region src/options/options.ts\n/** SVGPathCommander default options */\nconst defaultOptions = {\n\torigin: [\n\t\t0,\n\t\t0,\n\t\t0\n\t],\n\tround: 4\n};\n//#endregion\n//#region src/convert/pathToString.ts\n/**\n* Returns a valid `d` attribute string value created\n* by rounding values and concatenating the PathArray segments.\n*\n* @param path - The PathArray object\n* @param roundOption - Amount of decimals to round values to, or \"off\"\n* @returns The concatenated path string\n*\n* @example\n* ```ts\n* pathToString([['M', 10, 10], ['L', 90, 90]], 2)\n* // => 'M10 10L90 90'\n* ```\n*/\nconst pathToString = (path, roundOption) => {\n\tconst pathLen = path.length;\n\tlet { round } = defaultOptions;\n\tlet segment = path[0];\n\tlet result = \"\";\n\tround = roundOption === \"off\" ? roundOption : typeof roundOption === \"number\" && roundOption >= 0 ? roundOption : typeof round === \"number\" && round >= 0 ? round : \"off\";\n\tfor (let i = 0; i < pathLen; i += 1) {\n\t\tsegment = path[i];\n\t\tconst [pathCommand] = segment;\n\t\tconst values = segment.slice(1);\n\t\tresult += pathCommand;\n\t\tif (round === \"off\") result += values.join(\" \");\n\t\telse {\n\t\t\tlet j = 0;\n\t\t\tconst valLen = values.length;\n\t\t\twhile (j < valLen) {\n\t\t\t\tresult += roundTo(values[j], round);\n\t\t\t\tif (j !== valLen - 1) result += \" \";\n\t\t\t\tj += 1;\n\t\t\t}\n\t\t}\n\t}\n\treturn result;\n};\n//#endregion\n//#region src/util/getPathBBox.ts\n/**\n* Calculates the bounding box of a path.\n*\n* @param pathInput - The path string or PathArray\n* @returns An object with width, height, x, y, x2, y2, cx, cy, cz properties\n*\n* @example\n* ```ts\n* getPathBBox('M0 0L100 0L100 100L0 100Z')\n* // => { x: 0, y: 0, width: 100, height: 100, x2: 100, y2: 100, cx: 50, cy: 50, cz: 150 }\n* ```\n*/\nconst getPathBBox = (pathInput) => {\n\tif (!pathInput) return {\n\t\tx: 0,\n\t\ty: 0,\n\t\twidth: 0,\n\t\theight: 0,\n\t\tx2: 0,\n\t\ty2: 0,\n\t\tcx: 0,\n\t\tcy: 0,\n\t\tcz: 0\n\t};\n\tconst path = parsePathString(pathInput);\n\tlet pathCommand = \"M\";\n\tlet mx = 0;\n\tlet my = 0;\n\tconst { max, min } = Math;\n\tlet xMin = Infinity;\n\tlet yMin = Infinity;\n\tlet xMax = -Infinity;\n\tlet yMax = -Infinity;\n\tlet minX = 0;\n\tlet minY = 0;\n\tlet maxX = 0;\n\tlet maxY = 0;\n\tlet paramX1 = 0;\n\tlet paramY1 = 0;\n\tlet paramX2 = 0;\n\tlet paramY2 = 0;\n\tlet paramQX = 0;\n\tlet paramQY = 0;\n\titerate(path, (seg, index, lastX, lastY) => {\n\t\t[pathCommand] = seg;\n\t\tconst absCommand = pathCommand.toUpperCase();\n\t\tconst absoluteSegment = absCommand !== pathCommand ? absolutizeSegment(seg, index, lastX, lastY) : seg.slice(0);\n\t\tconst normalSegment = absCommand === \"V\" ? [\n\t\t\t\"L\",\n\t\t\tlastX,\n\t\t\tabsoluteSegment[1]\n\t\t] : absCommand === \"H\" ? [\n\t\t\t\"L\",\n\t\t\tabsoluteSegment[1],\n\t\t\tlastY\n\t\t] : absoluteSegment;\n\t\t[pathCommand] = normalSegment;\n\t\tif (!\"TQ\".includes(absCommand)) {\n\t\t\tparamQX = 0;\n\t\t\tparamQY = 0;\n\t\t}\n\t\tif (pathCommand === \"M\") {\n\t\t\t[, mx, my] = normalSegment;\n\t\t\tminX = mx;\n\t\t\tminY = my;\n\t\t\tmaxX = mx;\n\t\t\tmaxY = my;\n\t\t} else if (pathCommand === \"L\") [minX, minY, maxX, maxY] = getLineBBox(lastX, lastY, normalSegment[1], normalSegment[2]);\n\t\telse if (pathCommand === \"A\") [minX, minY, maxX, maxY] = getArcBBox(lastX, lastY, normalSegment[1], normalSegment[2], normalSegment[3], normalSegment[4], normalSegment[5], normalSegment[6], normalSegment[7]);\n\t\telse if (pathCommand === \"S\") {\n\t\t\tconst cp1x = paramX1 * 2 - paramX2;\n\t\t\tconst cp1y = paramY1 * 2 - paramY2;\n\t\t\t[minX, minY, maxX, maxY] = getCubicBBox(lastX, lastY, cp1x, cp1y, normalSegment[1], normalSegment[2], normalSegment[3], normalSegment[4]);\n\t\t} else if (pathCommand === \"C\") [minX, minY, maxX, maxY] = getCubicBBox(lastX, lastY, normalSegment[1], normalSegment[2], normalSegment[3], normalSegment[4], normalSegment[5], normalSegment[6]);\n\t\telse if (pathCommand === \"T\") {\n\t\t\tparamQX = paramX1 * 2 - paramQX;\n\t\t\tparamQY = paramY1 * 2 - paramQY;\n\t\t\t[minX, minY, maxX, maxY] = getQuadBBox(lastX, lastY, paramQX, paramQY, normalSegment[1], normalSegment[2]);\n\t\t} else if (pathCommand === \"Q\") {\n\t\t\tparamQX = normalSegment[1];\n\t\t\tparamQY = normalSegment[2];\n\t\t\t[minX, minY, maxX, maxY] = getQuadBBox(lastX, lastY, normalSegment[1], normalSegment[2], normalSegment[3], normalSegment[4]);\n\t\t} else if (pathCommand === \"Z\") [minX, minY, maxX, maxY] = getLineBBox(lastX, lastY, mx, my);\n\t\txMin = min(minX, xMin);\n\t\tyMin = min(minY, yMin);\n\t\txMax = max(maxX, xMax);\n\t\tyMax = max(maxY, yMax);\n\t\t[paramX1, paramY1] = pathCommand === \"Z\" ? [mx, my] : normalSegment.slice(-2);\n\t\t[paramX2, paramY2] = pathCommand === \"C\" ? [normalSegment[3], normalSegment[4]] : pathCommand === \"S\" ? [normalSegment[1], normalSegment[2]] : [paramX1, paramY1];\n\t});\n\tconst width = xMax - xMin;\n\tconst height = yMax - yMin;\n\treturn {\n\t\twidth,\n\t\theight,\n\t\tx: xMin,\n\t\ty: yMin,\n\t\tx2: xMax,\n\t\ty2: yMax,\n\t\tcx: xMin + width / 2,\n\t\tcy: yMin + height / 2,\n\t\tcz: Math.max(width, height) + Math.min(width, height) / 2\n\t};\n};\n//#endregion\n//#region src/util/getTotalLength.ts\n/**\n* Returns the total length of a path, equivalent to `shape.getTotalLength()`.\n*\n* @param pathInput - The target path string or PathArray\n* @returns The total length of the path\n*\n* @example\n* ```ts\n* getTotalLength('M0 0L100 0L100 100L0 100Z')\n* // => 300\n* ```\n*/\nconst getTotalLength = (pathInput) => {\n\tconst path = parsePathString(pathInput);\n\tlet paramX1 = 0;\n\tlet paramY1 = 0;\n\tlet paramX2 = 0;\n\tlet paramY2 = 0;\n\tlet paramQX = 0;\n\tlet paramQY = 0;\n\tlet pathCommand = \"M\";\n\tlet mx = 0;\n\tlet my = 0;\n\tlet totalLength = 0;\n\titerate(path, (seg, index, lastX, lastY) => {\n\t\t[pathCommand] = seg;\n\t\tconst absCommand = pathCommand.toUpperCase();\n\t\tconst absoluteSegment = absCommand !== pathCommand ? absolutizeSegment(seg, index, lastX, lastY) : seg.slice(0);\n\t\tconst normalSegment = absCommand === \"V\" ? [\n\t\t\t\"L\",\n\t\t\tlastX,\n\t\t\tabsoluteSegment[1]\n\t\t] : absCommand === \"H\" ? [\n\t\t\t\"L\",\n\t\t\tabsoluteSegment[1],\n\t\t\tlastY\n\t\t] : absoluteSegment;\n\t\t[pathCommand] = normalSegment;\n\t\tif (!\"TQ\".includes(absCommand)) {\n\t\t\tparamQX = 0;\n\t\t\tparamQY = 0;\n\t\t}\n\t\tif (pathCommand === \"M\") [, mx, my] = normalSegment;\n\t\telse if (pathCommand === \"L\") totalLength += getLineLength(lastX, lastY, normalSegment[1], normalSegment[2]);\n\t\telse if (pathCommand === \"A\") totalLength += getArcLength(lastX, lastY, normalSegment[1], normalSegment[2], normalSegment[3], normalSegment[4], normalSegment[5], normalSegment[6], normalSegment[7]);\n\t\telse if (pathCommand === \"S\") {\n\t\t\tconst cp1x = paramX1 * 2 - paramX2;\n\t\t\tconst cp1y = paramY1 * 2 - paramY2;\n\t\t\ttotalLength += getCubicLength(lastX, lastY, cp1x, cp1y, normalSegment[1], normalSegment[2], normalSegment[3], normalSegment[4]);\n\t\t} else if (pathCommand === \"C\") totalLength += getCubicLength(lastX, lastY, normalSegment[1], normalSegment[2], normalSegment[3], normalSegment[4], normalSegment[5], normalSegment[6]);\n\t\telse if (pathCommand === \"T\") {\n\t\t\tparamQX = paramX1 * 2 - paramQX;\n\t\t\tparamQY = paramY1 * 2 - paramQY;\n\t\t\ttotalLength += getQuadLength(lastX, lastY, paramQX, paramQY, normalSegment[1], normalSegment[2]);\n\t\t} else if (pathCommand === \"Q\") {\n\t\t\tparamQX = normalSegment[1];\n\t\t\tparamQY = normalSegment[2];\n\t\t\ttotalLength += getQuadLength(lastX, lastY, normalSegment[1], normalSegment[2], normalSegment[3], normalSegment[4]);\n\t\t} else if (pathCommand === \"Z\") totalLength += getLineLength(lastX, lastY, mx, my);\n\t\t[paramX1, paramY1] = pathCommand === \"Z\" ? [mx, my] : normalSegment.slice(-2);\n\t\t[paramX2, paramY2] = pathCommand === \"C\" ? [normalSegment[3], normalSegment[4]] : pathCommand === \"S\" ? [normalSegment[1], normalSegment[2]] : [paramX1, paramY1];\n\t});\n\treturn totalLength;\n};\n//#endregion\n//#region src/util/distanceEpsilon.ts\n/** Small threshold value used for floating-point distance comparisons in path calculations. */\nconst DISTANCE_EPSILON = 1e-5;\n//#endregion\n//#region src/process/normalizePath.ts\n/**\n* Parses a path string or PathArray, then iterates the result for:\n* * converting segments to absolute values\n* * converting shorthand commands to their non-shorthand notation\n*\n* @param pathInput - The path string or PathArray\n* @returns The normalized PathArray\n*\n* @example\n* ```ts\n* normalizePath('M10 90s20 -80 40 -80s20 80 40 80')\n* // => [['M', 10, 90], ['C', 30, 90, 25, 10, 50, 10], ['C', 75, 10, 70, 90, 90, 90]]\n* ```\n*/\nconst normalizePath = (pathInput) => {\n\tconst path = parsePathString(pathInput);\n\tconst params = { ...paramsParser };\n\treturn iterate(path, (seg, _, lastX, lastY) => {\n\t\tparams.x = lastX;\n\t\tparams.y = lastY;\n\t\tconst result = normalizeSegment(seg, params);\n\t\tconst seglen = result.length;\n\t\tparams.x1 = +result[seglen - 2];\n\t\tparams.y1 = +result[seglen - 1];\n\t\tparams.x2 = +result[seglen - 4] || params.x1;\n\t\tparams.y2 = +result[seglen - 3] || params.y1;\n\t\treturn result;\n\t});\n};\n//#endregion\n//#region src/util/getPointAtLength.ts\n/**\n* Returns [x,y] coordinates of a point at a given length along a path.\n*\n* @param pathInput - The PathArray or path string to look into\n* @param distance - The distance along the path\n* @returns The requested {x, y} point coordinates\n*\n* @example\n* ```ts\n* getPointAtLength('M0 0L100 0L100 100Z', 50)\n* // => { x: 50, y: 0 }\n* ```\n*/\nconst getPointAtLength = (pathInput, distance) => {\n\tconst path = normalizePath(pathInput);\n\tlet isM = false;\n\tlet data = [];\n\tlet x = 0;\n\tlet y = 0;\n\tlet [mx, my] = path[0].slice(1);\n\tconst distanceIsNumber = typeof distance === \"number\";\n\tlet point = {\n\t\tx: mx,\n\t\ty: my\n\t};\n\tlet length = 0;\n\tlet POINT = point;\n\tlet totalLength = 0;\n\tif (!distanceIsNumber || distance < 1e-5) return point;\n\titerate(path, (seg, _, lastX, lastY) => {\n\t\tconst pathCommand = seg[0];\n\t\tisM = pathCommand === \"M\";\n\t\tdata = !isM ? [lastX, lastY].concat(seg.slice(1)) : data;\n\t\tif (isM) {\n\t\t\t[, mx, my] = seg;\n\t\t\tpoint = {\n\t\t\t\tx: mx,\n\t\t\t\ty: my\n\t\t\t};\n\t\t\tlength = 0;\n\t\t} else if (pathCommand === \"L\") {\n\t\t\tpoint = getPointAtLineLength(data[0], data[1], data[2], data[3], distance - totalLength);\n\t\t\tlength = getLineLength(data[0], data[1], data[2], data[3]);\n\t\t} else if (pathCommand === \"A\") {\n\t\t\tpoint = getPointAtArcLength(data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], distance - totalLength);\n\t\t\tlength = getArcLength(data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8]);\n\t\t} else if (pathCommand === \"C\") {\n\t\t\tpoint = getPointAtCubicLength(data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], distance - totalLength);\n\t\t\tlength = getCubicLength(data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);\n\t\t} else if (pathCommand === \"Q\") {\n\t\t\tpoint = getPointAtQuadLength(data[0], data[1], data[2], data[3], data[4], data[5], distance - totalLength);\n\t\t\tlength = getQuadLength(data[0], data[1], data[2], data[3], data[4], data[5]);\n\t\t} else if (pathCommand === \"Z\") {\n\t\t\tdata = [\n\t\t\t\tlastX,\n\t\t\t\tlastY,\n\t\t\t\tmx,\n\t\t\t\tmy\n\t\t\t];\n\t\t\tpoint = {\n\t\t\t\tx: mx,\n\t\t\t\ty: my\n\t\t\t};\n\t\t\tlength = getLineLength(data[0], data[1], data[2], data[3]);\n\t\t}\n\t\t[x, y] = data.slice(-2);\n\t\tif (totalLength < distance) POINT = point;\n\t\telse return false;\n\t\ttotalLength += length;\n\t});\n\tif (distance > totalLength - 1e-5) return {\n\t\tx,\n\t\ty\n\t};\n\treturn POINT;\n};\n//#endregion\n//#region src/util/getPropertiesAtLength.ts\n/**\n* Returns the segment, its index and length as well as\n* the length to that segment at a given length in a path.\n*\n* @param pathInput target `pathArray`\n* @param distance the given length\n* @returns the requested properties\n*/\nconst getPropertiesAtLength = (pathInput, distance) => {\n\tconst pathArray = parsePathString(pathInput);\n\tlet pathTemp = pathArray.slice(0);\n\tlet pathLength = getTotalLength(pathTemp);\n\tlet index = pathTemp.length - 1;\n\tlet lengthAtSegment = 0;\n\tlet length = 0;\n\tlet segment = pathArray[0];\n\tif (index <= 0 || !distance || !Number.isFinite(distance)) return {\n\t\tsegment,\n\t\tindex: 0,\n\t\tlength,\n\t\tlengthAtSegment\n\t};\n\tif (distance >= pathLength) {\n\t\tpathTemp = pathArray.slice(0, -1);\n\t\tlengthAtSegment = getTotalLength(pathTemp);\n\t\tlength = pathLength - lengthAtSegment;\n\t\tsegment = pathArray[index];\n\t\treturn {\n\t\t\tsegment,\n\t\t\tindex,\n\t\t\tlength,\n\t\t\tlengthAtSegment\n\t\t};\n\t}\n\tconst segments = [];\n\twhile (index > 0) {\n\t\tsegment = pathTemp[index];\n\t\tpathTemp = pathTemp.slice(0, -1);\n\t\tlengthAtSegment = getTotalLength(pathTemp);\n\t\tlength = pathLength - lengthAtSegment;\n\t\tpathLength = lengthAtSegment;\n\t\tsegments.push({\n\t\t\tsegment,\n\t\t\tindex,\n\t\t\tlength,\n\t\t\tlengthAtSegment\n\t\t});\n\t\tindex -= 1;\n\t}\n\treturn segments.find(({ lengthAtSegment: l }) => l <= distance);\n};\n//#endregion\n//#region src/util/getPropertiesAtPoint.ts\n/**\n* Returns the point and segment in path closest to a given point as well as\n* the distance to the path stroke.\n*\n* @see https://bl.ocks.org/mbostock/8027637\n*\n* @param pathInput target `pathArray`\n* @param point the given point\n* @returns the requested properties\n*/\nconst getPropertiesAtPoint = (pathInput, point) => {\n\tconst path = parsePathString(pathInput);\n\tconst normalPath = normalizePath(path);\n\tconst pathLength = getTotalLength(normalPath);\n\tconst distanceTo = (p) => {\n\t\tconst dx = p.x - point.x;\n\t\tconst dy = p.y - point.y;\n\t\treturn dx * dx + dy * dy;\n\t};\n\tlet precision = 8;\n\tlet scan;\n\tlet closest = {\n\t\tx: 0,\n\t\ty: 0\n\t};\n\tlet scanDistance = 0;\n\tlet bestLength = 0;\n\tlet bestDistance = Infinity;\n\tfor (let scanLength = 0; scanLength <= pathLength; scanLength += precision) {\n\t\tscan = getPointAtLength(normalPath, scanLength);\n\t\tscanDistance = distanceTo(scan);\n\t\tif (scanDistance < bestDistance) {\n\t\t\tclosest = scan;\n\t\t\tbestLength = scanLength;\n\t\t\tbestDistance = scanDistance;\n\t\t}\n\t}\n\tprecision /= 2;\n\tlet before;\n\tlet after;\n\tlet beforeLength = 0;\n\tlet afterLength = 0;\n\tlet beforeDistance = 0;\n\tlet afterDistance = 0;\n\twhile (precision > 1e-6) {\n\t\tbeforeLength = bestLength - precision;\n\t\tbefore = getPointAtLength(normalPath, beforeLength);\n\t\tbeforeDistance = distanceTo(before);\n\t\tafterLength = bestLength + precision;\n\t\tafter = getPointAtLength(normalPath, afterLength);\n\t\tafterDistance = distanceTo(after);\n\t\tif (beforeLength >= 0 && beforeDistance < bestDistance) {\n\t\t\tclosest = before;\n\t\t\tbestLength = beforeLength;\n\t\t\tbestDistance = beforeDistance;\n\t\t} else if (afterLength <= pathLength && afterDistance < bestDistance) {\n\t\t\tclosest = after;\n\t\t\tbestLength = afterLength;\n\t\t\tbestDistance = afterDistance;\n\t\t} else precision /= 2;\n\t\tif (precision < 1e-5) break;\n\t}\n\tconst segment = getPropertiesAtLength(path, bestLength);\n\treturn {\n\t\tclosest,\n\t\tdistance: Math.sqrt(bestDistance),\n\t\tsegment\n\t};\n};\n//#endregion\n//#region src/util/getClosestPoint.ts\n/**\n* Returns the point in path closest to a given point.\n*\n* @param pathInput target `pathArray`\n* @param point the given point\n* @returns the best match\n*/\nconst getClosestPoint = (pathInput, point) => {\n\treturn getPropertiesAtPoint(pathInput, point).closest;\n};\n//#endregion\n//#region src/util/getPathArea.ts\n/**\n* Returns the area of a single cubic-bezier segment.\n*\n* http://objectmix.com/graphics/133553-area-closed-bezier-curve.html\n*\n* @param x1 the starting point X\n* @param y1 the starting point Y\n* @param c1x the first control point X\n* @param c1y the first control point Y\n* @param c2x the second control point X\n* @param c2y the second control point Y\n* @param x2 the ending point X\n* @param y2 the ending point Y\n* @returns the area of the cubic-bezier segment\n*/\nconst getCubicSegArea = (x1, y1, c1x, c1y, c2x, c2y, x2, y2) => {\n\treturn 3 * ((y2 - y1) * (c1x + c2x) - (x2 - x1) * (c1y + c2y) + c1y * (x1 - c2x) - c1x * (y1 - c2y) + y2 * (c2x + x1 / 3) - x2 * (c2y + y1 / 3)) / 20;\n};\n/**\n* Returns the signed area of a shape.\n*\n* @author Jürg Lehni & Jonathan Puckey\n*\n* @see https://github.com/paperjs/paper.js/blob/develop/src/path/Path.js\n*\n* @param path - The shape PathArray\n* @returns The signed area of the shape (positive for clockwise, negative for counter-clockwise)\n*\n* @example\n* ```ts\n* getPathArea([['M', 0, 0], ['L', 100, 0], ['L', 100, 100], ['L', 0, 100], ['Z']])\n* // => -10000 (counter-clockwise square)\n* ```\n*/\nconst getPathArea = (path) => {\n\tlet x = 0;\n\tlet y = 0;\n\tlet len = 0;\n\treturn pathToCurve(path).map((seg) => {\n\t\tswitch (seg[0]) {\n\t\t\tcase \"M\":\n\t\t\t\t[, x, y] = seg;\n\t\t\t\treturn 0;\n\t\t\tdefault:\n\t\t\t\tlen = getCubicSegArea(x, y, seg[1], seg[2], seg[3], seg[4], seg[5], seg[6]);\n\t\t\t\t[x, y] = seg.slice(-2);\n\t\t\t\treturn len;\n\t\t}\n\t}).reduce((a, b) => a + b, 0);\n};\n//#endregion\n//#region src/util/getDrawDirection.ts\n/**\n* Check if a path is drawn clockwise and returns true if so,\n* false otherwise.\n*\n* @param path the path string or `pathArray`\n* @returns true when clockwise or false if not\n*/\nconst getDrawDirection = (path) => {\n\treturn getPathArea(pathToCurve(path)) >= 0;\n};\n//#endregion\n//#region src/util/getSegmentAtLength.ts\n/**\n* Returns the segment at a given length.\n*\n* @param pathInput the target `pathArray`\n* @param distance the distance in path to look at\n* @returns the requested segment\n*/\nconst getSegmentAtLength = (pathInput, distance) => {\n\treturn getPropertiesAtLength(pathInput, distance).segment;\n};\n//#endregion\n//#region src/util/getSegmentOfPoint.ts\n/**\n* Returns the path segment which contains a given point.\n*\n* @param path the `pathArray` to look into\n* @param point the point of the shape to look for\n* @returns the requested segment\n*/\nconst getSegmentOfPoint = (path, point) => {\n\treturn getPropertiesAtPoint(path, point).segment;\n};\n//#endregion\n//#region src/util/isPathArray.ts\n/**\n* Iterates an array to check if it's an actual `pathArray`.\n*\n* @param path the `pathArray` to be checked\n* @returns iteration result\n*/\nconst isPathArray = (path) => {\n\treturn Array.isArray(path) && path.every((seg) => {\n\t\tconst lk = seg[0].toLowerCase();\n\t\treturn paramsCounts[lk] === seg.length - 1 && \"achlmqstvz\".includes(lk) && seg.slice(1).every(Number.isFinite);\n\t}) && path.length > 0;\n};\n//#endregion\n//#region src/util/isAbsoluteArray.ts\n/**\n* Iterates an array to check if it's a `pathArray`\n* with all absolute values.\n*\n* @param path the `pathArray` to be checked\n* @returns iteration result\n*/\nconst isAbsoluteArray = (path) => {\n\treturn isPathArray(path) && path.every(([x]) => x === x.toUpperCase());\n};\n//#endregion\n//#region src/util/isNormalizedArray.ts\n/**\n* Iterates an array to check if it's a `pathArray`\n* with all segments in non-shorthand notation\n* with absolute values.\n*\n* @param path - the array to be checked\n* @returns true if the array is a normalized path array\n*/\nconst isNormalizedArray = (path) => {\n\treturn isAbsoluteArray(path) && path.every(([pc]) => \"ACLMQZ\".includes(pc));\n};\n//#endregion\n//#region src/util/isCurveArray.ts\n/**\n* Iterates an array to check if it's a `pathArray`\n* with all C (cubic bezier) segments.\n*\n* @param path the `Array` to be checked\n* @returns iteration result\n*/\nconst isCurveArray = (path) => {\n\treturn isNormalizedArray(path) && path.every(([pc]) => \"MC\".includes(pc));\n};\n//#endregion\n//#region src/util/isPointInStroke.ts\n/**\n* Checks if a given point is in the stroke of a path.\n*\n* @param pathInput target path\n* @param point the given `{x,y}` point\n* @returns the query result\n*/\nconst isPointInStroke = (pathInput, point) => {\n\tconst { distance } = getPropertiesAtPoint(pathInput, point);\n\treturn Math.abs(distance) < DISTANCE_EPSILON;\n};\n//#endregion\n//#region src/util/isPolygonArray.ts\n/**\n* Checks if a path is a polygon (only M, L, H, V, Z commands).\n* @param pathArray PathArray (pre-normalize if needed)\n* @returns boolean\n*/\nconst isPolygonArray = (path) => {\n\treturn isNormalizedArray(path) && path.every(([pc]) => \"MLVHZ\".includes(pc));\n};\n//#endregion\n//#region src/util/isPolylineArray.ts\n/**\n* Checks if a path is a polyline (only M, L, H, V commands).\n* @param pathArray PathArray (pre-normalize if needed)\n* @returns boolean\n*/\nfunction isPolylineArray(path) {\n\treturn isNormalizedArray(path) && path.every(([pc]) => \"MLVH\".includes(pc));\n}\n//#endregion\n//#region src/util/isRelativeArray.ts\n/**\n* Iterates an array to check if it's a `pathArray`\n* with relative values.\n*\n* @param path the `pathArray` to be checked\n* @returns iteration result\n*/\nconst isRelativeArray = (path) => {\n\treturn isPathArray(path) && path.slice(1).every(([pc]) => pc === pc.toLowerCase());\n};\n//#endregion\n//#region src/util/isValidPath.ts\n/**\n* Parses a path string value to determine its validity\n* then returns true if it's valid or false otherwise.\n*\n* @param pathString the path string to be parsed\n* @returns the path string validity\n*/\nconst isValidPath = (pathString) => {\n\tif (typeof pathString !== \"string\" || !pathString.length) return false;\n\tconst path = new PathParser(pathString);\n\tskipSpaces(path);\n\twhile (path.index < path.max && !path.err.length) scanSegment(path);\n\treturn !path.err.length && \"mM\".includes(path.segments[0][0]);\n};\n//#endregion\n//#region src/util/isMultiPath.ts\n/**\n* Determines if an SVG path contains multiple subpaths.\n* Accepts path string or PathArray.\n* @param path - 'M10,10 L20,20 Z M30,30 L40,40' → true\n* @returns boolean\n*/\nconst isMultiPath = (path) => {\n\tif (typeof path === \"string\") {\n\t\tconst matches = path.match(/[Mm]/g);\n\t\treturn matches ? matches.length > 1 : false;\n\t}\n\tif (isPathArray(path)) {\n\t\tlet moveCount = 0;\n\t\tfor (const segment of path) if (segment[0].toUpperCase() === \"M\") {\n\t\t\tmoveCount++;\n\t\t\tif (moveCount > 1) return true;\n\t\t}\n\t\treturn false;\n\t}\n\tthrow new TypeError(error + \": expected string or PathArray\");\n};\n//#endregion\n//#region src/util/isClosedPath.ts\n/**\n* Check if a PathArray is closed, which means its last segment is a Z.\n* @param path\n* @returns true if the path is closed\n*/\nconst isClosedPath = (path) => {\n\treturn path[path.length - 1][0].toUpperCase() === \"Z\";\n};\n//#endregion\n//#region src/util/shapeParams.ts\n/**\n* Supported shapes and their specific parameters.\n*/\nconst shapeParams = {\n\tline: [\n\t\t\"x1\",\n\t\t\"y1\",\n\t\t\"x2\",\n\t\t\"y2\"\n\t],\n\tcircle: [\n\t\t\"cx\",\n\t\t\"cy\",\n\t\t\"r\"\n\t],\n\tellipse: [\n\t\t\"cx\",\n\t\t\"cy\",\n\t\t\"rx\",\n\t\t\"ry\"\n\t],\n\trect: [\n\t\t\"width\",\n\t\t\"height\",\n\t\t\"x\",\n\t\t\"y\",\n\t\t\"rx\",\n\t\t\"ry\"\n\t],\n\tpolygon: [\"points\"],\n\tpolyline: [\"points\"],\n\tglyph: [\"d\"]\n};\n//#endregion\n//#region src/util/isElement.ts\n/**\n* Checks if a value is a DOM Element.\n*\n* @param node - The value to check\n* @returns True if the value is a DOM Element (nodeType === 1)\n*/\nconst isElement = (node) => node !== void 0 && node !== null && typeof node === \"object\" && node.nodeType === 1;\n//#endregion\n//#region src/util/shapeToPathArray.ts\n/**\n* Returns a new PathArray from line attributes.\n*\n* @param attr - Shape configuration with x1, y1, x2, y2\n* @returns A new line PathArray\n*\n* @example\n* ```ts\n* getLinePath({ x1: 0, y1: 0, x2: 100, y2: 100 })\n* // => [['M', 0, 0], ['L', 100, 100]]\n* ```\n*/\nconst getLinePath = (attr) => {\n\tlet { x1, y1, x2, y2 } = attr;\n\t[x1, y1, x2, y2] = [\n\t\tx1,\n\t\ty1,\n\t\tx2,\n\t\ty2\n\t].map((a) => +a);\n\treturn [[\n\t\t\"M\",\n\t\tx1,\n\t\ty1\n\t], [\n\t\t\"L\",\n\t\tx2,\n\t\ty2\n\t]];\n};\n/**\n* Returns a new PathArray from polyline/polygon attributes.\n*\n* @param attr - Shape configuration with points string\n* @returns A new polygon/polyline PathArray\n*\n* @example\n* ```ts\n* getPolyPath({ type: 'polygon', points: '0,0 100,0 100,100 0,100' })\n* // => [['M', 0, 0], ['L', 100, 0], ['L', 100, 100], ['L', 0, 100], ['z']]\n* ```\n*/\nconst getPolyPath = (attr) => {\n\tconst pathArray = [];\n\tconst points = (attr.points || \"\").trim().split(/[\\s|,]/).map((a) => +a);\n\tlet index = 0;\n\twhile (index < points.length) {\n\t\tpathArray.push([\n\t\t\tindex ? \"L\" : \"M\",\n\t\t\tpoints[index],\n\t\t\tpoints[index + 1]\n\t\t]);\n\t\tindex += 2;\n\t}\n\treturn attr.type === \"polygon\" ? [...pathArray, [\"z\"]] : pathArray;\n};\n/**\n* Returns a new PathArray from circle attributes.\n*\n* @param attr - Shape configuration with cx, cy, r\n* @returns A circle PathArray\n*\n* @example\n* ```ts\n* getCirclePath({ cx: 50, cy: 50, r: 25 })\n* // => [['M', 25, 50], ['a', 25, 25, 0, 1, 0, 50, 0], ['a', 25, 25, 0, 1, 0, -50, 0]]\n* ```\n*/\nconst getCirclePath = (attr) => {\n\tlet { cx, cy, r } = attr;\n\t[cx, cy, r] = [\n\t\tcx,\n\t\tcy,\n\t\tr\n\t].map((a) => +a);\n\treturn [\n\t\t[\n\t\t\t\"M\",\n\t\t\tcx - r,\n\t\t\tcy\n\t\t],\n\t\t[\n\t\t\t\"a\",\n\t\t\tr,\n\t\t\tr,\n\t\t\t0,\n\t\t\t1,\n\t\t\t0,\n\t\t\t2 * r,\n\t\t\t0\n\t\t],\n\t\t[\n\t\t\t\"a\",\n\t\t\tr,\n\t\t\tr,\n\t\t\t0,\n\t\t\t1,\n\t\t\t0,\n\t\t\t-2 * r,\n\t\t\t0\n\t\t]\n\t];\n};\n/**\n* Returns a new PathArray from ellipse attributes.\n*\n* @param attr - Shape configuration with cx, cy, rx, ry\n* @returns An ellipse PathArray\n*\n* @example\n* ```ts\n* getEllipsePath({ cx: 50, cy: 50, rx: 30, ry: 20 })\n* // => [['M', 20, 50], ['a', 30, 20, 0, 1, 0, 60, 0], ['a', 30, 20, 0, 1, 0, -60, 0]]\n* ```\n*/\nconst getEllipsePath = (attr) => {\n\tlet { cx, cy } = attr;\n\tlet rx = attr.rx || 0;\n\tlet ry = attr.ry || rx;\n\t[cx, cy, rx, ry] = [\n\t\tcx,\n\t\tcy,\n\t\trx,\n\t\try\n\t].map((a) => +a);\n\treturn [\n\t\t[\n\t\t\t\"M\",\n\t\t\tcx - rx,\n\t\t\tcy\n\t\t],\n\t\t[\n\t\t\t\"a\",\n\t\t\trx,\n\t\t\try,\n\t\t\t0,\n\t\t\t1,\n\t\t\t0,\n\t\t\t2 * rx,\n\t\t\t0\n\t\t],\n\t\t[\n\t\t\t\"a\",\n\t\t\trx,\n\t\t\try,\n\t\t\t0,\n\t\t\t1,\n\t\t\t0,\n\t\t\t-2 * rx,\n\t\t\t0\n\t\t]\n\t];\n};\n/**\n* Returns a new PathArray from rect attributes.\n*\n* @param attr - Object with x, y, width, height, and optional rx/ry\n* @returns A new PathArray from `<rect>` attributes\n*\n* @example\n* ```ts\n* getRectanglePath({ x: 0, y: 0, width: 100, height: 50, ry: 10 })\n* // => [['M', 10, 0], ['h', 80], ['a', 10, 10, 0, 0, 1, 10, 10], ...]\n* ```\n*/\nconst getRectanglePath = (attr) => {\n\tconst x = +attr.x || 0;\n\tconst y = +attr.y || 0;\n\tconst w = +attr.width;\n\tconst h = +attr.height;\n\tlet rx = +(attr.rx || 0);\n\tlet ry = +(attr.ry || rx);\n\tif (rx || ry) {\n\t\tif (rx * 2 > w) rx -= (rx * 2 - w) / 2;\n\t\tif (ry * 2 > h) ry -= (ry * 2 - h) / 2;\n\t\treturn [\n\t\t\t[\n\t\t\t\t\"M\",\n\t\t\t\tx + rx,\n\t\t\t\ty\n\t\t\t],\n\t\t\t[\"h\", w - rx * 2],\n\t\t\t[\n\t\t\t\t\"s\",\n\t\t\t\trx,\n\t\t\t\t0,\n\t\t\t\trx,\n\t\t\t\try\n\t\t\t],\n\t\t\t[\"v\", h - ry * 2],\n\t\t\t[\n\t\t\t\t\"s\",\n\t\t\t\t0,\n\t\t\t\try,\n\t\t\t\t-rx,\n\t\t\t\try\n\t\t\t],\n\t\t\t[\"h\", -w + rx * 2],\n\t\t\t[\n\t\t\t\t\"s\",\n\t\t\t\t-rx,\n\t\t\t\t0,\n\t\t\t\t-rx,\n\t\t\t\t-ry\n\t\t\t],\n\t\t\t[\"v\", -h + ry * 2],\n\t\t\t[\n\t\t\t\t\"s\",\n\t\t\t\t0,\n\t\t\t\t-ry,\n\t\t\t\trx,\n\t\t\t\t-ry\n\t\t\t]\n\t\t];\n\t}\n\treturn [\n\t\t[\n\t\t\t\"M\",\n\t\t\tx,\n\t\t\ty\n\t\t],\n\t\t[\"h\", w],\n\t\t[\"v\", h],\n\t\t[\"H\", x],\n\t\t[\"Z\"]\n\t];\n};\n/**\n* Returns a new `pathArray` created from attributes of a `<line>`, `<polyline>`,\n* `<polygon>`, `<rect>`, `<ellipse>`, `<circle>`, <path> or `<glyph>`.\n*\n* It can also work with an options object, see the type below\n* @see ShapeOps\n*\n* @param element target shape\n* @returns the newly created `<path>` element\n*/\nconst shapeToPathArray = (element) => {\n\tconst supportedShapes = Object.keys(shapeParams);\n\tconst targetIsElement = isElement(element);\n\tconst tagName = targetIsElement ? element.tagName : null;\n\tif (tagName && [...supportedShapes, \"path\"].every((s) => tagName !== s)) throw TypeError(`${error}: \"${tagName}\" is not SVGElement`);\n\tconst type = targetIsElement ? tagName : element.type;\n\tconst shapeAttrs = shapeParams[type];\n\tconst config = { type };\n\tif (targetIsElement) shapeAttrs.forEach((p) => {\n\t\tconfig[p] = element.getAttribute(p);\n\t});\n\telse Object.assign(config, element);\n\tlet pathArray = [];\n\tif (type === \"circle\") pathArray = getCirclePath(config);\n\telse if (type === \"ellipse\") pathArray = getEllipsePath(config);\n\telse if ([\"polyline\", \"polygon\"].includes(type)) pathArray = getPolyPath(config);\n\telse if (type === \"rect\") pathArray = getRectanglePath(config);\n\telse if (type === \"line\") pathArray = getLinePath(config);\n\telse if ([\"glyph\", \"path\"].includes(type)) pathArray = parsePathString(targetIsElement ? element.getAttribute(\"d\") || \"\" : element.d || \"\");\n\tif (isPathArray(pathArray) && pathArray.length) return pathArray;\n\treturn false;\n};\n//#endregion\n//#region src/util/shapeToPath.ts\n/**\n* Returns a new `<path>` element created from attributes of a `<line>`, `<polyline>`,\n* `<polygon>`, `<rect>`, `<ellipse>`, `<circle>` or `<glyph>`. If `replace` parameter\n* is `true`, it will replace the target. The default `ownerDocument` is your current\n* `document` browser page, if you want to use in server-side using `jsdom`, you can\n* pass the `jsdom` `document` to `ownDocument`.\n*\n* It can also work with an options object, see the type below\n* @see ShapeOps\n*\n* The newly created `<path>` element keeps all non-specific\n* attributes like `class`, `fill`, etc.\n*\n* @param element - Target shape element or shape options object\n* @param replace - Option to replace target element\n* @param ownerDocument - Document for creating the element\n* @returns The newly created `<path>` element, or false if the path is invalid\n*\n* @example\n* ```ts\n* const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle')\n* circle.setAttribute('cx', '50')\n* circle.setAttribute('cy', '50')\n* circle.setAttribute('r', '25')\n* const path = shapeToPath(circle)\n* path.getAttribute('d')\n* // => 'M50 25A25 25 0 1 1 50 75A25 25 0 1 1 50 25Z'\n* ```\n*/\nconst shapeToPath = (element, replace, ownerDocument) => {\n\tconst doc = ownerDocument || document;\n\tconst supportedShapes = Object.keys(shapeParams);\n\tconst targetIsElement = isElement(element);\n\tconst tagName = targetIsElement ? element.tagName : null;\n\tif (tagName === \"path\") throw TypeError(`${error}: \"${tagName}\" is already SVGPathElement`);\n\tif (tagName && supportedShapes.every((s) => tagName !== s)) throw TypeError(`${error}: \"${tagName}\" is not SVGElement`);\n\tconst path = doc.createElementNS(\"http://www.w3.org/2000/svg\", \"path\");\n\tconst type = targetIsElement ? tagName : element.type;\n\tconst shapeAttrs = shapeParams[type];\n\tconst config = { type };\n\tconst round = defaultOptions.round;\n\tconst pathArray = shapeToPathArray(element);\n\tconst description = pathArray && pathArray.length ? pathToString(pathArray, round) : \"\";\n\tif (targetIsElement) {\n\t\tshapeAttrs.forEach((p) => {\n\t\t\tconfig[p] = element.getAttribute(p);\n\t\t});\n\t\tfor (let i = 0; i < element.attributes.length; i++) {\n\t\t\tconst attr = element.attributes[i];\n\t\t\tif (attr && !shapeAttrs.includes(attr.name)) path.setAttribute(attr.name, attr.value);\n\t\t}\n\t} else {\n\t\tObject.assign(config, element);\n\t\tObject.keys(config).forEach((k) => {\n\t\t\tif (!shapeAttrs.includes(k) && k !== \"type\") path.setAttribute(k.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`), config[k]);\n\t\t});\n\t}\n\tif (isValidPath(description)) {\n\t\tpath.setAttribute(\"d\", description);\n\t\tif (replace && targetIsElement) {\n\t\t\telement.before(path, element);\n\t\t\telement.remove();\n\t\t}\n\t\treturn path;\n\t}\n\treturn false;\n};\n//#endregion\n//#region src/process/shortenSegment.ts\n/**\n* Shorten a single segment of a `pathArray` object.\n*\n* @param segment the `absoluteSegment` object\n* @param normalSegment the `normalSegment` object\n* @param params the coordinates of the previous segment\n* @param prevCommand the path command of the previous segment\n* @returns the shortened segment\n*/\nconst shortenSegment = (segment, normalSegment, params, prevCommand) => {\n\tconst [pathCommand] = segment;\n\tconst { round: defaultRound } = defaultOptions;\n\tconst round = typeof defaultRound === \"number\" ? defaultRound : 4;\n\tconst normalValues = normalSegment.slice(1);\n\tconst { x1, y1, x2, y2, x, y } = params;\n\tconst [nx, ny] = normalValues.slice(-2);\n\tconst result = segment;\n\tif (!\"TQ\".includes(pathCommand)) {\n\t\tparams.qx = null;\n\t\tparams.qy = null;\n\t}\n\tif (pathCommand === \"L\") {\n\t\tif (roundTo(x, round) === roundTo(nx, round)) return [\"V\", ny];\n\t\telse if (roundTo(y, round) === roundTo(ny, round)) return [\"H\", nx];\n\t} else if (pathCommand === \"C\") {\n\t\tconst [nx1, ny1] = normalValues;\n\t\tparams.x1 = nx1;\n\t\tparams.y1 = ny1;\n\t\tif (\"CS\".includes(prevCommand) && (roundTo(nx1, round) === roundTo(x1 * 2 - x2, round) && roundTo(ny1, round) === roundTo(y1 * 2 - y2, round) || roundTo(x1, round) === roundTo(x2 * 2 - x, round) && roundTo(y1, round) === roundTo(y2 * 2 - y, round))) return [\n\t\t\t\"S\",\n\t\t\tnormalValues[2],\n\t\t\tnormalValues[3],\n\t\t\tnormalValues[4],\n\t\t\tnormalValues[5]\n\t\t];\n\t} else if (pathCommand === \"Q\") {\n\t\tconst [qx, qy] = normalValues;\n\t\tparams.qx = qx;\n\t\tparams.qy = qy;\n\t\tif (\"QT\".includes(prevCommand) && roundTo(qx, round) === roundTo(x1 * 2 - x2, round) && roundTo(qy, round) === roundTo(y1 * 2 - y2, round)) return [\n\t\t\t\"T\",\n\t\t\tnormalValues[2],\n\t\t\tnormalValues[3]\n\t\t];\n\t}\n\treturn result;\n};\n//#endregion\n//#region src/process/roundSegment.ts\n/**\n* Rounds the numeric values of a path segment to the specified precision.\n*\n* @param segment - The path segment to round\n* @param roundOption - Number of decimal places\n* @returns The rounded segment\n*/\nconst roundSegment = (segment, roundOption) => {\n\tconst values = segment.slice(1).map((n) => roundTo(n, roundOption));\n\treturn [segment[0]].concat(values);\n};\n//#endregion\n//#region src/process/optimizePath.ts\n/**\n* Optimizes a PathArray:\n* * converts segments to shorthand if possible\n* * selects shortest representation from absolute and relative forms\n*\n* @param pathInput - A path string or PathArray\n* @param roundOption - Number of decimal places for rounding\n* @returns The optimized PathArray\n*\n* @example\n* ```ts\n* optimizePath('M10 10L10 10L90 90', 2)\n* // => [['M', 10, 10], ['l', 0, 0], ['l', 80, 80]]\n* ```\n*/\nconst optimizePath = (pathInput, roundOption) => {\n\tconst path = pathToAbsolute(pathInput);\n\tconst round = typeof roundOption === \"number\" && roundOption >= 0 ? roundOption : 2;\n\tconst optimParams = { ...paramsParser };\n\tconst allPathCommands = [];\n\tlet pathCommand = \"M\";\n\tlet prevCommand = \"Z\";\n\treturn iterate(path, (seg, i, lastX, lastY) => {\n\t\toptimParams.x = lastX;\n\t\toptimParams.y = lastY;\n\t\tconst normalizedSegment = normalizeSegment(seg, optimParams);\n\t\tlet result = seg;\n\t\tpathCommand = seg[0];\n\t\tallPathCommands[i] = pathCommand;\n\t\tif (i) {\n\t\t\tprevCommand = allPathCommands[i - 1];\n\t\t\tconst shortSegment = shortenSegment(seg, normalizedSegment, optimParams, prevCommand);\n\t\t\tconst absSegment = roundSegment(shortSegment, round);\n\t\t\tconst absString = absSegment.join(\"\");\n\t\t\tconst relSegment = roundSegment(relativizeSegment(shortSegment, i, lastX, lastY), round);\n\t\t\tconst relString = relSegment.join(\"\");\n\t\t\tresult = absString.length < relString.length ? absSegment : relSegment;\n\t\t}\n\t\tconst seglen = normalizedSegment.length;\n\t\toptimParams.x1 = +normalizedSegment[seglen - 2];\n\t\toptimParams.y1 = +normalizedSegment[seglen - 1];\n\t\toptimParams.x2 = +normalizedSegment[seglen - 4] || optimParams.x1;\n\t\toptimParams.y2 = +normalizedSegment[seglen - 3] || optimParams.y1;\n\t\treturn result;\n\t});\n};\n//#endregion\n//#region src/process/reversePath.ts\n/**\n* Reverses all segments of a PathArray and returns a new PathArray\n* with absolute values.\n*\n* @param pathInput - The source PathArray\n* @returns The reversed PathArray\n*\n* @example\n* ```ts\n* reversePath([['M', 0, 0], ['L', 100, 0], ['L', 100, 100], ['L', 0, 100], ['Z']])\n* // => [['M', 0, 100], ['L', 0, 0], ['L', 100, 0], ['L', 100, 100], ['Z']]\n* ```\n*/\nconst reversePath = (pathInput) => {\n\tconst absolutePath = pathToAbsolute(pathInput);\n\tconst normalizedPath = normalizePath(absolutePath);\n\tconst pLen = absolutePath.length;\n\tconst isClosed = absolutePath[pLen - 1][0] === \"Z\";\n\tconst reversedPath = iterate(absolutePath, (segment, i) => {\n\t\tconst normalizedSegment = normalizedPath[i];\n\t\tconst prevSeg = i && absolutePath[i - 1];\n\t\tconst prevCommand = prevSeg && prevSeg[0];\n\t\tconst nextSeg = absolutePath[i + 1];\n\t\tconst nextCommand = nextSeg && nextSeg[0];\n\t\tconst pathCommand = segment[0];\n\t\tconst [x, y] = normalizedPath[i ? i - 1 : pLen - 1].slice(-2);\n\t\tlet result = segment;\n\t\tswitch (pathCommand) {\n\t\t\tcase \"M\":\n\t\t\t\tresult = isClosed ? [\"Z\"] : [\n\t\t\t\t\tpathCommand,\n\t\t\t\t\tx,\n\t\t\t\t\ty\n\t\t\t\t];\n\t\t\t\tbreak;\n\t\t\tcase \"A\":\n\t\t\t\tresult = [\n\t\t\t\t\tpathCommand,\n\t\t\t\t\tsegment[1],\n\t\t\t\t\tsegment[2],\n\t\t\t\t\tsegment[3],\n\t\t\t\t\tsegment[4],\n\t\t\t\t\tsegment[5] === 1 ? 0 : 1,\n\t\t\t\t\tx,\n\t\t\t\t\ty\n\t\t\t\t];\n\t\t\t\tbreak;\n\t\t\tcase \"C\":\n\t\t\t\tif (nextSeg && nextCommand === \"S\") result = [\n\t\t\t\t\t\"S\",\n\t\t\t\t\tsegment[1],\n\t\t\t\t\tsegment[2],\n\t\t\t\t\tx,\n\t\t\t\t\ty\n\t\t\t\t];\n\t\t\t\telse result = [\n\t\t\t\t\tpathCommand,\n\t\t\t\t\tsegment[3],\n\t\t\t\t\tsegment[4],\n\t\t\t\t\tsegment[1],\n\t\t\t\t\tsegment[2],\n\t\t\t\t\tx,\n\t\t\t\t\ty\n\t\t\t\t];\n\t\t\t\tbreak;\n\t\t\tcase \"S\":\n\t\t\t\tif (prevCommand && \"CS\".includes(prevCommand) && (!nextSeg || nextCommand !== \"S\")) result = [\n\t\t\t\t\t\"C\",\n\t\t\t\t\tnormalizedSegment[3],\n\t\t\t\t\tnormalizedSegment[4],\n\t\t\t\t\tnormalizedSegment[1],\n\t\t\t\t\tnormalizedSegment[2],\n\t\t\t\t\tx,\n\t\t\t\t\ty\n\t\t\t\t];\n\t\t\t\telse result = [\n\t\t\t\t\tpathCommand,\n\t\t\t\t\tnormalizedSegment[1],\n\t\t\t\t\tnormalizedSegment[2],\n\t\t\t\t\tx,\n\t\t\t\t\ty\n\t\t\t\t];\n\t\t\t\tbreak;\n\t\t\tcase \"Q\":\n\t\t\t\tif (nextSeg && nextCommand === \"T\") result = [\n\t\t\t\t\t\"T\",\n\t\t\t\t\tx,\n\t\t\t\t\ty\n\t\t\t\t];\n\t\t\t\telse result = [\n\t\t\t\t\tpathCommand,\n\t\t\t\t\tsegment[1],\n\t\t\t\t\tsegment[2],\n\t\t\t\t\tx,\n\t\t\t\t\ty\n\t\t\t\t];\n\t\t\t\tbreak;\n\t\t\tcase \"T\":\n\t\t\t\tif (prevCommand && \"QT\".includes(prevCommand) && (!nextSeg || nextCommand !== \"T\")) result = [\n\t\t\t\t\t\"Q\",\n\t\t\t\t\tnormalizedSegment[1],\n\t\t\t\t\tnormalizedSegment[2],\n\t\t\t\t\tx,\n\t\t\t\t\ty\n\t\t\t\t];\n\t\t\t\telse result = [\n\t\t\t\t\tpathCommand,\n\t\t\t\t\tx,\n\t\t\t\t\ty\n\t\t\t\t];\n\t\t\t\tbreak;\n\t\t\tcase \"Z\":\n\t\t\t\tresult = [\n\t\t\t\t\t\"M\",\n\t\t\t\t\tx,\n\t\t\t\t\ty\n\t\t\t\t];\n\t\t\t\tbreak;\n\t\t\tcase \"H\":\n\t\t\t\tresult = [pathCommand, x];\n\t\t\t\tbreak;\n\t\t\tcase \"V\":\n\t\t\t\tresult = [pathCommand, y];\n\t\t\t\tbreak;\n\t\t\tdefault: result = [pathCommand].concat(segment.slice(1, -2), x, y);\n\t\t}\n\t\treturn result;\n\t});\n\treturn isClosed ? reversedPath.reverse() : [reversedPath[0]].concat(reversedPath.slice(1).reverse());\n};\n//#endregion\n//#region src/process/splitPath.ts\n/**\n* Split a path string or PathArray into an array of sub-paths.\n*\n* In the process, values are converted to absolute\n* for visual consistency.\n*\n* @param pathInput - The source path string or PathArray\n* @returns An array of sub-path PathArrays\n*\n* @example\n* ```ts\n* splitPath('M0 0L100 0ZM200 0L300 0Z')\n* // => [\n* // [['M', 0, 0], ['L', 100, 0], ['Z']],\n* // [['M', 200, 0], ['L', 300, 0], ['Z']]\n* // ]\n* ```\n*/\nconst splitPath = (pathInput) => {\n\tconst composite = [];\n\tconst parsedPath = parsePathString(pathInput);\n\tlet path = [];\n\tlet pi = -1;\n\tlet x = 0;\n\tlet y = 0;\n\tlet mx = 0;\n\tlet my = 0;\n\titerate(parsedPath, (seg, _, prevX, prevY) => {\n\t\tconst cmd = seg[0];\n\t\tconst absCommand = cmd.toUpperCase();\n\t\tconst isRelative = cmd === cmd.toLowerCase();\n\t\tconst values = seg.slice(1);\n\t\tif (absCommand === \"M\") {\n\t\t\tpi += 1;\n\t\t\t[x, y] = values;\n\t\t\tx += isRelative ? prevX : 0;\n\t\t\ty += isRelative ? prevY : 0;\n\t\t\tmx = x;\n\t\t\tmy = y;\n\t\t\tpath = [isRelative ? [\n\t\t\t\tabsCommand,\n\t\t\t\tmx,\n\t\t\t\tmy\n\t\t\t] : seg];\n\t\t} else {\n\t\t\tif (absCommand === \"Z\") {\n\t\t\t\tx = mx;\n\t\t\t\ty = my;\n\t\t\t} else if (absCommand === \"H\") {\n\t\t\t\t[, x] = seg;\n\t\t\t\tx += isRelative ? prevX : 0;\n\t\t\t} else if (absCommand === \"V\") {\n\t\t\t\t[, y] = seg;\n\t\t\t\ty += isRelative ? prevY : 0;\n\t\t\t} else {\n\t\t\t\t[x, y] = seg.slice(-2);\n\t\t\t\tx += isRelative ? prevX : 0;\n\t\t\t\ty += isRelative ? prevY : 0;\n\t\t\t}\n\t\t\tpath.push(seg);\n\t\t}\n\t\tcomposite[pi] = path;\n\t});\n\treturn composite;\n};\n//#endregion\n//#region src/process/getSVGMatrix.ts\n/**\n* Returns a transformation matrix to apply to `<path>` elements.\n*\n* @see TransformObjectValues\n*\n* @param transform the `transformObject`\n* @returns a new transformation matrix\n*/\nconst getSVGMatrix = (transform) => {\n\tlet matrix = new CSSMatrix();\n\tconst { origin } = transform;\n\tconst [originX, originY] = origin;\n\tconst { translate } = transform;\n\tconst { rotate } = transform;\n\tconst { skew } = transform;\n\tconst { scale } = transform;\n\tif (Array.isArray(translate) && translate.length >= 2 && translate.every((x) => !Number.isNaN(+x)) && translate.some((x) => x !== 0)) matrix = matrix.translate(...translate);\n\telse if (typeof translate === \"number\" && !Number.isNaN(translate)) matrix = matrix.translate(translate);\n\tif (rotate || skew || scale) {\n\t\tmatrix = matrix.translate(originX, originY);\n\t\tif (Array.isArray(rotate) && rotate.length >= 2 && rotate.every((x) => !Number.isNaN(+x)) && rotate.some((x) => x !== 0)) matrix = matrix.rotate(...rotate);\n\t\telse if (typeof rotate === \"number\" && !Number.isNaN(rotate)) matrix = matrix.rotate(rotate);\n\t\tif (Array.isArray(skew) && skew.length === 2 && skew.every((x) => !Number.isNaN(+x)) && skew.some((x) => x !== 0)) {\n\t\t\tmatrix = skew[0] ? matrix.skewX(skew[0]) : matrix;\n\t\t\tmatrix = skew[1] ? matrix.skewY(skew[1]) : matrix;\n\t\t} else if (typeof skew === \"number\" && !Number.isNaN(skew)) matrix = matrix.skewX(skew);\n\t\tif (Array.isArray(scale) && scale.length >= 2 && scale.every((x) => !Number.isNaN(+x)) && scale.some((x) => x !== 1)) matrix = matrix.scale(...scale);\n\t\telse if (typeof scale === \"number\" && !Number.isNaN(scale)) matrix = matrix.scale(scale);\n\t\tmatrix = matrix.translate(-originX, -originY);\n\t}\n\treturn matrix;\n};\n//#endregion\n//#region src/process/projection2d.ts\n/**\n* Transforms a specified point using a matrix, returning a new\n* Tuple *Object* comprising of the transformed point.\n* Neither the matrix nor the original point are altered.\n*\n* @copyright thednp © 2021\n*\n* @param cssm CSSMatrix instance\n* @param v Tuple\n* @returns the resulting Tuple\n*/\nconst translatePoint = (cssm, v) => {\n\tlet m = CSSMatrix.Translate(v[0], v[1], v[2]);\n\t[, , , m.m44] = v;\n\tm = cssm.multiply(m);\n\treturn [\n\t\tm.m41,\n\t\tm.m42,\n\t\tm.m43,\n\t\tm.m44\n\t];\n};\n/**\n* Returns the [x,y] projected coordinates for a given an [x,y] point\n* and an [x,y,z] perspective origin point.\n*\n* Equation found here =>\n* http://en.wikipedia.org/wiki/3D_projection#Diagram\n* Details =>\n* https://stackoverflow.com/questions/23792505/predicted-rendering-of-css-3d-transformed-pixel\n*\n* @param m the transformation matrix\n* @param point2D the initial [x,y] coordinates\n* @param origin the [x,y,z] transform origin\n* @returns the projected [x,y] coordinates\n*/\nconst projection2d = (m, point2D, origin) => {\n\tconst [originX, originY, originZ] = origin;\n\tconst [x, y, z] = translatePoint(m, [\n\t\tpoint2D[0],\n\t\tpoint2D[1],\n\t\t0,\n\t\t1\n\t]);\n\tconst relativePositionX = x - originX;\n\tconst relativePositionY = y - originY;\n\tconst relativePositionZ = z - originZ;\n\treturn [relativePositionX * (Math.abs(originZ) / Math.abs(relativePositionZ) || 1) + originX, relativePositionY * (Math.abs(originZ) / Math.abs(relativePositionZ) || 1) + originY];\n};\n//#endregion\n//#region src/process/transformPath.ts\n/**\n* Apply a 2D / 3D transformation to a PathArray.\n*\n* Since SVGElement doesn't support 3D transformation, this function\n* creates a 2D projection of the path element.\n*\n* @param pathInput - The PathArray or path string to transform\n* @param transform - The transform functions object (translate, rotate, skew, scale, origin)\n* @returns The transformed PathArray\n*\n* @example\n* ```ts\n* transformPath('M0 0L100 0L100 100L0 100Z', { translate: [10, 20], scale: 2 })\n* // => [['M', 10, 20], ['L', 210, 20], ['L', 210, 220], ['L', 10, 220], ['Z']]\n* ```\n*/\nconst transformPath = (pathInput, transform) => {\n\tlet x = 0;\n\tlet y = 0;\n\tlet lx = 0;\n\tlet ly = 0;\n\tlet j = 0;\n\tlet jj = 0;\n\tconst path = parsePathString(pathInput);\n\tconst transformProps = transform && Object.keys(transform);\n\tif (!transform || transformProps && !transformProps.length) return path.slice(0);\n\tif (!transform.origin) Object.assign(transform, { origin: defaultOptions.origin });\n\tconst origin = transform.origin;\n\tconst matrixInstance = getSVGMatrix(transform);\n\tif (matrixInstance.isIdentity) return path.slice(0);\n\treturn iterate(path, (seg, index, lastX, lastY) => {\n\t\tlet [pathCommand] = seg;\n\t\tconst absCommand = pathCommand.toUpperCase();\n\t\tconst absoluteSegment = absCommand !== pathCommand ? absolutizeSegment(seg, index, lastX, lastY) : seg.slice(0);\n\t\tlet result = absCommand === \"A\" ? [\"C\"].concat(arcToCubic(lastX, lastY, absoluteSegment[1], absoluteSegment[2], absoluteSegment[3], absoluteSegment[4], absoluteSegment[5], absoluteSegment[6], absoluteSegment[7])) : absCommand === \"V\" ? [\n\t\t\t\"L\",\n\t\t\tlastX,\n\t\t\tabsoluteSegment[1]\n\t\t] : absCommand === \"H\" ? [\n\t\t\t\"L\",\n\t\t\tabsoluteSegment[1],\n\t\t\tlastY\n\t\t] : absoluteSegment;\n\t\tpathCommand = result[0];\n\t\tconst isLongArc = pathCommand === \"C\" && result.length > 7;\n\t\tconst tempSegment = isLongArc ? result.slice(0, 7) : result.slice(0);\n\t\tif (isLongArc) {\n\t\t\tpath.splice(index + 1, 0, [\"C\"].concat(result.slice(7)));\n\t\t\tresult = tempSegment;\n\t\t}\n\t\tif (pathCommand === \"L\") {\n\t\t\t[lx, ly] = projection2d(matrixInstance, [result[1], result[2]], origin);\n\t\t\tif (x !== lx && y !== ly) result = [\n\t\t\t\t\"L\",\n\t\t\t\tlx,\n\t\t\t\tly\n\t\t\t];\n\t\t\telse if (y === ly) result = [\"H\", lx];\n\t\t\telse if (x === lx) result = [\"V\", ly];\n\t\t} else for (j = 1, jj = result.length; j < jj; j += 2) {\n\t\t\t[lx, ly] = projection2d(matrixInstance, [+result[j], +result[j + 1]], origin);\n\t\t\tresult[j] = lx;\n\t\t\tresult[j + 1] = ly;\n\t\t}\n\t\tx = lx;\n\t\ty = ly;\n\t\treturn result;\n\t});\n};\n//#endregion\n//#region src/process/reverseCurve.ts\n/**\n* Reverses all segments of a `pathArray`\n* which consists of only C (cubic-bezier) path commands.\n*\n* @param path the source `pathArray`\n* @returns the reversed `pathArray`\n*/\nconst reverseCurve = (path) => {\n\tconst rotatedCurve = path.slice(1).map((x, i, curveOnly) => !i ? path[0].slice(1).concat(x.slice(1)) : curveOnly[i - 1].slice(-2).concat(x.slice(1))).map((x) => x.map((_, i) => x[x.length - i - 2 * (1 - i % 2)])).reverse();\n\treturn [[\"M\"].concat(rotatedCurve[0].slice(0, 2))].concat(rotatedCurve.map((x) => [\"C\"].concat(x.slice(2))));\n};\n//#endregion\n//#region src/process/roundPath.ts\n/**\n* Rounds the values of a `pathArray` instance to\n* a specified amount of decimals and returns it.\n*\n* @param path the source `pathArray`\n* @param roundOption the amount of decimals to round numbers to\n* @returns the resulted `pathArray` with rounded values\n*/\nconst roundPath = (path, roundOption) => {\n\tlet { round } = defaultOptions;\n\tround = roundOption === \"off\" ? roundOption : typeof roundOption === \"number\" && roundOption >= 0 ? roundOption : typeof round === \"number\" && round >= 0 ? round : \"off\";\n\tif (round === \"off\") return path.slice(0);\n\treturn iterate(path, (segment) => {\n\t\treturn roundSegment(segment, round);\n\t});\n};\n//#endregion\n//#region src/morph/fixPath.ts\n/**\n* Checks a `PathArray` for an unnecessary `Z` segment\n* and removes it. The `PathArray` is modified in place.\n* In short, if the segment before `Z` extends to `M`,\n* the `Z` segment must be removed.\n*\n* The `pathInput` must be a single path, without\n* sub-paths. For multi-path `<path>` elements,\n* use `splitPath` first and apply this utility on each\n* sub-path separately.\n*\n* @param pathInput the `pathArray` source\n* @returns void\n*/\nconst fixPath = (pathInput) => {\n\tconst pathArray = parsePathString(pathInput);\n\tif (isClosedPath(pathArray)) {\n\t\tconst normalArray = normalizePath(pathArray);\n\t\tconst length = pathArray.length;\n\t\tconst segBeforeZ = length - 2;\n\t\tconst [mx, my] = normalArray[0].slice(1);\n\t\tconst [x, y] = normalArray[segBeforeZ].slice(-2);\n\t\tif (mx === x && my === y) pathArray.splice(length - 1, 1);\n\t}\n};\n//#endregion\n//#region src/morph/splitCubicSegment.ts\n/**\n* Split a cubic Bézier into two cubics at parameter t [0–1].\n*\n* @param x1 - Start point X\n* @param y1 - Start point Y\n* @param x2 - First control point X\n* @param y2 - First control point Y\n* @param x3 - Second control point X\n* @param y3 - Second control point Y\n* @param x4 - End point X\n* @param y4 - End point Y\n* @param t - Parameter in range [0, 1] at which to split\n* @returns Array of two cubic segments, each as [x1,y1, x2,y2, x3,y3, x4,y4]\n*/\nfunction splitCubicSegment(x1, y1, x2, y2, x3, y3, x4, y4, t) {\n\tconst [px01, py01] = midPoint([x1, y1], [x2, y2], t);\n\tconst [px12, py12] = midPoint([x2, y2], [x3, y3], t);\n\tconst [px23, py23] = midPoint([x3, y3], [x4, y4], t);\n\tconst [cx0, cy0] = midPoint([px01, py01], [px12, py12], t);\n\tconst [cx1, cy1] = midPoint([px12, py12], [px23, py23], t);\n\tconst [px, py] = midPoint([cx0, cy0], [cx1, cy1], t);\n\treturn [[\n\t\tx1,\n\t\ty1,\n\t\tpx01,\n\t\tpy01,\n\t\tcx0,\n\t\tcy0,\n\t\tpx,\n\t\tpy\n\t], [\n\t\tpx,\n\t\tpy,\n\t\tcx1,\n\t\tcy1,\n\t\tpx23,\n\t\tpy23,\n\t\tx4,\n\t\ty4\n\t]];\n}\n//#endregion\n//#region src/morph/pathToPolyline.ts\n/**\n* Converts any `PolyLineArray`/`PolygonArray` path (closed or open) to an explicit polyline (M + L*).\n* If the path is closed (has Z), the Z is replaced with an explicit L back to the initial M point.\n* This allows uniform processing without special-casing Z.\n*\n* @param path string or PathArray\n* @returns PolylineArray (M + L*) — never contains Z\n*/\nconst pathToPolyline = (path) => {\n\tconst normal = normalizePath(path);\n\tif (!isPolygonArray(normal) && !isPolylineArray(normal)) throw TypeError(`${error}: pathValue is not a polyline/polygon`);\n\tif (!isClosedPath(normal)) return normal;\n\tconst result = [normal[0]];\n\tconst [mx, my] = normal[0].slice(1);\n\tfor (let i = 1; i < normal.length; i++) {\n\t\tconst seg = normal[i];\n\t\tif (seg[0].toUpperCase() === \"Z\") result.push([\n\t\t\t\"L\",\n\t\t\tmx,\n\t\t\tmy\n\t\t]);\n\t\telse result.push(seg);\n\t}\n\treturn result;\n};\n//#endregion\n//#region src/morph/splitLineToCount.ts\n/**\n* Split a line segment into `count` smaller segments of equal length\n* using the same repeated front-cutting strategy as splitCubicToCount.\n*\n* Does NOT mutate input.\n*\n* @param x1 - Start point X\n* @param y1 - Start point Y\n* @param x2 - End point X\n* @param y2 - End point Y\n* @param count - Number of segments to split into\n* @returns Array of `count` line segments, each as [x1, y1, x2, y2]\n*/\nfunction splitLineToCount(x1, y1, x2, y2, count) {\n\tif (count <= 1) return [[\n\t\tx1,\n\t\ty1,\n\t\tx2,\n\t\ty2\n\t]];\n\tconst result = [];\n\tconst dx = x2 - x1;\n\tconst dy = y2 - y1;\n\tlet currentX = x1;\n\tlet currentY = y1;\n\tlet i = 0;\n\twhile (i < count) {\n\t\tconst t = 1 / (count - i);\n\t\tconst nextX = x1 + t * dx;\n\t\tconst nextY = y1 + t * dy;\n\t\tresult.push([\n\t\t\tcurrentX,\n\t\t\tcurrentY,\n\t\t\tnextX,\n\t\t\tnextY\n\t\t]);\n\t\tcurrentX = nextX;\n\t\tcurrentY = nextY;\n\t\ti++;\n\t}\n\treturn result;\n}\n//#endregion\n//#region src/morph/getPathSplits.ts\n/**\n* Determine the right amount of splits for each segment in a given PathArray\n* and for a target total amount of sub-segments.\n* For a triangle path \"M0,0 L600,300 L0,600 Z\" we have 3 equal lines,\n* we can easily do 4 splits per line and go to town, however, most triangles\n* are not even so we need to take side lengths into account.\n* @param path The target PathArray\n* @param target The total amount of sub-segments\n* @returns an array of numbers reprezenting the sub-segment count for each segment\n*/\nfunction getPathSplits(path, target) {\n\tif (target <= 1) throw new TypeError(`${error}: target must be >= 2`);\n\tconst totalLength = getTotalLength(path);\n\tif (totalLength === 0) return Array(path.length).fill(1);\n\tconst idealSegLen = totalLength / target;\n\tconst isPoly = isPolylineArray(path);\n\tconst splits = [1];\n\tconst lengths = [0];\n\titerate(path, (seg, i, prevX, prevY) => {\n\t\tif (i > 0) {\n\t\t\tconst [endX, endY] = seg.slice(-2);\n\t\t\tconst segLen = isPoly ? getLineLength(prevX, prevY, endX, endY) : getCubicLength(prevX, prevY, seg[1], seg[2], seg[3], seg[4], seg[5], seg[6]);\n\t\t\tlengths.push(segLen);\n\t\t\tsplits.push(1);\n\t\t}\n\t});\n\tlet totalAllocated = 1;\n\tfor (let i = 1; i < lengths.length; i++) {\n\t\tconst segLen = lengths[i];\n\t\tconst desired = segLen > idealSegLen ? Math.round(segLen / idealSegLen) : 1;\n\t\tsplits[i] = desired;\n\t\ttotalAllocated += desired;\n\t}\n\tlet diff = target - totalAllocated;\n\tif (diff !== 0) {\n\t\tconst candidates = [];\n\t\tfor (let i = 1; i < lengths.length; i++) if (lengths[i] > 0) candidates.push([i, lengths[i]]);\n\t\tconst cLen = candidates.length;\n\t\tif (diff < 0) {\n\t\t\tcandidates.sort((a, b) => a[1] - b[1]);\n\t\t\tfor (let i = 0; i < cLen; i++) {\n\t\t\t\tconst idx = candidates[i][0];\n\t\t\t\tif (splits[idx] > 1 && candidates[i][1] > 0) {\n\t\t\t\t\tsplits[idx]--;\n\t\t\t\t\tdiff++;\n\t\t\t\t}\n\t\t\t\tif (diff === 0) break;\n\t\t\t\telse if (i === cLen - 1) i = 0;\n\t\t\t}\n\t\t} else if (diff > 0) {\n\t\t\tcandidates.sort((a, b) => b[1] - a[1]);\n\t\t\tfor (let i = 0; i < cLen; i++) {\n\t\t\t\tconst idx = candidates[i][0];\n\t\t\t\tif (candidates[i][1] > 0) {\n\t\t\t\t\tsplits[idx]++;\n\t\t\t\t\tdiff--;\n\t\t\t\t}\n\t\t\t\tif (diff === 0) break;\n\t\t\t\telse if (i === cLen - 1) i = 0;\n\t\t\t}\n\t\t}\n\t}\n\treturn splits;\n}\n//#endregion\n//#region src/morph/splitLinePathToCount.ts\n/**\n* Splits a PolylineArray so that it has exactly `target` line segments.\n*\n* @param path - The polyline array to split\n* @param target - The desired number of line segments\n* @returns The modified polyline array with the target segment count\n*/\nfunction splitLinePathToCount(path, target) {\n\tif (path.length < 2 || target <= 1) return path;\n\tconst splits = getPathSplits(path, target);\n\tlet totalAdded = 0;\n\tconst newPath = [path[0]];\n\tconst pathLen = path.length;\n\tlet currentX = path[0][1];\n\tlet currentY = path[0][2];\n\tfor (let i = 1; i < pathLen; i++) {\n\t\tconst [endX, endY] = path[i].slice(1);\n\t\tconst count = splits[i];\n\t\tif (count >= 1) {\n\t\t\tconst subLines = splitLineToCount(currentX, currentY, endX, endY, count);\n\t\t\tfor (const sub of subLines) {\n\t\t\t\tnewPath.push([\n\t\t\t\t\t\"L\",\n\t\t\t\t\tsub[2],\n\t\t\t\t\tsub[3]\n\t\t\t\t]);\n\t\t\t\ttotalAdded++;\n\t\t\t}\n\t\t}\n\t\tcurrentX = endX;\n\t\tcurrentY = endY;\n\t}\n\tif (newPath.length !== target) console.warn(`${error}: requested ${target} segments, got ${newPath.length}. Adjusted on last segment.`);\n\treturn newPath;\n}\n//#endregion\n//#region src/morph/splitCubicToCount.ts\n/**\n* Split a cubic Bézier into `count` segments of roughly equal parameter length.\n* Does NOT mutate input parameters.\n*\n* @param x1 - Start point X\n* @param y1 - Start point Y\n* @param x2 - First control point X\n* @param y2 - First control point Y\n* @param x3 - Second control point X\n* @param y3 - Second control point Y\n* @param x4 - End point X\n* @param y4 - End point Y\n* @param count - Number of segments to split into\n* @returns Array of `count` cubic segments, each as [x1,y1,x2,y2,x3,y3,x4,y4]\n*/\nfunction splitCubicToCount(x1, y1, x2, y2, x3, y3, x4, y4, count) {\n\tif (count <= 1) return [[\n\t\tx1,\n\t\ty1,\n\t\tx2,\n\t\ty2,\n\t\tx3,\n\t\ty3,\n\t\tx4,\n\t\ty4\n\t]];\n\tconst result = [];\n\tlet cx1 = x1;\n\tlet cy1 = y1;\n\tlet cx2 = x2;\n\tlet cy2 = y2;\n\tlet cx3 = x3;\n\tlet cy3 = y3;\n\tlet cx4 = x4;\n\tlet cy4 = y4;\n\tlet i = 0;\n\twhile (i < count) {\n\t\tconst t = 1 / (count - i);\n\t\tconst [first, second] = splitCubicSegment(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4, t);\n\t\tresult.push(first);\n\t\t[cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4] = second;\n\t\ti++;\n\t}\n\treturn result;\n}\n//#endregion\n//#region src/morph/splitCurvePathToCount.ts\n/**\n* Splits a CurveArray so that it has exactly `target` cubic segments.\n*\n* @param path - The curve array to split\n* @param target - The desired number of cubic segments\n* @returns The modified curve array with the target segment count\n*/\nfunction splitCurvePathToCount(path, target) {\n\tif (path.length < 2 || target <= 1) return path;\n\tconst splits = getPathSplits(path, target);\n\tlet totalAdded = 0;\n\tconst newPath = [path[0]];\n\tconst pathLen = path.length;\n\tlet currentX = path[0][1];\n\tlet currentY = path[0][2];\n\tfor (let i = 1; i < pathLen; i++) {\n\t\tconst seg = path[i];\n\t\tconst [endX, endY] = seg.slice(-2);\n\t\tconst count = splits[i];\n\t\tif (count >= 1) {\n\t\t\tconst subs = splitCubicToCount(currentX, currentY, seg[1], seg[2], seg[3], seg[4], seg[5], seg[6], count);\n\t\t\tfor (const sub of subs) {\n\t\t\t\tnewPath.push([\n\t\t\t\t\t\"C\",\n\t\t\t\t\tsub[2],\n\t\t\t\t\tsub[3],\n\t\t\t\t\tsub[4],\n\t\t\t\t\tsub[5],\n\t\t\t\t\tsub[6],\n\t\t\t\t\tsub[7]\n\t\t\t\t]);\n\t\t\t\ttotalAdded++;\n\t\t\t}\n\t\t}\n\t\tcurrentX = endX;\n\t\tcurrentY = endY;\n\t}\n\tif (newPath.length !== target) console.warn(`${error}: requested ${target} segments, got ${newPath.length}.`);\n\treturn newPath;\n}\n//#endregion\n//#region src/morph/samplePolygon.ts\n/**\n* Samples points from a path to form a polygon approximation.\n* Collects endpoints of each segment (M start + ends of L/C/etc).\n*\n* If `sampleSize` parameter is provided, it will return a polygon\n* equivalent to the original `PathArray`.\n* @param path `PolygonPathArray` or `CurvePathArray`\n* @returns Array of [x, y] points\n*/\nfunction samplePolygon(path) {\n\tconst points = [];\n\tlet [mx, my] = [0, 0];\n\titerate(path, (seg) => {\n\t\tconst cmd = seg[0];\n\t\tif (cmd === \"M\") {\n\t\t\t[mx, my] = [seg[1], seg[2]];\n\t\t\tpoints.push([mx, my]);\n\t\t} else if (cmd === \"L\") points.push([seg[1], seg[2]]);\n\t\telse if (cmd === \"C\") points.push([seg[5], seg[6]]);\n\t\telse if (cmd === \"A\") points.push([seg[6], seg[7]]);\n\t\telse if (cmd === \"Z\") points.push([mx, my]);\n\t\telse throw new TypeError(`${error}: path command \"${cmd}\" is not supported`);\n\t});\n\treturn points;\n}\n//#endregion\n//#region src/morph/getRotatedPath.ts\n/**\n* Returns all possible rotations of a path (line or curve) by shifting the start point.\n* Each rotation is a new PathArray starting at a different original segment.\n*\n* @param path PathArray (M + L/C + optional Z) — must be single subpath, normalized\n* @returns PathArray[] — array of all possible rotations\n*/\nfunction getRotations(a) {\n\tconst pathLen = a.length;\n\tconst pointCount = pathLen - 1;\n\tlet path;\n\tconst result = [];\n\tfor (let idx = 0; idx < pathLen; idx++) {\n\t\tpath = [];\n\t\tfor (let i = 0; i < pathLen; i++) {\n\t\t\tlet oldSegIdx = idx + i;\n\t\t\tlet seg;\n\t\t\tif (i === 0 || a[oldSegIdx] && a[oldSegIdx][0] === \"M\") {\n\t\t\t\tseg = a[oldSegIdx];\n\t\t\t\tpath.push([\"M\", ...seg.slice(-2)]);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (oldSegIdx >= pathLen) oldSegIdx -= pointCount;\n\t\t\tpath.push(a[oldSegIdx]);\n\t\t}\n\t\tresult.push(path);\n\t}\n\treturn result;\n}\n/**\n* Finds the best rotation of pathA to match pathB by minimizing sum of squared distances\n* between corresponding endpoints.\n*\n* Works with both polygon (L) and curve (C) arrays.\n*\n* @param pathA PathArray to rotate (will be modified in rotation options)\n* @param pathB PathArray reference (fixed)\n* @returns PathArray — best rotation of pathA\n*/\nfunction getRotatedPath(pathA, pathB, computedRotations) {\n\tconst rotations = computedRotations || getRotations(pathA);\n\tif (pathA.length !== pathB.length) throw new TypeError(error + \": paths must have the same number of segments after equalization\");\n\tlet bestIndex = 0;\n\tlet minDistanceSq = Infinity;\n\tfor (let ri = 0; ri < rotations.length; ri++) {\n\t\tconst rotation = rotations[ri];\n\t\tconst rLen = rotation.length;\n\t\tlet sumDistSq = 0;\n\t\tfor (let i = 0; i < rLen; i++) {\n\t\t\tconst segA = rotation[i];\n\t\t\tconst segB = pathB[i];\n\t\t\tconst endA = segA.slice(-2);\n\t\t\tconst endB = segB.slice(-2);\n\t\t\tconst dx = endA[0] - endB[0];\n\t\t\tconst dy = endA[1] - endB[1];\n\t\t\tsumDistSq += dx * dx + dy * dy;\n\t\t}\n\t\tif (sumDistSq < minDistanceSq) {\n\t\t\tminDistanceSq = sumDistSq;\n\t\t\tbestIndex = ri;\n\t\t}\n\t}\n\treturn rotations[bestIndex];\n}\n//#endregion\n//#region src/morph/equalizeSegments.ts\nconst equalizeSegmentsDefaults = {\n\tmode: \"auto\",\n\tsampleSize: 10,\n\troundValues: 4,\n\treverse: true,\n\tclose: false,\n\ttarget: void 0\n};\n/**\n* Equalizes two paths for morphing (single subpath only).\n*\n* @see https://minus-ze.ro/posts/morphing-arbitrary-paths-in-svg/\n* @param path1 - First path string or PathArray\n* @param path2 - Second path string or PathArray\n* @param initialCfg - Equalization options\n* @returns Tuple of two equalized MorphPathArrays\n*\n* @example\n* ```ts\n* const [eq1, eq2] = equalizeSegments('M0 0L100 0L50 100Z', 'M0 0L100 0L100 100L0 100Z')\n* // eq1.length === eq2.length\n* ```\n*/\nconst equalizeSegments = (path1, path2, initialCfg = {}) => {\n\tconst { close, mode, reverse, roundValues, target: initialTarget } = Object.assign(equalizeSegmentsDefaults, initialCfg);\n\tlet p1 = normalizePath(path1);\n\tlet p2 = normalizePath(path2);\n\tfixPath(p1);\n\tfixPath(p2);\n\tlet bothPoly = (isPolygonArray(p1) || isPolylineArray(p1)) && (isPolygonArray(p2) || isPolylineArray(p2));\n\tif (bothPoly && mode === \"auto\") {\n\t\tp1 = pathToPolyline(p1);\n\t\tp2 = pathToPolyline(p2);\n\t} else {\n\t\tbothPoly = false;\n\t\tp1 = pathToCurve(p1);\n\t\tp2 = pathToCurve(p2);\n\t}\n\tconst area1 = polygonArea(samplePolygon(p1));\n\tconst area2 = polygonArea(samplePolygon(p2));\n\tif (reverse !== false && Math.sign(area1) !== Math.sign(area2)) p2 = reversePath(p2);\n\tconst segCount1 = p1.length;\n\tconst segCount2 = p2.length;\n\tconst minTarget = Math.max(segCount1, segCount2);\n\tlet target = minTarget;\n\tif (typeof initialTarget !== \"number\") {\n\t\tconst avgLen = (getTotalLength(p1) + getTotalLength(p2)) / 2;\n\t\tconst avgSegLen = avgLen / Math.max(segCount1, segCount2);\n\t\tconst idealSegCount = Math.max(minTarget, Math.round(avgLen / Math.max(avgSegLen, 1)));\n\t\ttarget = Math.min(idealSegCount, Math.max(segCount1, segCount2) * 3);\n\t} else if (initialTarget >= minTarget) target = initialTarget;\n\telse console.warn(\"equalizeSegments \\\"target\\\" option: \" + initialTarget + \", expected >= \" + minTarget);\n\tlet equalP1 = p1;\n\tlet equalP2 = p2;\n\tif (bothPoly) {\n\t\tequalP1 = splitLinePathToCount(p1, target);\n\t\tequalP2 = splitLinePathToCount(p2, target);\n\t} else {\n\t\tequalP1 = splitCurvePathToCount(p1, target);\n\t\tequalP2 = splitCurvePathToCount(p2, target);\n\t}\n\tequalP2 = getRotatedPath(equalP2, equalP1);\n\tif (typeof roundValues === \"number\" && roundValues !== 4) {\n\t\tequalP1 = roundPath(equalP1, roundValues);\n\t\tequalP2 = roundPath(equalP2, roundValues);\n\t}\n\tif (close) {\n\t\tequalP1.push([\"Z\"]);\n\t\tequalP2.push([\"Z\"]);\n\t}\n\treturn [equalP1, equalP2];\n};\n//#endregion\n//#region src/intersect/isPointInsideBBox.ts\n/**\n* Checks if a point is inside a bounding box.\n*\n* @param bbox - The bounding box as [minX, minY, maxX, maxY]\n* @param point - The point as [x, y]\n* @returns True if the point is inside or on the edge of the bounding box\n*/\nconst isPointInsideBBox = (bbox, [x, y]) => {\n\tconst [minX, minY, maxX, maxY] = bbox;\n\treturn x >= minX && x <= maxX && y >= minY && y <= maxY;\n};\n//#endregion\n//#region src/intersect/boundingBoxIntersect.ts\n/**\n* Checks if two bounding boxes intersect.\n*\n* @param a - First bounding box as [minX, minY, maxX, maxY]\n* @param b - Second bounding box as [minX, minY, maxX, maxY]\n* @returns True if the bounding boxes overlap\n*/\nconst boundingBoxIntersect = (a, b) => {\n\tconst [ax1, ay1, ax2, ay2] = a;\n\tconst [bx1, by1, bx2, by2] = b;\n\treturn isPointInsideBBox(b, [ax1, ay1]) || isPointInsideBBox(b, [ax2, ay1]) || isPointInsideBBox(b, [ax1, ay2]) || isPointInsideBBox(b, [ax2, ay2]) || isPointInsideBBox(a, [bx1, by1]) || isPointInsideBBox(a, [bx2, by1]) || isPointInsideBBox(a, [bx1, by2]) || isPointInsideBBox(a, [bx2, by2]) || (ax1 < bx2 && ax1 > bx1 || bx1 < ax2 && bx1 > ax1) && (ay1 < by2 && ay1 > by1 || by1 < ay2 && by1 > ay1);\n};\n//#endregion\n//#region src/morph/createPlaceholder.ts\n/**\n* Create a degenerate `PathArray` at a given coordinate\n* to serve as a pair for another `PathArray`.\n* @param param0 An [x, y] tuple for the coordinate\n* @returns A new degenerate `PathArray`\n*/\nconst createPlaceholder = ([atx, aty]) => {\n\tconst r = .001;\n\treturn [\n\t\t[\n\t\t\t\"M\",\n\t\t\tatx,\n\t\t\taty\n\t\t],\n\t\t[\n\t\t\t\"L\",\n\t\t\tatx + r,\n\t\t\taty\n\t\t],\n\t\t[\n\t\t\t\"L\",\n\t\t\tatx + r,\n\t\t\taty + r\n\t\t],\n\t\t[\n\t\t\t\"L\",\n\t\t\tatx,\n\t\t\taty + r\n\t\t],\n\t\t[\n\t\t\t\"L\",\n\t\t\tatx,\n\t\t\taty\n\t\t],\n\t\t[\"Z\"]\n\t];\n};\n//#endregion\n//#region src/morph/matchPaths.ts\nfunction getBestMatch(target, candidates) {\n\tconst targetBBox = target.bbox;\n\tconst potentialCandidates = [];\n\tfor (let i = 0; i < candidates.length; i++) {\n\t\tconst { bbox, size } = candidates[i];\n\t\tconst dx = targetBBox.cx - bbox.cx;\n\t\tconst dy = targetBBox.cy - bbox.cy;\n\t\tconst centeredDistance = Math.sqrt(dx * dx + dy * dy);\n\t\tconst sizeDifference = Math.abs(target.size - size) / Math.max(target.size, size, 1e-6);\n\t\tconst hasOverlap = isPointInsideBBox([\n\t\t\ttargetBBox.x,\n\t\t\ttargetBBox.y,\n\t\t\ttargetBBox.x2,\n\t\t\ttargetBBox.y2\n\t\t], [bbox.cx, bbox.cy]) || isPointInsideBBox([\n\t\t\tbbox.x,\n\t\t\tbbox.y,\n\t\t\tbbox.x2,\n\t\t\tbbox.y2\n\t\t], [targetBBox.cx, targetBBox.cy]);\n\t\tconst boxIntersect = boundingBoxIntersect([\n\t\t\ttargetBBox.x,\n\t\t\ttargetBBox.y,\n\t\t\ttargetBBox.x2,\n\t\t\ttargetBBox.y2\n\t\t], [\n\t\t\tbbox.x,\n\t\t\tbbox.y,\n\t\t\tbbox.x2,\n\t\t\tbbox.y2\n\t\t]);\n\t\tpotentialCandidates.push({\n\t\t\tindex: i,\n\t\t\thasOverlap,\n\t\t\tboxIntersect,\n\t\t\tsizeDifference,\n\t\t\tcenteredDistance\n\t\t});\n\t}\n\tconst overlaping = potentialCandidates.filter((c) => c.hasOverlap && c.boxIntersect);\n\tif (overlaping.length > 0) {\n\t\tlet best = overlaping[0];\n\t\tfor (let i = 1; i < overlaping.length; i++) if (overlaping[i].centeredDistance < best.centeredDistance) best = overlaping[i];\n\t\treturn candidates.splice(best.index, 1)[0];\n\t}\n\treturn null;\n}\n/**\n* Matches paths from two sets by proximity and size similarity.\n* Unmatched paths receive placeholder paths at their centroid.\n*\n* @param fromPaths - Source path features to match from\n* @param toPaths - Target path features to match to\n* @returns Array of paired NormalArrays [from, to]\n*/\nfunction matchPaths(fromPaths, toPaths) {\n\tconst pairs = [];\n\tfromPaths.sort((a, b) => b.size - a.size);\n\ttoPaths.sort((a, b) => b.size - a.size);\n\twhile (fromPaths.length > 0) {\n\t\tconst from = fromPaths.shift();\n\t\tconst bestTo = getBestMatch(from, toPaths);\n\t\tif (bestTo) pairs.push([from.path, bestTo.path]);\n\t\telse {\n\t\t\tconst fromCentroid = [from.bbox.cx, from.bbox.cy];\n\t\t\tpairs.push([from.path, createPlaceholder(fromCentroid)]);\n\t\t}\n\t}\n\twhile (toPaths.length > 0) {\n\t\tconst to = toPaths.shift();\n\t\tconst toCentroid = [to.bbox.cx, to.bbox.cy];\n\t\tpairs.push([createPlaceholder(toCentroid), to.path]);\n\t}\n\treturn pairs;\n}\n//#endregion\n//#region src/morph/classifyPaths.ts\n/**\n* Classifies paths into outer (containing) and inner (hole) paths.\n*\n* @param paths - Array of normalized path arrays to classify\n* @returns Object with `outers` (containing shapes) and `inners` (holes)\n*/\nconst classifyPaths = (paths) => {\n\tconst outers = [];\n\tconst inners = [];\n\tfor (const path of paths) {\n\t\tconst signedArea = polygonArea(samplePolygon(path));\n\t\tconst bbox = getPathBBox(path);\n\t\tconst feature = {\n\t\t\tisPoly: isPolygonArray(path) || isPolylineArray(path),\n\t\t\tsize: bbox.width * bbox.height,\n\t\t\tpath,\n\t\t\tsignedArea,\n\t\t\tarea: Math.abs(signedArea),\n\t\t\tbbox\n\t\t};\n\t\tif (signedArea > 0) outers.push(feature);\n\t\telse inners.push(feature);\n\t}\n\treturn {\n\t\touters,\n\t\tinners\n\t};\n};\n//#endregion\n//#region src/morph/equalizePaths.ts\nconst equalizePathsDefaults = {\n\tmode: \"auto\",\n\troundValues: 4,\n\tclose: false,\n\tsampleSize: 10\n};\n/**\n* Equalizes two paths for morphing (single/multi subpath).\n*\n* @see https://minus-ze.ro/posts/morphing-arbitrary-paths-in-svg/\n* @param pathInput1 - First path string or PathArray\n* @param pathInput2 - Second path string or PathArray\n* @param initialCfg - Configuration options for equalization\n* @returns Tuple of two equalized MorphPathArrays\n*\n* @example\n* ```ts\n* const [eq1, eq2] = equalizePaths('M0 0L100 0L50 100Z', 'M0 0L100 0L100 100L0 100Z')\n* // eq1.length === eq2.length — ready for morphing\n* ```\n*/\nconst equalizePaths = (pathInput1, pathInput2, initialCfg = {}) => {\n\tconst cfg = Object.assign(equalizePathsDefaults, initialCfg);\n\tconst p1 = normalizePath(pathInput1);\n\tconst p2 = normalizePath(pathInput2);\n\tconst multi1 = isMultiPath(p1);\n\tconst multi2 = isMultiPath(p2);\n\tif (!multi1 && !multi2) return equalizeSegments(p1, p2, cfg);\n\tconst globalArea1 = polygonArea(samplePolygon(p1));\n\tconst globalArea2 = polygonArea(samplePolygon(p2));\n\tlet path1 = p1;\n\tlet path2 = p2;\n\tif (Math.sign(globalArea1) < 0) path1 = reversePath(path1);\n\tif (Math.sign(globalArea2) < 0) path2 = reversePath(path2);\n\tconst multiPath1 = splitPath(path1);\n\tconst multiPath2 = splitPath(path2);\n\tconst { outers: outers1, inners: inners1 } = classifyPaths(multiPath1);\n\tconst { outers: outers2, inners: inners2 } = classifyPaths(multiPath2);\n\tconst outerPairs = matchPaths(outers1, outers2);\n\tconst innerPairs = matchPaths(inners1, inners2);\n\tconst equalizedPairs = [];\n\tfor (const [from, to] of [...outerPairs, ...innerPairs]) {\n\t\tconst [eqFrom, eqTo] = equalizeSegments(from, to, {\n\t\t\t...cfg,\n\t\t\treverse: false\n\t\t});\n\t\tequalizedPairs.push([eqFrom, eqTo]);\n\t}\n\treturn [equalizedPairs.map((p) => p[0]).flat(), equalizedPairs.map((p) => p[1]).flat()];\n};\n//#endregion\n//#region src/intersect/interHelper.ts\nconst intersect = (x1, y1, x2, y2, x3, y3, x4, y4) => {\n\tif (Math.max(x1, x2) < Math.min(x3, x4) || Math.min(x1, x2) > Math.max(x3, x4) || Math.max(y1, y2) < Math.min(y3, y4) || Math.min(y1, y2) > Math.max(y3, y4)) return;\n\tconst nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4), ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4), denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);\n\tif (!denominator) return;\n\tconst px = nx / denominator, py = ny / denominator, px2 = roundTo(px, 2), py2 = roundTo(py, 2);\n\tif (px2 < roundTo(Math.min(x1, x2), 2) || px2 > roundTo(Math.max(x1, x2), 2) || px2 < roundTo(Math.min(x3, x4), 2) || px2 > roundTo(Math.max(x3, x4), 2) || py2 < roundTo(Math.min(y1, y2), 2) || py2 > roundTo(Math.max(y1, y2), 2) || py2 < roundTo(Math.min(y3, y4), 2) || py2 > roundTo(Math.max(y3, y4), 2)) return;\n\treturn {\n\t\tx: px,\n\t\ty: py\n\t};\n};\nconst interHelper = (bez1, bez2, config) => {\n\tconst bbox1 = getCubicBBox(...bez1);\n\tconst bbox2 = getCubicBBox(...bez2);\n\tconst { justCount, epsilon } = Object.assign({\n\t\tjustCount: true,\n\t\tepsilon: DISTANCE_EPSILON\n\t}, config);\n\tif (!boundingBoxIntersect(bbox1, bbox2)) return justCount ? 0 : [];\n\tconst l1 = getCubicLength(...bez1), l2 = getCubicLength(...bez2), n1 = Math.max(l1 / 5 >> 0, 1), n2 = Math.max(l2 / 5 >> 0, 1), points1 = [], points2 = [], xy = {};\n\tlet res = justCount ? 0 : [];\n\tfor (let i = 0; i < n1 + 1; i++) {\n\t\tconst p = getPointAtCubicLength(...bez1, i / n1 * l1);\n\t\tpoints1.push({\n\t\t\tx: p.x,\n\t\t\ty: p.y,\n\t\t\tt: i / n1\n\t\t});\n\t}\n\tfor (let i = 0; i < n2 + 1; i++) {\n\t\tconst p = getPointAtCubicLength(...bez2, i / n2 * l2);\n\t\tpoints2.push({\n\t\t\tx: p.x,\n\t\t\ty: p.y,\n\t\t\tt: i / n2\n\t\t});\n\t}\n\tfor (let i = 0; i < n1; i++) for (let j = 0; j < n2; j++) {\n\t\tconst maxLimit = 1 + epsilon, di = points1[i], di1 = points1[i + 1], dj = points2[j], dj1 = points2[j + 1], ci = Math.abs(di1.x - di.x) < .001 ? \"y\" : \"x\", cj = Math.abs(dj1.x - dj.x) < .001 ? \"y\" : \"x\", is = intersect(di.x, di.y, di1.x, di1.y, dj.x, dj.y, dj1.x, dj1.y);\n\t\tif (is) {\n\t\t\tif (xy[is.x.toFixed(4)] == is.y.toFixed(4)) continue;\n\t\t\txy[is.x.toFixed(4)] = is.y.toFixed(4);\n\t\t\tconst t1 = di.t + Math.abs((is[ci] - di[ci]) / (di1[ci] - di[ci])) * (di1.t - di.t), t2 = dj.t + Math.abs((is[cj] - dj[cj]) / (dj1[cj] - dj[cj])) * (dj1.t - dj.t);\n\t\t\tif (t1 >= 0 && t1 <= maxLimit && t2 >= 0 && t2 <= maxLimit) if (justCount) res++;\n\t\t\telse res.push({\n\t\t\t\tx: is.x,\n\t\t\t\ty: is.y,\n\t\t\t\tt1: Math.min(t1, 1),\n\t\t\t\tt2: Math.min(t2, 1)\n\t\t\t});\n\t\t}\n\t}\n\treturn res;\n};\n//#endregion\n//#region src/intersect/pathIntersection.ts\n/**\n* Finds intersection points between two paths.\n*\n* @param pathInput1 - First path string or PathArray\n* @param pathInput2 - Second path string or PathArray\n* @param justCount - If true, returns the count of intersections; if false, returns the intersection points\n* @returns The number of intersections (when justCount is true) or an array of IntersectionPoint objects\n*\n* @example\n* ```ts\n* pathsIntersection('M0 50C0 0,100 0,100 50', 'M50 0C100 0,100 100,50 100', true)\n* // => 1\n* pathsIntersection('M0 50C0 0,100 0,100 50', 'M50 0C100 0,100 100,50 100', false)\n* // => [{ x: 50, y: 25, t1: 0.5, t2: 0.5 }]\n* ```\n*/\nconst pathsIntersection = (pathInput1, pathInput2, justCount = true) => {\n\tconst path1 = pathToCurve(pathInput1);\n\tconst path2 = pathToCurve(pathInput2);\n\tlet x1 = 0, y1 = 0, x2 = 0, y2 = 0, x1m = 0, y1m = 0, x2m = 0, y2m = 0, bez1 = [\n\t\tx1,\n\t\ty1,\n\t\tx1,\n\t\ty1,\n\t\tx1m,\n\t\ty1m,\n\t\tx1m,\n\t\ty1m\n\t], bez2 = [\n\t\tx2,\n\t\ty2,\n\t\tx2,\n\t\ty2,\n\t\tx2m,\n\t\ty2m,\n\t\tx2m,\n\t\ty2m\n\t], countResult = 0;\n\tconst pointsResult = [];\n\tconst pathLen1 = path1.length;\n\tconst pathLen2 = path2.length;\n\tfor (let i = 0; i < pathLen1; i++) {\n\t\tconst seg1 = path1[i];\n\t\tif (seg1[0] == \"M\") {\n\t\t\tx1 = seg1[1];\n\t\t\ty1 = seg1[2];\n\t\t\tx1m = x1;\n\t\t\ty1m = y1;\n\t\t} else {\n\t\t\tif (seg1[0] == \"C\") {\n\t\t\t\tbez1 = [\n\t\t\t\t\tx1,\n\t\t\t\t\ty1,\n\t\t\t\t\tseg1[1],\n\t\t\t\t\tseg1[2],\n\t\t\t\t\tseg1[3],\n\t\t\t\t\tseg1[4],\n\t\t\t\t\tseg1[5],\n\t\t\t\t\tseg1[6]\n\t\t\t\t];\n\t\t\t\tx1 = bez1[6];\n\t\t\t\ty1 = bez1[7];\n\t\t\t} else {\n\t\t\t\tbez1 = [\n\t\t\t\t\tx1,\n\t\t\t\t\ty1,\n\t\t\t\t\tx1,\n\t\t\t\t\ty1,\n\t\t\t\t\tx1m,\n\t\t\t\t\ty1m,\n\t\t\t\t\tx1m,\n\t\t\t\t\ty1m\n\t\t\t\t];\n\t\t\t\tx1 = x1m;\n\t\t\t\ty1 = y1m;\n\t\t\t}\n\t\t\tfor (let j = 0; j < pathLen2; j++) {\n\t\t\t\tconst seg2 = path2[j];\n\t\t\t\tif (seg2[0] == \"M\") {\n\t\t\t\t\tx2 = seg2[1];\n\t\t\t\t\ty2 = seg2[2];\n\t\t\t\t\tx2m = x2;\n\t\t\t\t\ty2m = y2;\n\t\t\t\t} else if (seg2[0] == \"C\") {\n\t\t\t\t\tbez2 = [\n\t\t\t\t\t\tx2,\n\t\t\t\t\t\ty2,\n\t\t\t\t\t\tseg2[1],\n\t\t\t\t\t\tseg2[2],\n\t\t\t\t\t\tseg2[3],\n\t\t\t\t\t\tseg2[4],\n\t\t\t\t\t\tseg2[5],\n\t\t\t\t\t\tseg2[6]\n\t\t\t\t\t];\n\t\t\t\t\tx2 = bez2[6];\n\t\t\t\t\ty2 = bez2[7];\n\t\t\t\t}\n\t\t\t\tconst intr = interHelper(bez1, bez2, { justCount });\n\t\t\t\tif (justCount) countResult += intr;\n\t\t\t\telse pointsResult.push(...intr);\n\t\t\t}\n\t\t}\n\t}\n\treturn justCount ? countResult : pointsResult;\n};\n//#endregion\nexport { PathParser, absolutizeSegment, arcToCubic, arcTools, bezierTools, boundingBoxIntersect, cubicTools, DISTANCE_EPSILON as distanceEpsilon, distanceSquareRoot, equalizePaths, equalizeSegments, finalizeSegment, fixPath, getClosestPoint, getDrawDirection, getPathArea, getPathBBox, getPointAtLength, getPropertiesAtLength, getPropertiesAtPoint, getSVGMatrix, getSegmentAtLength, getSegmentOfPoint, getTotalLength, invalidPathValue, isAbsoluteArray, isArcCommand, isClosedPath, isCurveArray, isDigit, isDigitStart, isMoveCommand, isMultiPath, isNormalizedArray, isPathArray, isPathCommand, isPointInStroke, isPointInsideBBox, isPolygonArray, isPolylineArray, isRelativeArray, isSpace, isValidPath, iterate, lineToCubic, lineTools, midPoint, normalizePath, normalizeSegment, optimizePath, paramsCounts, paramsParser, parsePathString, pathToAbsolute, pathToCurve, pathToRelative, pathToString, pathsIntersection, polygonTools, projection2d, quadToCubic, quadTools, relativizeSegment, reverseCurve, reversePath, rotateVector, roundPath, roundSegment, roundTo, scanFlag, scanParam, scanSegment, segmentToCubic, shapeParams, shapeToPath, shapeToPathArray, shortenSegment, skipSpaces, splitCubicSegment, splitPath, transformPath };\n\n//# sourceMappingURL=util.js.map","// src/extend/path.ts\nimport {\n equalizePaths,\n equalizeSegments,\n pathToString,\n} from \"svg-path-commander/util\";\nimport { isArray, isNumber } from \"../Util.ts\";\n\nimport type {\n InterpolatorFunction,\n MorphPathArray,\n MorphPathSegment,\n PathLike,\n ValidationResultEntry,\n} from \"../types.ts\";\n\nexport { equalizePaths, equalizeSegments, pathToString };\n\n/**\n * Interpolate `PathArray` values.\n *\n * **NOTE**: these values must be validated first!\n * @param target - The target PathArray value\n * @param start - A starting PathArray value\n * @param end - An ending PathArray value\n * @param t - The progress value\n * @returns The interpolated PathArray value\n */\nexport const interpolatePath: InterpolatorFunction<MorphPathSegment[]> = <\n T extends MorphPathSegment[],\n>(\n target: T,\n start: T,\n end: T,\n t: number,\n): T => {\n const segCount = end.length;\n let i = 0;\n\n while (i < segCount) {\n const targetSeg = target[i];\n const startSeg = start[i];\n const endSeg = end[i];\n\n if (targetSeg[0] === \"Z\") {\n // force update when Z is used\n // Z has no params\n targetSeg[0] === \"Z\";\n } else if (targetSeg[0] === \"C\") {\n targetSeg[1] = startSeg[1]! + (endSeg[1]! - startSeg[1]!) * t;\n targetSeg[2] = startSeg[2]! + (endSeg[2]! - startSeg[2]!) * t;\n targetSeg[3] = startSeg[3]! + (endSeg[3]! - startSeg[3]!) * t;\n targetSeg[4] = startSeg[4]! + (endSeg[4]! - startSeg[4]!) * t;\n targetSeg[5] = startSeg[5]! + (endSeg[5]! - startSeg[5]!) * t;\n targetSeg[6] = startSeg[6]! + (endSeg[6]! - startSeg[6]!) * t;\n } else {\n // M / L\n targetSeg[1] = startSeg[1]! + (endSeg[1]! - startSeg[1]!) * t;\n targetSeg[2] = startSeg[2]! + (endSeg[2]! - startSeg[2]!) * t;\n }\n i++;\n }\n\n return target as T;\n};\n\nconst supportedPathCommands = [\"M\", \"L\", \"C\", \"Z\"] as const;\n\n/**\n * Check if an array of arrays is potentially a PathArray\n * @param target The incoming value `constructor()` `from()` / `to()`\n * @returns `true` when array is potentially a PathArray\n */\nexport const isPathLike = (value: unknown): value is PathLike =>\n isArray(value) &&\n value.some(\n (seg) => isArray(seg) && supportedPathCommands.includes(seg[0] as never),\n );\n\n/**\n * Check if an array of arrays is a valid PathArray for interpolation\n * @param target The incoming value `from()` / `to()`\n * @returns `true` when array is valid\n */\nexport const isValidPath = (value: unknown): value is MorphPathArray =>\n isPathLike(value) &&\n value.length > 1 &&\n value.every(isArray) &&\n value.every(\n ([cmd, ...values]) =>\n supportedPathCommands.includes(cmd as MorphPathSegment[0]) &&\n (([\"M\", \"L\"].includes(cmd as MorphPathSegment[0]) &&\n (values as number[]).length === 2 &&\n values.every(isNumber)) ||\n (\"C\" === cmd &&\n (values as number[]).length === 6 &&\n values.every(isNumber)) ||\n (\"Z\" === cmd && (values as number[]).length === 0)),\n );\n\n/**\n * Validate a `PathArray` and check if it's compatible with a reference.\n *\n * **NOTE**: Path interpolation only works when both paths have:\n * - Identical segments structure (same number and order of M/L/C/Z path commands)\n * - Corresponding coordinates to interpolate\n * Complex morphs require preprocessing (e.g. KUTE.js, Flubber)\n *\n * @example\n * // simple shapes\n * const linePath1 = [[\"M\", 0, 0],[\"L\", 50, 50]]\n * const linePath2 = [[\"M\",50,50],[\"L\",150,150]]\n * const curvePath1 = [[\"M\", 0, 0],[\"C\",15,15, 35, 35, 50, 50]]\n * const curvePath2 = [[\"M\",50,50],[\"C\",50,50,100,100,150,150]]\n *\n * // closed shapes\n * const closedLinePath1 = [[\"M\", 0, 0],[\"L\", 50, 50],[\"Z\"]]\n * const closedLinePath2 = [[\"M\",50,50],[\"L\",150,150],[\"Z\"]]\n * const closedCurvePath1 = [[\"M\", 0, 0],[\"C\",15,15, 35, 35, 50, 50],[\"Z\"]]\n * const closedCurvePath2 = [[\"M\",50,50],[\"C\",50,50,100,100,150,150],[\"Z\"]]\n *\n * // composit shapes (multi-path)\n * const compositPath1 = [\n * [\"M\", 0, 0],[\"L\",50,50],\n * [\"M\",50,50],[\"C\",50,50,100,100,150,150],\n * ]\n * const compositPath2 = [\n * [\"M\",50,50],[\"L\",150,150],\n * [\"M\", 0, 0],[\"C\", 15, 15,35,35,50,50],\n * ]\n *\n * @param target The incoming value `from()` / `to()`\n * @param ref The state reference value\n * @returns a tuple with validation result as a `boolean` and,\n * if not valid, a reason why value isn't\n */\nexport const validatePath = <T extends MorphPathArray>(\n propName: string,\n target: unknown,\n ref?: T,\n): ValidationResultEntry => {\n // ref is state[prop] and is already validated on initialization\n if (!isValidPath(target)) {\n return [false, `Property \"${propName}\" is not a valid PathArray.`];\n }\n\n if (ref) {\n if (ref.length !== target.length) {\n return [\n false,\n `Property \"${propName}\" is expecting an array of ${ref.length} path segments, got ${target.length}.`,\n ];\n }\n\n let i = 0;\n const len = ref.length;\n while (i < len) {\n const refSeg = ref[i];\n const targetSeg = target[i];\n const refCmd = refSeg[0];\n const targetCmd = targetSeg[0];\n const refLen = refSeg.length;\n const targetLen = targetSeg.length;\n\n if (refCmd !== targetCmd || refLen !== targetLen) {\n return [\n false,\n `Property \"${propName}\" mismatch at index ${i}. ` +\n `Segments don't match:\\n` +\n `> segment: \"[${targetCmd}, ${targetSeg.slice(1)}]\"\\n` +\n `> reference: \"[${refCmd}, ${refSeg.slice(1)}]\"`,\n ];\n }\n i++;\n }\n }\n\n return [true];\n};\n\n/**\n * Config for .use(propName, pathArrayConfig)\n */\nexport const pathArrayConfig = {\n interpolate: interpolatePath,\n validate: validatePath,\n};\n","// src/extend/object.ts\nimport type {\n BaseTweenProps,\n InterpolatorFunction,\n ValidationResultEntry,\n} from \"../types.ts\";\nimport { isNumber, isPlainObject } from \"../Util.ts\";\n\n/**\n * Single-level `Record<string, number>` object interpolate function.\n *\n * **NOTE**: values must be validated first!\n *\n * Input: single-level nested object\n *\n * Output: interpolated flat object with same structure\n *\n * @example\n * const initialValues = { translate : { x: 0, y: 0 } };\n * // we will need to validate the value of `translate`\n *\n * @param target The target value of the state object\n * @param start The start value of the object\n * @param end The end value of the object\n * @param t The progress value\n * @returns The interpolated flat object with same structure.\n */\nexport const interpolateObject: InterpolatorFunction<BaseTweenProps> = <\n T extends BaseTweenProps,\n>(\n target: T,\n start: T,\n end: T,\n t: number,\n): T => {\n // Iterate over end keys (we only interpolate what's in end)\n const keys = Object.keys(end) as (keyof T)[];\n let i = 0;\n\n while (i < keys.length) {\n const key = keys[i++];\n const endVal = end[key];\n const startVal = start[key];\n\n target[key] = (startVal + (endVal - startVal) * t) as T[keyof T];\n }\n\n return target;\n};\n\n/**\n * Validate a plain `Record<string, number>` object and compare its compatibility\n * with a reference object.\n * @param propName The property name to which this object belongs to\n * @param target The target object itself\n * @param ref A reference object to compare our target to\n * @returns A [boolean, string?] tuple which represents [validity, \"reason why not valid\"]\n */\nexport const validateObject = (\n propName: string,\n target: unknown,\n ref?: BaseTweenProps,\n): ValidationResultEntry => {\n if (!isPlainObject(target)) {\n return [false, `Property \"${propName}\" must be a plain object.`];\n }\n\n const keys = Object.keys(target);\n let i = 0;\n const iLen = keys.length;\n\n while (i < iLen) {\n const key = keys[i++];\n const value = target[key];\n\n if (value === null || value === undefined) {\n return [\n false,\n `Property \"${key}\" from \"${propName}\" is null/undefined.`,\n ];\n }\n\n // We never want to go down that route\n // if (isPlainObject(value)) {}\n\n if (!isNumber(value)) {\n return [\n false,\n `Property \"${key}\" from \"${propName}\" must be a number.` +\n `${\n isPlainObject(value)\n ? \" Deeper nested objects are not supported.\"\n : ` Unsupported value: \"${typeof value}\".`\n }`,\n ];\n }\n\n if (ref) {\n if (ref[key] === undefined) {\n return [\n false,\n `Property \"${key}\" in \"${propName}\" doesn't exist in the reference object.`,\n ];\n }\n }\n }\n\n return [true];\n};\n\n/**\n * Config for .use(propName, objectConfig)\n */\nexport const objectConfig = {\n interpolate: interpolateObject,\n validate: validateObject,\n};\n","// src/extend/transform.ts\nimport type {\n InterpolatorFunction,\n TransformArray,\n TransformLike,\n TransformStep,\n TransformStepInternal,\n ValidationResultEntry,\n Vec3,\n} from \"../types.ts\";\nimport { isArray, isNumber } from \"../Util.ts\";\n\n/**\n * Returns a valid CSS transform string either with transform functions (Eg.: `translate(15px) rotate(25deg)`)\n * or `matrix(...)` / `matrix3d(...)`.\n * When the `toMatrix` parameter is `true` it will create a DOMMatrix instance, apply transform\n * steps and return a `matrix(...)` or `matrix3d(...)` string value.\n * @param steps An array of TransformStep\n * @param toMatrix An optional parameter to modify the function output\n * @returns The valid CSS transform string value\n */\nexport const transformToString = (steps: TransformStep[], toMatrix = false) => {\n if (toMatrix) {\n const matrix = new DOMMatrix();\n const len = steps.length;\n let i = 0;\n\n while (i < len) {\n const step = steps[i++];\n\n switch (step[0]) {\n case \"perspective\": {\n const m2 = new DOMMatrix();\n m2.m34 = -1 / step[1];\n matrix.multiplySelf(m2);\n break;\n }\n case \"translate\": {\n matrix.translateSelf(step[1], step[2] || 0, step[3] || 0);\n break;\n }\n case \"rotate\": {\n matrix.rotateSelf(step[1], step[2] || 0, step[3] || 0);\n break;\n }\n case \"rotateAxisAngle\": {\n matrix.rotateAxisAngleSelf(step[1], step[2], step[3], step[4]);\n break;\n }\n case \"scale\": {\n matrix.scaleSelf(step[1], step[2] || 1, step[3] || 1);\n break;\n }\n case \"skewX\": {\n matrix.skewXSelf(step[1]);\n break;\n }\n case \"skewY\": {\n matrix.skewYSelf(step[1]);\n break;\n }\n }\n }\n\n return matrix.toString();\n }\n // Return CSS transform string\n const len = steps.length;\n let i = 0;\n let stringOutput = \"\";\n\n while (i < len) {\n const step = steps[i++];\n\n switch (step[0]) {\n case \"perspective\": {\n stringOutput += ` perspective(${step[1]}px)`;\n break;\n }\n case \"translate\": {\n stringOutput += ` translate3d(${step[1]}px, ${step[2] || 0}px, ${\n step[3] || 0\n }px)`;\n break;\n }\n case \"rotate\": {\n const [rx, ry, rz] = step.slice(1) as Vec3;\n\n if (typeof rx === \"number\" && ry === undefined && rz === undefined) {\n stringOutput += ` rotate(${step[1]}deg)`;\n } else {\n stringOutput += ` rotateX(${step[1]}deg)`;\n // istanbul ignore else @preserve\n if (step[2] !== undefined) stringOutput += ` rotateY(${step[2]}deg)`;\n // istanbul ignore else @preserve\n if (step[3] !== undefined) stringOutput += ` rotateZ(${step[3]}deg)`;\n }\n break;\n }\n case \"rotateAxisAngle\": {\n stringOutput += ` rotate3d(${step[1]}, ${step[2]}, ${step[3]}, ${\n step[4]\n }deg)`;\n break;\n }\n case \"scale\": {\n stringOutput += ` scale(${step[1]}, ${step[2] || step[1]}, ${\n step[3] || 1\n })`;\n break;\n }\n case \"skewX\": {\n stringOutput += ` skewX(${step[1]}deg)`;\n break;\n }\n case \"skewY\": {\n stringOutput += ` skewY(${step[1]}deg)`;\n break;\n }\n }\n }\n\n return stringOutput.slice(1);\n};\n\n/**\n * Convert euler rotation to axis angle.\n * All values are degrees.\n * @param x rotateX value\n * @param y rotateY value\n * @param z rotateZ value\n * @returns The axis angle tuple [vectorX, vectorY, vectorZ, angle]\n */\nexport const eulerToAxisAngle = (\n x: number,\n y: number,\n z: number,\n): [number, number, number, number] => {\n // Convert to quaternion first\n const quat = eulerToQuaternion(x, y, z);\n\n // Then convert quaternion to axis-angle\n return quaternionToAxisAngle(quat);\n};\n\n/**\n * Convert euler rotation tuple to quaternion.\n * All values are degrees.\n * @param x The rotateX value\n * @param y The rotateY value\n * @param z The rotateZ value\n * @returns The rotation quaternion\n */\nconst eulerToQuaternion = (\n x: number,\n y: number,\n z: number,\n): [number, number, number, number] => {\n const cx = Math.cos(x / 2);\n const sx = Math.sin(x / 2);\n const cy = Math.cos(y / 2);\n const sy = Math.sin(y / 2);\n const cz = Math.cos(z / 2);\n const sz = Math.sin(z / 2);\n\n return [\n cx * cy * cz + sx * sy * sz,\n sx * cy * cz - cx * sy * sz,\n cx * sy * cz + sx * cy * sz,\n cx * cy * sz - sx * sy * cz,\n ];\n};\n\n/**\n * Convert euler rotation tuple to axis angle.\n * All values are degrees.\n * @param q The rotation quaternion\n * @returns The axis angle tuple [vectorX, vectorY, vectorZ, angle]\n */\nconst quaternionToAxisAngle = (\n q: [number, number, number, number],\n): [number, number, number, number] => {\n const [w, x, y, z] = q;\n\n // Normalize\n const len = Math.sqrt(x * x + y * y + z * z);\n\n if (len < 0.0001) {\n // No rotation\n return [0, 0, 1, 0];\n }\n\n const angle = 2 * Math.acos(Math.max(-1, Math.min(1, w)));\n\n return [x / len, y / len, z / len, angle];\n};\n\n/**\n * Interpolates arrays of `TransformStep`s → returns interpolated `TransformStep`s.\n *\n * **NOTE** - Like `PathArray`, these values are required to have same length,\n * structure and must be validated beforehand.\n * @example\n * const a1: TransformArray = [\n * [\"translate\", 0, 0], // [translateX, translateY]\n * [\"rotate\", 0], // [rotateZ]\n * [\"rotate\", 0, 0], // [rotateX, rotateY]\n * [\"rotateAxisAngle\", 0, 0, 0, 0], // [originX, originY, originZ, angle]\n * [\"scale\", 1], // [scale]\n * [\"scale\", 1, 1], // [scaleX, scaleY]\n * [\"perspective\", 800], // [length]\n * ];\n * const a2: TransformArray = [\n * [\"translate\", 50, 50],\n * [\"rotate\", 45],\n * [\"rotate\", 45, 45],\n * [\"rotateAxisAngle\", 1, 0, 0, 45],\n * [\"scale\", 1.5],\n * [\"scale\", 1.5, 1.2],\n * [\"perspective\", 400],\n * ];\n *\n * @param target The target `TransformArray` of the state object\n * @param start The start `TransformArray`\n * @param end The end `TransformArray`\n * @param t The progress value\n * @returns The interpolated `TransformArray`\n */\nexport const interpolateTransform: InterpolatorFunction<TransformStep[]> = <\n T extends TransformStepInternal[],\n>(\n target: T,\n start: T,\n end: T,\n t: number,\n): T => {\n const len = end.length;\n let i = 0;\n\n while (i < len) {\n const targetStep = target[i];\n const startStep = start[i];\n const endStep = end[i];\n\n switch (targetStep[0]) {\n case \"translate\":\n case \"rotate\":\n case \"scale\":\n case \"rotateAxisAngle\":\n targetStep[1] = startStep[1] + (endStep[1] - startStep[1]) * t;\n\n typeof endStep[2] === \"number\" &&\n (targetStep[2] = startStep[2]! + (endStep[2]! - startStep[2]!) * t);\n\n typeof endStep[3] === \"number\" &&\n (targetStep[3] = startStep[3]! + (endStep[3]! - startStep[3]!) * t);\n\n typeof endStep[4] === \"number\" &&\n (targetStep[4] = startStep[4]! + (endStep[4]! - startStep[4]!) * t);\n\n break;\n case \"skewX\":\n case \"skewY\":\n case \"perspective\":\n targetStep[1] = startStep[1] + (endStep[1] - startStep[1]) * t;\n\n break;\n }\n i++;\n }\n\n return target as T;\n};\n\nconst supportedTransform = [\n \"perspective\",\n \"translate\",\n \"rotate\",\n \"rotateAxisAngle\",\n \"scale\",\n \"skewX\",\n \"skewY\",\n] as const;\n\n/**\n * Check if a value is potentially a `TransformArray`.\n * @param target The incoming value `constructor()` `from()` / `to()`\n * @returns `true` when array is potentially a PathArray\n */\nexport const isTransformLike = (value: unknown): value is TransformLike =>\n isArray(value) &&\n value.some(\n (step) => isArray(step) && supportedTransform.includes(step[0] as never),\n );\n\n/**\n * Check if a value is a valid `TransformArray` for interpolation.\n * @param target The incoming value `from()` / `to()`\n * @returns a tuple with validation result as a `boolean` and,\n * if not valid, a reason why value isn't\n */\nexport const isValidTransformArray = (\n value: unknown,\n): value is TransformArray =>\n isTransformLike(value) &&\n value.every(\n ([fn, ...values]) =>\n supportedTransform.includes(fn as TransformStep[0]) &&\n (([\"translate\", \"rotate\", \"scale\"].includes(fn as TransformStep[0]) &&\n values.length > 0 &&\n values.length <= 3 &&\n values.every(isNumber)) ||\n (\"rotateAxisAngle\" === fn &&\n (values as number[]).length === 4 &&\n values.every(isNumber)) ||\n ([\"skewX\", \"skewY\", \"perspective\"].includes(fn as string) &&\n (values as number[]).length === 1 &&\n isNumber((values as number[])[0]))),\n );\n\n/**\n * Validator for `TransformArray` that checks\n * structure + parameter counts, and if provided,\n * the compatibility with a reference value.\n */\nexport const validateTransform = (\n propName: string,\n target: unknown,\n ref?: TransformArray,\n): ValidationResultEntry => {\n if (!isValidTransformArray(target)) {\n return [false, `Property \"${propName}\" must be an array of TransformStep.`];\n }\n\n if (ref) {\n if (ref.length !== target.length) {\n return [\n false,\n `Property \"${propName}\" is expecting an array of ${ref.length} transform steps, got ${target.length}.`,\n ];\n }\n\n let i = 0;\n const len = target.length;\n\n while (i < len) {\n const step = target[i] as [string, ...Vec3];\n const refStep = ref[i] as [string, ...Vec3];\n const fn = step[0];\n const fnRef = refStep[0];\n\n // istanbul ignore else @preserve\n if (refStep) {\n if (fnRef !== fn || refStep.length !== step.length) {\n return [\n false,\n `Property \"${propName}\" mismatch at index ${i}\":\\n` +\n `> step: [\"${fn}\", ${step.slice(1)}]\\n` +\n `> reference: [\"${fnRef}\", ${refStep.slice(1)}]`,\n ];\n }\n }\n i++;\n }\n }\n\n return [true];\n};\n\n/**\n * Config for .use(\"transform\", transformConfig)\n */\nexport const transformConfig = {\n interpolate: interpolateTransform,\n validate: validateTransform,\n};\n","let _nowFunc = () => globalThis.performance.now();\n\nexport const now = (): number => {\n return _nowFunc();\n};\n\nexport function setNow(nowFunction: typeof _nowFunc) {\n _nowFunc = nowFunction;\n}\n","// Runtime.ts\nimport type { AnimationItem, TweenProps } from \"./types.d.ts\";\nimport { now } from \"./Now.ts\";\n\n/**\n * The runtime queue\n */\nexport const Queue: AnimationItem[] = new Array(0);\n\nlet rafID = 0;\nlet queueLength = 0;\n\n/**\n * The hot update loop updates all items in the queue,\n * and stops automatically when there are no items left.\n * @param t execution time (performance.now)\n */\nexport function Runtime(t = now()) {\n let i = 0;\n // queueLength = Queue.length;\n while (i < queueLength) {\n if (Queue[i]?.update(t)) {\n i += 1;\n } else {\n Queue.splice(i, 1);\n queueLength--;\n }\n }\n\n if (queueLength === 0) {\n cancelAnimationFrame(rafID);\n rafID = 0;\n } else rafID = requestAnimationFrame(Runtime);\n}\n\n/**\n * Add a new item to the update loop.\n * If it's the first item, it will also start the update loop.\n * @param newItem Tween / Timeline\n */\nexport function addToQueue<T extends TweenProps>(\n newItem: AnimationItem<T>,\n): void {\n // istanbul ignore else @preserve\n if (Queue.includes(newItem as AnimationItem<never>)) return;\n // Queue.push(item);\n Queue[queueLength++] = newItem as AnimationItem<never>;\n // istanbul ignore else @preserve\n if (!rafID) Runtime();\n}\n\n/**\n * Remove item from the update loop.\n * @param newItem Tween / Timeline\n */\nexport function removeFromQueue<T extends TweenProps>(\n removedItem: AnimationItem<T>,\n): void {\n const idx = Queue.indexOf(removedItem as AnimationItem<never>);\n // istanbul ignore else @preserve\n if (idx > -1) {\n Queue.splice(idx, 1);\n queueLength--;\n }\n}\n","// Tween.ts\nimport type {\n DeepPartial,\n EasingFunction,\n InterpolatorFunction,\n PropConfig,\n TweenCallback,\n TweenProps,\n TweenRuntime,\n TweenUpdateCallback,\n ValidationFunction,\n} from \"./types.d.ts\";\nimport {\n deepAssign,\n deproxy,\n isArray,\n isObject,\n validateValues,\n} from \"./Util.ts\";\nimport { addToQueue, removeFromQueue } from \"./Runtime.ts\";\nimport { now } from \"./Now.ts\";\n\n/**\n * Lightweight tween engine for interpolating values over time.\n * Supports numbers and via extensions it enxtends to arrays\n * (e.g. RGB, points), nested objects, and SVG path morphing.\n *\n * @template T - The type of the target object (usually a plain object with numeric properties)\n *\n * @example\n * ```ts\n * const tween = new Tween({ x: 0, opacity: 1 })\n * .to({ x: 300, opacity: 0 })\n * .duration(1.5)\n * .easing(Easing.Elastic.Out)\n * .start();\n * ```\n *\n * @param initialValues The initial values object\n */\nexport class Tween<T extends TweenProps = TweenProps> {\n state: T;\n private _state: T;\n private _startIsSet = false;\n private _repeat = 0;\n private _yoyo = false;\n private _reversed = false;\n private _initialRepeat = 0;\n private _startFired = false;\n private _propsStart: Partial<T> = {};\n private _propsEnd: Partial<T> = {};\n private _isPlaying = false;\n private _duration = 1000;\n private _delay = 0;\n private _pauseStart = 0;\n private _repeatDelay = 0;\n private _startTime: number = 0;\n private _errors = new Map<string | \"init\", string>();\n private _interpolators = new Map<string | keyof T, InterpolatorFunction>();\n private _validators = new Map<string | keyof T, ValidationFunction>();\n private _easing: EasingFunction = (t) => t;\n private _onUpdate?: TweenUpdateCallback<T>;\n private _onComplete?: TweenCallback<T>;\n private _onStart?: TweenCallback<T>;\n private _onStop?: TweenCallback<T>;\n private _onPause?: TweenCallback<T>;\n private _onResume?: TweenCallback<T>;\n private _onRepeat?: TweenCallback<T>;\n private _runtime: (TweenRuntime<T>)[] = [];\n /**\n * Creates a new Tween instance.\n * @param initialValues - The initial state of the animated object\n */\n constructor(initialValues: T) {\n // we must initialize state to allow isValidState to work from here\n this.state = {} as T;\n validateValues.call(this as unknown as Tween, initialValues);\n if (this._errors.size) {\n // we temporarily store initialValues reference here\n this._state = initialValues;\n } else {\n // or set values right away\n this.state = initialValues;\n this._state = deproxy(initialValues);\n }\n\n return this;\n }\n\n // GETTERS FIRST\n /**\n * A boolean that returns `true` when tween is playing.\n */\n get isPlaying(): boolean {\n return this._isPlaying;\n }\n\n /**\n * A boolean that returns `true` when tween is paused.\n */\n get isPaused(): boolean {\n return this._pauseStart > 0;\n }\n\n /**\n * A boolean that returns `true` when initial values are valid.\n */\n get isValidState(): boolean {\n return Object.keys(this.state).length > 0;\n }\n\n /**\n * A boolean that returns `true` when all values are valid.\n */\n get isValid(): boolean {\n return this._errors.size === 0;\n }\n\n /**\n * Returns the configured duration in seconds.\n */\n getDuration() {\n return this._duration / 1000;\n }\n\n /**\n * Returns the total duration in seconds. It's calculated as a sum of\n * the delay, duration multiplied by repeat value, repeat delay multiplied\n * by repeat value.\n */\n get totalDuration() {\n const repeat = this._initialRepeat;\n return (\n this._delay +\n this._duration * (repeat + 1) +\n this._repeatDelay * repeat\n ) / 1000;\n }\n\n /**\n * Returns the validator configured for a given property.\n */\n getValidator(propName: string) {\n return this._validators.get(propName);\n }\n\n /**\n * Returns the errors Map, mainly used by external validators.\n */\n getErrors() {\n return this._errors;\n }\n\n /**\n * Starts the tween (adds it to the global update loop).\n * Triggers `onStart` if set.\n * @param time - Optional explicit start time (defaults to `now()`)\n * @param overrideStart - If true, resets starting values even if already set\n * @returns this\n */\n start(time = now(), overrideStart = false) {\n if (this._isPlaying) return this;\n if (this._pauseStart) return this.resume();\n if (!this.isValid) {\n this._report();\n return this;\n }\n // micro-optimization - don't reset state if never started\n if (this._startTime && !overrideStart) this._resetState();\n\n // istanbul ignore else @preserve\n if (!this._startIsSet || /* istanbul ignore next */ overrideStart) {\n this._startIsSet = true;\n\n this._setProps(\n this.state,\n this._propsStart,\n this._propsEnd,\n overrideStart,\n );\n }\n this._isPlaying = true;\n this._startTime = time;\n this._startTime += this._delay;\n\n addToQueue(this);\n return this;\n }\n\n /**\n * Starts the tween from current values.\n * @param time - Optional explicit start time (defaults to `now()`)\n * @returns this\n */\n startFromLast(time = now()) {\n return this.start(time, true);\n }\n\n /**\n * Immediately stops the tween and removes it from the update loop.\n * Triggers `onStop` if set.\n * @returns this\n */\n stop() {\n if (!this._isPlaying) return this;\n removeFromQueue(this);\n this._isPlaying = false;\n this._repeat = this._initialRepeat;\n this._reversed = false;\n\n this._onStop?.(this.state);\n return this;\n }\n\n /**\n * Reverses playback direction and mirrors current time position.\n * @returns this\n */\n reverse(): this {\n // istanbul ignore next @preserve\n if (!this._isPlaying) return this;\n\n const currentTime = now();\n const elapsed = currentTime - this._startTime;\n this._startTime = currentTime - (this._duration - elapsed);\n this._reversed = !this._reversed;\n\n // istanbul ignore else @preserve\n if (this._initialRepeat > 0) {\n this._repeat = this._initialRepeat - this._repeat;\n }\n\n return this;\n }\n\n /**\n * Pause playback and capture the pause time.\n * @param time - Time of pause\n * @returns this\n */\n pause(time = now()): this {\n if (!this._isPlaying) return this;\n\n this._pauseStart = time;\n this._isPlaying = false;\n this._onPause?.(this.state);\n\n return this;\n }\n\n /**\n * Resume playback and reset the pause time.\n * @param time - Time of pause\n * @returns this\n */\n resume(time = now()): this {\n if (!this._pauseStart) return this;\n\n this._startTime += time - this._pauseStart;\n this._pauseStart = 0;\n this._isPlaying = true;\n this._onResume?.(this.state);\n\n addToQueue(this);\n\n return this;\n }\n\n /**\n * Sets the starting values for properties.\n * @param startValues - Partial object with starting values\n * @returns this\n */\n from(startValues: Partial<T> | DeepPartial<T>) {\n if (!this.isValidState || this.isPlaying) return this;\n\n this._evaluate(startValues);\n if (this.isValid) {\n Object.assign(this._propsStart, startValues);\n this._startIsSet = false;\n }\n\n return this;\n }\n\n /**\n * Sets the ending values for properties.\n * @param endValues - Partial object with target values\n * @returns this\n */\n to(endValues: Partial<T> | DeepPartial<T>) {\n if (!this.isValidState || this.isPlaying) return this;\n\n this._evaluate(endValues);\n if (this.isValid) {\n this._propsEnd = endValues as T;\n this._startIsSet = false;\n }\n\n return this;\n }\n\n /**\n * Sets the duration of the tween in seconds.\n * Internally it's converted to milliseconds.\n * @param duration - Time in seconds\n * @default 1 second\n * @returns this\n */\n duration(seconds = 1) {\n this._duration = seconds * 1000;\n return this;\n }\n\n /**\n * Sets the delay in seconds before the tween starts.\n * Internally it's converted to milliseconds.\n * @param delay - Time in seconds\n * @default 0 seconds\n * @returns this\n */\n delay(seconds = 0) {\n this._delay = seconds * 1000;\n return this;\n }\n\n /**\n * Sets how many times to repeat.\n * @param times - How many times to repeat\n * @default 0 times\n * @returns this\n */\n repeat(times = 0) {\n this._repeat = times;\n this._initialRepeat = times;\n return this;\n }\n\n /**\n * Sets a number of seconds to delay the animation\n * after each repeat.\n * @param seconds - How many seconds to delay\n * @default 0 seconds\n * @returns this\n */\n repeatDelay(seconds = 0) {\n this._repeatDelay = seconds * 1000;\n return this;\n }\n\n /**\n * Sets to tween from end to start values.\n * The easing is also goes backwards.\n * This requires repeat value of at least 1.\n * @param yoyo - When `true` values are reversed on every uneven repeat\n * @default false\n * @returns this\n */\n yoyo(yoyo = false) {\n this._yoyo = yoyo;\n return this;\n }\n\n /**\n * Sets the easing function.\n * @param easing - Function that maps progress [0,1] → eased progress [0,1]\n * @default linear\n * @returns this\n */\n easing(easing: EasingFunction = (t: number) => t) {\n this._easing = easing;\n return this;\n }\n\n /**\n * Registers a callback fired when `.start()` is called.\n * @param callback - Receives state at start time\n * @returns this\n */\n onStart(callback: TweenCallback<T>) {\n this._onStart = callback;\n return this;\n }\n\n /**\n * Registers a callback fired on every frame.\n * @param callback - Receives current state, elapsed (0–1)\n * @returns this\n */\n onUpdate(callback?: TweenUpdateCallback<T>) {\n this._onUpdate = callback;\n return this;\n }\n\n /**\n * Registers a callback fired when the tween reaches progress = 1.\n * @param callback - Receives final state\n * @returns this\n */\n onComplete(callback: TweenCallback<T>) {\n this._onComplete = callback;\n return this;\n }\n\n /**\n * Registers a callback fired when `.stop()` is called.\n * @param callback - Receives state at stop time\n * @returns this\n */\n onStop(callback: TweenCallback<T>) {\n this._onStop = callback;\n return this;\n }\n\n /**\n * Registers a callback fired when `pause()` was called.\n */\n onPause(cb: TweenCallback<T>) {\n this._onPause = cb;\n return this;\n }\n\n /**\n * Registers a callback fired when `.resume()` was called.\n */\n onResume(cb: TweenCallback<T>) {\n this._onResume = cb;\n return this;\n }\n\n /**\n * Registers a callback that is invoked **every time** one full cycle\n * (repeat iteration) * of the tween has completed — but **before**\n * the next repeat begins (if any remain).\n *\n * This is different from `onComplete`, which only fires once at the\n * very end of the entire tween (after all repeats are finished).\n */\n onRepeat(cb?: TweenCallback<T>) {\n this._onRepeat = cb;\n return this;\n }\n\n /**\n * Manually advances the tween to the given time.\n * @param time - Current absolute time (performance.now style)\n *\n * @returns `true` if the tween is still playing after the update, `false`\n * otherwise.\n */\n update(time = now()) {\n // istanbul ignore else\n if (!this._isPlaying) return false;\n\n // istanbul ignore else\n if (time < this._startTime) return true;\n\n // istanbul ignore else\n if (!this._startFired) {\n this._onStart?.(this.state);\n this._startFired = true;\n }\n\n const reversed = this._reversed;\n const state = this.state;\n const runtime = this._runtime;\n let progress = (time - this._startTime) / this._duration;\n // some limits are in good order for reverse\n // if (progress < 0) progress = 0;\n if (progress > 1) progress = 1;\n\n // super cheap yoyo\n let eased = this._easing(reversed ? 1 - progress : progress);\n eased = reversed ? 1 - eased : eased;\n\n const len = runtime.length;\n let i = 0;\n while (i < len) {\n const prop = runtime[i++];\n const targetObject = prop[0];\n const property = prop[1];\n const interpolator = prop[2];\n const startVal = reversed ? prop[4] : prop[3];\n const endVal = reversed ? prop[3] : prop[4];\n\n if (typeof endVal === \"number\") {\n state[property as keyof T] =\n ((startVal as number) + (endVal - (startVal as number)) * eased) as T[\n keyof T\n ];\n } else {\n interpolator(\n targetObject as never,\n startVal as never,\n endVal as never,\n eased,\n );\n }\n }\n\n this._onUpdate?.(state, progress);\n\n // istanbul ignore else\n if (progress === 1) {\n if (this._repeat === 0) {\n this._isPlaying = false;\n this._repeat = this._initialRepeat;\n this._reversed = false;\n this._onComplete?.(state);\n return false;\n }\n // istanbul ignore else @preserve\n if (this._repeat !== Infinity) this._repeat--;\n // istanbul ignore else @preserve\n if (this._yoyo) this._reversed = !reversed;\n this._startTime = time;\n this._startTime += this._repeatDelay;\n this._onRepeat?.(state);\n return true;\n }\n\n return true;\n }\n\n /**\n * Public method to register an extension for a given property.\n *\n * **NOTES**\n * - the extension will validate the initial values once `.use()` is called.\n * - the `.use()` method must be called before `.to()` / `.from()`.\n *\n * @param property The property name\n * @param extension The extension object\n * @returns this\n *\n * @example\n *\n * const tween = new Tween({ myProp: { x: 0, y: 0 } });\n * tween.use(\"myProp\", objectConfig);\n */\n use(property: string, { interpolate, validate }: PropConfig): this {\n // istanbul ignore else\n if (interpolate && !this._interpolators.has(property)) {\n this._interpolators.set(property, interpolate);\n }\n if (validate && !this._validators.has(property)) {\n this._validators.set(property, validate);\n }\n this._evaluate();\n return this;\n }\n\n /**\n * Internal method to reset state to initial values.\n * @internal\n */\n private _resetState() {\n deepAssign(this.state, this._state);\n }\n\n /**\n * Reset starting values, end values and runtime.\n */\n clear() {\n this._propsStart = {} as T;\n this._propsEnd = {} as T;\n this._runtime.length = 0;\n this._startTime = 0;\n this._pauseStart = 0;\n this._repeat = 0;\n this._initialRepeat = 0;\n return this;\n }\n\n /**\n * Internal method to handle instrumentation of start and end values for interpolation.\n * @internal\n */\n private _setProps(\n obj: T,\n propsStart: Partial<T>,\n propsEnd: Partial<T>,\n overrideStartingValues: boolean,\n ): void {\n const endKeys = Object.keys(propsEnd) as (keyof T)[];\n const len = endKeys.length;\n this._runtime.length = 0;\n let rtLen = 0;\n let i = 0;\n\n while (i < len) {\n const property = endKeys[i++];\n const objValue = obj[property] as T[keyof T];\n\n // Save the starting value, but only once unless override is requested.\n // istanbul ignore else\n if (\n typeof propsStart[property] === \"undefined\" ||\n overrideStartingValues\n ) {\n // Update start property value\n if (isObject(objValue) || isArray(objValue)) {\n propsStart[property] = deproxy(objValue);\n } else {\n // number\n propsStart[property] = objValue;\n }\n }\n // Pre-register interpolator\n const interpolator = this._interpolators.get(property) || null;\n\n // Store all values needed for interpolation\n // regardless if propsStart[property] is set or not\n this._runtime[rtLen++] = [\n objValue,\n property,\n interpolator,\n propsStart[property] as T[keyof T],\n propsEnd[property] as T[keyof T],\n ] as TweenRuntime<T>;\n }\n }\n\n /**\n * Internal method to handle validation of initial values, start and end values.\n * @internal\n */\n private _evaluate(newObj?: Partial<T> | DeepPartial<T>) {\n // the reference of the initialization state is stored here\n // istanbul ignore else @preserve\n if (!this.isValidState) {\n const temp = this._state;\n validateValues.call(this as unknown as Tween, temp);\n // istanbul ignore else @preserve\n if (this.isValid) {\n this.state = temp;\n this._state = deproxy(temp);\n }\n } else if (newObj) {\n validateValues.call(this as unknown as Tween, newObj, this._state);\n }\n return this;\n }\n\n /**\n * Internal method to provide feedback on validation issues.\n * @internal\n */\n private _report() {\n // istanbul ignore else @preserve\n if (!this.isValid) {\n const message = [\n \"[Tween] failed validation:\",\n \"- \" + Array.from(this._errors.values()).join(\"\\n- \"),\n ];\n\n console.warn(message.join(\"\\n\"));\n }\n return this;\n }\n}\n","// Timeline.ts\nimport type {\n DeepPartial,\n InterpolatorFunction,\n Position,\n PropConfig,\n TimelineCallback,\n TimelineEntry,\n TimelineEntryConfig,\n TweenProps,\n ValidationFunction,\n} from \"./types.d.ts\";\nimport { addToQueue, removeFromQueue } from \"./Runtime.ts\";\nimport {\n deepAssign,\n deproxy,\n isArray,\n isObject,\n validateValues,\n} from \"./Util.ts\";\nimport { now } from \"./Now.ts\";\n\n/**\n * Timeline orchestrates multiple tweens with scheduling, overlaps, labels and repeat.\n * Supports numbers and via extensions it enxtends to arrays\n * (e.g. RGB, points), nested objects, and SVG path morphing.\n *\n * @template T - Type of the animated state object\n *\n * @example\n * ```ts\n * const tl = new Timeline({ x: 0, opacity: 0 })\n * .to({ x: 300, duration: 1.2 })\n * .to({ opacity: 1, duration: 0.8 }, \"-=0.4\")\n * .play();\n * ```\n *\n * @param initialValues The initial values object\n */\nexport class Timeline<T extends TweenProps = TweenProps> {\n public state: T;\n private _state: T;\n private _entries: TimelineEntry<T>[] = [];\n private _labels = new Map<string, number>();\n private _progress = 0;\n private _duration = 0;\n private _yoyo = false;\n private _reversed = false;\n private _time = 0;\n private _pauseTime = 0;\n private _lastTime = 0;\n private _isPlaying = false;\n private _repeat = 0;\n private _repeatDelay = 0;\n private _repeatDelayStart = 0;\n private _initialRepeat = 0;\n private _errors = new Map<string | \"init\", string>();\n private _interpolators = new Map<string | keyof T, InterpolatorFunction>();\n private _validators = new Map<string | keyof T, ValidationFunction>();\n private _onStart?: TimelineCallback<T>;\n private _onStop?: TimelineCallback<T>;\n private _onPause?: TimelineCallback<T>;\n private _onResume?: TimelineCallback<T>;\n private _onUpdate?: TimelineCallback<T>;\n private _onComplete?: TimelineCallback<T>;\n private _onRepeat?: TimelineCallback<T>;\n\n /**\n * Creates a new Timeline instance.\n * @param initialValues - The initial state of the animated object\n */\n constructor(initialValues: T) {\n // we must initialize state to allow isValidState to work from here\n this.state = {} as T;\n validateValues.call(this as Timeline, initialValues);\n if (this._errors.size) {\n // we temporarily store initialValues reference here\n this._state = initialValues;\n } else {\n this.state = initialValues;\n this._state = { ...initialValues };\n }\n\n return this;\n }\n\n // GETTERS FIRST\n /**\n * Returns the current [0-1] progress value.\n */\n get progress() {\n return this._progress;\n }\n\n /**\n * Returns the total duration in seconds.\n */\n get duration() {\n return this._duration / 1000;\n }\n\n /**\n * Returns the total duration in seconds, which is a sum of all entries duration\n * multiplied by repeat value and repeat delay multiplied by repeat value.\n */\n get totalDuration() {\n const repeat = this._initialRepeat;\n return (\n this._duration * (repeat + 1) +\n this._repeatDelay * repeat\n ) / 1000;\n }\n\n /**\n * A boolean that returns `true` when timeline is playing.\n */\n get isPlaying(): boolean {\n return this._isPlaying;\n }\n\n /**\n * A boolean that returns `true` when timeline is paused.\n */\n get isPaused(): boolean {\n return !this._isPlaying && this._pauseTime > 0;\n }\n\n /**\n * A boolean that returns `true` when initial values are valid.\n */\n get isValidState(): boolean {\n return Object.keys(this.state).length > 0;\n }\n\n /**\n * A boolean that returns `true` when all values are valid.\n */\n get isValid(): boolean {\n return this._errors.size === 0;\n }\n\n /**\n * Returns the validator configured for a given property.\n */\n getValidator(propName: string) {\n return this._validators.get(propName);\n }\n\n /**\n * Returns the errors Map, mainly used by external validators.\n */\n getErrors() {\n return this._errors;\n }\n\n /**\n * Starts or resumes playback from the beginning (or current time if resumed).\n * Triggers the `onStart` callback if set.\n * @param startTime - Optional explicit start timestamp (defaults to now)\n * @returns this\n */\n play(time = now()): this {\n if (this._pauseTime) return this.resume();\n if (this._isPlaying) return this;\n if (!this.isValid) {\n this._report();\n return this;\n }\n if (this._time) this._resetState();\n this._isPlaying = true;\n this._lastTime = time;\n this._time = 0;\n this._onStart?.(this.state, 0);\n\n addToQueue(this);\n return this;\n }\n\n /**\n * Pauses playback (preserves current time).\n * Triggers the `onPause` callback if set.\n * @returns this\n */\n pause(time = now()): this {\n if (!this._isPlaying) return this;\n this._isPlaying = false;\n this._pauseTime = time;\n this._onPause?.(this.state, this.progress);\n return this;\n }\n\n /**\n * Resumes from paused state (adjusts internal clock).\n * Triggers the `onResume` callback if set.\n\n * @param time - Optional current timestamp (defaults to now)\n * @returns this\n */\n resume(time = now()): this {\n if (this._isPlaying) return this;\n this._isPlaying = true;\n const dif = time - this._pauseTime;\n this._pauseTime = 0;\n this._lastTime += dif;\n this._onResume?.(this.state, this.progress);\n\n addToQueue(this);\n return this;\n }\n\n /**\n * Reverses playback direction and mirrors current time position.\n * @returns this\n */\n reverse(): this {\n if (!this._isPlaying) return this;\n\n this._reversed = !this._reversed;\n this._time = this._duration - this._time;\n\n // istanbul ignore else @preserve\n if (this._initialRepeat > 0) {\n this._repeat = this._initialRepeat - this._repeat;\n }\n\n return this;\n }\n\n /**\n * Jumps to a specific time or label. When playback is reversed\n * the time is adjusted.\n * @param pointer - Seconds or label name\n * @returns this\n */\n seek(pointer: number | string): this {\n const elapsed = this._resolvePosition(pointer);\n\n this._time = elapsed;\n return this;\n }\n\n /**\n * Stops playback, resets time to 0, and restores initial state.\n * Triggers the `onStop` callback if set.\n * @returns this\n */\n stop(): this {\n if (!this._isPlaying) return this;\n this._isPlaying = false;\n this._time = 0;\n this._pauseTime = 0;\n this._repeat = this._initialRepeat;\n this._reversed = false;\n removeFromQueue(this);\n this._onStop?.(this.state, this._progress);\n return this;\n }\n\n /**\n * Sets the number of times the timeline should repeat.\n * @param count - Number of repeats (0 = once, Infinity = loop forever)\n * @returns this\n */\n repeat(count = 0): this {\n this._repeat = count;\n this._initialRepeat = count;\n return this;\n }\n\n /**\n * Sets a number of seconds to delay the animation\n * after each repeat.\n * @param amount - How many seconds to delay\n * @default 0 seconds\n * @returns this\n */\n repeatDelay(amount = 0) {\n this._repeatDelay = amount * 1000;\n return this;\n }\n\n /**\n * Sets to Timeline entries to tween from end to start values.\n * The easing is also goes backwards.\n * This requires repeat value of at least 1.\n * @param yoyo - When `true` values are reversed\n * @default false\n * @returns this\n */\n yoyo(yoyo = false) {\n this._yoyo = yoyo;\n return this;\n }\n\n /**\n * Adds a named time position for use in `.seek(\"label\")`.\n * @param name - Label identifier\n * @param position - Time offset or relative position\n * @returns this\n */\n label(name: string, position?: Position): this {\n this._labels.set(name, this._resolvePosition(position));\n return this;\n }\n\n /**\n * Adds a new tween entry to the timeline.\n * @param config - Values to animate + duration, easing, etc.\n * @param position - Start offset: number, \"+=0.5\", \"-=0.3\", or label name\n * @returns this (chainable)\n */\n to(\n {\n duration = 1,\n easing = (t) => t,\n ...values\n }: (Partial<T> | DeepPartial<T>) & TimelineEntryConfig,\n position: Position = \"+=0\",\n ): this {\n if (!this.isValidState || this._isPlaying) return this;\n\n this._evaluate(values as Partial<T> | DeepPartial<T>);\n if (this.isValid) {\n const startTime = this._resolvePosition(position);\n const to = values as Partial<T> | DeepPartial<T>;\n const from = {} as Partial<T>;\n const entryDuration = duration * 1000;\n const runtime = [] as TimelineEntry<T>[\"runtime\"];\n\n this._entries.push({\n from,\n to,\n runtime,\n startTime,\n duration: entryDuration,\n easing,\n isActive: false,\n });\n\n const endTime = startTime + entryDuration;\n this._duration = Math.max(this._duration, endTime);\n }\n return this;\n }\n\n /**\n * Registers a callback fired when playback begins.\n */\n onStart(cb: TimelineCallback<T>): this {\n this._onStart = cb;\n return this;\n }\n\n /**\n * Registers a callback fired when `pause()` was called.\n */\n onPause(cb: TimelineCallback<T>): this {\n this._onPause = cb;\n return this;\n }\n\n /**\n * Registers a callback fired when `.play()` / `.resume()` was called.\n */\n onResume(cb: TimelineCallback<T>): this {\n this._onResume = cb;\n return this;\n }\n\n /**\n * Registers a callback fired on explicit `.stop()`.\n */\n onStop(cb: TimelineCallback<T>): this {\n this._onStop = cb;\n return this;\n }\n\n /**\n * Registers a callback fired every frame.\n */\n onUpdate(cb: TimelineCallback<T>): this {\n this._onUpdate = cb;\n return this;\n }\n\n /**\n * Registers a callback fired when timeline naturally completes.\n */\n onComplete(cb: TimelineCallback<T>): this {\n this._onComplete = cb;\n return this;\n }\n\n /**\n * Registers a callback fired when `.play()` / `.resume()` was called.\n */\n onRepeat(cb?: TimelineCallback<T>) {\n this._onRepeat = cb;\n return this;\n }\n\n /**\n * Public method to register an extension for a given property.\n *\n * **NOTES**\n * - the extension will validate the initial values once `.use()` is called.\n * - the `.use()` method must be called before `.to()`.\n *\n * @param property The property name\n * @param extension The extension object\n * @returns this\n *\n * @example\n *\n * const timeline = new Timeline({ myProp: { x: 0, y: 0 } });\n * timeline.use(\"myProp\", objectConfig);\n */\n use(property: string, { interpolate, validate }: PropConfig): this {\n // istanbul ignore else\n if (interpolate && !this._interpolators.has(property)) {\n this._interpolators.set(property, interpolate);\n }\n if (validate && !this._validators.has(property)) {\n this._validators.set(property, validate);\n }\n this._evaluate();\n return this;\n }\n\n /**\n * Manually advances the timeline to the given time.\n * @param time - Current absolute time (performance.now style)\n *\n * @returns `true` if the timeline is still playing after the update, `false`\n * otherwise.\n */\n update(time = now()) {\n if (!this._isPlaying) return false;\n\n if (this._repeatDelayStart) {\n if (time - this._repeatDelayStart < this._repeatDelay) {\n this._lastTime = time; // Update lastTime to prevent delta accumulation\n return true;\n }\n // Delay complete\n this._repeatDelayStart = 0;\n }\n\n const delta = time - this._lastTime;\n const reversed = this._reversed;\n this._lastTime = time;\n this._time += delta;\n\n this._progress = this._time > this._duration\n ? 1\n : this._time / this._duration;\n\n const entries = this._entries;\n const state = this.state;\n const entriesLen = entries.length;\n let i = 0;\n\n while (i < entriesLen) {\n const entry = entries[i++];\n\n // reverse start time\n const startTime = !reversed\n ? entry.startTime\n : this._duration - entry.startTime - entry.duration;\n\n const localTime = this._time - startTime;\n\n // Calculate local time within the entry's duration\n let tweenElapsed = localTime / entry.duration;\n // some limits are in good order for reverse\n if (tweenElapsed > 1) tweenElapsed = 1;\n if (tweenElapsed < 0) tweenElapsed = 0;\n\n // Only build runtime once on first activation\n if (!entry.isActive && tweenElapsed > 0 && tweenElapsed < 1) {\n // istanbul ignore else @preserve\n if (entry.runtime.length === 0) {\n this._setEntry(entry, state);\n }\n entry.isActive = true;\n }\n\n // istanbul ignore else @preserve\n if (entry.isActive) {\n // super cheap yoyo\n let easedValue = entry.easing(\n reversed ? 1 - tweenElapsed : tweenElapsed,\n );\n easedValue = reversed ? 1 - easedValue : easedValue;\n const runtime = entry.runtime;\n\n const runtimeLen = runtime.length;\n let j = 0;\n while (j < runtimeLen) {\n const prop = runtime[j++];\n const targetObject = prop[0];\n const property = prop[1];\n const interpolator = prop[2];\n const startVal = reversed ? prop[4] : prop[3];\n const endVal = reversed ? prop[3] : prop[4];\n\n if (typeof endVal === \"number\") {\n state[property as keyof T] = ((startVal as number) +\n (endVal - (startVal as number)) * easedValue) as T[keyof T];\n } else {\n interpolator(\n targetObject as never,\n startVal as never,\n endVal as never,\n easedValue,\n );\n }\n }\n if (tweenElapsed === 1) entry.isActive = false;\n }\n }\n\n this._onUpdate?.(state, this._progress);\n\n // istanbul ignore else\n if (this._progress === 1) {\n // istanbul ignore else\n if (this._repeat === 0) {\n this._isPlaying = false;\n this._repeat = this._initialRepeat;\n this._reversed = false;\n this._onComplete?.(state, 1);\n this._resetState(true);\n\n return false;\n }\n\n // istanbul ignore else @preserve\n if (this._repeat !== Infinity) this._repeat--;\n if (this._yoyo) this._reversed = !reversed;\n\n this._time = 0;\n this._resetState();\n this._onRepeat?.(state, this.progress);\n\n if (this._repeatDelay > 0) this._repeatDelayStart = time;\n\n return true;\n }\n\n return true;\n }\n\n /**\n * Public method to clear all entries, labels and reset timers to zero\n * or initial value (repeat).\n */\n clear() {\n this._entries.length = 0;\n this._duration = 0;\n this._labels.clear();\n this._time = 0;\n this._progress = 0;\n this._pauseTime = 0;\n this._lastTime = 0;\n this._repeatDelay = 0;\n this._repeat = this._initialRepeat;\n this._repeatDelayStart = 0;\n this._reversed = false;\n return this;\n }\n\n /**\n * Internal method to handle instrumentation of start and end values for interpolation\n * of a tween entry. Only called once per entry on first activation.\n * @internal\n */\n private _setEntry(entry: TimelineEntry<T>, state: T) {\n const from = entry.from as Partial<T>;\n const to = entry.to as Partial<T>;\n const keysTo = Object.keys(to) as (keyof T)[];\n const keyLen = keysTo.length;\n entry.runtime = new Array(keyLen);\n let rtLen = 0;\n let j = 0;\n\n while (j < keyLen) {\n const key = keysTo[j++];\n const objValue = state[key] as T[keyof T];\n\n // Capture current state value for 'from'\n if (isObject(objValue) || isArray(objValue)) {\n from[key] = deproxy(objValue);\n } else {\n // number\n from[key] = objValue;\n }\n\n const interpolator = this._interpolators.get(key) || null;\n\n // Push tuple\n entry.runtime[rtLen++] = [\n objValue,\n key,\n interpolator,\n from[key] as T[keyof T],\n to[key] as T[keyof T],\n ] as TimelineEntry<T>[\"runtime\"][0];\n }\n }\n\n /**\n * Internal method to revert state to initial values and reset entry flags.\n * @internal\n */\n private _resetState(isComplete = false) {\n let i = 0;\n const entriesLen = this._entries.length;\n while (i < entriesLen) {\n const entry = this._entries[i++];\n entry.isActive = false;\n }\n if (!isComplete) {\n deepAssign(this.state, this._state);\n }\n }\n\n /**\n * Internal method to resolve the position relative to the current duration\n * or a set value in seconds.\n * @internal\n */\n private _resolvePosition(pos?: Position): number {\n if (typeof pos === \"number\") {\n return Math.min(this._duration, Math.max(0, pos * 1000));\n }\n\n // istanbul ignore else @preserve\n if (typeof pos === \"string\") {\n // First try label\n const labelTime = this._labels.get(pos);\n if (labelTime !== undefined) return labelTime;\n\n // Then relative\n // istanbul ignore else @preserve\n if (pos.startsWith(\"+=\") || pos.startsWith(\"-=\")) {\n let offset = parseFloat(pos.slice(2));\n if (isNaN(offset)) offset = 0;\n offset *= 1000;\n return pos.startsWith(\"+=\")\n ? this._duration + offset\n : Math.max(0, this._duration - offset);\n }\n }\n\n // Fallback to current duration\n return this._duration;\n }\n\n /**\n * Internal method to handle validation of initial values and entries values.\n * @internal\n */\n private _evaluate(newObj?: Partial<T> | DeepPartial<T>) {\n // the reference of the initialization state is stored here\n // istanbul ignore else @preserve\n if (!this.isValidState) {\n const temp = this._state;\n validateValues.call(this as Timeline, temp);\n // istanbul ignore else @preserve\n if (this.isValid) {\n this.state = temp;\n this._state = deproxy(temp);\n }\n } else if (newObj) {\n validateValues.call(this as Timeline, newObj, this._state);\n }\n return this;\n }\n\n /**\n * Internal method to provide feedback on validation issues.\n * @internal\n */\n private _report() {\n // istanbul ignore else @preserve\n if (!this.isValid) {\n const message = [\n \"[Timeline] failed validation:\",\n \"- \" + Array.from(this._errors.values()).join(\"\\n- \"),\n ].join(\"\\n\");\n\n console.warn(message);\n }\n return this;\n }\n}\n",""],"x_google_ignoreList":[3],"mappings":"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"}
|