From 724fe28f016ad4c4e7ec053cafab66c2231f1ab3 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 24 Oct 2018 11:28:11 +0100 Subject: [PATCH 001/333] feat: add temp geom2 & vectors2 packages (defmulti API) --- packages/geom2/.npmignore | 11 ++ packages/geom2/LICENSE | 201 ++++++++++++++++++++ packages/geom2/README.md | 40 ++++ packages/geom2/package.json | 44 +++++ packages/geom2/src/api.ts | 146 ++++++++++++++ packages/geom2/src/circle2.ts | 25 +++ packages/geom2/src/index.ts | 3 + packages/geom2/src/rect2.ts | 30 +++ packages/geom2/test/index.ts | 6 + packages/geom2/test/tsconfig.json | 10 + packages/geom2/tsconfig.json | 9 + packages/vectors2/.npmignore | 11 ++ packages/vectors2/LICENSE | 201 ++++++++++++++++++++ packages/vectors2/README.md | 40 ++++ packages/vectors2/package.json | 52 +++++ packages/vectors2/src/accessors.ts | 16 ++ packages/vectors2/src/api.ts | 209 ++++++++++++++++++++ packages/vectors2/src/avec.ts | 39 ++++ packages/vectors2/src/codegen.ts | 195 +++++++++++++++++++ packages/vectors2/src/index.ts | 3 + packages/vectors2/src/vec2.ts | 235 +++++++++++++++++++++++ packages/vectors2/src/vec3.ts | 275 +++++++++++++++++++++++++++ packages/vectors2/src/vop.ts | 18 ++ packages/vectors2/test/index.ts | 6 + packages/vectors2/test/tsconfig.json | 10 + packages/vectors2/tsconfig.json | 10 + 26 files changed, 1845 insertions(+) create mode 100644 packages/geom2/.npmignore create mode 100644 packages/geom2/LICENSE create mode 100644 packages/geom2/README.md create mode 100644 packages/geom2/package.json create mode 100644 packages/geom2/src/api.ts create mode 100644 packages/geom2/src/circle2.ts create mode 100644 packages/geom2/src/index.ts create mode 100644 packages/geom2/src/rect2.ts create mode 100644 packages/geom2/test/index.ts create mode 100644 packages/geom2/test/tsconfig.json create mode 100644 packages/geom2/tsconfig.json create mode 100644 packages/vectors2/.npmignore create mode 100644 packages/vectors2/LICENSE create mode 100644 packages/vectors2/README.md create mode 100644 packages/vectors2/package.json create mode 100644 packages/vectors2/src/accessors.ts create mode 100644 packages/vectors2/src/api.ts create mode 100644 packages/vectors2/src/avec.ts create mode 100644 packages/vectors2/src/codegen.ts create mode 100644 packages/vectors2/src/index.ts create mode 100644 packages/vectors2/src/vec2.ts create mode 100644 packages/vectors2/src/vec3.ts create mode 100644 packages/vectors2/src/vop.ts create mode 100644 packages/vectors2/test/index.ts create mode 100644 packages/vectors2/test/tsconfig.json create mode 100644 packages/vectors2/tsconfig.json diff --git a/packages/geom2/.npmignore b/packages/geom2/.npmignore new file mode 100644 index 0000000000..ec83d74c9d --- /dev/null +++ b/packages/geom2/.npmignore @@ -0,0 +1,11 @@ +build +coverage +dev +doc +export +src* +test +.nyc_output +tsconfig.json +*.tgz +*.html diff --git a/packages/geom2/LICENSE b/packages/geom2/LICENSE new file mode 100644 index 0000000000..8dada3edaf --- /dev/null +++ b/packages/geom2/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/geom2/README.md b/packages/geom2/README.md new file mode 100644 index 0000000000..6ab103f4d7 --- /dev/null +++ b/packages/geom2/README.md @@ -0,0 +1,40 @@ +# @thi.ng/geom2 + +[![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/geom2.svg)](https://www.npmjs.com/package/@thi.ng/geom2) +![npm downloads](https://img.shields.io/npm/dm/@thi.ng/geom2.svg) +[![Twitter Follow](https://img.shields.io/twitter/follow/thing_umbrella.svg?style=flat-square&label=twitter)](https://twitter.com/thing_umbrella) + +This project is part of the +[@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo. + + + + + +## About + +TODO... + +## Installation + +```bash +yarn add @thi.ng/geom2 +``` + +## Dependencies + +- TODO... + +## Usage examples + +```ts +import * as g from "@thi.ng/geom2"; +``` + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/packages/geom2/package.json b/packages/geom2/package.json new file mode 100644 index 0000000000..df4d1830fd --- /dev/null +++ b/packages/geom2/package.json @@ -0,0 +1,44 @@ +{ + "name": "@thi.ng/geom2", + "version": "0.0.1", + "description": "TODO", + "main": "./index.js", + "typings": "./index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/thi-ng/umbrella.git" + }, + "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/geom2", + "author": "Karsten Schmidt ", + "license": "Apache-2.0", + "scripts": { + "build": "yarn run clean && tsc --declaration", + "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "cover": "yarn test && nyc report --reporter=lcov", + "doc": "node_modules/.bin/typedoc --mode modules --out doc src", + "pub": "yarn run build && yarn publish --access public", + "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + }, + "devDependencies": { + "@types/mocha": "^5.2.5", + "@types/node": "^10.12.0", + "mocha": "^5.2.0", + "nyc": "^13.1.0", + "typedoc": "^0.13.0", + "typescript": "^3.1.3" + }, + "dependencies": { + "@thi.ng/api": "^4.2.3", + "@thi.ng/defmulti": "^0.4.1", + "@thi.ng/malloc": "^0.1.0", + "@thi.ng/math": "^0.2.0", + "@thi.ng/vectors2": "^0.0.1" + }, + "keywords": [ + "ES6", + "typescript" + ], + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/packages/geom2/src/api.ts b/packages/geom2/src/api.ts new file mode 100644 index 0000000000..8eac58994e --- /dev/null +++ b/packages/geom2/src/api.ts @@ -0,0 +1,146 @@ +import { defmulti, DEFAULT } from "@thi.ng/defmulti"; +import { Vec } from "@thi.ng/vectors2/api"; +import { IObjectOf, ICopy } from "@thi.ng/api"; + +import "@thi.ng/vectors2/vec2"; +import { asVec2, Vec2 } from "@thi.ng/vectors2/vec2"; + +export enum Type { + CIRCLE2 = "circle", + RECT2 = "rect", + POLYGON2 = "polygon", + QUAD2 = "quad", +} + +export interface Shape { + readonly type: string; + attribs?: IObjectOf; +} + +export interface AABB extends Shape { + pos: Vec; + size: Vec; +} + +export type Attribs = IObjectOf; + +const dispatch = (x: Shape) => x.type; + +export const area = defmulti(dispatch); +export const arcLength = defmulti(dispatch); + +export const bounds = defmulti(dispatch); +export const width = defmulti(dispatch); +export const height = defmulti(dispatch); +export const depth = defmulti(dispatch); +width.add(DEFAULT, (x) => bounds(x).size[0]); +height.add(DEFAULT, (x) => bounds(x).size[0]); +depth.add(DEFAULT, (x) => bounds(x).size[2] || 0); + +export const centroid = defmulti(dispatch); +export const center = defmulti(dispatch); +export const vertices = defmulti(dispatch); + +export class HShape extends Array implements + Shape { + + constructor(type: string, attribs: Attribs, ...xs: any[]) { + super(type, attribs, ...xs); + } + + get type() { + return this[0]; + } + + get attribs() { + return this[1]; + } + + set attribs(attr: Attribs) { + this[1] = attr; + } +} + +export class Circle2 extends HShape implements + ICopy { + + constructor(pos: Vec, r: number, attribs?: Attribs) { + super(Type.CIRCLE2, attribs, asVec2(pos), r); + } + + copy() { + return new Circle2(this.pos.copy(), this.r, { ...this.attribs }); + } + + get pos(): Vec2 { + return this[2]; + } + + set pos(v: Vec2) { + this[2] = v; + } + + get r(): number { + return this[3]; + } + + set r(r: number) { + this[3] = r; + } +} + +export class Rect2 extends HShape implements AABB { + + constructor(pos: Vec, size: Vec, attribs?: Attribs) { + super(Type.RECT2, attribs, asVec2(pos), asVec2(size)); + } + + get pos(): Vec2 { + return this[2]; + } + + set pos(v: Vec2) { + this[2] = v; + } + + get size(): Vec2 { + return this[3]; + } + + set size(v: Vec2) { + this[3] = v; + } +} + +export class Quad2 extends HShape implements + ICopy { + + constructor(points: Vec[], attribs?: Attribs) { + super(Type.POLYGON2, attribs, points.map(asVec2)); + } + + copy() { + return new Quad2(this.points, { ...this.attribs }); + } + + get type() { + return Type.QUAD2; + } + + get points(): Vec2[] { + return this[2]; + } + + set points(pts: Vec2[]) { + this[3] = pts; + } +} + +// traverse until no further link is found or stop if an impl is found +// e.g. quad -> polygon -> container +// TODO add to defmulti + +// const hierarchy = { +// [Type.QUAD2]: [Type.POLYGON2,...], +// [Type.POLYGON2]: [Type.CONTAINER2,...] +// }; diff --git a/packages/geom2/src/circle2.ts b/packages/geom2/src/circle2.ts new file mode 100644 index 0000000000..423ed22af9 --- /dev/null +++ b/packages/geom2/src/circle2.ts @@ -0,0 +1,25 @@ +import { PI, TAU } from "@thi.ng/math/api"; +import { subNewN, Vec } from "@thi.ng/vectors2/api"; +import { asVec2, vec2 } from "@thi.ng/vectors2/vec2"; +import { + arcLength, + area, + bounds, + centroid, + Circle2, + Type, + Attribs, + Rect2, +} from "./api"; + +export function circle2(pos: Vec, r = 1, attribs?: Attribs): Circle2 { + return new Circle2(asVec2(pos), r, attribs); +} + +area.add(Type.CIRCLE2, (x: Circle2) => PI * x.r * x.r); + +arcLength.add(Type.CIRCLE2, (x: Circle2) => TAU * x.r); + +bounds.add(Type.CIRCLE2, (x: Circle2) => new Rect2(subNewN(x.pos, x.r), vec2(x.r * 2, x.r * 2))); + +centroid.add(Type.CIRCLE2, (x: Circle2) => x.pos); diff --git a/packages/geom2/src/index.ts b/packages/geom2/src/index.ts new file mode 100644 index 0000000000..d67a96f039 --- /dev/null +++ b/packages/geom2/src/index.ts @@ -0,0 +1,3 @@ +export * from "./api"; +export * from "./circle2"; +export * from "./rect2"; diff --git a/packages/geom2/src/rect2.ts b/packages/geom2/src/rect2.ts new file mode 100644 index 0000000000..fe3ce65e5b --- /dev/null +++ b/packages/geom2/src/rect2.ts @@ -0,0 +1,30 @@ +import { addNew, maddNewN, Vec } from "@thi.ng/vectors2/api"; +import { Vec2, vec2 } from "@thi.ng/vectors2/vec2"; +import { + arcLength, + area, + Attribs, + bounds, + centroid, + Rect2, + Type, + vertices +} from "./api"; + +export function rect2(pos: Vec, size: Vec, attribs?: Attribs): Rect2 { + return new Rect2(pos, size, attribs); +} + +area.add(Type.RECT2, (x: Rect2) => x.size[0] * x.size[1]); + +arcLength.add(Type.RECT2, (x: Rect2) => 2 * (x.size[0] + x.size[1])); + +bounds.add(Type.RECT2, (x: Rect2) => x); + +centroid.add(Type.RECT2, (x: Rect2) => maddNewN(x.pos, x.size, 0.5)); + +vertices.add(Type.RECT2, (x: Rect2) => { + const p = x.pos; + const q = addNew(p, x.size, vec2()); + return [p.copy(), vec2(q.x, p.y), q, vec2(p.x, q.y)]; +}); diff --git a/packages/geom2/test/index.ts b/packages/geom2/test/index.ts new file mode 100644 index 0000000000..dd5942b987 --- /dev/null +++ b/packages/geom2/test/index.ts @@ -0,0 +1,6 @@ +// import * as assert from "assert"; +// import * as g from "../src/index"; + +describe("geom2", () => { + it("tests pending"); +}); diff --git a/packages/geom2/test/tsconfig.json b/packages/geom2/test/tsconfig.json new file mode 100644 index 0000000000..bcf29ace54 --- /dev/null +++ b/packages/geom2/test/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "../build" + }, + "include": [ + "./**/*.ts", + "../src/**/*.ts" + ] +} diff --git a/packages/geom2/tsconfig.json b/packages/geom2/tsconfig.json new file mode 100644 index 0000000000..bd6481a5a6 --- /dev/null +++ b/packages/geom2/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "." + }, + "include": [ + "./src/**/*.ts" + ] +} diff --git a/packages/vectors2/.npmignore b/packages/vectors2/.npmignore new file mode 100644 index 0000000000..ec83d74c9d --- /dev/null +++ b/packages/vectors2/.npmignore @@ -0,0 +1,11 @@ +build +coverage +dev +doc +export +src* +test +.nyc_output +tsconfig.json +*.tgz +*.html diff --git a/packages/vectors2/LICENSE b/packages/vectors2/LICENSE new file mode 100644 index 0000000000..8dada3edaf --- /dev/null +++ b/packages/vectors2/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/vectors2/README.md b/packages/vectors2/README.md new file mode 100644 index 0000000000..42fad90a53 --- /dev/null +++ b/packages/vectors2/README.md @@ -0,0 +1,40 @@ +# @thi.ng/vectors2 + +[![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/vectors2.svg)](https://www.npmjs.com/package/@thi.ng/vectors2) +![npm downloads](https://img.shields.io/npm/dm/@thi.ng/vectors2.svg) +[![Twitter Follow](https://img.shields.io/twitter/follow/thing_umbrella.svg?style=flat-square&label=twitter)](https://twitter.com/thing_umbrella) + +This project is part of the +[@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo. + + + + + +## About + +TODO... + +## Installation + +```bash +yarn add @thi.ng/vectors2 +``` + +## Dependencies + +- TODO... + +## Usage examples + +```ts +import * as m from "@thi.ng/vectors2"; +``` + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/packages/vectors2/package.json b/packages/vectors2/package.json new file mode 100644 index 0000000000..fb8438b033 --- /dev/null +++ b/packages/vectors2/package.json @@ -0,0 +1,52 @@ +{ + "name": "@thi.ng/vectors2", + "version": "0.0.1", + "description": "TODO", + "main": "./index.js", + "typings": "./index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/thi-ng/umbrella.git" + }, + "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/vectors2", + "author": "Karsten Schmidt ", + "license": "Apache-2.0", + "scripts": { + "build": "yarn run clean && tsc --declaration", + "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "cover": "yarn test && nyc report --reporter=lcov", + "doc": "node_modules/.bin/typedoc --mode modules --out doc src", + "pub": "yarn run build && yarn publish --access public", + "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + }, + "devDependencies": { + "@types/mocha": "^5.2.5", + "@types/node": "^10.12.0", + "mocha": "^5.2.0", + "nyc": "^13.1.0", + "typedoc": "^0.13.0", + "typescript": "^3.1.3" + }, + "dependencies": { + "@thi.ng/api": "^4.2.3", + "@thi.ng/malloc": "^0.1.0", + "@thi.ng/math": "^0.2.0" + }, + "keywords": [ + "ES6", + "typescript" + ], + "publishConfig": { + "access": "public" + }, + "browserslist": [ + "last 3 Chrome versions" + ], + "browser": { + "process": false + }, + "sideEffects": [ + "./src/vec2.js", + "./src/vec3.js" + ] +} \ No newline at end of file diff --git a/packages/vectors2/src/accessors.ts b/packages/vectors2/src/accessors.ts new file mode 100644 index 0000000000..c86a5bb69c --- /dev/null +++ b/packages/vectors2/src/accessors.ts @@ -0,0 +1,16 @@ +export const declareIndices = (proto: any, props: string[]) => { + const get = (i: number) => function () { return this.buf[this.i + i * this.s]; }; + const set = (i: number) => function (n: number) { this.buf[this.i + i * this.s] = n; }; + props.forEach((id, i) => { + Object.defineProperty(proto, i, { + get: get(i), + set: set(i), + enumerable: true, + }); + Object.defineProperty(proto, id, { + get: get(i), + set: set(i), + enumerable: true, + }); + }); +}; diff --git a/packages/vectors2/src/api.ts b/packages/vectors2/src/api.ts new file mode 100644 index 0000000000..d2de8400de --- /dev/null +++ b/packages/vectors2/src/api.ts @@ -0,0 +1,209 @@ +import { + ICopy, + IEmpty, + IEqualsDelta, + ILength +} from "@thi.ng/api"; +import { atan2Abs } from "@thi.ng/math/angle"; +import { EPS } from "@thi.ng/math/api"; +import { repeatedly } from "@thi.ng/transducers/iter/repeatedly"; +import { vop } from "./vop"; + +// suffix convention: +// V = vector arg +// N = numeric / scalar arg +// Ro = readonly + +export type VecOpV = (a: Vec, ...xs: any[]) => T; +export type VecOpVV = (a: Vec, b: Readonly) => T; +export type VecOpVN = (a: Vec, n: number) => T; +export type VecOpVNN = (a: Vec, n: number, m: number) => T; +export type VecOpVVN = (a: Vec, b: Readonly, n: number) => T; +export type VecOpVVV = (a: Vec, b: Readonly, c: Readonly) => T; + +export type VecOpNewVN = (a: Vec, n: number, o?: T) => T; +export type VecOpNewVV = (a: Vec, b: Readonly, o?: T) => T; +export type VecOpNewVVN = (a: Vec, b: Readonly, n: number, o?: T) => T; +export type VecOpNewVVV = (a: Vec, b: Readonly, c: Readonly, o?: T) => T; + +export type VecOpRoV = (a: Readonly, ...xs: any[]) => T; +export type VecOpRoVV = (a: Readonly, b: Readonly, ...xs: any[]) => T; +export type VecOpRoVVV = (a: Readonly, b: Readonly, c: Readonly, ...xs: any[]) => T; + +export interface MultiVecOp { + add(dim: number, op: VOP); + default(op: VOP); +} + +export interface MultiVecOpV extends VecOpV, MultiVecOp> { } +export interface MultiVecOpVV extends VecOpVV, MultiVecOp> { } +export interface MultiVecOpVN extends VecOpVN, MultiVecOp> { } +export interface MultiVecOpVNN extends VecOpVNN, MultiVecOp> { } +export interface MultiVecOpVVN extends VecOpVVN, MultiVecOp> { } +export interface MultiVecOpVVV extends VecOpVVV, MultiVecOp> { } + +export interface MultiVecOpNewVV extends VecOpNewVV, MultiVecOp> { } +export interface MultiVecOpNewVN extends VecOpNewVN, MultiVecOp> { } +export interface MultiVecOpNewVVN extends VecOpNewVVN, MultiVecOp> { } +export interface MultiVecOpNewVVV extends VecOpNewVVV, MultiVecOp> { } + +export interface MultiVecOpRoV extends VecOpRoV, MultiVecOp> { } +export interface MultiVecOpRoVV extends VecOpRoVV, MultiVecOp> { } +export interface MultiVecOpRoVVV extends VecOpRoVVV, MultiVecOp> { } + +export interface Vec extends + Iterable, + ILength { + + [id: number]: number; +} + +export interface IVector extends + Vec, + ICopy, + IEmpty, + IEqualsDelta { + + i: number; + s: number; +} + +export type Vec2Coord = 0 | 1; +export type Vec3Coord = 0 | 1 | 2; +export type Vec4Coord = 0 | 1 | 2 | 3; + +export const set: MultiVecOpVV = vop(); +export const setN: MultiVecOpVN = vop(); +export const setS: MultiVecOpV = vop(); + +export const zero = (a: Vec) => setN(a, 0); +export const one = (a: Vec) => setN(a, 1); + +export const eqDelta: MultiVecOpRoVV = vop(); + +export const rand: MultiVecOpVNN = vop(); +export const rand01: MultiVecOpV = vop(); +export const rand11: MultiVecOpV = vop(); + +export const [add, sub, mul, div]: MultiVecOpVV[] + = [...repeatedly(vop, 4)]; +export const [addNew, subNew, mulNew, divNew]: MultiVecOpNewVV[] + = [...repeatedly(vop, 4)]; +export const [addN, subN, mulN, divN]: MultiVecOpVN[] + = [...repeatedly(vop, 4)]; +export const [addNewN, subNewN, mulNewN, divNewN]: MultiVecOpNewVN[] + = [...repeatedly(vop, 4)]; + +export const neg: MultiVecOpV = vop(); +neg.default((v) => mulN(v, -1)); + +export const madd: MultiVecOpVVV = vop(); +export const maddN: MultiVecOpVVN = vop(); +export const maddNew: MultiVecOpNewVVV = vop(); +export const maddNewN: MultiVecOpNewVVN = vop(); + +export const dot: MultiVecOpRoVV = vop(); + +export const magSq: MultiVecOpRoV = vop(); +export const mag: MultiVecOpRoV = vop(); +mag.default((a) => Math.sqrt(magSq(a, a))); + +export const normalize: MultiVecOpV = vop(); +normalize.default((v, n: number) => { + let m = mag(v); + return m >= EPS ? mulN(v, n / m) : v; +}); + +export const limit: MultiVecOpV = vop(); +limit.default((v, n: number) => { + let m = mag(v); + return m > n ? mulN(v, n / m) : v; +}); + +export const distSq: MultiVecOpVV = vop(); +export const dist: MultiVecOpVV = vop(); +dist.default((a, b) => Math.sqrt(distSq(a, b))); + +export const distManhattan: MultiVecOpRoVV = vop(); +export const distChebyshev: MultiVecOpRoVV = vop(); + +export const abs: MultiVecOpV = vop(); +export const sign: MultiVecOpV = vop(); +export const sin: MultiVecOpV = vop(); +export const cos: MultiVecOpV = vop(); +export const sqrt: MultiVecOpV = vop(); +export const floor: MultiVecOpV = vop(); +export const ceil: MultiVecOpV = vop(); +export const fract: MultiVecOpV = vop(); +export const trunc: MultiVecOpV = vop(); +export const log: MultiVecOpV = vop(); +export const exp: MultiVecOpV = vop(); +export const pow: MultiVecOpVV = vop(); +export const powN: MultiVecOpVN = vop(); + +export const min: MultiVecOpVV = vop(); +export const max: MultiVecOpVV = vop(); +export const clamp: MultiVecOpVVV = vop(); +clamp.default((a, b, c) => min(max(a, b), c)); + +export const minor: MultiVecOpV = vop(); +export const major: MultiVecOpV = vop(); + +export const mix: MultiVecOpVVV = vop(); +export const mixN: MultiVecOpVVN = vop(); +export const mixNew: MultiVecOpNewVVV = vop(); +export const mixNewN: MultiVecOpNewVVN = vop(); + +export const step: MultiVecOpVV = vop(); +export const smoothStep: MultiVecOpVVV = vop(); + +const _rotate = (u: number, v: number): VecOpVN => + (a: Vec, theta: number) => { + const s = Math.sin(theta); + const c = Math.cos(theta); + const x = a[u]; + const y = a[v]; + a[u] = x * c - y * s; + a[v] = x * s + y * c; + return a; + }; + +export const rotateX = _rotate(1, 2); +export const rotateY = _rotate(2, 0); +export const rotateZ = _rotate(0, 1); + +export const polar: MultiVecOpV = vop(); +export const cartesian: MultiVecOpV = vop(); + +export const reflect: VecOpVV = + (a, b) => maddN(a, b, -2 * dot(a, b)); + +export const refract: VecOpVVN = + (a, n, eta) => { + const d = dot(a, n); + const k = 1 - eta * eta * (1 - d * d); + return k < 0 ? + zero(a) : + maddN(mulN(a, eta), n, -(eta * d + Math.sqrt(k))); + }; + +export const headingXY = (a: Readonly) => atan2Abs(a[1], a[0]); +export const headingXZ = (a: Readonly) => atan2Abs(a[2], a[0]); +export const headingYZ = (a: Readonly) => atan2Abs(a[2], a[1]); + +export const angleRatio = + (a: Readonly, b: Readonly) => + dot(a, b) / (mag(a) * mag(b)); + +export const angleBetween: MultiVecOpRoVV = vop(); + +const mi = -Infinity; +const mx = Infinity; +export const MIN4 = Object.freeze([mi, mi, mi, mi]); +export const MAX4 = Object.freeze([mx, mx, mx, mx]); +export const ONE4 = Object.freeze([1, 1, 1, 1]); +export const ZERO4 = Object.freeze([0, 0, 0, 0]); +export const X4 = Object.freeze([1, 0, 0, 0]); +export const Y4 = Object.freeze([0, 1, 0, 0]); +export const Z4 = Object.freeze([0, 0, 1, 0]); +export const W4 = Object.freeze([0, 0, 0, 1]); diff --git a/packages/vectors2/src/avec.ts b/packages/vectors2/src/avec.ts new file mode 100644 index 0000000000..b747c9c367 --- /dev/null +++ b/packages/vectors2/src/avec.ts @@ -0,0 +1,39 @@ +import { Vec } from "./api"; + +export abstract class AVec { + + buf: Vec; + i: number; + s: number; + + constructor(buf: Vec, i = 0, s = 1) { + this.buf = buf; + this.i = i; + this.s = s; + } + + abstract get length(): number; + + dim() { + return 1; + } + + offset() { + return this.i; + } + + shape() { + return [this.length]; + } + + stride() { + return [this.s]; + } + + extract(dest: Vec = []) { + for (let n = this.length - 1, s = this.s, i = this.i + n * s; n >= 0; i -= s, n--) { + dest[n] = this.buf[i]; + } + return dest; + } +} diff --git a/packages/vectors2/src/codegen.ts b/packages/vectors2/src/codegen.ts new file mode 100644 index 0000000000..12d3e067e9 --- /dev/null +++ b/packages/vectors2/src/codegen.ts @@ -0,0 +1,195 @@ +import { FnAny } from "@thi.ng/api"; +import { sign as _sign } from "@thi.ng/math/abs"; +import { clamp as _clamp } from "@thi.ng/math/interval"; +import { fract as _fract, trunc as _trunc } from "@thi.ng/math/prec"; +import { smoothStep as _smoothStep, step as _step } from "@thi.ng/math/step"; +import { comp } from "@thi.ng/transducers/func/comp"; +import { range } from "@thi.ng/transducers/iter/range"; +import { tuples } from "@thi.ng/transducers/iter/tuples"; +import { push } from "@thi.ng/transducers/rfn/push"; +import { transduce } from "@thi.ng/transducers/transduce"; +import { map } from "@thi.ng/transducers/xform/map"; +import { mapIndexed } from "@thi.ng/transducers/xform/map-indexed"; +import { take } from "@thi.ng/transducers/xform/take"; +import { + abs, + add, + addN, + addNew, + addNewN, + ceil, + cos, + div, + divN, + divNew, + divNewN, + exp, + floor, + fract, + madd, + maddN, + max, + min, + mix, + mixN, + mixNew, + mixNewN, + mul, + mulN, + mulNew, + mulNewN, + pow, + powN, + set, + setN, + sign, + sin, + smoothStep, + sqrt, + step, + sub, + subN, + subNew, + subNewN, + trunc, + Vec, + VecOpV, + VecOpVV, + VecOpVN, + VecOpNewVV, + VecOpNewVN, + rand01, + rand11, + log, + setS, + rand, + clamp, + maddNew, + maddNewN, +} from "./api"; + +type Template = (syms: string[], i?: number) => string; + +const indices = (sym: string) => map((i) => `${sym}[${i}]`, range()); + +/** + * Takes a vector size `dim`, a code template function and an array of + * symbol names participating in the template. For each symbol, creates + * iterator of index lookups (e.g. `a[0]`), forms them into tuples and + * passes them to template to generate code. If the optional `ret` arg + * is not `null` (default `"a"`), appends a `return` statement to the + * result array, using `ret` as return value. Returns array of source + * code lines. + * + * @param dim + * @param tpl + * @param syms + * @param ret + */ +const assemble = ( + dim: number, + tpl: Template, + syms: string, + ret = "a") => { + + const src = transduce( + comp(take(dim), mapIndexed((i, x: string[]) => tpl(x, i))), + push(), + tuples.apply(null, [...map(indices, syms.split(","))]) + ); + ret !== null && src.push(`return ${ret};`); + return src; +}; + +const compile = (dim: number, tpl: Template, args: string, syms = args, ret = "a") => + new Function(args, assemble(dim, tpl, syms, ret).join("")); + +const compileHOF = (dim: number, fn: FnAny, tpl: Template, args: string, syms = args, ret = "a") => { + return new Function( + "fn", + `return (${args})=>{${assemble(dim, tpl, syms, ret).join("\n")}}` + )(fn); +}; + +export const genOpFnV = (dim: number, op: string): VecOpV => + compile(dim, ([a]) => `${a}=${op}(${a});`, "a"); + +export const genOpHofV = (dim: number, fn) => + compileHOF(dim, fn, ([a]) => `${a}=fn(${a});`, "a"); + +export const genOpVV = (dim: number, op: string): VecOpVV => + compile(dim, ([a, b]) => `${a}${op}=${b};`, "a,b"); + +export const genOpFnVV = (dim: number, fn: string): VecOpVV => + compile(dim, ([a, b]) => `${a}=${fn}(${a},${b});`, "a,b"); + +export const genOpVN = (dim: number, op: string): VecOpVN => + compile(dim, ([a]) => `${a}${op}=n;`, "a,n", "a"); + +export const genOpNewVV = (dim: number, op: string): VecOpNewVV => + compile(dim, ([a, b, o]) => `${o}=${a}${op}${b};`, "a,b,o=[]", "a,b,o", "o"); + +export const genOpNewVN = (dim: number, op: string): VecOpNewVN => + compile(dim, ([a, o]) => `${o}=${a}${op}n;`, "a,n,o=[]", "a,o", "o"); + +export const genCommon = (dim: number) => { + set.add(dim, genOpVV(dim, "")); + setN.add(dim, genOpVN(dim, "")); + setS.add(dim, compile(dim, ([a], i) => `${a}=xs[${i}];`, "a,...xs", "a")); + + // TODO add IRandom support + rand01.add(dim, compile(dim, ([a]) => `${a}=Math.random();`, "a")); + rand11.add(dim, compile(dim, ([a]) => `${a}=Math.random()*2-1;`, "a")); + rand.add(dim, compile(dim, ([a]) => `${a}=n+(m-n)*Math.random();`, "a,n,m", "a")); + + add.add(dim, genOpVV(dim, "+")); + sub.add(dim, genOpVV(dim, "-")); + mul.add(dim, genOpVV(dim, "*")); + div.add(dim, genOpVV(dim, "/")); + + subNew.add(dim, genOpNewVV(dim, "-")); + addNew.add(dim, genOpNewVV(dim, "+")); + mulNew.add(dim, genOpNewVV(dim, "*")); + divNew.add(dim, genOpNewVV(dim, "/")); + + subN.add(dim, genOpVN(dim, "-")); + addN.add(dim, genOpVN(dim, "+")); + mulN.add(dim, genOpVN(dim, "*")); + divN.add(dim, genOpVN(dim, "/")); + + subNewN.add(dim, genOpNewVN(dim, "-")); + addNewN.add(dim, genOpNewVN(dim, "+")); + mulNewN.add(dim, genOpNewVN(dim, "*")); + divNewN.add(dim, genOpNewVN(dim, "/")); + + madd.add(dim, compile(dim, ([a, b, c]) => `${a}+=${b}*${c};`, "a,b,c")); + maddN.add(dim, compile(dim, ([a, b]) => `${a}+=${b}*n;`, "a,b,n", "a,b")); + maddNew.add(dim, compile(dim, ([a, b, c, o]) => `${o}=${a}+${b}*${c};`, "a,b,c,o=[]", "a,b,c,o", "o")); + maddNewN.add(dim, compile(dim, ([a, b, o]) => `${o}=${a}+${b}*n;`, "a,b,n,o=[]", "a,b,o", "o")); + + abs.add(dim, genOpFnV(dim, "Math.abs")); + sign.add(dim, genOpHofV(dim, _sign)); + sin.add(dim, genOpFnV(dim, "Math.sin")); + cos.add(dim, genOpFnV(dim, "Math.cos")); + floor.add(dim, genOpFnV(dim, "Math.floor")); + ceil.add(dim, genOpFnV(dim, "Math.ceil")); + trunc.add(dim, genOpFnV(dim, "Math.trunc")); + fract.add(dim, genOpHofV(dim, _fract)); + sqrt.add(dim, genOpFnV(dim, "Math.sqrt")); + log.add(dim, genOpFnVV(dim, "Math.log")); + exp.add(dim, genOpFnVV(dim, "Math.exp")); + pow.add(dim, genOpFnVV(dim, "Math.pow")); + powN.add(dim, compile(dim, ([a]) => `${a}=Math.pow(${a},n);`, "a,n", "a")); + + min.add(dim, genOpFnVV(dim, "Math.min")); + max.add(dim, genOpFnVV(dim, "Math.max")); + clamp.add(dim, compileHOF(dim, _clamp, ([a, b, c]) => `${a}=fn(${a},${b},${c});`, "a,b,c")); + + step.add(dim, compileHOF(dim, _step, ([a, e]) => `${a}=fn(${e},${a});`, "a,e")); + smoothStep.add(dim, compileHOF(dim, _smoothStep, ([a, e1, e2]) => `${a}=fn(${e1},${e2},${a});`, "a,e1,e2")); + + mix.add(dim, compile(dim, ([a, b, c]) => `${a}+=(${b}-${a})*${c};`, "a,b,c")); + mixN.add(dim, compile(dim, ([a, b]) => `${a}+=(${b}-${a})*n;`, "a,b,n", "a,b")); + mixNew.add(dim, compile(dim, ([a, b, c, o]) => `${o}=${a}+(${b}-${a})*${c};`, "a,b,c,o=[]", "a,b,c,o", "o")); + mixNewN.add(dim, compile(dim, ([a, b, o]) => `${o}=${a}+(${b}-${a})*n;`, "a,b,n,o=[]", "a,b,o", "o")); +}; diff --git a/packages/vectors2/src/index.ts b/packages/vectors2/src/index.ts new file mode 100644 index 0000000000..11e7eb3259 --- /dev/null +++ b/packages/vectors2/src/index.ts @@ -0,0 +1,3 @@ +export * from "./api"; +export * from "./vec2"; +export * from "./vec3"; diff --git a/packages/vectors2/src/vec2.ts b/packages/vectors2/src/vec2.ts new file mode 100644 index 0000000000..ff0171908a --- /dev/null +++ b/packages/vectors2/src/vec2.ts @@ -0,0 +1,235 @@ +import { Comparator } from "@thi.ng/api"; +import { EPS, HALF_PI, PI } from "@thi.ng/math/api"; +import { eqDelta as _eqDelta } from "@thi.ng/math/eqdelta"; +import { max2id, min2id } from "@thi.ng/math/interval"; +import { declareIndices } from "./accessors"; +import { AVec } from "./avec"; +import { genCommon } from "./codegen"; +import { + magSq, + dot, + Vec, + IVector, + minor, + major, + polar, + mag, + cartesian, + distSq, + distManhattan, + distChebyshev, + headingXY, + angleBetween, + angleRatio, + eqDelta, + Vec2Coord, + VecOpRoVV, + VecOpVVN, + VecOpV, + X4, + Y4, + Z4, + MIN4, + MAX4, + ZERO4, + ONE4, +} from "./api"; + +export class Vec2 extends AVec implements + IVector { + + /** + * Returns array of memory mapped `Vec2` instances using given + * backing array and stride settings: The `cstride` is the step size + * between individual XY vector components. `estride` is the step + * size between successive vectors. This arrangement allows for + * different storage approaches, incl. SOA, AOS, striped / + * interleaved etc. + * + * @param buf backing array + * @param n num vectors + * @param start start index + * @param cstride component stride + * @param estride element stride + */ + static mapBuffer(buf: Vec, n: number = buf.length >> 1, start = 0, cstride = 1, estride = 2) { + const res: Vec2[] = []; + while (--n >= 0) { + res.push(new Vec2(buf, start, cstride)); + start += estride; + } + return res; + } + + /** + * Merges given `src` iterable of `Vec2`s into single array `buf`. + * Vectors will be arranged according to given component and element + * strides, starting at `start` index. It's the user's + * responsibility to ensure the target buffer has sufficient + * capacity to hold the input vectors. See `Vec2.mapBuffer` for the + * inverse operation. Returns `buf`. + * + * @param buf + * @param src + * @param start + * @param cstride + * @param estride + */ + static intoBuffer(buf: Vec, src: Iterable>, start = 0, cstride = 1, estride = 2) { + for (let v of src) { + buf[start] = v[0]; + buf[start + cstride] = v[1]; + start += estride; + } + return buf; + } + + static readonly X_AXIS = new Vec2(X4); + static readonly Y_AXIS = new Vec2(Y4); + static readonly Z_AXIS = new Vec2(Z4); + static readonly MIN = new Vec2(MIN4); + static readonly MAX = new Vec2(MAX4); + static readonly ZERO = new Vec2(ZERO4); + static readonly ONE = new Vec2(ONE4); + + x: number; + y: number; + [id: number]: number; + + constructor(buf?: Vec, i = 0, s = 1) { + super(buf || [0, 0], i, s); + } + + *[Symbol.iterator]() { + yield this.x; + yield this.y; + } + + get length() { + return 2; + } + + copy() { + return new Vec2([this.x, this.y]); + } + + empty() { + return new Vec2(); + } + + eqDelta(v: Readonly, eps = EPS) { + return eqDelta(this, v, eps); + } + + toJSON() { + return [this.x, this.y]; + } + + toString() { + return `[${this.x}, ${this.y}]`; + } +} + +declareIndices(Vec2.prototype, ["x", "y"]); +genCommon(2); + +eqDelta.add(2, (a, b, eps = EPS) => + b.length === 2 && + _eqDelta(a[0], b[0], eps) && + _eqDelta(a[1], b[1], eps) +); + +dot.add(2, (a, b) => a[0] * b[0] + a[1] * b[1]); +magSq.add(2, (a) => a[0] * a[0] + a[1] * a[1]); +distSq.add(2, (a, b) => { + const x = a[0] - b[0]; + const y = a[1] - b[1]; + return x * x + y * y; +}); +distManhattan.add(2, (a, b) => + Math.abs(a[0] - b[0]) + Math.abs(a[1] - b[1])); +distChebyshev.add(2, (a, b) => + Math.max(Math.abs(a[0] - b[0]), Math.abs(a[1] - b[1]))); + +minor.add(2, (a) => min2id(Math.abs(a[0]), Math.abs(a[1]))); +major.add(2, (a) => max2id(Math.abs(a[0]), Math.abs(a[1]))); + +polar.add(2, (a) => { + const x = a[0]; + a[0] = mag(a); + a[1] = Math.atan2(a[1], x); + return a; +}); + +cartesian.add(2, (a, b = Vec2.ZERO) => { + const r = a[0]; + const t = a[1]; + a[0] = r * Math.cos(t) + b[0]; + a[1] = r * Math.sin(t) + b[1]; + return a; +}); + +angleBetween.add(2, (a, b, normalize) => + normalize ? + (a[0] * b[1] < a[1] * b[0] ? -1 : 1) * + Math.acos(angleRatio(a, b)) : + Math.acos(dot(a, b)) +); + +export const vec2 = + (x = 0, y = 0) => new Vec2([x, y]); + +export const asVec2 = + (x: Vec) => + x instanceof Vec2 ? + x : + new Vec2(x.length === 2 ? x : [x[0] || 0, x[1] || 0]); + +export const swizzle2 = (a: Vec, b: Readonly, x: number, y: number) => + (a[0] = b[x] || 0, a[1] = b[y] || 0, a); + +export const comparator2 = + (o1: Vec2Coord, o2: Vec2Coord): Comparator> => + (a, b): number => { + const ax = a[o1]; + const ay = a[o2]; + const bx = b[o1]; + const by = b[o2]; + return ax === bx ? + ay === by ? + 0 : + ay < by ? -2 : 2 : + ax < bx ? -1 : 1; + }; + +export const perpendicularLeft2: VecOpV = (a) => { + const x = a[0]; + a[0] = -a[1]; + a[1] = x; + return a; +}; + +export const perpendicularRight2: VecOpV = (a) => { + const x = -a[0]; + a[0] = a[1]; + a[1] = x; + return a; +}; + +export const rotateAroundPoint2: VecOpVVN = (a, b, theta) => { + const x = a[0] - b[0]; + const y = a[1] - b[1]; + const s = Math.sin(theta); + const c = Math.cos(theta); + a[0] = x * c - y * s + b[0]; + a[1] = x * s + y * c + b[1]; + return a; +}; + +export const cross2: VecOpRoVV = + (a, b) => a[0] * b[1] - a[1] * b[0]; + +export const bisect2: VecOpRoVV = (a, b) => { + const theta = (headingXY(a) + headingXY(b)) / 2; + return theta <= HALF_PI ? theta : PI - theta; +}; diff --git a/packages/vectors2/src/vec3.ts b/packages/vectors2/src/vec3.ts new file mode 100644 index 0000000000..40ee187c2d --- /dev/null +++ b/packages/vectors2/src/vec3.ts @@ -0,0 +1,275 @@ +import { Comparator } from "@thi.ng/api"; +import { EPS } from "@thi.ng/math/api"; +import { eqDelta as _eqDelta } from "@thi.ng/math/eqdelta"; +import { max3id, min3id } from "@thi.ng/math/interval"; +import { declareIndices } from "./accessors"; +import { AVec } from "./avec"; +import { genCommon } from "./codegen"; +import { + magSq, + dot, + Vec, + IVector, + minor, + major, + polar, + cartesian, + distSq, + distManhattan, + distChebyshev, + angleBetween, + angleRatio, + eqDelta, + VecOpVVN, + subNew, + VecOpRoVVV, + VecOpVV, + Vec3Coord, + X4, + Y4, + Z4, + MIN4, + MAX4, + ZERO4, + ONE4, +} from "./api"; + +export class Vec3 extends AVec implements + IVector { + + /** + * Returns array of memory mapped `Vec3` instances using given + * backing array and stride settings: The `cstride` is the step size + * between individual XYZ vector components. `estride` is the step + * size between successive vectors. This arrangement allows for + * different storage approaches, incl. SOA, AOS, striped / + * interleaved etc. + * + * @param buf backing array + * @param n num vectors + * @param start start index + * @param cstride component stride + * @param estride element stride + */ + static mapBuffer(buf: Vec, n: number = (buf.length / 3) | 0, start = 0, cstride = 1, estride = 3) { + const res: Vec3[] = []; + while (--n >= 0) { + res.push(new Vec3(buf, start, cstride)); + start += estride; + } + return res; + } + + /** + * Merges given `src` iterable of `Vec3`s into single array `buf`. + * Vectors will be arranged according to given component and element + * strides, starting at `start` index. It's the user's + * responsibility to ensure the target buffer has sufficient + * capacity to hold the input vectors. See `Vec3.mapBuffer` for the + * inverse operation. Returns `buf`. + * + * @param buf + * @param src + * @param start + * @param cstride + * @param estride + */ + static intoBuffer(buf: Vec, src: Iterable>, start = 0, cstride = 1, estride = 3) { + for (let v of src) { + buf[start] = v[0]; + buf[start + cstride] = v[1]; + buf[start + 2 * cstride] = v[2]; + start += estride; + } + return buf; + } + + static readonly X_AXIS = new Vec3(X4); + static readonly Y_AXIS = new Vec3(Y4); + static readonly Z_AXIS = new Vec3(Z4); + static readonly MIN = new Vec3(MIN4); + static readonly MAX = new Vec3(MAX4); + static readonly ZERO = new Vec3(ZERO4); + static readonly ONE = new Vec3(ONE4); + + x: number; + y: number; + z: number; + [id: number]: number; + + constructor(buf?: Vec, i = 0, s = 1) { + super(buf || [0, 0, 0], i, s); + } + + *[Symbol.iterator]() { + yield this.x; + yield this.y; + yield this.z; + } + + get length() { + return 3; + } + + copy() { + return new Vec3([this.x, this.y, this.z]); + } + + empty() { + return new Vec3(); + } + + eqDelta(v: Readonly, eps = EPS) { + return eqDelta(this, v, eps); + } + + toJSON() { + return [this.x, this.y]; + } + + toString() { + return `[${this.x}, ${this.y}, ${this.z}]`; + } +} + +declareIndices(Vec3.prototype, ["x", "y", "z"]); +genCommon(2); + +eqDelta.add(3, (a, b, eps = EPS) => + b.length == 3 && + _eqDelta(a[0], b[0], eps) && + _eqDelta(a[1], b[1], eps) && + _eqDelta(a[2], b[2], eps) +); + +dot.add(3, (a, b) => a[0] * b[0] + a[1] * b[1] + a[2] * b[2]); + +magSq.add(3, (a) => a[0] * a[0] + a[1] * a[1] + a[2] * a[2]); + +distSq.add(3, (a, b) => { + const x = a[0] - b[0]; + const y = a[1] - b[1]; + const z = a[2] - b[2]; + return x * x + y * y + z * z; +}); + +distManhattan.add(3, (a, b) => + Math.abs(a[0] - b[0]) + + Math.abs(a[1] - b[1]) + + Math.abs(a[2] - b[2]) +); + +distChebyshev.add(3, (a, b) => + Math.max( + Math.abs(a[0] - b[0]), + Math.abs(a[1] - b[1]), + Math.abs(a[2] - b[2]) + ) +); + +minor.add(3, (a) => + min3id(Math.abs(a[0]), Math.abs(a[1]), Math.abs(a[2]))); + +major.add(3, (a) => + max3id(Math.abs(a[0]), Math.abs(a[1]), Math.abs(a[2]))); + +polar.add(3, (a) => { + const x = a[0]; + const y = a[1]; + const z = a[2]; + const r = Math.sqrt(x * x + y * y + z * z); + a[0] = r; + a[1] = Math.asin(z / r); + a[2] = Math.atan2(y, x); + return a; +}); + +cartesian.add(3, (a, b = Vec3.ZERO) => { + const r = a[0]; + const theta = a[1]; + const phi = a[2]; + const ct = Math.cos(theta); + + a[0] = r * ct * Math.cos(phi) + b[0]; + a[1] = r * ct * Math.sin(phi) + b[1]; + a[2] = r * Math.sin(theta) + b[2]; + return a; +}); + +angleBetween.add(3, (a, b, normalize) => + normalize ? + (a[0] * b[1] < a[1] * b[0] ? -1 : 1) * + Math.acos(angleRatio(a, b)) : + Math.acos(dot(a, b)) +); + +export const vec3 = + (x = 0, y = 0, z = 0) => new Vec3([x, y, z]); + +export const asVec3 = + (x: Vec) => + x instanceof Vec3 ? + x : + new Vec3(x.length === 3 ? x : [x[0] || 0, x[1] || 0, x[2] || 0]); + +export const swizzle3 = + (a: Vec, b: Readonly, x: number, y: number, z: number) => + (a[0] = b[x] || 0, a[1] = b[y] || 0, a[2] = b[z] || 0, a); + +export const comparator3 = + (o1: Vec3Coord, o2: Vec3Coord, o3: Vec3Coord): Comparator> => + (a, b): number => { + const ax = a[o1]; + const ay = a[o2]; + const az = a[o3]; + const bx = b[o1]; + const by = b[o2]; + const bz = b[o3]; + return ax === bx ? + ay === by ? + az === bz ? + 0 : + az < bz ? -3 : 3 : + ay < by ? -2 : 2 : + ax < bx ? -1 : 1; + }; + +export const rotateAroundAxis3: VecOpVVN = + (v, axis, theta) => { + const x = v[0]; + const y = v[1]; + const z = v[2]; + const ax = axis[0]; + const ay = axis[1]; + const az = axis[2]; + const ux = ax * x; + const uy = ax * y; + const uz = ax * z; + const vx = ay * x; + const vy = ay * y; + const vz = ay * z; + const wx = az * x; + const wy = az * y; + const wz = az * z; + const uvw = ux + vy + wz; + const s = Math.sin(theta); + const c = Math.cos(theta); + + v[0] = (ax * uvw + (x * (ay * ay + az * az) - ax * (vy + wz)) * c + (-wy + vz) * s); + v[1] = (ay * uvw + (y * (ax * ax + az * az) - ay * (ux + wz)) * c + (wx - uz) * s); + v[2] = (az * uvw + (z * (ax * ax + ay * ay) - az * (ux + vy)) * c + (-vx + uy) * s); + return v; + }; + +export const cross3: VecOpVV = + (a, b) => { + const x = a[1] * b[2] - a[2] * b[1]; + const y = a[2] * b[0] - a[0] * b[2]; + a[2] = a[0] * b[1] - a[1] * b[0]; + a[1] = y; + a[0] = x; + return a; + }; + +export const orthoNormal3: VecOpRoVVV = (a: Vec, b: Vec, c: Vec) => + cross3(subNew(c, a), subNew(b, a)); diff --git a/packages/vectors2/src/vop.ts b/packages/vectors2/src/vop.ts new file mode 100644 index 0000000000..cdd881afc5 --- /dev/null +++ b/packages/vectors2/src/vop.ts @@ -0,0 +1,18 @@ +import { unsupported } from "@thi.ng/errors/unsupported"; + +/** + * Specialized / optimized version of `@thi.ng/defmulti` for vector + * operations. Uses hardcoded logic to dispatch on length (vector size) + * of first argument. + */ +export const vop = () => { + const impls = new Array(5); + let fallback; + const fn = (...args) => { + const g = impls[args[0].length] || fallback; + return g ? g(...args) : unsupported(`no impl for vec size ${args[0].length}`); + }; + fn.add = (dim: number, fn) => (impls[dim] = fn); + fn.default = (fn) => (fallback = fn); + return fn; +}; diff --git a/packages/vectors2/test/index.ts b/packages/vectors2/test/index.ts new file mode 100644 index 0000000000..cea49f3372 --- /dev/null +++ b/packages/vectors2/test/index.ts @@ -0,0 +1,6 @@ +// import * as assert from "assert"; +// import * as v from "../src/index"; + +describe("vectors2", () => { + it("tests pending"); +}); diff --git a/packages/vectors2/test/tsconfig.json b/packages/vectors2/test/tsconfig.json new file mode 100644 index 0000000000..bcf29ace54 --- /dev/null +++ b/packages/vectors2/test/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "../build" + }, + "include": [ + "./**/*.ts", + "../src/**/*.ts" + ] +} diff --git a/packages/vectors2/tsconfig.json b/packages/vectors2/tsconfig.json new file mode 100644 index 0000000000..5a76bc343b --- /dev/null +++ b/packages/vectors2/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": ".", + "target": "es6" + }, + "include": [ + "./src/**/*.ts" + ] +} \ No newline at end of file From fde2db215d23f66502b6bf778eea3964c885d672 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 25 Oct 2018 11:53:59 +0100 Subject: [PATCH 002/333] feat(defmulti): add callable() & implementations(), update readme --- packages/defmulti/README.md | 45 +++++++++++++++++++++++++++++---- packages/defmulti/src/index.ts | 38 ++++++++++++++++++++++++++++ packages/defmulti/test/index.ts | 20 ++++++++++++++- 3 files changed, 97 insertions(+), 6 deletions(-) diff --git a/packages/defmulti/README.md b/packages/defmulti/README.md index f8ad7219cb..19758c7ce5 100644 --- a/packages/defmulti/README.md +++ b/packages/defmulti/README.md @@ -28,7 +28,7 @@ yarn add @thi.ng/defmulti ## API -### defmulti +### defmulti() `defmulti` returns a new multi-dispatch function using the provided dispatcher function. The dispatcher acts as a mapping function, can take @@ -43,9 +43,17 @@ return type) and the generics will also apply to all implementations. If more than 8 args are required, `defmulti` will fall back to an untyped varargs solution. -Implementations for different dispatch values can be added and removed -dynamically by calling `.add(id, fn)` or `.remove(id)` on the returned -function. +The function returned by `defmulti` can be called like any other function, but also exposes the following operations: + +- `.add(id, fn)` - adds new implementation for given dispatch value +- `.remove(id)` - removes implementation for dispatch value +- `.callable(...args)` - takes same args as if calling the + multi-function, but only checks if an implementation exists for the + given args. Returns boolean. +- `.isa(child, parent)` - establish dispatch value relationship hierarchy +- `.rels()` - return all dispatch value relationships +- `.parents(id)` - direct parents of dispatch value `id` +- `.ancestors(id)` - transitive parents of dispatch value `id` #### Dispatch value hierarchies @@ -105,7 +113,34 @@ foo.rels(); // even: Set { "number" } } ``` -### defmultiN +### implementations() + +Intended for multi-methods sharing same dispatch values / logic. +Takes a dispatch value and a number of multi-methods, each with an +implementation for the given dispatch value. Then for each +multi-method associates the related implementation with the given +dispatch value. + +```ts +const foo = defmulti((x) => x.id); +const bar = defmulti((x) => x.id); + +// batch define implementations for dispatch value "a" +implementations( + "a", + + foo, + (x) => `foo: ${x.val}`, + + bar, + (x) => `bar: ${x.val.toUpperCase()}` +); + +foo({ id: "a", val: "alice" }); // "foo: alice" +bar({ id: "a", val: "alice" }); // "bar: ALICE" +``` + +### defmultiN() Returns a multi-dispatch function which delegates to one of the provided implementations, based on the arity (number of args) when the function diff --git a/packages/defmulti/src/index.ts b/packages/defmulti/src/index.ts index 0f734eb8a2..6f0030c8d2 100644 --- a/packages/defmulti/src/index.ts +++ b/packages/defmulti/src/index.ts @@ -1,4 +1,5 @@ import { IObjectOf } from "@thi.ng/api/api"; +import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; import { unsupported } from "@thi.ng/errors/unsupported"; import { illegalArity } from "@thi.ng/errors/illegal-arity"; @@ -27,6 +28,7 @@ export type Implementation8 = (a: A, b: B, c: C, d: D export interface MultiFnBase { add(id: PropertyKey, g: I): boolean; remove(id: PropertyKey): boolean; + callable(...args: any[]): boolean; isa(id: PropertyKey, parent: PropertyKey); rels(): IObjectOf>; parents(id: PropertyKey): Set; @@ -117,6 +119,10 @@ export function defmulti(f: any, ancestors?: AncestorDefs): MultiFn { delete impls[id]; return true; }; + fn.callable = (...args: any[]) => { + const id = f(...args); + return !!(impls[id] || findImpl(impls, rels, id) || impls[DEFAULT]); + }; fn.isa = (id: PropertyKey, parent: PropertyKey) => { let val = rels[id]; !val && (rels[id] = val = new Set()); @@ -199,3 +205,35 @@ export function defmultiN(impls: { [id: number]: Implementation }) { } return fn; } + +/** + * Intended for multi-methods sharing same dispatch values / logic. + * Takes a dispatch value and a number of multi-methods, each with an + * implementation for the given dispatch value. Then for each + * multi-method associates the related implementation with the given + * dispatch value. + * + * ``` + * foo = defmulti((x) => x.id); + * bar = defmulti((x) => x.id); + * + * implementations( + * "a", + * + * foo, (x) => `foo: ${x.val}`, + * bar, (x) => `bar: ${x.val.toUpperCase()}` + * ) + * + * foo({ id: "a", val: "alice" }); // "foo: alice" + * bar({ id: "a", val: "alice" }); // "bar: ALICE" + * ``` + * + * @param type + * @param impls + */ +export const implementations = (type: PropertyKey, ...impls: (MultiFn | Implementation)[]) => { + (impls.length & 1) && illegalArgs("require an even number of implementation items"); + for (let i = 0; i < impls.length; i += 2) { + (>impls[i]).add(type, impls[i + 1]); + } +}; diff --git a/packages/defmulti/test/index.ts b/packages/defmulti/test/index.ts index 41e17b28ef..7567e4a1e8 100644 --- a/packages/defmulti/test/index.ts +++ b/packages/defmulti/test/index.ts @@ -1,5 +1,5 @@ import * as assert from "assert"; -import { DEFAULT, defmulti, defmultiN } from "../src/index"; +import { DEFAULT, defmulti, defmultiN, implementations } from "../src/index"; describe("defmulti", () => { it("flatten", () => { @@ -81,6 +81,9 @@ describe("defmulti", () => { }, "foo rels"); assert.equal(foo(23), "odd"); assert.equal(foo(42), "number"); + assert(foo.callable(23)); + assert(foo.callable(42)); + assert(!foo.callable(66)); assert.throws(() => foo(66), "no default"); foo.add(DEFAULT, (x) => -x); assert.equal(foo(66), -66); @@ -98,4 +101,19 @@ describe("defmulti", () => { "even": new Set(["number"]), }, "bar rels"); }); + + it("implementations", () => { + const foo = defmulti((x) => x.id); + const bar = defmulti((x) => x.id); + + implementations( + "a", + + foo, (x) => `foo: ${x.val}`, + bar, (x) => `bar: ${x.val.toUpperCase()}` + ) + + assert.equal(foo({ id: "a", val: "alice" }), "foo: alice"); + assert.equal(bar({ id: "a", val: "alice" }), "bar: ALICE"); + }); }); From 505ca49c7f60e639f16ca35161521f2eee2bfcf4 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 25 Oct 2018 13:38:31 +0100 Subject: [PATCH 003/333] feat(vectors): add vec2n/vec3n(), copy() methods, update deps --- packages/vectors2/package.json | 2 +- packages/vectors2/src/api.ts | 2 ++ packages/vectors2/src/vec2.ts | 3 +++ packages/vectors2/src/vec3.ts | 3 +++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/vectors2/package.json b/packages/vectors2/package.json index fb8438b033..4884eb8e7c 100644 --- a/packages/vectors2/package.json +++ b/packages/vectors2/package.json @@ -29,7 +29,7 @@ }, "dependencies": { "@thi.ng/api": "^4.2.3", - "@thi.ng/malloc": "^0.1.0", + "@thi.ng/malloc": "^0.1.1", "@thi.ng/math": "^0.2.0" }, "keywords": [ diff --git a/packages/vectors2/src/api.ts b/packages/vectors2/src/api.ts index d2de8400de..72b7866a19 100644 --- a/packages/vectors2/src/api.ts +++ b/packages/vectors2/src/api.ts @@ -75,6 +75,8 @@ export type Vec4Coord = 0 | 1 | 2 | 3; export const set: MultiVecOpVV = vop(); export const setN: MultiVecOpVN = vop(); export const setS: MultiVecOpV = vop(); +export const copy: MultiVecOpV = vop(); +copy.default((v) => [...v]); export const zero = (a: Vec) => setN(a, 0); export const one = (a: Vec) => setN(a, 1); diff --git a/packages/vectors2/src/vec2.ts b/packages/vectors2/src/vec2.ts index ff0171908a..93cdc8eeb0 100644 --- a/packages/vectors2/src/vec2.ts +++ b/packages/vectors2/src/vec2.ts @@ -179,6 +179,9 @@ angleBetween.add(2, (a, b, normalize) => export const vec2 = (x = 0, y = 0) => new Vec2([x, y]); +export const vec2n = + (n: number) => new Vec2([n, n]); + export const asVec2 = (x: Vec) => x instanceof Vec2 ? diff --git a/packages/vectors2/src/vec3.ts b/packages/vectors2/src/vec3.ts index 40ee187c2d..e1d5eef474 100644 --- a/packages/vectors2/src/vec3.ts +++ b/packages/vectors2/src/vec3.ts @@ -206,6 +206,9 @@ angleBetween.add(3, (a, b, normalize) => export const vec3 = (x = 0, y = 0, z = 0) => new Vec3([x, y, z]); +export const vec3n = + (n: number) => new Vec3([n, n, n]); + export const asVec3 = (x: Vec) => x instanceof Vec3 ? From 252f66db2e75098ef9eeb56032faf2542735b263 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 25 Oct 2018 13:42:02 +0100 Subject: [PATCH 004/333] feat(geom): re-add more classes & methods, add svg conversions --- packages/geom2/package.json | 7 +- packages/geom2/src/api.ts | 198 ++++++++++++++++----- packages/geom2/src/circle.ts | 65 +++++++ packages/geom2/src/circle2.ts | 25 --- packages/geom2/src/container2.ts | 29 +++ packages/geom2/src/group.ts | 24 +++ packages/geom2/src/index.ts | 10 +- packages/geom2/src/internal/bounds.ts | 32 ++++ packages/geom2/src/internal/corner.ts | 38 ++++ packages/geom2/src/internal/graham-scan.ts | 38 ++++ packages/geom2/src/polygon.ts | 14 ++ packages/geom2/src/quad.ts | 13 ++ packages/geom2/src/rect.ts | 51 ++++++ packages/geom2/src/rect2.ts | 30 ---- packages/geom2/src/svg.ts | 19 ++ 15 files changed, 494 insertions(+), 99 deletions(-) create mode 100644 packages/geom2/src/circle.ts delete mode 100644 packages/geom2/src/circle2.ts create mode 100644 packages/geom2/src/container2.ts create mode 100644 packages/geom2/src/group.ts create mode 100644 packages/geom2/src/internal/bounds.ts create mode 100644 packages/geom2/src/internal/corner.ts create mode 100644 packages/geom2/src/internal/graham-scan.ts create mode 100644 packages/geom2/src/polygon.ts create mode 100644 packages/geom2/src/quad.ts create mode 100644 packages/geom2/src/rect.ts delete mode 100644 packages/geom2/src/rect2.ts create mode 100644 packages/geom2/src/svg.ts diff --git a/packages/geom2/package.json b/packages/geom2/package.json index df4d1830fd..8b6b9697f5 100644 --- a/packages/geom2/package.json +++ b/packages/geom2/package.json @@ -29,8 +29,11 @@ }, "dependencies": { "@thi.ng/api": "^4.2.3", - "@thi.ng/defmulti": "^0.4.1", - "@thi.ng/malloc": "^0.1.0", + "@thi.ng/checks": "^1.5.13", + "@thi.ng/defmulti": "^0.5.0", + "@thi.ng/hiccup": "^2.4.3", + "@thi.ng/hiccup-svg": "^2.0.4", + "@thi.ng/malloc": "^0.1.1", "@thi.ng/math": "^0.2.0", "@thi.ng/vectors2": "^0.0.1" }, diff --git a/packages/geom2/src/api.ts b/packages/geom2/src/api.ts index 8eac58994e..902d5cd436 100644 --- a/packages/geom2/src/api.ts +++ b/packages/geom2/src/api.ts @@ -1,23 +1,30 @@ -import { defmulti, DEFAULT } from "@thi.ng/defmulti"; -import { Vec } from "@thi.ng/vectors2/api"; -import { IObjectOf, ICopy } from "@thi.ng/api"; - -import "@thi.ng/vectors2/vec2"; -import { asVec2, Vec2 } from "@thi.ng/vectors2/vec2"; +import { ICopy, IObjectOf } from "@thi.ng/api"; +import { DEFAULT, defmulti } from "@thi.ng/defmulti"; +import { IVector, subNew, Vec } from "@thi.ng/vectors2/api"; +import { asVec2, Vec2, vec2 } from "@thi.ng/vectors2/vec2"; export enum Type { CIRCLE2 = "circle", - RECT2 = "rect", + GROUP = "g", + LINE2 = "line", + PATH2 = "path", + POINTS2 = "points", POLYGON2 = "polygon", + POLYLINE2 = "polyline", QUAD2 = "quad", + RECT2 = "rect", + TRIANGLE2 = "triangle", } -export interface Shape { +export const DEFAULT_SAMPLES = 20; + +export interface Shape extends + ICopy { readonly type: string; attribs?: IObjectOf; } -export interface AABB extends Shape { +export interface AABBLike extends Shape { pos: Vec; size: Vec; } @@ -27,21 +34,42 @@ export type Attribs = IObjectOf; const dispatch = (x: Shape) => x.type; export const area = defmulti(dispatch); + export const arcLength = defmulti(dispatch); -export const bounds = defmulti(dispatch); -export const width = defmulti(dispatch); -export const height = defmulti(dispatch); +export const asPolygon = defmulti(dispatch); + +export const asPolyline = defmulti(dispatch); + +export const bounds = defmulti(dispatch); + +export const center = defmulti(dispatch); + +export const centroid = defmulti(dispatch); + +export const classifyPoint = defmulti(dispatch); + export const depth = defmulti(dispatch); -width.add(DEFAULT, (x) => bounds(x).size[0]); -height.add(DEFAULT, (x) => bounds(x).size[0]); depth.add(DEFAULT, (x) => bounds(x).size[2] || 0); -export const centroid = defmulti(dispatch); -export const center = defmulti(dispatch); +export const difference = defmulti(dispatch); + +// TODO add options type +export const extrude = defmulti(dispatch); + +export const height = defmulti(dispatch); +height.add(DEFAULT, (x) => bounds(x).size[1]); + +export const intersect = defmulti(dispatch); + +export const union = defmulti(dispatch); + export const vertices = defmulti(dispatch); -export class HShape extends Array implements +export const width = defmulti(dispatch); +width.add(DEFAULT, (x) => bounds(x).size[0]); + +export abstract class AShape extends Array implements Shape { constructor(type: string, attribs: Attribs, ...xs: any[]) { @@ -59,9 +87,40 @@ export class HShape extends Array implements set attribs(attr: Attribs) { this[1] = attr; } + + abstract copy(): Shape; } -export class Circle2 extends HShape implements +/** + * [type, {}, points] + */ +export class PointContainer> extends AShape { + + constructor(type: Type, points: Vec[], attribs?: Attribs) { + super(type, attribs, points); + } + + get points(): T[] { + return this[2]; + } + + set points(pts: T[]) { + this[2] = pts; + } + + copy() { + return new PointContainer( + this.type, + this.points.map((p) => p.copy()), + { ...this.attribs } + ); + } +} + +/** + * ["circle", {}, pos, r] + */ +export class Circle2 extends AShape implements ICopy { constructor(pos: Vec, r: number, attribs?: Attribs) { @@ -89,34 +148,56 @@ export class Circle2 extends HShape implements } } -export class Rect2 extends HShape implements AABB { +/** + * ["circle", {}, pos, r] + */ +export class Group2 extends AShape implements + ICopy { - constructor(pos: Vec, size: Vec, attribs?: Attribs) { - super(Type.RECT2, attribs, asVec2(pos), asVec2(size)); + constructor(attribs?: Attribs, ...children: Shape[]) { + super(Type.GROUP, attribs, children); } - get pos(): Vec2 { + copy() { + return new Group2({ ...this.attribs }, ...this.children.map((c) => c.copy())); + } + + get children(): Shape[] { return this[2]; } - set pos(v: Vec2) { - this[2] = v; + set children(children: Shape[]) { + this[2] = children; } +} - get size(): Vec2 { - return this[3]; +/** + * ``` + * ["polygon", {}, points] + * ``` + */ +export class Polygon2 extends PointContainer implements + ICopy { + + constructor(points: Vec[], attribs?: Attribs) { + super(Type.POLYGON2, points.map(asVec2), attribs); } - set size(v: Vec2) { - this[3] = v; + copy() { + return new Polygon2(this.points, { ...this.attribs }); } } -export class Quad2 extends HShape implements +/** + * ``` + * ["quad", {}, points] + * ``` + */ +export class Quad2 extends PointContainer implements ICopy { constructor(points: Vec[], attribs?: Attribs) { - super(Type.POLYGON2, attribs, points.map(asVec2)); + super(Type.POLYGON2, points.map(asVec2), attribs); } copy() { @@ -126,21 +207,58 @@ export class Quad2 extends HShape implements get type() { return Type.QUAD2; } +} + +/** + * ``` + * ["rect", {}, pos, size] + * ``` + */ +export class Rect2 extends AShape implements + AABBLike, + ICopy { + + static fromMinMax(min: Vec, max: Vec) { + return new Rect2(min, subNew(max, min, vec2())); + } - get points(): Vec2[] { + constructor(pos: Vec, size: Vec, attribs?: Attribs) { + super(Type.RECT2, attribs, asVec2(pos), asVec2(size)); + } + + copy() { + return new Rect2(this.pos.copy(), this.size.copy(), { ...this.attribs }); + } + + get pos(): Vec2 { return this[2]; } - set points(pts: Vec2[]) { - this[3] = pts; + set pos(v: Vec2) { + this[2] = v; + } + + get size(): Vec2 { + return this[3]; + } + + set size(v: Vec2) { + this[3] = v; } } -// traverse until no further link is found or stop if an impl is found -// e.g. quad -> polygon -> container -// TODO add to defmulti +export class Triangle2 extends PointContainer implements + ICopy { + + constructor(points: Vec[], attribs?: Attribs) { + super(Type.POLYGON2, points.map(asVec2), attribs); + } + + copy() { + return new Triangle2(this.points, { ...this.attribs }); + } -// const hierarchy = { -// [Type.QUAD2]: [Type.POLYGON2,...], -// [Type.POLYGON2]: [Type.CONTAINER2,...] -// }; + get type() { + return Type.TRIANGLE2; + } +} diff --git a/packages/geom2/src/circle.ts b/packages/geom2/src/circle.ts new file mode 100644 index 0000000000..827989e92d --- /dev/null +++ b/packages/geom2/src/circle.ts @@ -0,0 +1,65 @@ +import { isNumber } from "@thi.ng/checks/is-number"; +import { implementations } from "@thi.ng/defmulti"; +import { PI, TAU } from "@thi.ng/math/api"; +import { subNewN, Vec, cartesian } from "@thi.ng/vectors2/api"; +import { vec2n, vec2 } from "@thi.ng/vectors2/vec2"; +import { + arcLength, + area, + bounds, + centroid, + Circle2, + Type, + Attribs, + Rect2, + vertices, + Polygon2, + asPolygon, + DEFAULT_SAMPLES, +} from "./api"; + +export function circle2(pos: Vec, r = 1, attribs?: Attribs): Circle2 { + return new Circle2(pos, r, attribs); +} + +implementations( + Type.CIRCLE2, + + area, + (x: Circle2) => PI * x.r * x.r, + + arcLength, + (x: Circle2) => TAU * x.r, + + asPolygon, + (x: Circle2, opts) => new Polygon2(vertices(x, opts), { ...x.attribs }), + + bounds, + (x: Circle2) => new Rect2(subNewN(x.pos, x.r), vec2n(x.r * 2)), + + centroid, + (x: Circle2) => x.pos, + + vertices, + (x: Circle2, opts) => { + const buf: Vec[] = []; + const pos = x.pos; + const r = x.r; + let [num, last] = isNumber(opts) ? + [opts, false] : + [ + opts.theta ? + Math.floor(TAU / opts.theta) : + opts.dist ? + Math.floor(TAU / (opts.dist / r)) : + opts.num || DEFAULT_SAMPLES, + opts.last === true + ]; + const delta = TAU / num; + last && num++; + for (let i = 0; i < num; i++) { + buf[i] = cartesian(vec2(r, i * delta), pos); + } + return buf; + } +); diff --git a/packages/geom2/src/circle2.ts b/packages/geom2/src/circle2.ts deleted file mode 100644 index 423ed22af9..0000000000 --- a/packages/geom2/src/circle2.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { PI, TAU } from "@thi.ng/math/api"; -import { subNewN, Vec } from "@thi.ng/vectors2/api"; -import { asVec2, vec2 } from "@thi.ng/vectors2/vec2"; -import { - arcLength, - area, - bounds, - centroid, - Circle2, - Type, - Attribs, - Rect2, -} from "./api"; - -export function circle2(pos: Vec, r = 1, attribs?: Attribs): Circle2 { - return new Circle2(asVec2(pos), r, attribs); -} - -area.add(Type.CIRCLE2, (x: Circle2) => PI * x.r * x.r); - -arcLength.add(Type.CIRCLE2, (x: Circle2) => TAU * x.r); - -bounds.add(Type.CIRCLE2, (x: Circle2) => new Rect2(subNewN(x.pos, x.r), vec2(x.r * 2, x.r * 2))); - -centroid.add(Type.CIRCLE2, (x: Circle2) => x.pos); diff --git a/packages/geom2/src/container2.ts b/packages/geom2/src/container2.ts new file mode 100644 index 0000000000..e1debb6058 --- /dev/null +++ b/packages/geom2/src/container2.ts @@ -0,0 +1,29 @@ +import { Vec } from "@thi.ng/vectors2/api"; +import { Vec2 } from "@thi.ng/vectors2/vec2"; +import { + Attribs, + bounds, + PointContainer, + Rect2, + Type, + vertices +} from "./api"; +import { bounds as _bounds } from "./internal/bounds"; +import { implementations } from "@thi.ng/defmulti"; + +export function points(points: Vec[], attribs?: Attribs) { + return new PointContainer(Type.POINTS2, points, attribs); +}; + +implementations( + Type.POINTS2, + + bounds, + (x: PointContainer) => { + const b = _bounds(x.points, Vec2.MAX.copy(), Vec2.MIN.copy()); + return Rect2.fromMinMax(b[0], b[1]); + }, + + vertices, + (x: PointContainer) => x.points +); diff --git a/packages/geom2/src/group.ts b/packages/geom2/src/group.ts new file mode 100644 index 0000000000..458290bc6b --- /dev/null +++ b/packages/geom2/src/group.ts @@ -0,0 +1,24 @@ +import { implementations } from "@thi.ng/defmulti"; +import { + area, + Attribs, + bounds, + Group2, + Shape, + Type +} from "./api"; +import { collBounds } from "./internal/bounds"; + +export function group(attribs?: Attribs, ...children: Shape[]) { + return new Group2(attribs, ...children); +} + +implementations( + Type.GROUP, + + area, + (g: Group2) => area(bounds(g)), + + bounds, + (g: Group2) => collBounds(g.children), +); diff --git a/packages/geom2/src/index.ts b/packages/geom2/src/index.ts index d67a96f039..4c7d6abef7 100644 --- a/packages/geom2/src/index.ts +++ b/packages/geom2/src/index.ts @@ -1,3 +1,9 @@ export * from "./api"; -export * from "./circle2"; -export * from "./rect2"; +export * from "./circle"; +export * from "./container2"; +export * from "./group"; +export * from "./polygon"; +export * from "./quad"; +export * from "./rect"; + +export * from "./svg"; diff --git a/packages/geom2/src/internal/bounds.ts b/packages/geom2/src/internal/bounds.ts new file mode 100644 index 0000000000..bf69f114e8 --- /dev/null +++ b/packages/geom2/src/internal/bounds.ts @@ -0,0 +1,32 @@ +import { max, min, Vec, addNew, sub } from "@thi.ng/vectors2/api"; +import { bounds as _bounds, Shape, union } from "../api"; + +export const bounds = + (pts: ReadonlyArray, vmin: Vec, vmax: Vec): [Vec, Vec] => { + + for (let i = pts.length; --i >= 0;) { + const p = pts[i]; + min(vmin, p); + max(vmax, p); + } + return [vmin, vmax]; + }; + +export const collBounds = + (shapes: Shape[]) => { + + let n = shapes.length - 1; + let res: Shape = n >= 0 ? _bounds(shapes[n]) : undefined; + for (; --n >= 0;) { + res = union(res, _bounds(shapes[n])); + } + return res; + }; + +export const unionBounds = + (pos1: Vec, size1: Vec, pos2: Vec, size2: Vec): [Vec, Vec] => { + const p = addNew(pos1, size1); + const q = addNew(pos2, size2); + const pos = min([...pos1], pos2); + return [pos, sub(max(p, q), pos)] + }; diff --git a/packages/geom2/src/internal/corner.ts b/packages/geom2/src/internal/corner.ts new file mode 100644 index 0000000000..aac56f7e7d --- /dev/null +++ b/packages/geom2/src/internal/corner.ts @@ -0,0 +1,38 @@ +import { sign } from "@thi.ng/math/abs"; +import { EPS } from "@thi.ng/math/api"; +import { Vec } from "@thi.ng/vectors2/api"; + +export const corner = + (a: Readonly, b: Readonly, c: Readonly) => { + const ax = a[0]; + const ay = a[1]; + return (b[0] - ax) * (c[1] - ay) - (c[0] - ax) * (b[1] - ay); + }; + +export const classify = + (a: Readonly, b: Readonly, c: Readonly, eps = EPS) => + sign(corner(a, b, c), eps); + +export const clockwise2 = + (a: Readonly, b: Readonly, c: Readonly) => + corner(a, b, c) < 0; + +export const classifyPointInTriangle2 = + (p: Readonly, a: Readonly, b: Readonly, c: Readonly) => { + const s = clockwise2(a, b, c) ? 1 : -1; + return sign( + Math.min( + s * corner(a, c, p), + s * corner(b, a, p), + s * corner(c, b, p) + ) + ); + }; + +export const pointInTriangle2 = + (p: Readonly, a: Readonly, b: Readonly, c: Readonly) => { + const s = clockwise2(a, b, c) ? 1 : -1; + return s * corner(a, c, p) >= 0 && + s * corner(b, a, p) >= 0 && + s * corner(c, b, p) >= 0; + }; diff --git a/packages/geom2/src/internal/graham-scan.ts b/packages/geom2/src/internal/graham-scan.ts new file mode 100644 index 0000000000..9506ee2271 --- /dev/null +++ b/packages/geom2/src/internal/graham-scan.ts @@ -0,0 +1,38 @@ +import { Vec } from "@thi.ng/vectors2/api"; +import { corner } from "./corner"; +import { comparator2 } from "@thi.ng/vectors2/vec2"; + +/** + * Returns array of points defining the 2D Convex Hull of `pts` using + * the Graham Scan method. + * + * https://en.wikipedia.org/wiki/Graham_scan + * + * @param pts + */ +export const convexHull2 = (pts: ReadonlyArray) => { + const num = pts.length; + const res: Vec[] = []; + let h = 0, i; + pts = pts.slice().sort(comparator2(0, 1)); + + const scan = (p: Vec, thresh: number) => { + while (h >= thresh && corner(res[h - 2], res[h - 1], p) >= 0) { + res.pop(); + h--; + } + res[h++] = p; + }; + + for (i = 0; i < num; i++) { + scan(pts[i], 2); + } + res.pop(); + h--; + const h2 = h + 2; + for (i = num - 1; i >= 0; i--) { + scan(pts[i], h2); + } + res.pop(); + return res; +}; diff --git a/packages/geom2/src/polygon.ts b/packages/geom2/src/polygon.ts new file mode 100644 index 0000000000..0c7828ffd6 --- /dev/null +++ b/packages/geom2/src/polygon.ts @@ -0,0 +1,14 @@ +import { Polygon2, Attribs, Type, bounds } from "./api"; +import { Vec } from "@thi.ng/vectors2/api"; +import { convexHull2 } from "./internal/graham-scan"; + +export function polygon(points: Vec[], attribs?: Attribs): Polygon2 { + return new Polygon2(points, attribs); +} + +const type = Type.POLYGON2; + +bounds.isa(type, Type.POINTS2); + +export const convexHull = (poly: Polygon2) => + convexHull2(poly.points); diff --git a/packages/geom2/src/quad.ts b/packages/geom2/src/quad.ts new file mode 100644 index 0000000000..1d9df64aad --- /dev/null +++ b/packages/geom2/src/quad.ts @@ -0,0 +1,13 @@ +import { Quad2, Attribs, bounds, Type, centroid, area, vertices } from "./api"; +import { Vec } from "@thi.ng/vectors2/api"; + +export function quad(points: Vec[], attribs?: Attribs): Quad2 { + return new Quad2(points, attribs); +} + +const type = Type.QUAD2; + +area.isa(type, Type.POLYGON2); +bounds.isa(type, Type.POINTS2); +centroid.isa(type, Type.POLYGON2); +vertices.isa(type, Type.POINTS2); diff --git a/packages/geom2/src/rect.ts b/packages/geom2/src/rect.ts new file mode 100644 index 0000000000..e14a7c0267 --- /dev/null +++ b/packages/geom2/src/rect.ts @@ -0,0 +1,51 @@ +import { implementations } from "@thi.ng/defmulti"; +import { addNew, maddNewN, Vec } from "@thi.ng/vectors2/api"; +import { Vec2, vec2 } from "@thi.ng/vectors2/vec2"; +import { + arcLength, + area, + asPolygon, + Attribs, + bounds, + centroid, + Polygon2, + Rect2, + Type, + union, + vertices +} from "./api"; +import { unionBounds } from "./internal/bounds"; + +export function rect(pos: Vec, size: Vec, attribs?: Attribs): Rect2 { + return new Rect2(pos, size, attribs); +} + +implementations( + Type.RECT2, + + area, + (x: Rect2) => x.size[0] * x.size[1], + + arcLength, + (x: Rect2) => 2 * (x.size[0] + x.size[1]), + + asPolygon, + (x: Rect2) => new Polygon2(vertices(x), { ...x.attribs }), + + bounds, + (x: Rect2) => x, + + centroid, + (x: Rect2, o = vec2()) => maddNewN(x.pos, x.size, 0.5, o), + + union, + (r1: Rect2, r2: Rect2) => + new Rect2(...unionBounds(r1.pos, r1.size, r2.pos, r2.size)), + + vertices, + (x: Rect2) => { + const p = x.pos; + const q = addNew(p, x.size, vec2()); + return [p.copy(), vec2(q.x, p.y), q, vec2(p.x, q.y)]; + } +); diff --git a/packages/geom2/src/rect2.ts b/packages/geom2/src/rect2.ts deleted file mode 100644 index fe3ce65e5b..0000000000 --- a/packages/geom2/src/rect2.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { addNew, maddNewN, Vec } from "@thi.ng/vectors2/api"; -import { Vec2, vec2 } from "@thi.ng/vectors2/vec2"; -import { - arcLength, - area, - Attribs, - bounds, - centroid, - Rect2, - Type, - vertices -} from "./api"; - -export function rect2(pos: Vec, size: Vec, attribs?: Attribs): Rect2 { - return new Rect2(pos, size, attribs); -} - -area.add(Type.RECT2, (x: Rect2) => x.size[0] * x.size[1]); - -arcLength.add(Type.RECT2, (x: Rect2) => 2 * (x.size[0] + x.size[1])); - -bounds.add(Type.RECT2, (x: Rect2) => x); - -centroid.add(Type.RECT2, (x: Rect2) => maddNewN(x.pos, x.size, 0.5)); - -vertices.add(Type.RECT2, (x: Rect2) => { - const p = x.pos; - const q = addNew(p, x.size, vec2()); - return [p.copy(), vec2(q.x, p.y), q, vec2(p.x, q.y)]; -}); diff --git a/packages/geom2/src/svg.ts b/packages/geom2/src/svg.ts new file mode 100644 index 0000000000..0ff947a34b --- /dev/null +++ b/packages/geom2/src/svg.ts @@ -0,0 +1,19 @@ +import { serialize } from "@thi.ng/hiccup"; +import { convertTree } from "@thi.ng/hiccup-svg/convert"; +import { svg } from "@thi.ng/hiccup-svg/svg"; +import { collBounds } from "./internal/bounds"; +import { Shape, Rect2 } from "./api"; + +export const asSVG = (...args: any[]) => + serialize(convertTree(args)); + +export const svgDoc = (attribs, ...args: Shape[]) => { + const bounds = collBounds(args); + attribs = { + width: bounds.size.x, + height: bounds.size.y, + viewBox: `${bounds.pos.x} ${bounds.pos.y} ${bounds.size.x} ${bounds.size.y}`, + ...attribs + }; + return asSVG(svg(attribs, ...args)); +}; From 125c784ffd1dd957ef80407ccc046c2ea39ca626 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 26 Oct 2018 15:00:33 +0100 Subject: [PATCH 005/333] feat(defmulti): add versions w/ 1 optional typed arg, add .impls() --- packages/defmulti/README.md | 13 ++++++- packages/defmulti/src/index.ts | 67 ++++++++++++++++++++++++++++++++- packages/defmulti/test/index.ts | 1 + 3 files changed, 78 insertions(+), 3 deletions(-) diff --git a/packages/defmulti/README.md b/packages/defmulti/README.md index 19758c7ce5..4262b1b5f7 100644 --- a/packages/defmulti/README.md +++ b/packages/defmulti/README.md @@ -51,6 +51,7 @@ The function returned by `defmulti` can be called like any other function, but a multi-function, but only checks if an implementation exists for the given args. Returns boolean. - `.isa(child, parent)` - establish dispatch value relationship hierarchy +- `.impls()` - returns set of all dispatch values which have an implementation - `.rels()` - return all dispatch value relationships - `.parents(id)` - direct parents of dispatch value `id` - `.ancestors(id)` - transitive parents of dispatch value `id` @@ -91,9 +92,15 @@ foo.ancestors(1); // Set { } foo.add("odd", (x) => `${x} is odd`); foo.add("number", (x) => `${x} is a number`); +// dispatch values w/ implementations +foo.impls(); +// Set { "odd", "even", "number", "23", "42" } + foo(23); // "23 is odd" foo(42); // "42 is a number" foo(1); // error (missing impl & no default) + +foo.callable(1) // false ``` Same example, but with relationships provided as argument to `defmulti`: @@ -122,8 +129,10 @@ multi-method associates the related implementation with the given dispatch value. ```ts -const foo = defmulti((x) => x.id); -const bar = defmulti((x) => x.id); +const dispatch = (x) => x.id; + +const foo = defmulti(dispatch); +const bar = defmulti(dispatch); // batch define implementations for dispatch value "a" implementations( diff --git a/packages/defmulti/src/index.ts b/packages/defmulti/src/index.ts index 6f0030c8d2..393c424ee2 100644 --- a/packages/defmulti/src/index.ts +++ b/packages/defmulti/src/index.ts @@ -3,33 +3,50 @@ import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; import { unsupported } from "@thi.ng/errors/unsupported"; import { illegalArity } from "@thi.ng/errors/illegal-arity"; -export const DEFAULT: unique symbol = Symbol(); +export const DEFAULT: unique symbol = Symbol("DEFAULT"); export type DispatchFn = (...args) => PropertyKey; export type DispatchFn1 = (a: A, ...xs: any[]) => PropertyKey; +export type DispatchFn1O = (a: A, b?: B, ...xs: any[]) => PropertyKey; export type DispatchFn2 = (a: A, b: B, ...xs: any[]) => PropertyKey; +export type DispatchFn2O = (a: A, b: B, c?: C, ...xs: any[]) => PropertyKey; export type DispatchFn3 = (a: A, b: B, c: C, ...xs: any[]) => PropertyKey; +export type DispatchFn3O = (a: A, b: B, c: C, d?: D, ...xs: any[]) => PropertyKey; export type DispatchFn4 = (a: A, b: B, c: C, d: D, ...xs: any[]) => PropertyKey; +export type DispatchFn4O = (a: A, b: B, c: C, d: D, e?: E, ...xs: any[]) => PropertyKey; export type DispatchFn5 = (a: A, b: B, c: C, d: D, e: E, ...xs: any[]) => PropertyKey; +export type DispatchFn5O = (a: A, b: B, c: C, d: D, e: E, f?: F, ...xs: any[]) => PropertyKey; export type DispatchFn6 = (a: A, b: B, c: C, d: D, e: E, f: F, ...xs: any[]) => PropertyKey; +export type DispatchFn6O = (a: A, b: B, c: C, d: D, e: E, f: F, g?: G, ...xs: any[]) => PropertyKey; export type DispatchFn7 = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, ...xs: any[]) => PropertyKey; +export type DispatchFn7O = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h?: H, ...xs: any[]) => PropertyKey; export type DispatchFn8 = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, ...xs: any[]) => PropertyKey; +export type DispatchFn8O = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i?: I, ...xs: any[]) => PropertyKey; export type Implementation = (...args: any[]) => T; export type Implementation1 = (a: A, ...xs: any[]) => T; +export type Implementation1O = (a: A, b?: B, ...xs: any[]) => T; export type Implementation2 = (a: A, b: B, ...xs: any[]) => T; +export type Implementation2O = (a: A, b: B, c?: C, ...xs: any[]) => T; export type Implementation3 = (a: A, b: B, c: C, ...xs: any[]) => T; +export type Implementation3O = (a: A, b: B, c: C, d?: D, ...xs: any[]) => T; export type Implementation4 = (a: A, b: B, c: C, d: D, ...xs: any[]) => T; +export type Implementation4O = (a: A, b: B, c: C, d: D, e?: E, ...xs: any[]) => T; export type Implementation5 = (a: A, b: B, c: C, d: D, e: E, ...xs: any[]) => T; +export type Implementation5O = (a: A, b: B, c: C, d: D, e: E, f?: F, ...xs: any[]) => T; export type Implementation6 = (a: A, b: B, c: C, d: D, e: E, f: F, ...xs: any[]) => T; +export type Implementation6O = (a: A, b: B, c: C, d: D, e: E, f: F, g?: G, ...xs: any[]) => T; export type Implementation7 = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, ...xs: any[]) => T; +export type Implementation7O = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h?: H, ...xs: any[]) => T; export type Implementation8 = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, ...xs: any[]) => T; +export type Implementation8O = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i?: I, ...xs: any[]) => T; export interface MultiFnBase { add(id: PropertyKey, g: I): boolean; remove(id: PropertyKey): boolean; callable(...args: any[]): boolean; isa(id: PropertyKey, parent: PropertyKey); + impls(): Set; rels(): IObjectOf>; parents(id: PropertyKey): Set; ancestors(id: PropertyKey): Set; @@ -43,34 +60,66 @@ export interface MultiFn1 extends Implementation1, MultiFnBase> { } +export interface MultiFn1O extends + Implementation1O, + MultiFnBase> { } + export interface MultiFn2 extends Implementation2, MultiFnBase> { } +export interface MultiFn2O extends + Implementation2O, + MultiFnBase> { } + export interface MultiFn3 extends Implementation3, MultiFnBase> { } +export interface MultiFn3O extends + Implementation3O, + MultiFnBase> { } + export interface MultiFn4 extends Implementation4, MultiFnBase> { } +export interface MultiFn4O extends + Implementation4O, + MultiFnBase> { } + export interface MultiFn5 extends Implementation5, MultiFnBase> { } +export interface MultiFn5O extends + Implementation5O, + MultiFnBase> { } + export interface MultiFn6 extends Implementation6, MultiFnBase> { } +export interface MultiFn6O extends + Implementation6O, + MultiFnBase> { } + export interface MultiFn7 extends Implementation7, MultiFnBase> { } +export interface MultiFn7O extends + Implementation7O, + MultiFnBase> { } + export interface MultiFn8 extends Implementation8, MultiFnBase> { } +export interface MultiFn8O extends + Implementation8O, + MultiFnBase> { } + export type AncestorDefs = IObjectOf>; /** @@ -95,12 +144,20 @@ export type AncestorDefs = IObjectOf>; export function defmulti(f: DispatchFn, rels?: AncestorDefs): MultiFn; export function defmulti(f: DispatchFn1, rels?: AncestorDefs): MultiFn1; export function defmulti(f: DispatchFn2, rels?: AncestorDefs): MultiFn2; +export function defmulti(f: DispatchFn1O, rels?: AncestorDefs): MultiFn1O; export function defmulti(f: DispatchFn3, rels?: AncestorDefs): MultiFn3; +export function defmulti(f: DispatchFn2O, rels?: AncestorDefs): MultiFn2O; export function defmulti(f: DispatchFn4, rels?: AncestorDefs): MultiFn4; +export function defmulti(f: DispatchFn3O, rels?: AncestorDefs): MultiFn3O; export function defmulti(f: DispatchFn5, rels?: AncestorDefs): MultiFn5; +export function defmulti(f: DispatchFn4O, rels?: AncestorDefs): MultiFn4O; export function defmulti(f: DispatchFn6, rels?: AncestorDefs): MultiFn6; +export function defmulti(f: DispatchFn5O, rels?: AncestorDefs): MultiFn5O; export function defmulti(f: DispatchFn7, rels?: AncestorDefs): MultiFn7; +export function defmulti(f: DispatchFn6O, rels?: AncestorDefs): MultiFn6O; export function defmulti(f: DispatchFn8, rels?: AncestorDefs): MultiFn8; +export function defmulti(f: DispatchFn7O, rels?: AncestorDefs): MultiFn7O; +export function defmulti(f: DispatchFn8O, rels?: AncestorDefs): MultiFn8O; export function defmulti(f: any, ancestors?: AncestorDefs): MultiFn { let impls: IObjectOf> = {}; let rels: IObjectOf> = ancestors ? makeRels(ancestors) : {}; @@ -128,6 +185,14 @@ export function defmulti(f: any, ancestors?: AncestorDefs): MultiFn { !val && (rels[id] = val = new Set()); val.add(parent); }; + fn.impls = () => { + const res = new Set(Object.keys(impls)); + for (let id in rels) { + findImpl(impls, rels, id) && res.add(id); + } + impls[DEFAULT] && res.add(DEFAULT); + return res; + }; fn.rels = () => rels; fn.parents = (id: PropertyKey) => rels[id]; fn.ancestors = (id: PropertyKey) => new Set(findAncestors([], rels, id)); diff --git a/packages/defmulti/test/index.ts b/packages/defmulti/test/index.ts index 7567e4a1e8..7fe077f647 100644 --- a/packages/defmulti/test/index.ts +++ b/packages/defmulti/test/index.ts @@ -87,6 +87,7 @@ describe("defmulti", () => { assert.throws(() => foo(66), "no default"); foo.add(DEFAULT, (x) => -x); assert.equal(foo(66), -66); + assert.deepEqual(foo.impls(), new Set([DEFAULT, "odd", "even", "number", "23", "42"])); const bar = defmulti((x) => x, { 23: ["odd"], From 51c4a49fe6de2ccb212c5c751343e611910b44b6 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 26 Oct 2018 16:55:04 +0100 Subject: [PATCH 006/333] feat(vectors): add/update types, multi-methods, minor optimizations --- packages/vectors2/src/api.ts | 70 ++++++++++++++++++++++---------- packages/vectors2/src/codegen.ts | 12 +++++- packages/vectors2/src/vec2.ts | 36 +++++++++------- packages/vectors2/src/vec3.ts | 50 +++++++++++++---------- packages/vectors2/src/vop.ts | 2 +- 5 files changed, 110 insertions(+), 60 deletions(-) diff --git a/packages/vectors2/src/api.ts b/packages/vectors2/src/api.ts index 72b7866a19..be4cfb0df1 100644 --- a/packages/vectors2/src/api.ts +++ b/packages/vectors2/src/api.ts @@ -4,6 +4,7 @@ import { IEqualsDelta, ILength } from "@thi.ng/api"; +import { implementsFunction } from "@thi.ng/checks/implements-function"; import { atan2Abs } from "@thi.ng/math/angle"; import { EPS } from "@thi.ng/math/api"; import { repeatedly } from "@thi.ng/transducers/iter/repeatedly"; @@ -15,20 +16,22 @@ import { vop } from "./vop"; // Ro = readonly export type VecOpV = (a: Vec, ...xs: any[]) => T; -export type VecOpVV = (a: Vec, b: Readonly) => T; +export type VecOpVO = (a: Vec, o?: O, ...xs: any[]) => T; +export type VecOpVV = (a: Vec, b: ReadonlyVec) => T; export type VecOpVN = (a: Vec, n: number) => T; export type VecOpVNN = (a: Vec, n: number, m: number) => T; -export type VecOpVVN = (a: Vec, b: Readonly, n: number) => T; -export type VecOpVVV = (a: Vec, b: Readonly, c: Readonly) => T; +export type VecOpVVN = (a: Vec, b: ReadonlyVec, n: number) => T; +export type VecOpVVV = (a: Vec, b: ReadonlyVec, c: ReadonlyVec) => T; -export type VecOpNewVN = (a: Vec, n: number, o?: T) => T; -export type VecOpNewVV = (a: Vec, b: Readonly, o?: T) => T; -export type VecOpNewVVN = (a: Vec, b: Readonly, n: number, o?: T) => T; -export type VecOpNewVVV = (a: Vec, b: Readonly, c: Readonly, o?: T) => T; +export type VecOpNewVN = (a: ReadonlyVec, n: number, o?: T) => T; +export type VecOpNewVV = (a: ReadonlyVec, b: ReadonlyVec, o?: T) => T; +export type VecOpNewVVN = (a: ReadonlyVec, b: ReadonlyVec, n: number, o?: T) => T; +export type VecOpNewVVV = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, o?: T) => T; -export type VecOpRoV = (a: Readonly, ...xs: any[]) => T; -export type VecOpRoVV = (a: Readonly, b: Readonly, ...xs: any[]) => T; -export type VecOpRoVVV = (a: Readonly, b: Readonly, c: Readonly, ...xs: any[]) => T; +export type VecOpRoV = (a: ReadonlyVec, ...xs: any[]) => T; +export type VecOpRoVV = (a: ReadonlyVec, b: ReadonlyVec, ...xs: any[]) => T; +export type VecOpRoVVO = (a: ReadonlyVec, b: ReadonlyVec, o?: O, ...xs: any[]) => T; +export type VecOpRoVVV = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, ...xs: any[]) => T; export interface MultiVecOp { add(dim: number, op: VOP); @@ -36,6 +39,7 @@ export interface MultiVecOp { } export interface MultiVecOpV extends VecOpV, MultiVecOp> { } +export interface MultiVecOpVO extends VecOpVO, MultiVecOp> { } export interface MultiVecOpVV extends VecOpVV, MultiVecOp> { } export interface MultiVecOpVN extends VecOpVN, MultiVecOp> { } export interface MultiVecOpVNN extends VecOpVNN, MultiVecOp> { } @@ -49,6 +53,7 @@ export interface MultiVecOpNewVVV extends VecOpNewVVV, MultiVecOp extends VecOpRoV, MultiVecOp> { } export interface MultiVecOpRoVV extends VecOpRoVV, MultiVecOp> { } +export interface MultiVecOpRoVVO extends VecOpRoVVO, MultiVecOp> { } export interface MultiVecOpRoVVV extends VecOpRoVVV, MultiVecOp> { } export interface Vec extends @@ -58,6 +63,12 @@ export interface Vec extends [id: number]: number; } +export interface ReadonlyVec extends + Iterable, + ILength { + readonly [id: number]: number; +} + export interface IVector extends Vec, ICopy, @@ -75,13 +86,28 @@ export type Vec4Coord = 0 | 1 | 2 | 3; export const set: MultiVecOpVV = vop(); export const setN: MultiVecOpVN = vop(); export const setS: MultiVecOpV = vop(); -export const copy: MultiVecOpV = vop(); -copy.default((v) => [...v]); + +export const copy: MultiVecOpRoV = vop(); +copy.default((v) => + implementsFunction(v, "copy") ? + (v).copy() : + [...v] +); + +export const empty: MultiVecOpRoV = vop(); +empty.default((v) => + implementsFunction(v, "empty") ? + (v).empty() : + zero(copy(v)) +); export const zero = (a: Vec) => setN(a, 0); export const one = (a: Vec) => setN(a, 1); -export const eqDelta: MultiVecOpRoVV = vop(); +export const zeroes = (n: number) => new Array(n).fill(0); +export const ones = (n: number) => new Array(n).fill(1); + +export const eqDelta: MultiVecOpRoVVO = vop(); export const rand: MultiVecOpVNN = vop(); export const rand01: MultiVecOpV = vop(); @@ -110,7 +136,7 @@ export const magSq: MultiVecOpRoV = vop(); export const mag: MultiVecOpRoV = vop(); mag.default((a) => Math.sqrt(magSq(a, a))); -export const normalize: MultiVecOpV = vop(); +export const normalize: MultiVecOpVO = vop(); normalize.default((v, n: number) => { let m = mag(v); return m >= EPS ? mulN(v, n / m) : v; @@ -122,8 +148,8 @@ limit.default((v, n: number) => { return m > n ? mulN(v, n / m) : v; }); -export const distSq: MultiVecOpVV = vop(); -export const dist: MultiVecOpVV = vop(); +export const distSq: MultiVecOpRoVV = vop(); +export const dist: MultiVecOpRoVV = vop(); dist.default((a, b) => Math.sqrt(distSq(a, b))); export const distManhattan: MultiVecOpRoVV = vop(); @@ -175,7 +201,7 @@ export const rotateY = _rotate(2, 0); export const rotateZ = _rotate(0, 1); export const polar: MultiVecOpV = vop(); -export const cartesian: MultiVecOpV = vop(); +export const cartesian: MultiVecOpVO = vop(); export const reflect: VecOpVV = (a, b) => maddN(a, b, -2 * dot(a, b)); @@ -189,15 +215,15 @@ export const refract: VecOpVVN = maddN(mulN(a, eta), n, -(eta * d + Math.sqrt(k))); }; -export const headingXY = (a: Readonly) => atan2Abs(a[1], a[0]); -export const headingXZ = (a: Readonly) => atan2Abs(a[2], a[0]); -export const headingYZ = (a: Readonly) => atan2Abs(a[2], a[1]); +export const headingXY = (a: ReadonlyVec) => atan2Abs(a[1], a[0]); +export const headingXZ = (a: ReadonlyVec) => atan2Abs(a[2], a[0]); +export const headingYZ = (a: ReadonlyVec) => atan2Abs(a[2], a[1]); export const angleRatio = - (a: Readonly, b: Readonly) => + (a: ReadonlyVec, b: ReadonlyVec) => dot(a, b) / (mag(a) * mag(b)); -export const angleBetween: MultiVecOpRoVV = vop(); +export const angleBetween: MultiVecOpRoVVO = vop(); const mi = -Infinity; const mx = Infinity; diff --git a/packages/vectors2/src/codegen.ts b/packages/vectors2/src/codegen.ts index 12d3e067e9..d2bc098aff 100644 --- a/packages/vectors2/src/codegen.ts +++ b/packages/vectors2/src/codegen.ts @@ -81,22 +81,32 @@ const indices = (sym: string) => map((i) => `${sym}[${i}]`, range()); * result array, using `ret` as return value. Returns array of source * code lines. * + * The optional `pre` and `post` strings can be used to wrap the + * generated code. `post` will be injected **before** the generated + * return statement (if not suppressed). + * * @param dim * @param tpl * @param syms * @param ret + * @param pre + * @param post */ const assemble = ( dim: number, tpl: Template, syms: string, - ret = "a") => { + ret = "a", + pre?: string, + post?: string) => { const src = transduce( comp(take(dim), mapIndexed((i, x: string[]) => tpl(x, i))), push(), + pre ? [pre] : [], tuples.apply(null, [...map(indices, syms.split(","))]) ); + post && src.push(post); ret !== null && src.push(`return ${ret};`); return src; }; diff --git a/packages/vectors2/src/vec2.ts b/packages/vectors2/src/vec2.ts index 93cdc8eeb0..73f58de45c 100644 --- a/packages/vectors2/src/vec2.ts +++ b/packages/vectors2/src/vec2.ts @@ -33,6 +33,8 @@ import { MAX4, ZERO4, ONE4, + ReadonlyVec, + dist, } from "./api"; export class Vec2 extends AVec implements @@ -117,7 +119,7 @@ export class Vec2 extends AVec implements return new Vec2(); } - eqDelta(v: Readonly, eps = EPS) { + eqDelta(v: ReadonlyVec, eps = EPS) { return eqDelta(this, v, eps); } @@ -133,6 +135,10 @@ export class Vec2 extends AVec implements declareIndices(Vec2.prototype, ["x", "y"]); genCommon(2); +const abs = Math.abs; +const pow = Math.pow; +const sqrt = Math.sqrt; + eqDelta.add(2, (a, b, eps = EPS) => b.length === 2 && _eqDelta(a[0], b[0], eps) && @@ -141,18 +147,20 @@ eqDelta.add(2, (a, b, eps = EPS) => dot.add(2, (a, b) => a[0] * b[0] + a[1] * b[1]); magSq.add(2, (a) => a[0] * a[0] + a[1] * a[1]); -distSq.add(2, (a, b) => { - const x = a[0] - b[0]; - const y = a[1] - b[1]; - return x * x + y * y; -}); -distManhattan.add(2, (a, b) => - Math.abs(a[0] - b[0]) + Math.abs(a[1] - b[1])); -distChebyshev.add(2, (a, b) => - Math.max(Math.abs(a[0] - b[0]), Math.abs(a[1] - b[1]))); -minor.add(2, (a) => min2id(Math.abs(a[0]), Math.abs(a[1]))); -major.add(2, (a) => max2id(Math.abs(a[0]), Math.abs(a[1]))); +const distsq2 = + (a: ReadonlyVec, b: ReadonlyVec) => + pow(a[0] - b[0], 2) + + pow(a[1] - b[1], 2); + +distSq.add(2, distsq2); +dist.add(2, (a, b) => sqrt(distsq2(a, b))); + +distManhattan.add(2, (a, b) => abs(a[0] - b[0]) + abs(a[1] - b[1])); +distChebyshev.add(2, (a, b) => Math.max(abs(a[0] - b[0]), abs(a[1] - b[1]))); + +minor.add(2, (a) => min2id(abs(a[0]), abs(a[1]))); +major.add(2, (a) => max2id(abs(a[0]), abs(a[1]))); polar.add(2, (a) => { const x = a[0]; @@ -188,11 +196,11 @@ export const asVec2 = x : new Vec2(x.length === 2 ? x : [x[0] || 0, x[1] || 0]); -export const swizzle2 = (a: Vec, b: Readonly, x: number, y: number) => +export const swizzle2 = (a: Vec, b: ReadonlyVec, x: number, y: number) => (a[0] = b[x] || 0, a[1] = b[y] || 0, a); export const comparator2 = - (o1: Vec2Coord, o2: Vec2Coord): Comparator> => + (o1: Vec2Coord, o2: Vec2Coord): Comparator => (a, b): number => { const ax = a[o1]; const ay = a[o2]; diff --git a/packages/vectors2/src/vec3.ts b/packages/vectors2/src/vec3.ts index e1d5eef474..1af4069077 100644 --- a/packages/vectors2/src/vec3.ts +++ b/packages/vectors2/src/vec3.ts @@ -32,6 +32,8 @@ import { MAX4, ZERO4, ONE4, + ReadonlyVec, + dist, } from "./api"; export class Vec3 extends AVec implements @@ -119,12 +121,12 @@ export class Vec3 extends AVec implements return new Vec3(); } - eqDelta(v: Readonly, eps = EPS) { + eqDelta(v: ReadonlyVec, eps = EPS) { return eqDelta(this, v, eps); } toJSON() { - return [this.x, this.y]; + return [this.x, this.y, this.z]; } toString() { @@ -133,7 +135,11 @@ export class Vec3 extends AVec implements } declareIndices(Vec3.prototype, ["x", "y", "z"]); -genCommon(2); +genCommon(3); + +const abs = Math.abs; +const pow = Math.pow; +const sqrt = Math.sqrt; eqDelta.add(3, (a, b, eps = EPS) => b.length == 3 && @@ -146,38 +152,38 @@ dot.add(3, (a, b) => a[0] * b[0] + a[1] * b[1] + a[2] * b[2]); magSq.add(3, (a) => a[0] * a[0] + a[1] * a[1] + a[2] * a[2]); -distSq.add(3, (a, b) => { - const x = a[0] - b[0]; - const y = a[1] - b[1]; - const z = a[2] - b[2]; - return x * x + y * y + z * z; -}); +const distsq3 = + (a: ReadonlyVec, b: ReadonlyVec) => + pow(a[0] - b[0], 2) + + pow(a[1] - b[1], 2) + + pow(a[2] - b[2], 2); + +distSq.add(3, distsq3); +dist.add(3, (a, b) => sqrt(distsq3(a, b))); distManhattan.add(3, (a, b) => - Math.abs(a[0] - b[0]) + - Math.abs(a[1] - b[1]) + - Math.abs(a[2] - b[2]) + abs(a[0] - b[0]) + + abs(a[1] - b[1]) + + abs(a[2] - b[2]) ); distChebyshev.add(3, (a, b) => Math.max( - Math.abs(a[0] - b[0]), - Math.abs(a[1] - b[1]), - Math.abs(a[2] - b[2]) + abs(a[0] - b[0]), + abs(a[1] - b[1]), + abs(a[2] - b[2]) ) ); -minor.add(3, (a) => - min3id(Math.abs(a[0]), Math.abs(a[1]), Math.abs(a[2]))); +minor.add(3, (a) => min3id(abs(a[0]), abs(a[1]), abs(a[2]))); -major.add(3, (a) => - max3id(Math.abs(a[0]), Math.abs(a[1]), Math.abs(a[2]))); +major.add(3, (a) => max3id(abs(a[0]), abs(a[1]), abs(a[2]))); polar.add(3, (a) => { const x = a[0]; const y = a[1]; const z = a[2]; - const r = Math.sqrt(x * x + y * y + z * z); + const r = sqrt(x * x + y * y + z * z); a[0] = r; a[1] = Math.asin(z / r); a[2] = Math.atan2(y, x); @@ -216,11 +222,11 @@ export const asVec3 = new Vec3(x.length === 3 ? x : [x[0] || 0, x[1] || 0, x[2] || 0]); export const swizzle3 = - (a: Vec, b: Readonly, x: number, y: number, z: number) => + (a: Vec, b: ReadonlyVec, x: number, y: number, z: number) => (a[0] = b[x] || 0, a[1] = b[y] || 0, a[2] = b[z] || 0, a); export const comparator3 = - (o1: Vec3Coord, o2: Vec3Coord, o3: Vec3Coord): Comparator> => + (o1: Vec3Coord, o2: Vec3Coord, o3: Vec3Coord): Comparator => (a, b): number => { const ax = a[o1]; const ay = a[o2]; diff --git a/packages/vectors2/src/vop.ts b/packages/vectors2/src/vop.ts index cdd881afc5..2dd6787a67 100644 --- a/packages/vectors2/src/vop.ts +++ b/packages/vectors2/src/vop.ts @@ -8,7 +8,7 @@ import { unsupported } from "@thi.ng/errors/unsupported"; export const vop = () => { const impls = new Array(5); let fallback; - const fn = (...args) => { + const fn = (...args: any[]) => { const g = impls[args[0].length] || fallback; return g ? g(...args) : unsupported(`no impl for vec size ${args[0].length}`); }; From a070016c416e1242b4bd7e4b8324c47a6e5894f8 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 27 Oct 2018 14:20:24 +0100 Subject: [PATCH 007/333] feat(vectors): add VecPool skeleton, add more types, export codegen fns --- packages/vectors2/src/api.ts | 5 ++++ packages/vectors2/src/codegen.ts | 31 ++++++++++++++----- packages/vectors2/src/index.ts | 1 + packages/vectors2/src/pool.ts | 51 ++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 7 deletions(-) create mode 100644 packages/vectors2/src/pool.ts diff --git a/packages/vectors2/src/api.ts b/packages/vectors2/src/api.ts index be4cfb0df1..259234f37a 100644 --- a/packages/vectors2/src/api.ts +++ b/packages/vectors2/src/api.ts @@ -27,6 +27,8 @@ export type VecOpNewVN = (a: ReadonlyVec, n: number, o?: T) => T; export type VecOpNewVV = (a: ReadonlyVec, b: ReadonlyVec, o?: T) => T; export type VecOpNewVVN = (a: ReadonlyVec, b: ReadonlyVec, n: number, o?: T) => T; export type VecOpNewVVV = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, o?: T) => T; +export type VecOpNewVVVN = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, n: number, o?: T) => T; +export type VecOpNewVVVVN = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, n: number, o?: T) => T; export type VecOpRoV = (a: ReadonlyVec, ...xs: any[]) => T; export type VecOpRoVV = (a: ReadonlyVec, b: ReadonlyVec, ...xs: any[]) => T; @@ -50,6 +52,8 @@ export interface MultiVecOpNewVV extends VecOpNewVV, MultiVecOp extends VecOpNewVN, MultiVecOp> { } export interface MultiVecOpNewVVN extends VecOpNewVVN, MultiVecOp> { } export interface MultiVecOpNewVVV extends VecOpNewVVV, MultiVecOp> { } +export interface MultiVecOpNewVVVN extends VecOpNewVVVN, MultiVecOp> { } +export interface MultiVecOpNewVVVVN extends VecOpNewVVVVN, MultiVecOp> { } export interface MultiVecOpRoV extends VecOpRoV, MultiVecOp> { } export interface MultiVecOpRoVV extends VecOpRoVV, MultiVecOp> { } @@ -75,6 +79,7 @@ export interface IVector extends IEmpty, IEqualsDelta { + buf: Vec; i: number; s: number; } diff --git a/packages/vectors2/src/codegen.ts b/packages/vectors2/src/codegen.ts index d2bc098aff..4d46f1cfc6 100644 --- a/packages/vectors2/src/codegen.ts +++ b/packages/vectors2/src/codegen.ts @@ -68,9 +68,9 @@ import { maddNewN, } from "./api"; -type Template = (syms: string[], i?: number) => string; +export type Template = (syms: string[], i?: number) => string; -const indices = (sym: string) => map((i) => `${sym}[${i}]`, range()); +export const indices = (sym: string) => map((i) => `${sym}[${i}]`, range()); /** * Takes a vector size `dim`, a code template function and an array of @@ -92,7 +92,7 @@ const indices = (sym: string) => map((i) => `${sym}[${i}]`, range()); * @param pre * @param post */ -const assemble = ( +export const assemble = ( dim: number, tpl: Template, syms: string, @@ -111,13 +111,30 @@ const assemble = ( return src; }; -const compile = (dim: number, tpl: Template, args: string, syms = args, ret = "a") => - new Function(args, assemble(dim, tpl, syms, ret).join("")); +export const compile = ( + dim: number, + tpl: Template, + args: string, + syms = args, + ret = "a", + pre?: string, + post?: string) => + + new Function(args, assemble(dim, tpl, syms, ret, pre, post).join("")); + +export const compileHOF = ( + dim: number, + fn: FnAny, + tpl: Template, + args: string, + syms = args, + ret = "a", + pre?: string, + post?: string) => { -const compileHOF = (dim: number, fn: FnAny, tpl: Template, args: string, syms = args, ret = "a") => { return new Function( "fn", - `return (${args})=>{${assemble(dim, tpl, syms, ret).join("\n")}}` + `return (${args})=>{${assemble(dim, tpl, syms, ret, pre, post).join("\n")}}` )(fn); }; diff --git a/packages/vectors2/src/index.ts b/packages/vectors2/src/index.ts index 11e7eb3259..bf93825e15 100644 --- a/packages/vectors2/src/index.ts +++ b/packages/vectors2/src/index.ts @@ -1,3 +1,4 @@ export * from "./api"; +export * from "./pool"; export * from "./vec2"; export * from "./vec3"; diff --git a/packages/vectors2/src/pool.ts b/packages/vectors2/src/pool.ts new file mode 100644 index 0000000000..e94e58e83b --- /dev/null +++ b/packages/vectors2/src/pool.ts @@ -0,0 +1,51 @@ +import { TypedArray } from "@thi.ng/api"; +import { isTypedArray } from "@thi.ng/checks/is-typedarray"; +import { MemPool, Type, MemPoolOpts } from "@thi.ng/malloc"; +import { Vec2 } from "./vec2"; +import { Vec3 } from "./vec3"; +import { IVector } from "./api"; + +export { Type } + +const F64 = Type.F64; + +export class VecPool { + + pool: MemPool; + + constructor(pool: MemPool); + constructor(buf: number | ArrayBuffer, opts?: Partial); + constructor(pool: any, opts?: Partial) { + this.pool = !(pool instanceof MemPool) ? + new MemPool(pool, opts) : + pool; + } + + malloc(size: number, type: Type = F64) { + return this.pool.callocAs(type, size); + } + + mallocWrapped(size: number, stride = 1, type: Type = F64) { + const buf = this.pool.callocAs(type, size * stride); + if (!buf) return; + switch (size) { + case 2: + return new Vec2(buf, 0, stride); + case 3: + return new Vec3(buf, 0, stride); + case 4: + default: + // TODO add Vec4 & GVec + } + } + + free(vec: IVector | TypedArray) { + const buf = (vec).buf; + if (buf) { + return isTypedArray(buf) ? + this.pool.free(buf) : + false; + } + return this.pool.free(vec); + } +} From cfd8855540c5ac47f89856a15fc19de4b88a4cc0 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 27 Oct 2018 14:22:09 +0100 Subject: [PATCH 008/333] feat(geom): re-add & update more types / shape ops --- packages/geom2/package.json | 2 +- packages/geom2/src/api.ts | 250 ++++++++++++++--- packages/geom2/src/bezier.ts | 262 ++++++++++++++++++ packages/geom2/src/circle.ts | 36 ++- packages/geom2/src/container2.ts | 19 +- packages/geom2/src/ellipse.ts | 76 +++++ packages/geom2/src/index.ts | 4 + packages/geom2/src/internal/arc-length.ts | 14 + packages/geom2/src/internal/area.ts | 10 + packages/geom2/src/internal/barycentric.ts | 32 +++ packages/geom2/src/internal/bounds.ts | 6 +- packages/geom2/src/internal/centroid.ts | 29 ++ packages/geom2/src/internal/circumcenter.ts | 43 +++ packages/geom2/src/internal/closest-point.ts | 103 +++++++ packages/geom2/src/internal/corner.ts | 12 +- .../internal/douglas\342\200\223peucker.ts" | 43 +++ packages/geom2/src/internal/graham-scan.ts | 47 ++-- packages/geom2/src/internal/liang-barsky.ts | 53 ++++ .../geom2/src/internal/line-intersection.ts | 31 +++ packages/geom2/src/internal/sampler.ts | 77 +++++ .../geom2/src/internal/sutherland-hodgeman.ts | 44 +++ packages/geom2/src/polygon.ts | 81 +++++- packages/geom2/src/polyline.ts | 68 +++++ packages/geom2/src/quad.ts | 3 +- packages/geom2/src/rect.ts | 26 +- packages/geom2/src/svg.ts | 10 +- packages/geom2/src/tessellate.ts | 159 +++++++++++ 27 files changed, 1442 insertions(+), 98 deletions(-) create mode 100644 packages/geom2/src/bezier.ts create mode 100644 packages/geom2/src/ellipse.ts create mode 100644 packages/geom2/src/internal/arc-length.ts create mode 100644 packages/geom2/src/internal/area.ts create mode 100644 packages/geom2/src/internal/barycentric.ts create mode 100644 packages/geom2/src/internal/centroid.ts create mode 100644 packages/geom2/src/internal/circumcenter.ts create mode 100644 packages/geom2/src/internal/closest-point.ts create mode 100644 "packages/geom2/src/internal/douglas\342\200\223peucker.ts" create mode 100644 packages/geom2/src/internal/liang-barsky.ts create mode 100644 packages/geom2/src/internal/line-intersection.ts create mode 100644 packages/geom2/src/internal/sampler.ts create mode 100644 packages/geom2/src/internal/sutherland-hodgeman.ts create mode 100644 packages/geom2/src/polyline.ts create mode 100644 packages/geom2/src/tessellate.ts diff --git a/packages/geom2/package.json b/packages/geom2/package.json index 8b6b9697f5..d95fe3fec2 100644 --- a/packages/geom2/package.json +++ b/packages/geom2/package.json @@ -13,7 +13,7 @@ "license": "Apache-2.0", "scripts": { "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc internal", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn run build && yarn publish --access public", diff --git a/packages/geom2/src/api.ts b/packages/geom2/src/api.ts index 902d5cd436..69817845b0 100644 --- a/packages/geom2/src/api.ts +++ b/packages/geom2/src/api.ts @@ -1,10 +1,13 @@ import { ICopy, IObjectOf } from "@thi.ng/api"; -import { DEFAULT, defmulti } from "@thi.ng/defmulti"; -import { IVector, subNew, Vec } from "@thi.ng/vectors2/api"; -import { asVec2, Vec2, vec2 } from "@thi.ng/vectors2/vec2"; +import { DEFAULT, defmulti, MultiFn1O } from "@thi.ng/defmulti"; +import { copy, subNew, Vec, mixNewN } from "@thi.ng/vectors2/api"; + +import "@thi.ng/vectors2/vec2"; export enum Type { CIRCLE2 = "circle", + CUBIC2 = "cubic", + ELLIPSE2 = "ellipse", GROUP = "g", LINE2 = "line", PATH2 = "path", @@ -12,10 +15,19 @@ export enum Type { POLYGON2 = "polygon", POLYLINE2 = "polyline", QUAD2 = "quad", + QUADRATIC2 = "quadratic", RECT2 = "rect", TRIANGLE2 = "triangle", } +export const enum LineIntersectionType { + PARALLEL, + COINCIDENT, + COINCIDENT_NO_INTERSECT, + INTERSECT, + INTERSECT_OUTSIDE, +} + export const DEFAULT_SAMPLES = 20; export interface Shape extends @@ -29,32 +41,95 @@ export interface AABBLike extends Shape { size: Vec; } +export interface LineIntersection { + type: LineIntersectionType; + isec?: Vec; + det?: number; + alpha?: number; + beta?: number; +} + +export interface SamplingOpts { + /** + * Number of points to sample & return. Defaults to the implementing + * type's `DEFAULT_RES` if neither this nor `theta` option is given + * (see `ArcSamplingOpts`). + */ + num: number; + /** + * Approximate desired distance between sampled result points. If + * given, takes priority over the `num` option, but the latter MIGHT + * be used as part of the sampling process (implementation + * specific). Note: For circles this value is interpreted as arc + * length, not cartesian distance (error will be proportional to the + * given value relative to the circle's radius). + */ + dist: number; + /** + * Currently only used by these types: + * + * - Arc2 + * - Circle2 + * + * Defines the target angle between sampled points. If greater than + * the actual range of the arc, only the two end points will be + * returned at most. This option is used to derive a `num` value and + * takes priority if `num` is given as well. + * + * This option is useful to adapt the sampling based on angular + * resolution, rather than a fixed number of samples. + */ + theta: number; + /** + * If `true`, the shape's end point will be included in the result + * array. The default setting for open geometries is `true`, for + * closed ones `false`. This option has no influence on any internal + * resolution calculation. + * + * For open geometry this option is useful to when re-sampling paths + * of consecutive segments, where the end points of each segment + * coincide with the start points of the next segment. For all but + * the last segment, this option should be `false` and so can be + * used to avoid duplicate vertices in the concatenated result. + * + * When sampling closed shapes, enabling this option will include an + * extra point (start), i.e. if the `num` option was given, results + * in `num+1` points. + */ + last: boolean; +} + export type Attribs = IObjectOf; +export type Tessellator = (points: Vec[]) => Vec[][]; + const dispatch = (x: Shape) => x.type; -export const area = defmulti(dispatch); +export const area: MultiFn1O = defmulti(dispatch); export const arcLength = defmulti(dispatch); -export const asPolygon = defmulti(dispatch); +export const asCubic = defmulti(dispatch); -export const asPolyline = defmulti(dispatch); +export const asPolygon: MultiFn1O = defmulti(dispatch); + +export const asPolyline: MultiFn1O = defmulti(dispatch); export const bounds = defmulti(dispatch); export const center = defmulti(dispatch); -export const centroid = defmulti(dispatch); +export const centroid: MultiFn1O = defmulti(dispatch); export const classifyPoint = defmulti(dispatch); +export const convexHull = defmulti(dispatch); + export const depth = defmulti(dispatch); depth.add(DEFAULT, (x) => bounds(x).size[2] || 0); export const difference = defmulti(dispatch); -// TODO add options type export const extrude = defmulti(dispatch); export const height = defmulti(dispatch); @@ -62,9 +137,26 @@ height.add(DEFAULT, (x) => bounds(x).size[1]); export const intersect = defmulti(dispatch); +export const pointAt = defmulti(dispatch); + +export const resample = defmulti(dispatch); + +/** + * Returns new shape of same type with a shallow copy of the original + * geometry (vertex list) simplified using Douglas-Peucker algorithm. + * + * @param shape + * @param eps simplification threshold (default: 0.1) + */ +export const simplify: MultiFn1O = defmulti(dispatch); + +export const splitAt = defmulti(dispatch); + +export const tessellate = defmulti, Vec[][]>(dispatch); + export const union = defmulti(dispatch); -export const vertices = defmulti(dispatch); +export const vertices: MultiFn1O, Vec[]> = defmulti(dispatch); export const width = defmulti(dispatch); width.add(DEFAULT, (x) => bounds(x).size[0]); @@ -94,24 +186,24 @@ export abstract class AShape extends Array implements /** * [type, {}, points] */ -export class PointContainer> extends AShape { +export class PointContainer extends AShape { constructor(type: Type, points: Vec[], attribs?: Attribs) { super(type, attribs, points); } - get points(): T[] { + get points(): Vec[] { return this[2]; } - set points(pts: T[]) { + set points(pts: Vec[]) { this[2] = pts; } copy() { - return new PointContainer( + return new PointContainer( this.type, - this.points.map((p) => p.copy()), + this.points.map((p) => copy(p)), { ...this.attribs } ); } @@ -124,18 +216,18 @@ export class Circle2 extends AShape implements ICopy { constructor(pos: Vec, r: number, attribs?: Attribs) { - super(Type.CIRCLE2, attribs, asVec2(pos), r); + super(Type.CIRCLE2, attribs, pos, r); } copy() { - return new Circle2(this.pos.copy(), this.r, { ...this.attribs }); + return new Circle2(copy(this.pos), this.r, { ...this.attribs }); } - get pos(): Vec2 { + get pos(): Vec { return this[2]; } - set pos(v: Vec2) { + set pos(v: Vec) { this[2] = v; } @@ -148,6 +240,58 @@ export class Circle2 extends AShape implements } } +/** + * ``` + * ["cubic", {}, points] + * ``` + */ +export class Cubic2 extends PointContainer implements + ICopy { + + static fromLine(a: Vec, b: Vec, attribs?: Attribs) { + return new Cubic2([a, mixNewN(a, b, 1 / 3), mixNewN(b, a, 1 / 3), b], attribs); + } + + constructor(points: Vec[], attribs?: Attribs) { + super(Type.CUBIC2, points, attribs); + } + + copy() { + return new Cubic2(this.points.map(copy), { ...this.attribs }); + } +} + +/** + * ["ellipse", {}, pos, r] + */ +export class Ellipse2 extends AShape implements + ICopy { + + constructor(pos: Vec, r: Vec, attribs?: Attribs) { + super(Type.ELLIPSE2, attribs, pos, r); + } + + copy() { + return new Ellipse2(copy(this.pos), this.r, { ...this.attribs }); + } + + get pos(): Vec { + return this[2]; + } + + set pos(v: Vec) { + this[2] = v; + } + + get r(): Vec { + return this[3]; + } + + set r(r: Vec) { + this[3] = r; + } +} + /** * ["circle", {}, pos, r] */ @@ -171,16 +315,37 @@ export class Group2 extends AShape implements } } +/** + * ``` + * ["quadratic", {}, points] + * ``` + */ +export class Quadratic2 extends PointContainer implements + ICopy { + + static fromLine(a: Vec, b: Vec, attribs?: Attribs) { + return new Quadratic2([a, mixNewN(a, b, 0.5), b], attribs); + } + + constructor(points: Vec[], attribs?: Attribs) { + super(Type.QUADRATIC2, points, attribs); + } + + copy() { + return new Quadratic2(this.points.map(copy), { ...this.attribs }); + } +} + /** * ``` * ["polygon", {}, points] * ``` */ -export class Polygon2 extends PointContainer implements +export class Polygon2 extends PointContainer implements ICopy { constructor(points: Vec[], attribs?: Attribs) { - super(Type.POLYGON2, points.map(asVec2), attribs); + super(Type.POLYGON2, points, attribs); } copy() { @@ -188,20 +353,37 @@ export class Polygon2 extends PointContainer implements } } +/** + * ``` + * ["polygon", {}, points] + * ``` + */ +export class Polyline2 extends PointContainer implements + ICopy { + + constructor(points: Vec[], attribs?: Attribs) { + super(Type.POLYLINE2, points, attribs); + } + + copy() { + return new Polyline2(this.points.map(copy), { ...this.attribs }); + } +} + /** * ``` * ["quad", {}, points] * ``` */ -export class Quad2 extends PointContainer implements +export class Quad2 extends PointContainer implements ICopy { constructor(points: Vec[], attribs?: Attribs) { - super(Type.POLYGON2, points.map(asVec2), attribs); + super(Type.POLYGON2, points, attribs); } copy() { - return new Quad2(this.points, { ...this.attribs }); + return new Quad2(this.points.map(copy), { ...this.attribs }); } get type() { @@ -218,44 +400,44 @@ export class Rect2 extends AShape implements AABBLike, ICopy { - static fromMinMax(min: Vec, max: Vec) { - return new Rect2(min, subNew(max, min, vec2())); + static fromMinMax(min: Vec, max: Vec, attribs?: Attribs) { + return new Rect2(min, subNew(max, min), attribs); } constructor(pos: Vec, size: Vec, attribs?: Attribs) { - super(Type.RECT2, attribs, asVec2(pos), asVec2(size)); + super(Type.RECT2, attribs, pos, size); } copy() { - return new Rect2(this.pos.copy(), this.size.copy(), { ...this.attribs }); + return new Rect2(copy(this.pos), copy(this.size), { ...this.attribs }); } - get pos(): Vec2 { + get pos(): Vec { return this[2]; } - set pos(v: Vec2) { + set pos(v: Vec) { this[2] = v; } - get size(): Vec2 { + get size(): Vec { return this[3]; } - set size(v: Vec2) { + set size(v: Vec) { this[3] = v; } } -export class Triangle2 extends PointContainer implements +export class Triangle2 extends PointContainer implements ICopy { constructor(points: Vec[], attribs?: Attribs) { - super(Type.POLYGON2, points.map(asVec2), attribs); + super(Type.POLYGON2, points, attribs); } copy() { - return new Triangle2(this.points, { ...this.attribs }); + return new Triangle2(this.points.map(copy), { ...this.attribs }); } get type() { diff --git a/packages/geom2/src/bezier.ts b/packages/geom2/src/bezier.ts new file mode 100644 index 0000000000..0c85046165 --- /dev/null +++ b/packages/geom2/src/bezier.ts @@ -0,0 +1,262 @@ +import { isNumber } from "@thi.ng/checks/is-number"; +import { isPlainObject } from "@thi.ng/checks/is-plain-object"; +import { implementations } from "@thi.ng/defmulti"; +import { clamp01 } from "@thi.ng/math/interval"; +import { mixCubic as _mixC, mixQuadratic as _mixQ } from "@thi.ng/math/mix"; +import { + copy, + maddN, + max, + min, + mixNewN, + mulNewN, + MultiVecOpNewVVVN, + MultiVecOpNewVVVVN, + ReadonlyVec, + Vec +} from "@thi.ng/vectors2/api"; +import { compile } from "@thi.ng/vectors2/codegen"; +import { vop } from "@thi.ng/vectors2/vop"; +import { + asCubic, + Attribs, + bounds, + Cubic2, + DEFAULT_SAMPLES, + pointAt, + Quadratic2, + Rect2, + SamplingOpts, + splitAt, + Type, + vertices +} from "./api"; +import { Sampler } from "./internal/sampler"; + +const compileMixQ = (dim: number) => + compile( + dim, + ([a, b, c, o]) => `${o} = ${a}*wa + ${b}*wb + ${c}*wc;`, + "a,b,c,t,o=[]", + "a,b,c,o", + "o", + "const s=1-t, wa=s*s, wb=2*s*t, wc=t*t;" + ); + +const compileMixC = (dim: number) => + compile( + dim, + ([a, b, c, d, o]) => `${o}=${a}*wa + ${b}*wb + ${c}*wc + ${d}*wd;`, + "a,b,c,d,t,o=[]", + "a,b,c,d,o", + "o", + "const s=1-t, s2=s*s, t2=t*t, wa=s2*s, wb=3*s2*t, wc=3*t2*s, wd=t2*t;" + ); + +export const mixQuadratic: MultiVecOpNewVVVN = vop(); +mixQuadratic.add(2, compileMixQ(2)); +mixQuadratic.add(3, compileMixQ(3)); +mixQuadratic.default((a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, t: number, o: Vec = []) => { + const s = 1 - t; + return maddN(maddN(mulNewN(a, s * s, o), b, 2 * s * t), c, t * t); +}); + +export const mixCubic: MultiVecOpNewVVVVN = vop(); +mixCubic.add(2, compileMixC(2)); +mixCubic.add(3, compileMixC(3)); +mixCubic.default((a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, t: number, o: Vec = []) => { + const t2 = t * t; + const s = 1 - t; + const s2 = s * s; + return maddN(maddN(maddN(mulNewN(a, s2 * s, o), b, 3 * s2 * t), c, 3 * t2 * s), d, t2 * t); +}); + +const cubicAxisBounds = (pa: number, pb: number, pc: number, pd: number) => { + let a = 3 * pd - 9 * pc + 9 * pb - 3 * pa; + let b = 6 * pa - 12 * pb + 6 * pc; + let c = 3 * pb - 3 * pa; + let disc = b * b - 4 * a * c; + let l = pa; + let h = pa; + + const bounds = (t: number) => { + if (t > 0 && t < 1) { + const x = _mixC(pa, pb, pc, pd, t); + x < l && (l = x); + x > h && (h = x); + } + }; + + pd < l && (l = pd); + pd > h && (h = pd); + if (disc >= 0) { + disc = Math.sqrt(disc); + a *= 2; + bounds((-b + disc) / a); + bounds((-b - disc) / a); + } + return [l, h]; +}; + +implementations( + Type.CUBIC2, + + bounds, + ($: Cubic2) => { + const [a, b, c, d] = $.points; + const x = cubicAxisBounds(a[0], b[0], c[0], d[0]); + const y = cubicAxisBounds(a[1], b[1], c[1], d[1]); + return Rect2.fromMinMax([x[0], y[0]], [x[1], y[1]]); + }, + + pointAt, + (x: Cubic2, t: number) => { + const pts = x.points; + return mixCubic(pts[0], pts[1], pts[2], pts[3], t); + }, + + splitAt, + (x: Cubic2, t: number) => { + const [a, b, c, d] = x.points; + if (t <= 0 || t >= 1) { + const p = t <= 0 ? a : d; + const c1 = new Cubic2([copy(p), copy(p), copy(p), copy(p)]); + const c2 = new Cubic2([copy(a), copy(b), copy(c), copy(d)]); + return t <= 0 ? [c1, c2] : [c2, c1]; + } + const ab = mixNewN(a, b, t); + const bc = mixNewN(b, c, t); + const cd = mixNewN(c, d, t); + const abc = mixNewN(ab, bc, t); + const bcd = mixNewN(bc, cd, t); + const p = mixNewN(abc, bcd, t); + return [ + new Cubic2([[a[0], a[1]], [ab[0], ab[1]], [abc[0], abc[1]], [p[0], p[1]]]), + new Cubic2([[p[0], p[1]], [bcd[0], bcd[1]], [cd[0], cd[1]], [d[0], d[1]]]) + ]; + }, + + vertices, + (x: Cubic2, opts?: number | Partial) => { + if (isPlainObject(opts) && (opts).dist !== undefined) { + return new Sampler(vertices(x, (opts).num || DEFAULT_SAMPLES)) + .sampleUniform((opts).dist, (opts).last !== false); + } + opts = isNumber(opts) ? + { + num: opts, + last: true + } : + { + num: DEFAULT_SAMPLES, + ...opts + }; + const res: Vec[] = []; + const [a, b, c, d] = x.points; + const delta = 1 / opts.num; + for (let t = 0; t < opts.num; t++) { + res.push(mixCubic(a, b, c, d, t * delta)); + } + opts.last && res.push([d[0], d[1]]); + return res; + } +); + +implementations( + Type.QUADRATIC2, + + asCubic, + (x: Quadratic2) => { + const [a, b, c] = x.points; + return [ + new Cubic2( + [ + copy(a), + mixNewN(a, b, 2 / 3), + mixNewN(c, b, 2 / 3), + copy(c) + ], + { ...x.attribs } + ) + ]; + }, + + bounds, + (x: Quadratic2) => { + const [a, b, c] = x.points; + const mi = min(copy(a), c); + const ma = max(copy(a), c); + const solve = (a, b, c) => { + const t = clamp01((a - b) / (a - 2.0 * b + c)); + const s = 1 - t; + return s * s * a + 2.0 * s * t * b + t * t * c; + }; + if (b[0] < mi[0] || b[0] > ma[0] || b[1] < mi[1] || b[1] > ma[1]) { + const q = [ + solve(a[0], b[0], c[0]), + solve(a[1], b[1], c[1]), + ]; + min(mi, q); + max(ma, q); + } + return Rect2.fromMinMax(mi, ma); + }, + + pointAt, + (x: Quadratic2, t: number) => { + const pts = x.points; + return mixQuadratic(pts[0], pts[1], pts[2], t); + }, + + splitAt, + (x: Quadratic2, t: number) => { + const [a, b, c] = x.points; + if (t <= 0 || t >= 1) { + const p = t <= 0 ? a : c; + const c1 = new Quadratic2([copy(p), copy(p), copy(p), copy(p)]); + const c2 = new Quadratic2([copy(a), copy(b), copy(c)]); + return t <= 0 ? [c1, c2] : [c2, c1]; + } + const ab = mixNewN(a, b, t); + const bc = mixNewN(b, c, t); + const p = mixNewN(ab, bc, t); + return [ + new Quadratic2([copy(a), ab, p]), + new Quadratic2([p, bc, copy(c)]) + ]; + }, + + vertices, + (x: Quadratic2, opts?: number | Partial) => { + if (isPlainObject(opts) && (opts).dist !== undefined) { + return new Sampler(vertices(x, (opts).num || DEFAULT_SAMPLES)) + .sampleUniform((opts).dist, (opts).last !== false); + } + opts = isNumber(opts) ? + { + num: opts, + last: true + } : + { + num: DEFAULT_SAMPLES, + ...opts + }; + const res: Vec[] = []; + const delta = 1 / opts.num; + const [a, b, c] = x.points; + for (let t = 0; t < opts.num; t++) { + res.push(mixQuadratic(a, b, c, t * delta)); + } + opts.last && res.push([c[0], c[1]]); + return res; + } + +); + +export function cubic2(points: Vec[], attribs?: Attribs): Cubic2 { + return new Cubic2(points, attribs); +} + +export function quadratic2(points: Vec[], attribs?: Attribs): Quadratic2 { + return new Quadratic2(points, attribs); +} diff --git a/packages/geom2/src/circle.ts b/packages/geom2/src/circle.ts index 827989e92d..47f3ec9f2c 100644 --- a/packages/geom2/src/circle.ts +++ b/packages/geom2/src/circle.ts @@ -1,8 +1,16 @@ import { isNumber } from "@thi.ng/checks/is-number"; import { implementations } from "@thi.ng/defmulti"; import { PI, TAU } from "@thi.ng/math/api"; -import { subNewN, Vec, cartesian } from "@thi.ng/vectors2/api"; -import { vec2n, vec2 } from "@thi.ng/vectors2/vec2"; +import { + cartesian, + dist, + mixNewN, + ReadonlyVec, + subNewN, + Vec, + mulN +} from "@thi.ng/vectors2/api"; +import { circumCenter } from "./internal/circumcenter"; import { arcLength, area, @@ -18,10 +26,22 @@ import { DEFAULT_SAMPLES, } from "./api"; -export function circle2(pos: Vec, r = 1, attribs?: Attribs): Circle2 { +export function circle(pos: Vec, r = 1, attribs?: Attribs): Circle2 { return new Circle2(pos, r, attribs); } +export const circleFrom2Points = + (a: ReadonlyVec, b: ReadonlyVec, attribs?: Attribs) => + new Circle2(mixNewN(a, b, 0.5), dist(a, b) / 2, attribs); + +export const circleFrom3Points = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, attribs?: Attribs) => { + const o = circumCenter(a, b, c); + if (o) { + return new Circle2(o, dist(a, o), attribs); + } + }; + implementations( Type.CIRCLE2, @@ -32,16 +52,18 @@ implementations( (x: Circle2) => TAU * x.r, asPolygon, - (x: Circle2, opts) => new Polygon2(vertices(x, opts), { ...x.attribs }), + (x: Circle2, opts) => + new Polygon2(vertices(x, opts), { ...x.attribs }), bounds, - (x: Circle2) => new Rect2(subNewN(x.pos, x.r), vec2n(x.r * 2)), + (x: Circle2) => + new Rect2(subNewN(x.pos, x.r), mulN([2, 2], x.r)), centroid, (x: Circle2) => x.pos, vertices, - (x: Circle2, opts) => { + (x: Circle2, opts = DEFAULT_SAMPLES) => { const buf: Vec[] = []; const pos = x.pos; const r = x.r; @@ -58,7 +80,7 @@ implementations( const delta = TAU / num; last && num++; for (let i = 0; i < num; i++) { - buf[i] = cartesian(vec2(r, i * delta), pos); + buf[i] = cartesian([r, i * delta], pos); } return buf; } diff --git a/packages/geom2/src/container2.ts b/packages/geom2/src/container2.ts index e1debb6058..c8b6160398 100644 --- a/packages/geom2/src/container2.ts +++ b/packages/geom2/src/container2.ts @@ -1,29 +1,32 @@ import { Vec } from "@thi.ng/vectors2/api"; -import { Vec2 } from "@thi.ng/vectors2/vec2"; import { Attribs, bounds, PointContainer, Rect2, Type, - vertices + vertices, + centroid } from "./api"; import { bounds as _bounds } from "./internal/bounds"; +import { centroid as _centroid } from "./internal/centroid"; import { implementations } from "@thi.ng/defmulti"; +import { Vec2 } from "@thi.ng/vectors2/vec2"; export function points(points: Vec[], attribs?: Attribs) { - return new PointContainer(Type.POINTS2, points, attribs); + return new PointContainer(Type.POINTS2, points, attribs); }; implementations( Type.POINTS2, bounds, - (x: PointContainer) => { - const b = _bounds(x.points, Vec2.MAX.copy(), Vec2.MIN.copy()); - return Rect2.fromMinMax(b[0], b[1]); - }, + (x: PointContainer) => + Rect2.fromMinMax(..._bounds(x.points, [...Vec2.MAX], [...Vec2.MIN])), + + centroid, + (x: PointContainer) => _centroid(x.points), vertices, - (x: PointContainer) => x.points + (x: PointContainer) => x.points ); diff --git a/packages/geom2/src/ellipse.ts b/packages/geom2/src/ellipse.ts new file mode 100644 index 0000000000..b1d50283c7 --- /dev/null +++ b/packages/geom2/src/ellipse.ts @@ -0,0 +1,76 @@ +import { isNumber } from "@thi.ng/checks/is-number"; +import { implementations } from "@thi.ng/defmulti"; +import { sincos } from "@thi.ng/math/angle"; +import { PI, TAU } from "@thi.ng/math/api"; +import { + add, + mul, + mulNewN, + subNew, + Vec, + ones +} from "@thi.ng/vectors2/api"; +import { + arcLength, + area, + bounds, + centroid, + Ellipse2, + Type, + Attribs, + Rect2, + vertices, + Polygon2, + asPolygon, + DEFAULT_SAMPLES, +} from "./api"; + +export function ellipse(pos: Vec, r = ones(2), attribs?: Attribs): Ellipse2 { + return new Ellipse2(pos, r, attribs); +} + +implementations( + Type.ELLIPSE2, + + area, + (x: Ellipse2) => PI * x.r[0] * x.r[1], + + arcLength, + (x: Ellipse2) => { + const a = x.r[0]; + const b = x.r[1]; + return PI * (3 * (a + b) - Math.sqrt((3 * a + b) * (3 * b + a))); + }, + + asPolygon, + (x: Ellipse2, opts) => + new Polygon2(vertices(x, opts), { ...x.attribs }), + + bounds, + (x: Ellipse2) => + new Rect2(subNew(x.pos, x.r), mulNewN(x.r, 2)), + + centroid, + (x: Ellipse2) => x.pos, + + vertices, + (x: Ellipse2, opts = DEFAULT_SAMPLES) => { + const buf: Vec[] = []; + const pos = x.pos; + const r = x.r; + let [num, last] = isNumber(opts) ? + [opts, false] : + [ + opts.theta ? + Math.floor(TAU / opts.theta) : + opts.num || DEFAULT_SAMPLES, + opts.last === true + ]; + const delta = TAU / num; + last && num++; + for (let i = 0; i < num; i++) { + buf[i] = add(mul(sincos(i * delta), r), pos); + } + return buf; + } +); diff --git a/packages/geom2/src/index.ts b/packages/geom2/src/index.ts index 4c7d6abef7..0607772999 100644 --- a/packages/geom2/src/index.ts +++ b/packages/geom2/src/index.ts @@ -1,9 +1,13 @@ export * from "./api"; +export * from "./bezier"; export * from "./circle"; export * from "./container2"; +export * from "./ellipse"; export * from "./group"; export * from "./polygon"; +export * from "./polyline"; export * from "./quad"; export * from "./rect"; export * from "./svg"; +export * from "./tessellate"; diff --git a/packages/geom2/src/internal/arc-length.ts b/packages/geom2/src/internal/arc-length.ts new file mode 100644 index 0000000000..8495fbd5f8 --- /dev/null +++ b/packages/geom2/src/internal/arc-length.ts @@ -0,0 +1,14 @@ +import { dist, ReadonlyVec } from "@thi.ng/vectors2/api"; + +export const arcLength = (pts: ReadonlyVec[], closed = false) => { + const num = pts.length; + if (num < 2) return 0; + let res = 0; + let p = pts[0]; + let q = pts[1]; + for (let i = 1; i < num; i++ , p = q, q = pts[i]) { + res += dist(p, q); + } + closed && (res += dist(p, pts[0])); + return res; +}; diff --git a/packages/geom2/src/internal/area.ts b/packages/geom2/src/internal/area.ts new file mode 100644 index 0000000000..47b75aeb20 --- /dev/null +++ b/packages/geom2/src/internal/area.ts @@ -0,0 +1,10 @@ +import { ReadonlyVec } from "@thi.ng/vectors2/api"; +import { cross2 } from "@thi.ng/vectors2/vec2"; + +export const polygonArea = (pts: ReadonlyVec[]) => { + let res = 0; + for (let n = pts.length - 1, i = n, j = 0; n >= 0; i = j, j++ , n--) { + res += cross2(pts[i], pts[j]); + } + return res / 2; +}; diff --git a/packages/geom2/src/internal/barycentric.ts b/packages/geom2/src/internal/barycentric.ts new file mode 100644 index 0000000000..65b395400f --- /dev/null +++ b/packages/geom2/src/internal/barycentric.ts @@ -0,0 +1,32 @@ +import { + dot, + maddN, + magSq, + mulNewN, + ReadonlyVec, + setS, + subNew, + Vec +} from "@thi.ng/vectors2/api"; + +export const toBarycentric = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, p: ReadonlyVec, out: Vec) => { + + const u = subNew(b, a); + const v = subNew(c, a); + const w = subNew(p, a); + const uu = magSq(u); + const vv = magSq(v); + const uv = dot(u, v); + const uw = dot(u, w); + const vw = dot(v, w); + const d = 1 / (uv * uv - uu * vv); + const s = d * (uv * vw - vv * uw); + const t = d * (uv * uw - uu * vw); + + return setS(out, 1 - (s + t), s, t); + }; + +export const fromBarycentric = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, p: ReadonlyVec, out: Vec) => + maddN(maddN(mulNewN(a, p[0], out), b, p[1]), c, p[2]); diff --git a/packages/geom2/src/internal/bounds.ts b/packages/geom2/src/internal/bounds.ts index bf69f114e8..b0a6ee067f 100644 --- a/packages/geom2/src/internal/bounds.ts +++ b/packages/geom2/src/internal/bounds.ts @@ -1,4 +1,4 @@ -import { max, min, Vec, addNew, sub } from "@thi.ng/vectors2/api"; +import { max, min, Vec, addNew, sub, ReadonlyVec } from "@thi.ng/vectors2/api"; import { bounds as _bounds, Shape, union } from "../api"; export const bounds = @@ -24,9 +24,9 @@ export const collBounds = }; export const unionBounds = - (pos1: Vec, size1: Vec, pos2: Vec, size2: Vec): [Vec, Vec] => { + (pos1: ReadonlyVec, size1: ReadonlyVec, pos2: ReadonlyVec, size2: ReadonlyVec): [Vec, Vec] => { const p = addNew(pos1, size1); const q = addNew(pos2, size2); const pos = min([...pos1], pos2); - return [pos, sub(max(p, q), pos)] + return [pos, sub(max(p, q), pos)]; }; diff --git a/packages/geom2/src/internal/centroid.ts b/packages/geom2/src/internal/centroid.ts new file mode 100644 index 0000000000..d44a3cc3b8 --- /dev/null +++ b/packages/geom2/src/internal/centroid.ts @@ -0,0 +1,29 @@ +import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { ReadonlyVec, Vec, empty, add, divN, setS } from "@thi.ng/vectors2/api"; +import { cross2 } from "@thi.ng/vectors2/vec2"; + +export const centroid = (pts: ReadonlyVec[], c?: Vec) => { + const num = pts.length; + !num && illegalArgs("no points available"); + !c && (c = empty(pts[0])); + for (let i = num; --i >= 0;) { + add(c, pts[i]); + } + return divN(c, num); +}; + +export const centerOfWeight2 = (pts: ReadonlyVec[], c?: Vec) => { + let area = 0; + let x = 0; + let y = 0; + for (let n = pts.length - 1, i = pts[n], j = pts[0], k = 0; k <= n; k++ , i = j, j = pts[k]) { + const z = cross2(i, j); + area += z; + x += (i[0] + j[0]) * z; + y += (i[1] + j[1]) * z; + } + area = 1 / (area * 3); + x *= area; + y *= area; + return c ? setS(c, x, y) : [x, y]; +}; diff --git a/packages/geom2/src/internal/circumcenter.ts b/packages/geom2/src/internal/circumcenter.ts new file mode 100644 index 0000000000..56e1777dc7 --- /dev/null +++ b/packages/geom2/src/internal/circumcenter.ts @@ -0,0 +1,43 @@ +import { EPS } from "@thi.ng/math/api"; +import { ReadonlyVec } from "@thi.ng/vectors2/api"; + +export const circumCenter = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, eps = EPS) => { + + const deltaAB = Math.abs(a[1] - b[1]); + const deltaBC = Math.abs(b[1] - c[1]); + if (deltaAB < eps && deltaBC < eps) { + return null; + } + const ax = a[0], ay = a[1]; + const bx = b[0], by = b[1]; + const cx = c[0], cy = c[1]; + let m1, m2, mx1, mx2, my1, my2, xc, yc; + if (deltaAB < eps) { + m2 = - (cx - bx) / (cy - by); + mx2 = (bx + cx) / 2; + my2 = (by + cy) / 2; + xc = (bx + ax) / 2; + yc = m2 * (xc - mx2) + my2; + } else if (deltaBC < eps) { + m1 = - (bx - ax) / (by - ay); + mx1 = (ax + bx) / 2; + my1 = (ay + by) / 2; + xc = (cx + bx) / 2; + yc = m1 * (xc - mx1) + my1; + } else { + m1 = - (bx - ax) / (by - ay); + m2 = - (cx - bx) / (cy - by); + mx1 = (ax + bx) / 2; + my1 = (ay + by) / 2; + mx2 = (bx + cx) / 2; + my2 = (by + cy) / 2; + xc = (m1 * mx1 - m2 * mx2 + my2 - my1) / (m1 - m2); + if (deltaAB > deltaBC) { + yc = m1 * (xc - mx1) + my1; + } else { + yc = m2 * (xc - mx2) + my2; + } + } + return [xc, yc]; + }; diff --git a/packages/geom2/src/internal/closest-point.ts b/packages/geom2/src/internal/closest-point.ts new file mode 100644 index 0000000000..36b10621d6 --- /dev/null +++ b/packages/geom2/src/internal/closest-point.ts @@ -0,0 +1,103 @@ +import { + distSq, + dot, + empty, + magSq, + mixNewN, + ReadonlyVec, + set, + subNew, + Vec +} from "@thi.ng/vectors2/api"; + +export const closestPoint = + (p: ReadonlyVec, pts: Vec[]) => { + + let minD = Infinity; + let closest: Vec; + for (let i = pts.length; --i >= 0;) { + const d = distSq(pts[i], p); + if (d < minD) { + minD = d; + closest = pts[i]; + } + } + return closest; + }; + +export const closestCoeff = + (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec) => { + + const d = subNew(b, a); + const l = magSq(d); + if (l > 1e-6) { + return dot(subNew(p, a), d) / l; + } + }; + +export const closestPointSegment = + (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, out: Vec) => { + + const t = closestCoeff(p, a, b); + if (t !== undefined) { + return t <= 0.0 ? + set(out, a) : + t >= 1.0 ? + set(out, b) : + mixNewN(a, b, t, out); + } + }; + +export const closestPointPolyline = + (p: ReadonlyVec, pts: ReadonlyArray, closed = false) => { + + const closest = empty(pts[0]); + const tmp = empty(closest); + const n = pts.length - 1; + let minD = Infinity, i, j; + if (closed) { + i = n; + j = 0; + } else { + i = 0; + j = 1; + } + for (; j <= n; i = j, j++) { + if (closestPointSegment(p, pts[i], pts[j], tmp)) { + const d = distSq(p, tmp); + if (d < minD) { + minD = d; + set(closest, tmp); + } + } + } + return closest; + }; + +/** + * Returns the index of the start point containing the segment in the + * polyline array `points` farthest away from `p` with regards to the + * line segment `a` to `b`. `points` is only checked between indices + * `from` and `to` (not including the latter). + * + * @param a + * @param b + * @param points + * @param from + * @param to + */ +export const farthestPointSegment = + (a: Vec, b: Vec, points: Vec[], from = 0, to = points.length) => { + let maxD = -1; + let maxIdx; + const tmp = empty(a); + for (let i = from; i < to; i++) { + const p = points[i]; + const d = distSq(p, closestPointSegment(p, a, b, tmp) || a); + if (d > maxD) { + maxD = d; + maxIdx = i; + } + } + return [maxIdx, Math.sqrt(maxD)]; + }; diff --git a/packages/geom2/src/internal/corner.ts b/packages/geom2/src/internal/corner.ts index aac56f7e7d..1fe380bb8c 100644 --- a/packages/geom2/src/internal/corner.ts +++ b/packages/geom2/src/internal/corner.ts @@ -1,24 +1,24 @@ import { sign } from "@thi.ng/math/abs"; import { EPS } from "@thi.ng/math/api"; -import { Vec } from "@thi.ng/vectors2/api"; +import { ReadonlyVec } from "@thi.ng/vectors2/api"; export const corner = - (a: Readonly, b: Readonly, c: Readonly) => { + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => { const ax = a[0]; const ay = a[1]; return (b[0] - ax) * (c[1] - ay) - (c[0] - ax) * (b[1] - ay); }; export const classify = - (a: Readonly, b: Readonly, c: Readonly, eps = EPS) => + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, eps = EPS) => sign(corner(a, b, c), eps); export const clockwise2 = - (a: Readonly, b: Readonly, c: Readonly) => + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => corner(a, b, c) < 0; export const classifyPointInTriangle2 = - (p: Readonly, a: Readonly, b: Readonly, c: Readonly) => { + (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => { const s = clockwise2(a, b, c) ? 1 : -1; return sign( Math.min( @@ -30,7 +30,7 @@ export const classifyPointInTriangle2 = }; export const pointInTriangle2 = - (p: Readonly, a: Readonly, b: Readonly, c: Readonly) => { + (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => { const s = clockwise2(a, b, c) ? 1 : -1; return s * corner(a, c, p) >= 0 && s * corner(b, a, p) >= 0 && diff --git "a/packages/geom2/src/internal/douglas\342\200\223peucker.ts" "b/packages/geom2/src/internal/douglas\342\200\223peucker.ts" new file mode 100644 index 0000000000..3bb09c75a4 --- /dev/null +++ "b/packages/geom2/src/internal/douglas\342\200\223peucker.ts" @@ -0,0 +1,43 @@ +import { peek } from "@thi.ng/transducers/func/peek"; +import { Vec, eqDelta } from "@thi.ng/vectors2/api"; +import { farthestPointSegment } from "./closest-point"; + +// https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm + +export const douglasPeucker2 = + (pts: Vec[], eps = 0, closed = false) => { + + let num = pts.length; + const visited: boolean[] = []; + if (num <= 2) { + return pts.slice(); + } + if (closed && !eqDelta(pts[0], peek(pts))) { + pts = pts.slice(); + pts.push(pts[0]); + num++; + } + + const $ = (from: number, to: number) => { + visited[from] = visited[to] = true; + if (to <= from + 1) { + return; + } + const [maxIdx, maxD] = farthestPointSegment(pts[from], pts[to], pts, from + 1, to); + if (maxD <= eps) { + return; + } + $(from, maxIdx); + $(maxIdx, to); + }; + + $(0, num - 1); + + const res: Vec[] = []; + for (let i = 0, n = closed ? num - 1 : num; i < n; i++) { + if (visited[i]) { + res.push(pts[i]); + } + } + return res; + }; diff --git a/packages/geom2/src/internal/graham-scan.ts b/packages/geom2/src/internal/graham-scan.ts index 9506ee2271..9d0eb6d0c5 100644 --- a/packages/geom2/src/internal/graham-scan.ts +++ b/packages/geom2/src/internal/graham-scan.ts @@ -10,29 +10,30 @@ import { comparator2 } from "@thi.ng/vectors2/vec2"; * * @param pts */ -export const convexHull2 = (pts: ReadonlyArray) => { - const num = pts.length; - const res: Vec[] = []; - let h = 0, i; - pts = pts.slice().sort(comparator2(0, 1)); +export const grahamScan2 = + (pts: ReadonlyArray) => { + const num = pts.length; + const res: Vec[] = []; + let h = 0, i; + pts = pts.slice().sort(comparator2(0, 1)); - const scan = (p: Vec, thresh: number) => { - while (h >= thresh && corner(res[h - 2], res[h - 1], p) >= 0) { - res.pop(); - h--; + const scan = (p: Vec, thresh: number) => { + while (h >= thresh && corner(res[h - 2], res[h - 1], p) >= 0) { + res.pop(); + h--; + } + res[h++] = p; + }; + + for (i = 0; i < num; i++) { + scan(pts[i], 2); + } + res.pop(); + h--; + const h2 = h + 2; + for (i = num - 1; i >= 0; i--) { + scan(pts[i], h2); } - res[h++] = p; + res.pop(); + return res; }; - - for (i = 0; i < num; i++) { - scan(pts[i], 2); - } - res.pop(); - h--; - const h2 = h + 2; - for (i = num - 1; i >= 0; i--) { - scan(pts[i], h2); - } - res.pop(); - return res; -}; diff --git a/packages/geom2/src/internal/liang-barsky.ts b/packages/geom2/src/internal/liang-barsky.ts new file mode 100644 index 0000000000..a2ec19e91d --- /dev/null +++ b/packages/geom2/src/internal/liang-barsky.ts @@ -0,0 +1,53 @@ +import { EPS } from "@thi.ng/math/api"; +import { Vec, setS } from "@thi.ng/vectors2/api"; + +// https://en.wikipedia.org/wiki/Liang%E2%80%93Barsky_algorithm +// https://github.com/thi-ng/c-thing/blob/master/src/geom/clip/liangbarsky.c + +export const liangBarsky2 = + (la: Vec, lb: Vec, tl: Vec, br: Vec, ca?: Vec, cb?: Vec): [Vec, Vec, number, number] => { + const lax = la[0]; + const lay = la[1]; + const dx = lb[0] - lax; + const dy = lb[1] - lay; + let a = 0; + let b = 1; + + const clip = (p: number, q: number) => { + if (q < 0 && Math.abs(p) < EPS) { + return 0; + } + const r = q / p; + if (p < 0) { + if (r > b) { + return false; + } else if (r > a) { + a = r; + } + } else if (p > 0) { + if (r < a) { + return false; + } else if (r < b) { + b = r; + } + } + return true; + }; + + if (!( + clip(-dx, -(tl[0] - lax)) && + clip(dx, br[0] - lax) && + clip(-dy, -(tl[1] - lay)) && + clip(dy, br[1] - lay) + )) { + return; + } + + !ca && (ca = [0, 0]); + !cb && (cb = [0, 0]); + + setS(ca, a * dx + lax, a * dy + lay); + setS(cb, b * dx + lax, b * dy + lay); + + return [ca, cb, a, b]; + }; diff --git a/packages/geom2/src/internal/line-intersection.ts b/packages/geom2/src/internal/line-intersection.ts new file mode 100644 index 0000000000..6abb57fade --- /dev/null +++ b/packages/geom2/src/internal/line-intersection.ts @@ -0,0 +1,31 @@ +import { LineIntersection, LineIntersectionType } from "../api"; +import { ReadonlyVec, mixNewN } from "@thi.ng/vectors2/api"; + +export const intersectLines2 = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec) => { + const bax = b[0] - a[0]; + const bay = b[1] - a[1]; + const dcx = d[0] - c[0]; + const dcy = d[1] - c[1]; + const acx = a[0] - c[0]; + const acy = a[1] - c[1]; + const det = dcy * bax - dcx * bay; + let alpha = dcx * acy - dcy * acx; + let beta = bax * acy - bay * acx; + if (det === 0) { + if (alpha === 0 && beta === 0) { + return { type: LineIntersectionType.COINCIDENT }; + } + return { type: LineIntersectionType.PARALLEL }; + } + alpha /= det; + beta /= det; + return { + type: (0 <= alpha && alpha <= 1) && (0 <= beta && beta <= 1) ? + LineIntersectionType.INTERSECT : + LineIntersectionType.INTERSECT_OUTSIDE, + isec: mixNewN(a, b, alpha), + alpha, + beta, + det, + }; +}; diff --git a/packages/geom2/src/internal/sampler.ts b/packages/geom2/src/internal/sampler.ts new file mode 100644 index 0000000000..830b9acb33 --- /dev/null +++ b/packages/geom2/src/internal/sampler.ts @@ -0,0 +1,77 @@ +import { peek } from "@thi.ng/transducers/func/peek"; +import { + copy, + dist, + mixNewN, + ReadonlyVec, + Vec +} from "@thi.ng/vectors2/api"; + +export class Sampler { + + points: ReadonlyVec[]; + index: number[]; + + constructor(points: ReadonlyVec[], closed = false) { + if (closed) { + this.points = points.slice(); + this.points.push(points[0]); + } else { + this.points = points; + } + this.buildIndex(); + } + + pointAt(t: number) { + const pts = this.points; + const n = pts.length - 1; + if (n < 0) { + return; + } + if (n === 0 || t <= 0) { + return pts[0]; + } + if (t >= 1) { + return pts[n]; + } + const idx = this.index; + const t0 = t * idx[n]; + for (let i = 1; i <= n; i++) { + if (idx[i] >= t0) { + return mixNewN(pts[i - 1], pts[i], (t0 - idx[i - 1]) / (idx[i] - idx[i - 1])); + } + } + } + + sampleUniform(dist: number, includeLast = false, result: Vec[] = []) { + const index = this.index; + const total = peek(index); + const delta = dist / total; + const n = index.length; + for (let t = 0, i = 1; t < 1; t += delta) { + const ct = t * total; + while (ct >= index[i] && i < n) { i++; } + if (i >= n) break; + const p = index[i - 1]; + result.push(mixNewN(this.points[i - 1], this.points[i], (ct - p) / (index[i] - p))); + } + if (includeLast) { + result.push(copy(this.points[this.points.length - 1])); + } + return result; + } + + sampleFixedNum(num: number, includeLast = false, result?: Vec[]) { + return this.sampleUniform(peek(this.index) / num, includeLast, result); + } + + protected buildIndex() { + const idx: number[] = [0]; + const pts = this.points; + const n = pts.length; + for (let i = 0, j = 1; j < n; i = j, j++) { + idx[j] = idx[i] + dist(pts[i], pts[j]); + } + this.index = idx; + } +} diff --git a/packages/geom2/src/internal/sutherland-hodgeman.ts b/packages/geom2/src/internal/sutherland-hodgeman.ts new file mode 100644 index 0000000000..d35b8012a9 --- /dev/null +++ b/packages/geom2/src/internal/sutherland-hodgeman.ts @@ -0,0 +1,44 @@ +import { ReadonlyVec } from "@thi.ng/vectors2/api"; +import { classify } from "./corner"; +import { intersectLines2 } from "./line-intersection"; + +/** + * Extended version of Sutherland-Hodgeman convex polygon clipping + * supporting any convex boundary (not only rects). Returns new array of + * clipped vertices. + * + * https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm + * + * @param pts subject poly vertices + * @param bounds clipping boundary vertices + * @param bc pre-computed boundary centroid + * @param eps edge classification tolerance + */ +export const sutherlandHodgeman = + (pts: ReadonlyVec[], bounds: ReadonlyVec[], bc: ReadonlyVec, eps = 1e-4) => { + for (let ne = bounds.length, j = ne - 1, i = 0; i < ne; j = i, i++) { + const clipped = []; + const ca = bounds[j]; + const cb = bounds[i]; + const sign = classify(ca, cb, bc, eps); + for (let np = pts.length, k = np - 1, l = 0; l < np; k = l, l++) { + const p = pts[k]; + const q = pts[l]; + const cqsign = classify(ca, cb, q, eps); + if (classify(ca, cb, p, eps) === sign) { + clipped.push( + cqsign !== sign ? + intersectLines2(ca, cb, p, q).isec : + q + ); + } else if (cqsign === sign) { + clipped.push(intersectLines2(ca, cb, p, q).isec, q); + } + } + if (clipped.length < 2) { + return []; + } + pts = clipped; + } + return pts; + }; diff --git a/packages/geom2/src/polygon.ts b/packages/geom2/src/polygon.ts index 0c7828ffd6..afdc03b59b 100644 --- a/packages/geom2/src/polygon.ts +++ b/packages/geom2/src/polygon.ts @@ -1,6 +1,31 @@ -import { Polygon2, Attribs, Type, bounds } from "./api"; +import { isPlainObject } from "@thi.ng/checks/is-plain-object"; +import { implementations } from "@thi.ng/defmulti"; import { Vec } from "@thi.ng/vectors2/api"; -import { convexHull2 } from "./internal/graham-scan"; +import { + arcLength, + area, + Attribs, + bounds, + centroid, + convexHull, + Polygon2, + resample, + SamplingOpts, + Shape, + simplify, + tessellate, + Tessellator, + Type, + vertices +} from "./api"; +import { arcLength as _arcLength } from "./internal/arc-length"; +import { polygonArea } from "./internal/area"; +import { centerOfWeight2 } from "./internal/centroid"; +import { grahamScan2 } from "./internal/graham-scan"; +import { Sampler } from "./internal/sampler"; +import { sutherlandHodgeman } from "./internal/sutherland-hodgeman"; +import { tessellatePoints } from "./tessellate"; +import { douglasPeucker2 } from "./internal/douglas–peucker"; export function polygon(points: Vec[], attribs?: Attribs): Polygon2 { return new Polygon2(points, attribs); @@ -9,6 +34,54 @@ export function polygon(points: Vec[], attribs?: Attribs): Polygon2 { const type = Type.POLYGON2; bounds.isa(type, Type.POINTS2); +vertices.isa(type, Type.POINTS2); -export const convexHull = (poly: Polygon2) => - convexHull2(poly.points); +implementations( + type, + + arcLength, + (x: Polygon2) => _arcLength(x.points, true), + + area, + (x: Polygon2, signed = true) => { + const area = polygonArea(x.points); + return signed ? area : Math.abs(area); + }, + + centroid, + (x: Polygon2, c: Vec) => centerOfWeight2(x.points, c), + + convexHull, + (poly: Polygon2) => grahamScan2(poly.points), + + resample, + (x: Polygon2, opts?: number | SamplingOpts) => + new Polygon2(vertices(x, opts), { ...this.attribs }), + + simplify, + (x: Polygon2, eps = 0.1) => + new Polygon2( + douglasPeucker2(x.points, eps, true), + { ...this.attribs } + ), + + tessellate, + (x: Polygon2, tessel: Iterable) => + tessellatePoints(x.points, tessel), + + vertices, + (x: Polygon2, opts?: number | SamplingOpts) => { + if (opts !== undefined) { + const sampler = new Sampler(x.points, true); + return isPlainObject(opts) ? + opts.dist ? + sampler.sampleUniform(opts.dist, opts.last) : + sampler.sampleFixedNum(opts.num, opts.last) : + sampler.sampleFixedNum(opts, false); + } + return x.points; + }, +); + +export const clipConvex = (poly: Polygon2, boundary: Shape) => + sutherlandHodgeman(poly.points, vertices(boundary), centroid(boundary)); diff --git a/packages/geom2/src/polyline.ts b/packages/geom2/src/polyline.ts new file mode 100644 index 0000000000..52ed6d9778 --- /dev/null +++ b/packages/geom2/src/polyline.ts @@ -0,0 +1,68 @@ +import { isPlainObject } from "@thi.ng/checks/is-plain-object"; +import { implementations } from "@thi.ng/defmulti"; +import { Vec } from "@thi.ng/vectors2/api"; +import { + arcLength, + Attribs, + bounds, + centroid, + convexHull, + DEFAULT_SAMPLES, + Polyline2, + resample, + SamplingOpts, + simplify, + Type, + vertices +} from "./api"; +import { arcLength as _arcLength } from "./internal/arc-length"; +import { centroid as _centroid } from "./internal/centroid"; +import { grahamScan2 } from "./internal/graham-scan"; +import { Sampler } from "./internal/sampler"; +import { douglasPeucker2 } from "./internal/douglas–peucker"; + +export function polyline(points: Vec[], attribs?: Attribs): Polyline2 { + return new Polyline2(points, attribs); +} + +const type = Type.POLYLINE2; + +bounds.isa(type, Type.POINTS2); +vertices.isa(type, Type.POINTS2); + +implementations( + type, + + arcLength, + (x: Polyline2) => _arcLength(x.points, false), + + centroid, + (x: Polyline2, c: Vec) => _centroid(x.points, c), + + convexHull, + (poly: Polyline2) => grahamScan2(poly.points), + + resample, + (x: Polyline2, opts?: number | SamplingOpts) => + new Polyline2(vertices(x, opts), { ...this.attribs }), + + simplify, + (x: Polyline2, eps = 0.1) => + new Polyline2( + douglasPeucker2(x.points, eps, true), + { ...this.attribs } + ), + + vertices, + (x: Polyline2, opts?: number | SamplingOpts) => { + if (opts !== undefined) { + const sampler = new Sampler(x.points, false); + return isPlainObject(opts) ? + opts.dist ? + sampler.sampleUniform(opts.dist, opts.last !== false) : + sampler.sampleFixedNum(opts.num, opts.last !== false) : + sampler.sampleFixedNum(opts || DEFAULT_SAMPLES, true); + } + return x.points; + }, +); diff --git a/packages/geom2/src/quad.ts b/packages/geom2/src/quad.ts index 1d9df64aad..8e7541d742 100644 --- a/packages/geom2/src/quad.ts +++ b/packages/geom2/src/quad.ts @@ -1,4 +1,4 @@ -import { Quad2, Attribs, bounds, Type, centroid, area, vertices } from "./api"; +import { Quad2, Attribs, bounds, Type, centroid, area, vertices, tessellate } from "./api"; import { Vec } from "@thi.ng/vectors2/api"; export function quad(points: Vec[], attribs?: Attribs): Quad2 { @@ -10,4 +10,5 @@ const type = Type.QUAD2; area.isa(type, Type.POLYGON2); bounds.isa(type, Type.POINTS2); centroid.isa(type, Type.POLYGON2); +tessellate.isa(type, Type.POLYGON2); vertices.isa(type, Type.POINTS2); diff --git a/packages/geom2/src/rect.ts b/packages/geom2/src/rect.ts index e14a7c0267..6e9e6e6e8a 100644 --- a/packages/geom2/src/rect.ts +++ b/packages/geom2/src/rect.ts @@ -1,6 +1,10 @@ import { implementations } from "@thi.ng/defmulti"; -import { addNew, maddNewN, Vec } from "@thi.ng/vectors2/api"; -import { Vec2, vec2 } from "@thi.ng/vectors2/vec2"; +import { + addNew, + copy, + maddNewN, + Vec +} from "@thi.ng/vectors2/api"; import { arcLength, area, @@ -10,16 +14,22 @@ import { centroid, Polygon2, Rect2, + tessellate, + Tessellator, Type, union, vertices } from "./api"; import { unionBounds } from "./internal/bounds"; +import { tessellatePoints } from "./tessellate"; -export function rect(pos: Vec, size: Vec, attribs?: Attribs): Rect2 { +export function rect(pos: Vec, size: Vec, attribs?: Attribs) { return new Rect2(pos, size, attribs); } +export const rectFromMinMax = (min: Vec, max: Vec, attribs?: Attribs) => + Rect2.fromMinMax(min, max, attribs); + implementations( Type.RECT2, @@ -36,7 +46,11 @@ implementations( (x: Rect2) => x, centroid, - (x: Rect2, o = vec2()) => maddNewN(x.pos, x.size, 0.5, o), + (x: Rect2, o?: Vec) => maddNewN(x.pos, x.size, 0.5, o), + + tessellate, + (x: Rect2, tessel: Tessellator | Iterable, iter?: number) => + tessellatePoints(vertices(x), tessel, iter), union, (r1: Rect2, r2: Rect2) => @@ -45,7 +59,7 @@ implementations( vertices, (x: Rect2) => { const p = x.pos; - const q = addNew(p, x.size, vec2()); - return [p.copy(), vec2(q.x, p.y), q, vec2(p.x, q.y)]; + const q = addNew(p, x.size); + return [copy(p), [q[0], p[1]], q, [p[0], q[1]]]; } ); diff --git a/packages/geom2/src/svg.ts b/packages/geom2/src/svg.ts index 0ff947a34b..2488867e5f 100644 --- a/packages/geom2/src/svg.ts +++ b/packages/geom2/src/svg.ts @@ -8,12 +8,12 @@ export const asSVG = (...args: any[]) => serialize(convertTree(args)); export const svgDoc = (attribs, ...args: Shape[]) => { - const bounds = collBounds(args); + const b = collBounds(args); attribs = { - width: bounds.size.x, - height: bounds.size.y, - viewBox: `${bounds.pos.x} ${bounds.pos.y} ${bounds.size.x} ${bounds.size.y}`, + width: b.size[0], + height: b.size[1], + viewBox: `${b.pos[0]} ${b.pos[1]} ${b.size[0]} ${b.size[1]}`, ...attribs }; - return asSVG(svg(attribs, ...args)); + return svg(attribs, ...args); }; diff --git a/packages/geom2/src/tessellate.ts b/packages/geom2/src/tessellate.ts new file mode 100644 index 0000000000..7115e30397 --- /dev/null +++ b/packages/geom2/src/tessellate.ts @@ -0,0 +1,159 @@ +import { isFunction } from "@thi.ng/checks/is-function"; +import { comp } from "@thi.ng/transducers/func/comp"; +import { range } from "@thi.ng/transducers/iter/range"; +import { repeat } from "@thi.ng/transducers/iter/repeat"; +import { tuples } from "@thi.ng/transducers/iter/tuples"; +import { wrap } from "@thi.ng/transducers/iter/wrap"; +import { reducer } from "@thi.ng/transducers/reduce"; +import { last } from "@thi.ng/transducers/rfn/last"; +import { push } from "@thi.ng/transducers/rfn/push"; +import { transduce } from "@thi.ng/transducers/transduce"; +import { map } from "@thi.ng/transducers/xform/map"; +import { mapcat } from "@thi.ng/transducers/xform/mapcat"; +import { partition } from "@thi.ng/transducers/xform/partition"; +import { scan } from "@thi.ng/transducers/xform/scan"; +import { mixNewN, ReadonlyVec, Vec } from "@thi.ng/vectors2/api"; +import { Tessellator } from "./api"; +import { polygonArea } from "./internal/area"; +import { centroid } from "./internal/centroid"; +import { corner, pointInTriangle2 } from "./internal/corner"; + +const snip = (points: ReadonlyVec[], u: number, v: number, w: number, n: number, ids: number[]) => { + const a = points[ids[u]]; + const b = points[ids[v]]; + const c = points[ids[w]]; + if (corner(a, b, c) > 0) { + for (let i = 0; i < n; i++) { + if (i !== u && i !== v && i !== w) { + if (pointInTriangle2(points[ids[i]], a, b, c)) { + return; + } + } + } + return [a, b, c]; + } +}; + +export const earCut = (points: ReadonlyVec[]) => { + const tris: Vec[][] = []; + let n = points.length; + const ids = [ + ...(polygonArea(points) > 0 ? + range(n) : + range(n - 1, -1, -1)) + ]; + let count = 2 * n - 1; + let v = n - 1, u, w, t; + while (count > 0 && n > 2) { + u = n <= v ? 0 : v; + v = u + 1; + v = n <= v ? 0 : v; + w = v + 1; + w = n <= w ? 0 : w; + t = snip(points, u, v, w, n, ids); + if (t !== undefined) { + tris.push(t); + ids.splice(v, 1); + n--; + count = 2 * n; + } else { + count--; + } + } + return tris; +}; + +export const triFan = (points: ReadonlyVec[]) => { + const c = centroid(points); + return transduce( + comp( + partition(2, 1), + map(([a, b]) => [a, b, c]) + ), + push(), + wrap(points, 1, false, true) + ); +}; + +export const quadFan = (points: ReadonlyVec[]) => { + const p = centroid(points); + return transduce( + comp( + partition(3, 1), + map(([a, b, c]) => [mixNewN(a, b, 0.5), b, mixNewN(b, c, 0.5), p]) + ), + push(), + wrap(points, 1, true, true) + ); +}; + +export const edgeSplit = (points: ReadonlyVec[]) => { + const c = centroid(points); + return transduce( + comp( + partition(2, 1), + mapcat(([a, b]) => { + const m = mixNewN(a, b, 0.5); + return [[a, m, c], [m, b, c]]; + })), + push(), + wrap(points, 1, false, true) + ); +}; + +export const rimTris = (points: ReadonlyVec[]) => { + const edgeCentroids = transduce( + comp( + partition(2, 1), + map((e) => mixNewN(e[0], e[1], 0.5)) + ), + push(), + wrap(points, 1, false, true) + ); + return transduce( + comp( + partition(2, 1), + map((t) => [t[0][0], t[1][1], t[1][0]]) + ), + push(), + [edgeCentroids], + wrap([...tuples(edgeCentroids, points)], 1, true, false) + ); +}; + +export const inset = (inset = 0.5, keepInterior = false) => + (points: ReadonlyVec[]) => { + const c = centroid(points); + const inner = points.map((p) => mixNewN(p, c, inset)); + return transduce( + comp( + partition(2, 1), + map(([[a, b], [c, d]]) => [a, b, d, c]) + ), + push(), + keepInterior ? [inner] : [], + wrap([...tuples(points, inner)], 1, false, true) + ); + }; + +export function tessellatePoints(points: ReadonlyVec[], tessFn: Tessellator, iter?: number): Vec[][]; +export function tessellatePoints(points: ReadonlyVec[], tessFns: Iterable): Vec[][]; +export function tessellatePoints(...args): Vec[][] { + return transduce( + scan( + reducer( + () => [args[0]], + (acc: Vec[][], fn: Tessellator) => + transduce( + mapcat(fn), + push(), + acc + ) + ) + ), + last(), + isFunction(args[1]) ? + repeat(args[1], args[2] || 1) : + args[1] + ); +} From e3727ce937824b1ed889fac6d66e488d4684a53e Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 27 Oct 2018 22:42:16 +0100 Subject: [PATCH 009/333] refactor(malloc): add/extract types to api.ts --- packages/malloc/src/api.ts | 51 ++++++++++++++++++++++++++++++++++++ packages/malloc/src/index.ts | 38 ++++++++------------------- 2 files changed, 62 insertions(+), 27 deletions(-) create mode 100644 packages/malloc/src/api.ts diff --git a/packages/malloc/src/api.ts b/packages/malloc/src/api.ts new file mode 100644 index 0000000000..2ecfd0692f --- /dev/null +++ b/packages/malloc/src/api.ts @@ -0,0 +1,51 @@ +import { IRelease, TypedArray } from "@thi.ng/api/api"; + +export const enum Type { + U8, + U8C, + I8, + U16, + I16, + U32, + I32, + F32, + F64 +}; + +export interface MemBlock { + addr: number; + size: number; + next: MemBlock; +} + +export interface MemPoolOpts { + start: number; + end: number; + compact: boolean; + split: boolean; + minSplit: number; +} + +export interface MemPoolStats { + free: { count: number, size: number }; + used: { count: number, size: number }; + top: number; + available: number; + total: number; +} + +export interface IMemPool extends IRelease { + malloc(size: number): number; + + calloc(size: number): number; + + mallocAs(type: Type, num: number): TypedArray; + + callocAs(type: Type, num: number): TypedArray; + + free(ptr: number | TypedArray): boolean; + + freeAll(); + + stats(): MemPoolStats; +} diff --git a/packages/malloc/src/index.ts b/packages/malloc/src/index.ts index b99cca4c6f..b31143079b 100644 --- a/packages/malloc/src/index.ts +++ b/packages/malloc/src/index.ts @@ -1,19 +1,16 @@ -import { IObjectOf, IRelease, TypedArray } from "@thi.ng/api"; +import { IObjectOf, TypedArray } from "@thi.ng/api"; import { align } from "@thi.ng/binary/align"; import { isNumber } from "@thi.ng/checks/is-number"; import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { + IMemPool, + MemBlock, + MemPoolOpts, + Type, + MemPoolStats +} from "./api"; -export const enum Type { - U8, - U8C, - I8, - U16, - I16, - U32, - I32, - F32, - F64 -}; +export * from "./api"; type BlockCtor = (buf: ArrayBuffer, addr: number, num: number) => TypedArray; @@ -41,21 +38,8 @@ const SIZEOF = { [Type.F64]: 8, }; -export interface MemBlock { - addr: number; - size: number; - next: MemBlock; -} - -export interface MemPoolOpts { - start: number; - end: number; - compact: boolean; - split: boolean; - minSplit: number; -} export class MemPool implements - IRelease { + IMemPool { buf: ArrayBuffer; protected top: number; @@ -89,7 +73,7 @@ export class MemPool implements this._used = null; } - stats() { + stats(): MemPoolStats { const listStats = (block: MemBlock) => { let count = 0; let size = 0; From 766fdee2f7468e64d5677ed957a6309c8d07b629 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 31 Oct 2018 12:04:47 +0000 Subject: [PATCH 010/333] feat(vectors): re-add vec4, mat23/33/44, nd arrays - add NDArray1/2/3 - refactor Mat23/33/44 as NDArray2 extensions - update VecPool - add asin/acos/atan/tan vec ops - re-export suffixed generated ops - --- packages/vectors2/package.json | 2 +- packages/vectors2/src/api.ts | 175 +++++- packages/vectors2/src/avec.ts | 8 +- packages/vectors2/src/index.ts | 6 + .../vectors2/src/{ => internal}/accessors.ts | 0 .../vectors2/src/{ => internal}/codegen.ts | 138 +++-- packages/vectors2/src/internal/equiv.ts | 25 + packages/vectors2/src/internal/iterator.ts | 7 + packages/vectors2/src/internal/matrix.ts | 36 ++ .../vectors2/src/{vop.ts => internal/ops.ts} | 0 packages/vectors2/src/mat23.ts | 271 +++++++++ packages/vectors2/src/mat33.ts | 313 ++++++++++ packages/vectors2/src/mat44.ts | 541 +++++++++++++++++ packages/vectors2/src/nd.ts | 554 ++++++++++++++++++ packages/vectors2/src/pool.ts | 27 +- packages/vectors2/src/vec2.ts | 60 +- packages/vectors2/src/vec3.ts | 60 +- packages/vectors2/src/vec4.ts | 273 +++++++++ 18 files changed, 2400 insertions(+), 96 deletions(-) rename packages/vectors2/src/{ => internal}/accessors.ts (100%) rename packages/vectors2/src/{ => internal}/codegen.ts (66%) create mode 100644 packages/vectors2/src/internal/equiv.ts create mode 100644 packages/vectors2/src/internal/iterator.ts create mode 100644 packages/vectors2/src/internal/matrix.ts rename packages/vectors2/src/{vop.ts => internal/ops.ts} (100%) create mode 100644 packages/vectors2/src/mat23.ts create mode 100644 packages/vectors2/src/mat33.ts create mode 100644 packages/vectors2/src/mat44.ts create mode 100644 packages/vectors2/src/nd.ts create mode 100644 packages/vectors2/src/vec4.ts diff --git a/packages/vectors2/package.json b/packages/vectors2/package.json index 4884eb8e7c..3b908fe9bf 100644 --- a/packages/vectors2/package.json +++ b/packages/vectors2/package.json @@ -29,7 +29,7 @@ }, "dependencies": { "@thi.ng/api": "^4.2.3", - "@thi.ng/malloc": "^0.1.1", + "@thi.ng/malloc": "^0.2.0", "@thi.ng/math": "^0.2.0" }, "keywords": [ diff --git a/packages/vectors2/src/api.ts b/packages/vectors2/src/api.ts index 259234f37a..b6ca20a450 100644 --- a/packages/vectors2/src/api.ts +++ b/packages/vectors2/src/api.ts @@ -2,13 +2,18 @@ import { ICopy, IEmpty, IEqualsDelta, - ILength + ILength, + IRelease, + TypedArray, + IEquiv } from "@thi.ng/api"; import { implementsFunction } from "@thi.ng/checks/implements-function"; +import { Type } from "@thi.ng/malloc/api"; import { atan2Abs } from "@thi.ng/math/angle"; import { EPS } from "@thi.ng/math/api"; -import { repeatedly } from "@thi.ng/transducers/iter/repeatedly"; -import { vop } from "./vop"; +import { eqDelta as _eqDelta } from "./internal/equiv"; +import { vop } from "./internal/ops"; +import { VecPool } from "./pool"; // suffix convention: // V = vector arg @@ -36,8 +41,8 @@ export type VecOpRoVVO = (a: ReadonlyVec, b: ReadonlyVec, o?: O, ...xs: an export type VecOpRoVVV = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, ...xs: any[]) => T; export interface MultiVecOp { - add(dim: number, op: VOP); - default(op: VOP); + add(dim: number, op: VOP): VOP; + default(op: VOP): VOP; } export interface MultiVecOpV extends VecOpV, MultiVecOp> { } @@ -73,6 +78,9 @@ export interface ReadonlyVec extends readonly [id: number]: number; } +export type Mat = Vec; +export type ReadonlyMat = ReadonlyVec; + export interface IVector extends Vec, ICopy, @@ -84,10 +92,125 @@ export interface IVector extends s: number; } +export interface NDVec extends + Iterable, + ILength { + [id: number]: T; +} + +export interface INDArray extends + ICopy>, + IEquiv, + IEqualsDelta>, + Iterable { + + buf: NDVec; + i: number; + readonly shape: number[]; + readonly stride: number[]; + readonly length: number; + + get(...args: number[]): T; + + set(...args: [number, T] | [number, number, T] | [number, number, number, T]): void; + + lo(...args: number[]): INDArray; + + hi(...args: number[]): INDArray; + + step(...args: number[]): INDArray; + + pick(...args: number[]): INDArray; + + transpose(...args: number[]): INDArray; +} + +export interface IVecPool extends IRelease { + + malloc(size: number, type?: Type): Vec; + + mallocWrapped(size: number, stride?: number, type?: Type): IVector; + + free(vec: IVector | TypedArray): boolean; + + freeAll(); +} + +export type CommonOps = [ + // set + VecOpVV, + VecOpVN, + VecOpV, + // rand + VecOpVNN, + VecOpV, + VecOpV, + // math + VecOpVV, + VecOpVV, + VecOpVV, + VecOpVV, + VecOpNewVV, + VecOpNewVV, + VecOpNewVV, + VecOpNewVV, + VecOpVN, + VecOpVN, + VecOpVN, + VecOpVN, + VecOpNewVN, + VecOpNewVN, + VecOpNewVN, + VecOpNewVN, + // madd + VecOpVVV, + VecOpVVN, + VecOpNewVVV, + VecOpNewVVN, + // Math. + VecOpV, + VecOpV, + VecOpV, + VecOpV, + VecOpV, + VecOpV, + VecOpV, + VecOpV, + VecOpV, + VecOpV, + VecOpV, + VecOpV, + VecOpV, + VecOpV, + VecOpV, + VecOpV, + VecOpVN, + // minmax + VecOpVV, + VecOpVV, + VecOpVVV, + // step + VecOpVV, + VecOpVVV, + // mix + VecOpVVV, + VecOpVVN, + VecOpNewVVV, + VecOpNewVVN +]; + export type Vec2Coord = 0 | 1; export type Vec3Coord = 0 | 1 | 2; export type Vec4Coord = 0 | 1 | 2 | 3; +let POOL: IVecPool; + +export const getPool = () => POOL; +export const usePool = (pool: VecPool) => (POOL = pool); + +export const vec = (n: number) => + POOL ? POOL.malloc(n) : new Array(n).fill(0); + export const set: MultiVecOpVV = vop(); export const setN: MultiVecOpVN = vop(); export const setS: MultiVecOpV = vop(); @@ -103,7 +226,7 @@ export const empty: MultiVecOpRoV = vop(); empty.default((v) => implementsFunction(v, "empty") ? (v).empty() : - zero(copy(v)) + vec(v.length) ); export const zero = (a: Vec) => setN(a, 0); @@ -113,19 +236,39 @@ export const zeroes = (n: number) => new Array(n).fill(0); export const ones = (n: number) => new Array(n).fill(1); export const eqDelta: MultiVecOpRoVVO = vop(); +eqDelta.default((v1, v2, eps = EPS) => { + if (implementsFunction(v1, "eqDelta")) { + return (v1).eqDelta(v2, eps); + } + if (implementsFunction(v2, "eqDelta")) { + return (v2).eqDelta(v1, eps); + } + return _eqDelta(v1, v2, v1.length, eps); +}); export const rand: MultiVecOpVNN = vop(); export const rand01: MultiVecOpV = vop(); export const rand11: MultiVecOpV = vop(); -export const [add, sub, mul, div]: MultiVecOpVV[] - = [...repeatedly(vop, 4)]; -export const [addNew, subNew, mulNew, divNew]: MultiVecOpNewVV[] - = [...repeatedly(vop, 4)]; -export const [addN, subN, mulN, divN]: MultiVecOpVN[] - = [...repeatedly(vop, 4)]; -export const [addNewN, subNewN, mulNewN, divNewN]: MultiVecOpNewVN[] - = [...repeatedly(vop, 4)]; +export const add: MultiVecOpVV = vop(); +export const sub: MultiVecOpVV = vop(); +export const mul: MultiVecOpVV = vop(); +export const div: MultiVecOpVV = vop(); + +export const addNew: MultiVecOpNewVV = vop(); +export const subNew: MultiVecOpNewVV = vop(); +export const mulNew: MultiVecOpNewVV = vop(); +export const divNew: MultiVecOpNewVV = vop(); + +export const addN: MultiVecOpVN = vop(); +export const subN: MultiVecOpVN = vop(); +export const mulN: MultiVecOpVN = vop(); +export const divN: MultiVecOpVN = vop(); + +export const addNewN: MultiVecOpNewVN = vop(); +export const subNewN: MultiVecOpNewVN = vop(); +export const mulNewN: MultiVecOpNewVN = vop(); +export const divNewN: MultiVecOpNewVN = vop(); export const neg: MultiVecOpV = vop(); neg.default((v) => mulN(v, -1)); @@ -164,6 +307,10 @@ export const abs: MultiVecOpV = vop(); export const sign: MultiVecOpV = vop(); export const sin: MultiVecOpV = vop(); export const cos: MultiVecOpV = vop(); +export const tan: MultiVecOpV = vop(); +export const asin: MultiVecOpV = vop(); +export const acos: MultiVecOpV = vop(); +export const atan: MultiVecOpV = vop(); export const sqrt: MultiVecOpV = vop(); export const floor: MultiVecOpV = vop(); export const ceil: MultiVecOpV = vop(); diff --git a/packages/vectors2/src/avec.ts b/packages/vectors2/src/avec.ts index b747c9c367..4291f14dd2 100644 --- a/packages/vectors2/src/avec.ts +++ b/packages/vectors2/src/avec.ts @@ -14,19 +14,19 @@ export abstract class AVec { abstract get length(): number; - dim() { + get dim() { return 1; } - offset() { + get offset() { return this.i; } - shape() { + get shape() { return [this.length]; } - stride() { + get stride() { return [this.s]; } diff --git a/packages/vectors2/src/index.ts b/packages/vectors2/src/index.ts index bf93825e15..7f299eabc6 100644 --- a/packages/vectors2/src/index.ts +++ b/packages/vectors2/src/index.ts @@ -2,3 +2,9 @@ export * from "./api"; export * from "./pool"; export * from "./vec2"; export * from "./vec3"; +export * from "./vec4"; + +export * from "./nd"; +export * from "./mat23"; +export * from "./mat33"; +export * from "./mat44"; diff --git a/packages/vectors2/src/accessors.ts b/packages/vectors2/src/internal/accessors.ts similarity index 100% rename from packages/vectors2/src/accessors.ts rename to packages/vectors2/src/internal/accessors.ts diff --git a/packages/vectors2/src/codegen.ts b/packages/vectors2/src/internal/codegen.ts similarity index 66% rename from packages/vectors2/src/codegen.ts rename to packages/vectors2/src/internal/codegen.ts index 4d46f1cfc6..e90c92c41b 100644 --- a/packages/vectors2/src/codegen.ts +++ b/packages/vectors2/src/internal/codegen.ts @@ -66,7 +66,12 @@ import { clamp, maddNew, maddNewN, -} from "./api"; + asin, + acos, + tan, + atan, + CommonOps, +} from "../api"; export type Template = (syms: string[], i?: number) => string; @@ -124,8 +129,9 @@ export const compile = ( export const compileHOF = ( dim: number, - fn: FnAny, + fns: FnAny[], tpl: Template, + hofArgs: string, args: string, syms = args, ret = "a", @@ -133,16 +139,16 @@ export const compileHOF = ( post?: string) => { return new Function( - "fn", + hofArgs, `return (${args})=>{${assemble(dim, tpl, syms, ret, pre, post).join("\n")}}` - )(fn); + )(...fns); }; export const genOpFnV = (dim: number, op: string): VecOpV => compile(dim, ([a]) => `${a}=${op}(${a});`, "a"); export const genOpHofV = (dim: number, fn) => - compileHOF(dim, fn, ([a]) => `${a}=fn(${a});`, "a"); + compileHOF(dim, [fn], ([a]) => `${a}=fn(${a});`, "fn", "a"); export const genOpVV = (dim: number, op: string): VecOpVV => compile(dim, ([a, b]) => `${a}${op}=${b};`, "a,b"); @@ -159,64 +165,68 @@ export const genOpNewVV = (dim: number, op: string): VecOpNewVV => export const genOpNewVN = (dim: number, op: string): VecOpNewVN => compile(dim, ([a, o]) => `${o}=${a}${op}n;`, "a,n,o=[]", "a,o", "o"); -export const genCommon = (dim: number) => { - set.add(dim, genOpVV(dim, "")); - setN.add(dim, genOpVN(dim, "")); - setS.add(dim, compile(dim, ([a], i) => `${a}=xs[${i}];`, "a,...xs", "a")); +export const genCommon = (dim: number): CommonOps => [ + set.add(dim, genOpVV(dim, "")), + setN.add(dim, genOpVN(dim, "")), + setS.add(dim, compile(dim, ([a], i) => `${a}=xs[${i}];`, "a,...xs", "a")), // TODO add IRandom support - rand01.add(dim, compile(dim, ([a]) => `${a}=Math.random();`, "a")); - rand11.add(dim, compile(dim, ([a]) => `${a}=Math.random()*2-1;`, "a")); - rand.add(dim, compile(dim, ([a]) => `${a}=n+(m-n)*Math.random();`, "a,n,m", "a")); - - add.add(dim, genOpVV(dim, "+")); - sub.add(dim, genOpVV(dim, "-")); - mul.add(dim, genOpVV(dim, "*")); - div.add(dim, genOpVV(dim, "/")); - - subNew.add(dim, genOpNewVV(dim, "-")); - addNew.add(dim, genOpNewVV(dim, "+")); - mulNew.add(dim, genOpNewVV(dim, "*")); - divNew.add(dim, genOpNewVV(dim, "/")); - - subN.add(dim, genOpVN(dim, "-")); - addN.add(dim, genOpVN(dim, "+")); - mulN.add(dim, genOpVN(dim, "*")); - divN.add(dim, genOpVN(dim, "/")); - - subNewN.add(dim, genOpNewVN(dim, "-")); - addNewN.add(dim, genOpNewVN(dim, "+")); - mulNewN.add(dim, genOpNewVN(dim, "*")); - divNewN.add(dim, genOpNewVN(dim, "/")); - - madd.add(dim, compile(dim, ([a, b, c]) => `${a}+=${b}*${c};`, "a,b,c")); - maddN.add(dim, compile(dim, ([a, b]) => `${a}+=${b}*n;`, "a,b,n", "a,b")); - maddNew.add(dim, compile(dim, ([a, b, c, o]) => `${o}=${a}+${b}*${c};`, "a,b,c,o=[]", "a,b,c,o", "o")); - maddNewN.add(dim, compile(dim, ([a, b, o]) => `${o}=${a}+${b}*n;`, "a,b,n,o=[]", "a,b,o", "o")); - - abs.add(dim, genOpFnV(dim, "Math.abs")); - sign.add(dim, genOpHofV(dim, _sign)); - sin.add(dim, genOpFnV(dim, "Math.sin")); - cos.add(dim, genOpFnV(dim, "Math.cos")); - floor.add(dim, genOpFnV(dim, "Math.floor")); - ceil.add(dim, genOpFnV(dim, "Math.ceil")); - trunc.add(dim, genOpFnV(dim, "Math.trunc")); - fract.add(dim, genOpHofV(dim, _fract)); - sqrt.add(dim, genOpFnV(dim, "Math.sqrt")); - log.add(dim, genOpFnVV(dim, "Math.log")); - exp.add(dim, genOpFnVV(dim, "Math.exp")); - pow.add(dim, genOpFnVV(dim, "Math.pow")); - powN.add(dim, compile(dim, ([a]) => `${a}=Math.pow(${a},n);`, "a,n", "a")); - - min.add(dim, genOpFnVV(dim, "Math.min")); - max.add(dim, genOpFnVV(dim, "Math.max")); - clamp.add(dim, compileHOF(dim, _clamp, ([a, b, c]) => `${a}=fn(${a},${b},${c});`, "a,b,c")); - - step.add(dim, compileHOF(dim, _step, ([a, e]) => `${a}=fn(${e},${a});`, "a,e")); - smoothStep.add(dim, compileHOF(dim, _smoothStep, ([a, e1, e2]) => `${a}=fn(${e1},${e2},${a});`, "a,e1,e2")); - - mix.add(dim, compile(dim, ([a, b, c]) => `${a}+=(${b}-${a})*${c};`, "a,b,c")); - mixN.add(dim, compile(dim, ([a, b]) => `${a}+=(${b}-${a})*n;`, "a,b,n", "a,b")); - mixNew.add(dim, compile(dim, ([a, b, c, o]) => `${o}=${a}+(${b}-${a})*${c};`, "a,b,c,o=[]", "a,b,c,o", "o")); - mixNewN.add(dim, compile(dim, ([a, b, o]) => `${o}=${a}+(${b}-${a})*n;`, "a,b,n,o=[]", "a,b,o", "o")); -}; + rand01.add(dim, compile(dim, ([a]) => `${a}=Math.random();`, "a")), + rand11.add(dim, compile(dim, ([a]) => `${a}=Math.random()*2-1;`, "a")), + rand.add(dim, compile(dim, ([a]) => `${a}=n+(m-n)*Math.random();`, "a,n,m", "a")), + + add.add(dim, genOpVV(dim, "+")), + sub.add(dim, genOpVV(dim, "-")), + mul.add(dim, genOpVV(dim, "*")), + div.add(dim, genOpVV(dim, "/")), + + addNew.add(dim, genOpNewVV(dim, "+")), + subNew.add(dim, genOpNewVV(dim, "-")), + mulNew.add(dim, genOpNewVV(dim, "*")), + divNew.add(dim, genOpNewVV(dim, "/")), + + addN.add(dim, genOpVN(dim, "+")), + subN.add(dim, genOpVN(dim, "-")), + mulN.add(dim, genOpVN(dim, "*")), + divN.add(dim, genOpVN(dim, "/")), + + addNewN.add(dim, genOpNewVN(dim, "+")), + subNewN.add(dim, genOpNewVN(dim, "-")), + mulNewN.add(dim, genOpNewVN(dim, "*")), + divNewN.add(dim, genOpNewVN(dim, "/")), + + madd.add(dim, compile(dim, ([a, b, c]) => `${a}+=${b}*${c};`, "a,b,c")), + maddN.add(dim, compile(dim, ([a, b]) => `${a}+=${b}*n;`, "a,b,n", "a,b")), + maddNew.add(dim, compile(dim, ([a, b, c, o]) => `${o}=${a}+${b}*${c};`, "a,b,c,o=[]", "a,b,c,o", "o")), + maddNewN.add(dim, compile(dim, ([a, b, o]) => `${o}=${a}+${b}*n;`, "a,b,n,o=[]", "a,b,o", "o")), + + abs.add(dim, genOpFnV(dim, "Math.abs")), + sign.add(dim, genOpHofV(dim, _sign)), + sin.add(dim, genOpFnV(dim, "Math.sin")), + cos.add(dim, genOpFnV(dim, "Math.cos")), + tan.add(dim, genOpFnV(dim, "Math.tan")), + asin.add(dim, genOpFnV(dim, "Math.asin")), + acos.add(dim, genOpFnV(dim, "Math.acos")), + atan.add(dim, genOpFnV(dim, "Math.atan")), + floor.add(dim, genOpFnV(dim, "Math.floor")), + ceil.add(dim, genOpFnV(dim, "Math.ceil")), + trunc.add(dim, genOpFnV(dim, "Math.trunc")), + fract.add(dim, genOpHofV(dim, _fract)), + sqrt.add(dim, genOpFnV(dim, "Math.sqrt")), + log.add(dim, genOpFnVV(dim, "Math.log")), + exp.add(dim, genOpFnVV(dim, "Math.exp")), + pow.add(dim, genOpFnVV(dim, "Math.pow")), + powN.add(dim, compile(dim, ([a]) => `${a}=Math.pow(${a},n);`, "a,n", "a")), + + min.add(dim, genOpFnVV(dim, "Math.min")), + max.add(dim, genOpFnVV(dim, "Math.max")), + clamp.add(dim, compileHOF(dim, [_clamp], ([a, b, c]) => `${a}=fn(${a},${b},${c});`, "fn", "a,b,c")), + + step.add(dim, compileHOF(dim, [_step], ([a, e]) => `${a}=fn(${e},${a});`, "fn", "a,e")), + smoothStep.add(dim, compileHOF(dim, [_smoothStep], ([a, e1, e2]) => `${a}=fn(${e1},${e2},${a});`, "fn", "a,e1,e2")), + + mix.add(dim, compile(dim, ([a, b, c]) => `${a}+=(${b}-${a})*${c};`, "a,b,c")), + mixN.add(dim, compile(dim, ([a, b]) => `${a}+=(${b}-${a})*n;`, "a,b,n", "a,b")), + mixNew.add(dim, compile(dim, ([a, b, c, o]) => `${o}=${a}+(${b}-${a})*${c};`, "a,b,c,o=[]", "a,b,c,o", "o")), + mixNewN.add(dim, compile(dim, ([a, b, o]) => `${o}=${a}+(${b}-${a})*n;`, "a,b,n,o=[]", "a,b,o", "o")), +]; diff --git a/packages/vectors2/src/internal/equiv.ts b/packages/vectors2/src/internal/equiv.ts new file mode 100644 index 0000000000..9004ea623a --- /dev/null +++ b/packages/vectors2/src/internal/equiv.ts @@ -0,0 +1,25 @@ +import { EPS } from "@thi.ng/math/api"; +import { eqDelta as _eqDelta } from "@thi.ng/math/eqdelta"; +import { ReadonlyVec } from "../api"; + +/** + * Similar to `equiv()`, but takes tolerance `eps` into account for + * equality checks. + * + * @param a first vector + * @param b second vector + * @param n number of elements + * @param eps tolerance + * @param ia start index a + * @param ib start index b + * @param sa stride a + * @param sb stride b + */ +export const eqDelta = (a: ReadonlyVec, b: ReadonlyVec, n: number, eps = EPS, ia = 0, ib = 0, sa = 1, sb = 1) => { + for (; n > 0; n-- , ia += sa, ib += sb) { + if (!_eqDelta(a[ia], b[ib], eps)) { + return false; + } + } + return true; +}; diff --git a/packages/vectors2/src/internal/iterator.ts b/packages/vectors2/src/internal/iterator.ts new file mode 100644 index 0000000000..64db8e8b04 --- /dev/null +++ b/packages/vectors2/src/internal/iterator.ts @@ -0,0 +1,7 @@ +import { Vec } from "../api"; + +export function* iterator(buf: Vec, n: number, i = 0, s = 1) { + for (; n > 0; n-- , i += s) { + yield buf[i]; + } +} diff --git a/packages/vectors2/src/internal/matrix.ts b/packages/vectors2/src/internal/matrix.ts new file mode 100644 index 0000000000..29de9e0f38 --- /dev/null +++ b/packages/vectors2/src/internal/matrix.ts @@ -0,0 +1,36 @@ +import { ReadonlyVec, Vec } from "../api"; + +export const dot2 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => + a[ia] * b[ib] + a[ia + sa] * b[ib + sb]; + +export const dot3 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => + a[ia] * b[ib] + + a[ia + sa] * b[ib + sb] + + a[ia + 2 * sa] * b[ib + 2 * sb]; + +export const dot4 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => + a[ia] * b[ib] + + a[ia + sa] * b[ib + sb] + + a[ia + 2 * sa] * b[ib + 2 * sb] + + a[ia + 3 * sa] * b[ib + 3 * sb]; + +export const set3 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => ( + a[ia] = b[ib], + a[ia + sa] = b[ib + sb], + a[ia + 2 * sa] = b[ib + 2 * sb], + a +); + +export const setS3 = (a: Vec, x: number, y: number, z: number, ia = 0, sa = 1) => + (a[ia] = x, a[ia + sa] = y, a[ia + 2 * sa] = z, a); + +export const setS4 = (a: Vec, x: number, y: number, z: number, w: number, ia = 0, sa = 1) => ( + a[ia] = x, + a[ia + sa] = y, + a[ia + 2 * sa] = z, + a[ia + 3 * sa] = w, + a +); + +export const cross2 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => + a[ia] * b[ib + sb] - a[ia + sa] * b[ib]; diff --git a/packages/vectors2/src/vop.ts b/packages/vectors2/src/internal/ops.ts similarity index 100% rename from packages/vectors2/src/vop.ts rename to packages/vectors2/src/internal/ops.ts diff --git a/packages/vectors2/src/mat23.ts b/packages/vectors2/src/mat23.ts new file mode 100644 index 0000000000..46e5c67df5 --- /dev/null +++ b/packages/vectors2/src/mat23.ts @@ -0,0 +1,271 @@ +import { isArrayLike } from "@thi.ng/checks/is-arraylike"; +import { isNumber } from "@thi.ng/checks/is-number"; +import { + Mat, + ReadonlyMat, + ReadonlyVec, + setS, + Vec +} from "./api"; +import { iterator } from "./internal/iterator"; +import { cross2, dot2 } from "./internal/matrix"; +import { NDArray2 } from "./nd"; + +export const get23 = (a: Mat, i = 0) => + (a).slice(i, i + 6); + +export const set23 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => ( + a[ia] = b[ib], + a[ia + 1] = b[ib + 1], + a[ia + 2] = b[ib + 2], + a[ia + 3] = b[ib + 3], + a[ia + 4] = b[ib + 4], + a[ia + 5] = b[ib + 5], + a +); + +/** + * ``` + * m00 m10 m20 + * m01 m11 m21 + * ``` + * + * @param m + * @param m00 + * @param m01 + * @param m10 + * @param m11 + * @param m20 + * @param m21 + * @param i + */ +export const setS23 = ( + m: Mat, + m00: number, m01: number, + m10: number, m11: number, + m20: number, m21: number, + i = 0) => ( + m[i] = m00, + m[i + 1] = m01, + m[i + 2] = m10, + m[i + 3] = m11, + m[i + 4] = m20, + m[i + 5] = m21, + m + ); + +export const identity23 = (m?: Mat, i = 0) => + setS23(m || [], 1, 0, 0, 1, 0, 0, i); + +export const rotation23 = (m: Mat, theta: number, i = 0) => { + const s = Math.sin(theta); + const c = Math.cos(theta); + return setS23(m || [], c, s, -s, c, 0, 0, i); +}; + +export const rotationAroundPoint23 = (m: Mat, p: ReadonlyVec, theta: number, im = 0) => + concat23( + translationV23(m || [], p, im), im, + rotation23([], theta), + translationS23([], -p[0], -p[1]) + ); + +export const scaleV23 = (m: Mat, v: Vec, i = 0) => + scaleS23(m, v[0], v[1], i); + +export const scaleN23 = (m: Mat, n: number, i = 0) => + scaleS23(m, n, n, i); + +export const scaleS23 = (m: Mat, sx: number, sy: number, i = 0) => + setS23(m || [], sx, 0, 0, sy, 0, 0, i); + +export const scaleWithCenter23 = (m: Mat, p: ReadonlyVec, sx: number, sy: number, im = 0) => + concat23( + translationV23(m || [], p, im), im, + scaleS23([], sx, sy), + translationS23([], -p[0], -p[1]) + ); + +export const translationV23 = (m: Mat, v: ReadonlyVec, i = 0) => + translationS23(m, v[0], v[1], i); + +export const translationS23 = (m: Mat, x: number, y: number, i = 0) => + setS23(m || [], 1, 0, 0, 1, x, y, i); + +export const shearX23 = (m: Mat, x: number, i = 0) => + setS23(m || [], 1, 0, x, 1, 0, 0, i); + +export const shearY23 = (m: Mat, y: number, i = 0) => + setS23(m || [], 1, y, 0, 1, 0, 0, i); + +export const skewX23 = (m: Mat, theta: number, i = 0) => + shearX23(m, Math.tan(theta), i); + +export const skewY23 = (m: Mat, theta: number, i = 0) => + shearY23(m, Math.tan(theta), i); + +export const mul23 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => + setS23( + a, + dot2(a, b, ia, ib, 2), + dot2(a, b, ia + 1, ib, 2), + dot2(a, b, ia, ib + 2, 2), + dot2(a, b, ia + 1, ib + 2, 2), + dot2(a, b, ia, ib + 4, 2) + a[ia + 4], + dot2(a, b, ia + 1, ib + 4, 2) + a[ia + 5], + ia + ); + +export const concat23 = (a: Mat, ia: number, ...xs: (ReadonlyMat | [ReadonlyMat, number])[]) => + xs.reduce( + (acc: Mat, x) => isArrayLike(x[0]) ? + mul23(acc, x[0], ia, x[1]) : + mul23(acc, x, ia), + a + ); + +export const mulV23 = (v: Vec, m: ReadonlyMat, im = 0) => + setS( + v, + dot2(m, v, im, 0, 2) + m[im + 4], + dot2(m, v, im + 1, 0, 2) + m[im + 5], + ); + +export const det23 = (m: ReadonlyMat, i = 0) => + cross2(m, m, i, i + 1, 2, 2); + +export const invert23 = (m: Mat, i = 0) => { + const m00 = m[i]; + const m01 = m[i + 1]; + const m10 = m[i + 2]; + const m11 = m[i + 3]; + const m20 = m[i + 4]; + const m21 = m[i + 5]; + let det = m00 * m11 - m01 * m10; + if (!det) { + return; + } + det = 1.0 / det; + return setS23( + m, + m11 * det, + -m01 * det, + -m10 * det, + m00 * det, + (m10 * m21 - m11 * m20) * det, + (m01 * m20 - m00 * m21) * det, + i + ); +} + +export class Mat23 extends NDArray2 { + + static identity() { + return new Mat23(identity23()); + } + + static rotation(theta: number) { + return new Mat23(rotation23([], theta)); + } + + static rotationAroundPoint(p: ReadonlyVec, theta: number) { + return new Mat23(rotationAroundPoint23([], p, theta)); + } + + static scale(v: ReadonlyVec): Mat23; + static scale(n: number): Mat23; + static scale(x: number, y: number): Mat23; + static scale(x: any, y = x) { + return new Mat23( + isNumber(x) ? + scaleS23([], x, y) : + scaleV23([], x) + ); + } + + static scaleWithCenter(p: ReadonlyVec, sx: number, sy = sx) { + return new Mat23(scaleWithCenter23([], p, sx, sy)); + } + + static translation(v: ReadonlyVec): Mat23; + static translation(x: number, y: number): Mat23; + static translation(x: any, y?: any) { + return new Mat23( + isNumber(x) ? + translationS23([], x, y) : + translationV23([], x) + ); + } + + static skewX(x: number) { + return new Mat23(skewX23([], x)); + } + + static skewY(y: number) { + return new Mat23(skewY23([], y)); + } + + static shearX(theta: number) { + return new Mat23(shearX23([], theta)); + } + + static shearY(theta: number) { + return new Mat23(shearY23([], theta)); + } + + static concat(m: Readonly, ...xs: Readonly[]) { + return new Mat23(concat23.apply(null, [ + get23(m.buf, m.i), 0, + ...<[ReadonlyMat, number][]>xs.map((x) => [x.buf, x.i])]) + ); + } + + constructor(buf?: Mat, i = 0) { + super(buf || [0, 0, 0, 0, 0, 0], [2, 3], [1, 2], i); + } + + [Symbol.iterator]() { + return iterator(this.buf, 6, this.i); + } + + get length() { + return 6; + } + + copy() { + return new Mat23([...this]); + } + + identity() { + identity23(this.buf, this.i); + return this; + } + + setM(m: Readonly) { + set23(this.buf, m.buf, this.i, m.i); + return this; + } + + setS(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number) { + setS23(this.buf, m00, m01, m10, m11, m20, m21, this.i); + return this; + } + + mul(m: Readonly) { + mul23(this.buf, m.buf, this.i, m.i); + return this; + } + + mulV(v: Vec) { + return mulV23(v, this.buf, this.i); + } + + determinant() { + return det23(this.buf, this.i); + } + + invert() { + invert23(this.buf, this.i); + return this; + } +} diff --git a/packages/vectors2/src/mat33.ts b/packages/vectors2/src/mat33.ts new file mode 100644 index 0000000000..98fa602f65 --- /dev/null +++ b/packages/vectors2/src/mat33.ts @@ -0,0 +1,313 @@ +import { isArrayLike } from "@thi.ng/checks/is-arraylike"; +import { isNumber } from "@thi.ng/checks/is-number"; +import { + Mat, + ReadonlyMat, + ReadonlyVec, + setS, + Vec +} from "./api"; +import { iterator } from "./internal/iterator"; +import { NDArray2 } from "./nd"; +import { dot3, set3, setS3, setS4 } from "./internal/matrix"; + +export const get33 = (a: Mat, i = 0) => + (a).slice(i, i + 9); + +export const set33 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => ( + a[ia] = b[ib], + a[ia + 1] = b[ib + 1], + a[ia + 2] = b[ib + 2], + a[ia + 3] = b[ib + 3], + a[ia + 4] = b[ib + 4], + a[ia + 5] = b[ib + 5], + a[ia + 6] = b[ib + 6], + a[ia + 7] = b[ib + 7], + a[ia + 8] = b[ib + 8], + a +); + +/** + * ``` + * m00 m10 m20 + * m01 m11 m21 + * m02 m12 m22 + * ``` + * + * @param m + * @param m00 + * @param m01 + * @param m02 + * @param m10 + * @param m11 + * @param m12 + * @param m20 + * @param m21 + * @param m22 + * @param i + */ +export const setS33 = ( + m: Mat, + m00: number, m01: number, m02: number, + m10: number, m11: number, m12: number, + m20: number, m21: number, m22: number, + i = 0) => ( + m[i] = m00, + m[i + 1] = m01, + m[i + 2] = m02, + m[i + 3] = m10, + m[i + 4] = m11, + m[i + 5] = m12, + m[i + 6] = m20, + m[i + 7] = m21, + m[i + 8] = m22, + m + ); + +export const identity33 = (m?: Mat, i = 0) => + setS33(m || [], + 1, 0, 0, + 0, 1, 0, + 0, 0, 1, + i + ); + +export const rotationX33 = (m: Mat, theta: number, i = 0) => { + const s = Math.sin(theta); + const c = Math.cos(theta); + return setS33(m || [], + 1, 0, 0, + 0, c, s, + 0, -s, c, + i + ); +}; + +export const rotationY33 = (m: Mat, theta: number, i = 0) => { + const s = Math.sin(theta); + const c = Math.cos(theta); + return setS33(m || [], + c, 0, -s, + 0, 1, 0, + s, 0, c, + i + ); +}; + +export const rotationZ33 = (m: Mat, theta: number, i = 0) => { + const s = Math.sin(theta); + const c = Math.cos(theta); + return setS33(m || [], + c, s, 0, + -s, c, 0, + 0, 0, 1, + i + ); +}; + +export const scaleV33 = (m: Mat, v: ReadonlyVec, i = 0) => + scaleS33(m, v[0], v[1], v[2], i); + +export const scaleN33 = (m: Mat, n: number, i = 0) => + scaleS33(m, n, n, n, i); + +export const scaleS33 = (m: Mat, sx: number, sy: number, sz: number, i = 0) => + setS33(m || [], + sx, 0, 0, + 0, sy, 0, + 0, 0, sz, + i + ); + +export const mul33 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => + setS33( + a, + dot3(a, b, ia, ib, 3), + dot3(a, b, ia + 1, ib, 3), + dot3(a, b, ia + 2, ib, 3), + dot3(a, b, ia, ib + 3, 3), + dot3(a, b, ia + 1, ib + 3, 3), + dot3(a, b, ia + 2, ib + 3, 3), + dot3(a, b, ia, ib + 6, 3), + dot3(a, b, ia + 1, ib + 6, 3), + dot3(a, b, ia + 2, ib + 6, 3), + ia + ); + +export const concat33 = (a: Mat, ia: number, ...xs: (ReadonlyMat | [ReadonlyMat, number])[]) => + xs.reduce( + (acc: Mat, x) => isArrayLike(x[0]) ? + mul33(acc, x[0], ia, x[1]) : + mul33(acc, x, ia), + a + ); + +export const mulV33 = (v: Vec, m: ReadonlyMat, im = 0) => + setS( + v, + dot3(m, v, im, 0, 3), + dot3(m, v, im + 1, 0, 3), + dot3(m, v, im + 2, 0, 3), + ); + +export const det33 = (m: ReadonlyMat, i = 0) => { + const m00 = m[i]; + const m01 = m[i + 1]; + const m02 = m[i + 2]; + const m10 = m[i + 3]; + const m11 = m[i + 4]; + const m12 = m[i + 5]; + const m20 = m[i + 6]; + const m21 = m[i + 7]; + const m22 = m[i + 8]; + const d01 = m22 * m11 - m12 * m21; + const d11 = -m22 * m10 + m12 * m20; + const d21 = m21 * m10 - m11 * m20; + return m00 * d01 + m01 * d11 + m02 * d21; +}; + +export const invert33 = (m: Mat, i = 0) => { + const m00 = m[i]; + const m01 = m[i + 1]; + const m02 = m[i + 2]; + const m10 = m[i + 3]; + const m11 = m[i + 4]; + const m12 = m[i + 5]; + const m20 = m[i + 6]; + const m21 = m[i + 7]; + const m22 = m[i + 8]; + const d01 = m22 * m11 - m12 * m21; + const d11 = -m22 * m10 + m12 * m20; + const d21 = m21 * m10 - m11 * m20; + let det = m00 * d01 + m01 * d11 + m02 * d21; + if (!det) { + return; + } + det = 1.0 / det; + return setS33( + m, + d01 * det, + (-m22 * m01 + m02 * m21) * det, + (m12 * m01 - m02 * m11) * det, + d11 * det, + (m22 * m00 - m02 * m20) * det, + (-m12 * m00 + m02 * m10) * det, + d21 * det, + (-m21 * m00 + m01 * m20) * det, + (m11 * m00 - m01 * m10) * det, + i + ); +} + +export const transpose33 = (m: Mat, i = 0) => + setS33( + m, + m[i], m[i + 3], m[i + 6], + m[i + 1], m[i + 4], m[i + 7], + m[i + 2], m[i + 5], m[i + 8], + i + ); + +export const mat33to44 = (m44: Mat, m33: ReadonlyMat, ia = 0, ib = 0) => ( + set3(m44, m33, ia, ib), + set3(m44, m33, ia + 4, ib + 3), + set3(m44, m33, ia + 8, ib + 6), + setS3(m44, 0, 0, 0, ia + 12), + setS4(m44, 0, 0, 0, 1, ia + 3, 4), + m44 +); + +export class Mat33 extends NDArray2 { + + static identity() { + return new Mat33(identity33()); + } + + static rotationX(theta: number) { + return new Mat33(rotationX33([], theta)); + } + + static rotationY(theta: number) { + return new Mat33(rotationY33([], theta)); + } + + static rotationZ(theta: number) { + return new Mat33(rotationZ33([], theta)); + } + + static scale(v: ReadonlyVec): Mat33; + static scale(n: number): Mat33; + static scale(x: number, y: number, z: number): Mat33; + static scale(x: any, y = x, z = x) { + return new Mat33( + isNumber(x) ? + scaleS33([], x, y, z) : + scaleV33([], x) + ); + } + + static concat(m: Readonly, ...xs: Readonly[]) { + return new Mat33(concat33.apply(null, [ + get33(m.buf, m.i), 0, + ...<[ReadonlyMat, number][]>xs.map((x) => [x.buf, x.i])]) + ); + } + + + constructor(buf?: Mat, i = 0) { + super(buf || [0, 0, 0, 0, 0, 0, 0, 0, 0], [3, 3], [1, 3], i); + } + + [Symbol.iterator]() { + return iterator(this.buf, 9, this.i); + } + + get length() { + return 9; + } + + copy() { + return new Mat33([...this]); + } + + identity() { + identity33(this.buf, this.i); + return this; + } + + setM(m: Readonly) { + set33(this.buf, m.buf, this.i, m.i); + return this; + } + + setS(m00: number, m01: number, m02: number, + m10: number, m11: number, m12: number, + m20: number, m21: number, m22: number) { + setS33(this.buf, m00, m01, m02, m10, m11, m12, m20, m21, m22, this.i); + return this; + } + + mul(m: Readonly) { + mul33(this.buf, m.buf, this.i, m.i); + return this; + } + + mulV(v: Vec) { + mulV33(v, this.buf, this.i); + return v; + } + + determinant() { + return det33(this.buf, this.i); + } + + invert() { + invert33(this.buf, this.i); + return this; + } + + transpose() { + transpose33(this.buf, this.i); + return this; + } +} diff --git a/packages/vectors2/src/mat44.ts b/packages/vectors2/src/mat44.ts new file mode 100644 index 0000000000..4d8dd492e0 --- /dev/null +++ b/packages/vectors2/src/mat44.ts @@ -0,0 +1,541 @@ +import { isArrayLike } from "@thi.ng/checks/is-arraylike"; +import { isNumber } from "@thi.ng/checks/is-number"; +import { DEG2RAD } from "@thi.ng/math/api"; +import { + copy, + Mat, + normalize, + ReadonlyMat, + ReadonlyVec, + Vec +} from "./api"; +import { iterator } from "./internal/iterator"; +import { + dot3, + dot4, + set3, + setS3, + setS4 +} from "./internal/matrix"; +import { Mat33 } from "./mat33"; +import { NDArray2 } from "./nd"; +import { cross3, sub3 } from "./vec3"; + +export const get44 = (a: Mat, i = 0) => + (a).slice(i, i + 16); + +export const set44 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => { + for (let i = 0; i < 16; i++) { + a[ia + i] = b[ib + i]; + } + return a; +}; + +/** + * ``` + * m00 m10 m20 m30 + * m01 m11 m21 m31 + * m02 m12 m22 m32 + * m03 m13 m23 m33 + * ``` + */ +export const setS44 = ( + m: Mat, + m00: number, m01: number, m02: number, m03: number, + m10: number, m11: number, m12: number, m13: number, + m20: number, m21: number, m22: number, m23: number, + m30: number, m31: number, m32: number, m33: number, + i = 0) => ( + m[i] = m00, + m[i + 1] = m01, + m[i + 2] = m02, + m[i + 3] = m03, + m[i + 4] = m10, + m[i + 5] = m11, + m[i + 6] = m12, + m[i + 7] = m13, + m[i + 8] = m20, + m[i + 9] = m21, + m[i + 10] = m22, + m[i + 11] = m23, + m[i + 12] = m30, + m[i + 13] = m31, + m[i + 14] = m32, + m[i + 15] = m33, + m + ); + +export const identity44 = (m?: Mat, i = 0) => + setS44(m || [], + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1, + i + ); + +export const rotationX44 = (m: Mat, theta: number, i = 0) => { + const s = Math.sin(theta); + const c = Math.cos(theta); + return setS44(m || [], + 1, 0, 0, 0, + 0, c, s, 0, + 0, -s, c, 0, + 0, 0, 0, 1, + i + ); +}; + +export const rotationY44 = (m: Mat, theta: number, i = 0) => { + const s = Math.sin(theta); + const c = Math.cos(theta); + return setS44(m || [], + c, 0, -s, 0, + 0, 1, 0, 0, + s, 0, c, 0, + 0, 0, 0, 1, + i + ); +}; + +export const rotationZ44 = (m: Mat, theta: number, i = 0) => { + const s = Math.sin(theta); + const c = Math.cos(theta); + return setS44(m || [], + c, s, 0, 0, + -s, c, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1, + i + ); +}; + +export const scaleV44 = (m: Mat, v: ReadonlyVec, i = 0) => + scaleS44(m, v[0], v[1], v[2], i); + +export const scaleN44 = (m: Mat, n: number, i = 0) => + scaleS44(m, n, n, n, i); + +export const scaleS44 = (m: Mat, sx: number, sy: number, sz: number, i = 0) => + setS44(m || [], + sx, 0, 0, 0, + 0, sy, 0, 0, + 0, 0, sz, 0, + 0, 0, 0, 1, + i + ); + +export const scaleWithCenter44 = (m: Mat, p: ReadonlyVec, sx: number, sy: number, sz: number, im = 0) => + concat44( + translationV44(m || [], p, im), im, + scaleS44([], sx, sy, sz), + translationS44([], -p[0], -p[1], -p[2]) + ); + +export const translationV44 = (m: Mat, v: ReadonlyVec, i = 0) => + translationS44(m, v[0], v[1], v[2], i); + +export const translationS44 = (m: Mat, x: number, y: number, z: number, i = 0) => + setS44(m || [], + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + x, y, z, 1, + i + ); + +export const frustum = (m: Mat, left: number, right: number, bottom: number, top: number, near: number, far: number, i = 0) => { + const dx = 1 / (right - left); + const dy = 1 / (top - bottom); + const dz = 1 / (far - near); + return setS44(m || [], + near * 2 * dx, 0, 0, 0, + 0, near * 2 * dy, 0, 0, + (right + left) * dx, (top + bottom) * dy, -(far + near) * dz, -1, + 0, 0, -(far * near * 2) * dz, 0, + i + ); +}; + +export const frustumBounds = (fovy: number, aspect: number, near: number, far: number) => { + const top = near * Math.tan(fovy * DEG2RAD / 2); + const right = top * aspect; + return { + left: -right, + right, + bottom: -top, + top, + near, + far + }; +}; + +export const perspective = (m: Mat, fov: number, aspect: number, near: number, far: number, i = 0) => { + const f = frustumBounds(fov, aspect, near, far); + return frustum(m || [], f.left, f.right, f.bottom, f.top, f.near, f.far, i); +}; + +export const ortho = (m: Mat, left: number, right: number, bottom: number, top: number, near: number, far: number, i = 0) => { + const dx = 1 / (right - left); + const dy = 1 / (top - bottom); + const dz = 1 / (far - near); + return setS44(m || [], + 2 * dx, 0, 0, 0, + 0, 2 * dy, 0, 0, + 0, 0, -2 * dz, 0, + -(left + right) * dx, -(top + bottom) * dy, -(far + near) * dz, 1, + i + ); +}; + +export const lookAt = (m: Mat, eye: ReadonlyVec, target: ReadonlyVec, up: ReadonlyVec, im = 0) => { + const z = normalize(sub3(copy(eye), target)); + const x = normalize(cross3(copy(up), z)); + const y = normalize(cross3(z, x)); + return setS44(m || [], + x[0], y[0], z[0], 0, + x[1], y[1], z[1], 0, + x[2], y[2], z[2], 0, + -dot3(eye, x), -dot3(eye, y), -dot3(eye, z), 1, + im + ); +} + +export const mul44 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => + setS44( + a, + dot4(a, b, ia, ib, 4), + dot4(a, b, ia + 1, ib, 4), + dot4(a, b, ia + 2, ib, 4), + dot4(a, b, ia + 3, ib, 4), + dot4(a, b, ia, ib + 4, 4), + dot4(a, b, ia + 1, ib + 4, 4), + dot4(a, b, ia + 2, ib + 4, 4), + dot4(a, b, ia + 3, ib + 4, 4), + dot4(a, b, ia, ib + 8, 4), + dot4(a, b, ia + 1, ib + 8, 4), + dot4(a, b, ia + 2, ib + 8, 4), + dot4(a, b, ia + 3, ib + 8, 4), + dot4(a, b, ia, ib + 12, 4), + dot4(a, b, ia + 1, ib + 12, 4), + dot4(a, b, ia + 2, ib + 12, 4), + dot4(a, b, ia + 3, ib + 12, 4), + ia + ); + +export const concat44 = (a: Mat, ia: number, ...xs: (ReadonlyMat | [ReadonlyMat, number])[]) => + xs.reduce( + (acc: Mat, x) => isArrayLike(x[0]) ? + mul44(acc, x[0], ia, x[1]) : + mul44(acc, x, ia), + a + ); + +export const mulV344 = (v: Vec, m: ReadonlyMat, im = 0) => + setS3( + v, + dot3(m, v, im, 0, 4) + m[12], + dot3(m, v, im + 1, 0, 4) + m[13], + dot3(m, v, im + 2, 0, 4) + m[14], + ); + +export const mulV44 = (v: Vec, m: ReadonlyMat, im = 0) => + setS4( + v, + dot4(m, v, im, 0, 4), + dot4(m, v, im + 1, 0, 4), + dot4(m, v, im + 2, 0, 4), + dot4(m, v, im + 3, 0, 4), + ); + +const detCoeffs44 = (m: ReadonlyMat, i = 0) => { + const m00 = m[i]; + const m01 = m[i + 1]; + const m02 = m[i + 2]; + const m03 = m[i + 3]; + const m10 = m[i + 4]; + const m11 = m[i + 5]; + const m12 = m[i + 6]; + const m13 = m[i + 7]; + const m20 = m[i + 8]; + const m21 = m[i + 9]; + const m22 = m[i + 10]; + const m23 = m[i + 11]; + const m30 = m[i + 12]; + const m31 = m[i + 13]; + const m32 = m[i + 14]; + const m33 = m[i + 15]; + return [ + m00 * m11 - m01 * m10, + m00 * m12 - m02 * m10, + m00 * m13 - m03 * m10, + m01 * m12 - m02 * m11, + m01 * m13 - m03 * m11, + m02 * m13 - m03 * m12, + m20 * m31 - m21 * m30, + m20 * m32 - m22 * m30, + m20 * m33 - m23 * m30, + m21 * m32 - m22 * m31, + m21 * m33 - m23 * m31, + m22 * m33 - m23 * m32, + ]; +}; + +export const det44 = (m: ReadonlyMat, i = 0) => { + const d = detCoeffs44(m, i); + return d[0] * d[11] - d[1] * d[10] + d[2] * d[9] + + d[3] * d[8] - d[4] * d[7] + d[5] * d[6]; +}; + +export const invert44 = (m: Mat, i = 0) => { + const m00 = m[i]; + const m01 = m[i + 1]; + const m02 = m[i + 2]; + const m03 = m[i + 3]; + const m10 = m[i + 4]; + const m11 = m[i + 5]; + const m12 = m[i + 6]; + const m13 = m[i + 7]; + const m20 = m[i + 8]; + const m21 = m[i + 9]; + const m22 = m[i + 10]; + const m23 = m[i + 11]; + const m30 = m[i + 12]; + const m31 = m[i + 13]; + const m32 = m[i + 14]; + const m33 = m[i + 15]; + const d = detCoeffs44(m, i); + const d00 = d[0]; + const d01 = d[1]; + const d02 = d[2]; + const d03 = d[3]; + const d04 = d[4]; + const d05 = d[5]; + const d06 = d[6]; + const d07 = d[7]; + const d08 = d[8]; + const d09 = d[9]; + const d10 = d[10]; + const d11 = d[11]; + let det = (d00 * d11 - d01 * d10 + d02 * d09 + d03 * d08 - d04 * d07 + d05 * d06); + if (!det) { + return; + } + det = 1.0 / det; + return setS44( + m, + (m11 * d11 - m12 * d10 + m13 * d09) * det, + (-m01 * d11 + m02 * d10 - m03 * d09) * det, + (m31 * d05 - m32 * d04 + m33 * d03) * det, + (-m21 * d05 + m22 * d04 - m23 * d03) * det, + (-m10 * d11 + m12 * d08 - m13 * d07) * det, + (m00 * d11 - m02 * d08 + m03 * d07) * det, + (-m30 * d05 + m32 * d02 - m33 * d01) * det, + (m20 * d05 - m22 * d02 + m23 * d01) * det, + (m10 * d10 - m11 * d08 + m13 * d06) * det, + (-m00 * d10 + m01 * d08 - m03 * d06) * det, + (m30 * d04 - m31 * d02 + m33 * d00) * det, + (-m20 * d04 + m21 * d02 - m23 * d00) * det, + (-m10 * d09 + m11 * d07 - m12 * d06) * det, + (m00 * d09 - m01 * d07 + m02 * d06) * det, + (-m30 * d03 + m31 * d01 - m32 * d00) * det, + (m20 * d03 - m21 * d01 + m22 * d00) * det, + i + ); +} + +export const transpose44 = (m: Mat, i = 0) => + setS44( + m, + m[i], m[i + 4], m[i + 8], m[i + 12], + m[i + 1], m[i + 5], m[i + 9], m[i + 13], + m[i + 2], m[i + 6], m[i + 10], m[i + 14], + m[i + 3], m[i + 7], m[i + 11], m[i + 15], + i + ); + +export const normal44 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => { + const m00 = b[ib]; + const m01 = b[ib + 1]; + const m02 = b[ib + 2]; + const m10 = b[ib + 4]; + const m11 = b[ib + 5]; + const m12 = b[ib + 6]; + const m20 = b[ib + 8]; + const m21 = b[ib + 9]; + const m22 = b[ib + 10]; + const d01 = m22 * m11 - m12 * m21; + const d11 = -m22 * m10 + m12 * m20; + const d21 = m21 * m10 - m11 * m20; + let det = m00 * d01 + m01 * d11 + m02 * d21; + if (!det) { + return; + } + det = 1.0 / det; + a[ia] = d01 * det; + a[ia + 1] = d11 * det; + a[ia + 2] = d21 * det; + a[ia + 3] = (-m22 * m01 + m02 * m21) * det; + a[ia + 4] = (m22 * m00 - m02 * m20) * det; + a[ia + 5] = (-m21 * m00 + m01 * m20) * det; + a[ia + 6] = (m12 * m01 - m02 * m11) * det; + a[ia + 7] = (-m12 * m00 + m02 * m10) * det; + a[ia + 8] = (m11 * m00 - m01 * m10) * det; + return a; +}; + +export const mat44to33 = (m33: Mat, m44: ReadonlyMat, ia = 0, ib = 0) => ( + set3(m33, m44, ia, ib), + set3(m33, m44, ia + 3, ib + 4), + set3(m33, m44, ia + 6, ib + 8), + m33 +); + +export class Mat44 extends NDArray2 { + + static identity() { + return new Mat44(identity44()); + } + + static rotationX(theta: number) { + return new Mat44(rotationX44([], theta)); + } + + static rotationY(theta: number) { + return new Mat44(rotationY44([], theta)); + } + + static rotationZ(theta: number) { + return new Mat44(rotationZ44([], theta)); + } + + static scale(v: ReadonlyVec): Mat44; + static scale(n: number): Mat44; + static scale(x: number, y: number, z: number): Mat44; + static scale(x: any, y = x, z = x) { + return new Mat44( + isNumber(x) ? + scaleS44([], x, y, z) : + scaleV44([], x) + ); + } + + static scaleWithCenter(p: ReadonlyVec, sx: number, sy = sx, sz = sy) { + return new Mat44(scaleWithCenter44([], p, sx, sy, sz)); + } + + static translation(v: ReadonlyVec): Mat44; + static translation(x: number, y: number, z: number): Mat44; + static translation(x: any, y?: any, z?: any) { + return new Mat44( + isNumber(x) ? + translationS44([], x, y, z) : + translationV44([], x) + ); + } + + static perspective(fov: number, aspect: number, near: number, far: number) { + return new Mat44(perspective([], fov, aspect, near, far)); + } + + static ortho(left: number, right: number, bottom: number, top: number, near: number, far: number) { + return new Mat44(ortho([], left, right, bottom, top, near, far)); + } + + static frustum(left: number, right: number, bottom: number, top: number, near: number, far: number) { + return new Mat44(frustum([], left, right, bottom, top, near, far)); + } + + static lookAt(eye: ReadonlyVec, target: ReadonlyVec, up: ReadonlyVec) { + return new Mat44(lookAt([], eye, target, up)); + } + + static concat(m: Readonly, ...xs: Readonly[]) { + return new Mat44(concat44.apply(null, [ + get44(m.buf, m.i), 0, + ...<[ReadonlyMat, number][]>xs.map((x) => [x.buf, x.i])]) + ); + } + + constructor(buf?: Mat, i = 0) { + super(buf || (new Array(16).fill(0)), [4, 4], [1, 4], i); + } + + [Symbol.iterator]() { + return iterator(this.buf, 16, this.i); + } + + get length() { + return 16; + } + + copy() { + return new Mat44([...this]); + } + + identity() { + identity44(this.buf, this.i); + return this; + } + + setM(m: Readonly) { + set44(this.buf, m.buf, this.i, m.i); + return this; + } + + setS(m00: number, m01: number, m02: number, m03: number, + m10: number, m11: number, m12: number, m13: number, + m20: number, m21: number, m22: number, m23: number, + m30: number, m31: number, m32: number, m33: number) { + setS44( + this.buf, + m00, m01, m02, m03, + m10, m11, m12, m13, + m20, m21, m22, m23, + m30, m31, m32, m33, + this.i + ); + return this; + } + + mul(m: Readonly) { + mul44(this.buf, m.buf, this.i, m.i); + return this; + } + + mulV3(v: Vec) { + mulV344(v, this.buf, this.i); + return v; + } + + mulV(v: Vec) { + mulV44(v, this.buf, this.i); + return v; + } + + determinant() { + return det44(this.buf, this.i); + } + + invert() { + invert44(this.buf, this.i); + return this; + } + + transpose() { + transpose44(this.buf, this.i); + return this; + } + + normalMat(m?: Mat33) { + !m && (m = new Mat33([])); + normal44(m.buf, this.buf, m.i, this.i); + return m; + } + + toMat33(m?: Mat33) { + !m && (m = new Mat33([])); + mat44to33(m.buf, this.buf, m.i, this.i); + return m; + } +} diff --git a/packages/vectors2/src/nd.ts b/packages/vectors2/src/nd.ts new file mode 100644 index 0000000000..eff49022cb --- /dev/null +++ b/packages/vectors2/src/nd.ts @@ -0,0 +1,554 @@ +import { isArrayLike } from "@thi.ng/checks/is-arraylike"; +import { isNumber } from "@thi.ng/checks/is-number"; +import { equiv } from "@thi.ng/equiv"; +import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { unsupported } from "@thi.ng/errors/unsupported"; +import { EPS } from "@thi.ng/math/api"; +import { floatFixedWidth } from "@thi.ng/strings/float"; +import { padLeft } from "@thi.ng/strings/pad-left"; +import { truncate } from "@thi.ng/strings/truncate"; +import { INDArray, NDVec } from "./api"; +import { declareIndices } from "./internal/accessors"; +import { eqDelta as _eqDelta } from "./internal/equiv"; + +export class NDArray1 implements + INDArray { + + buf: NDVec; + i: number; + s: number; + readonly length: number; + + x: number; + y: number; + z: number; + w: number; + [id: number]: number; + + constructor(buf: NDVec, shape: number[], strides: number[], offset = 0) { + this.buf = buf; + this.i = offset; + this.s = strides[0]; + this.length = shape[0]; + } + + *[Symbol.iterator]() { + for (let i = this.i, y = this.length, s = this.s, buf = this.buf; --y >= 0; i += s) { + yield buf[i]; + } + } + + get dim() { + return 1; + } + + get offset() { + return this.i; + } + + get order() { + return [0]; + } + + get shape() { + return [this.length]; + } + + get stride() { + return [this.s]; + } + + copy() { + return new NDArray1( + [...this], + [this.shape[0]], + [1], + this.i + ); + } + + equiv(o: any) { + return this === o || + (isArrayLike(o) && + this.length === o.length && + equiv([...this], o)); + } + + eqDelta(o: NDArray1, eps = EPS) { + return this === o || + _eqDelta([...this], [...o], this.length, eps); + } + + index(x: number) { + return this.i + x * this.s; + } + + get(x: number) { + return this.buf[this.i + x * this.s]; + } + + set(x: number, v: T) { + this.buf[this.i + x * this.s] = v; + return this; + } + + hi(x: number) { + return new NDArray1( + this.buf, + [x != null && x >= 0 ? x : this.shape[0]], + this.stride, + this.i + ); + } + + lo(x: number) { + const s = this.shape; + const t = this.stride; + let o = this.i; + return new NDArray1( + this.buf, + [x != null && x >= 0 ? (o += t[0] * x, s[0] - x) : s[0]], + t, o + ); + } + + step(x: number) { + const s = this.shape.slice(); + const t = this.stride.slice(); + return new NDArray1(this.buf, s, t, step(x, 0, s, t, this.i)); + } + + pick(x: number) { + return x != null && x >= 0 ? + new NDArray1(this.buf, [1], [1], this.i + x * this.s) : + undefined + } + + transpose() { + return this.copy() + } + + toJSON() { + return { + buf: [...this], + shape: this.shape, + stride: [1], + }; + } + + toString() { + const res = []; + for (let x of this) { + res.push(format(x)); + } + return res.join(" "); + } +} + +declareIndices(NDArray1.prototype, ["x", "y", "z", "w"]); + +export class NDArray2 implements + INDArray { + + buf: NDVec; + i: number; + shape: number[]; + stride: number[]; + + protected _n: number; + + constructor(buf: NDVec, shape: number[], stride: number[], offset = 0) { + this.buf = buf; + this.i = offset; + this.shape = shape; + this.stride = stride; + } + + *[Symbol.iterator]() { + const buf = this.buf; + const [sx, sy] = this.shape; + const [tx, ty] = this.stride; + for (let i = this.i, x = 0; x < sx; x++ , i += tx) { + for (let y = 0; y < sy; y++) { + yield buf[i + y * ty]; + } + } + } + + get length() { + return this._n || (this._n = this.shape.reduce((acc, x) => acc * x, 1)); + } + + get dim() { + return 2; + } + + get offset() { + return this.i; + } + + get order() { + return Math.abs(this.stride[1]) > Math.abs(this.stride[0]) ? + [1, 0] : + [0, 1]; + } + + copy() { + return new NDArray2( + [...this.buf], + [...this.shape], + shapeToStride(this.shape), + this.i + ); + } + + equiv(o: any) { + return this === o || + (o instanceof NDArray2 && + equiv(this.shape, o.shape) && + equiv([...this], [...o])); + } + + eqDelta(o: NDArray2, eps = EPS) { + return this === o || + (equiv(this.shape, o.shape) && + _eqDelta([...this], [...o], this.length, eps)); + } + + index(x: number, y: number) { + const t = this.stride; + return this.i + x * t[0] + y * t[1]; + } + + get(x: number, y: number) { + const t = this.stride; + return this.buf[this.i + x * t[0] + y * t[1]]; + } + + set(x: number, y: number, v: T) { + const t = this.stride; + this.buf[this.i + x * t[0] + y * t[1]] = v; + return this; + } + + hi(x?: number, y?: number) { + const s = this.shape; + return new NDArray2( + this.buf, + [ + x != null && x >= 0 ? x : s[0], + y != null && y >= 0 ? y : s[1], + ], + this.stride, + this.i + ); + } + + lo(x?: number, y?: number) { + const s = this.shape; + const t = this.stride; + let o = this.i; + return new NDArray2( + this.buf, + [ + x != null && x >= 0 ? (o += t[0] * x, s[0] - x) : s[0], + y != null && y >= 0 ? (o += t[1] * y, s[1] - y) : s[1] + ], + t, o + ); + } + + step(x?: number, y?: number) { + const s = this.shape.slice(); + const t = this.stride.slice(); + return new NDArray2( + this.buf, s, t, + step(y, 1, s, t, step(x, 0, s, t, this.i)) + ); + } + + pick(x?: number, y?: number) { + const s = []; + const t = []; + return ndarray(this.buf, s, t, + pick(y, 1, s, t, this.shape, this.stride, + pick(x, 0, s, t, this.shape, this.stride, this.i)) + ); + } + + transpose(x: number, y: number) { + const s = this.shape; + const t = this.stride; + return new NDArray2(this.buf, [s[x], s[y]], [t[x], t[y]], this.i); + } + + toJSON() { + return { + buf: [...this], + shape: this.shape, + stride: shapeToStride(this.shape), + }; + } + + toString() { + const res = []; + for (let i = 0; i < this.shape[0]; i++) { + res.push(this.pick(i).toString()); + } + return res.join("\n"); + } +} + +export class NDArray3 implements + INDArray { + + buf: NDVec; + i: number; + shape: number[]; + stride: number[]; + + protected _n: number; + + constructor(buf: NDVec, shape: number[], stride: number[], offset = 0) { + this.buf = buf; + this.shape = shape; + this.stride = stride; + this.i = offset; + } + + *[Symbol.iterator]() { + const buf = this.buf; + const [sx, sy, sz] = this.shape; + const [tx, ty, tz] = this.stride; + for (let i = this.i, x = sx; --x >= 0; i += tx) { + for (let j = i, y = sy; --y >= 0; j += ty) { + for (let z = 0; z < sz; z++) { + yield buf[j + z * tz]; + } + } + } + } + + get length() { + return this._n || (this._n = this.shape.reduce((acc, x) => acc * x, 1)); + } + + get dim() { + return 3; + } + + get offset() { + return this.i; + } + + get order() { + return strideOrder(this.stride); + } + + index(x: number, y: number, z: number) { + const t = this.stride; + return this.i + x * t[0] + y * t[1] + z * t[2]; + } + + get(x: number, y: number, z: number) { + const t = this.stride; + return this.buf[this.i + x * t[0] + y * t[1] + z * t[2]]; + } + + set(x: number, y: number, z: number, v: T) { + const t = this.stride; + this.buf[this.i + x * t[0] + y * t[1] + z * t[2]] = v; + } + + copy() { + return new NDArray2( + [...this.buf], + [...this.shape], + shapeToStride(this.shape), + this.i + ); + } + + equiv(o: any) { + return this === o || + (o instanceof NDArray3 && + equiv(this.shape, o.shape) && + equiv([...this], [...o])); + } + + eqDelta(o: NDArray3, eps = EPS) { + return this === o || + (equiv(this.shape, o.shape) && + _eqDelta([...this], [...o], this.length, eps)); + } + + hi(x?: number, y?: number, z?: number) { + const s = this.shape; + return new NDArray3( + this.buf, + [ + x != null && x >= 0 ? x : s[0], + y != null && y >= 0 ? y : s[1], + z != null && z >= 0 ? z : s[2], + ], + this.stride, + this.i + ); + } + + lo(x?: number, y?: number, z?: number) { + const s = this.shape; + const t = this.stride; + let o = this.i; + return new NDArray3( + this.buf, + [ + x != null && x >= 0 ? (o += t[0] * x, s[0] - x) : s[0], + y != null && y >= 0 ? (o += t[1] * y, s[1] - y) : s[1], + z != null && z >= 0 ? (o += t[2] * z, s[2] - y) : s[2], + ], + t, o + ); + } + + step(x?: number, y?: number, z?: number) { + const s = this.shape.slice(); + const t = this.stride.slice(); + return new NDArray3( + this.buf, s, t, + step(z, 2, s, t, + step(y, 1, s, t, + step(x, 0, s, t, this.i))) + ); + } + + pick(x?: number, y?: number, z?: number) { + const s = []; + const t = []; + const ss = this.shape; + const st = this.stride; + return ndarray( + this.buf, s, t, + pick(z, 2, s, t, ss, st, + pick(y, 1, s, t, ss, st, + pick(x, 0, s, t, ss, st, this.i))) + ); + } + + transpose(x: number, y: number, z: number) { + const s = this.shape; + const t = this.stride; + return new NDArray3(this.buf, [s[x], s[y], s[z]], [t[x], t[y], t[z]], this.i); + } + + toJSON() { + return { + buf: [...this], + shape: this.shape, + stride: shapeToStride(this.shape), + }; + } + + toString() { + const res = []; + for (let i = 0; i < this.shape[0]; i++) { + res.push(`--- ${i}: ---`, this.pick(i).toString()); + } + return res.join("\n"); + } +} + +export const ndarray = ( + buf?: NDVec, + shape?: number[], + strides?: number[], + offset?: number): INDArray => { + + if (!(buf || shape)) { + illegalArgs("data or shape must be provided"); + } + buf = buf || new Array(shape.reduce((a, b) => a * b, 1)).fill(0); + !shape && (shape = [buf.length]); + !strides && (strides = shapeToStride(shape)); + if (offset === undefined) { + offset = 0; + for (let i = 0; i < shape.length; i++) { + if (strides[i] < 0) { + offset -= (shape[i] - 1) * strides[i]; + } + } + } + switch (shape.length) { + case 0: + return new NDArray1(buf, [1], [1], offset); + case 1: + return new NDArray1(buf, shape, strides, offset); + case 2: + return new NDArray2(buf, shape, strides, offset); + case 3: + return new NDArray3(buf, shape, strides, offset); + default: + unsupported(`unsupported dimension: ${shape.length}`); + } +} + +const shapeToStride = + (shape: number[]) => { + const n = shape.length; + const stride = new Array(n); + for (let i = n, s = 1; --i >= 0; s *= shape[i]) { + stride[i] = s; + } + return stride; + }; + +const strideOrder = + (strides: number[]) => + strides + .map((x, i) => [x, i]) + .sort((a, b) => Math.abs(b[0]) - Math.abs(a[0])) + .map((x) => x[1]); + +const step = ( + x: number, + i: number, + shape: number[], + strides: number[], + o: number) => { + + if (x) { + if (x < 0) { + o += strides[i] * (shape[i] - 1); + shape[i] = Math.ceil(-shape[i] / x); + } else { + shape[i] = Math.ceil(shape[i] / x); + } + strides[i] *= x; + } + return o; +}; + +const pick = ( + x: number, + i: number, + ds: number[], + dt: number[], + ss: number[], + st: number[], + o: number) => { + + if (x != null && x >= 0) { + o += st[i] * x; + } else { + ds.push(ss[i]); + dt.push(st[i]); + } + return o; +}; + +const ff = floatFixedWidth(9, 4); +const pad = padLeft(9); +const trunc = truncate(9); + +const format = + (x: any) => isNumber(x) ? ff(x) : trunc(pad(x.toString())); \ No newline at end of file diff --git a/packages/vectors2/src/pool.ts b/packages/vectors2/src/pool.ts index e94e58e83b..07ee85b17a 100644 --- a/packages/vectors2/src/pool.ts +++ b/packages/vectors2/src/pool.ts @@ -1,15 +1,14 @@ import { TypedArray } from "@thi.ng/api"; import { isTypedArray } from "@thi.ng/checks/is-typedarray"; -import { MemPool, Type, MemPoolOpts } from "@thi.ng/malloc"; +import { MemPool, MemPoolOpts, Type } from "@thi.ng/malloc"; +import { IVecPool, IVector, Vec } from "./api"; import { Vec2 } from "./vec2"; import { Vec3 } from "./vec3"; -import { IVector } from "./api"; - -export { Type } const F64 = Type.F64; -export class VecPool { +export class VecPool implements + IVecPool { pool: MemPool; @@ -21,11 +20,15 @@ export class VecPool { pool; } - malloc(size: number, type: Type = F64) { + stats() { + return this.pool.stats(); + } + + malloc(size: number, type: Type = F64): Vec { return this.pool.callocAs(type, size); } - mallocWrapped(size: number, stride = 1, type: Type = F64) { + mallocWrapped(size: number, stride = 1, type: Type = F64): IVector { const buf = this.pool.callocAs(type, size * stride); if (!buf) return; switch (size) { @@ -48,4 +51,14 @@ export class VecPool { } return this.pool.free(vec); } + + freeAll() { + this.pool.freeAll(); + } + + release() { + const res = this.pool.release(); + res && delete this.pool; + return res; + } } diff --git a/packages/vectors2/src/vec2.ts b/packages/vectors2/src/vec2.ts index 73f58de45c..fc8e0deddd 100644 --- a/packages/vectors2/src/vec2.ts +++ b/packages/vectors2/src/vec2.ts @@ -2,9 +2,9 @@ import { Comparator } from "@thi.ng/api"; import { EPS, HALF_PI, PI } from "@thi.ng/math/api"; import { eqDelta as _eqDelta } from "@thi.ng/math/eqdelta"; import { max2id, min2id } from "@thi.ng/math/interval"; -import { declareIndices } from "./accessors"; +import { declareIndices } from "./internal/accessors"; import { AVec } from "./avec"; -import { genCommon } from "./codegen"; +import { genCommon } from "./internal/codegen"; import { magSq, dot, @@ -133,7 +133,61 @@ export class Vec2 extends AVec implements } declareIndices(Vec2.prototype, ["x", "y"]); -genCommon(2); + +export const [ + set2, + setN2, + setS2, + rand2_01, + rand2_11, + rand2, + add2, + sub2, + mul2, + div2, + addNew2, + subNew2, + mulNew2, + divNew2, + addN2, + subN2, + mulN2, + divN2, + addNewN2, + subNewN2, + mulNewN2, + divNewN2, + madd2, + maddN2, + maddNew2, + maddNewN2, + abs2, + sign2, + sin2, + cos2, + tan2, + asin2, + acos2, + atan2, + floor2, + ceil2, + trunc2, + fract2, + sqrt2, + log2, + exp2, + pow2, + powN2, + min2, + max2, + clamp2, + step2, + smoothStep2, + mix2, + mixN2, + mixNew2, + mixNewN2, +] = genCommon(2); const abs = Math.abs; const pow = Math.pow; diff --git a/packages/vectors2/src/vec3.ts b/packages/vectors2/src/vec3.ts index 1af4069077..3d226b0eb4 100644 --- a/packages/vectors2/src/vec3.ts +++ b/packages/vectors2/src/vec3.ts @@ -2,9 +2,9 @@ import { Comparator } from "@thi.ng/api"; import { EPS } from "@thi.ng/math/api"; import { eqDelta as _eqDelta } from "@thi.ng/math/eqdelta"; import { max3id, min3id } from "@thi.ng/math/interval"; -import { declareIndices } from "./accessors"; +import { declareIndices } from "./internal/accessors"; import { AVec } from "./avec"; -import { genCommon } from "./codegen"; +import { genCommon } from "./internal/codegen"; import { magSq, dot, @@ -135,7 +135,61 @@ export class Vec3 extends AVec implements } declareIndices(Vec3.prototype, ["x", "y", "z"]); -genCommon(3); + +export const [ + set3, + setN3, + setS3, + rand3_01, + rand3_11, + rand3, + add3, + sub3, + mul3, + div3, + addNew3, + subNew3, + mulNew3, + divNew3, + addN3, + subN3, + mulN3, + divN3, + addNewN3, + subNewN3, + mulNewN3, + divNewN3, + madd3, + maddN3, + maddNew3, + maddNewN3, + abs3, + sign3, + sin3, + cos3, + tan3, + asin3, + acos3, + atan3, + floor3, + ceil3, + trunc3, + fract3, + sqrt3, + log3, + exp3, + pow3, + powN3, + min3, + max3, + clamp3, + step3, + smoothStep3, + mix3, + mixN3, + mixNew3, + mixNewN3, +] = genCommon(3); const abs = Math.abs; const pow = Math.pow; diff --git a/packages/vectors2/src/vec4.ts b/packages/vectors2/src/vec4.ts new file mode 100644 index 0000000000..d5fbdf4524 --- /dev/null +++ b/packages/vectors2/src/vec4.ts @@ -0,0 +1,273 @@ +import { Comparator } from "@thi.ng/api/api"; +import { EPS } from "@thi.ng/math/api"; +import { eqDelta as _eqDelta } from "@thi.ng/math/eqdelta"; +import { max4id, min4id } from "@thi.ng/math/interval"; +import { declareIndices } from "./internal/accessors"; +import { AVec } from "./avec"; +import { genCommon } from "./internal/codegen"; +import { + magSq, + dot, + Vec, + IVector, + minor, + major, + distSq, + distManhattan, + distChebyshev, + eqDelta, + Vec4Coord, + X4, + Y4, + Z4, + MIN4, + MAX4, + ZERO4, + ONE4, + ReadonlyVec, + dist, +} from "./api"; + +export class Vec4 extends AVec implements + IVector { + + /** + * Returns array of memory mapped `Vec4` instances using given + * backing array and stride settings: The `cstride` is the step size + * between individual XYZ vector components. `estride` is the step + * size between successive vectors. This arrangement allows for + * different storage approaches, incl. SOA, AOS, striped / + * interleaved etc. + * + * @param buf backing array + * @param n num vectors + * @param start start index + * @param cstride component stride + * @param estride element stride + */ + static mapBuffer(buf: Vec, n: number = buf.length >> 2, start = 0, cstride = 1, estride = 4) { + const res: Vec4[] = []; + while (--n >= 0) { + res.push(new Vec4(buf, start, cstride)); + start += estride; + } + return res; + } + + /** + * Merges given `src` iterable of `Vec4`s into single array `buf`. + * Vectors will be arranged according to given component and element + * strides, starting at `start` index. It's the user's + * responsibility to ensure the target buffer has sufficient + * capacity to hold the input vectors. See `Vec4.mapBuffer` for the + * inverse operation. Returns `buf`. + * + * @param buf + * @param src + * @param start + * @param cstride + * @param estride + */ + static intoBuffer(buf: Vec, src: Iterable>, start = 0, cstride = 1, estride = 3) { + for (let v of src) { + buf[start] = v[0]; + buf[start + cstride] = v[1]; + buf[start + 2 * cstride] = v[2]; + start += estride; + } + return buf; + } + + static readonly X_AXIS = new Vec4(X4); + static readonly Y_AXIS = new Vec4(Y4); + static readonly Z_AXIS = new Vec4(Z4); + static readonly MIN = new Vec4(MIN4); + static readonly MAX = new Vec4(MAX4); + static readonly ZERO = new Vec4(ZERO4); + static readonly ONE = new Vec4(ONE4); + + x: number; + y: number; + z: number; + w: number; + [id: number]: number; + + constructor(buf?: Vec, i = 0, s = 1) { + super(buf || [0, 0, 0, 0], i, s); + } + + *[Symbol.iterator]() { + yield this.x; + yield this.y; + yield this.z; + yield this.w; + } + + get length() { + return 4; + } + + copy() { + return new Vec4([this.x, this.y, this.z]); + } + + empty() { + return new Vec4(); + } + + eqDelta(v: ReadonlyVec, eps = EPS) { + return eqDelta(this, v, eps); + } + + toJSON() { + return [this.x, this.y, this.z]; + } + + toString() { + return `[${this.x}, ${this.y}, ${this.z}]`; + } +} + +declareIndices(Vec4.prototype, ["x", "y", "z", "w"]); + +export const [ + set4, + setN4, + setS4, + rand4_01, + rand4_11, + rand4, + add4, + sub4, + mul4, + div4, + addNew4, + subNew4, + mulNew4, + divNew4, + addN4, + subN4, + mulN4, + divN4, + addNewN4, + subNewN4, + mulNewN4, + divNewN4, + madd4, + maddN4, + maddNew4, + maddNewN4, + abs4, + sign4, + sin4, + cos4, + tan4, + asin4, + acos4, + atan4, + floor4, + ceil4, + trunc4, + fract4, + sqrt4, + log4, + exp4, + pow4, + powN4, + min4, + max4, + clamp4, + step4, + smoothStep4, + mix4, + mixN4, + mixNew4, + mixNewN4, +] = genCommon(4); + +const abs = Math.abs; +const pow = Math.pow; +const sqrt = Math.sqrt; + +eqDelta.add(4, (a, b, eps = EPS) => + b.length == 4 && + _eqDelta(a[0], b[0], eps) && + _eqDelta(a[1], b[1], eps) && + _eqDelta(a[2], b[2], eps) && + _eqDelta(a[3], b[3], eps) +); + +dot.add(4, (a, b) => a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]); + +magSq.add(4, (a) => a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3]); + +const distsq4 = + (a: ReadonlyVec, b: ReadonlyVec) => + pow(a[0] - b[0], 2) + + pow(a[1] - b[1], 2) + + pow(a[2] - b[2], 2) + + pow(a[3] - b[3], 2); + +distSq.add(4, distsq4); +dist.add(4, (a, b) => sqrt(distsq4(a, b))); + +distManhattan.add(4, (a, b) => + abs(a[0] - b[0]) + + abs(a[1] - b[1]) + + abs(a[2] - b[2]) + + abs(a[3] - b[3]) +); + +distChebyshev.add(4, (a, b) => + Math.max( + abs(a[0] - b[0]), + abs(a[1] - b[1]), + abs(a[2] - b[2]), + abs(a[3] - b[3]) + ) +); + +minor.add(4, (a) => min4id(abs(a[0]), abs(a[1]), abs(a[2]), abs(a[3]))); + +major.add(4, (a) => max4id(abs(a[0]), abs(a[1]), abs(a[2]), abs(a[3]))); + +export const vec4 = + (x = 0, y = 0, z = 0, w = 0) => new Vec4([x, y, z, w]); + +export const vec4n = + (n: number) => new Vec4([n, n, n, n]); + +export const asVec4 = + (x: Vec) => + x instanceof Vec4 ? + x : + new Vec4(x.length !== 4 ? + [x[0] || 0, x[1] || 0, x[2] || 0, x[3] || 0] : + x); + +export const swizzle4 = + (a: Vec, b: ReadonlyVec, x: number, y: number, z: number, w: number) => + (a[0] = b[x] || 0, a[1] = b[y] || 0, a[2] = b[z] || 0, a[3] = b[w] || 0, a); + +export const comparator4 = + (o1: Vec4Coord, o2: Vec4Coord, o3: Vec4Coord, o4: Vec4Coord): Comparator => + (a, b): number => { + + const ax = a[o1]; + const ay = a[o2]; + const az = a[o3]; + const aw = b[o4]; + const bx = b[o1]; + const by = b[o2]; + const bz = b[o3]; + const bw = b[o4]; + return ax === bx ? + ay === by ? + az === bz ? + aw === bw ? + 0 : + aw < bw ? -4 : 4 : + az < bz ? -3 : 3 : + ay < by ? -2 : 2 : + ax < bx ? -1 : 1; + }; From 816c9c01e52a475788c0b295aaf4a92915e3d0a8 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 31 Oct 2018 12:09:29 +0000 Subject: [PATCH 011/333] feat(strings): add floatFixedWidth(), update float() - add support for NaN, -/+Infinity --- packages/strings/src/float.ts | 55 ++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/packages/strings/src/float.ts b/packages/strings/src/float.ts index 5b8d2f71d6..f1f10c4006 100644 --- a/packages/strings/src/float.ts +++ b/packages/strings/src/float.ts @@ -1,12 +1,65 @@ import { memoizeJ } from "@thi.ng/memoize/memoizej"; import { Stringer } from "./api"; +import { padLeft } from "./pad-left"; /** * Returns `Stringer` which formats numbers to given precision. + * Exceptions: + * + * - NaN => "NaN" + * - Infinity => "+/-∞" * * @param len number of fractional digits * @kind function */ export const float: (prec: number) => Stringer = - memoizeJ((prec) => (x: number) => x.toFixed(prec)); + memoizeJ((prec) => + (x: number) => + nanOrInf(x) || x.toFixed(prec) + ); + +/** + * Similar to `float`, returns `Stringer` which formats numbers to given + * character width & precision. Uses scientific notation if needed. + * + * Default precision: 3 fractional digits + */ +export const floatFixedWidth: (width: number, prec?: number) => Stringer = + memoizeJ((width, prec = 3) => { + const l = width - prec - 1; + const pl = Math.pow(10, l); + const pln = -Math.pow(10, l - 1); + const pr = Math.pow(10, -(prec - 1)); + const pad = padLeft(width); + return (x: number) => { + const ax = Math.abs(x); + return pad( + nanOrInf(x) || + (x === 0 ? + "0" : + ax < pr || ax >= pl ? + exp(x, width) : + x.toFixed(prec - (x < pln ? 1 : 0))) + ); + } + }); + +const exp = (x: number, w: number) => + x.toExponential( + Math.max( + w - 4 - + (Math.log(Math.abs(x)) / Math.LN10 >= 10 ? 2 : 1) + - (x < 0 ? 1 : 0), + 0 + ) + ); + +const nanOrInf = (x: number) => + isNaN(x) ? + "NaN" : + x === Infinity ? + "+∞" : + x === -Infinity ? + "-∞" : + undefined; From 954e0c28ca89272f569f6c1bbb33559097b58099 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 31 Oct 2018 14:16:21 +0000 Subject: [PATCH 012/333] feat(vectors): add generic impls for common vec ops --- packages/vectors2/src/api.ts | 18 +- packages/vectors2/src/avec.ts | 7 - packages/vectors2/src/internal/codegen.ts | 196 +++++++++++++++++++--- packages/vectors2/src/nd.ts | 12 +- packages/vectors2/src/pool.ts | 9 +- 5 files changed, 202 insertions(+), 40 deletions(-) diff --git a/packages/vectors2/src/api.ts b/packages/vectors2/src/api.ts index b6ca20a450..1f921ac737 100644 --- a/packages/vectors2/src/api.ts +++ b/packages/vectors2/src/api.ts @@ -2,15 +2,16 @@ import { ICopy, IEmpty, IEqualsDelta, + IEquiv, ILength, IRelease, - TypedArray, - IEquiv + TypedArray } from "@thi.ng/api"; import { implementsFunction } from "@thi.ng/checks/implements-function"; import { Type } from "@thi.ng/malloc/api"; import { atan2Abs } from "@thi.ng/math/angle"; import { EPS } from "@thi.ng/math/api"; +import { genCommonDefaults } from "./internal/codegen"; import { eqDelta as _eqDelta } from "./internal/equiv"; import { vop } from "./internal/ops"; import { VecPool } from "./pool"; @@ -209,7 +210,7 @@ export const getPool = () => POOL; export const usePool = (pool: VecPool) => (POOL = pool); export const vec = (n: number) => - POOL ? POOL.malloc(n) : new Array(n).fill(0); + POOL ? POOL.malloc(n) : zeroes(n); export const set: MultiVecOpVV = vop(); export const setN: MultiVecOpVN = vop(); @@ -279,8 +280,17 @@ export const maddNew: MultiVecOpNewVVV = vop(); export const maddNewN: MultiVecOpNewVVN = vop(); export const dot: MultiVecOpRoVV = vop(); +dot.default((a, b) => { + let res = 0; + for (let i = a.length; --i >= 0;) { + res += a[i] * b[i]; + } + return res; +}); export const magSq: MultiVecOpRoV = vop(); +magSq.default((v) => dot(v, v)); + export const mag: MultiVecOpRoV = vop(); mag.default((a) => Math.sqrt(magSq(a, a))); @@ -387,3 +397,5 @@ export const X4 = Object.freeze([1, 0, 0, 0]); export const Y4 = Object.freeze([0, 1, 0, 0]); export const Z4 = Object.freeze([0, 0, 1, 0]); export const W4 = Object.freeze([0, 0, 0, 1]); + +genCommonDefaults(); diff --git a/packages/vectors2/src/avec.ts b/packages/vectors2/src/avec.ts index 4291f14dd2..e9a4ac24a0 100644 --- a/packages/vectors2/src/avec.ts +++ b/packages/vectors2/src/avec.ts @@ -29,11 +29,4 @@ export abstract class AVec { get stride() { return [this.s]; } - - extract(dest: Vec = []) { - for (let n = this.length - 1, s = this.s, i = this.i + n * s; n >= 0; i -= s, n--) { - dest[n] = this.buf[i]; - } - return dest; - } } diff --git a/packages/vectors2/src/internal/codegen.ts b/packages/vectors2/src/internal/codegen.ts index e90c92c41b..983241df78 100644 --- a/packages/vectors2/src/internal/codegen.ts +++ b/packages/vectors2/src/internal/codegen.ts @@ -116,6 +116,20 @@ export const assemble = ( return src; }; +export const assembleG = ( + tpl: Template, + syms: string, + ret = "a", + pre?: string, + post?: string) => [ + pre, + "for(let i=a.length;--i>=0;) {", + tpl(syms.split(",").map((x) => `${x}[i]`)), + "}", + post, + ret !== null ? `return ${ret};` : "" + ]; + export const compile = ( dim: number, tpl: Template, @@ -144,26 +158,75 @@ export const compileHOF = ( )(...fns); }; -export const genOpFnV = (dim: number, op: string): VecOpV => - compile(dim, ([a]) => `${a}=${op}(${a});`, "a"); +export const compileG = ( + tpl: Template, + args: string, + syms = args, + ret = "a", + pre?: string, + post?: string) => + + new Function(args, assembleG(tpl, syms, ret, pre, post).join("")); + +export const compileGHOF = ( + fns: FnAny[], + tpl: Template, + hofArgs: string, + args: string, + syms = args, + ret = "a", + pre?: string, + post?: string) => { + + return new Function( + hofArgs, + `return (${args})=>{${assembleG(tpl, syms, ret, pre, post).join("\n")}}` + )(...fns); +}; + +const tplFnV = (fn) => ([a]) => `${a}=${fn}(${a});`; +const tplHofV = ([a]) => `${a}=fn(${a});`; +const tplVV = (op) => ([a, b]) => `${a}${op}=${b};` +const tplFnVV = (fn) => ([a, b]) => `${a}=${fn}(${a},${b});` +const tplVN = (op) => ([a]) => `${a}${op}=n;` +const tplNewVV = (op) => ([a, b, o]) => `${o}=${a}${op}${b};` +const tplNewVN = (op) => ([a, o]) => `${o}=${a}${op}n;`; +const tplRand01 = ([a]) => `${a}=Math.random();` +const tplRand11 = ([a]) => `${a}=Math.random()*2-1;` +const tplRand = ([a]) => `${a}=n+(m-n)*Math.random();` +const tplMadd = ([a, b, c]) => `${a}+=${b}*${c};` +const tplMaddN = ([a, b]) => `${a}+=${b}*n;`; +const tplMaddNew = ([a, b, c, o]) => `${o}=${a}+${b}*${c};` +const tplMaddNewN = ([a, b, o]) => `${o}=${a}+${b}*n;`; +const tplPowN = ([a]) => `${a}=Math.pow(${a},n);`; +const tplClamp = ([a, b, c]) => `${a}=fn(${a},${b},${c});`; +const tplStep = ([a, e]) => `${a}=fn(${e},${a});`; +const tplSmoothStep = ([a, e1, e2]) => `${a}=fn(${e1},${e2},${a});`; +const tplMix = ([a, b, c]) => `${a}+=(${b}-${a})*${c};`; +const tplMixN = ([a, b]) => `${a}+=(${b}-${a})*n;`; +const tplMixNew = ([a, b, c, o]) => `${o}=${a}+(${b}-${a})*${c};`; +const tplMixNewN = ([a, b, o]) => `${o}=${a}+(${b}-${a})*n;`; + +export const genOpFnV = (dim: number, fn: string): VecOpV => + compile(dim, tplFnV(fn), "a"); export const genOpHofV = (dim: number, fn) => - compileHOF(dim, [fn], ([a]) => `${a}=fn(${a});`, "fn", "a"); + compileHOF(dim, [fn], tplHofV, "fn", "a"); export const genOpVV = (dim: number, op: string): VecOpVV => - compile(dim, ([a, b]) => `${a}${op}=${b};`, "a,b"); + compile(dim, tplVV(op), "a,b"); export const genOpFnVV = (dim: number, fn: string): VecOpVV => - compile(dim, ([a, b]) => `${a}=${fn}(${a},${b});`, "a,b"); + compile(dim, tplFnVV(fn), "a,b"); export const genOpVN = (dim: number, op: string): VecOpVN => - compile(dim, ([a]) => `${a}${op}=n;`, "a,n", "a"); + compile(dim, tplVN(op), "a,n", "a"); export const genOpNewVV = (dim: number, op: string): VecOpNewVV => - compile(dim, ([a, b, o]) => `${o}=${a}${op}${b};`, "a,b,o=[]", "a,b,o", "o"); + compile(dim, tplNewVV(op), "a,b,o=[]", "a,b,o", "o"); export const genOpNewVN = (dim: number, op: string): VecOpNewVN => - compile(dim, ([a, o]) => `${o}=${a}${op}n;`, "a,n,o=[]", "a,o", "o"); + compile(dim, tplNewVN(op), "a,n,o=[]", "a,o", "o"); export const genCommon = (dim: number): CommonOps => [ set.add(dim, genOpVV(dim, "")), @@ -171,9 +234,9 @@ export const genCommon = (dim: number): CommonOps => [ setS.add(dim, compile(dim, ([a], i) => `${a}=xs[${i}];`, "a,...xs", "a")), // TODO add IRandom support - rand01.add(dim, compile(dim, ([a]) => `${a}=Math.random();`, "a")), - rand11.add(dim, compile(dim, ([a]) => `${a}=Math.random()*2-1;`, "a")), - rand.add(dim, compile(dim, ([a]) => `${a}=n+(m-n)*Math.random();`, "a,n,m", "a")), + rand01.add(dim, compile(dim, tplRand01, "a")), + rand11.add(dim, compile(dim, tplRand11, "a")), + rand.add(dim, compile(dim, tplRand, "a,n,m", "a")), add.add(dim, genOpVV(dim, "+")), sub.add(dim, genOpVV(dim, "-")), @@ -195,10 +258,10 @@ export const genCommon = (dim: number): CommonOps => [ mulNewN.add(dim, genOpNewVN(dim, "*")), divNewN.add(dim, genOpNewVN(dim, "/")), - madd.add(dim, compile(dim, ([a, b, c]) => `${a}+=${b}*${c};`, "a,b,c")), - maddN.add(dim, compile(dim, ([a, b]) => `${a}+=${b}*n;`, "a,b,n", "a,b")), - maddNew.add(dim, compile(dim, ([a, b, c, o]) => `${o}=${a}+${b}*${c};`, "a,b,c,o=[]", "a,b,c,o", "o")), - maddNewN.add(dim, compile(dim, ([a, b, o]) => `${o}=${a}+${b}*n;`, "a,b,n,o=[]", "a,b,o", "o")), + madd.add(dim, compile(dim, tplMadd, "a,b,c")), + maddN.add(dim, compile(dim, tplMaddN, "a,b,n", "a,b")), + maddNew.add(dim, compile(dim, tplMaddNew, "a,b,c,o=[]", "a,b,c,o", "o")), + maddNewN.add(dim, compile(dim, tplMaddNewN, "a,b,n,o=[]", "a,b,o", "o")), abs.add(dim, genOpFnV(dim, "Math.abs")), sign.add(dim, genOpHofV(dim, _sign)), @@ -216,17 +279,104 @@ export const genCommon = (dim: number): CommonOps => [ log.add(dim, genOpFnVV(dim, "Math.log")), exp.add(dim, genOpFnVV(dim, "Math.exp")), pow.add(dim, genOpFnVV(dim, "Math.pow")), - powN.add(dim, compile(dim, ([a]) => `${a}=Math.pow(${a},n);`, "a,n", "a")), + powN.add(dim, compile(dim, tplPowN, "a,n", "a")), min.add(dim, genOpFnVV(dim, "Math.min")), max.add(dim, genOpFnVV(dim, "Math.max")), - clamp.add(dim, compileHOF(dim, [_clamp], ([a, b, c]) => `${a}=fn(${a},${b},${c});`, "fn", "a,b,c")), + clamp.add(dim, compileHOF(dim, [_clamp], tplClamp, "fn", "a,b,c")), - step.add(dim, compileHOF(dim, [_step], ([a, e]) => `${a}=fn(${e},${a});`, "fn", "a,e")), - smoothStep.add(dim, compileHOF(dim, [_smoothStep], ([a, e1, e2]) => `${a}=fn(${e1},${e2},${a});`, "fn", "a,e1,e2")), + step.add(dim, compileHOF(dim, [_step], tplStep, "fn", "a,e")), + smoothStep.add(dim, compileHOF(dim, [_smoothStep], tplSmoothStep, "fn", "a,e1,e2")), - mix.add(dim, compile(dim, ([a, b, c]) => `${a}+=(${b}-${a})*${c};`, "a,b,c")), - mixN.add(dim, compile(dim, ([a, b]) => `${a}+=(${b}-${a})*n;`, "a,b,n", "a,b")), - mixNew.add(dim, compile(dim, ([a, b, c, o]) => `${o}=${a}+(${b}-${a})*${c};`, "a,b,c,o=[]", "a,b,c,o", "o")), - mixNewN.add(dim, compile(dim, ([a, b, o]) => `${o}=${a}+(${b}-${a})*n;`, "a,b,n,o=[]", "a,b,o", "o")), + mix.add(dim, compile(dim, tplMix, "a,b,c")), + mixN.add(dim, compile(dim, tplMixN, "a,b,n", "a,b")), + mixNew.add(dim, compile(dim, tplMixNew, "a,b,c,o=[]", "a,b,c,o", "o")), + mixNewN.add(dim, compile(dim, tplMixNewN, "a,b,n,o=[]", "a,b,o", "o")), ]; + +export const genGOpFnV = (fn: string): VecOpV => + compileG(tplFnV(fn), "a"); + +export const genGOpHofV = (fn) => + compileGHOF([fn], tplHofV, "fn", "a"); + +export const genGOpVV = (op: string): VecOpVV => + compileG(tplVV(op), "a,b"); + +export const genGOpFnVV = (fn: string): VecOpVV => + compileG(tplFnVV(fn), "a,b"); + +export const genGOpVN = (op: string): VecOpVN => + compileG(tplVN(op), "a,n", "a"); + +export const genGOpNewVV = (op: string): VecOpNewVV => + compileG(tplNewVV(op), "a,b,o=[]", "a,b,o", "o"); + +export const genGOpNewVN = (op: string): VecOpNewVN => + compileG(tplNewVN(op), "a,n,o=[]", "a,o", "o"); + +export const genCommonDefaults = (): CommonOps => [ + set.default(genGOpVV("")), + setN.default(genGOpVN("")), + setS.default(compileG(([a]) => `${a}=xs[i];`, "a,...xs", "a")), + + // TODO add IRandom support + rand01.default(compileG(tplRand01, "a")), + rand11.default(compileG(tplRand11, "a")), + rand.default(compileG(tplRand, "a,n,m", "a")), + + add.default(genGOpVV("+")), + sub.default(genGOpVV("-")), + mul.default(genGOpVV("*")), + div.default(genGOpVV("/")), + + addNew.default(genGOpNewVV("+")), + subNew.default(genGOpNewVV("-")), + mulNew.default(genGOpNewVV("*")), + divNew.default(genGOpNewVV("/")), + + addN.default(genGOpVN("+")), + subN.default(genGOpVN("-")), + mulN.default(genGOpVN("*")), + divN.default(genGOpVN("/")), + + addNewN.default(genGOpNewVN("+")), + subNewN.default(genGOpNewVN("-")), + mulNewN.default(genGOpNewVN("*")), + divNewN.default(genGOpNewVN("/")), + + madd.default(compileG(tplMadd, "a,b,c")), + maddN.default(compileG(tplMaddN, "a,b,n", "a,b")), + maddNew.default(compileG(tplMaddNew, "a,b,c,o=[]", "a,b,c,o", "o")), + maddNewN.default(compileG(tplMaddNewN, "a,b,n,o=[]", "a,b,o", "o")), + + abs.default(genGOpFnV("Math.abs")), + sign.default(genGOpHofV(_sign)), + sin.default(genGOpFnV("Math.sin")), + cos.default(genGOpFnV("Math.cos")), + tan.default(genGOpFnV("Math.tan")), + asin.default(genGOpFnV("Math.asin")), + acos.default(genGOpFnV("Math.acos")), + atan.default(genGOpFnV("Math.atan")), + floor.default(genGOpFnV("Math.floor")), + ceil.default(genGOpFnV("Math.ceil")), + trunc.default(genGOpFnV("Math.trunc")), + fract.default(genGOpHofV(_fract)), + sqrt.default(genGOpFnV("Math.sqrt")), + log.default(genGOpFnVV("Math.log")), + exp.default(genGOpFnVV("Math.exp")), + pow.default(genGOpFnVV("Math.pow")), + powN.default(compileG(tplPowN, "a,n", "a")), + + min.default(genGOpFnVV("Math.min")), + max.default(genGOpFnVV("Math.max")), + clamp.default(compileGHOF([_clamp], tplClamp, "fn", "a,b,c")), + + step.default(compileGHOF([_step], tplStep, "fn", "a,e")), + smoothStep.default(compileGHOF([_smoothStep], tplSmoothStep, "fn", "a,e1,e2")), + + mix.default(compileG(tplMix, "a,b,c")), + mixN.default(compileG(tplMixN, "a,b,n", "a,b")), + mixNew.default(compileG(tplMixNew, "a,b,c,o=[]", "a,b,c,o", "o")), + mixNewN.default(compileG(tplMixNewN, "a,b,n,o=[]", "a,b,o", "o")), +]; \ No newline at end of file diff --git a/packages/vectors2/src/nd.ts b/packages/vectors2/src/nd.ts index eff49022cb..dc86ff15d2 100644 --- a/packages/vectors2/src/nd.ts +++ b/packages/vectors2/src/nd.ts @@ -10,6 +10,7 @@ import { truncate } from "@thi.ng/strings/truncate"; import { INDArray, NDVec } from "./api"; import { declareIndices } from "./internal/accessors"; import { eqDelta as _eqDelta } from "./internal/equiv"; +import { iterator } from "./internal/iterator"; export class NDArray1 implements INDArray { @@ -32,10 +33,8 @@ export class NDArray1 implements this.length = shape[0]; } - *[Symbol.iterator]() { - for (let i = this.i, y = this.length, s = this.s, buf = this.buf; --y >= 0; i += s) { - yield buf[i]; - } + [Symbol.iterator](): IterableIterator { + return iterator(this.buf, this.length, this.i, this.s); } get dim() { @@ -551,4 +550,7 @@ const pad = padLeft(9); const trunc = truncate(9); const format = - (x: any) => isNumber(x) ? ff(x) : trunc(pad(x.toString())); \ No newline at end of file + (x: any) => + isNumber(x) ? + ff(x) : + trunc(pad(x.toString())); diff --git a/packages/vectors2/src/pool.ts b/packages/vectors2/src/pool.ts index 07ee85b17a..17f0c07f2f 100644 --- a/packages/vectors2/src/pool.ts +++ b/packages/vectors2/src/pool.ts @@ -1,6 +1,11 @@ import { TypedArray } from "@thi.ng/api"; import { isTypedArray } from "@thi.ng/checks/is-typedarray"; -import { MemPool, MemPoolOpts, Type } from "@thi.ng/malloc"; +import { + MemPool, + MemPoolOpts, + MemPoolStats, + Type +} from "@thi.ng/malloc"; import { IVecPool, IVector, Vec } from "./api"; import { Vec2 } from "./vec2"; import { Vec3 } from "./vec3"; @@ -20,7 +25,7 @@ export class VecPool implements pool; } - stats() { + stats(): MemPoolStats { return this.pool.stats(); } From 184d55da1f7d3c5b61aa3621d15d37e211855eba Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 31 Oct 2018 15:34:07 +0000 Subject: [PATCH 013/333] build(vectors): update deps --- packages/vectors2/package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/vectors2/package.json b/packages/vectors2/package.json index 3b908fe9bf..3b42e8d2a3 100644 --- a/packages/vectors2/package.json +++ b/packages/vectors2/package.json @@ -29,8 +29,12 @@ }, "dependencies": { "@thi.ng/api": "^4.2.3", + "@thi.ng/checks": "^1.5.13", + "@thi.ng/equiv": "^0.1.13", + "@thi.ng/errors": "^0.1.11", "@thi.ng/malloc": "^0.2.0", - "@thi.ng/math": "^0.2.0" + "@thi.ng/math": "^0.2.0", + "@thi.ng/strings": "^0.5.2" }, "keywords": [ "ES6", @@ -44,9 +48,5 @@ ], "browser": { "process": false - }, - "sideEffects": [ - "./src/vec2.js", - "./src/vec3.js" - ] + } } \ No newline at end of file From 0043fb5df8cfd8393b6ab052819e12ae42f6e691 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 1 Nov 2018 00:33:27 +0000 Subject: [PATCH 014/333] feat(math): add cossin(), add opt scale arg for sincos() --- packages/math/src/angle.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/math/src/angle.ts b/packages/math/src/angle.ts index a2f4200922..b363891017 100644 --- a/packages/math/src/angle.ts +++ b/packages/math/src/angle.ts @@ -6,8 +6,11 @@ import { TAU } from "./api"; -export const sincos = (theta: number) => - [Math.sin(theta), Math.cos(theta)]; +export const sincos = (theta: number, n = 1) => + [Math.sin(theta) * n, Math.cos(theta) * n]; + +export const cossin = (theta: number, n = 1) => + [Math.cos(theta) * n, Math.sin(theta) * n]; export const absTheta = (theta: number) => (theta %= TAU, theta < 0 ? TAU + theta : theta); From 30f61da544e7a5ca907a0ebbcbe81c88e44bc408 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 1 Nov 2018 00:33:49 +0000 Subject: [PATCH 015/333] feat(vectors): add eqDeltaArray() --- packages/vectors2/src/internal/equiv.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/vectors2/src/internal/equiv.ts b/packages/vectors2/src/internal/equiv.ts index 9004ea623a..e27016bccb 100644 --- a/packages/vectors2/src/internal/equiv.ts +++ b/packages/vectors2/src/internal/equiv.ts @@ -23,3 +23,15 @@ export const eqDelta = (a: ReadonlyVec, b: ReadonlyVec, n: number, eps = EPS, ia } return true; }; + +export const eqDeltaArray = (a: ReadonlyVec[], b: ReadonlyVec[], eps = EPS) => { + if (a.length !== b.length) { + return false; + } + for (let i = a.length; --i >= 0;) { + if (!eqDelta(a[i], b[i], a[i].length, eps)) { + return false; + } + } + return true; +}; From e197f908d5100023b059e7f867ee78e1cbeabdd0 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 1 Nov 2018 00:35:54 +0000 Subject: [PATCH 016/333] feat(hiccup-svg): add toHiccup() support in convertTree() --- packages/hiccup-svg/src/convert.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/hiccup-svg/src/convert.ts b/packages/hiccup-svg/src/convert.ts index 9b409f3ed9..4db87bceb0 100644 --- a/packages/hiccup-svg/src/convert.ts +++ b/packages/hiccup-svg/src/convert.ts @@ -1,6 +1,6 @@ +import { implementsFunction } from "@thi.ng/checks/implements-function"; import { isArray } from "@thi.ng/checks/is-array"; import { isArrayLike } from "@thi.ng/checks/is-arraylike"; - import { PathSegment } from "./api"; import { circle } from "./circle"; import { ff } from "./format"; @@ -40,7 +40,10 @@ const TEXT_ALIGN = { * * @param tree */ -export const convertTree = (tree: any[]): any[] => { +export const convertTree = (tree: any): any[] => { + if (implementsFunction(tree, "toHiccup")) { + return convertTree(tree.toHiccup()); + } const type = tree[0]; if (isArray(type)) { return tree.map(convertTree); @@ -85,7 +88,7 @@ export const convertTree = (tree: any[]): any[] => { return circle(tree[2], tree[3], attribs); case "rect": { const r = tree[5] || 0; - return roundedRect(tree[2], tree[3], tree[4], r, r, attribs); + return roundedRect(tree[2], tree[3][0], tree[3][1], r, r, attribs); } case "line": return line(tree[2], tree[3], attribs); From 358169fdf75e62457deb127aef0cfb612621b03d Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 1 Nov 2018 00:42:47 +0000 Subject: [PATCH 017/333] feat(geom): add/update shape types --- packages/geom2/package.json | 2 +- packages/geom2/src/api.ts | 440 ++++++++++++++++---------- packages/geom2/src/arc.ts | 180 +++++++++++ packages/geom2/src/bezier.ts | 4 +- packages/geom2/src/group.ts | 4 +- packages/geom2/src/index.ts | 1 + packages/geom2/src/internal/bounds.ts | 15 +- packages/geom2/src/polygon.ts | 4 +- packages/geom2/src/svg.ts | 8 +- packages/geom2/test/circle.ts | 53 ++++ packages/geom2/test/index.ts | 6 - 11 files changed, 530 insertions(+), 187 deletions(-) create mode 100644 packages/geom2/src/arc.ts create mode 100644 packages/geom2/test/circle.ts delete mode 100644 packages/geom2/test/index.ts diff --git a/packages/geom2/package.json b/packages/geom2/package.json index d95fe3fec2..86a3474005 100644 --- a/packages/geom2/package.json +++ b/packages/geom2/package.json @@ -33,7 +33,7 @@ "@thi.ng/defmulti": "^0.5.0", "@thi.ng/hiccup": "^2.4.3", "@thi.ng/hiccup-svg": "^2.0.4", - "@thi.ng/malloc": "^0.1.1", + "@thi.ng/malloc": "^0.2.0", "@thi.ng/math": "^0.2.0", "@thi.ng/vectors2": "^0.0.1" }, diff --git a/packages/geom2/src/api.ts b/packages/geom2/src/api.ts index 69817845b0..aac0cc2187 100644 --- a/packages/geom2/src/api.ts +++ b/packages/geom2/src/api.ts @@ -1,10 +1,25 @@ -import { ICopy, IObjectOf } from "@thi.ng/api"; +import { + ICopy, + IEquiv, + IObjectOf, + IToHiccup +} from "@thi.ng/api"; import { DEFAULT, defmulti, MultiFn1O } from "@thi.ng/defmulti"; -import { copy, subNew, Vec, mixNewN } from "@thi.ng/vectors2/api"; - -import "@thi.ng/vectors2/vec2"; +import { equiv } from "@thi.ng/equiv"; +import { cossin } from "@thi.ng/math/angle"; +import { + add, + copy, + mixNewN, + mul, + rotateZ, + subNew, + Vec +} from "@thi.ng/vectors2/api"; +import { set2 } from "@thi.ng/vectors2/vec2"; export enum Type { + ARC2 = "arc", CIRCLE2 = "circle", CUBIC2 = "cubic", ELLIPSE2 = "ellipse", @@ -30,13 +45,16 @@ export const enum LineIntersectionType { export const DEFAULT_SAMPLES = 20; -export interface Shape extends - ICopy { +export interface IShape extends + ICopy, + IEquiv, + IToHiccup { + readonly type: string; attribs?: IObjectOf; } -export interface AABBLike extends Shape { +export interface AABBLike extends IShape { pos: Vec; size: Vec; } @@ -103,43 +121,43 @@ export type Attribs = IObjectOf; export type Tessellator = (points: Vec[]) => Vec[][]; -const dispatch = (x: Shape) => x.type; +const dispatch = (x: IShape) => x.type; -export const area: MultiFn1O = defmulti(dispatch); +export const area: MultiFn1O = defmulti(dispatch); -export const arcLength = defmulti(dispatch); +export const arcLength = defmulti(dispatch); -export const asCubic = defmulti(dispatch); +export const asCubic = defmulti(dispatch); -export const asPolygon: MultiFn1O = defmulti(dispatch); +export const asPolygon: MultiFn1O = defmulti(dispatch); -export const asPolyline: MultiFn1O = defmulti(dispatch); +export const asPolyline: MultiFn1O = defmulti(dispatch); -export const bounds = defmulti(dispatch); +export const bounds = defmulti(dispatch); -export const center = defmulti(dispatch); +export const center = defmulti(dispatch); -export const centroid: MultiFn1O = defmulti(dispatch); +export const centroid: MultiFn1O = defmulti(dispatch); -export const classifyPoint = defmulti(dispatch); +export const classifyPoint = defmulti(dispatch); -export const convexHull = defmulti(dispatch); +export const convexHull = defmulti(dispatch); -export const depth = defmulti(dispatch); +export const depth = defmulti(dispatch); depth.add(DEFAULT, (x) => bounds(x).size[2] || 0); -export const difference = defmulti(dispatch); +export const difference = defmulti(dispatch); -export const extrude = defmulti(dispatch); +export const extrude = defmulti(dispatch); -export const height = defmulti(dispatch); +export const height = defmulti(dispatch); height.add(DEFAULT, (x) => bounds(x).size[1]); -export const intersect = defmulti(dispatch); +export const intersect = defmulti(dispatch); -export const pointAt = defmulti(dispatch); +export const pointAt = defmulti(dispatch); -export const resample = defmulti(dispatch); +export const resample = defmulti(dispatch); /** * Returns new shape of same type with a shallow copy of the original @@ -148,105 +166,166 @@ export const resample = defmulti(dispatch); * @param shape * @param eps simplification threshold (default: 0.1) */ -export const simplify: MultiFn1O = defmulti(dispatch); +export const simplify: MultiFn1O = defmulti(dispatch); -export const splitAt = defmulti(dispatch); +export const splitAt = defmulti(dispatch); -export const tessellate = defmulti, Vec[][]>(dispatch); +export const tessellate = defmulti, Vec[][]>(dispatch); -export const union = defmulti(dispatch); +export const union = defmulti(dispatch); -export const vertices: MultiFn1O, Vec[]> = defmulti(dispatch); +export const vertices: MultiFn1O, Vec[]> = defmulti(dispatch); -export const width = defmulti(dispatch); +export const width = defmulti(dispatch); width.add(DEFAULT, (x) => bounds(x).size[0]); -export abstract class AShape extends Array implements - Shape { +export class PointContainer implements + IShape { + + readonly type: string; + points: Vec[]; + attribs: Attribs; - constructor(type: string, attribs: Attribs, ...xs: any[]) { - super(type, attribs, ...xs); + constructor(type: string, points: Vec[], attribs?: Attribs) { + this.type = type; + this.points = points; + this.attribs = attribs; } - get type() { - return this[0]; + copy() { + return new PointContainer(this.type, this._copy(), this.attribs); } - get attribs() { - return this[1]; + equiv(o: any) { + return o instanceof PointContainer && + equiv(this.points, o.points); } - set attribs(attr: Attribs) { - this[1] = attr; + toHiccup() { + return [this.type, this.attribs, this.points]; } - abstract copy(): Shape; + protected _copy() { + return this.points.map((p) => copy(p)); + } } -/** - * [type, {}, points] - */ -export class PointContainer extends AShape { - - constructor(type: Type, points: Vec[], attribs?: Attribs) { - super(type, attribs, points); - } +export class Arc2 implements + IShape { - get points(): Vec[] { - return this[2]; + pos: Vec; + r: Vec; + axis: number; + start: number; + end: number; + xl: boolean; + clockwise: boolean; + attribs: Attribs; + + constructor( + pos: Vec, + r: Vec, + axis: number, + start: number, + end: number, + xl = false, + clockwise = false, + attribs?: Attribs) { + + this.pos = pos; + this.r = r; + this.axis = axis; + this.start = start; + this.end = end; + this.xl = xl; + this.clockwise = clockwise; + this.attribs = attribs; } - set points(pts: Vec[]) { - this[2] = pts; + get type() { + return Type.ARC2; } copy() { - return new PointContainer( - this.type, - this.points.map((p) => copy(p)), + return new Arc2( + copy(this.pos), + copy(this.r), + this.axis, + this.start, + this.end, + this.xl, + this.clockwise, { ...this.attribs } ); } -} -/** - * ["circle", {}, pos, r] - */ -export class Circle2 extends AShape implements - ICopy { + equiv(o: any) { + return o instanceof Arc2 && + equiv(this.pos, o.pos) && + equiv(this.r, o.r) && + this.start === o.start && + this.end === o.end && + this.axis === o.axis && + this.xl === o.xl && + this.clockwise && o.clockwise; + } - constructor(pos: Vec, r: number, attribs?: Attribs) { - super(Type.CIRCLE2, attribs, pos, r); + pointAtTheta(theta: number, pos?: Vec) { + return add(rotateZ(mul(set2(pos || [], cossin(theta)), this.r), this.axis), this.pos); } - copy() { - return new Circle2(copy(this.pos), this.r, { ...this.attribs }); + toHiccup() { + return ["path", this.attribs, [ + ["M", pointAt(this, 0)], + ...this.toHiccupPathSegments() + ]]; } - get pos(): Vec { - return this[2]; + toHiccupPathSegments() { + return [["A", + this.r[0], + this.r[1], + this.axis, + this.xl, + this.clockwise, + pointAt(this, 1) + ]]; } +} - set pos(v: Vec) { - this[2] = v; +export class Circle2 implements + IShape { + + pos: Vec; + r: number; + attribs: Attribs; + + constructor(pos: Vec, r: number, attribs?: Attribs) { + this.pos = pos; + this.r = r; + this.attribs = attribs; + } + + get type() { + return Type.CIRCLE2; + } + + copy() { + return new Circle2(copy(this.pos), this.r, { ...this.attribs }); } - get r(): number { - return this[3]; + equiv(o: any) { + return o instanceof Circle2 && + equiv(this.pos, o.pos) && + this.r === o.r; } - set r(r: number) { - this[3] = r; + toHiccup() { + return [this.type, this.attribs, this.pos, this.r]; } } -/** - * ``` - * ["cubic", {}, points] - * ``` - */ -export class Cubic2 extends PointContainer implements - ICopy { +export class Cubic2 extends PointContainer { static fromLine(a: Vec, b: Vec, attribs?: Attribs) { return new Cubic2([a, mixNewN(a, b, 1 / 3), mixNewN(b, a, 1 / 3), b], attribs); @@ -257,71 +336,104 @@ export class Cubic2 extends PointContainer implements } copy() { - return new Cubic2(this.points.map(copy), { ...this.attribs }); + return new Cubic2(this._copy(), { ...this.attribs }); + } + + toHiccup() { + return ["path", this.attribs, + [ + ["M", this.points[0]], + ...this.toHiccupPathSegments() + ] + ]; + } + + toHiccupPathSegments() { + const pts = this.points; + return [["C", pts[1], pts[2], pts[3]]]; } } -/** - * ["ellipse", {}, pos, r] - */ -export class Ellipse2 extends AShape implements - ICopy { +export class Ellipse2 implements + IShape { + + pos: Vec; + r: Vec; + attribs: Attribs; constructor(pos: Vec, r: Vec, attribs?: Attribs) { - super(Type.ELLIPSE2, attribs, pos, r); + this.pos = pos; + this.r = r; + this.attribs = attribs; + } + + get type() { + return Type.ELLIPSE2; } copy() { - return new Ellipse2(copy(this.pos), this.r, { ...this.attribs }); + return new Ellipse2(copy(this.pos), copy(this.r), { ...this.attribs }); } - get pos(): Vec { - return this[2]; + equiv(o: any) { + return o instanceof Ellipse2 && + equiv(this.pos, o.pos) && + equiv(this.r, o.r); } - set pos(v: Vec) { - this[2] = v; + toHiccup() { + return [this.type, this.attribs, this.pos, this.r]; } +} + +export class Group2 implements + IShape { + + children: IShape[]; + attribs: Attribs; - get r(): Vec { - return this[3]; + constructor(attribs?: Attribs, ...children: IShape[]) { + this.attribs = attribs; + this.children = children; } - set r(r: Vec) { - this[3] = r; + get type() { + return Type.GROUP; } -} -/** - * ["circle", {}, pos, r] - */ -export class Group2 extends AShape implements - ICopy { + copy() { + return new Group2( + { ...this.attribs }, + ...this.children.map((c) => c.copy()) + ); + } - constructor(attribs?: Attribs, ...children: Shape[]) { - super(Type.GROUP, attribs, children); + equiv(o: any) { + return o instanceof Group2 && + equiv(this.children, o.children); } - copy() { - return new Group2({ ...this.attribs }, ...this.children.map((c) => c.copy())); + toHiccup() { + return [ + this.type, + this.attribs, + ...this.children.map((x) => x.toHiccup()) + ]; } +} + +export class Line2 extends PointContainer { - get children(): Shape[] { - return this[2]; + constructor(points: Vec[], attribs?: Attribs) { + super(Type.LINE2, points, attribs); } - set children(children: Shape[]) { - this[2] = children; + copy() { + return new Line2(this._copy(), { ...this.attribs }); } } -/** - * ``` - * ["quadratic", {}, points] - * ``` - */ -export class Quadratic2 extends PointContainer implements - ICopy { +export class Quadratic2 extends PointContainer { static fromLine(a: Vec, b: Vec, attribs?: Attribs) { return new Quadratic2([a, mixNewN(a, b, 0.5), b], attribs); @@ -332,58 +444,54 @@ export class Quadratic2 extends PointContainer implements } copy() { - return new Quadratic2(this.points.map(copy), { ...this.attribs }); + return new Quadratic2(this._copy(), { ...this.attribs }); + } + + toHiccup() { + return ["path", this.attribs, + [ + ["M", this.points[0]], + ...this.toHiccupPathSegments() + ] + ]; + } + + toHiccupPathSegments() { + const pts = this.points; + return [["Q", pts[1], pts[2]]]; } } -/** - * ``` - * ["polygon", {}, points] - * ``` - */ -export class Polygon2 extends PointContainer implements - ICopy { +export class Polygon2 extends PointContainer { constructor(points: Vec[], attribs?: Attribs) { super(Type.POLYGON2, points, attribs); } copy() { - return new Polygon2(this.points, { ...this.attribs }); + return new Polygon2(this._copy(), { ...this.attribs }); } } -/** - * ``` - * ["polygon", {}, points] - * ``` - */ -export class Polyline2 extends PointContainer implements - ICopy { +export class Polyline2 extends PointContainer { constructor(points: Vec[], attribs?: Attribs) { super(Type.POLYLINE2, points, attribs); } copy() { - return new Polyline2(this.points.map(copy), { ...this.attribs }); + return new Polyline2(this._copy(), { ...this.attribs }); } } -/** - * ``` - * ["quad", {}, points] - * ``` - */ -export class Quad2 extends PointContainer implements - ICopy { +export class Quad2 extends PointContainer { constructor(points: Vec[], attribs?: Attribs) { super(Type.POLYGON2, points, attribs); } copy() { - return new Quad2(this.points.map(copy), { ...this.attribs }); + return new Quad2(this._copy(), { ...this.attribs }); } get type() { @@ -391,53 +499,51 @@ export class Quad2 extends PointContainer implements } } -/** - * ``` - * ["rect", {}, pos, size] - * ``` - */ -export class Rect2 extends AShape implements +export class Rect2 implements AABBLike, - ICopy { + IShape { static fromMinMax(min: Vec, max: Vec, attribs?: Attribs) { return new Rect2(min, subNew(max, min), attribs); } - constructor(pos: Vec, size: Vec, attribs?: Attribs) { - super(Type.RECT2, attribs, pos, size); - } + pos: Vec; + size: Vec; + attribs: Attribs; - copy() { - return new Rect2(copy(this.pos), copy(this.size), { ...this.attribs }); + constructor(pos: Vec, size: Vec, attribs?: Attribs) { + this.pos = pos; + this.size = size; + this.attribs = attribs; } - get pos(): Vec { - return this[2]; + get type() { + return Type.RECT2; } - set pos(v: Vec) { - this[2] = v; + copy() { + return new Rect2(copy(this.pos), copy(this.size), { ...this.attribs }); } - get size(): Vec { - return this[3]; + equiv(o: any) { + return o instanceof Rect2 && + equiv(this.pos, o.pos) && + equiv(this.size, o.size); } - set size(v: Vec) { - this[3] = v; + toHiccup() { + return [this.type, this.attribs, this.pos, this.size]; } } -export class Triangle2 extends PointContainer implements - ICopy { +export class Triangle2 extends PointContainer { constructor(points: Vec[], attribs?: Attribs) { super(Type.POLYGON2, points, attribs); } copy() { - return new Triangle2(this.points.map(copy), { ...this.attribs }); + return new Triangle2(this._copy(), { ...this.attribs }); } get type() { diff --git a/packages/geom2/src/arc.ts b/packages/geom2/src/arc.ts new file mode 100644 index 0000000000..af446837e5 --- /dev/null +++ b/packages/geom2/src/arc.ts @@ -0,0 +1,180 @@ +import { isNumber } from "@thi.ng/checks/is-number"; +import { isPlainObject } from "@thi.ng/checks/is-plain-object"; +import { implementations } from "@thi.ng/defmulti"; +import { sincos } from "@thi.ng/math/angle"; +import { EPS, HALF_PI, PI, TAU } from "@thi.ng/math/api"; +import { fit01 } from "@thi.ng/math/fit"; +import { inRange } from "@thi.ng/math/interval"; +import { roundEps } from "@thi.ng/math/prec"; +import { range } from "@thi.ng/transducers/iter/range"; +import { push } from "@thi.ng/transducers/rfn/push"; +import { transduce } from "@thi.ng/transducers/transduce"; +import { filter } from "@thi.ng/transducers/xform/filter"; +import { map } from "@thi.ng/transducers/xform/map"; +import { add, magSq, Vec, ReadonlyVec, abs, mulN, subNew, angleBetween } from "@thi.ng/vectors2/api"; +import { Vec2 } from "@thi.ng/vectors2/vec2"; +import { + Arc2, + asCubic, + bounds, + centroid, + Cubic2, + DEFAULT_SAMPLES, + pointAt, + Rect2, + SamplingOpts, + Type, + vertices, + Attribs +} from "./api"; +import { bounds as _bounds } from "./internal/bounds"; +import { Sampler } from "./internal/sampler"; + +export function arc(pos: Vec, r: Vec, axis: number, start: number, end: number, xl: boolean, clockwise: boolean, attribs?: Attribs): Arc2 { + return new Arc2(pos, r, axis, start, end, xl, clockwise, attribs); +} + +export function arcFrom2Points( + a: ReadonlyVec, + b: ReadonlyVec, + radii: ReadonlyVec, + axisTheta = 0, + large = false, + clockwise = true) { + + const r = abs([...radii]); + const co = Math.cos(axisTheta); + const si = Math.sin(axisTheta); + const m = mulN(subNew(a, b), 0.5); + const px = co * m[0] + si * m[1]; + const py = -si * m[0] + co * m[1]; + const px2 = px * px; + const py2 = py * py; + + const l = px2 / (r[0] * r[0]) + py2 / (r[1] * r[1]); + l > 1 && mulN(r, Math.sqrt(l)); + + const rx2 = r[0] * r[0]; + const ry2 = r[1] * r[1]; + const rxpy = rx2 * py2; + const rypx = ry2 * px2; + const rad = ((large === clockwise) ? -1 : 1) * + Math.sqrt(Math.max(0, rx2 * ry2 - rxpy - rypx) / (rxpy + rypx)); + + const tc = [rad * r[0] / r[1] * py, rad * -r[1] / r[0] * px]; + const c = [co * tc[0] - si * tc[1] + (a[0] + b[0]) / 2, si * tc[0] + co * tc[1] + (a[1] + b[1]) / 2]; + const d1 = [(px - tc[0]) / r[0], (py - tc[1]) / r[1]]; + const d2 = [(-px - tc[0]) / r[0], (-py - tc[1]) / r[1]]; + + const theta = angleBetween(Vec2.X_AXIS, d1, true); + let delta = angleBetween(d1, d2, true); + + if (clockwise && delta < 0) { + delta += TAU; + } else if (!clockwise && delta > 0) { + delta -= TAU; + } + + return new Arc2(c, r, axisTheta, theta, theta + delta, large, clockwise); +}; + +implementations( + Type.ARC2, + + asCubic, + (x: Arc2) => { + const p = x.pointAtTheta(x.start); + const q = x.pointAtTheta(x.end); + const [rx, ry] = x.r; + const [sphi, cphi] = sincos(x.axis); + const dx = cphi * (p[0] - q[0]) / 2 + sphi * (p[1] - q[1]) / 2; + const dy = -sphi * (p[0] - q[0]) / 2 + cphi * (p[1] - q[1]) / 2; + if ((dx === 0 && dy === 0) || magSq(x.r) < EPS) { + return [Cubic2.fromLine(p, q, { ...x.attribs })]; + } + + const mapP = (x, y) => { + x *= rx; + y *= ry; + return add( + [ + cphi * x - sphi * y, + sphi * x + cphi * y + ], + x.pos + ); + }; + + const res: Cubic2[] = []; + const delta = x.end - x.start; + const n = Math.max(roundEps(Math.abs(delta) / HALF_PI), 1); + // https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/svg/svg_path_parser.cc#L253 + const d = delta / n; + const t = 8 / 6 * Math.tan(0.25 * d); + if (!isFinite(t)) { + return [Cubic2.fromLine(p, q)]; + } + for (let i = n, theta = x.start; i > 0; i-- , theta += d) { + const [s1, c1] = sincos(theta); + const [s2, c2] = sincos(theta + d); + const curve = new Cubic2( + [ + mapP(c1, s1), + mapP(c1 - s1 * t, s1 + c1 * t), + mapP(c2 + s2 * t, s2 - c2 * t), + mapP(c2, s2), + ], + { ...x.attribs } + ); + res.push(curve); + } + return res; + }, + + bounds, + (x: Arc2) => { + const pts = transduce( + map(x.pointAtTheta.bind(x)), + push(), + [ + x.start, + x.end, + // multiples of HALF_PI in arc range + ...filter( + (t: number) => inRange(t, x.start, x.end), + range(-3 * PI, 3.01 * PI, HALF_PI) + ) + ] + ); + return Rect2.fromMinMax(..._bounds(pts, [...Vec2.MAX], [...Vec2.MIN])); + }, + + centroid, + (x: Arc2) => x.pos, + + pointAt, + (x: Arc2, t: number) => x.pointAtTheta(fit01(t, x.start, x.end)), + + vertices, + (x: Arc2, opts?: number | Partial): Vec[] => { + if (isPlainObject(opts) && (opts).dist !== undefined) { + return new Sampler(vertices(x, (opts).num || DEFAULT_SAMPLES)) + .sampleUniform((opts).dist, (opts).last !== false); + } + opts = isNumber(opts) ? + { num: opts, last: true } : + { num: DEFAULT_SAMPLES, ...opts }; + const start = x.start; + let delta = x.end - start; + let num = opts.theta ? + Math.round(delta / opts.theta) : + opts.num; + delta /= num; + opts.last !== false && num++; + const pts: Vec[] = new Array(num); + for (let i = 0, j = 0; i < num; i++ , j += 2) { + pts[i] = x.pointAtTheta(start + i * delta); + } + return pts; + } +); diff --git a/packages/geom2/src/bezier.ts b/packages/geom2/src/bezier.ts index 0c85046165..8917b001d8 100644 --- a/packages/geom2/src/bezier.ts +++ b/packages/geom2/src/bezier.ts @@ -15,8 +15,8 @@ import { ReadonlyVec, Vec } from "@thi.ng/vectors2/api"; -import { compile } from "@thi.ng/vectors2/codegen"; -import { vop } from "@thi.ng/vectors2/vop"; +import { compile } from "@thi.ng/vectors2/internal/codegen"; +import { vop } from "@thi.ng/vectors2/internal/ops"; import { asCubic, Attribs, diff --git a/packages/geom2/src/group.ts b/packages/geom2/src/group.ts index 458290bc6b..8307d85561 100644 --- a/packages/geom2/src/group.ts +++ b/packages/geom2/src/group.ts @@ -4,12 +4,12 @@ import { Attribs, bounds, Group2, - Shape, + IShape, Type } from "./api"; import { collBounds } from "./internal/bounds"; -export function group(attribs?: Attribs, ...children: Shape[]) { +export function group(attribs?: Attribs, ...children: IShape[]) { return new Group2(attribs, ...children); } diff --git a/packages/geom2/src/index.ts b/packages/geom2/src/index.ts index 0607772999..cf7fcdb2c1 100644 --- a/packages/geom2/src/index.ts +++ b/packages/geom2/src/index.ts @@ -1,4 +1,5 @@ export * from "./api"; +export * from "./arc"; export * from "./bezier"; export * from "./circle"; export * from "./container2"; diff --git a/packages/geom2/src/internal/bounds.ts b/packages/geom2/src/internal/bounds.ts index b0a6ee067f..bb341ca08c 100644 --- a/packages/geom2/src/internal/bounds.ts +++ b/packages/geom2/src/internal/bounds.ts @@ -1,5 +1,12 @@ -import { max, min, Vec, addNew, sub, ReadonlyVec } from "@thi.ng/vectors2/api"; -import { bounds as _bounds, Shape, union } from "../api"; +import { + addNew, + max, + min, + ReadonlyVec, + sub, + Vec +} from "@thi.ng/vectors2/api"; +import { bounds as _bounds, IShape, union } from "../api"; export const bounds = (pts: ReadonlyArray, vmin: Vec, vmax: Vec): [Vec, Vec] => { @@ -13,10 +20,10 @@ export const bounds = }; export const collBounds = - (shapes: Shape[]) => { + (shapes: IShape[]) => { let n = shapes.length - 1; - let res: Shape = n >= 0 ? _bounds(shapes[n]) : undefined; + let res: IShape = n >= 0 ? _bounds(shapes[n]) : undefined; for (; --n >= 0;) { res = union(res, _bounds(shapes[n])); } diff --git a/packages/geom2/src/polygon.ts b/packages/geom2/src/polygon.ts index afdc03b59b..a61c172215 100644 --- a/packages/geom2/src/polygon.ts +++ b/packages/geom2/src/polygon.ts @@ -11,7 +11,7 @@ import { Polygon2, resample, SamplingOpts, - Shape, + IShape, simplify, tessellate, Tessellator, @@ -83,5 +83,5 @@ implementations( }, ); -export const clipConvex = (poly: Polygon2, boundary: Shape) => +export const clipConvex = (poly: Polygon2, boundary: IShape) => sutherlandHodgeman(poly.points, vertices(boundary), centroid(boundary)); diff --git a/packages/geom2/src/svg.ts b/packages/geom2/src/svg.ts index 2488867e5f..6a70c8eed5 100644 --- a/packages/geom2/src/svg.ts +++ b/packages/geom2/src/svg.ts @@ -2,12 +2,14 @@ import { serialize } from "@thi.ng/hiccup"; import { convertTree } from "@thi.ng/hiccup-svg/convert"; import { svg } from "@thi.ng/hiccup-svg/svg"; import { collBounds } from "./internal/bounds"; -import { Shape, Rect2 } from "./api"; +import { IShape, Rect2 } from "./api"; export const asSVG = (...args: any[]) => - serialize(convertTree(args)); + args + .map((x) => serialize(convertTree(x))) + .join(""); -export const svgDoc = (attribs, ...args: Shape[]) => { +export const svgDoc = (attribs, ...args: IShape[]) => { const b = collBounds(args); attribs = { width: b.size[0], diff --git a/packages/geom2/test/circle.ts b/packages/geom2/test/circle.ts new file mode 100644 index 0000000000..01a30cdd2c --- /dev/null +++ b/packages/geom2/test/circle.ts @@ -0,0 +1,53 @@ +import { equiv } from "@thi.ng/equiv"; +import { PI, TAU, HALF_PI } from "@thi.ng/math/api"; +import { eqDeltaArray } from "@thi.ng/vectors2/internal/equiv"; +import * as assert from "assert"; +import { + arcLength, + area, + asSVG, + circle, + Circle2, + Rect2, + bounds, + vertices, + asPolygon, + Polygon2 +} from "../src/index"; +import { Vec } from "@thi.ng/vectors2/api"; + +describe("circle", () => { + + let a: Circle2; + let apts: Vec[]; + + beforeEach(() => { + a = circle([100, 200], 10, { fill: "red" }); + apts = [[110, 200], [100, 210], [90, 200], [100, 190]]; + }); + + it("area", () => + assert.equal(area(a), a.r * a.r * PI)); + + it("arcLength", () => + assert.equal(arcLength(a), a.r * TAU)); + + it("asPolygon", () => + assert(equiv(asPolygon(a, 4), new Polygon2(apts)))); + + it("bounds", () => + assert(equiv(bounds(a), new Rect2([90, 190], [20, 20])))); + + it("vertices", () => + assert(eqDeltaArray(vertices(a, 4), apts))); + + it("vertices (theta)", () => + assert(eqDeltaArray(vertices(a, { theta: HALF_PI }), apts))); + + it("svg", () => { + assert.equal( + asSVG(a), + `` + ); + }); +}); diff --git a/packages/geom2/test/index.ts b/packages/geom2/test/index.ts deleted file mode 100644 index dd5942b987..0000000000 --- a/packages/geom2/test/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -// import * as assert from "assert"; -// import * as g from "../src/index"; - -describe("geom2", () => { - it("tests pending"); -}); From c41d12c010a866469d4877edd92cbdb1999c6b76 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 3 Nov 2018 15:21:41 +0000 Subject: [PATCH 018/333] feat(vectors): re-add quaternion, various refactorings --- packages/vectors2/package.json | 2 +- packages/vectors2/src/api.ts | 15 +- packages/vectors2/src/index.ts | 2 + packages/vectors2/src/internal/accessors.ts | 4 +- packages/vectors2/src/mat23.ts | 232 +++---- packages/vectors2/src/mat33.ts | 334 +++++----- packages/vectors2/src/mat44.ts | 661 ++++++++++---------- packages/vectors2/src/nd.ts | 28 +- packages/vectors2/src/quat.ts | 99 +++ packages/vectors2/src/vec2.ts | 15 +- packages/vectors2/src/vec3.ts | 16 +- packages/vectors2/src/vec4.ts | 24 +- 12 files changed, 822 insertions(+), 610 deletions(-) create mode 100644 packages/vectors2/src/quat.ts diff --git a/packages/vectors2/package.json b/packages/vectors2/package.json index 3b42e8d2a3..2110cdebaa 100644 --- a/packages/vectors2/package.json +++ b/packages/vectors2/package.json @@ -13,7 +13,7 @@ "license": "Apache-2.0", "scripts": { "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc internal", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn run build && yarn publish --access public", diff --git a/packages/vectors2/src/api.ts b/packages/vectors2/src/api.ts index 1f921ac737..6e2e5c6148 100644 --- a/packages/vectors2/src/api.ts +++ b/packages/vectors2/src/api.ts @@ -14,12 +14,13 @@ import { EPS } from "@thi.ng/math/api"; import { genCommonDefaults } from "./internal/codegen"; import { eqDelta as _eqDelta } from "./internal/equiv"; import { vop } from "./internal/ops"; -import { VecPool } from "./pool"; // suffix convention: // V = vector arg // N = numeric / scalar arg -// Ro = readonly +// O = optional arg +// New = immutable op (w/ output vector) +// Ro = readonly op export type VecOpV = (a: Vec, ...xs: any[]) => T; export type VecOpVO = (a: Vec, o?: O, ...xs: any[]) => T; @@ -204,14 +205,6 @@ export type Vec2Coord = 0 | 1; export type Vec3Coord = 0 | 1 | 2; export type Vec4Coord = 0 | 1 | 2 | 3; -let POOL: IVecPool; - -export const getPool = () => POOL; -export const usePool = (pool: VecPool) => (POOL = pool); - -export const vec = (n: number) => - POOL ? POOL.malloc(n) : zeroes(n); - export const set: MultiVecOpVV = vop(); export const setN: MultiVecOpVN = vop(); export const setS: MultiVecOpV = vop(); @@ -227,7 +220,7 @@ export const empty: MultiVecOpRoV = vop(); empty.default((v) => implementsFunction(v, "empty") ? (v).empty() : - vec(v.length) + zeroes(v.length) ); export const zero = (a: Vec) => setN(a, 0); diff --git a/packages/vectors2/src/index.ts b/packages/vectors2/src/index.ts index 7f299eabc6..2423847675 100644 --- a/packages/vectors2/src/index.ts +++ b/packages/vectors2/src/index.ts @@ -1,5 +1,6 @@ export * from "./api"; export * from "./pool"; + export * from "./vec2"; export * from "./vec3"; export * from "./vec4"; @@ -8,3 +9,4 @@ export * from "./nd"; export * from "./mat23"; export * from "./mat33"; export * from "./mat44"; +export * from "./quat"; diff --git a/packages/vectors2/src/internal/accessors.ts b/packages/vectors2/src/internal/accessors.ts index c86a5bb69c..51b2ccb0c3 100644 --- a/packages/vectors2/src/internal/accessors.ts +++ b/packages/vectors2/src/internal/accessors.ts @@ -1,8 +1,8 @@ -export const declareIndices = (proto: any, props: string[]) => { +export const declareIndices = (proto: any, props: string[], numeric = true) => { const get = (i: number) => function () { return this.buf[this.i + i * this.s]; }; const set = (i: number) => function (n: number) { this.buf[this.i + i * this.s] = n; }; props.forEach((id, i) => { - Object.defineProperty(proto, i, { + numeric && Object.defineProperty(proto, i, { get: get(i), set: set(i), enumerable: true, diff --git a/packages/vectors2/src/mat23.ts b/packages/vectors2/src/mat23.ts index 46e5c67df5..98bec7e46f 100644 --- a/packages/vectors2/src/mat23.ts +++ b/packages/vectors2/src/mat23.ts @@ -11,18 +11,20 @@ import { iterator } from "./internal/iterator"; import { cross2, dot2 } from "./internal/matrix"; import { NDArray2 } from "./nd"; -export const get23 = (a: Mat, i = 0) => - (a).slice(i, i + 6); - -export const set23 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => ( - a[ia] = b[ib], - a[ia + 1] = b[ib + 1], - a[ia + 2] = b[ib + 2], - a[ia + 3] = b[ib + 3], - a[ia + 4] = b[ib + 4], - a[ia + 5] = b[ib + 5], - a -); +export const get23 = + (a: Mat, i = 0) => + (a).slice(i, i + 6); + +export const set23 = + (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => ( + a[ia] = b[ib], + a[ia + 1] = b[ib + 1], + a[ia + 2] = b[ib + 2], + a[ia + 3] = b[ib + 3], + a[ia + 4] = b[ib + 4], + a[ia + 5] = b[ib + 5], + a + ); /** * ``` @@ -54,109 +56,127 @@ export const setS23 = ( m ); -export const identity23 = (m?: Mat, i = 0) => - setS23(m || [], 1, 0, 0, 1, 0, 0, i); - -export const rotation23 = (m: Mat, theta: number, i = 0) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS23(m || [], c, s, -s, c, 0, 0, i); -}; - -export const rotationAroundPoint23 = (m: Mat, p: ReadonlyVec, theta: number, im = 0) => - concat23( - translationV23(m || [], p, im), im, - rotation23([], theta), - translationS23([], -p[0], -p[1]) - ); - -export const scaleV23 = (m: Mat, v: Vec, i = 0) => - scaleS23(m, v[0], v[1], i); - -export const scaleN23 = (m: Mat, n: number, i = 0) => - scaleS23(m, n, n, i); - -export const scaleS23 = (m: Mat, sx: number, sy: number, i = 0) => - setS23(m || [], sx, 0, 0, sy, 0, 0, i); - -export const scaleWithCenter23 = (m: Mat, p: ReadonlyVec, sx: number, sy: number, im = 0) => - concat23( - translationV23(m || [], p, im), im, - scaleS23([], sx, sy), - translationS23([], -p[0], -p[1]) - ); - -export const translationV23 = (m: Mat, v: ReadonlyVec, i = 0) => - translationS23(m, v[0], v[1], i); - -export const translationS23 = (m: Mat, x: number, y: number, i = 0) => - setS23(m || [], 1, 0, 0, 1, x, y, i); +export const identity23 = + (m?: Mat, i = 0) => + setS23(m || [], 1, 0, 0, 1, 0, 0, i); + +export const rotation23 = + (m: Mat, theta: number, i = 0) => { + const s = Math.sin(theta); + const c = Math.cos(theta); + return setS23(m || [], c, s, -s, c, 0, 0, i); + }; + +export const rotationAroundPoint23 = + (m: Mat, p: ReadonlyVec, theta: number, im = 0) => + concat23( + translationV23(m || [], p, im), im, + rotation23([], theta), + translationS23([], -p[0], -p[1]) + ); -export const shearX23 = (m: Mat, x: number, i = 0) => - setS23(m || [], 1, 0, x, 1, 0, 0, i); +export const scaleV23 = + (m: Mat, v: Vec, i = 0) => + scaleS23(m, v[0], v[1], i); -export const shearY23 = (m: Mat, y: number, i = 0) => - setS23(m || [], 1, y, 0, 1, 0, 0, i); +export const scaleN23 = + (m: Mat, n: number, i = 0) => + scaleS23(m, n, n, i); -export const skewX23 = (m: Mat, theta: number, i = 0) => - shearX23(m, Math.tan(theta), i); +export const scaleS23 = + (m: Mat, sx: number, sy: number, i = 0) => + setS23(m || [], sx, 0, 0, sy, 0, 0, i); -export const skewY23 = (m: Mat, theta: number, i = 0) => - shearY23(m, Math.tan(theta), i); +export const scaleWithCenter23 = + (m: Mat, p: ReadonlyVec, sx: number, sy: number, im = 0) => + concat23( + translationV23(m || [], p, im), im, + scaleS23([], sx, sy), + translationS23([], -p[0], -p[1]) + ); -export const mul23 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => - setS23( - a, - dot2(a, b, ia, ib, 2), - dot2(a, b, ia + 1, ib, 2), - dot2(a, b, ia, ib + 2, 2), - dot2(a, b, ia + 1, ib + 2, 2), - dot2(a, b, ia, ib + 4, 2) + a[ia + 4], - dot2(a, b, ia + 1, ib + 4, 2) + a[ia + 5], - ia - ); +export const translationV23 = + (m: Mat, v: ReadonlyVec, i = 0) => + translationS23(m, v[0], v[1], i); + +export const translationS23 = + (m: Mat, x: number, y: number, i = 0) => + setS23(m || [], 1, 0, 0, 1, x, y, i); + +export const shearX23 = + (m: Mat, x: number, i = 0) => + setS23(m || [], 1, 0, x, 1, 0, 0, i); + +export const shearY23 = + (m: Mat, y: number, i = 0) => + setS23(m || [], 1, y, 0, 1, 0, 0, i); + +export const skewX23 = + (m: Mat, theta: number, i = 0) => + shearX23(m, Math.tan(theta), i); + +export const skewY23 = + (m: Mat, theta: number, i = 0) => + shearY23(m, Math.tan(theta), i); + +export const mul23 = + (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => + setS23( + a, + dot2(a, b, ia, ib, 2), + dot2(a, b, ia + 1, ib, 2), + dot2(a, b, ia, ib + 2, 2), + dot2(a, b, ia + 1, ib + 2, 2), + dot2(a, b, ia, ib + 4, 2) + a[ia + 4], + dot2(a, b, ia + 1, ib + 4, 2) + a[ia + 5], + ia + ); -export const concat23 = (a: Mat, ia: number, ...xs: (ReadonlyMat | [ReadonlyMat, number])[]) => - xs.reduce( - (acc: Mat, x) => isArrayLike(x[0]) ? - mul23(acc, x[0], ia, x[1]) : - mul23(acc, x, ia), - a - ); +export const concat23 = + (a: Mat, ia: number, ...xs: (ReadonlyMat | [ReadonlyMat, number])[]) => + xs.reduce( + (acc: Mat, x) => isArrayLike(x[0]) ? + mul23(acc, x[0], ia, x[1]) : + mul23(acc, x, ia), + a + ); -export const mulV23 = (v: Vec, m: ReadonlyMat, im = 0) => - setS( - v, - dot2(m, v, im, 0, 2) + m[im + 4], - dot2(m, v, im + 1, 0, 2) + m[im + 5], - ); +export const mulV23 = + (v: Vec, m: ReadonlyMat, im = 0) => + setS( + v, + dot2(m, v, im, 0, 2) + m[im + 4], + dot2(m, v, im + 1, 0, 2) + m[im + 5], + ); -export const det23 = (m: ReadonlyMat, i = 0) => - cross2(m, m, i, i + 1, 2, 2); - -export const invert23 = (m: Mat, i = 0) => { - const m00 = m[i]; - const m01 = m[i + 1]; - const m10 = m[i + 2]; - const m11 = m[i + 3]; - const m20 = m[i + 4]; - const m21 = m[i + 5]; - let det = m00 * m11 - m01 * m10; - if (!det) { - return; +export const det23 = + (m: ReadonlyMat, i = 0) => + cross2(m, m, i, i + 1, 2, 2); + +export const invert23 = + (m: Mat, i = 0) => { + const m00 = m[i]; + const m01 = m[i + 1]; + const m10 = m[i + 2]; + const m11 = m[i + 3]; + const m20 = m[i + 4]; + const m21 = m[i + 5]; + let det = m00 * m11 - m01 * m10; + if (!det) { + return; + } + det = 1.0 / det; + return setS23( + m, + m11 * det, + -m01 * det, + -m10 * det, + m00 * det, + (m10 * m21 - m11 * m20) * det, + (m01 * m20 - m00 * m21) * det, + i + ); } - det = 1.0 / det; - return setS23( - m, - m11 * det, - -m01 * det, - -m10 * det, - m00 * det, - (m10 * m21 - m11 * m20) * det, - (m01 * m20 - m00 * m21) * det, - i - ); -} export class Mat23 extends NDArray2 { diff --git a/packages/vectors2/src/mat33.ts b/packages/vectors2/src/mat33.ts index 98fa602f65..982d17fed1 100644 --- a/packages/vectors2/src/mat33.ts +++ b/packages/vectors2/src/mat33.ts @@ -11,21 +11,23 @@ import { iterator } from "./internal/iterator"; import { NDArray2 } from "./nd"; import { dot3, set3, setS3, setS4 } from "./internal/matrix"; -export const get33 = (a: Mat, i = 0) => - (a).slice(i, i + 9); - -export const set33 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => ( - a[ia] = b[ib], - a[ia + 1] = b[ib + 1], - a[ia + 2] = b[ib + 2], - a[ia + 3] = b[ib + 3], - a[ia + 4] = b[ib + 4], - a[ia + 5] = b[ib + 5], - a[ia + 6] = b[ib + 6], - a[ia + 7] = b[ib + 7], - a[ia + 8] = b[ib + 8], - a -); +export const get33 = + (a: Mat, i = 0) => + (a).slice(i, i + 9); + +export const set33 = + (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => ( + a[ia] = b[ib], + a[ia + 1] = b[ib + 1], + a[ia + 2] = b[ib + 2], + a[ia + 3] = b[ib + 3], + a[ia + 4] = b[ib + 4], + a[ia + 5] = b[ib + 5], + a[ia + 6] = b[ib + 6], + a[ia + 7] = b[ib + 7], + a[ia + 8] = b[ib + 8], + a + ); /** * ``` @@ -64,158 +66,172 @@ export const setS33 = ( m ); -export const identity33 = (m?: Mat, i = 0) => - setS33(m || [], - 1, 0, 0, - 0, 1, 0, - 0, 0, 1, - i - ); - -export const rotationX33 = (m: Mat, theta: number, i = 0) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS33(m || [], - 1, 0, 0, - 0, c, s, - 0, -s, c, - i - ); -}; - -export const rotationY33 = (m: Mat, theta: number, i = 0) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS33(m || [], - c, 0, -s, - 0, 1, 0, - s, 0, c, - i - ); -}; - -export const rotationZ33 = (m: Mat, theta: number, i = 0) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS33(m || [], - c, s, 0, - -s, c, 0, - 0, 0, 1, - i - ); -}; - -export const scaleV33 = (m: Mat, v: ReadonlyVec, i = 0) => - scaleS33(m, v[0], v[1], v[2], i); - -export const scaleN33 = (m: Mat, n: number, i = 0) => - scaleS33(m, n, n, n, i); +export const identity33 = + (m?: Mat, i = 0) => + setS33(m || [], + 1, 0, 0, + 0, 1, 0, + 0, 0, 1, + i + ); -export const scaleS33 = (m: Mat, sx: number, sy: number, sz: number, i = 0) => - setS33(m || [], - sx, 0, 0, - 0, sy, 0, - 0, 0, sz, - i - ); +export const rotationX33 = + (m: Mat, theta: number, i = 0) => { + const s = Math.sin(theta); + const c = Math.cos(theta); + return setS33(m || [], + 1, 0, 0, + 0, c, s, + 0, -s, c, + i + ); + }; + +export const rotationY33 = + (m: Mat, theta: number, i = 0) => { + const s = Math.sin(theta); + const c = Math.cos(theta); + return setS33(m || [], + c, 0, -s, + 0, 1, 0, + s, 0, c, + i + ); + }; + +export const rotationZ33 = + (m: Mat, theta: number, i = 0) => { + const s = Math.sin(theta); + const c = Math.cos(theta); + return setS33(m || [], + c, s, 0, + -s, c, 0, + 0, 0, 1, + i + ); + }; + +export const scaleV33 = + (m: Mat, v: ReadonlyVec, i = 0) => + scaleS33(m, v[0], v[1], v[2], i); + +export const scaleN33 = + (m: Mat, n: number, i = 0) => + scaleS33(m, n, n, n, i); + +export const scaleS33 = + (m: Mat, sx: number, sy: number, sz: number, i = 0) => + setS33(m || [], + sx, 0, 0, + 0, sy, 0, + 0, 0, sz, + i + ); -export const mul33 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => - setS33( - a, - dot3(a, b, ia, ib, 3), - dot3(a, b, ia + 1, ib, 3), - dot3(a, b, ia + 2, ib, 3), - dot3(a, b, ia, ib + 3, 3), - dot3(a, b, ia + 1, ib + 3, 3), - dot3(a, b, ia + 2, ib + 3, 3), - dot3(a, b, ia, ib + 6, 3), - dot3(a, b, ia + 1, ib + 6, 3), - dot3(a, b, ia + 2, ib + 6, 3), - ia - ); +export const mul33 = + (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => + setS33( + a, + dot3(a, b, ia, ib, 3), + dot3(a, b, ia + 1, ib, 3), + dot3(a, b, ia + 2, ib, 3), + dot3(a, b, ia, ib + 3, 3), + dot3(a, b, ia + 1, ib + 3, 3), + dot3(a, b, ia + 2, ib + 3, 3), + dot3(a, b, ia, ib + 6, 3), + dot3(a, b, ia + 1, ib + 6, 3), + dot3(a, b, ia + 2, ib + 6, 3), + ia + ); -export const concat33 = (a: Mat, ia: number, ...xs: (ReadonlyMat | [ReadonlyMat, number])[]) => - xs.reduce( - (acc: Mat, x) => isArrayLike(x[0]) ? - mul33(acc, x[0], ia, x[1]) : - mul33(acc, x, ia), - a - ); +export const concat33 = + (a: Mat, ia: number, ...xs: (ReadonlyMat | [ReadonlyMat, number])[]) => + xs.reduce( + (acc: Mat, x) => isArrayLike(x[0]) ? + mul33(acc, x[0], ia, x[1]) : + mul33(acc, x, ia), + a + ); -export const mulV33 = (v: Vec, m: ReadonlyMat, im = 0) => - setS( - v, - dot3(m, v, im, 0, 3), - dot3(m, v, im + 1, 0, 3), - dot3(m, v, im + 2, 0, 3), - ); +export const mulV33 = + (v: Vec, m: ReadonlyMat, im = 0) => + setS( + v, + dot3(m, v, im, 0, 3), + dot3(m, v, im + 1, 0, 3), + dot3(m, v, im + 2, 0, 3), + ); -export const det33 = (m: ReadonlyMat, i = 0) => { - const m00 = m[i]; - const m01 = m[i + 1]; - const m02 = m[i + 2]; - const m10 = m[i + 3]; - const m11 = m[i + 4]; - const m12 = m[i + 5]; - const m20 = m[i + 6]; - const m21 = m[i + 7]; - const m22 = m[i + 8]; - const d01 = m22 * m11 - m12 * m21; - const d11 = -m22 * m10 + m12 * m20; - const d21 = m21 * m10 - m11 * m20; - return m00 * d01 + m01 * d11 + m02 * d21; -}; - -export const invert33 = (m: Mat, i = 0) => { - const m00 = m[i]; - const m01 = m[i + 1]; - const m02 = m[i + 2]; - const m10 = m[i + 3]; - const m11 = m[i + 4]; - const m12 = m[i + 5]; - const m20 = m[i + 6]; - const m21 = m[i + 7]; - const m22 = m[i + 8]; - const d01 = m22 * m11 - m12 * m21; - const d11 = -m22 * m10 + m12 * m20; - const d21 = m21 * m10 - m11 * m20; - let det = m00 * d01 + m01 * d11 + m02 * d21; - if (!det) { - return; +export const det33 = + (m: ReadonlyMat, i = 0) => { + const m00 = m[i]; + const m01 = m[i + 1]; + const m02 = m[i + 2]; + const m10 = m[i + 3]; + const m11 = m[i + 4]; + const m12 = m[i + 5]; + const m20 = m[i + 6]; + const m21 = m[i + 7]; + const m22 = m[i + 8]; + const d01 = m22 * m11 - m12 * m21; + const d11 = -m22 * m10 + m12 * m20; + const d21 = m21 * m10 - m11 * m20; + return m00 * d01 + m01 * d11 + m02 * d21; + }; + +export const invert33 = + (m: Mat, i = 0) => { + const m00 = m[i]; + const m01 = m[i + 1]; + const m02 = m[i + 2]; + const m10 = m[i + 3]; + const m11 = m[i + 4]; + const m12 = m[i + 5]; + const m20 = m[i + 6]; + const m21 = m[i + 7]; + const m22 = m[i + 8]; + const d01 = m22 * m11 - m12 * m21; + const d11 = -m22 * m10 + m12 * m20; + const d21 = m21 * m10 - m11 * m20; + let det = m00 * d01 + m01 * d11 + m02 * d21; + if (!det) { + return; + } + det = 1.0 / det; + return setS33( + m, + d01 * det, + (-m22 * m01 + m02 * m21) * det, + (m12 * m01 - m02 * m11) * det, + d11 * det, + (m22 * m00 - m02 * m20) * det, + (-m12 * m00 + m02 * m10) * det, + d21 * det, + (-m21 * m00 + m01 * m20) * det, + (m11 * m00 - m01 * m10) * det, + i + ); } - det = 1.0 / det; - return setS33( - m, - d01 * det, - (-m22 * m01 + m02 * m21) * det, - (m12 * m01 - m02 * m11) * det, - d11 * det, - (m22 * m00 - m02 * m20) * det, - (-m12 * m00 + m02 * m10) * det, - d21 * det, - (-m21 * m00 + m01 * m20) * det, - (m11 * m00 - m01 * m10) * det, - i - ); -} -export const transpose33 = (m: Mat, i = 0) => - setS33( - m, - m[i], m[i + 3], m[i + 6], - m[i + 1], m[i + 4], m[i + 7], - m[i + 2], m[i + 5], m[i + 8], - i - ); +export const transpose33 = + (m: Mat, i = 0) => + setS33( + m, + m[i], m[i + 3], m[i + 6], + m[i + 1], m[i + 4], m[i + 7], + m[i + 2], m[i + 5], m[i + 8], + i + ); -export const mat33to44 = (m44: Mat, m33: ReadonlyMat, ia = 0, ib = 0) => ( - set3(m44, m33, ia, ib), - set3(m44, m33, ia + 4, ib + 3), - set3(m44, m33, ia + 8, ib + 6), - setS3(m44, 0, 0, 0, ia + 12), - setS4(m44, 0, 0, 0, 1, ia + 3, 4), - m44 -); +export const mat33to44 = + (m44: Mat, m33: ReadonlyMat, ia = 0, ib = 0) => ( + set3(m44, m33, ia, ib), + set3(m44, m33, ia + 4, ib + 3), + set3(m44, m33, ia + 8, ib + 6), + setS3(m44, 0, 0, 0, ia + 12), + setS4(m44, 0, 0, 0, 1, ia + 3, 4), + m44 + ); export class Mat33 extends NDArray2 { diff --git a/packages/vectors2/src/mat44.ts b/packages/vectors2/src/mat44.ts index 4d8dd492e0..7ff3ec74c6 100644 --- a/packages/vectors2/src/mat44.ts +++ b/packages/vectors2/src/mat44.ts @@ -21,15 +21,17 @@ import { Mat33 } from "./mat33"; import { NDArray2 } from "./nd"; import { cross3, sub3 } from "./vec3"; -export const get44 = (a: Mat, i = 0) => - (a).slice(i, i + 16); - -export const set44 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => { - for (let i = 0; i < 16; i++) { - a[ia + i] = b[ib + i]; - } - return a; -}; +export const get44 = + (a: Mat, i = 0) => + (a).slice(i, i + 16); + +export const set44 = + (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => { + for (let i = 0; i < 16; i++) { + a[ia + i] = b[ib + i]; + } + return a; + }; /** * ``` @@ -65,331 +67,356 @@ export const setS44 = ( m ); -export const identity44 = (m?: Mat, i = 0) => - setS44(m || [], - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1, - i - ); +export const identity44 = + (m?: Mat, i = 0) => + setS44(m || [], + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1, + i + ); -export const rotationX44 = (m: Mat, theta: number, i = 0) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS44(m || [], - 1, 0, 0, 0, - 0, c, s, 0, - 0, -s, c, 0, - 0, 0, 0, 1, - i - ); -}; - -export const rotationY44 = (m: Mat, theta: number, i = 0) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS44(m || [], - c, 0, -s, 0, - 0, 1, 0, 0, - s, 0, c, 0, - 0, 0, 0, 1, - i - ); -}; - -export const rotationZ44 = (m: Mat, theta: number, i = 0) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS44(m || [], - c, s, 0, 0, - -s, c, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1, - i - ); -}; +export const rotationX44 = + (m: Mat, theta: number, i = 0) => { + const s = Math.sin(theta); + const c = Math.cos(theta); + return setS44(m || [], + 1, 0, 0, 0, + 0, c, s, 0, + 0, -s, c, 0, + 0, 0, 0, 1, + i + ); + }; -export const scaleV44 = (m: Mat, v: ReadonlyVec, i = 0) => - scaleS44(m, v[0], v[1], v[2], i); +export const rotationY44 = + (m: Mat, theta: number, i = 0) => { + const s = Math.sin(theta); + const c = Math.cos(theta); + return setS44(m || [], + c, 0, -s, 0, + 0, 1, 0, 0, + s, 0, c, 0, + 0, 0, 0, 1, + i + ); + }; -export const scaleN44 = (m: Mat, n: number, i = 0) => - scaleS44(m, n, n, n, i); +export const rotationZ44 = + (m: Mat, theta: number, i = 0) => { + const s = Math.sin(theta); + const c = Math.cos(theta); + return setS44(m || [], + c, s, 0, 0, + -s, c, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1, + i + ); + }; -export const scaleS44 = (m: Mat, sx: number, sy: number, sz: number, i = 0) => - setS44(m || [], - sx, 0, 0, 0, - 0, sy, 0, 0, - 0, 0, sz, 0, - 0, 0, 0, 1, - i - ); +export const scaleV44 = + (m: Mat, v: ReadonlyVec, i = 0) => + scaleS44(m, v[0], v[1], v[2], i); + +export const scaleN44 = + (m: Mat, n: number, i = 0) => + scaleS44(m, n, n, n, i); + +export const scaleS44 = + (m: Mat, sx: number, sy: number, sz: number, i = 0) => + setS44(m || [], + sx, 0, 0, 0, + 0, sy, 0, 0, + 0, 0, sz, 0, + 0, 0, 0, 1, + i + ); -export const scaleWithCenter44 = (m: Mat, p: ReadonlyVec, sx: number, sy: number, sz: number, im = 0) => - concat44( - translationV44(m || [], p, im), im, - scaleS44([], sx, sy, sz), - translationS44([], -p[0], -p[1], -p[2]) - ); +export const scaleWithCenter44 = + (m: Mat, p: ReadonlyVec, sx: number, sy: number, sz: number, im = 0) => + concat44( + translationV44(m || [], p, im), im, + scaleS44([], sx, sy, sz), + translationS44([], -p[0], -p[1], -p[2]) + ); -export const translationV44 = (m: Mat, v: ReadonlyVec, i = 0) => - translationS44(m, v[0], v[1], v[2], i); +export const translationV44 = + (m: Mat, v: ReadonlyVec, i = 0) => + translationS44(m, v[0], v[1], v[2], i); + +export const translationS44 = + (m: Mat, x: number, y: number, z: number, i = 0) => + setS44(m || [], + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + x, y, z, 1, + i + ); -export const translationS44 = (m: Mat, x: number, y: number, z: number, i = 0) => - setS44(m || [], - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - x, y, z, 1, - i - ); +export const frustum = + (m: Mat, left: number, right: number, bottom: number, top: number, near: number, far: number, i = 0) => { + const dx = 1 / (right - left); + const dy = 1 / (top - bottom); + const dz = 1 / (far - near); + return setS44(m || [], + near * 2 * dx, 0, 0, 0, + 0, near * 2 * dy, 0, 0, + (right + left) * dx, (top + bottom) * dy, -(far + near) * dz, -1, + 0, 0, -(far * near * 2) * dz, 0, + i + ); + }; -export const frustum = (m: Mat, left: number, right: number, bottom: number, top: number, near: number, far: number, i = 0) => { - const dx = 1 / (right - left); - const dy = 1 / (top - bottom); - const dz = 1 / (far - near); - return setS44(m || [], - near * 2 * dx, 0, 0, 0, - 0, near * 2 * dy, 0, 0, - (right + left) * dx, (top + bottom) * dy, -(far + near) * dz, -1, - 0, 0, -(far * near * 2) * dz, 0, - i - ); -}; - -export const frustumBounds = (fovy: number, aspect: number, near: number, far: number) => { - const top = near * Math.tan(fovy * DEG2RAD / 2); - const right = top * aspect; - return { - left: -right, - right, - bottom: -top, - top, - near, - far +export const frustumBounds = + (fovy: number, aspect: number, near: number, far: number) => { + const top = near * Math.tan(fovy * DEG2RAD / 2); + const right = top * aspect; + return { + left: -right, + right, + bottom: -top, + top, + near, + far + }; }; -}; - -export const perspective = (m: Mat, fov: number, aspect: number, near: number, far: number, i = 0) => { - const f = frustumBounds(fov, aspect, near, far); - return frustum(m || [], f.left, f.right, f.bottom, f.top, f.near, f.far, i); -}; - -export const ortho = (m: Mat, left: number, right: number, bottom: number, top: number, near: number, far: number, i = 0) => { - const dx = 1 / (right - left); - const dy = 1 / (top - bottom); - const dz = 1 / (far - near); - return setS44(m || [], - 2 * dx, 0, 0, 0, - 0, 2 * dy, 0, 0, - 0, 0, -2 * dz, 0, - -(left + right) * dx, -(top + bottom) * dy, -(far + near) * dz, 1, - i - ); -}; - -export const lookAt = (m: Mat, eye: ReadonlyVec, target: ReadonlyVec, up: ReadonlyVec, im = 0) => { - const z = normalize(sub3(copy(eye), target)); - const x = normalize(cross3(copy(up), z)); - const y = normalize(cross3(z, x)); - return setS44(m || [], - x[0], y[0], z[0], 0, - x[1], y[1], z[1], 0, - x[2], y[2], z[2], 0, - -dot3(eye, x), -dot3(eye, y), -dot3(eye, z), 1, - im - ); -} -export const mul44 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => - setS44( - a, - dot4(a, b, ia, ib, 4), - dot4(a, b, ia + 1, ib, 4), - dot4(a, b, ia + 2, ib, 4), - dot4(a, b, ia + 3, ib, 4), - dot4(a, b, ia, ib + 4, 4), - dot4(a, b, ia + 1, ib + 4, 4), - dot4(a, b, ia + 2, ib + 4, 4), - dot4(a, b, ia + 3, ib + 4, 4), - dot4(a, b, ia, ib + 8, 4), - dot4(a, b, ia + 1, ib + 8, 4), - dot4(a, b, ia + 2, ib + 8, 4), - dot4(a, b, ia + 3, ib + 8, 4), - dot4(a, b, ia, ib + 12, 4), - dot4(a, b, ia + 1, ib + 12, 4), - dot4(a, b, ia + 2, ib + 12, 4), - dot4(a, b, ia + 3, ib + 12, 4), - ia - ); +export const perspective = + (m: Mat, fov: number, aspect: number, near: number, far: number, i = 0) => { + const f = frustumBounds(fov, aspect, near, far); + return frustum(m || [], f.left, f.right, f.bottom, f.top, f.near, f.far, i); + }; -export const concat44 = (a: Mat, ia: number, ...xs: (ReadonlyMat | [ReadonlyMat, number])[]) => - xs.reduce( - (acc: Mat, x) => isArrayLike(x[0]) ? - mul44(acc, x[0], ia, x[1]) : - mul44(acc, x, ia), - a - ); +export const ortho = + (m: Mat, left: number, right: number, bottom: number, top: number, near: number, far: number, i = 0) => { + const dx = 1 / (right - left); + const dy = 1 / (top - bottom); + const dz = 1 / (far - near); + return setS44(m || [], + 2 * dx, 0, 0, 0, + 0, 2 * dy, 0, 0, + 0, 0, -2 * dz, 0, + -(left + right) * dx, -(top + bottom) * dy, -(far + near) * dz, 1, + i + ); + }; -export const mulV344 = (v: Vec, m: ReadonlyMat, im = 0) => - setS3( - v, - dot3(m, v, im, 0, 4) + m[12], - dot3(m, v, im + 1, 0, 4) + m[13], - dot3(m, v, im + 2, 0, 4) + m[14], - ); +export const lookAt = + (m: Mat, eye: ReadonlyVec, target: ReadonlyVec, up: ReadonlyVec, im = 0) => { + const z = normalize(sub3(copy(eye), target)); + const x = normalize(cross3(copy(up), z)); + const y = normalize(cross3(z, x)); + return setS44(m || [], + x[0], y[0], z[0], 0, + x[1], y[1], z[1], 0, + x[2], y[2], z[2], 0, + -dot3(eye, x), -dot3(eye, y), -dot3(eye, z), 1, + im + ); + } -export const mulV44 = (v: Vec, m: ReadonlyMat, im = 0) => - setS4( - v, - dot4(m, v, im, 0, 4), - dot4(m, v, im + 1, 0, 4), - dot4(m, v, im + 2, 0, 4), - dot4(m, v, im + 3, 0, 4), - ); +export const mul44 = + (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => + setS44( + a, + dot4(a, b, ia, ib, 4), + dot4(a, b, ia + 1, ib, 4), + dot4(a, b, ia + 2, ib, 4), + dot4(a, b, ia + 3, ib, 4), + dot4(a, b, ia, ib + 4, 4), + dot4(a, b, ia + 1, ib + 4, 4), + dot4(a, b, ia + 2, ib + 4, 4), + dot4(a, b, ia + 3, ib + 4, 4), + dot4(a, b, ia, ib + 8, 4), + dot4(a, b, ia + 1, ib + 8, 4), + dot4(a, b, ia + 2, ib + 8, 4), + dot4(a, b, ia + 3, ib + 8, 4), + dot4(a, b, ia, ib + 12, 4), + dot4(a, b, ia + 1, ib + 12, 4), + dot4(a, b, ia + 2, ib + 12, 4), + dot4(a, b, ia + 3, ib + 12, 4), + ia + ); -const detCoeffs44 = (m: ReadonlyMat, i = 0) => { - const m00 = m[i]; - const m01 = m[i + 1]; - const m02 = m[i + 2]; - const m03 = m[i + 3]; - const m10 = m[i + 4]; - const m11 = m[i + 5]; - const m12 = m[i + 6]; - const m13 = m[i + 7]; - const m20 = m[i + 8]; - const m21 = m[i + 9]; - const m22 = m[i + 10]; - const m23 = m[i + 11]; - const m30 = m[i + 12]; - const m31 = m[i + 13]; - const m32 = m[i + 14]; - const m33 = m[i + 15]; - return [ - m00 * m11 - m01 * m10, - m00 * m12 - m02 * m10, - m00 * m13 - m03 * m10, - m01 * m12 - m02 * m11, - m01 * m13 - m03 * m11, - m02 * m13 - m03 * m12, - m20 * m31 - m21 * m30, - m20 * m32 - m22 * m30, - m20 * m33 - m23 * m30, - m21 * m32 - m22 * m31, - m21 * m33 - m23 * m31, - m22 * m33 - m23 * m32, - ]; -}; - -export const det44 = (m: ReadonlyMat, i = 0) => { - const d = detCoeffs44(m, i); - return d[0] * d[11] - d[1] * d[10] + d[2] * d[9] + - d[3] * d[8] - d[4] * d[7] + d[5] * d[6]; -}; - -export const invert44 = (m: Mat, i = 0) => { - const m00 = m[i]; - const m01 = m[i + 1]; - const m02 = m[i + 2]; - const m03 = m[i + 3]; - const m10 = m[i + 4]; - const m11 = m[i + 5]; - const m12 = m[i + 6]; - const m13 = m[i + 7]; - const m20 = m[i + 8]; - const m21 = m[i + 9]; - const m22 = m[i + 10]; - const m23 = m[i + 11]; - const m30 = m[i + 12]; - const m31 = m[i + 13]; - const m32 = m[i + 14]; - const m33 = m[i + 15]; - const d = detCoeffs44(m, i); - const d00 = d[0]; - const d01 = d[1]; - const d02 = d[2]; - const d03 = d[3]; - const d04 = d[4]; - const d05 = d[5]; - const d06 = d[6]; - const d07 = d[7]; - const d08 = d[8]; - const d09 = d[9]; - const d10 = d[10]; - const d11 = d[11]; - let det = (d00 * d11 - d01 * d10 + d02 * d09 + d03 * d08 - d04 * d07 + d05 * d06); - if (!det) { - return; - } - det = 1.0 / det; - return setS44( - m, - (m11 * d11 - m12 * d10 + m13 * d09) * det, - (-m01 * d11 + m02 * d10 - m03 * d09) * det, - (m31 * d05 - m32 * d04 + m33 * d03) * det, - (-m21 * d05 + m22 * d04 - m23 * d03) * det, - (-m10 * d11 + m12 * d08 - m13 * d07) * det, - (m00 * d11 - m02 * d08 + m03 * d07) * det, - (-m30 * d05 + m32 * d02 - m33 * d01) * det, - (m20 * d05 - m22 * d02 + m23 * d01) * det, - (m10 * d10 - m11 * d08 + m13 * d06) * det, - (-m00 * d10 + m01 * d08 - m03 * d06) * det, - (m30 * d04 - m31 * d02 + m33 * d00) * det, - (-m20 * d04 + m21 * d02 - m23 * d00) * det, - (-m10 * d09 + m11 * d07 - m12 * d06) * det, - (m00 * d09 - m01 * d07 + m02 * d06) * det, - (-m30 * d03 + m31 * d01 - m32 * d00) * det, - (m20 * d03 - m21 * d01 + m22 * d00) * det, - i - ); -} +export const concat44 = + (a: Mat, ia: number, ...xs: (ReadonlyMat | [ReadonlyMat, number])[]) => + xs.reduce( + (acc: Mat, x) => isArrayLike(x[0]) ? + mul44(acc, x[0], ia, x[1]) : + mul44(acc, x, ia), + a + ); -export const transpose44 = (m: Mat, i = 0) => - setS44( - m, - m[i], m[i + 4], m[i + 8], m[i + 12], - m[i + 1], m[i + 5], m[i + 9], m[i + 13], - m[i + 2], m[i + 6], m[i + 10], m[i + 14], - m[i + 3], m[i + 7], m[i + 11], m[i + 15], - i - ); +export const mulV344 = + (v: Vec, m: ReadonlyMat, im = 0) => + setS3( + v, + dot3(m, v, im, 0, 4) + m[12], + dot3(m, v, im + 1, 0, 4) + m[13], + dot3(m, v, im + 2, 0, 4) + m[14], + ); -export const normal44 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => { - const m00 = b[ib]; - const m01 = b[ib + 1]; - const m02 = b[ib + 2]; - const m10 = b[ib + 4]; - const m11 = b[ib + 5]; - const m12 = b[ib + 6]; - const m20 = b[ib + 8]; - const m21 = b[ib + 9]; - const m22 = b[ib + 10]; - const d01 = m22 * m11 - m12 * m21; - const d11 = -m22 * m10 + m12 * m20; - const d21 = m21 * m10 - m11 * m20; - let det = m00 * d01 + m01 * d11 + m02 * d21; - if (!det) { - return; +export const mulV44 = + (v: Vec, m: ReadonlyMat, im = 0) => + setS4( + v, + dot4(m, v, im, 0, 4), + dot4(m, v, im + 1, 0, 4), + dot4(m, v, im + 2, 0, 4), + dot4(m, v, im + 3, 0, 4), + ); + +const detCoeffs44 = + (m: ReadonlyMat, i = 0) => { + const m00 = m[i]; + const m01 = m[i + 1]; + const m02 = m[i + 2]; + const m03 = m[i + 3]; + const m10 = m[i + 4]; + const m11 = m[i + 5]; + const m12 = m[i + 6]; + const m13 = m[i + 7]; + const m20 = m[i + 8]; + const m21 = m[i + 9]; + const m22 = m[i + 10]; + const m23 = m[i + 11]; + const m30 = m[i + 12]; + const m31 = m[i + 13]; + const m32 = m[i + 14]; + const m33 = m[i + 15]; + return [ + m00 * m11 - m01 * m10, + m00 * m12 - m02 * m10, + m00 * m13 - m03 * m10, + m01 * m12 - m02 * m11, + m01 * m13 - m03 * m11, + m02 * m13 - m03 * m12, + m20 * m31 - m21 * m30, + m20 * m32 - m22 * m30, + m20 * m33 - m23 * m30, + m21 * m32 - m22 * m31, + m21 * m33 - m23 * m31, + m22 * m33 - m23 * m32, + ]; + }; + +export const det44 = + (m: ReadonlyMat, i = 0) => { + const d = detCoeffs44(m, i); + return d[0] * d[11] - d[1] * d[10] + d[2] * d[9] + + d[3] * d[8] - d[4] * d[7] + d[5] * d[6]; + }; + +export const invert44 = + (m: Mat, i = 0) => { + const m00 = m[i]; + const m01 = m[i + 1]; + const m02 = m[i + 2]; + const m03 = m[i + 3]; + const m10 = m[i + 4]; + const m11 = m[i + 5]; + const m12 = m[i + 6]; + const m13 = m[i + 7]; + const m20 = m[i + 8]; + const m21 = m[i + 9]; + const m22 = m[i + 10]; + const m23 = m[i + 11]; + const m30 = m[i + 12]; + const m31 = m[i + 13]; + const m32 = m[i + 14]; + const m33 = m[i + 15]; + const d = detCoeffs44(m, i); + const d00 = d[0]; + const d01 = d[1]; + const d02 = d[2]; + const d03 = d[3]; + const d04 = d[4]; + const d05 = d[5]; + const d06 = d[6]; + const d07 = d[7]; + const d08 = d[8]; + const d09 = d[9]; + const d10 = d[10]; + const d11 = d[11]; + let det = (d00 * d11 - d01 * d10 + d02 * d09 + d03 * d08 - d04 * d07 + d05 * d06); + if (!det) { + return; + } + det = 1.0 / det; + return setS44( + m, + (m11 * d11 - m12 * d10 + m13 * d09) * det, + (-m01 * d11 + m02 * d10 - m03 * d09) * det, + (m31 * d05 - m32 * d04 + m33 * d03) * det, + (-m21 * d05 + m22 * d04 - m23 * d03) * det, + (-m10 * d11 + m12 * d08 - m13 * d07) * det, + (m00 * d11 - m02 * d08 + m03 * d07) * det, + (-m30 * d05 + m32 * d02 - m33 * d01) * det, + (m20 * d05 - m22 * d02 + m23 * d01) * det, + (m10 * d10 - m11 * d08 + m13 * d06) * det, + (-m00 * d10 + m01 * d08 - m03 * d06) * det, + (m30 * d04 - m31 * d02 + m33 * d00) * det, + (-m20 * d04 + m21 * d02 - m23 * d00) * det, + (-m10 * d09 + m11 * d07 - m12 * d06) * det, + (m00 * d09 - m01 * d07 + m02 * d06) * det, + (-m30 * d03 + m31 * d01 - m32 * d00) * det, + (m20 * d03 - m21 * d01 + m22 * d00) * det, + i + ); } - det = 1.0 / det; - a[ia] = d01 * det; - a[ia + 1] = d11 * det; - a[ia + 2] = d21 * det; - a[ia + 3] = (-m22 * m01 + m02 * m21) * det; - a[ia + 4] = (m22 * m00 - m02 * m20) * det; - a[ia + 5] = (-m21 * m00 + m01 * m20) * det; - a[ia + 6] = (m12 * m01 - m02 * m11) * det; - a[ia + 7] = (-m12 * m00 + m02 * m10) * det; - a[ia + 8] = (m11 * m00 - m01 * m10) * det; - return a; -}; - -export const mat44to33 = (m33: Mat, m44: ReadonlyMat, ia = 0, ib = 0) => ( - set3(m33, m44, ia, ib), - set3(m33, m44, ia + 3, ib + 4), - set3(m33, m44, ia + 6, ib + 8), - m33 -); + +export const transpose44 = + (m: Mat, i = 0) => + setS44( + m, + m[i], m[i + 4], m[i + 8], m[i + 12], + m[i + 1], m[i + 5], m[i + 9], m[i + 13], + m[i + 2], m[i + 6], m[i + 10], m[i + 14], + m[i + 3], m[i + 7], m[i + 11], m[i + 15], + i + ); + +export const normal44 = + (a: Mat, b: ReadonlyMat, ia = 0, ib = 0): Mat => { + const m00 = b[ib]; + const m01 = b[ib + 1]; + const m02 = b[ib + 2]; + const m10 = b[ib + 4]; + const m11 = b[ib + 5]; + const m12 = b[ib + 6]; + const m20 = b[ib + 8]; + const m21 = b[ib + 9]; + const m22 = b[ib + 10]; + const d01 = m22 * m11 - m12 * m21; + const d11 = -m22 * m10 + m12 * m20; + const d21 = m21 * m10 - m11 * m20; + let det = m00 * d01 + m01 * d11 + m02 * d21; + if (!det) { + return; + } + det = 1.0 / det; + a[ia] = d01 * det; + a[ia + 1] = d11 * det; + a[ia + 2] = d21 * det; + a[ia + 3] = (-m22 * m01 + m02 * m21) * det; + a[ia + 4] = (m22 * m00 - m02 * m20) * det; + a[ia + 5] = (-m21 * m00 + m01 * m20) * det; + a[ia + 6] = (m12 * m01 - m02 * m11) * det; + a[ia + 7] = (-m12 * m00 + m02 * m10) * det; + a[ia + 8] = (m11 * m00 - m01 * m10) * det; + return a; + }; + +export const mat44to33 = + (m33: Mat, m44: ReadonlyMat, ia = 0, ib = 0) => ( + set3(m33, m44, ia, ib), + set3(m33, m44, ia + 3, ib + 4), + set3(m33, m44, ia + 6, ib + 8), + m33 + ); export class Mat44 extends NDArray2 { diff --git a/packages/vectors2/src/nd.ts b/packages/vectors2/src/nd.ts index dc86ff15d2..8b6cefe7c8 100644 --- a/packages/vectors2/src/nd.ts +++ b/packages/vectors2/src/nd.ts @@ -1,9 +1,11 @@ import { isArrayLike } from "@thi.ng/checks/is-arraylike"; +import { isIterable } from "@thi.ng/checks/is-iterable"; import { isNumber } from "@thi.ng/checks/is-number"; -import { equiv } from "@thi.ng/equiv"; +import { equiv, equivArrayLike } from "@thi.ng/equiv"; import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; import { unsupported } from "@thi.ng/errors/unsupported"; import { EPS } from "@thi.ng/math/api"; +import { Stringer } from "@thi.ng/strings/api"; import { floatFixedWidth } from "@thi.ng/strings/float"; import { padLeft } from "@thi.ng/strings/pad-left"; import { truncate } from "@thi.ng/strings/truncate"; @@ -69,8 +71,9 @@ export class NDArray1 implements equiv(o: any) { return this === o || (isArrayLike(o) && + isIterable(o) && this.length === o.length && - equiv([...this], o)); + equivArrayLike([...this], [...o])); } eqDelta(o: NDArray1, eps = EPS) { @@ -205,7 +208,7 @@ export class NDArray2 implements return this === o || (o instanceof NDArray2 && equiv(this.shape, o.shape) && - equiv([...this], [...o])); + equivArrayLike([...this], [...o])); } eqDelta(o: NDArray2, eps = EPS) { @@ -372,7 +375,7 @@ export class NDArray3 implements return this === o || (o instanceof NDArray3 && equiv(this.shape, o.shape) && - equiv([...this], [...o])); + equivArrayLike([...this], [...o])); } eqDelta(o: NDArray3, eps = EPS) { @@ -545,12 +548,21 @@ const pick = ( return o; }; -const ff = floatFixedWidth(9, 4); -const pad = padLeft(9); -const trunc = truncate(9); +let formatNumber: Stringer; +let pad: Stringer; +let trunc: Stringer; const format = (x: any) => isNumber(x) ? - ff(x) : + formatNumber(x) : trunc(pad(x.toString())); + +export const setFormat = + (width: number, prec: number) => { + formatNumber = floatFixedWidth(width, prec); + pad = padLeft(width); + trunc = truncate(width); + }; + +setFormat(9, 4); diff --git a/packages/vectors2/src/quat.ts b/packages/vectors2/src/quat.ts new file mode 100644 index 0000000000..6ef91e8a50 --- /dev/null +++ b/packages/vectors2/src/quat.ts @@ -0,0 +1,99 @@ +import { + dot, + magSq, + ReadonlyVec, + Vec +} from "./api"; +import { maddN4, mulN4, Vec4 } from "./vec4"; + +export const mulQ = + (a: Vec, b: ReadonlyVec) => { + const [ax, ay, az, aw] = a; + const [bx, by, bz, bw] = b; + a[0] = ax * bw + aw * bx + ay * bz - az * by; + a[1] = ay * bw + aw * by + az * bx - ax * bz; + a[2] = az * bw + aw * bz + ax * by - ay * bx; + a[3] = aw * bw - ax * bx - ay * by - az * bz; + return a; + }; + +export const mulVQ = + (p: Vec, q: ReadonlyVec) => { + const [px, py, pz] = p; + const [qx, qy, qz, qw] = q; + const ix = qw * px + qy * pz - qz * py; + const iy = qw * py + qz * px - qx * pz; + const iz = qw * pz + qx * py - qy * px; + const iw = -qx * px - qy * py - qz * pz; + p[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy; + p[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz; + p[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx; + return p; + }; + +export const conjugateQ = + (a: Vec) => (a[0] *= -1, a[1] *= -1, a[2] *= -1, a); + +export const invertQ = + (a: Vec) => { + let d = magSq(a); + d = d > 0 ? -1 / d : 0; + a[0] *= d; + a[1] *= d; + a[2] *= d; + a[3] *= -d; + return a; + }; + +export const mixQ = + (a: Vec, b: ReadonlyVec, t: number, eps = 1e-3) => { + const d = dot(a, b); + if (Math.abs(d) < 1.0) { + const theta = Math.acos(d); + const stheta = Math.sqrt(1 - d * d); + let u, v; + if (Math.abs(stheta) < eps) { + u = v = 0.5; + } else { + u = Math.sin(theta * (1 - t)) / stheta; + v = Math.sin(theta * t) / stheta; + } + return maddN4(mulN4(a, u), b, v); + } + }; + +export class Quat extends Vec4 { + + static fromAxisAngle(axis: ReadonlyVec, theta: number) { + return quatFromAxisAngle(axis, theta); + } + + mulQ(q: Quat) { + mulQ(this, q); + return this; + } + + mulV(p: Vec) { + return mulVQ(p, this); + } + + mixQ(q: Quat, t: number) { + mixQ(this, q, t); + return this; + } +} + +export const quat = + (x = 0, y = 0, z = 0, w = 1) => new Quat([x, y, z, w]); + +export const quatFromAxisAngle = + (axis: ReadonlyVec, theta: number) => { + theta /= 2; + const s = Math.sin(theta); + return new Quat([ + s * axis[0], + s * axis[1], + s * axis[2], + Math.cos(theta) + ]); + }; diff --git a/packages/vectors2/src/vec2.ts b/packages/vectors2/src/vec2.ts index fc8e0deddd..45a111f635 100644 --- a/packages/vectors2/src/vec2.ts +++ b/packages/vectors2/src/vec2.ts @@ -2,8 +2,9 @@ import { Comparator } from "@thi.ng/api"; import { EPS, HALF_PI, PI } from "@thi.ng/math/api"; import { eqDelta as _eqDelta } from "@thi.ng/math/eqdelta"; import { max2id, min2id } from "@thi.ng/math/interval"; -import { declareIndices } from "./internal/accessors"; +import { mixBilinear } from "@thi.ng/math/mix"; import { AVec } from "./avec"; +import { declareIndices } from "./internal/accessors"; import { genCommon } from "./internal/codegen"; import { magSq, @@ -298,3 +299,15 @@ export const bisect2: VecOpRoVV = (a, b) => { const theta = (headingXY(a) + headingXY(b)) / 2; return theta <= HALF_PI ? theta : PI - theta; }; + +export const mixBilinear2 = ( + a: ReadonlyVec, + b: ReadonlyVec, + c: ReadonlyVec, + d: ReadonlyVec, + u: number, v: number, + out: Vec = []) => ( + out[0] = mixBilinear(a[0], b[0], c[0], d[0], u, v), + out[1] = mixBilinear(a[1], b[1], c[1], d[1], u, v), + out + ); diff --git a/packages/vectors2/src/vec3.ts b/packages/vectors2/src/vec3.ts index 3d226b0eb4..8a53084848 100644 --- a/packages/vectors2/src/vec3.ts +++ b/packages/vectors2/src/vec3.ts @@ -2,8 +2,9 @@ import { Comparator } from "@thi.ng/api"; import { EPS } from "@thi.ng/math/api"; import { eqDelta as _eqDelta } from "@thi.ng/math/eqdelta"; import { max3id, min3id } from "@thi.ng/math/interval"; -import { declareIndices } from "./internal/accessors"; +import { mixBilinear } from "@thi.ng/math/mix"; import { AVec } from "./avec"; +import { declareIndices } from "./internal/accessors"; import { genCommon } from "./internal/codegen"; import { magSq, @@ -336,3 +337,16 @@ export const cross3: VecOpVV = export const orthoNormal3: VecOpRoVVV = (a: Vec, b: Vec, c: Vec) => cross3(subNew(c, a), subNew(b, a)); + +export const mixBilinear3 = ( + a: ReadonlyVec, + b: ReadonlyVec, + c: ReadonlyVec, + d: ReadonlyVec, + u: number, v: number, + out: Vec = []) => ( + out[0] = mixBilinear(a[0], b[0], c[0], d[0], u, v), + out[1] = mixBilinear(a[1], b[1], c[1], d[1], u, v), + out[2] = mixBilinear(a[2], b[2], c[2], d[2], u, v), + out + ); diff --git a/packages/vectors2/src/vec4.ts b/packages/vectors2/src/vec4.ts index d5fbdf4524..9e509523a1 100644 --- a/packages/vectors2/src/vec4.ts +++ b/packages/vectors2/src/vec4.ts @@ -2,8 +2,9 @@ import { Comparator } from "@thi.ng/api/api"; import { EPS } from "@thi.ng/math/api"; import { eqDelta as _eqDelta } from "@thi.ng/math/eqdelta"; import { max4id, min4id } from "@thi.ng/math/interval"; -import { declareIndices } from "./internal/accessors"; +import { mixBilinear } from "@thi.ng/math/mix"; import { AVec } from "./avec"; +import { declareIndices } from "./internal/accessors"; import { genCommon } from "./internal/codegen"; import { magSq, @@ -73,6 +74,7 @@ export class Vec4 extends AVec implements buf[start] = v[0]; buf[start + cstride] = v[1]; buf[start + 2 * cstride] = v[2]; + buf[start + 3 * cstride] = v[3]; start += estride; } return buf; @@ -108,7 +110,7 @@ export class Vec4 extends AVec implements } copy() { - return new Vec4([this.x, this.y, this.z]); + return new Vec4([this.x, this.y, this.z, this.w]); } empty() { @@ -120,11 +122,11 @@ export class Vec4 extends AVec implements } toJSON() { - return [this.x, this.y, this.z]; + return [this.x, this.y, this.z, this.w]; } toString() { - return `[${this.x}, ${this.y}, ${this.z}]`; + return `[${this.x}, ${this.y}, ${this.z}, ${this.w}]`; } } @@ -271,3 +273,17 @@ export const comparator4 = ay < by ? -2 : 2 : ax < bx ? -1 : 1; }; + +export const mixBilinear4 = ( + a: ReadonlyVec, + b: ReadonlyVec, + c: ReadonlyVec, + d: ReadonlyVec, + u: number, v: number, + out: Vec = []) => ( + out[0] = mixBilinear(a[0], b[0], c[0], d[0], u, v), + out[1] = mixBilinear(a[1], b[1], c[1], d[1], u, v), + out[2] = mixBilinear(a[2], b[2], c[2], d[2], u, v), + out[3] = mixBilinear(a[3], b[3], c[3], d[3], u, v), + out + ); From 35bd06797dd815c7d17c8f018ab7f0c68446a73c Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 6 Nov 2018 00:02:55 +0000 Subject: [PATCH 019/333] feat(geom): add new / update all types / ops, add tests --- packages/geom2/src/api.ts | 329 +++++++++-- packages/geom2/src/arc.ts | 67 ++- packages/geom2/src/bezier.ts | 115 ++-- packages/geom2/src/circle.ts | 80 ++- packages/geom2/src/container2.ts | 38 +- packages/geom2/src/ellipse.ts | 72 ++- packages/geom2/src/group.ts | 4 + packages/geom2/src/index.ts | 3 + packages/geom2/src/internal/arc-length.ts | 14 - packages/geom2/src/internal/arc.ts | 24 + packages/geom2/src/internal/area.ts | 10 - packages/geom2/src/internal/barycentric.ts | 29 +- packages/geom2/src/internal/bounds.ts | 2 +- packages/geom2/src/internal/centroid.ts | 59 +- packages/geom2/src/internal/closest-point.ts | 19 +- packages/geom2/src/internal/corner.ts | 37 +- packages/geom2/src/internal/direction.ts | 14 + packages/geom2/src/internal/edges.ts | 12 + packages/geom2/src/internal/graham-scan.ts | 4 +- .../geom2/src/internal/greiner-hormann.ts | 307 +++++++++++ .../geom2/src/internal/line-intersection.ts | 29 +- packages/geom2/src/internal/offset.ts | 49 ++ packages/geom2/src/internal/perimeter.ts | 15 + packages/geom2/src/internal/polygon.ts | 21 + packages/geom2/src/internal/sampler.ts | 47 +- packages/geom2/src/internal/subdiv-curve.ts | 79 +++ packages/geom2/src/internal/transform.ts | 4 + packages/geom2/src/internal/warp.ts | 6 + packages/geom2/src/line.ts | 104 ++++ packages/geom2/src/path.ts | 509 ++++++++++++++++++ packages/geom2/src/polygon.ts | 230 ++++++-- packages/geom2/src/polyline.ts | 110 +++- packages/geom2/src/quad.ts | 78 ++- packages/geom2/src/rect.ts | 134 ++++- packages/geom2/src/svg.ts | 21 +- packages/geom2/src/tessellate.ts | 6 +- packages/geom2/src/triangle.ts | 106 ++++ packages/geom2/test/api.ts | 373 +++++++++++++ packages/geom2/test/circle.ts | 22 +- packages/geom2/test/clip.ts | 39 ++ 40 files changed, 2870 insertions(+), 351 deletions(-) delete mode 100644 packages/geom2/src/internal/arc-length.ts create mode 100644 packages/geom2/src/internal/arc.ts delete mode 100644 packages/geom2/src/internal/area.ts create mode 100644 packages/geom2/src/internal/direction.ts create mode 100644 packages/geom2/src/internal/edges.ts create mode 100644 packages/geom2/src/internal/greiner-hormann.ts create mode 100644 packages/geom2/src/internal/offset.ts create mode 100644 packages/geom2/src/internal/perimeter.ts create mode 100644 packages/geom2/src/internal/polygon.ts create mode 100644 packages/geom2/src/internal/subdiv-curve.ts create mode 100644 packages/geom2/src/internal/transform.ts create mode 100644 packages/geom2/src/internal/warp.ts create mode 100644 packages/geom2/src/line.ts create mode 100644 packages/geom2/src/path.ts create mode 100644 packages/geom2/src/triangle.ts create mode 100644 packages/geom2/test/api.ts create mode 100644 packages/geom2/test/clip.ts diff --git a/packages/geom2/src/api.ts b/packages/geom2/src/api.ts index aac0cc2187..4e8c87cc48 100644 --- a/packages/geom2/src/api.ts +++ b/packages/geom2/src/api.ts @@ -4,21 +4,33 @@ import { IObjectOf, IToHiccup } from "@thi.ng/api"; -import { DEFAULT, defmulti, MultiFn1O } from "@thi.ng/defmulti"; +import { + DEFAULT, + defmulti, + MultiFn1O, + MultiFn2O +} from "@thi.ng/defmulti"; import { equiv } from "@thi.ng/equiv"; import { cossin } from "@thi.ng/math/angle"; import { add, copy, + IMatrix, + max, + min, mixNewN, mul, + ReadonlyVec, rotateZ, subNew, - Vec + Vec, + neg } from "@thi.ng/vectors2/api"; -import { set2 } from "@thi.ng/vectors2/vec2"; +import { perpendicularLeft2, set2 } from "@thi.ng/vectors2/vec2"; +import { subdivKernel3 } from "./internal/subdiv-curve"; +import { warpPoints } from "./internal/warp"; -export enum Type { +export const enum Type { ARC2 = "arc", CIRCLE2 = "circle", CUBIC2 = "cubic", @@ -35,16 +47,76 @@ export enum Type { TRIANGLE2 = "triangle", } +export const enum ClipMode { + /** + * Shape union (A | B) + */ + UNION = 0, + /** + * Shape difference (B - A) + */ + DIFF_B = 1, + /** + * Shape difference (A - B) + */ + DIFF_A = 2, + /** + * Shape intersection (A & B) + */ + INTERSECTION = 3, +} + +export enum Convexity { + COLINEAR = 0, + CONVEX, + CONCAVE, +} + export const enum LineIntersectionType { - PARALLEL, + PARALLEL = 1, COINCIDENT, COINCIDENT_NO_INTERSECT, INTERSECT, INTERSECT_OUTSIDE, } +export const enum SegmentType { + MOVE, + LINE, + POLYLINE, + ARC, + CUBIC, + QUADRATIC, + CLOSE, +} + export const DEFAULT_SAMPLES = 20; +const CHAIKIN_FIRST = subdivKernel3([1 / 2, 1 / 2, 0], [0, 3 / 4, 1 / 4]); +const CHAIKIN_MAIN = subdivKernel3([1 / 4, 3 / 4, 0], [0, 3 / 4, 1 / 4]); +const CHAIKIN_LAST = subdivKernel3([1 / 4, 3 / 4, 0], [0, 1 / 2, 1 / 2]); +const CUBIC_MAIN = subdivKernel3([1 / 8, 3 / 4, 1 / 8], [0, 1 / 2, 1 / 2]); + +export const CHAIKIN_CLOSED: SubdivKernel = { + fn: CHAIKIN_MAIN, + size: 3 +}; + +export const CHAIKIN_OPEN: SubdivKernel = { + fn: (pts, i, n) => + i == 0 ? + [pts[0], ...CHAIKIN_FIRST(pts)] : + i === n - 3 ? + [...CHAIKIN_LAST(pts), pts[2]] : + CHAIKIN_MAIN(pts), + size: 3 +}; + +export const CUBIC_CLOSED: SubdivKernel = { + fn: CUBIC_MAIN, + size: 3 +}; + export interface IShape extends ICopy, IEquiv, @@ -54,6 +126,10 @@ export interface IShape extends attribs?: IObjectOf; } +export interface IHiccupPathSegment { + toHiccupPathSegments(): any[]; +} + export interface AABBLike extends IShape { pos: Vec; size: Vec; @@ -67,6 +143,12 @@ export interface LineIntersection { beta?: number; } +export interface PathSegment { + type: SegmentType; + point?: Vec; + geo?: IShape & IHiccupPathSegment; +} + export interface SamplingOpts { /** * Number of points to sample & return. Defaults to the implementing @@ -117,46 +199,86 @@ export interface SamplingOpts { last: boolean; } +export interface SubdivKernel { + fn: (pts: ReadonlyVec[], i: number, nump: number) => Vec[]; + size: number; +} + export type Attribs = IObjectOf; export type Tessellator = (points: Vec[]) => Vec[][]; +export type VecPair = [Vec, Vec]; + const dispatch = (x: IShape) => x.type; export const area: MultiFn1O = defmulti(dispatch); +area.add(DEFAULT, () => 0); -export const arcLength = defmulti(dispatch); - -export const asCubic = defmulti(dispatch); +export const asCubic = defmulti>(dispatch); export const asPolygon: MultiFn1O = defmulti(dispatch); +asPolygon.add(DEFAULT, (x, opts) => + new Polygon2(vertices(x, opts), { ...x.attribs }) +); export const asPolyline: MultiFn1O = defmulti(dispatch); +asPolyline.add(DEFAULT, (x, opts) => + new Polyline2(vertices(x, opts), { ...x.attribs }) +); export const bounds = defmulti(dispatch); -export const center = defmulti(dispatch); +export const center: MultiFn1O = defmulti(dispatch); +center.add(DEFAULT, (x, origin?) => { + const delta = neg(centroid(x)); + return translate(x, origin ? add(delta, origin) : delta); +}); export const centroid: MultiFn1O = defmulti(dispatch); -export const classifyPoint = defmulti(dispatch); +export const classifyPoint: MultiFn2O = defmulti(dispatch); + +export const closestPoint = defmulti(dispatch); + +export const clipConvex = defmulti(dispatch); export const convexHull = defmulti(dispatch); export const depth = defmulti(dispatch); depth.add(DEFAULT, (x) => bounds(x).size[2] || 0); -export const difference = defmulti(dispatch); +export const difference = defmulti(dispatch); + +export const edges: MultiFn1O, Iterable> = defmulti(dispatch); export const extrude = defmulti(dispatch); +export const flip = defmulti(dispatch); + export const height = defmulti(dispatch); height.add(DEFAULT, (x) => bounds(x).size[1]); -export const intersect = defmulti(dispatch); +export const intersection = defmulti(dispatch); + +// TODO define isec result +export const intersectShape = defmulti(dispatch); + +export const intersectLine = defmulti(dispatch); + +export const mapPoint: MultiFn2O = defmulti(dispatch); + +export const normalAt: MultiFn2O = defmulti(dispatch); +normalAt.add(DEFAULT, (shape, t, n = 1) => perpendicularLeft2(tangentAt(shape, t, n))); + +export const offset: MultiFn2O = defmulti(dispatch); + +export const perimeter = defmulti(dispatch); export const pointAt = defmulti(dispatch); +export const pointInside = defmulti(dispatch); + export const resample = defmulti(dispatch); /** @@ -170,15 +292,40 @@ export const simplify: MultiFn1O = defmulti(dispatch); export const splitAt = defmulti(dispatch); +export const subdivide: MultiFn2O = defmulti(dispatch); + +export const tangentAt: MultiFn2O = defmulti(dispatch); + export const tessellate = defmulti, Vec[][]>(dispatch); -export const union = defmulti(dispatch); +export const transform = defmulti, IShape>(dispatch); + +export const translate = defmulti(dispatch); + +export const union = defmulti(dispatch); + +export const unmapPoint: MultiFn2O = defmulti(dispatch); export const vertices: MultiFn1O, Vec[]> = defmulti(dispatch); +export const warp = defmulti(dispatch); +warp.add(DEFAULT, (src: IShape, dest: IShape) => + new Polygon2( + warpPoints(vertices(src), bounds(src), dest), + { ...src.attribs } + ) +); + export const width = defmulti(dispatch); width.add(DEFAULT, (x) => bounds(x).size[0]); +export const withAttribs = defmulti(dispatch); +withAttribs.add(DEFAULT, (x, attribs) => { + x = x.copy(); + Object.assign(x.attribs, attribs); + return x; +}); + export class PointContainer implements IShape { @@ -192,15 +339,25 @@ export class PointContainer implements this.attribs = attribs; } + *[Symbol.iterator]() { + yield* this.points; + } + copy() { return new PointContainer(this.type, this._copy(), this.attribs); } equiv(o: any) { return o instanceof PointContainer && + this.type === o.type && equiv(this.points, o.points); } + flip() { + this.points.reverse(); + return this; + } + toHiccup() { return [this.type, this.attribs, this.points]; } @@ -211,6 +368,7 @@ export class PointContainer implements } export class Arc2 implements + IHiccupPathSegment, IShape { pos: Vec; @@ -270,13 +428,13 @@ export class Arc2 implements this.clockwise && o.clockwise; } - pointAtTheta(theta: number, pos?: Vec) { - return add(rotateZ(mul(set2(pos || [], cossin(theta)), this.r), this.axis), this.pos); + pointAtTheta(theta: number, pos: Vec = []) { + return add(rotateZ(mul(set2(pos, cossin(theta)), this.r), this.axis), this.pos); } toHiccup() { return ["path", this.attribs, [ - ["M", pointAt(this, 0)], + ["M", this.pointAtTheta(this.start)], ...this.toHiccupPathSegments() ]]; } @@ -288,7 +446,7 @@ export class Arc2 implements this.axis, this.xl, this.clockwise, - pointAt(this, 1) + this.pointAtTheta(this.end) ]]; } } @@ -325,7 +483,8 @@ export class Circle2 implements } } -export class Cubic2 extends PointContainer { +export class Cubic2 extends PointContainer implements + IHiccupPathSegment { static fromLine(a: Vec, b: Vec, attribs?: Attribs) { return new Cubic2([a, mixNewN(a, b, 1 / 3), mixNewN(b, a, 1 / 3), b], attribs); @@ -401,6 +560,10 @@ export class Group2 implements return Type.GROUP; } + *[Symbol.iterator]() { + yield* this.children; + } + copy() { return new Group2( { ...this.attribs }, @@ -422,7 +585,8 @@ export class Group2 implements } } -export class Line2 extends PointContainer { +export class Line2 extends PointContainer implements + IHiccupPathSegment { constructor(points: Vec[], attribs?: Attribs) { super(Type.LINE2, points, attribs); @@ -431,34 +595,70 @@ export class Line2 extends PointContainer { copy() { return new Line2(this._copy(), { ...this.attribs }); } + + toHiccupPathSegments() { + return [["L", this.points[1]]]; + } + + get a() { + return this.points[0]; + } + + get b() { + return this.points[1]; + } } -export class Quadratic2 extends PointContainer { +export class Path2 implements IShape { - static fromLine(a: Vec, b: Vec, attribs?: Attribs) { - return new Quadratic2([a, mixNewN(a, b, 0.5), b], attribs); + segments: PathSegment[]; + closed: boolean; + attribs: Attribs; + + constructor(segments?: PathSegment[], attribs?: Attribs) { + this.segments = segments || []; + this.attribs = attribs; + this.closed = false; } - constructor(points: Vec[], attribs?: Attribs) { - super(Type.QUADRATIC2, points, attribs); + get type() { + return Type.PATH2; + } + + *[Symbol.iterator]() { + yield* this.segments; } copy() { - return new Quadratic2(this._copy(), { ...this.attribs }); + const p = new Path2([...this.segments], { ...this.attribs }); + p.closed = this.closed; + return p; } - toHiccup() { - return ["path", this.attribs, - [ - ["M", this.points[0]], - ...this.toHiccupPathSegments() - ] - ]; + equiv(o: any) { + return o instanceof Path2 && + equiv(this.segments, o.segments); } - toHiccupPathSegments() { - const pts = this.points; - return [["Q", pts[1], pts[2]]]; + add(s: PathSegment) { + this.segments.push(s); + } + + toHiccup() { + const dest: any[] = []; + const res: any[] = ["path", this.attribs || {}, dest]; + const src = this.segments; + const n = src.length; + if (n > 1) { + dest.push(["M", src[0].point]); + for (let i = 1; i < n; i++) { + dest.push(...src[i].geo.toHiccupPathSegments()); + } + if (this.closed) { + dest.push(["Z"]); + } + } + return res; } } @@ -473,7 +673,8 @@ export class Polygon2 extends PointContainer { } } -export class Polyline2 extends PointContainer { +export class Polyline2 extends PointContainer implements + IHiccupPathSegment { constructor(points: Vec[], attribs?: Attribs) { super(Type.POLYLINE2, points, attribs); @@ -482,20 +683,58 @@ export class Polyline2 extends PointContainer { copy() { return new Polyline2(this._copy(), { ...this.attribs }); } + + toHiccupPathSegments() { + const res: any[] = []; + for (let pts = this.points, n = pts.length, i = 1; i < n; i++) { + res.push(["L", pts[i]]); + } + return res; + } } export class Quad2 extends PointContainer { constructor(points: Vec[], attribs?: Attribs) { - super(Type.POLYGON2, points, attribs); + super(Type.QUAD2, points, attribs); } copy() { return new Quad2(this._copy(), { ...this.attribs }); } - get type() { - return Type.QUAD2; + toHiccup() { + return [Type.POLYGON2, this.attribs, this.points]; + } +} + +export class Quadratic2 extends PointContainer implements + IHiccupPathSegment { + + static fromLine(a: Vec, b: Vec, attribs?: Attribs) { + return new Quadratic2([a, mixNewN(a, b, 0.5), b], attribs); + } + + constructor(points: Vec[], attribs?: Attribs) { + super(Type.QUADRATIC2, points, attribs); + } + + copy() { + return new Quadratic2(this._copy(), { ...this.attribs }); + } + + toHiccup() { + return ["path", this.attribs, + [ + ["M", this.points[0]], + ...this.toHiccupPathSegments() + ] + ]; + } + + toHiccupPathSegments() { + const pts = this.points; + return [["Q", pts[1], pts[2]]]; } } @@ -503,8 +742,10 @@ export class Rect2 implements AABBLike, IShape { - static fromMinMax(min: Vec, max: Vec, attribs?: Attribs) { - return new Rect2(min, subNew(max, min), attribs); + static fromMinMax(mi: Vec, mx: Vec, attribs?: Attribs) { + const _mi = min(copy(mi), mx); + const _mx = max(copy(mx), mi); + return new Rect2(_mi, subNew(_mx, _mi), attribs); } pos: Vec; @@ -539,14 +780,14 @@ export class Rect2 implements export class Triangle2 extends PointContainer { constructor(points: Vec[], attribs?: Attribs) { - super(Type.POLYGON2, points, attribs); + super(Type.TRIANGLE2, points, attribs); } copy() { return new Triangle2(this._copy(), { ...this.attribs }); } - get type() { - return Type.TRIANGLE2; + toHiccup() { + return [Type.POLYGON2, this.attribs, this.points]; } } diff --git a/packages/geom2/src/arc.ts b/packages/geom2/src/arc.ts index af446837e5..840c77baf7 100644 --- a/packages/geom2/src/arc.ts +++ b/packages/geom2/src/arc.ts @@ -2,7 +2,12 @@ import { isNumber } from "@thi.ng/checks/is-number"; import { isPlainObject } from "@thi.ng/checks/is-plain-object"; import { implementations } from "@thi.ng/defmulti"; import { sincos } from "@thi.ng/math/angle"; -import { EPS, HALF_PI, PI, TAU } from "@thi.ng/math/api"; +import { + EPS, + HALF_PI, + PI, + TAU +} from "@thi.ng/math/api"; import { fit01 } from "@thi.ng/math/fit"; import { inRange } from "@thi.ng/math/interval"; import { roundEps } from "@thi.ng/math/prec"; @@ -11,11 +16,21 @@ import { push } from "@thi.ng/transducers/rfn/push"; import { transduce } from "@thi.ng/transducers/transduce"; import { filter } from "@thi.ng/transducers/xform/filter"; import { map } from "@thi.ng/transducers/xform/map"; -import { add, magSq, Vec, ReadonlyVec, abs, mulN, subNew, angleBetween } from "@thi.ng/vectors2/api"; +import { + abs, + add, + angleBetween, + magSq, + mulN, + ReadonlyVec, + subNew, + Vec +} from "@thi.ng/vectors2/api"; import { Vec2 } from "@thi.ng/vectors2/vec2"; import { Arc2, asCubic, + Attribs, bounds, centroid, Cubic2, @@ -24,9 +39,9 @@ import { Rect2, SamplingOpts, Type, - vertices, - Attribs + vertices } from "./api"; +import "./bezier"; import { bounds as _bounds } from "./internal/bounds"; import { Sampler } from "./internal/sampler"; @@ -82,15 +97,15 @@ implementations( Type.ARC2, asCubic, - (x: Arc2) => { - const p = x.pointAtTheta(x.start); - const q = x.pointAtTheta(x.end); - const [rx, ry] = x.r; - const [sphi, cphi] = sincos(x.axis); + (arc: Arc2) => { + const p = arc.pointAtTheta(arc.start); + const q = arc.pointAtTheta(arc.end); + const [rx, ry] = arc.r; + const [sphi, cphi] = sincos(arc.axis); const dx = cphi * (p[0] - q[0]) / 2 + sphi * (p[1] - q[1]) / 2; const dy = -sphi * (p[0] - q[0]) / 2 + cphi * (p[1] - q[1]) / 2; - if ((dx === 0 && dy === 0) || magSq(x.r) < EPS) { - return [Cubic2.fromLine(p, q, { ...x.attribs })]; + if ((dx === 0 && dy === 0) || magSq(arc.r) < EPS) { + return [Cubic2.fromLine(p, q, { ...arc.attribs })]; } const mapP = (x, y) => { @@ -106,7 +121,7 @@ implementations( }; const res: Cubic2[] = []; - const delta = x.end - x.start; + const delta = arc.end - arc.start; const n = Math.max(roundEps(Math.abs(delta) / HALF_PI), 1); // https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/svg/svg_path_parser.cc#L253 const d = delta / n; @@ -114,7 +129,7 @@ implementations( if (!isFinite(t)) { return [Cubic2.fromLine(p, q)]; } - for (let i = n, theta = x.start; i > 0; i-- , theta += d) { + for (let i = n, theta = arc.start; i > 0; i-- , theta += d) { const [s1, c1] = sincos(theta); const [s2, c2] = sincos(theta + d); const curve = new Cubic2( @@ -124,7 +139,7 @@ implementations( mapP(c2 + s2 * t, s2 - c2 * t), mapP(c2, s2), ], - { ...x.attribs } + { ...arc.attribs } ); res.push(curve); } @@ -132,16 +147,16 @@ implementations( }, bounds, - (x: Arc2) => { + (arc: Arc2) => { const pts = transduce( - map(x.pointAtTheta.bind(x)), + map(arc.pointAtTheta.bind(arc)), push(), [ - x.start, - x.end, + arc.start, + arc.end, // multiples of HALF_PI in arc range ...filter( - (t: number) => inRange(t, x.start, x.end), + (t: number) => inRange(t, arc.start, arc.end), range(-3 * PI, 3.01 * PI, HALF_PI) ) ] @@ -150,22 +165,22 @@ implementations( }, centroid, - (x: Arc2) => x.pos, + (arc: Arc2) => arc.pos, pointAt, - (x: Arc2, t: number) => x.pointAtTheta(fit01(t, x.start, x.end)), + (arc: Arc2, t: number) => arc.pointAtTheta(fit01(t, arc.start, arc.end)), vertices, - (x: Arc2, opts?: number | Partial): Vec[] => { + (arc: Arc2, opts?: number | Partial): Vec[] => { if (isPlainObject(opts) && (opts).dist !== undefined) { - return new Sampler(vertices(x, (opts).num || DEFAULT_SAMPLES)) + return new Sampler(vertices(arc, (opts).num || DEFAULT_SAMPLES)) .sampleUniform((opts).dist, (opts).last !== false); } opts = isNumber(opts) ? { num: opts, last: true } : { num: DEFAULT_SAMPLES, ...opts }; - const start = x.start; - let delta = x.end - start; + const start = arc.start; + let delta = arc.end - start; let num = opts.theta ? Math.round(delta / opts.theta) : opts.num; @@ -173,7 +188,7 @@ implementations( opts.last !== false && num++; const pts: Vec[] = new Array(num); for (let i = 0, j = 0; i < num; i++ , j += 2) { - pts[i] = x.pointAtTheta(start + i * delta); + pts[i] = arc.pointAtTheta(start + i * delta); } return pts; } diff --git a/packages/geom2/src/bezier.ts b/packages/geom2/src/bezier.ts index 8917b001d8..953ec1359d 100644 --- a/packages/geom2/src/bezier.ts +++ b/packages/geom2/src/bezier.ts @@ -1,6 +1,6 @@ import { isNumber } from "@thi.ng/checks/is-number"; import { isPlainObject } from "@thi.ng/checks/is-plain-object"; -import { implementations } from "@thi.ng/defmulti"; +import { implementations, relations } from "@thi.ng/defmulti"; import { clamp01 } from "@thi.ng/math/interval"; import { mixCubic as _mixC, mixQuadratic as _mixQ } from "@thi.ng/math/mix"; import { @@ -17,21 +17,35 @@ import { } from "@thi.ng/vectors2/api"; import { compile } from "@thi.ng/vectors2/internal/codegen"; import { vop } from "@thi.ng/vectors2/internal/ops"; +import { Mat23 } from "@thi.ng/vectors2/mat23"; import { asCubic, + asPolyline, Attribs, bounds, Cubic2, DEFAULT_SAMPLES, pointAt, + Polyline2, Quadratic2, Rect2, SamplingOpts, splitAt, + transform, Type, - vertices + vertices, + flip } from "./api"; import { Sampler } from "./internal/sampler"; +import { transformPoints } from "./internal/transform"; + +export function cubic2(points: Vec[], attribs?: Attribs): Cubic2 { + return new Cubic2(points, attribs); +} + +export function quadratic2(points: Vec[], attribs?: Attribs): Quadratic2 { + return new Quadratic2(points, attribs); +} const compileMixQ = (dim: number) => compile( @@ -46,7 +60,7 @@ const compileMixQ = (dim: number) => const compileMixC = (dim: number) => compile( dim, - ([a, b, c, d, o]) => `${o}=${a}*wa + ${b}*wb + ${c}*wc + ${d}*wd;`, + ([a, b, c, d, o]) => `${o} = ${a}*wa + ${b}*wb + ${c}*wc + ${d}*wd;`, "a,b,c,d,t,o=[]", "a,b,c,d,o", "o", @@ -65,9 +79,9 @@ export const mixCubic: MultiVecOpNewVVVVN = vop(); mixCubic.add(2, compileMixC(2)); mixCubic.add(3, compileMixC(3)); mixCubic.default((a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, t: number, o: Vec = []) => { - const t2 = t * t; const s = 1 - t; const s2 = s * s; + const t2 = t * t; return maddN(maddN(maddN(mulNewN(a, s2 * s, o), b, 3 * s2 * t), c, 3 * t2 * s), d, t2 * t); }); @@ -98,26 +112,42 @@ const cubicAxisBounds = (pa: number, pb: number, pc: number, pd: number) => { return [l, h]; }; +relations( + Type.CUBIC2, + { + [Type.POINTS2]: [ + flip, + ] + } +); + implementations( Type.CUBIC2, + asCubic, + (curve: Cubic2) => [curve], + + asPolyline, + (curve: Cubic2, opts?: number | Partial) => + new Polyline2(vertices(curve, opts), { ...curve.attribs }), + bounds, - ($: Cubic2) => { - const [a, b, c, d] = $.points; + (curve: Cubic2) => { + const [a, b, c, d] = curve.points; const x = cubicAxisBounds(a[0], b[0], c[0], d[0]); const y = cubicAxisBounds(a[1], b[1], c[1], d[1]); return Rect2.fromMinMax([x[0], y[0]], [x[1], y[1]]); }, pointAt, - (x: Cubic2, t: number) => { - const pts = x.points; + (curve: Cubic2, t: number) => { + const pts = curve.points; return mixCubic(pts[0], pts[1], pts[2], pts[3], t); }, splitAt, - (x: Cubic2, t: number) => { - const [a, b, c, d] = x.points; + (curve: Cubic2, t: number) => { + const [a, b, c, d] = curve.points; if (t <= 0 || t >= 1) { const p = t <= 0 ? a : d; const c1 = new Cubic2([copy(p), copy(p), copy(p), copy(p)]); @@ -136,10 +166,17 @@ implementations( ]; }, + transform, + (curve: Cubic2, mat: Mat23) => + new Cubic2( + transformPoints(curve.points, mat), + { ...curve.attribs } + ), + vertices, - (x: Cubic2, opts?: number | Partial) => { + (curve: Cubic2, opts?: number | Partial) => { if (isPlainObject(opts) && (opts).dist !== undefined) { - return new Sampler(vertices(x, (opts).num || DEFAULT_SAMPLES)) + return new Sampler(vertices(curve, (opts).num || DEFAULT_SAMPLES)) .sampleUniform((opts).dist, (opts).last !== false); } opts = isNumber(opts) ? @@ -152,7 +189,7 @@ implementations( ...opts }; const res: Vec[] = []; - const [a, b, c, d] = x.points; + const [a, b, c, d] = curve.points; const delta = 1 / opts.num; for (let t = 0; t < opts.num; t++) { res.push(mixCubic(a, b, c, d, t * delta)); @@ -162,12 +199,21 @@ implementations( } ); +relations( + Type.QUADRATIC2, + { + [Type.POINTS2]: [ + flip, + ] + } +); + implementations( Type.QUADRATIC2, asCubic, - (x: Quadratic2) => { - const [a, b, c] = x.points; + (curve: Quadratic2) => { + const [a, b, c] = curve.points; return [ new Cubic2( [ @@ -176,14 +222,18 @@ implementations( mixNewN(c, b, 2 / 3), copy(c) ], - { ...x.attribs } + { ...curve.attribs } ) ]; }, + asPolyline, + (curve: Quadratic2, opts?: number | Partial) => + new Polyline2(vertices(curve, opts), { ...curve.attribs }), + bounds, - (x: Quadratic2) => { - const [a, b, c] = x.points; + (curve: Quadratic2) => { + const [a, b, c] = curve.points; const mi = min(copy(a), c); const ma = max(copy(a), c); const solve = (a, b, c) => { @@ -203,14 +253,14 @@ implementations( }, pointAt, - (x: Quadratic2, t: number) => { - const pts = x.points; + (curve: Quadratic2, t: number) => { + const pts = curve.points; return mixQuadratic(pts[0], pts[1], pts[2], t); }, splitAt, - (x: Quadratic2, t: number) => { - const [a, b, c] = x.points; + (curve: Quadratic2, t: number) => { + const [a, b, c] = curve.points; if (t <= 0 || t >= 1) { const p = t <= 0 ? a : c; const c1 = new Quadratic2([copy(p), copy(p), copy(p), copy(p)]); @@ -226,10 +276,17 @@ implementations( ]; }, + transform, + (curve: Quadratic2, mat: Mat23) => + new Quadratic2( + transformPoints(curve.points, mat), + { ...curve.attribs } + ), + vertices, - (x: Quadratic2, opts?: number | Partial) => { + (curve: Quadratic2, opts?: number | Partial) => { if (isPlainObject(opts) && (opts).dist !== undefined) { - return new Sampler(vertices(x, (opts).num || DEFAULT_SAMPLES)) + return new Sampler(vertices(curve, (opts).num || DEFAULT_SAMPLES)) .sampleUniform((opts).dist, (opts).last !== false); } opts = isNumber(opts) ? @@ -243,7 +300,7 @@ implementations( }; const res: Vec[] = []; const delta = 1 / opts.num; - const [a, b, c] = x.points; + const [a, b, c] = curve.points; for (let t = 0; t < opts.num; t++) { res.push(mixQuadratic(a, b, c, t * delta)); } @@ -252,11 +309,3 @@ implementations( } ); - -export function cubic2(points: Vec[], attribs?: Attribs): Cubic2 { - return new Cubic2(points, attribs); -} - -export function quadratic2(points: Vec[], attribs?: Attribs): Quadratic2 { - return new Quadratic2(points, attribs); -} diff --git a/packages/geom2/src/circle.ts b/packages/geom2/src/circle.ts index 47f3ec9f2c..1728b03d66 100644 --- a/packages/geom2/src/circle.ts +++ b/packages/geom2/src/circle.ts @@ -1,18 +1,26 @@ import { isNumber } from "@thi.ng/checks/is-number"; import { implementations } from "@thi.ng/defmulti"; -import { PI, TAU } from "@thi.ng/math/api"; +import { sign } from "@thi.ng/math/abs"; +import { EPS, PI, TAU } from "@thi.ng/math/api"; import { + add, + addNew, cartesian, + copy, dist, + distSq, mixNewN, + mulN, + normalize, ReadonlyVec, + subNew, subNewN, - Vec, - mulN + Vec } from "@thi.ng/vectors2/api"; import { circumCenter } from "./internal/circumcenter"; +import "./polygon"; import { - arcLength, + perimeter, area, bounds, centroid, @@ -21,9 +29,13 @@ import { Attribs, Rect2, vertices, - Polygon2, - asPolygon, DEFAULT_SAMPLES, + pointAt, + pointInside, + classifyPoint, + closestPoint, + translate, + center, } from "./api"; export function circle(pos: Vec, r = 1, attribs?: Attribs): Circle2 { @@ -46,27 +58,55 @@ implementations( Type.CIRCLE2, area, - (x: Circle2) => PI * x.r * x.r, - - arcLength, - (x: Circle2) => TAU * x.r, - - asPolygon, - (x: Circle2, opts) => - new Polygon2(vertices(x, opts), { ...x.attribs }), + (circle: Circle2) => PI * circle.r * circle.r, bounds, - (x: Circle2) => - new Rect2(subNewN(x.pos, x.r), mulN([2, 2], x.r)), + (circle: Circle2) => + new Rect2(subNewN(circle.pos, circle.r), mulN([2, 2], circle.r)), centroid, - (x: Circle2) => x.pos, + (circle: Circle2) => copy(circle.pos), + + center, + (circle: Circle2, origin?: ReadonlyVec) => + new Circle2( + origin ? origin : [0, 0], + circle.r, + { ...circle.attribs } + ), + + classifyPoint, + (circle: Circle2, p: ReadonlyVec, eps = EPS) => + sign(circle.r - dist(circle.pos, p), eps), + + closestPoint, + (circle: Circle2, p: ReadonlyVec) => + add(normalize(subNew(p, circle.pos), circle.r), circle.pos), + + perimeter, + (circle: Circle2) => TAU * circle.r, + + pointAt, + (circle: Circle2, t: number) => + cartesian([circle.r, TAU * t], circle.pos), + + pointInside, + (circle: Circle2, p: ReadonlyVec) => + distSq(circle.pos, p) <= circle.r * circle.r, + + translate, + (circle: Circle2, delta: ReadonlyVec) => + new Circle2( + addNew(circle.pos, delta), + circle.r, + { ...circle.attribs } + ), vertices, - (x: Circle2, opts = DEFAULT_SAMPLES) => { + (circle: Circle2, opts = DEFAULT_SAMPLES) => { const buf: Vec[] = []; - const pos = x.pos; - const r = x.r; + const pos = circle.pos; + const r = circle.r; let [num, last] = isNumber(opts) ? [opts, false] : [ diff --git a/packages/geom2/src/container2.ts b/packages/geom2/src/container2.ts index c8b6160398..138aae4a96 100644 --- a/packages/geom2/src/container2.ts +++ b/packages/geom2/src/container2.ts @@ -1,17 +1,24 @@ +import { implementations } from "@thi.ng/defmulti"; import { Vec } from "@thi.ng/vectors2/api"; +import { Mat23 } from "@thi.ng/vectors2/mat23"; +import { Vec2 } from "@thi.ng/vectors2/vec2"; import { Attribs, bounds, + centroid, + convexHull, + flip, PointContainer, + Polygon2, Rect2, + transform, Type, - vertices, - centroid + vertices } from "./api"; import { bounds as _bounds } from "./internal/bounds"; import { centroid as _centroid } from "./internal/centroid"; -import { implementations } from "@thi.ng/defmulti"; -import { Vec2 } from "@thi.ng/vectors2/vec2"; +import { grahamScan2 } from "./internal/graham-scan"; +import { transformPoints } from "./internal/transform"; export function points(points: Vec[], attribs?: Attribs) { return new PointContainer(Type.POINTS2, points, attribs); @@ -21,12 +28,27 @@ implementations( Type.POINTS2, bounds, - (x: PointContainer) => - Rect2.fromMinMax(..._bounds(x.points, [...Vec2.MAX], [...Vec2.MIN])), + (pc: PointContainer) => + Rect2.fromMinMax(..._bounds(pc.points, [...Vec2.MAX], [...Vec2.MIN])), centroid, - (x: PointContainer) => _centroid(x.points), + (pc: PointContainer) => _centroid(pc.points), + + convexHull, + (pc: PointContainer) => + new Polygon2(grahamScan2(pc.points), { ...pc.attribs }), + + flip, + (pc: PointContainer) => pc.flip(), + + transform, + (pc: PointContainer, mat: Mat23) => + new PointContainer( + pc.type, + transformPoints(pc.points, mat), + { ...pc.attribs } + ), vertices, - (x: PointContainer) => x.points + (pc: PointContainer) => pc.points ); diff --git a/packages/geom2/src/ellipse.ts b/packages/geom2/src/ellipse.ts index b1d50283c7..74d7566217 100644 --- a/packages/geom2/src/ellipse.ts +++ b/packages/geom2/src/ellipse.ts @@ -1,17 +1,20 @@ import { isNumber } from "@thi.ng/checks/is-number"; import { implementations } from "@thi.ng/defmulti"; -import { sincos } from "@thi.ng/math/angle"; +import { cossin } from "@thi.ng/math/angle"; import { PI, TAU } from "@thi.ng/math/api"; import { - add, - mul, + addNew, + copy, + maddNew, mulNewN, + ones, + ReadonlyVec, subNew, - Vec, - ones + Vec } from "@thi.ng/vectors2/api"; +import "./polygon"; import { - arcLength, + perimeter, area, bounds, centroid, @@ -23,6 +26,9 @@ import { Polygon2, asPolygon, DEFAULT_SAMPLES, + pointAt, + center, + translate, } from "./api"; export function ellipse(pos: Vec, r = ones(2), attribs?: Attribs): Ellipse2 { @@ -33,31 +39,51 @@ implementations( Type.ELLIPSE2, area, - (x: Ellipse2) => PI * x.r[0] * x.r[1], - - arcLength, - (x: Ellipse2) => { - const a = x.r[0]; - const b = x.r[1]; - return PI * (3 * (a + b) - Math.sqrt((3 * a + b) * (3 * b + a))); - }, + (ellipse: Ellipse2) => PI * ellipse.r[0] * ellipse.r[1], asPolygon, - (x: Ellipse2, opts) => - new Polygon2(vertices(x, opts), { ...x.attribs }), + (ellipse: Ellipse2, opts) => + new Polygon2(vertices(ellipse, opts), { ...ellipse.attribs }), bounds, - (x: Ellipse2) => - new Rect2(subNew(x.pos, x.r), mulNewN(x.r, 2)), + (ellipse: Ellipse2) => + new Rect2(subNew(ellipse.pos, ellipse.r), mulNewN(ellipse.r, 2)), centroid, - (x: Ellipse2) => x.pos, + (ellipse: Ellipse2) => copy(ellipse.pos), + + center, + (ellipse: Ellipse2, origin?: ReadonlyVec) => + new Ellipse2( + origin ? origin : [0, 0], + copy(ellipse.r), + { ...ellipse.attribs } + ), + + perimeter, + (ellipse: Ellipse2) => { + const a = ellipse.r[0]; + const b = ellipse.r[1]; + return PI * (3 * (a + b) - Math.sqrt((3 * a + b) * (3 * b + a))); + }, + + pointAt, + (ellipse: Ellipse2, t: number) => + maddNew(ellipse.pos, cossin(t * TAU), ellipse.r), + + translate, + (ellipse: Ellipse2, delta: ReadonlyVec) => + new Ellipse2( + addNew(ellipse.pos, delta), + ellipse.r, + { ...ellipse.attribs } + ), vertices, - (x: Ellipse2, opts = DEFAULT_SAMPLES) => { + (ellipse: Ellipse2, opts = DEFAULT_SAMPLES) => { const buf: Vec[] = []; - const pos = x.pos; - const r = x.r; + const pos = ellipse.pos; + const r = ellipse.r; let [num, last] = isNumber(opts) ? [opts, false] : [ @@ -69,7 +95,7 @@ implementations( const delta = TAU / num; last && num++; for (let i = 0; i < num; i++) { - buf[i] = add(mul(sincos(i * delta), r), pos); + buf[i] = maddNew(pos, cossin(i * delta), r); } return buf; } diff --git a/packages/geom2/src/group.ts b/packages/geom2/src/group.ts index 8307d85561..5ffc313489 100644 --- a/packages/geom2/src/group.ts +++ b/packages/geom2/src/group.ts @@ -3,6 +3,7 @@ import { area, Attribs, bounds, + centroid, Group2, IShape, Type @@ -21,4 +22,7 @@ implementations( bounds, (g: Group2) => collBounds(g.children), + + centroid, + (g: Group2) => centroid(bounds(g)), ); diff --git a/packages/geom2/src/index.ts b/packages/geom2/src/index.ts index cf7fcdb2c1..d25bb8920e 100644 --- a/packages/geom2/src/index.ts +++ b/packages/geom2/src/index.ts @@ -5,10 +5,13 @@ export * from "./circle"; export * from "./container2"; export * from "./ellipse"; export * from "./group"; +export * from "./line"; +export * from "./path"; export * from "./polygon"; export * from "./polyline"; export * from "./quad"; export * from "./rect"; +export * from "./triangle"; export * from "./svg"; export * from "./tessellate"; diff --git a/packages/geom2/src/internal/arc-length.ts b/packages/geom2/src/internal/arc-length.ts deleted file mode 100644 index 8495fbd5f8..0000000000 --- a/packages/geom2/src/internal/arc-length.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { dist, ReadonlyVec } from "@thi.ng/vectors2/api"; - -export const arcLength = (pts: ReadonlyVec[], closed = false) => { - const num = pts.length; - if (num < 2) return 0; - let res = 0; - let p = pts[0]; - let q = pts[1]; - for (let i = 1; i < num; i++ , p = q, q = pts[i]) { - res += dist(p, q); - } - closed && (res += dist(p, pts[0])); - return res; -}; diff --git a/packages/geom2/src/internal/arc.ts b/packages/geom2/src/internal/arc.ts new file mode 100644 index 0000000000..aa83e0b555 --- /dev/null +++ b/packages/geom2/src/internal/arc.ts @@ -0,0 +1,24 @@ +import { TAU } from "@thi.ng/math/api"; +import { atan2Abs, cossin } from "@thi.ng/math/angle"; +import { ReadonlyVec, Vec, maddNew } from "@thi.ng/vectors2/api"; + +export const arcVertices = ( + o: ReadonlyVec, + a: ReadonlyVec, + b: ReadonlyVec, + r: ReadonlyVec, + verts: Vec[] = [], + outwards = false, + res = 8) => { + + const ta = atan2Abs(a[1] - o[1], a[0] - o[0]); + const tb = atan2Abs(b[1] - o[1], b[0] - o[0]); + const theta = ta > tb ? ta - tb : ta + TAU - tb; + const ts = (outwards ? -theta : TAU - theta) / res; + verts.push(a); + for (let i = 1; i < res; i++) { + verts.push(maddNew(o, cossin(ta + ts * i), r)); + } + verts.push(b); + return verts; +}; diff --git a/packages/geom2/src/internal/area.ts b/packages/geom2/src/internal/area.ts deleted file mode 100644 index 47b75aeb20..0000000000 --- a/packages/geom2/src/internal/area.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { ReadonlyVec } from "@thi.ng/vectors2/api"; -import { cross2 } from "@thi.ng/vectors2/vec2"; - -export const polygonArea = (pts: ReadonlyVec[]) => { - let res = 0; - for (let n = pts.length - 1, i = n, j = 0; n >= 0; i = j, j++ , n--) { - res += cross2(pts[i], pts[j]); - } - return res / 2; -}; diff --git a/packages/geom2/src/internal/barycentric.ts b/packages/geom2/src/internal/barycentric.ts index 65b395400f..d73b9d0916 100644 --- a/packages/geom2/src/internal/barycentric.ts +++ b/packages/geom2/src/internal/barycentric.ts @@ -1,30 +1,35 @@ import { dot, maddN, - magSq, mulNewN, ReadonlyVec, setS, subNew, - Vec + Vec, + zero } from "@thi.ng/vectors2/api"; +import { eqDelta } from "@thi.ng/math/eqdelta"; export const toBarycentric = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, p: ReadonlyVec, out: Vec) => { + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, p: ReadonlyVec, out: Vec = []) => { const u = subNew(b, a); const v = subNew(c, a); const w = subNew(p, a); - const uu = magSq(u); - const vv = magSq(v); - const uv = dot(u, v); - const uw = dot(u, w); - const vw = dot(v, w); - const d = 1 / (uv * uv - uu * vv); - const s = d * (uv * vw - vv * uw); - const t = d * (uv * uw - uu * vw); + const d00 = dot(u, u); + const d01 = dot(u, v); + const d11 = dot(v, v); + const d20 = dot(w, u); + const d21 = dot(w, v); + const denom = d00 * d11 - d01 * d01; - return setS(out, 1 - (s + t), s, t); + if (eqDelta(denom, 0)) { + return zero(out); + } + + const s = (d11 * d20 - d01 * d21) / denom; + const t = (d00 * d21 - d01 * d20) / denom; + return setS(out, 1 - s - t, s, t); }; export const fromBarycentric = diff --git a/packages/geom2/src/internal/bounds.ts b/packages/geom2/src/internal/bounds.ts index bb341ca08c..c89c1d13e1 100644 --- a/packages/geom2/src/internal/bounds.ts +++ b/packages/geom2/src/internal/bounds.ts @@ -25,7 +25,7 @@ export const collBounds = let n = shapes.length - 1; let res: IShape = n >= 0 ? _bounds(shapes[n]) : undefined; for (; --n >= 0;) { - res = union(res, _bounds(shapes[n])); + res = union(res, _bounds(shapes[n]))[0]; } return res; }; diff --git a/packages/geom2/src/internal/centroid.ts b/packages/geom2/src/internal/centroid.ts index d44a3cc3b8..7e973a7b5b 100644 --- a/packages/geom2/src/internal/centroid.ts +++ b/packages/geom2/src/internal/centroid.ts @@ -1,29 +1,38 @@ import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { ReadonlyVec, Vec, empty, add, divN, setS } from "@thi.ng/vectors2/api"; +import { + add, + divN, + empty, + ReadonlyVec, + setS, + Vec +} from "@thi.ng/vectors2/api"; import { cross2 } from "@thi.ng/vectors2/vec2"; -export const centroid = (pts: ReadonlyVec[], c?: Vec) => { - const num = pts.length; - !num && illegalArgs("no points available"); - !c && (c = empty(pts[0])); - for (let i = num; --i >= 0;) { - add(c, pts[i]); - } - return divN(c, num); -}; +export const centroid = + (pts: ReadonlyVec[], c?: Vec) => { + const num = pts.length; + !num && illegalArgs("no points available"); + !c && (c = empty(pts[0])); + for (let i = num; --i >= 0;) { + add(c, pts[i]); + } + return divN(c, num); + }; -export const centerOfWeight2 = (pts: ReadonlyVec[], c?: Vec) => { - let area = 0; - let x = 0; - let y = 0; - for (let n = pts.length - 1, i = pts[n], j = pts[0], k = 0; k <= n; k++ , i = j, j = pts[k]) { - const z = cross2(i, j); - area += z; - x += (i[0] + j[0]) * z; - y += (i[1] + j[1]) * z; - } - area = 1 / (area * 3); - x *= area; - y *= area; - return c ? setS(c, x, y) : [x, y]; -}; +export const centerOfWeight2 = + (pts: ReadonlyVec[], c?: Vec) => { + let area = 0; + let x = 0; + let y = 0; + for (let n = pts.length - 1, i = pts[n], j = pts[0], k = 0; k <= n; k++ , i = j, j = pts[k]) { + const z = cross2(i, j); + area += z; + x += (i[0] + j[0]) * z; + y += (i[1] + j[1]) * z; + } + area = 1 / (area * 3); + x *= area; + y *= area; + return c ? setS(c, x, y) : [x, y]; + }; diff --git a/packages/geom2/src/internal/closest-point.ts b/packages/geom2/src/internal/closest-point.ts index 36b10621d6..047a28a185 100644 --- a/packages/geom2/src/internal/closest-point.ts +++ b/packages/geom2/src/internal/closest-point.ts @@ -7,7 +7,7 @@ import { ReadonlyVec, set, subNew, - Vec + Vec, } from "@thi.ng/vectors2/api"; export const closestPoint = @@ -35,11 +35,24 @@ export const closestCoeff = } }; +/** + * Returns closest point to `p` on segment `a` -> `b`. By default, if + * the result point lies outside the segment, returns a copy of the + * closest end point. However, if `insideOnly` is true, only returns the + * closest point if it actually is inside the segment (incl. end + * points). + * + * @param p + * @param a + * @param b + * @param out + */ export const closestPointSegment = - (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, out: Vec) => { + (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, out?: Vec, insideOnly = false) => { const t = closestCoeff(p, a, b); - if (t !== undefined) { + if (t !== undefined && (!insideOnly || t >= 0 && t <= 1)) { + out = out || empty(p); return t <= 0.0 ? set(out, a) : t >= 1.0 ? diff --git a/packages/geom2/src/internal/corner.ts b/packages/geom2/src/internal/corner.ts index 1fe380bb8c..5479545c0f 100644 --- a/packages/geom2/src/internal/corner.ts +++ b/packages/geom2/src/internal/corner.ts @@ -1,8 +1,13 @@ import { sign } from "@thi.ng/math/abs"; import { EPS } from "@thi.ng/math/api"; -import { ReadonlyVec } from "@thi.ng/vectors2/api"; +import { + dot, + magSq, + mulNewN, + ReadonlyVec +} from "@thi.ng/vectors2/api"; -export const corner = +export const signedArea = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => { const ax = a[0]; const ay = a[1]; @@ -11,20 +16,20 @@ export const corner = export const classify = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, eps = EPS) => - sign(corner(a, b, c), eps); + sign(signedArea(a, b, c), eps); export const clockwise2 = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => - corner(a, b, c) < 0; + signedArea(a, b, c) < 0; export const classifyPointInTriangle2 = (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => { const s = clockwise2(a, b, c) ? 1 : -1; return sign( Math.min( - s * corner(a, c, p), - s * corner(b, a, p), - s * corner(c, b, p) + s * signedArea(a, c, p), + s * signedArea(b, a, p), + s * signedArea(c, b, p) ) ); }; @@ -32,7 +37,19 @@ export const classifyPointInTriangle2 = export const pointInTriangle2 = (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => { const s = clockwise2(a, b, c) ? 1 : -1; - return s * corner(a, c, p) >= 0 && - s * corner(b, a, p) >= 0 && - s * corner(c, b, p) >= 0; + return s * signedArea(a, c, p) >= 0 && + s * signedArea(b, a, p) >= 0 && + s * signedArea(c, b, p) >= 0; }; + +/** + * Returns vector projection of `v` onto `dir`. + * + * https://en.wikipedia.org/wiki/Vector_projection + * + * @param dir + * @param v + */ +export const project = + (dir: ReadonlyVec, v: ReadonlyVec) => + mulNewN(dir, dot(v, dir) / magSq(dir)); diff --git a/packages/geom2/src/internal/direction.ts b/packages/geom2/src/internal/direction.ts new file mode 100644 index 0000000000..a5418a08dc --- /dev/null +++ b/packages/geom2/src/internal/direction.ts @@ -0,0 +1,14 @@ +import { ReadonlyVec, normalize, subNew } from "@thi.ng/vectors2/api"; +import { perpendicularLeft2, perpendicularRight2 } from "@thi.ng/vectors2/vec2"; + +export const direction = + (a: ReadonlyVec, b: ReadonlyVec, n = 1) => + normalize(subNew(b, a), n); + +export const normalL2 = + (a: ReadonlyVec, b: ReadonlyVec, n = 1) => + perpendicularLeft2(direction(a, b, n)); + +export const normalR2 = + (a: ReadonlyVec, b: ReadonlyVec, n = 1) => + perpendicularRight2(direction(a, b, n)); diff --git a/packages/geom2/src/internal/edges.ts b/packages/geom2/src/internal/edges.ts new file mode 100644 index 0000000000..df255610c8 --- /dev/null +++ b/packages/geom2/src/internal/edges.ts @@ -0,0 +1,12 @@ +import { wrap } from "@thi.ng/transducers/iter/wrap"; +import { partition } from "@thi.ng/transducers/xform/partition"; +import { VecPair } from "../api"; +import { Vec } from "@thi.ng/vectors2/api"; + +export const edges = (vertices: Iterable, closed = false) => + >partition( + 2, 1, + closed ? + wrap(vertices, 1, false, true) : + vertices + ); diff --git a/packages/geom2/src/internal/graham-scan.ts b/packages/geom2/src/internal/graham-scan.ts index 9d0eb6d0c5..a132ceb817 100644 --- a/packages/geom2/src/internal/graham-scan.ts +++ b/packages/geom2/src/internal/graham-scan.ts @@ -1,5 +1,5 @@ import { Vec } from "@thi.ng/vectors2/api"; -import { corner } from "./corner"; +import { signedArea } from "./corner"; import { comparator2 } from "@thi.ng/vectors2/vec2"; /** @@ -18,7 +18,7 @@ export const grahamScan2 = pts = pts.slice().sort(comparator2(0, 1)); const scan = (p: Vec, thresh: number) => { - while (h >= thresh && corner(res[h - 2], res[h - 1], p) >= 0) { + while (h >= thresh && signedArea(res[h - 2], res[h - 1], p) >= 0) { res.pop(); h--; } diff --git a/packages/geom2/src/internal/greiner-hormann.ts b/packages/geom2/src/internal/greiner-hormann.ts new file mode 100644 index 0000000000..fd3e9774b6 --- /dev/null +++ b/packages/geom2/src/internal/greiner-hormann.ts @@ -0,0 +1,307 @@ +import { ICopy } from "@thi.ng/api/api"; +import { equivArrayLike } from "@thi.ng/equiv"; +import { mapcat } from "@thi.ng/transducers/xform/mapcat"; +import { Vec } from "@thi.ng/vectors2/api"; +import { ClipMode, LineIntersectionType, VecPair } from "../api"; +import { edges as _edges } from "./edges"; +import { intersectLines2 } from "./line-intersection"; +import { pointInside, polygonArea } from "./polygon"; + +export const enum VertexFlag { + ISEC = 1, + ENTRY = 2, + VISITED = 4 +} + +export class ClipVertex implements + ICopy { + + pos: Vec; + next: ClipVertex; + prev: ClipVertex; + pair: ClipVertex; + flags: VertexFlag; + dist: number; + + constructor(pos: Vec, dist = 0, flags = VertexFlag.ENTRY) { + this.pos = pos; + this.dist = dist; + this.flags = flags; + this.next = this.prev = this.pair = null; + } + + copy() { + return new ClipVertex(this.pos); + } + + equiv(v: any) { + return v && equivArrayLike(this.pos, v.pos); + } + + reset() { + this.flags = VertexFlag.ENTRY; + this.pair = null; + this.dist = 0; + return this; + } + + visit() { + this.flags |= VertexFlag.VISITED; + this.pair && (this.pair.flags |= VertexFlag.VISITED); + } + + nextNonIntersecting() { + let v: ClipVertex = this; + while (v.flags & VertexFlag.ISEC) { + v = v.next; + } + return v; + } +} + +export class ClipPolygon implements + ICopy { + + protected first: ClipVertex; + protected firstIsec: ClipVertex; + protected lastProc: ClipVertex; + protected length: number; + protected clockwise: boolean; + + constructor(points: Vec[], orient = true) { + if (orient && polygonArea(points) > 0) { + points = points.slice().reverse(); + } + this.first = this.firstIsec = this.lastProc = null; + this.length = 0; + const n = points.length; + for (let i = 0; i < n; i++) { + this.addVertex(points[i]); + } + } + + copy() { + return new ClipPolygon(this.vertices()); + } + + addVertex(p: Vec) { + const v = new ClipVertex(p); + if (this.first) { + const next = this.first; + const prev = next.prev; + next.prev = v; + v.next = next; + v.prev = prev; + prev.next = v; + } else { + this.first = v; + v.next = v.prev = v; + } + this.length++; + } + + insertVertex(v: ClipVertex, start: ClipVertex, end: ClipVertex) { + let curr = start; + while (curr !== end && curr.dist < v.dist) { + curr = curr.next; + } + v.next = curr; + const prev = curr.prev; + v.prev = prev; + prev.next = v; + curr.prev = v; + this.length++; + } + + removeVertex(v: ClipVertex) { + if (this.first === v) { + if (this.length === 1) { + this.first = null; + this.length = 0; + return; + } + this.first = v.next; + } + this.firstIsec === v && (this.firstIsec = null); + this.lastProc === v && (this.lastProc = null); + v.prev.next = v.next; + v.next.prev = v.prev; + this.length--; + } + + edges() { + const edges: VecPair[] = []; + const f = this.first; + let v = f; + do { + edges.push([v.pos, v.next.pos]); + v = v.next; + } while (v !== f); + return edges; + } + + vertices() { + const vertices: Vec[] = []; + const f = this.first; + let v = f; + do { + vertices.push(v.pos); + v = v.next; + } while (v !== f); + return vertices; + } + + clip(clip: ClipPolygon, mode: ClipMode) { + this.insertIntersections(clip); + const sinc = clip.pointInside(this.first.pos); + const cins = this.pointInside(clip.first.pos); + this.markEntryVertices(((mode & 1) ^ sinc) > 0); + clip.markEntryVertices((((mode >> 1) & 1) ^ cins) > 0); + const res = this.buildClipPolys(); + if (res.length === 0) { + switch (mode) { + case ClipMode.UNION: + if (sinc) { res.push(clip); } + else if (cins) { res.push(this); } + else { res.push(this, clip); } + break; + case ClipMode.INTERSECTION: + if (sinc) { res.push(this); } + else if (cins) { res.push(clip); } + break; + default: + if (sinc) { res.push(clip, this); } + else if (cins) { res.push(this, clip); } + else { res.push(this); } + } + } + return res; + } + + reset() { + const f = this.first; + let v = f; + do { + v = v.reset().next; + } while (v !== f); + } + + pointInside(p: Vec) { + const f = this.first; + const x = p[0]; + const y = p[1]; + let v = f; + let n = v.next; + let inside = 0; + do { + inside = pointInside(v.pos, n.pos, x, y, inside); + v = n; + n = n.next || f; + } while (v !== f); + return inside; + } + + + + protected insertIntersections(clip: ClipPolygon) { + let s = this.first; + let c = clip.first; + do { + if (!(s.flags & VertexFlag.ISEC)) { + do { + if (!(c.flags & VertexFlag.ISEC)) { + const ns = s.next.nextNonIntersecting(); + const nc = c.next.nextNonIntersecting(); + const i = intersectLines2(s.pos, ns.pos, c.pos, nc.pos); + if (i && i.type === LineIntersectionType.INTERSECT) { + const is = new ClipVertex(i.isec, i.alpha, VertexFlag.ISEC); + const ic = new ClipVertex(i.isec, i.beta, VertexFlag.ISEC); + is.pair = ic; + ic.pair = is; + this.insertVertex(is, s, ns); + clip.insertVertex(ic, c, nc); + } + } + c = c.next; + } while (c !== clip.first); + } + s = s.next; + } while (s !== this.first); + } + + protected markEntryVertices(state: boolean) { + const f = this.first; + let v = f; + do { + if (v.flags & VertexFlag.ISEC) { + v.flags = state ? + (v.flags | VertexFlag.ENTRY) : + (v.flags & (~VertexFlag.ENTRY)); + state = !state; + } + v = v.next; + } while (v !== f); + } + + protected buildClipPolys() { + const res: ClipPolygon[] = []; + while (this.hasUnprocessed()) { + let curr = this.findfirstIntersection(); + const clipped = new ClipPolygon([curr.pos]); + do { + curr.visit(); + if (curr.flags & VertexFlag.ENTRY) { + do { + curr = curr.next; + clipped.addVertex(curr.pos); + } while (!(curr.flags & VertexFlag.ISEC)); + } else { + do { + curr = curr.prev; + clipped.addVertex(curr.pos); + } while (!(curr.flags & VertexFlag.ISEC)); + } + curr = curr.pair; + } while (curr.flags < VertexFlag.VISITED); + clipped.removeVertex(clipped.first.prev); + // TODO only return vertices? + res.push(clipped); + } + return res; + } + + protected findfirstIntersection() { + const f = this.first; + let v = this.firstIsec || f; + do { + if (v.flags < VertexFlag.VISITED && (v.flags & VertexFlag.ISEC)) { + break; + } + v = v.next; + } while (v !== f); + this.firstIsec = v; + return v; + } + + protected hasUnprocessed() { + const f = this.first; + let v = this.lastProc || f; + do { + if (v.flags < VertexFlag.VISITED && (v.flags & VertexFlag.ISEC)) { + this.lastProc = v; + return true; + } + v = v.next; + } while (v !== f); + this.lastProc = null; + return false; + } +}; + +export const booleanOp = (a: Vec[][], b: Vec[], mode: ClipMode, orient = true) => + [...mapcat( + (a) => + new ClipPolygon(a, orient) + .clip(new ClipPolygon(b, orient), mode) + .map((c) => c.vertices()), + a)]; diff --git a/packages/geom2/src/internal/line-intersection.ts b/packages/geom2/src/internal/line-intersection.ts index 6abb57fade..6f8f5704ec 100644 --- a/packages/geom2/src/internal/line-intersection.ts +++ b/packages/geom2/src/internal/line-intersection.ts @@ -1,7 +1,16 @@ import { LineIntersection, LineIntersectionType } from "../api"; import { ReadonlyVec, mixNewN } from "@thi.ng/vectors2/api"; +import { EPS } from "@thi.ng/math/api"; +import { eqDelta } from "@thi.ng/math/eqdelta"; +import { closestPointSegment } from "./closest-point"; + +export const intersectLines2 = ( + a: ReadonlyVec, + b: ReadonlyVec, + c: ReadonlyVec, + d: ReadonlyVec, + eps = EPS): LineIntersection => { -export const intersectLines2 = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec) => { const bax = b[0] - a[0]; const bay = b[1] - a[1]; const dcx = d[0] - c[0]; @@ -11,16 +20,24 @@ export const intersectLines2 = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, const det = dcy * bax - dcx * bay; let alpha = dcx * acy - dcy * acx; let beta = bax * acy - bay * acx; - if (det === 0) { - if (alpha === 0 && beta === 0) { - return { type: LineIntersectionType.COINCIDENT }; + if (eqDelta(det, 0, eps)) { + if (eqDelta(alpha, 0, eps) && eqDelta(beta, 0, eps)) { + let isec = closestPointSegment(c, a, b, undefined, true) || + closestPointSegment(d, a, b, undefined, true); + return { + isec, + type: isec ? + LineIntersectionType.COINCIDENT : + LineIntersectionType.COINCIDENT_NO_INTERSECT, + }; } return { type: LineIntersectionType.PARALLEL }; } alpha /= det; beta /= det; - return { - type: (0 <= alpha && alpha <= 1) && (0 <= beta && beta <= 1) ? + const ieps = 1 - eps; + return { + type: (eps < alpha && alpha < ieps) && (eps < beta && beta < ieps) ? LineIntersectionType.INTERSECT : LineIntersectionType.INTERSECT_OUTSIDE, isec: mixNewN(a, b, alpha), diff --git a/packages/geom2/src/internal/offset.ts b/packages/geom2/src/internal/offset.ts new file mode 100644 index 0000000000..396fcc075c --- /dev/null +++ b/packages/geom2/src/internal/offset.ts @@ -0,0 +1,49 @@ +import { addNew, subNew, Vec } from "@thi.ng/vectors2/api"; +import { ClipMode, VecPair } from "../api"; +import { arcVertices } from "./arc"; +import { normalL2 } from "./direction"; +import { edges as _edges } from "./edges"; +import { booleanOp } from "./greiner-hormann"; +import { polygonArea } from "./polygon"; + +export const offset = (points: Vec[], dist: number, res = 8, closed = true) => { + if (!closed && dist < 0) return; + polygonArea(points) > 0 && (points = [...points].reverse()); + const contours = offsetEdges(_edges(points, closed), Math.abs(dist), res); + if (contours.length > 0) { + const a1 = Math.abs(polygonArea(contours[0])); + const a2 = Math.abs(polygonArea(contours[1])); + return contours[ + dist > 0 ? + a1 > a2 ? 0 : 1 : + a1 > a2 ? 1 : 0 + ]; + } +}; + +/** + * + * @param edges + * @param dist + * @param res + */ +export const offsetEdges = (edges: Iterable, dist: number, res: number) => { + let result: Vec[][]; + for (let e of edges) { + const seg = offsetLine(e, dist, res); + result = result ? + booleanOp(result, seg, ClipMode.UNION, false) : + [seg]; + } + return result; +}; + +export const offsetLine = ([ea, eb]: VecPair, dist: number, res: number) => { + const verts: Vec[] = []; + const r = [dist, dist]; + const n = normalL2(ea, eb, dist); + const e1 = [addNew(ea, n), addNew(eb, n)]; + const e2 = [subNew(eb, n), subNew(ea, n)]; + arcVertices(ea, e2[1], e1[0], r, verts, true, res); + return arcVertices(eb, e1[1], e2[0], r, verts, true, res); +}; diff --git a/packages/geom2/src/internal/perimeter.ts b/packages/geom2/src/internal/perimeter.ts new file mode 100644 index 0000000000..def47278b2 --- /dev/null +++ b/packages/geom2/src/internal/perimeter.ts @@ -0,0 +1,15 @@ +import { dist, ReadonlyVec } from "@thi.ng/vectors2/api"; + +export const perimeter = + (pts: ReadonlyVec[], closed = false) => { + const num = pts.length; + if (num < 2) return 0; + let res = 0; + let p = pts[0]; + let q = pts[1]; + for (let i = 1; i < num; i++ , p = q, q = pts[i]) { + res += dist(p, q); + } + closed && (res += dist(p, pts[0])); + return res; + }; diff --git a/packages/geom2/src/internal/polygon.ts b/packages/geom2/src/internal/polygon.ts new file mode 100644 index 0000000000..b604886066 --- /dev/null +++ b/packages/geom2/src/internal/polygon.ts @@ -0,0 +1,21 @@ +import { ReadonlyVec } from "@thi.ng/vectors2/api"; +import { cross2 } from "@thi.ng/vectors2/vec2"; + +export const polygonArea = + (pts: ReadonlyVec[]) => { + let res = 0; + for (let n = pts.length - 1, i = n, j = 0; n >= 0; i = j, j++ , n--) { + res += cross2(pts[i], pts[j]); + } + return res / 2; + }; + +export const pointInside = + (a: ReadonlyVec, b: ReadonlyVec, x: number, y: number, inside: number) => { + if (((a[1] < y && b[1] >= y) || + (b[1] < y && a[1] >= y)) && + (a[0] <= x || b[0] <= x)) { + inside ^= (((a[0] + (y - a[1]) / (b[1] - a[1]) * (b[0] - a[0])) < x) ? 1 : 0); + } + return inside; + }; diff --git a/packages/geom2/src/internal/sampler.ts b/packages/geom2/src/internal/sampler.ts index 830b9acb33..69bda6d4b7 100644 --- a/packages/geom2/src/internal/sampler.ts +++ b/packages/geom2/src/internal/sampler.ts @@ -4,8 +4,11 @@ import { dist, mixNewN, ReadonlyVec, - Vec + Vec, + subNew, + normalize } from "@thi.ng/vectors2/api"; +import { VecPair } from "../api"; export class Sampler { @@ -43,8 +46,46 @@ export class Sampler { } } + segmentAt(t: number): VecPair { + let i = this.indexAt(t); + if (i === undefined) { + return; + } + i = Math.max(1, i); + return [this.points[i - 1], this.points[i]]; + } + + tangentAt(t: number, n = 1) { + const seg = this.segmentAt(t); + return seg ? + normalize(subNew(seg[1], seg[0]), n) : + undefined; + } + + indexAt(t: number) { + const pts = this.points; + const n = pts.length - 1; + if (n < 0) { + return; + } + if (n === 0 || t <= 0) { + return 0; + } + if (t >= 1) { + return n; + } + const idx = this.index; + const t0 = t * idx[n]; + for (let i = 1; i <= n; i++) { + if (idx[i] >= t0) { + return i; + } + } + } + sampleUniform(dist: number, includeLast = false, result: Vec[] = []) { const index = this.index; + const pts = this.points; const total = peek(index); const delta = dist / total; const n = index.length; @@ -53,10 +94,10 @@ export class Sampler { while (ct >= index[i] && i < n) { i++; } if (i >= n) break; const p = index[i - 1]; - result.push(mixNewN(this.points[i - 1], this.points[i], (ct - p) / (index[i] - p))); + result.push(mixNewN(pts[i - 1], pts[i], (ct - p) / (index[i] - p))); } if (includeLast) { - result.push(copy(this.points[this.points.length - 1])); + result.push(copy(peek(pts))); } return result; } diff --git a/packages/geom2/src/internal/subdiv-curve.ts b/packages/geom2/src/internal/subdiv-curve.ts new file mode 100644 index 0000000000..3e3a73c7aa --- /dev/null +++ b/packages/geom2/src/internal/subdiv-curve.ts @@ -0,0 +1,79 @@ +import { comp } from "@thi.ng/transducers/func/comp"; +import { wrap } from "@thi.ng/transducers/iter/wrap"; +import { push } from "@thi.ng/transducers/rfn/push"; +import { transduce } from "@thi.ng/transducers/transduce"; +import { indexed } from "@thi.ng/transducers/xform/indexed"; +import { mapcat } from "@thi.ng/transducers/xform/mapcat"; +import { partition } from "@thi.ng/transducers/xform/partition"; +import { + maddN, + mulNewN, + ReadonlyVec, + Vec +} from "@thi.ng/vectors2/api"; +import { SubdivKernel } from "../api"; + +const madd2 = + (a: ReadonlyVec, b: ReadonlyVec, ua: number, ub: number) => + maddN(mulNewN(a, ua), b, ub); + +const madd3 = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, ua: number, ub: number, uc: number) => + maddN(maddN(mulNewN(a, ua), b, ub), c, uc); + +const madd5 = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, e: ReadonlyVec, + ua: number, ub: number, uc: number, ud: number, ue: number) => + maddN(maddN(maddN(maddN(mulNewN(a, ua), b, ub), c, uc), d, ud), e, ue); + +export const subdivKernel2 = + ([ua, ub]: number[], [va, vb]: number[]) => + ([a, b]: ReadonlyVec[]) => [ + madd2(a, b, ua, ub), + madd2(a, b, va, vb), + ]; + +export const subdivKernel3 = + ([ua, ub, uc]: number[], [va, vb, vc]: number[]) => + ([a, b, c]: ReadonlyVec[]) => [ + madd3(a, b, c, ua, ub, uc), + madd3(a, b, c, va, vb, vc), + ]; + +export const subdivKernel5 = + ([ua, ub, uc, ud, ue]: number[], [va, vb, vc, vd, ve]: number[]) => + ([a, b, c, d, e]: ReadonlyVec[]) => [ + madd5(a, b, c, d, e, ua, ub, uc, ud, ue), + madd5(a, b, c, d, e, va, vb, vc, vd, ve), + ]; + +/** + * http://algorithmicbotany.org/papers/subgpu.sig2003.pdf + * + * @param kernel subdivision scheme + * @param pts source points + * @param iter number of iterations + * @param closed true, if closed input geometry + */ +export const subdivideCurve = ( + { fn, size }: SubdivKernel, + pts: ReadonlyVec[], + iter = 1, + closed = false) => { + + while (--iter >= 0) { + const nump = pts.length; + pts = transduce( + comp( + partition(size, 1), + indexed(), + mapcat(([i, pts]) => fn(pts, i, nump)) + ), + push(), + closed ? + wrap(pts, size >> 1, true, true) : + pts + ); + } + return pts; +}; diff --git a/packages/geom2/src/internal/transform.ts b/packages/geom2/src/internal/transform.ts new file mode 100644 index 0000000000..fd11e1b866 --- /dev/null +++ b/packages/geom2/src/internal/transform.ts @@ -0,0 +1,4 @@ +import { IMatrix, ReadonlyVec } from "@thi.ng/vectors2/api"; + +export const transformPoints = (pts: ReadonlyVec[], mat: IMatrix) => + pts.map((p) => mat.mulV(p)); diff --git a/packages/geom2/src/internal/warp.ts b/packages/geom2/src/internal/warp.ts new file mode 100644 index 0000000000..121212aa65 --- /dev/null +++ b/packages/geom2/src/internal/warp.ts @@ -0,0 +1,6 @@ +import { ReadonlyVec } from "@thi.ng/vectors2/api"; +import { IShape, mapPoint, unmapPoint } from "../api"; + +export const warpPoints = + (src: ReadonlyVec[], srcBounds: IShape, dest: IShape) => + src.map((p) => unmapPoint(dest, mapPoint(srcBounds, p))); diff --git a/packages/geom2/src/line.ts b/packages/geom2/src/line.ts new file mode 100644 index 0000000000..6f5cf247b6 --- /dev/null +++ b/packages/geom2/src/line.ts @@ -0,0 +1,104 @@ +import { implementations, relations } from "@thi.ng/defmulti"; +import { + dist, + mixNewN, + ReadonlyVec, + subNew, + Vec +} from "@thi.ng/vectors2/api"; +import { Mat23 } from "@thi.ng/vectors2/mat23"; +import { intersectLines2 } from "./internal/line-intersection"; +import { offsetLine } from "./internal/offset"; +import { transformPoints } from "./internal/transform"; +import "./polygon"; +import { + asCubic, + asPolyline, + Attribs, + bounds, + centroid, + Cubic2, + flip, + intersectLine, + Line2, + offset, + perimeter, + Polygon2, + Polyline2, + Rect2, + tangentAt, + transform, + Type, + VecPair, + vertices, + resample, +} from "./api"; +import { direction } from "./internal/direction"; + +export function line(a: Vec, b: Vec, attribs?: Attribs) { + return new Line2([a, b], attribs); +} + +export const lineNormal = (a: ReadonlyVec, b: ReadonlyVec, out?: Vec) => + subNew(b, a, out); + +const type = Type.LINE2; + +relations( + type, + { + [Type.POINTS2]: [ + flip, + ], + [Type.POLYLINE2]: [ + resample, + vertices, + ], + } +); + +implementations( + type, + + asCubic, + (line: Line2) => + [Cubic2.fromLine(line.a, line.b, { ...line.attribs })], + + asPolyline, + (line: Line2) => + new Polyline2([...line.points], { ...line.attribs }), + + bounds, + (line: Line2) => + Rect2.fromMinMax(...line.points), + + centroid, + (line: Line2, c: Vec = []) => + mixNewN(line.a, line.b, 0.5, c), + + intersectLine, + (l1: Line2, l2: Line2) => + intersectLines2(l1.a, l1.b, l2.a, l2.b), + + offset, + (line: Line2, dist: number, res = 8) => + new Polygon2( + offsetLine(line.points, dist, res), + { ...line.attribs } + ), + + perimeter, + (line: Line2) => + dist(...line.points), + + tangentAt, + (line: Line2, _, n = 1) => + direction(line.a, line.b, n), + + transform, + (line: Line2, mat: Mat23) => + new Line2( + transformPoints(line.points, mat), + { ...line.attribs } + ), +); diff --git a/packages/geom2/src/path.ts b/packages/geom2/src/path.ts new file mode 100644 index 0000000000..037d3d92ae --- /dev/null +++ b/packages/geom2/src/path.ts @@ -0,0 +1,509 @@ +import { isNumber } from "@thi.ng/checks/is-number"; +import { implementations } from "@thi.ng/defmulti"; +import { rad } from "@thi.ng/math/angle"; +import { eqDelta } from "@thi.ng/math/eqdelta"; +import { comp } from "@thi.ng/transducers/func/comp"; +import { ensureArray } from "@thi.ng/transducers/func/ensure-array"; +import { peek } from "@thi.ng/transducers/func/peek"; +import { iterator1 } from "@thi.ng/transducers/iterator"; +import { filter } from "@thi.ng/transducers/xform/filter"; +import { map } from "@thi.ng/transducers/xform/map"; +import { mapcat } from "@thi.ng/transducers/xform/mapcat"; +import { + add, + copy, + maddNewN, + mulN, + ReadonlyVec, + set, + sub, + subNew, + Vec, + zeroes +} from "@thi.ng/vectors2/api"; +import { Mat23 } from "@thi.ng/vectors2/mat23"; +import { + asCubic, + asPolygon, + asPolyline, + Attribs, + bounds, + Cubic2, + Line2, + Path2, + PathSegment, + Polygon2, + Polyline2, + Quadratic2, + SamplingOpts, + SegmentType, + simplify, + transform, + translate, + Type, + vertices, + centroid +} from "./api"; +import { arcFrom2Points } from "./arc"; +import { collBounds } from "./internal/bounds"; +import "./polygon"; +import "./polyline"; +import { douglasPeucker2 } from "./internal/douglas–peucker"; + +const CMD_RE = /[achlmqstvz]/i; + +export function path(segments?: PathSegment[], attribs?: Attribs) { + return new Path2(segments, attribs); +} + +export const roundedRect = (pos: Vec, size: Vec, r: number | Vec) => { + r = isNumber(r) ? [r, r] : r; + const b = new PathBuilder(); + const [w, h] = maddNewN(size, r, -2); + b.moveTo([pos[0] + r[0], pos[1]]); + b.hlineTo(w, true); + b.arcTo(r, r, 0, false, true, true); + b.vlineTo(h, true); + b.arcTo([-r[0], r[1]], r, 0, false, true, true); + b.hlineTo(-w, true); + b.arcTo([-r[0], -r[1]], r, 0, false, true, true); + b.vlineTo(-h, true); + b.arcTo([r[0], -r[1]], r, 0, false, true, true); + return b.curr; +}; + +export const normalizePath = (path: Path2) => + new Path2([...mapcat( + (s) => + s.geo ? + map( + (c) => ({ type: SegmentType.CUBIC, geo: c }), + asCubic(s.geo) + ) : + [{ ...s }], + path.segments + )]); + +export const pathFromSVG = (svg: string) => { + const b = new PathBuilder(); + try { + let cmd: string; + for (let n = svg.length, i = 0; i < n;) { + i = skipWS(svg, i); + const c = svg.charAt(i); + if (CMD_RE.test(c)) { + cmd = c; + i++; + } + let p, pa, pb, t1, t2, t3; + switch (cmd.toLowerCase()) { + case "m": + [p, i] = readPoint(svg, i); + b.moveTo(p, cmd === "m"); + break; + case "l": + [p, i] = readPoint(svg, i); + b.lineTo(p, cmd === "l"); + break; + case "h": + [p, i] = readFloat(svg, i); + b.hlineTo(p, cmd === "h"); + break; + case "v": + [p, i] = readFloat(svg, i); + b.vlineTo(p, cmd === "v"); + break; + case "q": + [pa, i] = readPoint(svg, i); + [p, i] = readPoint(svg, i); + // console.log("quadratic", pa.toString(), p.toString()); + b.quadraticTo(pa, p, cmd === "q"); + break; + case "c": + [pa, i] = readPoint(svg, i); + [pb, i] = readPoint(svg, i); + [p, i] = readPoint(svg, i); + // console.log("cubic", pa.toString(), pb.toString(), p.toString()); + b.cubicTo(pa, pb, p, cmd === "c"); + break; + case "s": + [pa, i] = readPoint(svg, i); + [p, i] = readPoint(svg, i); + // console.log("cubicChain", pa.toString(), p.toString()); + b.cubicChainTo(pa, p, cmd === "s"); + break; + case "t": + [p, i] = readPoint(svg, i); + // console.log("quadraticChain", p.toString()); + b.quadraticChainTo(p, cmd === "t"); + break; + case "a": { + [pa, i] = readPoint(svg, i); + [t1, i] = readFloat(svg, i); + [t2, i] = readFloat(svg, i); + [t3, i] = readFloat(svg, i); + [pb, i] = readPoint(svg, i); + // console.log("arc", pa.toString(), rad(t1), t2, t3, pb.toString()); + b.arcTo(pb, pa, rad(t1), !!t2, !!t3, cmd === "a"); + break; + } + case "z": + b.closePath(); + break; + default: + throw new Error(`unsupported segment type: ${c} @ pos ${i}`); + } + } + return b.paths; + } catch (e) { + throw e instanceof Error ? e : new Error(`illegal char '${svg.charAt(e)}' @ ${e}`); + } +}; + +implementations( + Type.PATH2, + + asPolygon, + (path: Path2, opts?: number | Partial) => + new Polygon2(vertices(path, opts), { ...path.attribs }), + + asPolyline, + (path: Path2, opts?: number | Partial) => + new Polyline2(vertices(path, opts), { ...path.attribs }), + + bounds, + (path: Path2) => + collBounds([...iterator1( + comp( + map((s: PathSegment) => s.geo), + filter((s) => !!s), + ), + path.segments) + ]), + + centroid, + (path: Path2) => centroid(bounds(path)), + + simplify, + (path: Path2, eps = 0.1) => { + const res: PathSegment[] = []; + const orig = path.segments; + const n = orig.length; + let points: Vec[]; + let lastP: Vec; + for (let i = 0; i < n; i++) { + const s = orig[i]; + if (s.type === SegmentType.LINE || s.type === SegmentType.POLYLINE) { + points = (points || []).concat(ensureArray(vertices(s.geo))); + lastP = peek(points); + } else if (points) { + points.push(lastP); + res.push({ + geo: new Polyline2(douglasPeucker2(points, eps)), + type: SegmentType.POLYLINE, + }); + points = null; + } else { + res.push({ ...s }); + } + } + if (points) { + points.push(lastP); + res.push({ + geo: new Polyline2(points), + type: SegmentType.POLYLINE, + }); + } + return new Path2(res, { ...path.attribs }); + }, + + transform, + (path: Path2, mat: Mat23) => + new Path2( + path.segments.map((s) => + s.geo ? + { + type: s.type, + geo: transform(s.geo, mat) + } : + { ...s } + ), + { ...path.attribs } + ), + + translate, + (path: Path2, delta: ReadonlyVec) => + new Path2( + path.segments.map((s) => + s.geo ? + { + type: s.type, + geo: translate(s.geo, delta) + } : + { ...s } + ), + { ...path.attribs } + ), + + vertices, + (path: Path2, opts?: number | Partial) => { + const _opts = isNumber(opts) ? { num: opts } : opts; + let verts: Vec[] = []; + for (let segs = path.segments, n = segs.length - 1, i = 0; i <= n; i++) { + const s = segs[i]; + if (s.geo) { + verts = verts.concat( + ensureArray( + vertices(s.geo, { ..._opts, last: i === n && !path.closed }) + ) + ); + } + } + return verts; + } +); + +export class PathBuilder { + + paths: Path2[]; + curr: Path2; + protected currP: Vec; + protected bezierP: Vec; + protected startP: Vec; + + constructor() { + this.paths = []; + this.newPath(); + } + + *[Symbol.iterator]() { + yield* this.paths; + } + + newPath() { + this.curr = new Path2(); + this.paths.push(this.curr); + this.currP = zeroes(2); + this.bezierP = zeroes(2); + this.startP = zeroes(2); + } + + moveTo(p: Vec, relative = false): PathBuilder { + if (this.curr.segments.length > 0) { + this.curr = new Path2(); + this.paths.push(this.curr); + } + p = this.updateCurrent(p, relative); + set(this.startP, p); + set(this.bezierP, p); + this.curr.add({ + point: p, + type: SegmentType.MOVE, + }); + return this; + } + + lineTo(p: Vec, relative = false): PathBuilder { + this.curr.add({ + geo: new Line2([ + copy(this.currP), + this.updateCurrent(p, relative) + ]), + type: SegmentType.LINE, + }); + set(this.bezierP, this.currP); + return this; + } + + hlineTo(x: number, relative = false): PathBuilder { + const prev = copy(this.currP); + this.currP[0] = relative ? this.currP[0] + x : x; + set(this.bezierP, this.currP); + this.curr.add({ + geo: new Line2([prev, copy(this.currP)]), + type: SegmentType.LINE, + }); + return this; + } + + vlineTo(y: number, relative = false): PathBuilder { + const prev = copy(this.currP); + this.currP[1] = relative ? this.currP[1] + y : y; + set(this.bezierP, this.currP); + this.curr.add({ + geo: new Line2([prev, copy(this.currP)]), + type: SegmentType.LINE, + }); + return this; + } + + cubicTo(cp1: Vec, cp2: Vec, p: Vec, relative = false) { + const c2 = this.absPoint(cp2, relative); + set(this.bezierP, c2); + this.curr.add({ + geo: new Cubic2([ + copy(this.currP), + this.absPoint(cp1, relative), + c2, + this.updateCurrent(p, relative), + ]), + type: SegmentType.CUBIC, + }); + return this; + } + + quadraticTo(cp: Vec, p: Vec, relative = false) { + const c1 = this.absPoint(cp, relative); + set(this.bezierP, c1); + this.curr.add({ + geo: new Quadratic2([ + copy(this.currP), + c1, + this.updateCurrent(p, relative), + ]), + type: SegmentType.QUADRATIC, + }); + return this; + } + + cubicChainTo(cp2: Vec, p: Vec, relative = false) { + const prevMode = peek(this.curr.segments).type; + const c1 = copy(this.currP); + if (prevMode === SegmentType.CUBIC) { + add(c1, subNew(c1, this.bezierP)); + } + const c2 = this.absPoint(cp2, relative); + set(this.bezierP, c2); + this.curr.add({ + geo: new Cubic2([ + copy(this.currP), + c1, + c2, + this.updateCurrent(p, relative), + ]), + type: SegmentType.CUBIC, + }); + return this; + } + + quadraticChainTo(p: Vec, relative = false) { + const prevMode = peek(this.curr.segments).type; + const c1 = copy(this.currP); + if (prevMode === SegmentType.QUADRATIC) { + sub(mulN(c1, 2), this.bezierP); + } + set(this.bezierP, c1); + this.curr.add({ + geo: new Quadratic2([ + copy(this.currP), + c1, + this.updateCurrent(p, relative), + ]), + type: SegmentType.CUBIC, + }); + return this; + } + + arcTo(p: Vec, r: Vec, xaxis: number, xl: boolean, clockwise: boolean, relative = false) { + if (eqDelta(r[0], 0) || eqDelta(r[1], 0)) { + return this.lineTo(p, relative); + } + const prev = copy(this.currP); + this.curr.add({ + geo: arcFrom2Points( + prev, + this.updateCurrent(p, relative), + r, + xaxis, + xl, + clockwise + ), + type: SegmentType.ARC, + }); + set(this.bezierP, this.currP); + return this; + } + + closePath() { + this.curr.add({ + geo: new Line2([copy(this.currP), copy(this.startP)]), + type: SegmentType.LINE, + }); + this.curr.closed = true; + return this; + } + + protected updateCurrent(p: Vec, relative: boolean) { + p = copy(relative ? add(this.currP, p) : set(this.currP, p)); + return p; + } + + protected absPoint(p: Vec, relative: boolean) { + return relative ? add(p, this.currP) : p; + } +} + +const readPoint = + (src: string, index: number): [Vec, number] => { + let x, y; + [x, index] = readFloat(src, index); + index = skipWS(src, index); + [y, index] = readFloat(src, index); + return [[x, y], index]; + }; + +const isWS = + (c: string) => c === " " || c === "\n" || c === "\r" || c === "\t"; + +const skipWS = + (src: string, i: number) => { + const n = src.length; + while (i < n && isWS(src.charAt(i))) i++; + return i; + }; + +const readFloat = + (src: string, index: number) => { + index = skipWS(src, index); + let signOk = true; + let dotOk = true; + let expOk = false; + let commaOk = false; + let i = index; + for (let n = src.length; i < n; i++) { + const c = src.charAt(i); + // console.log("float", src.substring(index, i + 1)); + if ("0" <= c && c <= "9") { + expOk = true; + commaOk = true; + signOk = false; + continue; + } + if (c === "-" || c === "+") { + if (!signOk) break; + signOk = false; + continue; + } + if (c === ".") { + if (!dotOk) break; + dotOk = false; + continue; + } + if (c === "e") { + if (!expOk) throw i; + expOk = false; + dotOk = false; + signOk = true; + continue; + } + if (c === ",") { + if (!commaOk) throw i; + i++; + } + break; + } + if (i === index) { + throw new Error(`expected coordinate @ pos: ${i}`); + } + return [parseFloat(src.substring(index, i)), i]; + }; diff --git a/packages/geom2/src/polygon.ts b/packages/geom2/src/polygon.ts index a61c172215..0e0b30e8c2 100644 --- a/packages/geom2/src/polygon.ts +++ b/packages/geom2/src/polygon.ts @@ -1,87 +1,247 @@ import { isPlainObject } from "@thi.ng/checks/is-plain-object"; -import { implementations } from "@thi.ng/defmulti"; -import { Vec } from "@thi.ng/vectors2/api"; +import { implementations, relations } from "@thi.ng/defmulti"; +import { TAU } from "@thi.ng/math/api"; +import { Reducer } from "@thi.ng/transducers/api"; +import { cycle } from "@thi.ng/transducers/iter/cycle"; +import { normRange } from "@thi.ng/transducers/iter/norm-range"; +import { tuples } from "@thi.ng/transducers/iter/tuples"; +import { wrap } from "@thi.ng/transducers/iter/wrap"; +import { reduced } from "@thi.ng/transducers/reduced"; +import { push } from "@thi.ng/transducers/rfn/push"; +import { transduce } from "@thi.ng/transducers/transduce"; +import { map } from "@thi.ng/transducers/xform/map"; +import { partition } from "@thi.ng/transducers/xform/partition"; +import { + addNew, + cartesian, + ReadonlyVec, + Vec +} from "@thi.ng/vectors2/api"; +import { Mat23 } from "@thi.ng/vectors2/mat23"; +import "./container2"; +import { centerOfWeight2 } from "./internal/centroid"; +import { signedArea } from "./internal/corner"; +import { edges as _edges } from "./internal/edges"; +import { booleanOp } from "./internal/greiner-hormann"; +import { offset as _offset } from "./internal/offset"; +import { perimeter as _perimeter } from "./internal/perimeter"; +import { pointInside as _pointInside, polygonArea } from "./internal/polygon"; +import { Sampler } from "./internal/sampler"; +import { subdivideCurve } from "./internal/subdiv-curve"; +import { sutherlandHodgeman } from "./internal/sutherland-hodgeman"; +import { transformPoints } from "./internal/transform"; +import { tessellatePoints } from "./tessellate"; import { - arcLength, area, Attribs, bounds, centroid, + clipConvex, + ClipMode, convexHull, + Convexity, + difference, + edges, + flip, + intersection, + IShape, + offset, + perimeter, + pointAt, + pointInside, Polygon2, resample, SamplingOpts, - IShape, simplify, + subdivide, + SubdivKernel, + tangentAt, tessellate, Tessellator, + transform, + translate, Type, - vertices + union, + vertices, + asPolygon, } from "./api"; -import { arcLength as _arcLength } from "./internal/arc-length"; -import { polygonArea } from "./internal/area"; -import { centerOfWeight2 } from "./internal/centroid"; -import { grahamScan2 } from "./internal/graham-scan"; -import { Sampler } from "./internal/sampler"; -import { sutherlandHodgeman } from "./internal/sutherland-hodgeman"; -import { tessellatePoints } from "./tessellate"; import { douglasPeucker2 } from "./internal/douglas–peucker"; export function polygon(points: Vec[], attribs?: Attribs): Polygon2 { return new Polygon2(points, attribs); } +export const star = (r: number, n: number, profile: number[]) => { + const total = n * profile.length; + const pts = transduce( + map(([i, p]) => cartesian([r * p, i * TAU])), + push(), + tuples(normRange(total, false), cycle(profile)) + ); + return new Polygon2(pts); +}; + +const convexityReducer: Reducer = [ + () => 0, + (x) => x, + (type, [a, b, c]) => { + const t = signedArea(a, b, c); + if (t < 0) { + type |= 1; + } else if (t > 0) { + type |= 2; + } + return t === 3 ? reduced(3) : type; + } +]; + +export const convexity = (poly: Polygon2) => { + if (poly.points.length < 3) { + return Convexity.COLINEAR; + } + const type = transduce( + partition(3, 1), + convexityReducer, + wrap(poly.points, 1) + ); + return type === 3 ? + Convexity.CONCAVE : + type !== 0 ? Convexity.CONVEX : Convexity.COLINEAR; +}; + const type = Type.POLYGON2; -bounds.isa(type, Type.POINTS2); -vertices.isa(type, Type.POINTS2); +relations( + type, + { + [Type.POINTS2]: [ + bounds, + convexHull, + flip, + vertices + ] + } +); implementations( type, - arcLength, - (x: Polygon2) => _arcLength(x.points, true), - area, - (x: Polygon2, signed = true) => { - const area = polygonArea(x.points); + (poly: Polygon2, signed = true) => { + const area = polygonArea(poly.points); return signed ? area : Math.abs(area); }, + asPolygon, + (poly: Polygon2) => poly, + centroid, - (x: Polygon2, c: Vec) => centerOfWeight2(x.points, c), + (poly: Polygon2, c: Vec) => + centerOfWeight2(poly.points, c), - convexHull, - (poly: Polygon2) => grahamScan2(poly.points), + clipConvex, + (poly: Polygon2, boundary: IShape) => + new Polygon2( + sutherlandHodgeman(poly.points, vertices(boundary), centroid(boundary)), + { ...poly.attribs } + ), + + difference, + (poly: Polygon2, other: IShape) => + booleanOp([poly.points], vertices(other), ClipMode.DIFF_A) + .map((pts) => new Polygon2(pts, { ...poly.attribs })), + + edges, + (poly: Polygon2, opts: number | SamplingOpts) => + _edges(vertices(poly, opts), true), + + intersection, + (poly: Polygon2, other: IShape) => + booleanOp([poly.points], vertices(other), ClipMode.INTERSECTION) + .map((pts) => new Polygon2(pts)), + + offset, + (poly: Polygon2, dist: number, res = 8) => { + const pts = _offset(poly.points, dist, res, true); + return pts ? + new Polygon2(pts, { ...poly.attribs }) : + undefined; + }, + + perimeter, + (poly: Polygon2) => + _perimeter(poly.points, true), + + pointAt, + (poly: Polygon2, t: number) => + new Sampler(poly.points, true).pointAt(t), + + pointInside, + (poly: Polygon2, [x, y]: ReadonlyVec) => { + const pts = poly.points; + let inside = 0; + for (let n = pts.length - 1, i = n, j = 0; j <= n; i = j, j++) { + inside = _pointInside(pts[i], pts[j], x, y, inside); + } + return inside; + }, resample, - (x: Polygon2, opts?: number | SamplingOpts) => - new Polygon2(vertices(x, opts), { ...this.attribs }), + (poly: Polygon2, opts?: number | SamplingOpts) => + new Polygon2(vertices(poly, opts), { ...poly.attribs }), simplify, - (x: Polygon2, eps = 0.1) => + (poly: Polygon2, eps = 0.1) => new Polygon2( - douglasPeucker2(x.points, eps, true), - { ...this.attribs } + douglasPeucker2(poly.points, eps, true), + { ...poly.attribs } ), + subdivide, + (poly: Polygon2, kernel: SubdivKernel, iter = 1) => + new Polygon2( + subdivideCurve(kernel, poly.points, iter, true), + { ...poly.attribs } + ), + + tangentAt, + (poly: Polygon2, t: number, n = 1) => + new Sampler(poly.points, true).tangentAt(t, n), + tessellate, - (x: Polygon2, tessel: Iterable) => - tessellatePoints(x.points, tessel), + (poly: Polygon2, tessel: Iterable) => + tessellatePoints(poly.points, tessel), + + transform, + (poly: Polygon2, mat: Mat23) => + new Polygon2( + transformPoints(poly.points, mat), + { ...poly.attribs } + ), + + translate, + (poly: Polygon2, delta: ReadonlyVec) => + new Polygon2( + poly.points.map((p) => addNew(p, delta)), + { ...poly.attribs } + ), + + union, + (poly: Polygon2, other: IShape) => + booleanOp([poly.points], vertices(other), ClipMode.UNION) + .map((pts) => new Polygon2(pts)), vertices, - (x: Polygon2, opts?: number | SamplingOpts) => { + (poly: Polygon2, opts?: number | SamplingOpts) => { if (opts !== undefined) { - const sampler = new Sampler(x.points, true); + const sampler = new Sampler(poly.points, true); return isPlainObject(opts) ? opts.dist ? sampler.sampleUniform(opts.dist, opts.last) : sampler.sampleFixedNum(opts.num, opts.last) : sampler.sampleFixedNum(opts, false); } - return x.points; + return poly.points; }, -); -export const clipConvex = (poly: Polygon2, boundary: IShape) => - sutherlandHodgeman(poly.points, vertices(boundary), centroid(boundary)); +); diff --git a/packages/geom2/src/polyline.ts b/packages/geom2/src/polyline.ts index 52ed6d9778..51380b4f27 100644 --- a/packages/geom2/src/polyline.ts +++ b/packages/geom2/src/polyline.ts @@ -1,25 +1,46 @@ import { isPlainObject } from "@thi.ng/checks/is-plain-object"; -import { implementations } from "@thi.ng/defmulti"; -import { Vec } from "@thi.ng/vectors2/api"; +import { implementations, relations } from "@thi.ng/defmulti"; +import { + addNew, + ReadonlyVec, + Vec +} from "@thi.ng/vectors2/api"; +import { Mat23 } from "@thi.ng/vectors2/mat23"; import { - arcLength, Attribs, bounds, centroid, convexHull, DEFAULT_SAMPLES, + edges, + flip, + offset, + perimeter, + Polygon2, Polyline2, resample, SamplingOpts, simplify, + subdivide, + SubdivKernel, + tangentAt, + transform, + translate, Type, - vertices + vertices, + asCubic, + Cubic2 } from "./api"; -import { arcLength as _arcLength } from "./internal/arc-length"; +import "./container2"; import { centroid as _centroid } from "./internal/centroid"; -import { grahamScan2 } from "./internal/graham-scan"; +import { edges as _edges } from "./internal/edges"; +import { offset as _offset } from "./internal/offset"; +import { perimeter as _perimeter } from "./internal/perimeter"; import { Sampler } from "./internal/sampler"; +import { subdivideCurve } from "./internal/subdiv-curve"; +import { transformPoints } from "./internal/transform"; import { douglasPeucker2 } from "./internal/douglas–peucker"; +import { map } from "@thi.ng/transducers/xform/map"; export function polyline(points: Vec[], attribs?: Attribs): Polyline2 { return new Polyline2(points, attribs); @@ -27,42 +48,87 @@ export function polyline(points: Vec[], attribs?: Attribs): Polyline2 { const type = Type.POLYLINE2; -bounds.isa(type, Type.POINTS2); -vertices.isa(type, Type.POINTS2); +relations( + type, + { + [Type.POINTS2]: [ + bounds, + centroid, + convexHull, + flip + ], + } +); implementations( type, - arcLength, - (x: Polyline2) => _arcLength(x.points, false), + asCubic, + (line: Polyline2) => + map((e) => Cubic2.fromLine(...e), _edges(line.points)), - centroid, - (x: Polyline2, c: Vec) => _centroid(x.points, c), + edges, + (line: Polyline2, opts: number | SamplingOpts) => + _edges(vertices(line, opts), true), - convexHull, - (poly: Polyline2) => grahamScan2(poly.points), + offset, + (line: Polyline2, dist: number, res = 8) => { + const pts = _offset(line.points, dist, res, false); + return pts ? + new Polygon2(pts, { ...line.attribs }) : + undefined; + }, + + perimeter, + (line: Polyline2) => _perimeter(line.points, false), resample, - (x: Polyline2, opts?: number | SamplingOpts) => - new Polyline2(vertices(x, opts), { ...this.attribs }), + (line: Polyline2, opts?: number | SamplingOpts) => + new Polyline2(vertices(line, opts), { ...line.attribs }), simplify, - (x: Polyline2, eps = 0.1) => + (line: Polyline2, eps = 0.1) => new Polyline2( - douglasPeucker2(x.points, eps, true), - { ...this.attribs } + douglasPeucker2(line.points, eps, true), + { ...line.attribs } + ), + + subdivide, + (line: Polyline2, kernel: SubdivKernel, iter = 1) => + new Polyline2( + subdivideCurve(kernel, line.points, iter, false), + { ...line.attribs } + ), + + tangentAt, + (line: Polyline2, t: number, n = 1) => + new Sampler(line.points, false).tangentAt(t, n), + + transform, + (line: Polyline2, mat: Mat23) => + new Polyline2( + transformPoints(line.points, mat), + { ...line.attribs } + ), + + translate, + (line: Polyline2, delta: ReadonlyVec) => + new Polyline2( + line.points.map((p) => addNew(p, delta)), + { ...line.attribs } ), vertices, - (x: Polyline2, opts?: number | SamplingOpts) => { + (line: Polyline2, opts?: number | SamplingOpts) => { if (opts !== undefined) { - const sampler = new Sampler(x.points, false); + const sampler = new Sampler(line.points, false); return isPlainObject(opts) ? opts.dist ? sampler.sampleUniform(opts.dist, opts.last !== false) : sampler.sampleFixedNum(opts.num, opts.last !== false) : sampler.sampleFixedNum(opts || DEFAULT_SAMPLES, true); } - return x.points; + return line.points; }, + ); diff --git a/packages/geom2/src/quad.ts b/packages/geom2/src/quad.ts index 8e7541d742..4a3e6992ff 100644 --- a/packages/geom2/src/quad.ts +++ b/packages/geom2/src/quad.ts @@ -1,5 +1,29 @@ -import { Quad2, Attribs, bounds, Type, centroid, area, vertices, tessellate } from "./api"; -import { Vec } from "@thi.ng/vectors2/api"; +import { implementations, relations } from "@thi.ng/defmulti"; +import { addNew, ReadonlyVec, Vec } from "@thi.ng/vectors2/api"; +import { Mat23 } from "@thi.ng/vectors2/mat23"; +import { mixBilinear2 } from "@thi.ng/vectors2/vec2"; +import { + area, + Attribs, + bounds, + centroid, + clipConvex, + convexHull, + edges, + flip, + perimeter, + Quad2, + resample, + tessellate, + transform, + translate, + Type, + unmapPoint, + vertices +} from "./api"; +import "./container2"; +import { transformPoints } from "./internal/transform"; +import "./polygon"; export function quad(points: Vec[], attribs?: Attribs): Quad2 { return new Quad2(points, attribs); @@ -7,8 +31,48 @@ export function quad(points: Vec[], attribs?: Attribs): Quad2 { const type = Type.QUAD2; -area.isa(type, Type.POLYGON2); -bounds.isa(type, Type.POINTS2); -centroid.isa(type, Type.POLYGON2); -tessellate.isa(type, Type.POLYGON2); -vertices.isa(type, Type.POINTS2); +relations( + type, + { + [Type.POINTS2]: [ + bounds, + flip, + ], + [Type.POLYGON2]: [ + area, + centroid, + clipConvex, + convexHull, + edges, + perimeter, + resample, + tessellate, + vertices, + ], + } +); + +implementations( + type, + + transform, + (quad: Quad2, mat: Mat23) => + new Quad2( + transformPoints(quad.points, mat), + { ...quad.attribs } + ), + + translate, + (quad: Quad2, delta: ReadonlyVec) => + new Quad2( + quad.points.map((p) => addNew(p, delta)), + { ...quad.attribs } + ), + + unmapPoint, + (quad: Quad2, p: ReadonlyVec, out?: Vec) => { + const pts = quad.points; + return mixBilinear2(pts[0], pts[1], pts[3], pts[2], p[0], p[1], out); + }, + +); diff --git a/packages/geom2/src/rect.ts b/packages/geom2/src/rect.ts index 6e9e6e6e8a..65b822465f 100644 --- a/packages/geom2/src/rect.ts +++ b/packages/geom2/src/rect.ts @@ -1,27 +1,50 @@ -import { implementations } from "@thi.ng/defmulti"; +import { implementations, relations } from "@thi.ng/defmulti"; import { addNew, copy, + div, + madd, maddNewN, + ReadonlyVec, + set, + subNew, Vec } from "@thi.ng/vectors2/api"; +import { Mat23 } from "@thi.ng/vectors2/mat23"; +import { unionBounds } from "./internal/bounds"; +import { edges as _edges } from "./internal/edges"; +import { booleanOp } from "./internal/greiner-hormann"; +import { sutherlandHodgeman } from "./internal/sutherland-hodgeman"; +import { transformPoints } from "./internal/transform"; +import "./polygon"; +import { tessellatePoints } from "./tessellate"; import { - arcLength, area, - asPolygon, Attribs, bounds, centroid, + clipConvex, + ClipMode, + IShape, + mapPoint, + perimeter, Polygon2, Rect2, tessellate, Tessellator, Type, union, - vertices + unmapPoint, + vertices, + transform, + SamplingOpts, + edges, + translate, + resample, + pointAt, + pointInside, } from "./api"; -import { unionBounds } from "./internal/bounds"; -import { tessellatePoints } from "./tessellate"; +import { Sampler } from "./internal/sampler"; export function rect(pos: Vec, size: Vec, attribs?: Attribs) { return new Rect2(pos, size, attribs); @@ -30,36 +53,97 @@ export function rect(pos: Vec, size: Vec, attribs?: Attribs) { export const rectFromMinMax = (min: Vec, max: Vec, attribs?: Attribs) => Rect2.fromMinMax(min, max, attribs); -implementations( - Type.RECT2, +const type = Type.RECT2; - area, - (x: Rect2) => x.size[0] * x.size[1], +relations( + type, + { + [Type.POLYGON2]: [ + resample, + ] + } +); - arcLength, - (x: Rect2) => 2 * (x.size[0] + x.size[1]), +implementations( + type, - asPolygon, - (x: Rect2) => new Polygon2(vertices(x), { ...x.attribs }), + area, + (rect: Rect2) => rect.size[0] * rect.size[1], bounds, - (x: Rect2) => x, + (rect: Rect2) => rect, centroid, - (x: Rect2, o?: Vec) => maddNewN(x.pos, x.size, 0.5, o), + (rect: Rect2, o?: Vec) => maddNewN(rect.pos, rect.size, 0.5, o), + + clipConvex, + (rect: Rect2, boundary: IShape) => + new Polygon2( + sutherlandHodgeman(vertices(rect), vertices(boundary), centroid(boundary)), + { ...rect.attribs } + ), + + edges, + (rect: Rect2, opts: number | SamplingOpts) => + _edges(vertices(rect, opts), true), + + mapPoint, + (rect: Rect2, p: ReadonlyVec, out?: Vec) => { + return div(subNew(p, rect.pos, out), rect.size); + }, + + perimeter, + (rect: Rect2) => 2 * (rect.size[0] + rect.size[1]), + + pointAt, + (rect: Rect2, t: number) => + new Sampler(vertices(rect), true).pointAt(t), + + pointInside, + (rect: Rect2, [x, y]: ReadonlyVec) => { + const [rx, ry] = rect.pos; + const [sx, sy] = rect.size; + return x >= rx && x <= rx + sx && y >= ry && y <= ry + sy; + }, tessellate, - (x: Rect2, tessel: Tessellator | Iterable, iter?: number) => - tessellatePoints(vertices(x), tessel, iter), + (rect: Rect2, tessel: Tessellator | Iterable, iter?: number) => + tessellatePoints(vertices(rect), tessel, iter), + + transform, + (rect: Rect2, mat: Mat23) => + new Polygon2( + transformPoints(vertices(rect), mat), + { ...rect.attribs } + ), + + translate, + (rect: Rect2, delta: ReadonlyVec) => + new Rect2( + addNew(rect.pos, delta), + copy(rect.size), + { ...rect.attribs } + ), union, - (r1: Rect2, r2: Rect2) => - new Rect2(...unionBounds(r1.pos, r1.size, r2.pos, r2.size)), + (r1: Rect2, r2: IShape) => + r2 instanceof Rect2 ? + [new Rect2(...unionBounds(r1.pos, r1.size, r2.pos, r2.size))] : + booleanOp([vertices(r1)], vertices(r2), ClipMode.UNION) + .map((pts) => new Polygon2(pts, { ...r1.attribs })), + + unmapPoint, + (rect: Rect2, p: ReadonlyVec, out?: Vec) => { + return madd((out ? set(out, rect.pos) : copy(rect.pos)), rect.size, p); + }, vertices, - (x: Rect2) => { - const p = x.pos; - const q = addNew(p, x.size); - return [copy(p), [q[0], p[1]], q, [p[0], q[1]]]; - } + (rect: Rect2, opts: number | SamplingOpts) => { + const p = rect.pos; + const q = addNew(p, rect.size); + const verts = [copy(p), [q[0], p[1]], q, [p[0], q[1]]]; + return opts != null ? + vertices(new Polygon2(verts), opts) : + verts; + }, ); diff --git a/packages/geom2/src/svg.ts b/packages/geom2/src/svg.ts index 6a70c8eed5..cdf43e296c 100644 --- a/packages/geom2/src/svg.ts +++ b/packages/geom2/src/svg.ts @@ -1,21 +1,26 @@ import { serialize } from "@thi.ng/hiccup"; import { convertTree } from "@thi.ng/hiccup-svg/convert"; import { svg } from "@thi.ng/hiccup-svg/svg"; +import { ff } from "@thi.ng/hiccup-svg/format"; import { collBounds } from "./internal/bounds"; import { IShape, Rect2 } from "./api"; -export const asSVG = (...args: any[]) => +export const asSvg = (...args: any[]) => args .map((x) => serialize(convertTree(x))) .join(""); export const svgDoc = (attribs, ...args: IShape[]) => { - const b = collBounds(args); - attribs = { - width: b.size[0], - height: b.size[1], - viewBox: `${b.pos[0]} ${b.pos[1]} ${b.size[0]} ${b.size[1]}`, - ...attribs - }; + if (args.length > 0) { + if (!attribs || !attribs.viewBox) { + const b = collBounds(args); + attribs = { + width: ff(b.size[0]), + height: ff(b.size[1]), + viewBox: `${ff(b.pos[0])} ${ff(b.pos[1])} ${ff(b.size[0])} ${ff(b.size[1])}`, + ...attribs + }; + } + } return svg(attribs, ...args); }; diff --git a/packages/geom2/src/tessellate.ts b/packages/geom2/src/tessellate.ts index 7115e30397..61ada46b72 100644 --- a/packages/geom2/src/tessellate.ts +++ b/packages/geom2/src/tessellate.ts @@ -14,15 +14,15 @@ import { partition } from "@thi.ng/transducers/xform/partition"; import { scan } from "@thi.ng/transducers/xform/scan"; import { mixNewN, ReadonlyVec, Vec } from "@thi.ng/vectors2/api"; import { Tessellator } from "./api"; -import { polygonArea } from "./internal/area"; import { centroid } from "./internal/centroid"; -import { corner, pointInTriangle2 } from "./internal/corner"; +import { pointInTriangle2, signedArea } from "./internal/corner"; +import { polygonArea } from "./internal/polygon"; const snip = (points: ReadonlyVec[], u: number, v: number, w: number, n: number, ids: number[]) => { const a = points[ids[u]]; const b = points[ids[v]]; const c = points[ids[w]]; - if (corner(a, b, c) > 0) { + if (signedArea(a, b, c) > 0) { for (let i = 0; i < n; i++) { if (i !== u && i !== v && i !== w) { if (pointInTriangle2(points[ids[i]], a, b, c)) { diff --git a/packages/geom2/src/triangle.ts b/packages/geom2/src/triangle.ts new file mode 100644 index 0000000000..a03cbcc78d --- /dev/null +++ b/packages/geom2/src/triangle.ts @@ -0,0 +1,106 @@ +import { implementations, relations } from "@thi.ng/defmulti"; +import { PI } from "@thi.ng/math/api"; +import { + add, + addNew, + divN, + maddN, + mag, + normalize, + ReadonlyVec, + subNew, + Vec +} from "@thi.ng/vectors2/api"; +import { Mat23 } from "@thi.ng/vectors2/mat23"; +import { perpendicularLeft2 } from "@thi.ng/vectors2/vec2"; +import { + area, + Attribs, + bounds, + centroid, + classifyPoint, + clipConvex, + edges, + perimeter, + pointInside, + tessellate, + transform, + translate, + Triangle2, + Type, + vertices, + convexHull, + resample +} from "./api"; +import { classifyPointInTriangle2, pointInTriangle2, signedArea } from "./internal/corner"; +import { transformPoints } from "./internal/transform"; + +export function triangle(a: Vec, b: Vec, c: Vec, attribs?: Attribs) { + return new Triangle2([a, b, c], attribs); +} + +export const equilateralTriangle = (a: Vec, b: Vec) => { + const dir = subNew(b, a); + const c = normalize(perpendicularLeft2(dir), mag(dir) * Math.sin(PI / 3)); + return new Triangle2([a, b, maddN(c, dir, 0.5)]); +}; + +const type = Type.TRIANGLE2; + +relations( + type, + { + [Type.POINTS2]: [ + bounds, + ], + [Type.POLYGON2]: [ + clipConvex, + edges, + perimeter, + resample, + tessellate, + vertices, + ] + } +); + +implementations( + type, + + area, + (tri: Triangle2, signed = true) => { + const area = 0.5 * signedArea(...<[Vec, Vec, Vec]>tri.points); + return signed ? area : Math.abs(area); + }, + + centroid, + (tri: Triangle2, c?: Vec) => { + const pts = tri.points; + return divN(add(addNew(pts[0], pts[1], c), pts[2]), 3); + }, + + classifyPoint, + (tri: Triangle2, p: ReadonlyVec) => + classifyPointInTriangle2(p, ...<[Vec, Vec, Vec]>tri.points), + + convexHull, + (tri: Triangle2) => tri, + + pointInside, + (tri: Triangle2, p: ReadonlyVec) => + pointInTriangle2(p, ...<[Vec, Vec, Vec]>tri.points), + + transform, + (tri: Triangle2, mat: Mat23) => + new Triangle2( + transformPoints(tri.points, mat), + { ...tri.attribs } + ), + + translate, + (tri: Triangle2, delta: ReadonlyVec) => + new Triangle2( + tri.points.map((p) => addNew(p, delta)), + { ...tri.attribs } + ), +); diff --git a/packages/geom2/test/api.ts b/packages/geom2/test/api.ts new file mode 100644 index 0000000000..21bba56bf4 --- /dev/null +++ b/packages/geom2/test/api.ts @@ -0,0 +1,373 @@ +import { DEFAULT, MultiFn } from "@thi.ng/defmulti"; +import * as assert from "assert"; +import { + area, + asCubic, + asPolygon, + asPolyline, + bounds, + center, + centroid, + classifyPoint, + clipConvex, + closestPoint, + convexHull, + depth, + difference, + edges, + extrude, + flip, + height, + intersection, + intersectLine, + intersectShape, + mapPoint, + normalAt, + offset, + perimeter, + pointAt, + pointInside, + resample, + simplify, + splitAt, + subdivide, + tangentAt, + tessellate, + transform, + translate, + Type, + union, + unmapPoint, + vertices, + warp, + width +} from "../src"; + +const _DEFAULT = DEFAULT.toString(); + +const checkImpls = (fn: MultiFn, types: PropertyKey[]) => + assert.deepEqual( + [...fn.impls()].map((x) => x.toString()).sort(), + types.map((x) => x.toString()).sort() + ); + +describe("api", () => { + + it("area", () => + checkImpls(area, [ + _DEFAULT, + Type.CIRCLE2, + Type.ELLIPSE2, + Type.GROUP, + Type.POLYGON2, + Type.QUAD2, + Type.RECT2, + Type.TRIANGLE2, + ])); + + it("asCubic", () => + checkImpls(asCubic, [ + Type.ARC2, + Type.CUBIC2, + Type.LINE2, + Type.POLYLINE2, + Type.QUADRATIC2, + ])); + + it("asPolygon", () => + checkImpls(asPolygon, [ + _DEFAULT, + Type.ELLIPSE2, + Type.PATH2, + Type.POLYGON2, + ])); + + it("asPolyline", () => + checkImpls(asPolyline, [ + _DEFAULT, + Type.CUBIC2, + Type.LINE2, + Type.PATH2, + Type.QUADRATIC2, + ])); + + it("bounds", () => + checkImpls(bounds, [ + Type.ARC2, + Type.CIRCLE2, + Type.CUBIC2, + Type.ELLIPSE2, + Type.GROUP, + Type.LINE2, + Type.PATH2, + Type.POINTS2, + Type.POLYGON2, + Type.POLYLINE2, + Type.QUAD2, + Type.QUADRATIC2, + Type.RECT2, + Type.TRIANGLE2, + ])); + + it("center", () => + checkImpls(center, [ + _DEFAULT, + Type.CIRCLE2, + Type.ELLIPSE2 + ])); + + it("centroid", () => + checkImpls(centroid, [ + Type.ARC2, + Type.CIRCLE2, + Type.ELLIPSE2, + Type.GROUP, + Type.LINE2, + Type.PATH2, + Type.POINTS2, + Type.POLYGON2, + Type.POLYLINE2, + Type.QUAD2, + Type.RECT2, + Type.TRIANGLE2, + ])); + + it("classifyPoint", () => + checkImpls(classifyPoint, [ + Type.CIRCLE2, + Type.TRIANGLE2, + ])); + + it("closestPoint", () => + checkImpls(closestPoint, [ + Type.CIRCLE2, + ])); + + it("clipConvex", () => + checkImpls(clipConvex, [ + Type.POLYGON2, + Type.QUAD2, + Type.RECT2, + Type.TRIANGLE2, + ])); + + it("convexHull", () => + checkImpls(convexHull, [ + Type.POINTS2, + Type.POLYGON2, + Type.POLYLINE2, + Type.QUAD2, + Type.TRIANGLE2, + ])); + + it("depth", () => + checkImpls(depth, [ + _DEFAULT, + ])); + + it("difference", () => + checkImpls(difference, [ + Type.POLYGON2, + ])); + + it("edges", () => + checkImpls(edges, [ + Type.POLYGON2, + Type.POLYLINE2, + Type.QUAD2, + Type.RECT2, + Type.TRIANGLE2, + ])); + + it("extrude", () => + checkImpls(extrude, [ + ])); + + it("flip", () => + checkImpls(flip, [ + Type.CUBIC2, + Type.LINE2, + Type.POINTS2, + Type.POLYGON2, + Type.POLYLINE2, + Type.QUAD2, + Type.QUADRATIC2, + ])); + + it("height", () => + checkImpls(height, [ + _DEFAULT, + ])); + + it("intersection", () => + checkImpls(intersection, [ + Type.POLYGON2 + ])); + + it("intersectShape", () => + checkImpls(intersectShape, [ + ])); + + it("intersectLine", () => + checkImpls(intersectLine, [ + Type.LINE2 + ])); + + it("mapPoint", () => + checkImpls(mapPoint, [ + Type.RECT2 + ])); + + it("normalAt", () => + checkImpls(normalAt, [ + _DEFAULT, + ])); + + it("offset", () => + checkImpls(offset, [ + Type.LINE2, + Type.POLYGON2, + Type.POLYLINE2, + // TODO rect + ])); + + it("perimeter", () => + checkImpls(perimeter, [ + Type.CIRCLE2, + Type.ELLIPSE2, + Type.LINE2, + Type.POLYGON2, + Type.POLYLINE2, + Type.QUAD2, + Type.RECT2, + Type.TRIANGLE2, + ])); + + it("pointAt", () => + checkImpls(pointAt, [ + Type.ARC2, + Type.CIRCLE2, + Type.CUBIC2, + Type.ELLIPSE2, + Type.POLYGON2, + Type.QUADRATIC2, + Type.RECT2, + ])); + + it("pointInside", () => + checkImpls(pointInside, [ + Type.CIRCLE2, + Type.POLYGON2, + Type.TRIANGLE2, + Type.RECT2, + ])); + + it("resample", () => + checkImpls(resample, [ + Type.LINE2, + Type.POLYGON2, + Type.POLYLINE2, + Type.QUAD2, + Type.RECT2, + Type.TRIANGLE2, + ])); + + it("simplify", () => + checkImpls(simplify, [ + Type.PATH2, + Type.POLYGON2, + Type.POLYLINE2, + ])); + + it("splitAt", () => + checkImpls(splitAt, [ + Type.CUBIC2, + Type.QUADRATIC2, + ])); + + it("subdivide", () => + checkImpls(subdivide, [ + Type.POLYGON2, + Type.POLYLINE2 + ])); + + it("tangentAt", () => + checkImpls(tangentAt, [ + Type.LINE2, + Type.POLYGON2, + Type.POLYLINE2, + ])); + + it("tessellate", () => + checkImpls(tessellate, [ + Type.POLYGON2, + Type.QUAD2, + Type.RECT2, + Type.TRIANGLE2, + ])); + + it("transform", () => + checkImpls(transform, [ + Type.CUBIC2, + Type.LINE2, + Type.PATH2, + Type.POINTS2, + Type.POLYGON2, + Type.POLYLINE2, + Type.QUAD2, + Type.QUADRATIC2, + Type.RECT2, + Type.TRIANGLE2, + ])); + + it("translate", () => + checkImpls(translate, [ + Type.CIRCLE2, + Type.ELLIPSE2, + Type.PATH2, + Type.POLYGON2, + Type.POLYLINE2, + Type.QUAD2, + Type.RECT2, + Type.TRIANGLE2 + ])); + + it("union", () => + checkImpls(union, [ + Type.POLYGON2, + Type.RECT2, + ])); + + it("unmapPoint", () => + checkImpls(unmapPoint, [ + Type.QUAD2, + Type.RECT2, + ])); + + it("vertices", () => + checkImpls(vertices, [ + Type.ARC2, + Type.CIRCLE2, + Type.CUBIC2, + Type.ELLIPSE2, + Type.LINE2, + Type.PATH2, + Type.POINTS2, + Type.POLYGON2, + Type.POLYLINE2, + Type.QUAD2, + Type.QUADRATIC2, + Type.RECT2, + Type.TRIANGLE2, + ])); + + it("warp", () => + checkImpls(warp, [ + _DEFAULT, + ])); + + it("width", () => + checkImpls(width, [ + _DEFAULT, + ])); +}); \ No newline at end of file diff --git a/packages/geom2/test/circle.ts b/packages/geom2/test/circle.ts index 01a30cdd2c..71c39c3476 100644 --- a/packages/geom2/test/circle.ts +++ b/packages/geom2/test/circle.ts @@ -1,20 +1,20 @@ import { equiv } from "@thi.ng/equiv"; -import { PI, TAU, HALF_PI } from "@thi.ng/math/api"; +import { HALF_PI, PI, TAU } from "@thi.ng/math/api"; +import { Vec } from "@thi.ng/vectors2/api"; import { eqDeltaArray } from "@thi.ng/vectors2/internal/equiv"; import * as assert from "assert"; import { - arcLength, area, - asSVG, + asPolygon, + asSvg, + bounds, circle, Circle2, + perimeter, + Polygon2, Rect2, - bounds, - vertices, - asPolygon, - Polygon2 + vertices } from "../src/index"; -import { Vec } from "@thi.ng/vectors2/api"; describe("circle", () => { @@ -29,8 +29,8 @@ describe("circle", () => { it("area", () => assert.equal(area(a), a.r * a.r * PI)); - it("arcLength", () => - assert.equal(arcLength(a), a.r * TAU)); + it("perimeter", () => + assert.equal(perimeter(a), a.r * TAU)); it("asPolygon", () => assert(equiv(asPolygon(a, 4), new Polygon2(apts)))); @@ -46,7 +46,7 @@ describe("circle", () => { it("svg", () => { assert.equal( - asSVG(a), + asSvg(a), `` ); }); diff --git a/packages/geom2/test/clip.ts b/packages/geom2/test/clip.ts new file mode 100644 index 0000000000..25379e306c --- /dev/null +++ b/packages/geom2/test/clip.ts @@ -0,0 +1,39 @@ +import { Mat23 } from "@thi.ng/vectors2/mat23"; +import * as fs from "fs"; +import * as g from "../src"; + +const a = g.polygon([[0, 0], [35, 0], [35, 60], [65, 60], [65, 0], [100, 0], [100, 100], [0, 100]], { stroke: "red" }); +const b = g.polygon([[20, 25], [150, 80], [100, 150], [30, 110]], { stroke: "blue" }); + +fs.writeFileSync("clip-test.svg", + g.asSvg( + g.svgDoc({ + width: 600, + height: 600, + viewBox: "-10 -10 340 340", + fill: "none", + stroke: "black" + }, + g.group( + { transform: Mat23.translation(0, 0) }, + g.group({ "stroke-width": 5 }, ...g.union(a, b)), + a, b + ), + g.group( + { transform: Mat23.translation(160, 0) }, + g.group({ "stroke-width": 5 }, ...g.difference(a, b)), + a, b + ), + g.group( + { transform: Mat23.translation(0, 160) }, + g.group({ "stroke-width": 5 }, ...g.difference(b, a)), + a, b + ), + g.group( + { transform: Mat23.translation(160, 160) }, + g.group({ "stroke-width": 5 }, ...g.intersection(a, b)), + a, b + ), + ) + ) +); \ No newline at end of file From 4066c80f6af1ec19336efdcdefc63bd9efcaa8da Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 6 Nov 2018 00:03:20 +0000 Subject: [PATCH 020/333] feat(defmulti): add relations() --- packages/defmulti/src/index.ts | 36 +++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/packages/defmulti/src/index.ts b/packages/defmulti/src/index.ts index 393c424ee2..c4d40e7f68 100644 --- a/packages/defmulti/src/index.ts +++ b/packages/defmulti/src/index.ts @@ -297,8 +297,42 @@ export function defmultiN(impls: { [id: number]: Implementation }) { * @param impls */ export const implementations = (type: PropertyKey, ...impls: (MultiFn | Implementation)[]) => { - (impls.length & 1) && illegalArgs("require an even number of implementation items"); + (impls.length & 1) && illegalArgs("expected an even number of implementation items"); for (let i = 0; i < impls.length; i += 2) { (>impls[i]).add(type, impls[i + 1]); } }; + +/** + * Defines a number of `is-a` relationships for given `type` dispatch + * value. Takes a dispatch value and an object with other dispatch + * values as keys and arrays of multi-methods as their values. Then for + * each multi-method associates the given `type` with the related dispatch + * value. + * + * ``` + * area = defmulti((x) => x.type); + * bounds = defmulti((x) => x.type); + * circumference = defmulti((x) => x.type); + * + * // triangle area & circumference impls delegated to "poly" + * // triangle bounds delegated to "pointcloud" + * relations( + * "triangle", + * { + * "poly": [area, circumference], + * "pointcloud": [bounds], + * } + * ); + * ``` + * + * @param type + * @param rels + */ +export const relations = (type: PropertyKey, rels: IObjectOf[]>) => { + for (let parent in rels) { + for (let fn of rels[parent]) { + fn.isa(type, parent); + } + } +}; From c4db51aa3a62d7673ddd575f65632dc3779ded3e Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 6 Nov 2018 00:05:25 +0000 Subject: [PATCH 021/333] feat(vectors): add IMatrix & impls for Mat23/33/44, add/update accessors --- packages/vectors2/src/api.ts | 12 ++++++++ packages/vectors2/src/internal/accessors.ts | 21 ++++++++++--- packages/vectors2/src/mat23.ts | 27 ++++++++++++----- packages/vectors2/src/mat33.ts | 33 ++++++++++++++------- packages/vectors2/src/mat44.ts | 31 ++++++++++++++----- 5 files changed, 94 insertions(+), 30 deletions(-) diff --git a/packages/vectors2/src/api.ts b/packages/vectors2/src/api.ts index 6e2e5c6148..920cc83cf0 100644 --- a/packages/vectors2/src/api.ts +++ b/packages/vectors2/src/api.ts @@ -127,6 +127,18 @@ export interface INDArray extends transpose(...args: number[]): INDArray; } +export interface IMatrix extends + Vec, + ICopy, + IEqualsDelta { + + mul(m: Readonly): T; + mulV(v: ReadonlyVec, out?: Vec): Vec; + + identity(): T; + invert(): T; +} + export interface IVecPool extends IRelease { malloc(size: number, type?: Type): Vec; diff --git a/packages/vectors2/src/internal/accessors.ts b/packages/vectors2/src/internal/accessors.ts index 51b2ccb0c3..95510fdcc3 100644 --- a/packages/vectors2/src/internal/accessors.ts +++ b/packages/vectors2/src/internal/accessors.ts @@ -1,8 +1,21 @@ -export const declareIndices = (proto: any, props: string[], numeric = true) => { - const get = (i: number) => function () { return this.buf[this.i + i * this.s]; }; - const set = (i: number) => function (n: number) { this.buf[this.i + i * this.s] = n; }; +export const declareIndices = ( + proto: any, + props: string[], + strided = true, + defNumeric = true) => { + + const get = (i: number) => + strided ? + function () { return this.buf[this.i + i * this.s]; } : + function () { return this.buf[this.i + i]; }; + + const set = (i: number) => + strided ? + function (n: number) { this.buf[this.i + i * this.s] = n; } : + function (n: number) { this.buf[this.i + i] = n; }; + props.forEach((id, i) => { - numeric && Object.defineProperty(proto, i, { + defNumeric && Object.defineProperty(proto, i, { get: get(i), set: set(i), enumerable: true, diff --git a/packages/vectors2/src/mat23.ts b/packages/vectors2/src/mat23.ts index 98bec7e46f..44ff6440d7 100644 --- a/packages/vectors2/src/mat23.ts +++ b/packages/vectors2/src/mat23.ts @@ -1,15 +1,17 @@ import { isArrayLike } from "@thi.ng/checks/is-arraylike"; import { isNumber } from "@thi.ng/checks/is-number"; import { + IMatrix, Mat, ReadonlyMat, ReadonlyVec, - setS, Vec -} from "./api"; + } from "./api"; +import { declareIndices } from "./internal/accessors"; import { iterator } from "./internal/iterator"; import { cross2, dot2 } from "./internal/matrix"; import { NDArray2 } from "./nd"; +import { setS2 } from "./vec2"; export const get23 = (a: Mat, i = 0) => @@ -142,9 +144,9 @@ export const concat23 = ); export const mulV23 = - (v: Vec, m: ReadonlyMat, im = 0) => - setS( - v, + (v: ReadonlyVec, m: ReadonlyMat, out: Vec = [], im = 0) => + setS2( + out, dot2(m, v, im, 0, 2) + m[im + 4], dot2(m, v, im + 1, 0, 2) + m[im + 5], ); @@ -178,7 +180,8 @@ export const invert23 = ); } -export class Mat23 extends NDArray2 { +export class Mat23 extends NDArray2 implements + IMatrix { static identity() { return new Mat23(identity23()); @@ -240,6 +243,8 @@ export class Mat23 extends NDArray2 { ); } + [id: number]: number; + constructor(buf?: Mat, i = 0) { super(buf || [0, 0, 0, 0, 0, 0], [2, 3], [1, 2], i); } @@ -276,8 +281,8 @@ export class Mat23 extends NDArray2 { return this; } - mulV(v: Vec) { - return mulV23(v, this.buf, this.i); + mulV(v: ReadonlyVec, out?: Vec) { + return mulV23(v, this.buf, out, this.i); } determinant() { @@ -289,3 +294,9 @@ export class Mat23 extends NDArray2 { return this; } } + +declareIndices( + Mat23.prototype, + ["m00", "m01", "m10", "m11", "m20", "m21"], + false +); diff --git a/packages/vectors2/src/mat33.ts b/packages/vectors2/src/mat33.ts index 982d17fed1..67a4532aac 100644 --- a/packages/vectors2/src/mat33.ts +++ b/packages/vectors2/src/mat33.ts @@ -1,15 +1,21 @@ import { isArrayLike } from "@thi.ng/checks/is-arraylike"; import { isNumber } from "@thi.ng/checks/is-number"; import { + IMatrix, Mat, ReadonlyMat, ReadonlyVec, - setS, Vec -} from "./api"; + } from "./api"; +import { declareIndices } from "./internal/accessors"; import { iterator } from "./internal/iterator"; +import { + dot3, + set3, + setS3, + setS4 + } from "./internal/matrix"; import { NDArray2 } from "./nd"; -import { dot3, set3, setS3, setS4 } from "./internal/matrix"; export const get33 = (a: Mat, i = 0) => @@ -154,9 +160,9 @@ export const concat33 = ); export const mulV33 = - (v: Vec, m: ReadonlyMat, im = 0) => - setS( - v, + (v: Vec, m: ReadonlyMat, out: Vec = [], im = 0) => + setS3( + out, dot3(m, v, im, 0, 3), dot3(m, v, im + 1, 0, 3), dot3(m, v, im + 2, 0, 3), @@ -233,7 +239,8 @@ export const mat33to44 = m44 ); -export class Mat33 extends NDArray2 { +export class Mat33 extends NDArray2 implements + IMatrix { static identity() { return new Mat33(identity33()); @@ -269,6 +276,7 @@ export class Mat33 extends NDArray2 { ); } + [id: number]: number; constructor(buf?: Mat, i = 0) { super(buf || [0, 0, 0, 0, 0, 0, 0, 0, 0], [3, 3], [1, 3], i); @@ -308,9 +316,8 @@ export class Mat33 extends NDArray2 { return this; } - mulV(v: Vec) { - mulV33(v, this.buf, this.i); - return v; + mulV(v: ReadonlyVec, out?: Vec) { + return mulV33(v, this.buf, out, this.i); } determinant() { @@ -327,3 +334,9 @@ export class Mat33 extends NDArray2 { return this; } } + +declareIndices( + Mat33.prototype, + ["m00", "m01", "m02", "m10", "m11", "m12", "m20", "m21", "m22"], + false +); \ No newline at end of file diff --git a/packages/vectors2/src/mat44.ts b/packages/vectors2/src/mat44.ts index 7ff3ec74c6..d459841b8e 100644 --- a/packages/vectors2/src/mat44.ts +++ b/packages/vectors2/src/mat44.ts @@ -3,12 +3,14 @@ import { isNumber } from "@thi.ng/checks/is-number"; import { DEG2RAD } from "@thi.ng/math/api"; import { copy, + IMatrix, Mat, normalize, ReadonlyMat, ReadonlyVec, Vec -} from "./api"; + } from "./api"; +import { declareIndices } from "./internal/accessors"; import { iterator } from "./internal/iterator"; import { dot3, @@ -16,7 +18,7 @@ import { set3, setS3, setS4 -} from "./internal/matrix"; + } from "./internal/matrix"; import { Mat33 } from "./mat33"; import { NDArray2 } from "./nd"; import { cross3, sub3 } from "./vec3"; @@ -260,9 +262,9 @@ export const mulV344 = ); export const mulV44 = - (v: Vec, m: ReadonlyMat, im = 0) => + (v: ReadonlyVec, m: ReadonlyMat, out: Vec = [], im = 0) => setS4( - v, + out, dot4(m, v, im, 0, 4), dot4(m, v, im + 1, 0, 4), dot4(m, v, im + 2, 0, 4), @@ -418,7 +420,8 @@ export const mat44to33 = m33 ); -export class Mat44 extends NDArray2 { +export class Mat44 extends NDArray2 implements + IMatrix { static identity() { return new Mat44(identity44()); @@ -484,6 +487,8 @@ export class Mat44 extends NDArray2 { ); } + [id: number]: number; + constructor(buf?: Mat, i = 0) { super(buf || (new Array(16).fill(0)), [4, 4], [1, 4], i); } @@ -535,9 +540,8 @@ export class Mat44 extends NDArray2 { return v; } - mulV(v: Vec) { - mulV44(v, this.buf, this.i); - return v; + mulV(v: ReadonlyVec, out?: Vec) { + return mulV44(v, this.buf, out, this.i); } determinant() { @@ -566,3 +570,14 @@ export class Mat44 extends NDArray2 { return m; } } + +declareIndices( + Mat44.prototype, + [ + "m00", "m01", "m02", "m03", + "m10", "m11", "m12", "m13", + "m20", "m21", "m22", "m23", + "m30", "m31", "m32", "m33" + ], + false +); From 9d60ad0929e4fb08d2b71bc229f5cf4ced801536 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 6 Nov 2018 01:44:38 +0000 Subject: [PATCH 022/333] perf(geom): emit hline/vline segments if possible --- packages/geom2/src/api.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/geom2/src/api.ts b/packages/geom2/src/api.ts index 4e8c87cc48..9386aa1366 100644 --- a/packages/geom2/src/api.ts +++ b/packages/geom2/src/api.ts @@ -266,6 +266,8 @@ export const intersectShape = defmulti(dispatch); export const intersectLine = defmulti(dispatch); +export const isEmpty = defmulti(dispatch); + export const mapPoint: MultiFn2O = defmulti(dispatch); export const normalAt: MultiFn2O = defmulti(dispatch); @@ -597,7 +599,14 @@ export class Line2 extends PointContainer implements } toHiccupPathSegments() { - return [["L", this.points[1]]]; + const [a, b] = this.points; + return [ + a[0] === b[0] ? + ["V", b[1]] : + a[1] === b[1] ? + ["H", b[0]] : + ["L", this.points[1]] + ]; } get a() { From df9b9f9faac1656a12a16ad82fb64f440ca21deb Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 6 Nov 2018 01:45:38 +0000 Subject: [PATCH 023/333] fix(geom): asCubic() for arc --- packages/geom2/src/arc.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/geom2/src/arc.ts b/packages/geom2/src/arc.ts index 840c77baf7..5d657b2fe0 100644 --- a/packages/geom2/src/arc.ts +++ b/packages/geom2/src/arc.ts @@ -39,7 +39,7 @@ import { Rect2, SamplingOpts, Type, - vertices + vertices, } from "./api"; import "./bezier"; import { bounds as _bounds } from "./internal/bounds"; @@ -108,7 +108,7 @@ implementations( return [Cubic2.fromLine(p, q, { ...arc.attribs })]; } - const mapP = (x, y) => { + const mapP = (x: number, y: number) => { x *= rx; y *= ry; return add( @@ -116,7 +116,7 @@ implementations( cphi * x - sphi * y, sphi * x + cphi * y ], - x.pos + arc.pos ); }; From 94a40cc50dc323e3525f5d45e580851b326d7eb6 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 6 Nov 2018 01:55:59 +0000 Subject: [PATCH 024/333] fix(geom): Path2 transform() & translate(), add asCubic() impl --- packages/geom2/src/path.ts | 49 +++++++++++++++++++++++++++++--------- packages/geom2/test/api.ts | 1 + 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/packages/geom2/src/path.ts b/packages/geom2/src/path.ts index 037d3d92ae..3cc8049959 100644 --- a/packages/geom2/src/path.ts +++ b/packages/geom2/src/path.ts @@ -11,6 +11,7 @@ import { map } from "@thi.ng/transducers/xform/map"; import { mapcat } from "@thi.ng/transducers/xform/mapcat"; import { add, + addNew, copy, maddNewN, mulN, @@ -23,11 +24,13 @@ import { } from "@thi.ng/vectors2/api"; import { Mat23 } from "@thi.ng/vectors2/mat23"; import { + Arc2, asCubic, asPolygon, asPolyline, Attribs, bounds, + centroid, Cubic2, Line2, Path2, @@ -41,8 +44,7 @@ import { transform, translate, Type, - vertices, - centroid + vertices } from "./api"; import { arcFrom2Points } from "./arc"; import { collBounds } from "./internal/bounds"; @@ -163,6 +165,13 @@ export const pathFromSVG = (svg: string) => { implementations( Type.PATH2, + asCubic, + (path: Path2) => + [...mapcat( + (s) => s.geo ? asCubic(s.geo) : undefined, + path.segments + )], + asPolygon, (path: Path2, opts?: number | Partial) => new Polygon2(vertices(path, opts), { ...path.attribs }), @@ -220,14 +229,7 @@ implementations( transform, (path: Path2, mat: Mat23) => new Path2( - path.segments.map((s) => - s.geo ? - { - type: s.type, - geo: transform(s.geo, mat) - } : - { ...s } - ), + [...mapcat((s) => transformSegment(s, mat), path.segments)], { ...path.attribs } ), @@ -240,7 +242,10 @@ implementations( type: s.type, geo: translate(s.geo, delta) } : - { ...s } + { + type: s.type, + point: addNew(s.point, delta) + } ), { ...path.attribs } ), @@ -337,6 +342,7 @@ export class PathBuilder { return this; } + // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#Cubic_B%C3%A9zier_Curve cubicTo(cp1: Vec, cp2: Vec, p: Vec, relative = false) { const c2 = this.absPoint(cp2, relative); set(this.bezierP, c2); @@ -352,6 +358,7 @@ export class PathBuilder { return this; } + // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#Quadratic_B%C3%A9zier_Curve quadraticTo(cp: Vec, p: Vec, relative = false) { const c1 = this.absPoint(cp, relative); set(this.bezierP, c1); @@ -443,6 +450,26 @@ export class PathBuilder { } } +const transformSegment = (s: PathSegment, mat: Mat23): Iterable => { + if (s.geo) { + return s.geo instanceof Arc2 ? + map( + (c) => ({ + type: SegmentType.CUBIC, + geo: transform(c, mat) + }), + asCubic(s.geo) + ) : + [{ + type: s.type, + geo: transform(s.geo, mat) + }]; + } + return s.point ? + [{ type: s.type, point: mat.mulV(s.point) }] : + [{ ...s }]; +}; + const readPoint = (src: string, index: number): [Vec, number] => { let x, y; diff --git a/packages/geom2/test/api.ts b/packages/geom2/test/api.ts index 21bba56bf4..79e30ccc62 100644 --- a/packages/geom2/test/api.ts +++ b/packages/geom2/test/api.ts @@ -70,6 +70,7 @@ describe("api", () => { Type.ARC2, Type.CUBIC2, Type.LINE2, + Type.PATH2, Type.POLYLINE2, Type.QUADRATIC2, ])); From c0134fda30c474837a58e4c9fc7c205b59d5a504 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 6 Nov 2018 01:56:29 +0000 Subject: [PATCH 025/333] minor(geom): update imports --- packages/geom2/src/svg.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/geom2/src/svg.ts b/packages/geom2/src/svg.ts index cdf43e296c..648eda46ef 100644 --- a/packages/geom2/src/svg.ts +++ b/packages/geom2/src/svg.ts @@ -1,16 +1,16 @@ import { serialize } from "@thi.ng/hiccup"; import { convertTree } from "@thi.ng/hiccup-svg/convert"; -import { svg } from "@thi.ng/hiccup-svg/svg"; import { ff } from "@thi.ng/hiccup-svg/format"; +import { svg } from "@thi.ng/hiccup-svg/svg"; +import { Attribs, IShape, Rect2 } from "./api"; import { collBounds } from "./internal/bounds"; -import { IShape, Rect2 } from "./api"; export const asSvg = (...args: any[]) => args .map((x) => serialize(convertTree(x))) .join(""); -export const svgDoc = (attribs, ...args: IShape[]) => { +export const svgDoc = (attribs: Attribs, ...args: IShape[]) => { if (args.length > 0) { if (!attribs || !attribs.viewBox) { const b = collBounds(args); From 9a18620d3865af1a452a39822c2b56e15409c0dc Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 6 Nov 2018 01:57:49 +0000 Subject: [PATCH 026/333] minor(hiccup-svg): update path conversion/creation --- packages/hiccup-svg/src/convert.ts | 42 ++++++++++++------------------ packages/hiccup-svg/src/path.ts | 6 +++++ 2 files changed, 22 insertions(+), 26 deletions(-) diff --git a/packages/hiccup-svg/src/convert.ts b/packages/hiccup-svg/src/convert.ts index 4db87bceb0..5ae0abf06a 100644 --- a/packages/hiccup-svg/src/convert.ts +++ b/packages/hiccup-svg/src/convert.ts @@ -1,7 +1,6 @@ import { implementsFunction } from "@thi.ng/checks/implements-function"; import { isArray } from "@thi.ng/checks/is-array"; import { isArrayLike } from "@thi.ng/checks/is-arraylike"; -import { PathSegment } from "./api"; import { circle } from "./circle"; import { ff } from "./format"; import { linearGradient, radialGradient } from "./gradients"; @@ -10,6 +9,7 @@ import { hline, line, vline } from "./line"; import { path } from "./path"; import { points } from "./points"; import { polygon } from "./polygon"; +import { polyline } from "./polyline"; import { roundedRect } from "./rect"; import { text } from "./text"; @@ -32,11 +32,12 @@ const TEXT_ALIGN = { }; /** - * Takes a normalized hiccup tree of hdom-canvas shape definitions and - * recursively converts it into an hiccup flavor which is ready for SVG - * serialization. This conversion also involves translation & reorg of - * various attributes. Returns new tree. The original remains untouched, - * as will any unrecognized tree/shape nodes. + * Takes a normalized hiccup tree of thi.ng/geom or thi.ng/hdom-canvas + * shape definitions and recursively converts it into an hiccup flavor + * which is ready for SVG serialization. This conversion also involves + * translation & reorg of various attributes. Returns new tree. The + * original remains untouched, as will any unrecognized tree/shape + * nodes. * * @param tree */ @@ -97,24 +98,11 @@ export const convertTree = (tree: any): any[] => { case "vline": return vline(tree[2], attribs); case "polyline": + return polyline(tree[2], attribs); case "polygon": return polygon(tree[2], attribs); - case "path": { - let segments: PathSegment[] = []; - for (let seg of tree[2]) { - switch (seg[0].toLowerCase()) { - case "s": - case "t": - // TODO compute reflected control point - // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#Cubic_B%C3%A9zier_Curve - // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#Quadratic_B%C3%A9zier_Curve - break; - default: - segments.push(seg); - } - } - return path(segments, attribs); - } + case "path": + return path(tree[2], attribs); case "text": return text(tree[2], tree[3], attribs); case "img": @@ -148,11 +136,13 @@ const convertAttribs = (attribs: any) => { res["text-anchor"] = TEXT_ALIGN[v]; break; case "baseline": - // no SVG support? + // no SVG support? + break; case "filter": - // TODO needs to be translated into def first - // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/filter - // https://developer.mozilla.org/en-US/docs/Web/SVG/Element/filter + // TODO needs to be translated into def first + // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/filter + // https://developer.mozilla.org/en-US/docs/Web/SVG/Element/filter + break; case "transform": case "translate": case "rotate": diff --git a/packages/hiccup-svg/src/path.ts b/packages/hiccup-svg/src/path.ts index daffdf041c..751a4e25f4 100644 --- a/packages/hiccup-svg/src/path.ts +++ b/packages/hiccup-svg/src/path.ts @@ -8,11 +8,17 @@ export const path = (segments: PathSegment[], attribs?: any): any[] => { switch (seg[0].toLowerCase()) { case "a": res.push([ + // rx ff(seg[1]), + // ry ff(seg[2]), + // x-axis (theta) ff(seg[3]), + // xl seg[4] ? 1 : 0, + // clockwise seg[5] ? 1 : 0, + // target xy ff(seg[6][0]), ff(seg[6][1]), ].join(",")); From 9f03889b074c41e2f66f0a4557d60ae318919dff Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 6 Nov 2018 11:15:17 +0000 Subject: [PATCH 027/333] minor(geom): add/update edges()/vertices() arg types --- packages/geom2/src/circle.ts | 3 ++- packages/geom2/src/ellipse.ts | 3 ++- packages/geom2/src/polygon.ts | 6 +++--- packages/geom2/src/polyline.ts | 4 ++-- packages/geom2/src/rect.ts | 4 ++-- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/geom2/src/circle.ts b/packages/geom2/src/circle.ts index 1728b03d66..fbf00cc5b3 100644 --- a/packages/geom2/src/circle.ts +++ b/packages/geom2/src/circle.ts @@ -36,6 +36,7 @@ import { closestPoint, translate, center, + SamplingOpts, } from "./api"; export function circle(pos: Vec, r = 1, attribs?: Attribs): Circle2 { @@ -103,7 +104,7 @@ implementations( ), vertices, - (circle: Circle2, opts = DEFAULT_SAMPLES) => { + (circle: Circle2, opts: number | Partial = DEFAULT_SAMPLES) => { const buf: Vec[] = []; const pos = circle.pos; const r = circle.r; diff --git a/packages/geom2/src/ellipse.ts b/packages/geom2/src/ellipse.ts index 74d7566217..bdf4c4a4dc 100644 --- a/packages/geom2/src/ellipse.ts +++ b/packages/geom2/src/ellipse.ts @@ -29,6 +29,7 @@ import { pointAt, center, translate, + SamplingOpts, } from "./api"; export function ellipse(pos: Vec, r = ones(2), attribs?: Attribs): Ellipse2 { @@ -80,7 +81,7 @@ implementations( ), vertices, - (ellipse: Ellipse2, opts = DEFAULT_SAMPLES) => { + (ellipse: Ellipse2, opts: number | Partial = DEFAULT_SAMPLES) => { const buf: Vec[] = []; const pos = ellipse.pos; const r = ellipse.r; diff --git a/packages/geom2/src/polygon.ts b/packages/geom2/src/polygon.ts index 0e0b30e8c2..07760b02ed 100644 --- a/packages/geom2/src/polygon.ts +++ b/packages/geom2/src/polygon.ts @@ -152,7 +152,7 @@ implementations( .map((pts) => new Polygon2(pts, { ...poly.attribs })), edges, - (poly: Polygon2, opts: number | SamplingOpts) => + (poly: Polygon2, opts?: number | Partial) => _edges(vertices(poly, opts), true), intersection, @@ -187,7 +187,7 @@ implementations( }, resample, - (poly: Polygon2, opts?: number | SamplingOpts) => + (poly: Polygon2, opts?: number | Partial) => new Polygon2(vertices(poly, opts), { ...poly.attribs }), simplify, @@ -232,7 +232,7 @@ implementations( .map((pts) => new Polygon2(pts)), vertices, - (poly: Polygon2, opts?: number | SamplingOpts) => { + (poly: Polygon2, opts?: number | Partial) => { if (opts !== undefined) { const sampler = new Sampler(poly.points, true); return isPlainObject(opts) ? diff --git a/packages/geom2/src/polyline.ts b/packages/geom2/src/polyline.ts index 51380b4f27..54afdfeec1 100644 --- a/packages/geom2/src/polyline.ts +++ b/packages/geom2/src/polyline.ts @@ -83,7 +83,7 @@ implementations( (line: Polyline2) => _perimeter(line.points, false), resample, - (line: Polyline2, opts?: number | SamplingOpts) => + (line: Polyline2, opts?: number | Partial) => new Polyline2(vertices(line, opts), { ...line.attribs }), simplify, @@ -119,7 +119,7 @@ implementations( ), vertices, - (line: Polyline2, opts?: number | SamplingOpts) => { + (line: Polyline2, opts?: number | Partial) => { if (opts !== undefined) { const sampler = new Sampler(line.points, false); return isPlainObject(opts) ? diff --git a/packages/geom2/src/rect.ts b/packages/geom2/src/rect.ts index 65b822465f..0f9adbfe57 100644 --- a/packages/geom2/src/rect.ts +++ b/packages/geom2/src/rect.ts @@ -84,7 +84,7 @@ implementations( ), edges, - (rect: Rect2, opts: number | SamplingOpts) => + (rect: Rect2, opts: number | Partial) => _edges(vertices(rect, opts), true), mapPoint, @@ -138,7 +138,7 @@ implementations( }, vertices, - (rect: Rect2, opts: number | SamplingOpts) => { + (rect: Rect2, opts: number | Partial) => { const p = rect.pos; const q = addNew(p, rect.size); const verts = [copy(p), [q[0], p[1]], q, [p[0], q[1]]]; From 3713c02aed294c100fb07265c27864b9622f4667 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 6 Nov 2018 12:24:23 +0000 Subject: [PATCH 028/333] refactor(hiccup-svg): update convertTransforms(), update formatting --- packages/hiccup-svg/src/circle.ts | 15 +- packages/hiccup-svg/src/convert.ts | 298 +++++++++++++++------------ packages/hiccup-svg/src/defs.ts | 4 +- packages/hiccup-svg/src/format.ts | 12 +- packages/hiccup-svg/src/gradients.ts | 36 ++-- packages/hiccup-svg/src/group.ts | 4 +- packages/hiccup-svg/src/image.ts | 15 +- packages/hiccup-svg/src/line.ts | 27 +-- packages/hiccup-svg/src/path.ts | 75 +++---- packages/hiccup-svg/src/points.ts | 43 ++-- packages/hiccup-svg/src/polygon.ts | 5 +- packages/hiccup-svg/src/polyline.ts | 5 +- packages/hiccup-svg/src/rect.ts | 5 +- packages/hiccup-svg/src/svg.ts | 15 +- packages/hiccup-svg/src/text.ts | 13 +- 15 files changed, 311 insertions(+), 261 deletions(-) diff --git a/packages/hiccup-svg/src/circle.ts b/packages/hiccup-svg/src/circle.ts index bde7615028..a902c298d3 100644 --- a/packages/hiccup-svg/src/circle.ts +++ b/packages/hiccup-svg/src/circle.ts @@ -1,10 +1,11 @@ import { Vec2Like } from "./api"; import { ff } from "./format"; -export const circle = (p: Vec2Like, r: number, attribs?: any): any[] => - ["circle", { - cx: ff(p[0]), - cy: ff(p[1]), - r: ff(r), - ...attribs - }]; +export const circle = + (p: Vec2Like, r: number, attribs?: any): any[] => + ["circle", { + cx: ff(p[0]), + cy: ff(p[1]), + r: ff(r), + ...attribs + }]; diff --git a/packages/hiccup-svg/src/convert.ts b/packages/hiccup-svg/src/convert.ts index 5ae0abf06a..7ead6fdaa5 100644 --- a/packages/hiccup-svg/src/convert.ts +++ b/packages/hiccup-svg/src/convert.ts @@ -1,6 +1,7 @@ import { implementsFunction } from "@thi.ng/checks/implements-function"; import { isArray } from "@thi.ng/checks/is-array"; import { isArrayLike } from "@thi.ng/checks/is-arraylike"; +import { isString } from "@thi.ng/checks/is-string"; import { circle } from "./circle"; import { ff } from "./format"; import { linearGradient, radialGradient } from "./gradients"; @@ -34,148 +35,179 @@ const TEXT_ALIGN = { /** * Takes a normalized hiccup tree of thi.ng/geom or thi.ng/hdom-canvas * shape definitions and recursively converts it into an hiccup flavor - * which is ready for SVG serialization. This conversion also involves - * translation & reorg of various attributes. Returns new tree. The - * original remains untouched, as will any unrecognized tree/shape + * which is compatible for SVG serialization. This conversion also + * involves translation & reorg of various attributes. Returns new tree. + * The original remains untouched, as will any unrecognized tree/shape * nodes. * * @param tree */ -export const convertTree = (tree: any): any[] => { - if (implementsFunction(tree, "toHiccup")) { - return convertTree(tree.toHiccup()); - } - const type = tree[0]; - if (isArray(type)) { - return tree.map(convertTree); - } - let attribs = convertAttribs(tree[1]); - switch (tree[0]) { - case "svg": - case "defs": - case "g": { - const res: any[] = [type, attribs]; - for (let i = 2, n = tree.length; i < n; i++) { - const c = convertTree(tree[i]); - c != null && res.push(c); - } - return res; +export const convertTree = + (tree: any): any[] => { + if (implementsFunction(tree, "toHiccup")) { + return convertTree(tree.toHiccup()); } - case "linearGradient": - return linearGradient( - attribs.id, - attribs.from, - attribs.to, - tree[2], - { - gradientUnits: attribs.gradientUnits || "userSpaceOnUse", - gradientTransform: attribs.gradientTransform, - } - ); - case "radialGradient": - return radialGradient( - attribs.id, - attribs.from, - attribs.to, - attribs.r1, - attribs.r2, - tree[2], - { - gradientUnits: attribs.gradientUnits || "userSpaceOnUse", - gradientTransform: attribs.gradientTransform, + const type = tree[0]; + if (isArray(type)) { + return tree.map(convertTree); + } + let attribs = convertAttribs(tree[1]); + switch (tree[0]) { + case "svg": + case "defs": + case "g": { + const res: any[] = [type, attribs]; + for (let i = 2, n = tree.length; i < n; i++) { + const c = convertTree(tree[i]); + c != null && res.push(c); } - ); - case "circle": - return circle(tree[2], tree[3], attribs); - case "rect": { - const r = tree[5] || 0; - return roundedRect(tree[2], tree[3][0], tree[3][1], r, r, attribs); + return res; + } + case "linearGradient": + return linearGradient( + attribs.id, + attribs.from, + attribs.to, + tree[2], + { + gradientUnits: attribs.gradientUnits || "userSpaceOnUse", + gradientTransform: attribs.gradientTransform, + } + ); + case "radialGradient": + return radialGradient( + attribs.id, + attribs.from, + attribs.to, + attribs.r1, + attribs.r2, + tree[2], + { + gradientUnits: attribs.gradientUnits || "userSpaceOnUse", + gradientTransform: attribs.gradientTransform, + } + ); + case "circle": + return circle(tree[2], tree[3], attribs); + case "rect": { + const r = tree[5] || 0; + return roundedRect(tree[2], tree[3][0], tree[3][1], r, r, attribs); + } + case "line": + return line(tree[2], tree[3], attribs); + case "hline": + return hline(tree[2], attribs); + case "vline": + return vline(tree[2], attribs); + case "polyline": + return polyline(tree[2], attribs); + case "polygon": + return polygon(tree[2], attribs); + case "path": + return path(tree[2], attribs); + case "text": + return text(tree[2], tree[3], attribs); + case "img": + return image(tree[2], tree[3].src, attribs); + case "points": + return points(tree[2], attribs.shape, attribs.size, attribs); + default: + return tree; } - case "line": - return line(tree[2], tree[3], attribs); - case "hline": - return hline(tree[2], attribs); - case "vline": - return vline(tree[2], attribs); - case "polyline": - return polyline(tree[2], attribs); - case "polygon": - return polygon(tree[2], attribs); - case "path": - return path(tree[2], attribs); - case "text": - return text(tree[2], tree[3], attribs); - case "img": - return image(tree[2], tree[3].src, attribs); - case "points": - return points(tree[2], attribs.shape, attribs.size, attribs); - default: - return tree; - } -}; + }; -const convertAttribs = (attribs: any) => { - const res: any = convertTransforms(attribs); - for (let id in attribs) { - const v = attribs[id]; - if (ATTRIB_ALIASES[id]) { - res[ATTRIB_ALIASES[id]] = v; - } else { - switch (id) { - case "fill": - case "stroke": - res[id] = v[0] === "$" ? `url(#${v.substr(1)})` : v; - break; - case "font": { - const i = v.indexOf(" "); - res["font-size"] = v.substr(0, i); - res["font-family"] = v.substr(i + 1); - break; +const convertAttribs = + (attribs: any) => { + const res: any = convertTransforms(attribs); + for (let id in attribs) { + const v = attribs[id]; + if (ATTRIB_ALIASES[id]) { + res[ATTRIB_ALIASES[id]] = v; + } else { + switch (id) { + case "fill": + case "stroke": + res[id] = v[0] === "$" ? `url(#${v.substr(1)})` : v; + break; + case "font": { + const i = v.indexOf(" "); + res["font-size"] = v.substr(0, i); + res["font-family"] = v.substr(i + 1); + break; + } + case "align": + res["text-anchor"] = TEXT_ALIGN[v]; + break; + case "baseline": + // no SVG support? + break; + case "filter": + // TODO needs to be translated into def first + // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/filter + // https://developer.mozilla.org/en-US/docs/Web/SVG/Element/filter + break; + case "transform": + case "translate": + case "rotate": + case "scale": + break; + default: + res[id] = v; } - case "align": - res["text-anchor"] = TEXT_ALIGN[v]; - break; - case "baseline": - // no SVG support? - break; - case "filter": - // TODO needs to be translated into def first - // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/filter - // https://developer.mozilla.org/en-US/docs/Web/SVG/Element/filter - break; - case "transform": - case "translate": - case "rotate": - case "scale": - break; - default: - res[id] = v; } } - } - return res; -}; - -const convertTransforms = (attribs: any) => { - const res: any = {}; - if (!attribs) return res; - let v: any; - if ((v = attribs.transform) || - attribs.translate || - attribs.scale || - attribs.rotate) { + return res; + }; - const tx: string[] = []; - (v = attribs.transform) && tx.push(`matrix(${[...v].map(ff).join(" ")})`); - (v = attribs.translate) && tx.push(`translate(${ff(v[0])} ${ff(v[1])})`); - (v = attribs.rotate) && tx.push(`rotate(${ff(v * 180 / Math.PI)})`); - (v = attribs.scale) && - tx.push( - isArrayLike(v) ? - `scale(${ff(v[0])} ${ff(v[1])})` : - `scale(${ff(v)})` - ); - res.transform = tx.join(" "); - } - return res; -}; +/** + * Converts any transformation related attribs, i.e. `transform`, + * `rotate`, `scale`, `translate`. If the element has a `transform` + * attrib, conversion of the other attribs will be skipped, else the + * values are assumed to be either strings or: + * + * - `transform`: Mat23 or 6-element numeric array + * - `translate`: 2-element array + * - `rotate`: number (angle in radians) + * - `scale`: number (uniform scale) or 2-elem array + * + * If no `transform` is given, the resulting transformation order will + * always be TRS. Any string values given will used as-is and therefore + * need to be complete, e.g. `{ rotate: "rotate(60)" }` + * + * @param attribs + */ +const convertTransforms = + (attribs: any) => { + const res: any = {}; + if (!attribs) return res; + let v: any; + if ((v = attribs.transform) || + attribs.translate || + attribs.scale || + attribs.rotate) { + if (v) { + res.transform = !isString(v) ? + `matrix(${[...v].map(ff).join(" ")})` : + v; + } else { + const tx: string[] = []; + if (v = attribs.translate) { + tx.push(isString(v) ? v : `translate(${ff(v[0])} ${ff(v[1])})`); + } + if (v = attribs.rotate) { + tx.push(isString(v) ? v : `rotate(${ff(v * 180 / Math.PI)})`); + } + if (v = attribs.scale) { + tx.push( + isString(v) ? + v : + isArrayLike(v) ? + `scale(${ff(v[0])} ${ff(v[1])})` : + `scale(${ff(v)})` + ); + } + res.transform = tx.join(" "); + } + } + return res; + }; diff --git a/packages/hiccup-svg/src/defs.ts b/packages/hiccup-svg/src/defs.ts index fb03902b40..6a2f449e74 100644 --- a/packages/hiccup-svg/src/defs.ts +++ b/packages/hiccup-svg/src/defs.ts @@ -1,2 +1,2 @@ -export const defs = (...defs: any[]): any[] => - ["defs", {}, ...defs]; +export const defs = + (...defs: any[]): any[] => ["defs", {}, ...defs]; diff --git a/packages/hiccup-svg/src/format.ts b/packages/hiccup-svg/src/format.ts index fd1359f41b..dceba79fbf 100644 --- a/packages/hiccup-svg/src/format.ts +++ b/packages/hiccup-svg/src/format.ts @@ -2,10 +2,14 @@ import { Vec2Like } from "./api"; let PRECISION = 2; -export const setPrecision = (n: number) => (PRECISION = n); +export const setPrecision = + (n: number) => (PRECISION = n); -export const ff = (x: number) => x.toFixed(PRECISION); +export const ff = + (x: number) => x.toFixed(PRECISION); -export const fpoint = (p: Vec2Like) => ff(p[0]) + "," + ff(p[1]); +export const fpoint = + (p: Vec2Like) => ff(p[0]) + "," + ff(p[1]); -export const fpoints = (pts: Vec2Like[], sep = " ") => pts ? pts.map(fpoint).join(sep) : ""; +export const fpoints = + (pts: Vec2Like[], sep = " ") => pts ? pts.map(fpoint).join(sep) : ""; diff --git a/packages/hiccup-svg/src/gradients.ts b/packages/hiccup-svg/src/gradients.ts index f754ab6fe1..cc2131f266 100644 --- a/packages/hiccup-svg/src/gradients.ts +++ b/packages/hiccup-svg/src/gradients.ts @@ -3,24 +3,26 @@ import { ff } from "./format"; const RE_ALPHA_COLOR = /(rgb|hsl)a\(([a-z0-9.-]+),([0-9.%]+),([0-9.%]+),([0-9.]+)\)/; -const gradient = (type: string, attribs: any, stops: GradientStop[]): any[] => - [ - type, - attribs, - ...stops.map(gradientStop) - ]; +const gradient = + (type: string, attribs: any, stops: GradientStop[]): any[] => + [ + type, + attribs, + ...stops.map(gradientStop) + ]; -const gradientStop = ([offset, col]: GradientStop) => { - // use stop-opacity attrib for safari compatibility - // https://stackoverflow.com/a/26220870/294515 - let opacity: string; - const parts = RE_ALPHA_COLOR.exec(col); - if (parts) { - col = `${parts[1]}(${parts[2]},${parts[3]},${parts[4]})`; - opacity = parts[5]; - } - return ["stop", { offset, "stop-color": col, "stop-opacity": opacity }]; -}; +const gradientStop = + ([offset, col]: GradientStop) => { + // use stop-opacity attrib for safari compatibility + // https://stackoverflow.com/a/26220870/294515 + let opacity: string; + const parts = RE_ALPHA_COLOR.exec(col); + if (parts) { + col = `${parts[1]}(${parts[2]},${parts[3]},${parts[4]})`; + opacity = parts[5]; + } + return ["stop", { offset, "stop-color": col, "stop-opacity": opacity }]; + }; export const linearGradient = ( id: string, diff --git a/packages/hiccup-svg/src/group.ts b/packages/hiccup-svg/src/group.ts index 3795760626..b5b3bcc5c8 100644 --- a/packages/hiccup-svg/src/group.ts +++ b/packages/hiccup-svg/src/group.ts @@ -1,2 +1,2 @@ -export const group = (attr: any, ...body: any[]): any[] => - ["g", attr, ...body]; +export const group = + (attr: any, ...body: any[]): any[] => ["g", attr, ...body]; diff --git a/packages/hiccup-svg/src/image.ts b/packages/hiccup-svg/src/image.ts index 02b18d907a..c3536c7aaf 100644 --- a/packages/hiccup-svg/src/image.ts +++ b/packages/hiccup-svg/src/image.ts @@ -1,10 +1,11 @@ import { Vec2Like } from "./api"; import { ff } from "./format"; -export const image = (pos: Vec2Like, url: string, attribs?: any): any[] => - ["image", { - // TODO replace w/ SVG2 `href` once Safari supports it - "xlink:href": url, - x: ff(pos[0]), y: ff(pos[1]), - ...attribs - }]; +export const image = + (pos: Vec2Like, url: string, attribs?: any): any[] => + ["image", { + // TODO replace w/ SVG2 `href` once Safari supports it + "xlink:href": url, + x: ff(pos[0]), y: ff(pos[1]), + ...attribs + }]; diff --git a/packages/hiccup-svg/src/line.ts b/packages/hiccup-svg/src/line.ts index 791009211d..de925124e1 100644 --- a/packages/hiccup-svg/src/line.ts +++ b/packages/hiccup-svg/src/line.ts @@ -1,17 +1,20 @@ import { Vec2Like } from "./api"; import { ff } from "./format"; -export const line = (a: Vec2Like, b: Vec2Like, attribs?: any): any[] => - ["line", { - x1: ff(a[0]), - y1: ff(a[1]), - x2: ff(b[0]), - y2: ff(b[1]), - ...attribs - }]; +export const line = + (a: Vec2Like, b: Vec2Like, attribs?: any): any[] => + ["line", { + x1: ff(a[0]), + y1: ff(a[1]), + x2: ff(b[0]), + y2: ff(b[1]), + ...attribs + }]; -export const hline = (y: number, attribs?: any) => - line([-1e6, y], [1e6, y], attribs); +export const hline = + (y: number, attribs?: any) => + line([-1e6, y], [1e6, y], attribs); -export const vline = (x: number, attribs?: any) => - line([x, -1e6], [x, 1e6], attribs); +export const vline = + (x: number, attribs?: any) => + line([x, -1e6], [x, 1e6], attribs); diff --git a/packages/hiccup-svg/src/path.ts b/packages/hiccup-svg/src/path.ts index 751a4e25f4..d39ec6e58e 100644 --- a/packages/hiccup-svg/src/path.ts +++ b/packages/hiccup-svg/src/path.ts @@ -1,41 +1,42 @@ import { PathSegment } from "./api"; import { ff, fpoint, fpoints } from "./format"; -export const path = (segments: PathSegment[], attribs?: any): any[] => { - let res = []; - for (let seg of segments) { - res.push(seg[0]); - switch (seg[0].toLowerCase()) { - case "a": - res.push([ - // rx - ff(seg[1]), - // ry - ff(seg[2]), - // x-axis (theta) - ff(seg[3]), - // xl - seg[4] ? 1 : 0, - // clockwise - seg[5] ? 1 : 0, - // target xy - ff(seg[6][0]), - ff(seg[6][1]), - ].join(",")); - break; - case "h": - case "v": - res.push(ff(seg[1])); - break; - case "m": - case "l": - res.push(fpoint(seg[1])); - break; - case "z": - break; - default: - res.push(fpoints((seg).slice(1), ",")); +export const path = + (segments: PathSegment[], attribs?: any): any[] => { + let res = []; + for (let seg of segments) { + res.push(seg[0]); + switch (seg[0].toLowerCase()) { + case "a": + res.push([ + // rx + ff(seg[1]), + // ry + ff(seg[2]), + // x-axis (theta) + ff(seg[3]), + // xl + seg[4] ? 1 : 0, + // clockwise + seg[5] ? 1 : 0, + // target xy + ff(seg[6][0]), + ff(seg[6][1]), + ].join(",")); + break; + case "h": + case "v": + res.push(ff(seg[1])); + break; + case "m": + case "l": + res.push(fpoint(seg[1])); + break; + case "z": + break; + default: + res.push(fpoints((seg).slice(1), ",")); + } } - } - return ["path", { ...attribs, d: res.join("") }]; -}; + return ["path", { ...attribs, d: res.join("") }]; + }; diff --git a/packages/hiccup-svg/src/points.ts b/packages/hiccup-svg/src/points.ts index bcf110be8d..9e27d618b5 100644 --- a/packages/hiccup-svg/src/points.ts +++ b/packages/hiccup-svg/src/points.ts @@ -12,24 +12,25 @@ import { ff } from "./format"; * @param size * @param attribs */ -export const points = (pts: Iterable, shape: string, size = 1, attribs?: any): any[] => { - const group = ["g", attribs]; - let href: string; - if (!shape || shape[0] !== "#") { - const r = ff(size); - href = "_" + ((Math.random() * 1e6) | 0).toString(36); - group.push(["g", { opacity: 0 }, - shape === "circle" ? - ["circle", { id: href, cx: 0, cy: 0, r: r }] : - ["rect", { id: href, x: 0, y: 0, width: r, height: r }] - ]); - href = "#" + href; - } else { - href = shape; - } - for (let p of pts) { - // TODO replace w/ SVG2 `href` once Safari supports it - group.push(["use", { "xlink:href": href, x: ff(p[0]), y: ff(p[1]) }]); - } - return group; -}; +export const points = + (pts: Iterable, shape: string, size = 1, attribs?: any): any[] => { + const group = ["g", attribs]; + let href: string; + if (!shape || shape[0] !== "#") { + const r = ff(size); + href = "_" + ((Math.random() * 1e6) | 0).toString(36); + group.push(["g", { opacity: 0 }, + shape === "circle" ? + ["circle", { id: href, cx: 0, cy: 0, r: r }] : + ["rect", { id: href, x: 0, y: 0, width: r, height: r }] + ]); + href = "#" + href; + } else { + href = shape; + } + for (let p of pts) { + // TODO replace w/ SVG2 `href` once Safari supports it + group.push(["use", { "xlink:href": href, x: ff(p[0]), y: ff(p[1]) }]); + } + return group; + }; diff --git a/packages/hiccup-svg/src/polygon.ts b/packages/hiccup-svg/src/polygon.ts index 566b13786a..f3b593ae2f 100644 --- a/packages/hiccup-svg/src/polygon.ts +++ b/packages/hiccup-svg/src/polygon.ts @@ -1,5 +1,6 @@ import { Vec2Like } from "./api"; import { fpoints } from "./format"; -export const polygon = (pts: Vec2Like[], attribs?: any): any[] => - ["polygon", { points: fpoints(pts), ...attribs }]; +export const polygon = + (pts: Vec2Like[], attribs?: any): any[] => + ["polygon", { points: fpoints(pts), ...attribs }]; diff --git a/packages/hiccup-svg/src/polyline.ts b/packages/hiccup-svg/src/polyline.ts index d27a056443..5ea000444a 100644 --- a/packages/hiccup-svg/src/polyline.ts +++ b/packages/hiccup-svg/src/polyline.ts @@ -1,5 +1,6 @@ import { Vec2Like } from "./api"; import { fpoints } from "./format"; -export const polyline = (pts: Vec2Like[], attribs?: any): any[] => - ["polyline", { points: fpoints(pts), ...attribs }]; +export const polyline = + (pts: Vec2Like[], attribs?: any): any[] => + ["polyline", { points: fpoints(pts), ...attribs }]; diff --git a/packages/hiccup-svg/src/rect.ts b/packages/hiccup-svg/src/rect.ts index 65decabbc3..81338dcd45 100644 --- a/packages/hiccup-svg/src/rect.ts +++ b/packages/hiccup-svg/src/rect.ts @@ -1,8 +1,9 @@ import { Vec2Like } from "./api"; import { ff } from "./format"; -export const rect = (p: Vec2Like, width: number, height: number, attribs?: any) => - roundedRect(p, width, height, 0, 0, attribs); +export const rect = + (p: Vec2Like, width: number, height: number, attribs?: any) => + roundedRect(p, width, height, 0, 0, attribs); export const roundedRect = ( p: Vec2Like, diff --git a/packages/hiccup-svg/src/svg.ts b/packages/hiccup-svg/src/svg.ts index ba20816ee1..4df09bc8d0 100644 --- a/packages/hiccup-svg/src/svg.ts +++ b/packages/hiccup-svg/src/svg.ts @@ -8,10 +8,11 @@ import { SVG_NS, XLINK_NS } from "@thi.ng/hiccup/api"; * @param attribs * @param body */ -export const svg = (attribs: any, ...body: any[]): any[] => - ["svg", { - version: "1.1", - xmlns: SVG_NS, - "xmlns:xlink": XLINK_NS, - ...attribs - }, ...body]; +export const svg = + (attribs: any, ...body: any[]): any[] => + ["svg", { + version: "1.1", + xmlns: SVG_NS, + "xmlns:xlink": XLINK_NS, + ...attribs + }, ...body]; diff --git a/packages/hiccup-svg/src/text.ts b/packages/hiccup-svg/src/text.ts index b453a33c58..9ee29591f9 100644 --- a/packages/hiccup-svg/src/text.ts +++ b/packages/hiccup-svg/src/text.ts @@ -1,9 +1,10 @@ import { Vec2Like } from "./api"; import { ff } from "./format"; -export const text = (p: Vec2Like, body: string, attribs?: any): any[] => - ["text", { - x: ff(p[0]), - y: ff(p[1]), - ...attribs - }, body]; +export const text = + (p: Vec2Like, body: string, attribs?: any): any[] => + ["text", { + x: ff(p[0]), + y: ff(p[1]), + ...attribs + }, body]; From a24715e717e3bc596be100c1cb574850019625f0 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 6 Nov 2018 13:40:30 +0000 Subject: [PATCH 029/333] refactor(defmulti): merge relations() w/ implementations(), update readme --- packages/defmulti/README.md | 62 +++++++++++++----- packages/defmulti/src/index.ts | 114 +++++++++++++++++---------------- 2 files changed, 104 insertions(+), 72 deletions(-) diff --git a/packages/defmulti/README.md b/packages/defmulti/README.md index 4262b1b5f7..94d33a462f 100644 --- a/packages/defmulti/README.md +++ b/packages/defmulti/README.md @@ -43,7 +43,8 @@ return type) and the generics will also apply to all implementations. If more than 8 args are required, `defmulti` will fall back to an untyped varargs solution. -The function returned by `defmulti` can be called like any other function, but also exposes the following operations: +The function returned by `defmulti` can be called like any other +function, but also exposes the following operations: - `.add(id, fn)` - adds new implementation for given dispatch value - `.remove(id)` - removes implementation for dispatch value @@ -122,33 +123,60 @@ foo.rels(); ### implementations() -Intended for multi-methods sharing same dispatch values / logic. -Takes a dispatch value and a number of multi-methods, each with an -implementation for the given dispatch value. Then for each -multi-method associates the related implementation with the given -dispatch value. +Syntax-sugar intended for sets of multi-methods sharing same dispatch +values / logic. Takes a dispatch value, an object of "is-a" +relationships and a number of multi-methods, each with an implementation +for the given dispatch value. -```ts -const dispatch = (x) => x.id; +The relations object has dispatch values (parents) as keys and arrays of +multi-methods as their values. For each multi-method associates the +given `type` with the related parent dispatch value to delegate to its +implementation (see `.isa()` above). + +The remaining implementations are associated with their related +multi-method and the given `type` dispatch value. -const foo = defmulti(dispatch); -const bar = defmulti(dispatch); +```ts +foo = defmulti((x) => x.id); +bar = defmulti((x) => x.id); +bax = defmulti((x) => x.id); +baz = defmulti((x) => x.id); -// batch define implementations for dispatch value "a" +// define impls for dispatch value `a` implementations( - "a", + "a", + + // delegate bax & baz impls to dispatch val `b` + { + b: [bax, baz] + }, + + // concrete multi-fn impls + foo, + (x) => `foo: ${x.val}`, + bar, + (x) => `bar: ${x.val.toUpperCase()}` +); - foo, - (x) => `foo: ${x.val}`, +// some parent impls for bax & baz +bax.add("b", (x) => `bax: ${x.id}`); +baz.add("c", (x) => `baz: ${x.id}`); - bar, - (x) => `bar: ${x.val.toUpperCase()}` -); +// delegate to use "c" impl for "b" +baz.isa("b", "c"); foo({ id: "a", val: "alice" }); // "foo: alice" bar({ id: "a", val: "alice" }); // "bar: ALICE" +bax({ id: "a", val: "alice" }); // "bax: a" +baz({ id: "a", val: "alice" }); // "baz: a" + +baz.impls(); // Set { "c", "a", "b" } ``` +Also see the WIP package +[@thi.ng/geom2](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/geom2) +for a concreate realworld usage example. + ### defmultiN() Returns a multi-dispatch function which delegates to one of the provided diff --git a/packages/defmulti/src/index.ts b/packages/defmulti/src/index.ts index c4d40e7f68..ecdacd8f34 100644 --- a/packages/defmulti/src/index.ts +++ b/packages/defmulti/src/index.ts @@ -262,77 +262,81 @@ const makeRels = (spec: AncestorDefs) => { * * @param impls */ -export function defmultiN(impls: { [id: number]: Implementation }) { - const fn = defmulti((...args: any[]) => args.length); - fn.add(DEFAULT, (...args) => illegalArity(args.length)); - for (let id in impls) { - fn.add(id, impls[id]); - } - return fn; -} +export const defmultiN = + (impls: { [id: number]: Implementation }) => { + const fn = defmulti((...args: any[]) => args.length); + fn.add(DEFAULT, (...args) => illegalArity(args.length)); + for (let id in impls) { + fn.add(id, impls[id]); + } + return fn; + }; /** - * Intended for multi-methods sharing same dispatch values / logic. - * Takes a dispatch value and a number of multi-methods, each with an - * implementation for the given dispatch value. Then for each - * multi-method associates the related implementation with the given - * dispatch value. + * Syntax-sugar intended for sets of multi-methods sharing same dispatch + * values / logic. Takes a dispatch value, an object of "is-a" + * relationships and a number of multi-methods, each with an + * implementation for the given dispatch value. + * + * The relations object has dispatch values (parents) as keys and arrays + * of multi-methods as their values. For each multi-method associates + * the given `type` with the related parent dispatch value to delegate + * to its implementation. + * + * The remaining implementations are associated with their related + * multi-method and the given `type` dispatch value. * * ``` * foo = defmulti((x) => x.id); * bar = defmulti((x) => x.id); + * bax = defmulti((x) => x.id); + * baz = defmulti((x) => x.id); * + * // define impls for dispatch value `a` * implementations( * "a", * - * foo, (x) => `foo: ${x.val}`, - * bar, (x) => `bar: ${x.val.toUpperCase()}` - * ) + * // delegate bax & baz impls to dispatch val `b` + * { + * b: [bax, baz] + * }, * - * foo({ id: "a", val: "alice" }); // "foo: alice" - * bar({ id: "a", val: "alice" }); // "bar: ALICE" - * ``` + * // concrete multi-fn impls + * foo, + * (x) => `foo: ${x.val}`, * - * @param type - * @param impls - */ -export const implementations = (type: PropertyKey, ...impls: (MultiFn | Implementation)[]) => { - (impls.length & 1) && illegalArgs("expected an even number of implementation items"); - for (let i = 0; i < impls.length; i += 2) { - (>impls[i]).add(type, impls[i + 1]); - } -}; - -/** - * Defines a number of `is-a` relationships for given `type` dispatch - * value. Takes a dispatch value and an object with other dispatch - * values as keys and arrays of multi-methods as their values. Then for - * each multi-method associates the given `type` with the related dispatch - * value. + * bar, + * (x) => `bar: ${x.val.toUpperCase()}` + * ); * - * ``` - * area = defmulti((x) => x.type); - * bounds = defmulti((x) => x.type); - * circumference = defmulti((x) => x.type); + * // add parent impls + * bax.add("b", (x) => `bax: ${x.id}`); + * baz.add("c", (x) => `baz: ${x.id}`); + * // use "c" impl for "b" + * baz.isa("b", "c"); * - * // triangle area & circumference impls delegated to "poly" - * // triangle bounds delegated to "pointcloud" - * relations( - * "triangle", - * { - * "poly": [area, circumference], - * "pointcloud": [bounds], - * } - * ); + * foo({ id: "a", val: "alice" }); // "foo: alice" + * bar({ id: "a", val: "alice" }); // "bar: ALICE" + * bax({ id: "a", val: "alice" }); // "bax: a" + * baz({ id: "a", val: "alice" }); // "baz: a" + * + * baz.impls(); // Set { "c", "a", "b" } * ``` * * @param type - * @param rels + * @param impls */ -export const relations = (type: PropertyKey, rels: IObjectOf[]>) => { - for (let parent in rels) { - for (let fn of rels[parent]) { - fn.isa(type, parent); +export const implementations = + (type: PropertyKey, rels: IObjectOf[]>, ...impls: (MultiFn | Implementation)[]) => { + (impls.length & 1) && illegalArgs("expected an even number of implementation items"); + if (rels) { + for (let parent in rels) { + for (let fn of rels[parent]) { + fn.isa(type, parent); + } + } } - } -}; + for (let i = 0; i < impls.length; i += 2) { + (>impls[i]).add(type, impls[i + 1]); + } + }; From dc2c487d8eb161cba970c54cd2a7114e08c06504 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 6 Nov 2018 13:43:29 +0000 Subject: [PATCH 030/333] refactor(geom): update implementations() call sites --- packages/geom2/src/arc.ts | 8 +++++--- packages/geom2/src/bezier.ts | 20 +++++++------------- packages/geom2/src/circle.ts | 2 ++ packages/geom2/src/container2.ts | 2 ++ packages/geom2/src/ellipse.ts | 2 ++ packages/geom2/src/group.ts | 2 ++ packages/geom2/src/line.ts | 13 ++++--------- packages/geom2/src/path.ts | 2 ++ packages/geom2/src/polygon.ts | 13 ++++--------- packages/geom2/src/polyline.ts | 13 ++++--------- packages/geom2/src/quad.ts | 13 ++++--------- packages/geom2/src/rect.ts | 13 ++++--------- packages/geom2/src/triangle.ts | 13 ++++--------- 13 files changed, 46 insertions(+), 70 deletions(-) diff --git a/packages/geom2/src/arc.ts b/packages/geom2/src/arc.ts index 5d657b2fe0..be9e2c14bb 100644 --- a/packages/geom2/src/arc.ts +++ b/packages/geom2/src/arc.ts @@ -27,6 +27,9 @@ import { Vec } from "@thi.ng/vectors2/api"; import { Vec2 } from "@thi.ng/vectors2/vec2"; +import "./bezier"; +import { bounds as _bounds } from "./internal/bounds"; +import { Sampler } from "./internal/sampler"; import { Arc2, asCubic, @@ -41,9 +44,6 @@ import { Type, vertices, } from "./api"; -import "./bezier"; -import { bounds as _bounds } from "./internal/bounds"; -import { Sampler } from "./internal/sampler"; export function arc(pos: Vec, r: Vec, axis: number, start: number, end: number, xl: boolean, clockwise: boolean, attribs?: Attribs): Arc2 { return new Arc2(pos, r, axis, start, end, xl, clockwise, attribs); @@ -96,6 +96,8 @@ export function arcFrom2Points( implementations( Type.ARC2, + null, + asCubic, (arc: Arc2) => { const p = arc.pointAtTheta(arc.start); diff --git a/packages/geom2/src/bezier.ts b/packages/geom2/src/bezier.ts index 953ec1359d..2f849877ec 100644 --- a/packages/geom2/src/bezier.ts +++ b/packages/geom2/src/bezier.ts @@ -1,6 +1,6 @@ import { isNumber } from "@thi.ng/checks/is-number"; import { isPlainObject } from "@thi.ng/checks/is-plain-object"; -import { implementations, relations } from "@thi.ng/defmulti"; +import { implementations } from "@thi.ng/defmulti"; import { clamp01 } from "@thi.ng/math/interval"; import { mixCubic as _mixC, mixQuadratic as _mixQ } from "@thi.ng/math/mix"; import { @@ -112,17 +112,14 @@ const cubicAxisBounds = (pa: number, pb: number, pc: number, pd: number) => { return [l, h]; }; -relations( +implementations( Type.CUBIC2, + { [Type.POINTS2]: [ flip, ] - } -); - -implementations( - Type.CUBIC2, + }, asCubic, (curve: Cubic2) => [curve], @@ -199,17 +196,14 @@ implementations( } ); -relations( +implementations( Type.QUADRATIC2, + { [Type.POINTS2]: [ flip, ] - } -); - -implementations( - Type.QUADRATIC2, + }, asCubic, (curve: Quadratic2) => { diff --git a/packages/geom2/src/circle.ts b/packages/geom2/src/circle.ts index fbf00cc5b3..59a9516c43 100644 --- a/packages/geom2/src/circle.ts +++ b/packages/geom2/src/circle.ts @@ -58,6 +58,8 @@ export const circleFrom3Points = implementations( Type.CIRCLE2, + null, + area, (circle: Circle2) => PI * circle.r * circle.r, diff --git a/packages/geom2/src/container2.ts b/packages/geom2/src/container2.ts index 138aae4a96..75818af37c 100644 --- a/packages/geom2/src/container2.ts +++ b/packages/geom2/src/container2.ts @@ -27,6 +27,8 @@ export function points(points: Vec[], attribs?: Attribs) { implementations( Type.POINTS2, + null, + bounds, (pc: PointContainer) => Rect2.fromMinMax(..._bounds(pc.points, [...Vec2.MAX], [...Vec2.MIN])), diff --git a/packages/geom2/src/ellipse.ts b/packages/geom2/src/ellipse.ts index bdf4c4a4dc..16473e4ef9 100644 --- a/packages/geom2/src/ellipse.ts +++ b/packages/geom2/src/ellipse.ts @@ -39,6 +39,8 @@ export function ellipse(pos: Vec, r = ones(2), attribs?: Attribs): Ellipse2 { implementations( Type.ELLIPSE2, + null, + area, (ellipse: Ellipse2) => PI * ellipse.r[0] * ellipse.r[1], diff --git a/packages/geom2/src/group.ts b/packages/geom2/src/group.ts index 5ffc313489..a292df94d3 100644 --- a/packages/geom2/src/group.ts +++ b/packages/geom2/src/group.ts @@ -17,6 +17,8 @@ export function group(attribs?: Attribs, ...children: IShape[]) { implementations( Type.GROUP, + null, + area, (g: Group2) => area(bounds(g)), diff --git a/packages/geom2/src/line.ts b/packages/geom2/src/line.ts index 6f5cf247b6..34462c488e 100644 --- a/packages/geom2/src/line.ts +++ b/packages/geom2/src/line.ts @@ -1,4 +1,4 @@ -import { implementations, relations } from "@thi.ng/defmulti"; +import { implementations } from "@thi.ng/defmulti"; import { dist, mixNewN, @@ -42,10 +42,9 @@ export function line(a: Vec, b: Vec, attribs?: Attribs) { export const lineNormal = (a: ReadonlyVec, b: ReadonlyVec, out?: Vec) => subNew(b, a, out); -const type = Type.LINE2; +implementations( + Type.LINE2, -relations( - type, { [Type.POINTS2]: [ flip, @@ -54,11 +53,7 @@ relations( resample, vertices, ], - } -); - -implementations( - type, + }, asCubic, (line: Line2) => diff --git a/packages/geom2/src/path.ts b/packages/geom2/src/path.ts index 3cc8049959..0a84b30357 100644 --- a/packages/geom2/src/path.ts +++ b/packages/geom2/src/path.ts @@ -165,6 +165,8 @@ export const pathFromSVG = (svg: string) => { implementations( Type.PATH2, + null, + asCubic, (path: Path2) => [...mapcat( diff --git a/packages/geom2/src/polygon.ts b/packages/geom2/src/polygon.ts index 07760b02ed..156a56ccb1 100644 --- a/packages/geom2/src/polygon.ts +++ b/packages/geom2/src/polygon.ts @@ -1,5 +1,5 @@ import { isPlainObject } from "@thi.ng/checks/is-plain-object"; -import { implementations, relations } from "@thi.ng/defmulti"; +import { implementations } from "@thi.ng/defmulti"; import { TAU } from "@thi.ng/math/api"; import { Reducer } from "@thi.ng/transducers/api"; import { cycle } from "@thi.ng/transducers/iter/cycle"; @@ -109,10 +109,9 @@ export const convexity = (poly: Polygon2) => { type !== 0 ? Convexity.CONVEX : Convexity.COLINEAR; }; -const type = Type.POLYGON2; +implementations( + Type.POLYGON2, -relations( - type, { [Type.POINTS2]: [ bounds, @@ -120,11 +119,7 @@ relations( flip, vertices ] - } -); - -implementations( - type, + }, area, (poly: Polygon2, signed = true) => { diff --git a/packages/geom2/src/polyline.ts b/packages/geom2/src/polyline.ts index 54afdfeec1..4bdc1f1010 100644 --- a/packages/geom2/src/polyline.ts +++ b/packages/geom2/src/polyline.ts @@ -1,5 +1,5 @@ import { isPlainObject } from "@thi.ng/checks/is-plain-object"; -import { implementations, relations } from "@thi.ng/defmulti"; +import { implementations } from "@thi.ng/defmulti"; import { addNew, ReadonlyVec, @@ -46,10 +46,9 @@ export function polyline(points: Vec[], attribs?: Attribs): Polyline2 { return new Polyline2(points, attribs); } -const type = Type.POLYLINE2; +implementations( + Type.POLYLINE2, -relations( - type, { [Type.POINTS2]: [ bounds, @@ -57,11 +56,7 @@ relations( convexHull, flip ], - } -); - -implementations( - type, + }, asCubic, (line: Polyline2) => diff --git a/packages/geom2/src/quad.ts b/packages/geom2/src/quad.ts index 4a3e6992ff..21634eeb56 100644 --- a/packages/geom2/src/quad.ts +++ b/packages/geom2/src/quad.ts @@ -1,4 +1,4 @@ -import { implementations, relations } from "@thi.ng/defmulti"; +import { implementations } from "@thi.ng/defmulti"; import { addNew, ReadonlyVec, Vec } from "@thi.ng/vectors2/api"; import { Mat23 } from "@thi.ng/vectors2/mat23"; import { mixBilinear2 } from "@thi.ng/vectors2/vec2"; @@ -29,10 +29,9 @@ export function quad(points: Vec[], attribs?: Attribs): Quad2 { return new Quad2(points, attribs); } -const type = Type.QUAD2; +implementations( + Type.QUAD2, -relations( - type, { [Type.POINTS2]: [ bounds, @@ -49,11 +48,7 @@ relations( tessellate, vertices, ], - } -); - -implementations( - type, + }, transform, (quad: Quad2, mat: Mat23) => diff --git a/packages/geom2/src/rect.ts b/packages/geom2/src/rect.ts index 0f9adbfe57..9677382756 100644 --- a/packages/geom2/src/rect.ts +++ b/packages/geom2/src/rect.ts @@ -1,4 +1,4 @@ -import { implementations, relations } from "@thi.ng/defmulti"; +import { implementations } from "@thi.ng/defmulti"; import { addNew, copy, @@ -53,19 +53,14 @@ export function rect(pos: Vec, size: Vec, attribs?: Attribs) { export const rectFromMinMax = (min: Vec, max: Vec, attribs?: Attribs) => Rect2.fromMinMax(min, max, attribs); -const type = Type.RECT2; +implementations( + Type.RECT2, -relations( - type, { [Type.POLYGON2]: [ resample, ] - } -); - -implementations( - type, + }, area, (rect: Rect2) => rect.size[0] * rect.size[1], diff --git a/packages/geom2/src/triangle.ts b/packages/geom2/src/triangle.ts index a03cbcc78d..6821dabe57 100644 --- a/packages/geom2/src/triangle.ts +++ b/packages/geom2/src/triangle.ts @@ -1,4 +1,4 @@ -import { implementations, relations } from "@thi.ng/defmulti"; +import { implementations } from "@thi.ng/defmulti"; import { PI } from "@thi.ng/math/api"; import { add, @@ -45,10 +45,9 @@ export const equilateralTriangle = (a: Vec, b: Vec) => { return new Triangle2([a, b, maddN(c, dir, 0.5)]); }; -const type = Type.TRIANGLE2; +implementations( + Type.TRIANGLE2, -relations( - type, { [Type.POINTS2]: [ bounds, @@ -61,11 +60,7 @@ relations( tessellate, vertices, ] - } -); - -implementations( - type, + }, area, (tri: Triangle2, signed = true) => { From 34930b31b525d8831626865b39f7ee97862c56b6 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 7 Nov 2018 15:26:06 +0000 Subject: [PATCH 031/333] refactor(malloc): update package structure, fix stats() - move MemPool to pool.ts - update stats().available to incl. size of free blocks --- packages/malloc/src/api.ts | 15 ++ packages/malloc/src/index.ts | 271 +---------------------------------- packages/malloc/src/pool.ts | 271 +++++++++++++++++++++++++++++++++++ 3 files changed, 287 insertions(+), 270 deletions(-) create mode 100644 packages/malloc/src/pool.ts diff --git a/packages/malloc/src/api.ts b/packages/malloc/src/api.ts index 2ecfd0692f..b3a8c7ff83 100644 --- a/packages/malloc/src/api.ts +++ b/packages/malloc/src/api.ts @@ -27,10 +27,25 @@ export interface MemPoolOpts { } export interface MemPoolStats { + /** + * Free block stats. + */ free: { count: number, size: number }; + /** + * Used block stats. + */ used: { count: number, size: number }; + /** + * Current top address. + */ top: number; + /** + * Bytes available + */ available: number; + /** + * Total pool size. + */ total: number; } diff --git a/packages/malloc/src/index.ts b/packages/malloc/src/index.ts index b31143079b..73537bab37 100644 --- a/packages/malloc/src/index.ts +++ b/packages/malloc/src/index.ts @@ -1,271 +1,2 @@ -import { IObjectOf, TypedArray } from "@thi.ng/api"; -import { align } from "@thi.ng/binary/align"; -import { isNumber } from "@thi.ng/checks/is-number"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { - IMemPool, - MemBlock, - MemPoolOpts, - Type, - MemPoolStats -} from "./api"; - export * from "./api"; - -type BlockCtor = (buf: ArrayBuffer, addr: number, num: number) => TypedArray; - -const CTORS: IObjectOf = { - [Type.U8]: (buf, addr, num) => new Uint8Array(buf, addr, num), - [Type.U8C]: (buf, addr, num) => new Uint8ClampedArray(buf, addr, num), - [Type.I8]: (buf, addr, num) => new Int8Array(buf, addr, num), - [Type.U16]: (buf, addr, num) => new Uint16Array(buf, addr, num), - [Type.I16]: (buf, addr, num) => new Int16Array(buf, addr, num), - [Type.U32]: (buf, addr, num) => new Uint32Array(buf, addr, num), - [Type.I32]: (buf, addr, num) => new Int32Array(buf, addr, num), - [Type.F32]: (buf, addr, num) => new Float32Array(buf, addr, num), - [Type.F64]: (buf, addr, num) => new Float64Array(buf, addr, num), -}; - -const SIZEOF = { - [Type.U8]: 1, - [Type.U8C]: 1, - [Type.I8]: 1, - [Type.U16]: 2, - [Type.I16]: 2, - [Type.U32]: 4, - [Type.I32]: 4, - [Type.F32]: 4, - [Type.F64]: 8, -}; - -export class MemPool implements - IMemPool { - - buf: ArrayBuffer; - protected top: number; - protected start: number; - protected end: number; - protected doCompact: boolean; - protected doSplit: boolean; - protected minSplit: number; - protected _free: MemBlock; - protected _used: MemBlock; - - protected u8: Uint8Array; - - constructor(buf: number | ArrayBuffer, opts: Partial = {}) { - this.buf = isNumber(buf) ? new ArrayBuffer(buf) : buf; - this.u8 = new Uint8Array(this.buf); - this.start = opts.start != null ? - align(Math.max(opts.start, 8), 8) : - 8; - this.end = opts.end != null ? - Math.min(opts.end, this.buf.byteLength) : - this.buf.byteLength; - if (this.start >= this.end) { - illegalArgs(`invalid address range (0x${this.start.toString(16)} - 0x${this.end.toString(16)})`); - } - this.top = this.start; - this.doCompact = opts.compact !== false; - this.doSplit = opts.split !== false; - this.minSplit = opts.minSplit || 16; - this._free = null; - this._used = null; - } - - stats(): MemPoolStats { - const listStats = (block: MemBlock) => { - let count = 0; - let size = 0; - while (block) { - count++; - size += block.size; - block = block.next; - } - return { count, size }; - }; - return { - free: listStats(this._free), - used: listStats(this._used), - top: this.top, - available: this.end - this.top, - total: this.buf.byteLength - }; - } - - callocAs(type: Type, num: number): TypedArray { - const block = this.mallocAs(type, num); - block && block.fill(0); - return block; - } - - mallocAs(type: Type, num: number): TypedArray { - const addr = this.malloc(num * SIZEOF[type]); - return addr ? - CTORS[type](this.buf, addr, num) : - null; - } - - calloc(size: number): number { - const addr = this.malloc(size); - addr && this.u8.fill(0, addr, align(addr + size, 8)); - return addr; - } - - malloc(size: number): number { - if (size <= 0) { - return 0; - } - size = align(size, 8); - let top = this.top; - const end = this.end; - let block = this._free; - let prev = null; - while (block) { - const isTop = block.addr + block.size >= top; - if (isTop || block.size >= size) { - if (isTop && this.doCompact && block.addr + size > end) { - return 0; - } - if (prev) { - prev.next = block.next; - } else { - this._free = block.next; - } - block.next = this._used; - this._used = block; - if (isTop) { - block.size = size; - this.top = block.addr + size; - } else if (this.doSplit) { - const excess = block.size - size; - if (excess >= this.minSplit) { - block.size = size; - this.insert({ - addr: block.addr + size, - size: excess, - next: null - }); - this.doCompact && this.compact(); - } - } - return block.addr; - } - prev = block; - block = block.next; - } - const addr = align(top, 8); - top = addr + size; - if (top <= end) { - block = { - addr, - size, - next: this._used - }; - this._used = block; - this.top = top; - return addr; - } - return 0; - } - - free(ptr: number | TypedArray) { - let addr: number; - if (!isNumber(ptr)) { - if (ptr.buffer !== this.buf) { - return false; - } - addr = ptr.byteOffset; - } else { - addr = ptr; - } - let block = this._used; - let prev: MemBlock = null; - while (block) { - if (block.addr === addr) { - if (prev) { - prev.next = block.next; - } else { - this._used = block.next; - } - this.insert(block); - this.doCompact && this.compact(); - return true; - } - prev = block; - block = block.next; - } - return false; - } - - freeAll() { - this._free = null; - this._used = null; - this.top = this.start; - } - - release() { - delete this._free; - delete this._used; - delete this.u8; - delete this.buf; - delete this.top; - delete this.start; - delete this.end; - return true; - } - - protected compact() { - let block = this._free; - let prev: MemBlock; - let scan: MemBlock; - let res = false; - while (block) { - prev = block; - scan = block.next; - while (scan && prev.addr + prev.size === scan.addr) { - // console.log("merge:", scan.addr, scan.size); - prev = scan; - scan = scan.next; - } - if (prev !== block) { - const newSize = prev.addr - block.addr + prev.size; - // console.log("merged size:", newSize); - block.size = newSize; - const next = prev.next; - let tmp = block.next; - while (tmp !== prev.next) { - // console.log("release:", tmp.addr); - const tn = tmp.next; - tmp.next = null; - tmp = tn; - } - block.next = next; - res = true; - } - block = block.next; - } - return res; - } - - protected insert(block: MemBlock) { - let ptr = this._free; - if (!this.doCompact) { - block.next = ptr; - this._free = block; - return; - } - let prev: MemBlock = null; - while (ptr) { - if (block.addr <= ptr.addr) break; - prev = ptr; - ptr = ptr.next; - } - if (prev) { - prev.next = block; - } else { - this._free = block; - } - block.next = ptr; - } -} +export * from "./pool"; diff --git a/packages/malloc/src/pool.ts b/packages/malloc/src/pool.ts new file mode 100644 index 0000000000..79e49c6e6c --- /dev/null +++ b/packages/malloc/src/pool.ts @@ -0,0 +1,271 @@ +import { IObjectOf, TypedArray } from "@thi.ng/api"; +import { align } from "@thi.ng/binary/align"; +import { isNumber } from "@thi.ng/checks/is-number"; +import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { + IMemPool, + MemBlock, + MemPoolOpts, + Type, + MemPoolStats +} from "./api"; + +type BlockCtor = + (buf: ArrayBuffer, addr: number, num: number) => TypedArray; + +const CTORS: IObjectOf = { + [Type.U8]: (buf, addr, num) => new Uint8Array(buf, addr, num), + [Type.U8C]: (buf, addr, num) => new Uint8ClampedArray(buf, addr, num), + [Type.I8]: (buf, addr, num) => new Int8Array(buf, addr, num), + [Type.U16]: (buf, addr, num) => new Uint16Array(buf, addr, num), + [Type.I16]: (buf, addr, num) => new Int16Array(buf, addr, num), + [Type.U32]: (buf, addr, num) => new Uint32Array(buf, addr, num), + [Type.I32]: (buf, addr, num) => new Int32Array(buf, addr, num), + [Type.F32]: (buf, addr, num) => new Float32Array(buf, addr, num), + [Type.F64]: (buf, addr, num) => new Float64Array(buf, addr, num), +}; + +const SIZEOF = { + [Type.U8]: 1, + [Type.U8C]: 1, + [Type.I8]: 1, + [Type.U16]: 2, + [Type.I16]: 2, + [Type.U32]: 4, + [Type.I32]: 4, + [Type.F32]: 4, + [Type.F64]: 8, +}; + +export class MemPool implements + IMemPool { + + buf: ArrayBuffer; + protected top: number; + protected start: number; + protected end: number; + protected doCompact: boolean; + protected doSplit: boolean; + protected minSplit: number; + protected _free: MemBlock; + protected _used: MemBlock; + + protected u8: Uint8Array; + + constructor(buf: number | ArrayBuffer, opts: Partial = {}) { + this.buf = isNumber(buf) ? new ArrayBuffer(buf) : buf; + this.u8 = new Uint8Array(this.buf); + this.start = opts.start != null ? + align(Math.max(opts.start, 8), 8) : + 8; + this.end = opts.end != null ? + Math.min(opts.end, this.buf.byteLength) : + this.buf.byteLength; + if (this.start >= this.end) { + illegalArgs(`invalid address range (0x${this.start.toString(16)} - 0x${this.end.toString(16)})`); + } + this.top = this.start; + this.doCompact = opts.compact !== false; + this.doSplit = opts.split !== false; + this.minSplit = opts.minSplit || 16; + this._free = null; + this._used = null; + } + + stats(): MemPoolStats { + const listStats = (block: MemBlock) => { + let count = 0; + let size = 0; + while (block) { + count++; + size += block.size; + block = block.next; + } + return { count, size }; + }; + const free = listStats(this._free); + return { + free, + used: listStats(this._used), + top: this.top, + available: this.end - this.top + free.size, + total: this.buf.byteLength + }; + } + + callocAs(type: Type, num: number): TypedArray { + const block = this.mallocAs(type, num); + block && block.fill(0); + return block; + } + + mallocAs(type: Type, num: number): TypedArray { + const addr = this.malloc(num * SIZEOF[type]); + return addr ? + CTORS[type](this.buf, addr, num) : + null; + } + + calloc(size: number): number { + const addr = this.malloc(size); + addr && this.u8.fill(0, addr, align(addr + size, 8)); + return addr; + } + + malloc(size: number): number { + if (size <= 0) { + return 0; + } + size = align(size, 8); + let top = this.top; + const end = this.end; + let block = this._free; + let prev = null; + while (block) { + const isTop = block.addr + block.size >= top; + if (isTop || block.size >= size) { + if (isTop && this.doCompact && block.addr + size > end) { + return 0; + } + if (prev) { + prev.next = block.next; + } else { + this._free = block.next; + } + block.next = this._used; + this._used = block; + if (isTop) { + block.size = size; + this.top = block.addr + size; + } else if (this.doSplit) { + const excess = block.size - size; + if (excess >= this.minSplit) { + block.size = size; + this.insert({ + addr: block.addr + size, + size: excess, + next: null + }); + this.doCompact && this.compact(); + } + } + return block.addr; + } + prev = block; + block = block.next; + } + const addr = align(top, 8); + top = addr + size; + if (top <= end) { + block = { + addr, + size, + next: this._used + }; + this._used = block; + this.top = top; + return addr; + } + return 0; + } + + free(ptr: number | TypedArray) { + let addr: number; + if (!isNumber(ptr)) { + if (ptr.buffer !== this.buf) { + return false; + } + addr = ptr.byteOffset; + } else { + addr = ptr; + } + let block = this._used; + let prev: MemBlock = null; + while (block) { + if (block.addr === addr) { + if (prev) { + prev.next = block.next; + } else { + this._used = block.next; + } + this.insert(block); + this.doCompact && this.compact(); + return true; + } + prev = block; + block = block.next; + } + return false; + } + + freeAll() { + this._free = null; + this._used = null; + this.top = this.start; + } + + release() { + delete this._free; + delete this._used; + delete this.u8; + delete this.buf; + delete this.top; + delete this.start; + delete this.end; + return true; + } + + protected compact() { + let block = this._free; + let prev: MemBlock; + let scan: MemBlock; + let res = false; + while (block) { + prev = block; + scan = block.next; + while (scan && prev.addr + prev.size === scan.addr) { + // console.log("merge:", scan.addr, scan.size); + prev = scan; + scan = scan.next; + } + if (prev !== block) { + const newSize = prev.addr - block.addr + prev.size; + // console.log("merged size:", newSize); + block.size = newSize; + const next = prev.next; + let tmp = block.next; + while (tmp !== prev.next) { + // console.log("release:", tmp.addr); + const tn = tmp.next; + tmp.next = null; + tmp = tn; + } + block.next = next; + res = true; + } + block = block.next; + } + return res; + } + + protected insert(block: MemBlock) { + let ptr = this._free; + if (!this.doCompact) { + block.next = ptr; + this._free = block; + return; + } + let prev: MemBlock = null; + while (ptr) { + if (block.addr <= ptr.addr) break; + prev = ptr; + ptr = ptr.next; + } + if (prev) { + prev.next = block; + } else { + this._free = block; + } + block.next = ptr; + } +} From 5a3b860e555d93fa6be091e9899ca63add2c4f2e Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 7 Nov 2018 15:35:08 +0000 Subject: [PATCH 032/333] feat(vectors): update VecPool & NDArray1 - add VecPool.mallocArray() - add NDArray1.mapBuffer()/intoBuffer() --- packages/vectors2/package.json | 3 +- packages/vectors2/src/api.ts | 6 ++-- packages/vectors2/src/nd.ts | 21 +++++++++++ packages/vectors2/src/pool.ts | 64 ++++++++++++++++++++++++++++------ 4 files changed, 80 insertions(+), 14 deletions(-) diff --git a/packages/vectors2/package.json b/packages/vectors2/package.json index 2110cdebaa..1cb38405b1 100644 --- a/packages/vectors2/package.json +++ b/packages/vectors2/package.json @@ -34,7 +34,8 @@ "@thi.ng/errors": "^0.1.11", "@thi.ng/malloc": "^0.2.0", "@thi.ng/math": "^0.2.0", - "@thi.ng/strings": "^0.5.2" + "@thi.ng/strings": "^0.5.2", + "@thi.ng/transducers": "^2.2.1" }, "keywords": [ "ES6", diff --git a/packages/vectors2/src/api.ts b/packages/vectors2/src/api.ts index 920cc83cf0..cceb2c57f4 100644 --- a/packages/vectors2/src/api.ts +++ b/packages/vectors2/src/api.ts @@ -141,9 +141,11 @@ export interface IMatrix extends export interface IVecPool extends IRelease { - malloc(size: number, type?: Type): Vec; + malloc(size: number, type?: Type): TypedArray; - mallocWrapped(size: number, stride?: number, type?: Type): IVector; + mallocWrapped(size: number, stride?: number, type?: Type): Vec; + + mallocArray(num: number, size: number, cstride?: number, estride?: number, type?: Type): Vec[]; free(vec: IVector | TypedArray): boolean; diff --git a/packages/vectors2/src/nd.ts b/packages/vectors2/src/nd.ts index 8b6cefe7c8..54254d92ab 100644 --- a/packages/vectors2/src/nd.ts +++ b/packages/vectors2/src/nd.ts @@ -17,6 +17,27 @@ import { iterator } from "./internal/iterator"; export class NDArray1 implements INDArray { + static mapBuffer(buf: NDVec, num: number, size: number, start = 0, cstride = 1, estride = size) { + const res: NDArray1[] = []; + while (--num >= 0) { + res.push(new NDArray1(buf, [size], [cstride], start)); + start += estride; + } + return res; + } + + static intoBuffer(buf: NDVec, src: Iterable>, start: number, cstride: number, estride: number) { + for (let v of src) { + let i = start; + for (let x of v) { + buf[i] = x; + i += cstride; + } + start += estride; + } + return buf; + } + buf: NDVec; i: number; s: number; diff --git a/packages/vectors2/src/pool.ts b/packages/vectors2/src/pool.ts index 17f0c07f2f..f509f30810 100644 --- a/packages/vectors2/src/pool.ts +++ b/packages/vectors2/src/pool.ts @@ -1,4 +1,4 @@ -import { TypedArray } from "@thi.ng/api"; +import { NumericArray, TypedArray } from "@thi.ng/api"; import { isTypedArray } from "@thi.ng/checks/is-typedarray"; import { MemPool, @@ -7,8 +7,10 @@ import { Type } from "@thi.ng/malloc"; import { IVecPool, IVector, Vec } from "./api"; +import { NDArray1 } from "./nd"; import { Vec2 } from "./vec2"; import { Vec3 } from "./vec3"; +import { Vec4 } from "./vec4"; const F64 = Type.F64; @@ -29,22 +31,48 @@ export class VecPool implements return this.pool.stats(); } - malloc(size: number, type: Type = F64): Vec { + malloc(size: number, type: Type = F64): TypedArray { return this.pool.callocAs(type, size); } - mallocWrapped(size: number, stride = 1, type: Type = F64): IVector { + mallocWrapped(size: number, stride = 1, type: Type = F64): Vec { const buf = this.pool.callocAs(type, size * stride); + return wrapped(buf, size, 0, stride); + + } + + /** + * Intended to provide individual vector views of a larger + * underlying buffer. Attempts to allocate a single block of + * sufficient memory to hold `num` vectors of `size` elements and if + * successful returns array of vectors mapping the buffer with given + * stride lengths (both component and element strides can be + * provided). + * + * *Note:* Since all result vectors share the same continuous memory + * block, freeing any of them from the pool will invalidate all of + * them. + * + * Also see: + * - `Vec2.mapBuffer()` + * - `Vec3.mapBuffer()` + * - `Vec4.mapBuffer()` + * - `NDArray1.mapBuffer()` + * + * @param num + * @param size + * @param cstride + * @param estride + * @param type + */ + mallocArray(num: number, size: number, cstride = 1, estride = size, type: Type = F64): Vec[] { + const buf = this.malloc(Math.max(cstride, estride, size) * num, type); if (!buf) return; - switch (size) { - case 2: - return new Vec2(buf, 0, stride); - case 3: - return new Vec3(buf, 0, stride); - case 4: - default: - // TODO add Vec4 & GVec + const res: Vec[] = []; + for (let i = 0; i < num; i += estride) { + res.push(wrapped(buf, size, i, cstride)); } + return res; } free(vec: IVector | TypedArray) { @@ -67,3 +95,17 @@ export class VecPool implements return res; } } + +const wrapped = + (buf: NumericArray, size: number, idx: number, stride: number) => { + switch (size) { + case 2: + return new Vec2(buf, idx, stride); + case 3: + return new Vec3(buf, idx, stride); + case 4: + return new Vec4(buf, idx, stride); + default: + return new NDArray1(buf, [size], [stride], idx); + } + }; From 3f7fe2ad5cb56be4681a80700e0ad1d66c76edda Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 24 Nov 2018 15:58:32 +0000 Subject: [PATCH 033/333] build(vectors): update deps --- packages/vectors2/package.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/vectors2/package.json b/packages/vectors2/package.json index 1cb38405b1..129342e389 100644 --- a/packages/vectors2/package.json +++ b/packages/vectors2/package.json @@ -33,9 +33,10 @@ "@thi.ng/equiv": "^0.1.13", "@thi.ng/errors": "^0.1.11", "@thi.ng/malloc": "^0.2.0", - "@thi.ng/math": "^0.2.0", - "@thi.ng/strings": "^0.5.2", - "@thi.ng/transducers": "^2.2.1" + "@thi.ng/math": "^0.2.1", + "@thi.ng/random": "^0.1.0", + "@thi.ng/strings": "^0.6.0", + "@thi.ng/transducers": "^2.2.2" }, "keywords": [ "ES6", From 26d41996c9ccfeac1316e2629c40af17f4a5ff46 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 25 Nov 2018 14:59:28 +0000 Subject: [PATCH 034/333] feat(vectors): add yet another version of vectors package --- packages/vectors3/.npmignore | 11 + packages/vectors3/LICENSE | 201 +++++++++++++++++++ packages/vectors3/README.md | 40 ++++ packages/vectors3/package.json | 52 +++++ packages/vectors3/src/abs.ts | 5 + packages/vectors3/src/acos.ts | 5 + packages/vectors3/src/add.ts | 5 + packages/vectors3/src/addn.ts | 5 + packages/vectors3/src/angle-between.ts | 16 ++ packages/vectors3/src/api.ts | 56 ++++++ packages/vectors3/src/asin.ts | 5 + packages/vectors3/src/bisect.ts | 9 + packages/vectors3/src/cartesian.ts | 31 +++ packages/vectors3/src/ceil.ts | 5 + packages/vectors3/src/codegen.ts | 151 ++++++++++++++ packages/vectors3/src/compare.ts | 57 ++++++ packages/vectors3/src/copy.ts | 8 + packages/vectors3/src/cos.ts | 5 + packages/vectors3/src/cross.ts | 15 ++ packages/vectors3/src/dist-chebyshev.ts | 33 +++ packages/vectors3/src/dist-manhattan.ts | 34 ++++ packages/vectors3/src/dist.ts | 6 + packages/vectors3/src/distsq.ts | 20 ++ packages/vectors3/src/div.ts | 5 + packages/vectors3/src/divn.ts | 5 + packages/vectors3/src/dot.ts | 28 +++ packages/vectors3/src/empty.ts | 9 + packages/vectors3/src/eqdelta.ts | 71 +++++++ packages/vectors3/src/exp.ts | 5 + packages/vectors3/src/floor.ts | 5 + packages/vectors3/src/fract.ts | 6 + packages/vectors3/src/heading.ts | 8 + packages/vectors3/src/index.ts | 68 +++++++ packages/vectors3/src/invert.ts | 5 + packages/vectors3/src/limit.ts | 9 + packages/vectors3/src/log.ts | 5 + packages/vectors3/src/madd.ts | 8 + packages/vectors3/src/maddn.ts | 8 + packages/vectors3/src/mag.ts | 5 + packages/vectors3/src/magsq.ts | 28 +++ packages/vectors3/src/major.ts | 23 +++ packages/vectors3/src/max.ts | 5 + packages/vectors3/src/min.ts | 5 + packages/vectors3/src/minor.ts | 23 +++ packages/vectors3/src/mix-bilinear.ts | 10 + packages/vectors3/src/mix.ts | 8 + packages/vectors3/src/mixn.ts | 8 + packages/vectors3/src/mod.ts | 5 + packages/vectors3/src/modn.ts | 5 + packages/vectors3/src/mul.ts | 5 + packages/vectors3/src/muln.ts | 5 + packages/vectors3/src/neg.ts | 5 + packages/vectors3/src/normalize.ts | 10 + packages/vectors3/src/ortho-normal.ts | 7 + packages/vectors3/src/perpendicular.ts | 17 ++ packages/vectors3/src/polar.ts | 27 +++ packages/vectors3/src/pow.ts | 5 + packages/vectors3/src/pown.ts | 5 + packages/vectors3/src/random.ts | 20 ++ packages/vectors3/src/rotate-around-axis.ts | 28 +++ packages/vectors3/src/rotate-around-point.ts | 12 ++ packages/vectors3/src/rotate.ts | 19 ++ packages/vectors3/src/set.ts | 5 + packages/vectors3/src/setn.ts | 11 + packages/vectors3/src/sign.ts | 5 + packages/vectors3/src/sin.ts | 5 + packages/vectors3/src/smoothstep.ts | 10 + packages/vectors3/src/sqrt.ts | 5 + packages/vectors3/src/step.ts | 10 + packages/vectors3/src/sub.ts | 5 + packages/vectors3/src/subn.ts | 5 + packages/vectors3/src/swizzle.ts | 13 ++ packages/vectors3/src/tan.ts | 5 + packages/vectors3/src/trunc.ts | 5 + packages/vectors3/src/vop.ts | 24 +++ packages/vectors3/test/index.ts | 6 + packages/vectors3/test/tsconfig.json | 10 + packages/vectors3/tsconfig.json | 10 + 78 files changed, 1444 insertions(+) create mode 100644 packages/vectors3/.npmignore create mode 100644 packages/vectors3/LICENSE create mode 100644 packages/vectors3/README.md create mode 100644 packages/vectors3/package.json create mode 100644 packages/vectors3/src/abs.ts create mode 100644 packages/vectors3/src/acos.ts create mode 100644 packages/vectors3/src/add.ts create mode 100644 packages/vectors3/src/addn.ts create mode 100644 packages/vectors3/src/angle-between.ts create mode 100644 packages/vectors3/src/api.ts create mode 100644 packages/vectors3/src/asin.ts create mode 100644 packages/vectors3/src/bisect.ts create mode 100644 packages/vectors3/src/cartesian.ts create mode 100644 packages/vectors3/src/ceil.ts create mode 100644 packages/vectors3/src/codegen.ts create mode 100644 packages/vectors3/src/compare.ts create mode 100644 packages/vectors3/src/copy.ts create mode 100644 packages/vectors3/src/cos.ts create mode 100644 packages/vectors3/src/cross.ts create mode 100644 packages/vectors3/src/dist-chebyshev.ts create mode 100644 packages/vectors3/src/dist-manhattan.ts create mode 100644 packages/vectors3/src/dist.ts create mode 100644 packages/vectors3/src/distsq.ts create mode 100644 packages/vectors3/src/div.ts create mode 100644 packages/vectors3/src/divn.ts create mode 100644 packages/vectors3/src/dot.ts create mode 100644 packages/vectors3/src/empty.ts create mode 100644 packages/vectors3/src/eqdelta.ts create mode 100644 packages/vectors3/src/exp.ts create mode 100644 packages/vectors3/src/floor.ts create mode 100644 packages/vectors3/src/fract.ts create mode 100644 packages/vectors3/src/heading.ts create mode 100644 packages/vectors3/src/index.ts create mode 100644 packages/vectors3/src/invert.ts create mode 100644 packages/vectors3/src/limit.ts create mode 100644 packages/vectors3/src/log.ts create mode 100644 packages/vectors3/src/madd.ts create mode 100644 packages/vectors3/src/maddn.ts create mode 100644 packages/vectors3/src/mag.ts create mode 100644 packages/vectors3/src/magsq.ts create mode 100644 packages/vectors3/src/major.ts create mode 100644 packages/vectors3/src/max.ts create mode 100644 packages/vectors3/src/min.ts create mode 100644 packages/vectors3/src/minor.ts create mode 100644 packages/vectors3/src/mix-bilinear.ts create mode 100644 packages/vectors3/src/mix.ts create mode 100644 packages/vectors3/src/mixn.ts create mode 100644 packages/vectors3/src/mod.ts create mode 100644 packages/vectors3/src/modn.ts create mode 100644 packages/vectors3/src/mul.ts create mode 100644 packages/vectors3/src/muln.ts create mode 100644 packages/vectors3/src/neg.ts create mode 100644 packages/vectors3/src/normalize.ts create mode 100644 packages/vectors3/src/ortho-normal.ts create mode 100644 packages/vectors3/src/perpendicular.ts create mode 100644 packages/vectors3/src/polar.ts create mode 100644 packages/vectors3/src/pow.ts create mode 100644 packages/vectors3/src/pown.ts create mode 100644 packages/vectors3/src/random.ts create mode 100644 packages/vectors3/src/rotate-around-axis.ts create mode 100644 packages/vectors3/src/rotate-around-point.ts create mode 100644 packages/vectors3/src/rotate.ts create mode 100644 packages/vectors3/src/set.ts create mode 100644 packages/vectors3/src/setn.ts create mode 100644 packages/vectors3/src/sign.ts create mode 100644 packages/vectors3/src/sin.ts create mode 100644 packages/vectors3/src/smoothstep.ts create mode 100644 packages/vectors3/src/sqrt.ts create mode 100644 packages/vectors3/src/step.ts create mode 100644 packages/vectors3/src/sub.ts create mode 100644 packages/vectors3/src/subn.ts create mode 100644 packages/vectors3/src/swizzle.ts create mode 100644 packages/vectors3/src/tan.ts create mode 100644 packages/vectors3/src/trunc.ts create mode 100644 packages/vectors3/src/vop.ts create mode 100644 packages/vectors3/test/index.ts create mode 100644 packages/vectors3/test/tsconfig.json create mode 100644 packages/vectors3/tsconfig.json diff --git a/packages/vectors3/.npmignore b/packages/vectors3/.npmignore new file mode 100644 index 0000000000..ec83d74c9d --- /dev/null +++ b/packages/vectors3/.npmignore @@ -0,0 +1,11 @@ +build +coverage +dev +doc +export +src* +test +.nyc_output +tsconfig.json +*.tgz +*.html diff --git a/packages/vectors3/LICENSE b/packages/vectors3/LICENSE new file mode 100644 index 0000000000..8dada3edaf --- /dev/null +++ b/packages/vectors3/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/vectors3/README.md b/packages/vectors3/README.md new file mode 100644 index 0000000000..74e319094d --- /dev/null +++ b/packages/vectors3/README.md @@ -0,0 +1,40 @@ +# @thi.ng/vectors3 + +[![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/vectors3.svg)](https://www.npmjs.com/package/@thi.ng/vectors3) +![npm downloads](https://img.shields.io/npm/dm/@thi.ng/vectors3.svg) +[![Twitter Follow](https://img.shields.io/twitter/follow/thing_umbrella.svg?style=flat-square&label=twitter)](https://twitter.com/thing_umbrella) + +This project is part of the +[@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo. + + + + + +## About + +TODO... + +## Installation + +```bash +yarn add @thi.ng/vectors3 +``` + +## Dependencies + +- TODO... + +## Usage examples + +```ts +import * as v from "@thi.ng/vectors3"; +``` + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/packages/vectors3/package.json b/packages/vectors3/package.json new file mode 100644 index 0000000000..f53515f018 --- /dev/null +++ b/packages/vectors3/package.json @@ -0,0 +1,52 @@ +{ + "name": "@thi.ng/vectors3", + "version": "0.0.1", + "description": "Optimized 2d/3d/4d and arbitrary length vector operations", + "main": "./index.js", + "typings": "./index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/thi-ng/umbrella.git" + }, + "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/vectors3", + "author": "Karsten Schmidt ", + "license": "Apache-2.0", + "scripts": { + "build": "yarn run clean && tsc --declaration", + "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "cover": "yarn test && nyc report --reporter=lcov", + "doc": "node_modules/.bin/typedoc --mode modules --out doc src", + "pub": "yarn run build && yarn publish --access public", + "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + }, + "devDependencies": { + "@types/mocha": "^5.2.5", + "@types/node": "^10.12.0", + "mocha": "^5.2.0", + "nyc": "^13.1.0", + "typedoc": "^0.13.0", + "typescript": "^3.1.3" + }, + "dependencies": { + "@thi.ng/api": "^4.2.3", + "@thi.ng/checks": "^1.5.13", + "@thi.ng/equiv": "^0.1.13", + "@thi.ng/errors": "^0.1.11", + "@thi.ng/math": "^0.2.1", + "@thi.ng/random": "^0.1.0", + "@thi.ng/transducers": "^2.2.2" + }, + "keywords": [ + "algebra", + "code generator", + "data structures", + "ES6", + "geometry", + "typescript", + "webgl", + "vector" + ], + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/packages/vectors3/src/abs.ts b/packages/vectors3/src/abs.ts new file mode 100644 index 0000000000..aad77f2c0f --- /dev/null +++ b/packages/vectors3/src/abs.ts @@ -0,0 +1,5 @@ +import { MultiVecOpV, VecOpV } from "./api"; +import { defFnOp } from "./codegen"; + +export const [abs, abs2, abs3, abs4] = + defFnOp("Math.abs"); diff --git a/packages/vectors3/src/acos.ts b/packages/vectors3/src/acos.ts new file mode 100644 index 0000000000..4336b53f3f --- /dev/null +++ b/packages/vectors3/src/acos.ts @@ -0,0 +1,5 @@ +import { MultiVecOpV, VecOpV } from "./api"; +import { defFnOp } from "./codegen"; + +export const [acos, acos2, acos3, acos4] = + defFnOp("Math.acos"); diff --git a/packages/vectors3/src/add.ts b/packages/vectors3/src/add.ts new file mode 100644 index 0000000000..7b1a3a7261 --- /dev/null +++ b/packages/vectors3/src/add.ts @@ -0,0 +1,5 @@ +import { MultiVecOpVV, VecOpVV } from "./api"; +import { defOp } from "./codegen"; + +export const [add, add2, add3, add4] = + defOp(([o, a, b]) => `${o}=${a}+${b};`); diff --git a/packages/vectors3/src/addn.ts b/packages/vectors3/src/addn.ts new file mode 100644 index 0000000000..234b7411df --- /dev/null +++ b/packages/vectors3/src/addn.ts @@ -0,0 +1,5 @@ +import { MultiVecOpVN, VecOpVN } from "./api"; +import { defOp } from "./codegen"; + +export const [addN, addN2, addN3, addN4] = + defOp(([o, a]) => `${o}=${a}+n;`, "o,a,n"); diff --git a/packages/vectors3/src/angle-between.ts b/packages/vectors3/src/angle-between.ts new file mode 100644 index 0000000000..060f005e04 --- /dev/null +++ b/packages/vectors3/src/angle-between.ts @@ -0,0 +1,16 @@ +import { absTheta } from "@thi.ng/math/angle"; +import { ReadonlyVec } from "./api"; +import { dot } from "./dot"; +import { mag } from "./mag"; + +export const angleRatio = + (a: ReadonlyVec, b: ReadonlyVec) => + dot(a, b) / (mag(a) * mag(b)); + +export const angleBetween = + (a: ReadonlyVec, b: ReadonlyVec, normalize = true) => + absTheta( + normalize ? + Math.acos(angleRatio(a, b)) : + Math.acos(dot(a, b)) + ); diff --git a/packages/vectors3/src/api.ts b/packages/vectors3/src/api.ts new file mode 100644 index 0000000000..67dce8e848 --- /dev/null +++ b/packages/vectors3/src/api.ts @@ -0,0 +1,56 @@ +import { ILength } from "@thi.ng/api/api"; + +export interface Vec extends + Iterable, + ILength { + + [id: number]: number; +} + +export interface ReadonlyVec extends + Iterable, + ILength { + readonly [id: number]: number; +} + +export interface MultiVecOp { + add(dim: number, op: VOP): VOP; + default(op: VOP): VOP; +} + +export type VecOpV = (out: Vec, a: ReadonlyVec) => Vec; +export type VecOpN = (out: Vec, n: number) => Vec; +export type VecOpVV = (out: Vec, a: ReadonlyVec, b: ReadonlyVec) => Vec; +export type VecOpVN = (out: Vec, a: ReadonlyVec, n: number) => Vec; +export type VecOpVVV = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => Vec; +export type VecOpVVN = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, n: number) => Vec; +export type VecOpVVVVNN = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, u: number, v: number) => Vec; + +export type VecOpVO = (out: Vec, a: ReadonlyVec, b?: T) => Vec; +export type VecOpOO = (out: Vec, a?: A, b?: B) => Vec; +export type VecOpOOO = (out: Vec, a?: A, b?: B, c?: C) => Vec; +export type VecOpNNO = (out: Vec, a: number, b: number, c: T) => Vec; + +export type VecOpRoV = (a: ReadonlyVec) => T; +export type VecOpRoVV = (a: ReadonlyVec, b: ReadonlyVec) => T; +export type VecOpRoVVO = (a: ReadonlyVec, b: ReadonlyVec, c: O) => T; + +export interface MultiVecOpV extends VecOpV, MultiVecOp { } +export interface MultiVecOpN extends VecOpN, MultiVecOp { } +export interface MultiVecOpVV extends VecOpVV, MultiVecOp { } +export interface MultiVecOpVN extends VecOpVN, MultiVecOp { } +export interface MultiVecOpVVV extends VecOpVVV, MultiVecOp { } +export interface MultiVecOpVVN extends VecOpVVN, MultiVecOp { } +export interface MultiVecOpVVVVNN extends VecOpVVVVNN, MultiVecOp { } + +export interface MultiVecOpVO extends VecOpVO, MultiVecOp> { } +export interface MultiVecOpOO extends VecOpOO, MultiVecOp> { } +export interface MultiVecOpOOO extends VecOpOOO, MultiVecOp> { } +export interface MultiVecOpNNO extends VecOpNNO, MultiVecOp> { } + +export interface MultiVecOpRoV extends VecOpRoV, MultiVecOp> { } +export interface MultiVecOpRoVV extends VecOpRoVV, MultiVecOp> { } +export interface MultiVecOpRoVVO extends VecOpRoVVO, MultiVecOp> { } + +export const ZERO4 = Object.freeze([0, 0, 0, 0]); +export const ONE4 = Object.freeze([1, 1, 1, 1]); diff --git a/packages/vectors3/src/asin.ts b/packages/vectors3/src/asin.ts new file mode 100644 index 0000000000..4c6275ed3d --- /dev/null +++ b/packages/vectors3/src/asin.ts @@ -0,0 +1,5 @@ +import { MultiVecOpV, VecOpV } from "./api"; +import { defFnOp } from "./codegen"; + +export const [asin, asin2, asin3, asin4] = + defFnOp("Math.asin"); diff --git a/packages/vectors3/src/bisect.ts b/packages/vectors3/src/bisect.ts new file mode 100644 index 0000000000..f0f50fb068 --- /dev/null +++ b/packages/vectors3/src/bisect.ts @@ -0,0 +1,9 @@ +import { HALF_PI, PI } from "@thi.ng/math/api"; +import { VecOpRoVV } from "./api"; +import { headingXY } from "./heading"; + +export const bisect2: VecOpRoVV = + (a, b) => { + const theta = (headingXY(a) + headingXY(b)) / 2; + return theta <= HALF_PI ? theta : PI - theta; + }; diff --git a/packages/vectors3/src/cartesian.ts b/packages/vectors3/src/cartesian.ts new file mode 100644 index 0000000000..468ce3fa53 --- /dev/null +++ b/packages/vectors3/src/cartesian.ts @@ -0,0 +1,31 @@ +import { MultiVecOpVO, ReadonlyVec, ZERO4 } from "./api"; +import { vop } from "./vop"; + +const cos = Math.cos; +const sin = Math.sin; + +export const cartesian: MultiVecOpVO = vop(1); + +export const cartesian2 = + cartesian.add(2, + (out, a, b = ZERO4) => { + const r = a[0]; + const t = a[1]; + out[0] = r * cos(t) + b[0]; + out[1] = r * sin(t) + b[1]; + return out; + }); + +export const cartesian3 = + cartesian.add(3, + (out, a, b = ZERO4) => { + const r = a[0]; + const theta = a[1]; + const phi = a[2]; + const ct = cos(theta); + + out[0] = r * ct * cos(phi) + b[0]; + out[1] = r * ct * sin(phi) + b[1]; + out[2] = r * sin(theta) + b[2]; + return out; + }); diff --git a/packages/vectors3/src/ceil.ts b/packages/vectors3/src/ceil.ts new file mode 100644 index 0000000000..26e61dba43 --- /dev/null +++ b/packages/vectors3/src/ceil.ts @@ -0,0 +1,5 @@ +import { MultiVecOpV, VecOpV } from "./api"; +import { defFnOp } from "./codegen"; + +export const [ceil, ceil2, ceil3, ceil4] = + defFnOp("Math.ceil"); diff --git a/packages/vectors3/src/codegen.ts b/packages/vectors3/src/codegen.ts new file mode 100644 index 0000000000..8bacecbe50 --- /dev/null +++ b/packages/vectors3/src/codegen.ts @@ -0,0 +1,151 @@ +import { comp } from "@thi.ng/transducers/func/comp"; +import { range } from "@thi.ng/transducers/iter/range"; +import { tuples } from "@thi.ng/transducers/iter/tuples"; +import { str } from "@thi.ng/transducers/rfn/str"; +import { transduce } from "@thi.ng/transducers/transduce"; +import { map } from "@thi.ng/transducers/xform/map"; +import { mapIndexed } from "@thi.ng/transducers/xform/map-indexed"; +import { take } from "@thi.ng/transducers/xform/take"; +import { vop } from "./vop"; + +export type Template = (syms: string[], i?: number) => string; + +export const indices = (sym: string) => map((i) => `${sym}[${i}]`, range()); + +/** + * Takes a vector size `dim`, a code template function and an array of + * symbol names participating in the template. For each symbol, creates + * iterator of index lookups (e.g. `a[0]`), forms them into tuples and + * passes them to template to generate code. If the optional `ret` arg + * is not `null` (default `"a"`), appends a `return` statement to the + * result array, using `ret` as return value. Returns array of source + * code lines. + * + * The optional `pre` and `post` strings can be used to wrap the + * generated code. `post` will be injected **before** the generated + * return statement (if not suppressed). + * + * @param dim + * @param tpl + * @param syms + * @param ret + * @param opJoin + * @param pre + * @param post + */ +export const assemble = ( + dim: number, + tpl: Template, + syms: string, + ret = "a", + opJoin = "", + pre = "", + post = "") => + + [ + pre, + transduce( + comp(take(dim), mapIndexed((i, x: string[]) => tpl(x, i))), + str(opJoin), + tuples.apply(null, [...map(indices, syms.split(","))]) + ), + post, + ret !== null ? `return ${ret};` : "" + ]; + +export const assembleG = ( + tpl: Template, + syms: string, + ret = "a", + pre?: string, + post?: string) => [ + pre, + "for(let i=a.length;--i>=0;) {", + tpl(syms.split(",").map((x) => `${x}[i]`)), + "}", + post, + ret !== null ? `return ${ret};` : "" + ]; + +export const compile = ( + dim: number, + tpl: Template, + args: string, + syms = args, + ret = "a", + opJoin?: string, + pre?: string, + post?: string) => + + new Function(args, assemble(dim, tpl, syms, ret, opJoin, pre, post).join("")); + +export const compileHOF = ( + dim: number, + fns: any[], + tpl: Template, + hofArgs: string, + args: string, + syms = args, + ret = "a", + pre?: string, + post?: string) => { + + return new Function( + hofArgs, + `return (${args})=>{${assemble(dim, tpl, syms, ret, pre, post).join("\n")}}` + )(...fns); +}; + +export const compileG = ( + tpl: Template, + args: string, + syms = args, + ret = "a", + pre?: string, + post?: string) => + + new Function(args, assembleG(tpl, syms, ret, pre, post).join("")); + +export const compileGHOF = ( + fns: any[], + tpl: Template, + hofArgs: string, + args: string, + syms = args, + ret = "a", + pre?: string, + post?: string) => + + new Function( + hofArgs, + `return (${args})=>{${assembleG(tpl, syms, ret, pre, post).join("\n")}}` + )(...fns); + +export const defOp = (tpl: Template, args?: string, syms?: string, ret = "o", dispatch = 1): [M, V, V, V] => { + const fn: any = vop(dispatch); + args = args || "o,a,b"; + syms = syms || args; + const $ = (dim) => fn.add(dim, compile(dim, tpl, args, syms, ret)); + fn.default(compileG(tpl, args, syms, ret)); + return [fn, $(2), $(3), $(4)]; +}; + +export const defFnOp = (op: string, tpl?: Template, args?: string, syms?: string, ret = "o", dispatch = 1): [M, V, V, V] => { + const fn: any = vop(dispatch); + tpl = tpl || (([o, a]) => `${o}=${op}(${a});`); + args = args || "o,a"; + syms = syms || args; + const $ = (dim) => fn.add(dim, compile(dim, tpl, args, syms, ret)); + fn.default(compileG(tpl, args, syms, ret)); + return [fn, $(2), $(3), $(4)]; +}; + +export const defHofOp = (op, tpl?: Template, args?: string, syms?: string, ret = "o", dispatch = 1): [M, V, V, V] => { + const fn: any = vop(dispatch); + tpl = tpl || (([o, a]) => `${o}=op(${a});`); + args = args || "o,a"; + syms = syms || args; + const $ = (dim) => compileHOF(dim, [op], tpl, "op", args, syms, ret); + fn.default(compileGHOF([op], tpl, "op", args, syms, ret)); + return [fn, $(2), $(3), $(4)]; +}; diff --git a/packages/vectors3/src/compare.ts b/packages/vectors3/src/compare.ts new file mode 100644 index 0000000000..e396356789 --- /dev/null +++ b/packages/vectors3/src/compare.ts @@ -0,0 +1,57 @@ +import { Comparator } from "@thi.ng/api/api"; +import { ReadonlyVec } from "./api"; + +export const comparator2 = + (o1: number, o2: number): Comparator => + (a, b): number => { + const ax = a[o1]; + const ay = a[o2]; + const bx = b[o1]; + const by = b[o2]; + return ax === bx ? + ay === by ? + 0 : + ay < by ? -2 : 2 : + ax < bx ? -1 : 1; + }; + +export const comparator3 = + (o1: number, o2: number, o3: number): Comparator => + (a, b): number => { + const ax = a[o1]; + const ay = a[o2]; + const az = a[o3]; + const bx = b[o1]; + const by = b[o2]; + const bz = b[o3]; + return ax === bx ? + ay === by ? + az === bz ? + 0 : + az < bz ? -3 : 3 : + ay < by ? -2 : 2 : + ax < bx ? -1 : 1; + }; + +export const comparator4 = + (o1: number, o2: number, o3: number, o4: number): Comparator => + (a, b): number => { + + const ax = a[o1]; + const ay = a[o2]; + const az = a[o3]; + const aw = b[o4]; + const bx = b[o1]; + const by = b[o2]; + const bz = b[o3]; + const bw = b[o4]; + return ax === bx ? + ay === by ? + az === bz ? + aw === bw ? + 0 : + aw < bw ? -4 : 4 : + az < bz ? -3 : 3 : + ay < by ? -2 : 2 : + ax < bx ? -1 : 1; + }; diff --git a/packages/vectors3/src/copy.ts b/packages/vectors3/src/copy.ts new file mode 100644 index 0000000000..5db5b48755 --- /dev/null +++ b/packages/vectors3/src/copy.ts @@ -0,0 +1,8 @@ +import { implementsFunction } from "@thi.ng/checks/implements-function"; +import { ReadonlyVec } from "./api"; + +export const copy = + (v: ReadonlyVec) => + implementsFunction(v, "copy") ? + (v).copy() : + [...v]; diff --git a/packages/vectors3/src/cos.ts b/packages/vectors3/src/cos.ts new file mode 100644 index 0000000000..0f7807c649 --- /dev/null +++ b/packages/vectors3/src/cos.ts @@ -0,0 +1,5 @@ +import { MultiVecOpV, VecOpV } from "./api"; +import { defFnOp } from "./codegen"; + +export const [cos, cos2, cos3, cos4] = + defFnOp("Math.cos"); diff --git a/packages/vectors3/src/cross.ts b/packages/vectors3/src/cross.ts new file mode 100644 index 0000000000..6a182665a2 --- /dev/null +++ b/packages/vectors3/src/cross.ts @@ -0,0 +1,15 @@ +import { ReadonlyVec, Vec } from "./api"; + +export const cross2 = + (a: ReadonlyVec, b: ReadonlyVec) => + a[0] * b[1] - a[1] * b[0]; + +export const cross3 = + (out: Vec, a: ReadonlyVec, b: ReadonlyVec) => { + const x = a[1] * b[2] - a[2] * b[1]; + const y = a[2] * b[0] - a[0] * b[2]; + out[2] = a[0] * b[1] - a[1] * b[0]; + out[1] = y; + out[0] = x; + return a; + }; diff --git a/packages/vectors3/src/dist-chebyshev.ts b/packages/vectors3/src/dist-chebyshev.ts new file mode 100644 index 0000000000..da7155bf92 --- /dev/null +++ b/packages/vectors3/src/dist-chebyshev.ts @@ -0,0 +1,33 @@ +import { MultiVecOpRoVV } from "./api"; +import { compile } from "./codegen"; +import { vop } from "./vop"; + +const $ = (dim: number) => + distChebyshev.add( + dim, + compile( + dim, + ([a, b]) => `Math.abs(${a}-${b})`, + "a,b", + undefined, + null, + ",", + "return Math.max(", ");" + ) + ); + +export const distChebyshev: MultiVecOpRoVV = vop(); + +distChebyshev.default( + (a, b) => { + let max = 0; + for (let i = a.length; --i >= 0;) { + max = Math.max(max, Math.abs(a[i] - b[i])); + } + return max; + } +); + +export const distChebyshev2 = $(2); +export const distChebyshev3 = $(3); +export const distChebyshev4 = $(4); diff --git a/packages/vectors3/src/dist-manhattan.ts b/packages/vectors3/src/dist-manhattan.ts new file mode 100644 index 0000000000..75865791e6 --- /dev/null +++ b/packages/vectors3/src/dist-manhattan.ts @@ -0,0 +1,34 @@ +import { MultiVecOpRoVV } from "./api"; +import { compile, compileG } from "./codegen"; +import { vop } from "./vop"; + +const $ = (dim: number) => + distManhattan.add( + dim, + compile( + dim, + ([a, b]) => `Math.abs(${a}-${b})`, + "a,b", + undefined, + null, + "+", + "return ", + ";" + ) + ); + +export const distManhattan: MultiVecOpRoVV = vop(); + +distManhattan.default( + compileG( + ([a, b]) => `sum+=Math.abs(${a}-${b});`, + "a,b", + undefined, + "sum", + "let sum=0;" + ) +); + +export const distManhattan2 = $(2); +export const distManhattan3 = $(3); +export const distManhattan4 = $(4); diff --git a/packages/vectors3/src/dist.ts b/packages/vectors3/src/dist.ts new file mode 100644 index 0000000000..e9de6b2143 --- /dev/null +++ b/packages/vectors3/src/dist.ts @@ -0,0 +1,6 @@ +import { ReadonlyVec } from "./api"; +import { distSq } from "./distsq"; + +export const dist = + (a: ReadonlyVec, b: ReadonlyVec) => + Math.sqrt(distSq(a, b)); diff --git a/packages/vectors3/src/distsq.ts b/packages/vectors3/src/distsq.ts new file mode 100644 index 0000000000..4c7294b142 --- /dev/null +++ b/packages/vectors3/src/distsq.ts @@ -0,0 +1,20 @@ +import { MultiVecOpRoVV } from "./api"; +import { compile, compileG } from "./codegen"; +import { vop } from "./vop"; + +const tpl = ([a, b]) => `t=${a}-${b};sum+=t*t;`; +const pre = "let t,sum=0;"; + +const $ = (dim: number) => + distSq.add( + dim, + compile(dim, tpl, "a,b", undefined, "sum", "", pre) + ); + +export const distSq: MultiVecOpRoVV = vop(); + +distSq.default(compileG(tpl, "a,b", undefined, "sum", pre)); + +export const distSq2 = $(2); +export const distSq3 = $(3); +export const distSq4 = $(4); diff --git a/packages/vectors3/src/div.ts b/packages/vectors3/src/div.ts new file mode 100644 index 0000000000..b31864a2aa --- /dev/null +++ b/packages/vectors3/src/div.ts @@ -0,0 +1,5 @@ +import { MultiVecOpVV, VecOpVV } from "./api"; +import { defOp } from "./codegen"; + +export const [div, div2, div3, div4] = + defOp(([o, a, b]) => `${o}=${a}/${b};`); diff --git a/packages/vectors3/src/divn.ts b/packages/vectors3/src/divn.ts new file mode 100644 index 0000000000..32d49b647b --- /dev/null +++ b/packages/vectors3/src/divn.ts @@ -0,0 +1,5 @@ +import { MultiVecOpVN, VecOpVN } from "./api"; +import { defOp } from "./codegen"; + +export const [divN, divN2, divN3, divN4] = + defOp(([o, a]) => `${o}=${a}/n;`, "o,a,n"); diff --git a/packages/vectors3/src/dot.ts b/packages/vectors3/src/dot.ts new file mode 100644 index 0000000000..b88072034f --- /dev/null +++ b/packages/vectors3/src/dot.ts @@ -0,0 +1,28 @@ +import { MultiVecOpRoVV } from "./api"; +import { compile, compileG } from "./codegen"; +import { vop } from "./vop"; + +const $ = (dim: number) => + dot.add( + dim, + compile( + dim, + ([a, b]) => `${a}*${b}`, + "a,b", + undefined, + null, + "+", + "return ", + ";" + ) + ); + +export const dot: MultiVecOpRoVV = vop(); + +dot.default( + compileG(([a, b]) => `sum+=${a}*${b};`, "a,b", undefined, "sum", "let sum=0;") +); + +export const dot2 = $(2); +export const dot3 = $(3); +export const dot4 = $(4); diff --git a/packages/vectors3/src/empty.ts b/packages/vectors3/src/empty.ts new file mode 100644 index 0000000000..37c2219efd --- /dev/null +++ b/packages/vectors3/src/empty.ts @@ -0,0 +1,9 @@ +import { ReadonlyVec } from "./api"; +import { implementsFunction } from "@thi.ng/checks/implements-function"; +import { zeroes } from "./setn"; + +export const empty = + (v: ReadonlyVec) => + implementsFunction(v, "empty") ? + (v).empty() : + zeroes(v.length); diff --git a/packages/vectors3/src/eqdelta.ts b/packages/vectors3/src/eqdelta.ts new file mode 100644 index 0000000000..0573f6dfd2 --- /dev/null +++ b/packages/vectors3/src/eqdelta.ts @@ -0,0 +1,71 @@ +import { vop } from "./vop"; +import { MultiVecOpRoVVO, ReadonlyVec } from "./api"; +import { EPS } from "@thi.ng/math/api"; +import { eqDelta as _eq } from "@thi.ng/math/eqdelta"; +import { implementsFunction } from "@thi.ng/checks/implements-function"; + +export const eqDelta: MultiVecOpRoVVO = vop(); + +eqDelta.default( + (v1, v2, eps = EPS) => { + if (implementsFunction(v1, "eqDelta")) { + return (v1).eqDelta(v2, eps); + } + if (implementsFunction(v2, "eqDelta")) { + return (v2).eqDelta(v1, eps); + } + return eqDeltaStrided(v1, v2, v1.length, eps); + } +); + +eqDelta.add(2, (a, b, eps = EPS) => + a.length === b.length && + _eq(a[0], b[0], eps) && + _eq(a[1], b[1], eps) +); + +eqDelta.add(3, (a, b, eps = EPS) => + a.length === b.length && + _eq(a[0], b[0], eps) && + _eq(a[1], b[1], eps) && + _eq(a[2], b[2], eps) +); + +eqDelta.add(4, (a, b, eps = EPS) => + a.length === b.length && + _eq(a[0], b[0], eps) && + _eq(a[1], b[1], eps) && + _eq(a[2], b[2], eps) && + _eq(a[3], b[3], eps) +); + +/** + * Similar to `equiv()`, but takes tolerance `eps` into account for + * equality checks. + * + * @param a first vector + * @param b second vector + * @param n number of elements + * @param eps tolerance + * @param ia start index a + * @param ib start index b + * @param sa stride a + * @param sb stride b + */ +export const eqDeltaStrided = ( + a: ReadonlyVec, + b: ReadonlyVec, + n: number, + eps = EPS, + ia = 0, + ib = 0, + sa = 1, + sb = 1) => { + + for (; n > 0; n-- , ia += sa, ib += sb) { + if (!_eq(a[ia], b[ib], eps)) { + return false; + } + } + return true; +}; diff --git a/packages/vectors3/src/exp.ts b/packages/vectors3/src/exp.ts new file mode 100644 index 0000000000..11d149c6ed --- /dev/null +++ b/packages/vectors3/src/exp.ts @@ -0,0 +1,5 @@ +import { MultiVecOpV, VecOpV } from "./api"; +import { defFnOp } from "./codegen"; + +export const [exp, exp2, exp3, exp4] = + defFnOp("Math.exp"); diff --git a/packages/vectors3/src/floor.ts b/packages/vectors3/src/floor.ts new file mode 100644 index 0000000000..a215593bb9 --- /dev/null +++ b/packages/vectors3/src/floor.ts @@ -0,0 +1,5 @@ +import { MultiVecOpV, VecOpV } from "./api"; +import { defFnOp } from "./codegen"; + +export const [floor, floor2, floor3, floor4] = + defFnOp("Math.floor"); diff --git a/packages/vectors3/src/fract.ts b/packages/vectors3/src/fract.ts new file mode 100644 index 0000000000..cbbecd5023 --- /dev/null +++ b/packages/vectors3/src/fract.ts @@ -0,0 +1,6 @@ +import { fract as _fract } from "@thi.ng/math/prec"; +import { MultiVecOpV, VecOpV } from "./api"; +import { defHofOp } from "./codegen"; + +export const [fract, fract2, fract3, fract4] = + defHofOp(_fract); diff --git a/packages/vectors3/src/heading.ts b/packages/vectors3/src/heading.ts new file mode 100644 index 0000000000..0b73157a26 --- /dev/null +++ b/packages/vectors3/src/heading.ts @@ -0,0 +1,8 @@ +import { atan2Abs } from "@thi.ng/math/angle"; +import { ReadonlyVec } from "./api"; + +export const headingXY = (a: ReadonlyVec) => atan2Abs(a[1], a[0]); +export const headingXZ = (a: ReadonlyVec) => atan2Abs(a[2], a[0]); +export const headingYZ = (a: ReadonlyVec) => atan2Abs(a[2], a[1]); + +export const heading = headingXY; diff --git a/packages/vectors3/src/index.ts b/packages/vectors3/src/index.ts new file mode 100644 index 0000000000..04313b743e --- /dev/null +++ b/packages/vectors3/src/index.ts @@ -0,0 +1,68 @@ +export * from "./api"; +export * from "./codegen"; +export * from "./vop"; + +export * from "./abs"; +export * from "./acos"; +export * from "./add"; +export * from "./addn"; +export * from "./angle-between"; +export * from "./asin"; +export * from "./bisect"; +export * from "./cartesian"; +export * from "./ceil"; +export * from "./compare"; +export * from "./copy"; +export * from "./cos"; +export * from "./cross"; +export * from "./dist"; +export * from "./dist-chebyshev"; +export * from "./dist-manhattan"; +export * from "./distsq"; +export * from "./div"; +export * from "./divn"; +export * from "./dot"; +export * from "./empty"; +export * from "./eqdelta"; +export * from "./exp"; +export * from "./floor"; +export * from "./fract"; +export * from "./heading"; +export * from "./limit"; +export * from "./log"; +export * from "./madd"; +export * from "./maddn"; +export * from "./mag"; +export * from "./magsq"; +export * from "./major"; +export * from "./max"; +export * from "./min"; +export * from "./minor"; +export * from "./mix-bilinear"; +export * from "./mix"; +export * from "./mixn"; +export * from "./mod"; +export * from "./modn"; +export * from "./mul"; +export * from "./muln"; +export * from "./neg"; +export * from "./normalize"; +export * from "./perpendicular"; +export * from "./polar"; +export * from "./pow"; +export * from "./pown"; +export * from "./random"; +export * from "./rotate-around-axis"; +export * from "./rotate-around-point"; +export * from "./rotate"; +export * from "./set"; +export * from "./setn"; +export * from "./sign"; +export * from "./sin"; +export * from "./sqrt"; +export * from "./step"; +export * from "./smoothstep"; +export * from "./sub"; +export * from "./subn"; +export * from "./tan"; +export * from "./trunc"; diff --git a/packages/vectors3/src/invert.ts b/packages/vectors3/src/invert.ts new file mode 100644 index 0000000000..8b9c36d72f --- /dev/null +++ b/packages/vectors3/src/invert.ts @@ -0,0 +1,5 @@ +import { MultiVecOpV, VecOpV } from "./api"; +import { defOp } from "./codegen"; + +export const [invert, invert2, invert3, invert4] = + defOp(([o, a]) => `${o}=1/${a};`); diff --git a/packages/vectors3/src/limit.ts b/packages/vectors3/src/limit.ts new file mode 100644 index 0000000000..8d0bff7893 --- /dev/null +++ b/packages/vectors3/src/limit.ts @@ -0,0 +1,9 @@ +import { ReadonlyVec, Vec } from "./api"; +import { mag } from "./mag"; +import { mulN } from "./muln"; + +export const limit = + (out: Vec, v: ReadonlyVec, n: number) => { + let m = mag(v); + return m > n ? mulN(out, v, n / m) : v; + }; diff --git a/packages/vectors3/src/log.ts b/packages/vectors3/src/log.ts new file mode 100644 index 0000000000..189d778de8 --- /dev/null +++ b/packages/vectors3/src/log.ts @@ -0,0 +1,5 @@ +import { MultiVecOpV, VecOpV } from "./api"; +import { defFnOp } from "./codegen"; + +export const [log, log2, log3, log4] = + defFnOp("Math.log"); diff --git a/packages/vectors3/src/madd.ts b/packages/vectors3/src/madd.ts new file mode 100644 index 0000000000..18db242f53 --- /dev/null +++ b/packages/vectors3/src/madd.ts @@ -0,0 +1,8 @@ +import { MultiVecOpVVV, VecOpVVV } from "./api"; +import { defOp } from "./codegen"; + +export const [madd, madd2, madd3, madd4] = + defOp( + ([o, a, b, c]) => `${o}=${a}+${b}*${c};`, + "o,a,b,c" + ); diff --git a/packages/vectors3/src/maddn.ts b/packages/vectors3/src/maddn.ts new file mode 100644 index 0000000000..926e56ac82 --- /dev/null +++ b/packages/vectors3/src/maddn.ts @@ -0,0 +1,8 @@ +import { MultiVecOpVVN, VecOpVVN } from "./api"; +import { defOp } from "./codegen"; + +export const [maddN, maddN2, maddN3, maddN4] = + defOp( + ([o, a, b]) => `${o}=${a}+${b}*n;`, + "o,a,b,n" + ); diff --git a/packages/vectors3/src/mag.ts b/packages/vectors3/src/mag.ts new file mode 100644 index 0000000000..0ac55ab8f7 --- /dev/null +++ b/packages/vectors3/src/mag.ts @@ -0,0 +1,5 @@ +import { ReadonlyVec } from "./api"; +import { magSq } from "./magsq"; + +export const mag = + (v: ReadonlyVec) => Math.sqrt(magSq(v)); diff --git a/packages/vectors3/src/magsq.ts b/packages/vectors3/src/magsq.ts new file mode 100644 index 0000000000..93b822bf9c --- /dev/null +++ b/packages/vectors3/src/magsq.ts @@ -0,0 +1,28 @@ +import { MultiVecOpRoV } from "./api"; +import { compile, compileG } from "./codegen"; +import { vop } from "./vop"; + +const $ = (dim: number) => + magSq.add( + dim, + compile( + dim, + ([a]) => `${a}*${a}`, + "a", + undefined, + null, + "+", + "return ", + ";" + ) + ); + +export const magSq: MultiVecOpRoV = vop(); + +magSq.default( + compileG(([a]) => `sum+=${a}*${a};`, "a", undefined, "sum", "let sum=0;") +); + +export const magSq2 = $(2); +export const magSq3 = $(3); +export const magSq4 = $(4); diff --git a/packages/vectors3/src/major.ts b/packages/vectors3/src/major.ts new file mode 100644 index 0000000000..fa81adac4d --- /dev/null +++ b/packages/vectors3/src/major.ts @@ -0,0 +1,23 @@ +import { max2id, max3id, max4id } from "@thi.ng/math/interval"; +import { MultiVecOpRoV } from "./api"; +import { vop } from "./vop"; + +const abs = Math.abs; + +export const major: MultiVecOpRoV = vop(); + +major.default((a) => { + let id, max = -Infinity; + for (let i = a.length; --i >= 0;) { + const x = abs(a[i]); + if (x > max) { + max = x; + id = i; + } + } + return id; +}); + +export const major2 = major.add(2, (a) => max2id(abs(a[0]), abs(a[1]))); +export const major3 = major.add(3, (a) => max3id(abs(a[0]), abs(a[1]), abs(a[2]))); +export const major4 = major.add(4, (a) => max4id(abs(a[0]), abs(a[1]), abs(a[2]), abs(a[3]))); diff --git a/packages/vectors3/src/max.ts b/packages/vectors3/src/max.ts new file mode 100644 index 0000000000..6144848314 --- /dev/null +++ b/packages/vectors3/src/max.ts @@ -0,0 +1,5 @@ +import { MultiVecOpVV, VecOpVV } from "./api"; +import { defOp } from "./codegen"; + +export const [max, max2, max3, max4] = + defOp(([o, a, b]) => `${o}=Math.max(${a},${b});`); diff --git a/packages/vectors3/src/min.ts b/packages/vectors3/src/min.ts new file mode 100644 index 0000000000..ebfb751bef --- /dev/null +++ b/packages/vectors3/src/min.ts @@ -0,0 +1,5 @@ +import { MultiVecOpVV, VecOpVV } from "./api"; +import { defOp } from "./codegen"; + +export const [min, min2, min3, min4] = + defOp(([o, a, b]) => `${o}=Math.min(${a},${b});`); diff --git a/packages/vectors3/src/minor.ts b/packages/vectors3/src/minor.ts new file mode 100644 index 0000000000..4cf4475574 --- /dev/null +++ b/packages/vectors3/src/minor.ts @@ -0,0 +1,23 @@ +import { min2id, min3id, min4id } from "@thi.ng/math/interval"; +import { MultiVecOpRoV } from "./api"; +import { vop } from "./vop"; + +const abs = Math.abs; + +export const minor: MultiVecOpRoV = vop(); + +minor.default((a) => { + let id, min = Infinity; + for (let i = a.length; --i >= 0;) { + const x = abs(a[i]); + if (x < min) { + min = x; + id = i; + } + } + return id; +}); + +export const minor2 = minor.add(2, (a) => min2id(abs(a[0]), abs(a[1]))); +export const minor3 = minor.add(3, (a) => min3id(abs(a[0]), abs(a[1]), abs(a[2]))); +export const minor4 = minor.add(4, (a) => min4id(abs(a[0]), abs(a[1]), abs(a[2]), abs(a[3]))); diff --git a/packages/vectors3/src/mix-bilinear.ts b/packages/vectors3/src/mix-bilinear.ts new file mode 100644 index 0000000000..77768c6527 --- /dev/null +++ b/packages/vectors3/src/mix-bilinear.ts @@ -0,0 +1,10 @@ +import { mixBilinear as _mix } from "@thi.ng/math/mix"; +import { MultiVecOpVVVVNN, VecOpVVVVNN } from "./api"; +import { defHofOp } from "./codegen"; + +export const [mixBilinear, mixBilinear2, mixBilinear3, mixBilinear4] = + defHofOp( + _mix, + ([o, a, b, c, d]) => `${o}=op(${a},${b},${c},${d},u,v);`, + "o,a,b,c,d,u,v" + ); diff --git a/packages/vectors3/src/mix.ts b/packages/vectors3/src/mix.ts new file mode 100644 index 0000000000..f551ee4f02 --- /dev/null +++ b/packages/vectors3/src/mix.ts @@ -0,0 +1,8 @@ +import { MultiVecOpVVV, VecOpVVV } from "./api"; +import { defOp } from "./codegen"; + +export const [mix, mix2, mix3, mix4] = + defOp( + ([o, a, b, c]) => `${o}=${a}+(${b}-${a})*${c};`, + "o,a,b,c" + ); diff --git a/packages/vectors3/src/mixn.ts b/packages/vectors3/src/mixn.ts new file mode 100644 index 0000000000..5fa8d5e62a --- /dev/null +++ b/packages/vectors3/src/mixn.ts @@ -0,0 +1,8 @@ +import { MultiVecOpVVN, VecOpVVN } from "./api"; +import { defOp } from "./codegen"; + +export const [mixN, mixN2, mixN3, mixN4] = + defOp( + ([o, a, b]) => `${o}=${a}+(${b}-${a})*n;`, + "o,a,b,n" + ); diff --git a/packages/vectors3/src/mod.ts b/packages/vectors3/src/mod.ts new file mode 100644 index 0000000000..a2e80b3174 --- /dev/null +++ b/packages/vectors3/src/mod.ts @@ -0,0 +1,5 @@ +import { MultiVecOpVV, VecOpVV } from "./api"; +import { defOp } from "./codegen"; + +export const [mod, mod2, mod3, mod4] = + defOp(([o, a, b]) => `${o}=${a}%${b};`); diff --git a/packages/vectors3/src/modn.ts b/packages/vectors3/src/modn.ts new file mode 100644 index 0000000000..d43841c3e9 --- /dev/null +++ b/packages/vectors3/src/modn.ts @@ -0,0 +1,5 @@ +import { MultiVecOpVN, VecOpVN } from "./api"; +import { defOp } from "./codegen"; + +export const [modN, modN2, modN3, modN4] = + defOp(([o, a]) => `${o}=${a}%n;`, "o,a,n"); diff --git a/packages/vectors3/src/mul.ts b/packages/vectors3/src/mul.ts new file mode 100644 index 0000000000..f6ae2f7a36 --- /dev/null +++ b/packages/vectors3/src/mul.ts @@ -0,0 +1,5 @@ +import { MultiVecOpVV, VecOpVV } from "./api"; +import { defOp } from "./codegen"; + +export const [mul, mul2, mul3, mul4] = + defOp(([o, a, b]) => `${o}=${a}*${b};`); diff --git a/packages/vectors3/src/muln.ts b/packages/vectors3/src/muln.ts new file mode 100644 index 0000000000..60fc1aacf0 --- /dev/null +++ b/packages/vectors3/src/muln.ts @@ -0,0 +1,5 @@ +import { MultiVecOpVN, VecOpVN } from "./api"; +import { defOp } from "./codegen"; + +export const [mulN, mulN2, mulN3, mulN4] = + defOp(([o, a]) => `${o}=${a}*n;`, "o,a,n"); diff --git a/packages/vectors3/src/neg.ts b/packages/vectors3/src/neg.ts new file mode 100644 index 0000000000..6611bd7edf --- /dev/null +++ b/packages/vectors3/src/neg.ts @@ -0,0 +1,5 @@ +import { ReadonlyVec, Vec, VecOpV } from "./api"; +import { mulN } from "./muln"; + +export const neg: VecOpV = + (out: Vec, v: ReadonlyVec) => mulN(out, v, -1); diff --git a/packages/vectors3/src/normalize.ts b/packages/vectors3/src/normalize.ts new file mode 100644 index 0000000000..aed17e25a7 --- /dev/null +++ b/packages/vectors3/src/normalize.ts @@ -0,0 +1,10 @@ +import { EPS } from "@thi.ng/math/api"; +import { ReadonlyVec, Vec } from "./api"; +import { mag } from "./mag"; +import { mulN } from "./muln"; + +export const normalize = + (out: Vec, v: ReadonlyVec, n = 1) => { + let m = mag(v); + return m >= EPS ? mulN(out, v, n / m) : v; + }; diff --git a/packages/vectors3/src/ortho-normal.ts b/packages/vectors3/src/ortho-normal.ts new file mode 100644 index 0000000000..cd73d3ac31 --- /dev/null +++ b/packages/vectors3/src/ortho-normal.ts @@ -0,0 +1,7 @@ +import { ReadonlyVec, Vec } from "./api"; +import { cross3 } from "./cross"; +import { sub3 } from "./sub"; + +export const orthoNormal3 = + (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => + cross3(out, sub3(out, c, a), sub3([], b, a)); diff --git a/packages/vectors3/src/perpendicular.ts b/packages/vectors3/src/perpendicular.ts new file mode 100644 index 0000000000..a15de5254e --- /dev/null +++ b/packages/vectors3/src/perpendicular.ts @@ -0,0 +1,17 @@ +import { ReadonlyVec, Vec } from "./api"; + +export const perpendicularLeft2 = + (out: Vec, a: ReadonlyVec) => { + const x = a[0]; + out[0] = -a[1]; + out[1] = x; + return out; + }; + +export const perpendicularRight2 = + (out: Vec, a: ReadonlyVec) => { + const x = -a[0]; + out[0] = a[1]; + out[1] = x; + return out; + }; diff --git a/packages/vectors3/src/polar.ts b/packages/vectors3/src/polar.ts new file mode 100644 index 0000000000..05829f6f09 --- /dev/null +++ b/packages/vectors3/src/polar.ts @@ -0,0 +1,27 @@ +import { MultiVecOpV } from "./api"; +import { vop } from "./vop"; +import { mag } from "./mag"; + +const sqrt = Math.sqrt; +const asin = Math.asin; +const atan2 = Math.atan2; + +export const polar: MultiVecOpV = vop(1); + +export const polar2 = polar.add(2, (out, a) => { + const x = a[0]; + out[0] = mag(a); + out[1] = atan2(a[1], x); + return out; +}); + +export const polar3 = polar.add(3, (out, a) => { + const x = a[0]; + const y = a[1]; + const z = a[2]; + const r = sqrt(x * x + y * y + z * z); + out[0] = r; + out[1] = asin(z / r); + out[2] = atan2(y, x); + return out; +}); diff --git a/packages/vectors3/src/pow.ts b/packages/vectors3/src/pow.ts new file mode 100644 index 0000000000..a6928fdd6b --- /dev/null +++ b/packages/vectors3/src/pow.ts @@ -0,0 +1,5 @@ +import { MultiVecOpVV, VecOpVV } from "./api"; +import { defOp } from "./codegen"; + +export const [pow, pow2, pow3, pow4] = + defOp(([o, a, b]) => `${o}=Math.pow(${a},${b});`); diff --git a/packages/vectors3/src/pown.ts b/packages/vectors3/src/pown.ts new file mode 100644 index 0000000000..b7f21a6b9d --- /dev/null +++ b/packages/vectors3/src/pown.ts @@ -0,0 +1,5 @@ +import { MultiVecOpVN, VecOpVN } from "./api"; +import { defOp } from "./codegen"; + +export const [powN, powN2, powN3, powN4] = + defOp(([o, a]) => `${o}=Math.pow(${a},n);`, "o,a,n"); diff --git a/packages/vectors3/src/random.ts b/packages/vectors3/src/random.ts new file mode 100644 index 0000000000..49c9ad68ae --- /dev/null +++ b/packages/vectors3/src/random.ts @@ -0,0 +1,20 @@ +import { IRandom } from "@thi.ng/random/api"; +import { SYSTEM } from "@thi.ng/random/system"; +import { MultiVecOpOOO, Vec, VecOpOOO } from "./api"; +import { defHofOp } from "./codegen"; +import { normalize } from "./normalize"; + +export const [random, random2, random3, random4] = + defHofOp, VecOpOOO>( + SYSTEM, + ([a]) => `${a}=rnd.minmax(n,m);`, + "a,n=-1,m=1,rnd=op", + "a", + "a", + 0 + ); + +export const randNorm = (v: Vec, n = 1, rnd: IRandom = SYSTEM) => { + v = random(v, -1, 1, rnd); + return normalize(v, v, n); +}; diff --git a/packages/vectors3/src/rotate-around-axis.ts b/packages/vectors3/src/rotate-around-axis.ts new file mode 100644 index 0000000000..82b2937228 --- /dev/null +++ b/packages/vectors3/src/rotate-around-axis.ts @@ -0,0 +1,28 @@ +import { ReadonlyVec, Vec } from "./api"; + +export const rotateAroundAxis3 = + (out: Vec, v: ReadonlyVec, axis: ReadonlyVec, theta: number) => { + const x = v[0]; + const y = v[1]; + const z = v[2]; + const ax = axis[0]; + const ay = axis[1]; + const az = axis[2]; + const ux = ax * x; + const uy = ax * y; + const uz = ax * z; + const vx = ay * x; + const vy = ay * y; + const vz = ay * z; + const wx = az * x; + const wy = az * y; + const wz = az * z; + const uvw = ux + vy + wz; + const s = Math.sin(theta); + const c = Math.cos(theta); + + out[0] = (ax * uvw + (x * (ay * ay + az * az) - ax * (vy + wz)) * c + (-wy + vz) * s); + out[1] = (ay * uvw + (y * (ax * ax + az * az) - ay * (ux + wz)) * c + (wx - uz) * s); + out[2] = (az * uvw + (z * (ax * ax + ay * ay) - az * (ux + vy)) * c + (-vx + uy) * s); + return v; + }; diff --git a/packages/vectors3/src/rotate-around-point.ts b/packages/vectors3/src/rotate-around-point.ts new file mode 100644 index 0000000000..f460d01152 --- /dev/null +++ b/packages/vectors3/src/rotate-around-point.ts @@ -0,0 +1,12 @@ +import { VecOpVVN } from "./api"; + +export const rotateAroundPoint2: VecOpVVN = + (out, a, b, theta) => { + const x = a[0] - b[0]; + const y = a[1] - b[1]; + const s = Math.sin(theta); + const c = Math.cos(theta); + out[0] = x * c - y * s + b[0]; + out[1] = x * s + y * c + b[1]; + return out; + }; diff --git a/packages/vectors3/src/rotate.ts b/packages/vectors3/src/rotate.ts new file mode 100644 index 0000000000..239e9f6e85 --- /dev/null +++ b/packages/vectors3/src/rotate.ts @@ -0,0 +1,19 @@ +import { VecOpVN } from "./api"; +import { set } from "./set"; + +const _rotate = + (u: number, v: number): VecOpVN => + (out, a, theta) => { + const s = Math.sin(theta); + const c = Math.cos(theta); + const x = a[u]; + const y = a[v]; + out !== a && set(out, a); + out[u] = x * c - y * s; + out[v] = x * s + y * c; + return out; + }; + +export const rotateX = _rotate(1, 2); +export const rotateY = _rotate(2, 0); +export const rotateZ = _rotate(0, 1); diff --git a/packages/vectors3/src/set.ts b/packages/vectors3/src/set.ts new file mode 100644 index 0000000000..21be3cca6c --- /dev/null +++ b/packages/vectors3/src/set.ts @@ -0,0 +1,5 @@ +import { MultiVecOpV, VecOpV } from "./api"; +import { defOp } from "./codegen"; + +export const [set, set2, set3, set4] = + defOp(([o, a]) => `${o}=${a};`); diff --git a/packages/vectors3/src/setn.ts b/packages/vectors3/src/setn.ts new file mode 100644 index 0000000000..3284dd2180 --- /dev/null +++ b/packages/vectors3/src/setn.ts @@ -0,0 +1,11 @@ +import { MultiVecOpN, Vec, VecOpN } from "./api"; +import { defOp } from "./codegen"; + +export const [setN, setN2, setN3, setN4] = + defOp(([a]) => `${a}=n;`, "a,n", "a", "a", 0); + +export const zero = (a: Vec) => setN(a, 0); +export const one = (a: Vec) => setN(a, 1); + +export const zeroes = (n: number) => new Array(n).fill(0); +export const ones = (n: number) => new Array(n).fill(1); diff --git a/packages/vectors3/src/sign.ts b/packages/vectors3/src/sign.ts new file mode 100644 index 0000000000..616cdb1491 --- /dev/null +++ b/packages/vectors3/src/sign.ts @@ -0,0 +1,5 @@ +import { MultiVecOpV, VecOpV } from "./api"; +import { defFnOp } from "./codegen"; + +export const [sign, sign2, sign3, sign4] = + defFnOp("Math.sign"); diff --git a/packages/vectors3/src/sin.ts b/packages/vectors3/src/sin.ts new file mode 100644 index 0000000000..0eb5c4b6fc --- /dev/null +++ b/packages/vectors3/src/sin.ts @@ -0,0 +1,5 @@ +import { MultiVecOpV, VecOpV } from "./api"; +import { defFnOp } from "./codegen"; + +export const [sin, sin2, sin3, sin4] = + defFnOp("Math.sin"); diff --git a/packages/vectors3/src/smoothstep.ts b/packages/vectors3/src/smoothstep.ts new file mode 100644 index 0000000000..f6ca21cf9f --- /dev/null +++ b/packages/vectors3/src/smoothstep.ts @@ -0,0 +1,10 @@ +import { smoothStep as _step } from "@thi.ng/math/step"; +import { MultiVecOpV, VecOpV } from "./api"; +import { defHofOp } from "./codegen"; + +export const [smoothStep, smoothStep2, smoothStep3, smoothStep4] = + defHofOp( + _step, + ([o, a, e1, e2]) => `${o}=op(${e1},${e2},${a});`, + "o,a,e1,e2" + ); diff --git a/packages/vectors3/src/sqrt.ts b/packages/vectors3/src/sqrt.ts new file mode 100644 index 0000000000..df451e298f --- /dev/null +++ b/packages/vectors3/src/sqrt.ts @@ -0,0 +1,5 @@ +import { MultiVecOpV, VecOpV } from "./api"; +import { defFnOp } from "./codegen"; + +export const [sqrt, sqrt2, sqrt3, sqrt4] = + defFnOp("Math.sqrt"); diff --git a/packages/vectors3/src/step.ts b/packages/vectors3/src/step.ts new file mode 100644 index 0000000000..e26c2fe986 --- /dev/null +++ b/packages/vectors3/src/step.ts @@ -0,0 +1,10 @@ +import { step as _step } from "@thi.ng/math/step"; +import { MultiVecOpV, VecOpV } from "./api"; +import { defHofOp } from "./codegen"; + +export const [step, step2, step3, step4] = + defHofOp( + _step, + ([o, a, e]) => `${o}=op(${e},${a});`, + "o,a,e" + ); diff --git a/packages/vectors3/src/sub.ts b/packages/vectors3/src/sub.ts new file mode 100644 index 0000000000..d6f29f9355 --- /dev/null +++ b/packages/vectors3/src/sub.ts @@ -0,0 +1,5 @@ +import { MultiVecOpVV, VecOpVV } from "./api"; +import { defOp } from "./codegen"; + +export const [sub, sub2, sub3, sub4] = + defOp(([o, a, b]) => `${o}=${a}-${b};`); diff --git a/packages/vectors3/src/subn.ts b/packages/vectors3/src/subn.ts new file mode 100644 index 0000000000..275610a0ea --- /dev/null +++ b/packages/vectors3/src/subn.ts @@ -0,0 +1,5 @@ +import { MultiVecOpVN, VecOpVN } from "./api"; +import { defOp } from "./codegen"; + +export const [subN, subN2, subN3, subN4] = + defOp(([o, a]) => `${o}=${a}-n;`, "o,a,n"); diff --git a/packages/vectors3/src/swizzle.ts b/packages/vectors3/src/swizzle.ts new file mode 100644 index 0000000000..0ad363cf8e --- /dev/null +++ b/packages/vectors3/src/swizzle.ts @@ -0,0 +1,13 @@ +import { ReadonlyVec, Vec } from "./api"; + +export const swizzle2 = + (out: Vec, b: ReadonlyVec, x: number, y: number) => + (out[0] = b[x] || 0, out[1] = b[y] || 0, out); + +export const swizzle3 = + (out: Vec, b: ReadonlyVec, x: number, y: number, z: number) => + (out[0] = b[x] || 0, out[1] = b[y] || 0, out[2] = b[z] || 0, out); + +export const swizzle4 = + (out: Vec, b: ReadonlyVec, x: number, y: number, z: number, w: number) => + (out[0] = b[x] || 0, out[1] = b[y] || 0, out[2] = b[z] || 0, out[3] = b[w] || 0, out); diff --git a/packages/vectors3/src/tan.ts b/packages/vectors3/src/tan.ts new file mode 100644 index 0000000000..468023243b --- /dev/null +++ b/packages/vectors3/src/tan.ts @@ -0,0 +1,5 @@ +import { MultiVecOpV, VecOpV } from "./api"; +import { defFnOp } from "./codegen"; + +export const [tan, tan2, tan3, tan4] = + defFnOp("Math.tan"); diff --git a/packages/vectors3/src/trunc.ts b/packages/vectors3/src/trunc.ts new file mode 100644 index 0000000000..a9829defd9 --- /dev/null +++ b/packages/vectors3/src/trunc.ts @@ -0,0 +1,5 @@ +import { MultiVecOpV, VecOpV } from "./api"; +import { defFnOp } from "./codegen"; + +export const [trunc, trunc2, trunc3, trunc4] = + defFnOp("Math.trunc"); diff --git a/packages/vectors3/src/vop.ts b/packages/vectors3/src/vop.ts new file mode 100644 index 0000000000..867672b30a --- /dev/null +++ b/packages/vectors3/src/vop.ts @@ -0,0 +1,24 @@ +import { unsupported } from "@thi.ng/errors/unsupported"; + +/** + * Specialized / optimized version of `@thi.ng/defmulti` for vector + * operations. Uses simplified logic to dispatch on length (vector size) + * of `dispatch` argument. + * + * @param dispatch arg index + */ +export const vop = (dispatch = 0) => { + const impls = new Array(5); + let fallback; + const fn = (...args: any[]) => { + const g = impls[args[dispatch].length] || fallback; + return g ? + g(...args) : + unsupported(`no impl for vec size ${args[dispatch].length}`); + }; + fn.add = (dim: number, fn) => (impls[dim] = fn); + fn.default = (fn) => (fallback = fn); + // fn.impls = impls; + // fn.fallback = fallback; + return fn; +}; diff --git a/packages/vectors3/test/index.ts b/packages/vectors3/test/index.ts new file mode 100644 index 0000000000..2b933e91ec --- /dev/null +++ b/packages/vectors3/test/index.ts @@ -0,0 +1,6 @@ +// import * as assert from "assert"; +// import * as v from "../src/index"; + +describe("vectors3", () => { + it("tests pending"); +}); diff --git a/packages/vectors3/test/tsconfig.json b/packages/vectors3/test/tsconfig.json new file mode 100644 index 0000000000..bcf29ace54 --- /dev/null +++ b/packages/vectors3/test/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "../build" + }, + "include": [ + "./**/*.ts", + "../src/**/*.ts" + ] +} diff --git a/packages/vectors3/tsconfig.json b/packages/vectors3/tsconfig.json new file mode 100644 index 0000000000..5a76bc343b --- /dev/null +++ b/packages/vectors3/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": ".", + "target": "es6" + }, + "include": [ + "./src/**/*.ts" + ] +} \ No newline at end of file From bfbaaa9bca35265eacbecd348c97939bd241cf94 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 25 Nov 2018 15:01:52 +0000 Subject: [PATCH 035/333] feat(vectors2): update rand codegen tpls & compileHOF/GHOF --- packages/vectors2/src/internal/codegen.ts | 31 +++++++++++++---------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/packages/vectors2/src/internal/codegen.ts b/packages/vectors2/src/internal/codegen.ts index 983241df78..b6932bca21 100644 --- a/packages/vectors2/src/internal/codegen.ts +++ b/packages/vectors2/src/internal/codegen.ts @@ -1,8 +1,9 @@ -import { FnAny } from "@thi.ng/api"; +// import { FnAny } from "@thi.ng/api"; import { sign as _sign } from "@thi.ng/math/abs"; import { clamp as _clamp } from "@thi.ng/math/interval"; import { fract as _fract, trunc as _trunc } from "@thi.ng/math/prec"; import { smoothStep as _smoothStep, step as _step } from "@thi.ng/math/step"; +import { SYSTEM } from "@thi.ng/random/system"; import { comp } from "@thi.ng/transducers/func/comp"; import { range } from "@thi.ng/transducers/iter/range"; import { tuples } from "@thi.ng/transducers/iter/tuples"; @@ -143,7 +144,7 @@ export const compile = ( export const compileHOF = ( dim: number, - fns: FnAny[], + fns: any[], tpl: Template, hofArgs: string, args: string, @@ -169,7 +170,7 @@ export const compileG = ( new Function(args, assembleG(tpl, syms, ret, pre, post).join("")); export const compileGHOF = ( - fns: FnAny[], + fns: any[], tpl: Template, hofArgs: string, args: string, @@ -191,9 +192,9 @@ const tplFnVV = (fn) => ([a, b]) => `${a}=${fn}(${a},${b});` const tplVN = (op) => ([a]) => `${a}${op}=n;` const tplNewVV = (op) => ([a, b, o]) => `${o}=${a}${op}${b};` const tplNewVN = (op) => ([a, o]) => `${o}=${a}${op}n;`; -const tplRand01 = ([a]) => `${a}=Math.random();` -const tplRand11 = ([a]) => `${a}=Math.random()*2-1;` -const tplRand = ([a]) => `${a}=n+(m-n)*Math.random();` +const tplRand01 = ([a]) => `${a}=rnd.float();` +const tplRand11 = ([a]) => `${a}=rnd.norm();` +const tplRand = ([a]) => `${a}=rnd.minmax(n,m);` const tplMadd = ([a, b, c]) => `${a}+=${b}*${c};` const tplMaddN = ([a, b]) => `${a}+=${b}*n;`; const tplMaddNew = ([a, b, c, o]) => `${o}=${a}+${b}*${c};` @@ -233,10 +234,9 @@ export const genCommon = (dim: number): CommonOps => [ setN.add(dim, genOpVN(dim, "")), setS.add(dim, compile(dim, ([a], i) => `${a}=xs[${i}];`, "a,...xs", "a")), - // TODO add IRandom support - rand01.add(dim, compile(dim, tplRand01, "a")), - rand11.add(dim, compile(dim, tplRand11, "a")), - rand.add(dim, compile(dim, tplRand, "a,n,m", "a")), + rand01.add(dim, compileHOF(dim, [SYSTEM], tplRand01, "_rnd", "a,rnd=_rnd", "a")), + rand11.add(dim, compileHOF(dim, [SYSTEM], tplRand11, "_rnd", "a,rnd=_rnd", "a")), + rand.add(dim, compileHOF(dim, [SYSTEM], tplRand, "_rnd", "a,n,m,rnd=_rnd", "a")), add.add(dim, genOpVV(dim, "+")), sub.add(dim, genOpVV(dim, "-")), @@ -320,10 +320,13 @@ export const genCommonDefaults = (): CommonOps => [ setN.default(genGOpVN("")), setS.default(compileG(([a]) => `${a}=xs[i];`, "a,...xs", "a")), - // TODO add IRandom support - rand01.default(compileG(tplRand01, "a")), - rand11.default(compileG(tplRand11, "a")), - rand.default(compileG(tplRand, "a,n,m", "a")), + // rand01.default(compileG(tplRand01, "a")), + // rand11.default(compileG(tplRand11, "a")), + // rand.default(compileG(tplRand, "a,n,m", "a")), + + rand01.default(compileGHOF([SYSTEM], tplRand01, "_rnd", "a,rnd=_rnd", "a")), + rand11.default(compileGHOF([SYSTEM], tplRand11, "_rnd", "a,rnd=_rnd", "a")), + rand.default(compileGHOF([SYSTEM], tplRand, "_rnd", "a,n,m,rnd=_rnd", "a")), add.default(genGOpVV("+")), sub.default(genGOpVV("-")), From 18d44342737a0974c1e419155d025ac285d8308e Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 25 Nov 2018 15:18:12 +0000 Subject: [PATCH 036/333] refactor(vectors): update eqDelta & compileHOF() --- packages/vectors3/src/codegen.ts | 3 ++- packages/vectors3/src/eqdelta.ts | 41 ++++++++++++++++---------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/packages/vectors3/src/codegen.ts b/packages/vectors3/src/codegen.ts index 8bacecbe50..a5d53917f2 100644 --- a/packages/vectors3/src/codegen.ts +++ b/packages/vectors3/src/codegen.ts @@ -87,12 +87,13 @@ export const compileHOF = ( args: string, syms = args, ret = "a", + opJoin = "", pre?: string, post?: string) => { return new Function( hofArgs, - `return (${args})=>{${assemble(dim, tpl, syms, ret, pre, post).join("\n")}}` + `return (${args})=>{${assemble(dim, tpl, syms, ret, opJoin, pre, post).join("\n")}}` )(...fns); }; diff --git a/packages/vectors3/src/eqdelta.ts b/packages/vectors3/src/eqdelta.ts index 0573f6dfd2..c006d7530a 100644 --- a/packages/vectors3/src/eqdelta.ts +++ b/packages/vectors3/src/eqdelta.ts @@ -3,6 +3,24 @@ import { MultiVecOpRoVVO, ReadonlyVec } from "./api"; import { EPS } from "@thi.ng/math/api"; import { eqDelta as _eq } from "@thi.ng/math/eqdelta"; import { implementsFunction } from "@thi.ng/checks/implements-function"; +import { compileHOF } from "./codegen"; + +const $ = (dim) => + eqDelta.add( + dim, + compileHOF( + dim, + [_eq, EPS], + ([a, b]) => `eq(${a},${b},eps)`, + "eq,_eps", + "a,b,eps=_eps", + "a,b", + null, + "&&", + "return a.length === b.length && ", + ";" + ) + ); export const eqDelta: MultiVecOpRoVVO = vop(); @@ -18,26 +36,9 @@ eqDelta.default( } ); -eqDelta.add(2, (a, b, eps = EPS) => - a.length === b.length && - _eq(a[0], b[0], eps) && - _eq(a[1], b[1], eps) -); - -eqDelta.add(3, (a, b, eps = EPS) => - a.length === b.length && - _eq(a[0], b[0], eps) && - _eq(a[1], b[1], eps) && - _eq(a[2], b[2], eps) -); - -eqDelta.add(4, (a, b, eps = EPS) => - a.length === b.length && - _eq(a[0], b[0], eps) && - _eq(a[1], b[1], eps) && - _eq(a[2], b[2], eps) && - _eq(a[3], b[3], eps) -); +export const eqDelta2 = $(2); +export const eqDelta3 = $(3); +export const eqDelta4 = $(4); /** * Similar to `equiv()`, but takes tolerance `eps` into account for From 7448c6b611107f67bf9b981c6a3b43ca8cbfd5ad Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 25 Nov 2018 16:01:33 +0000 Subject: [PATCH 037/333] feat(vectors): re-add Vec2/3/4, clamp, reflect, refract, restructure package --- packages/vectors3/src/abs.ts | 2 +- packages/vectors3/src/acos.ts | 2 +- packages/vectors3/src/add.ts | 2 +- packages/vectors3/src/addn.ts | 2 +- packages/vectors3/src/api.ts | 25 +++- packages/vectors3/src/asin.ts | 2 +- packages/vectors3/src/cartesian.ts | 2 +- packages/vectors3/src/ceil.ts | 2 +- packages/vectors3/src/clamp.ts | 10 ++ packages/vectors3/src/clampn.ts | 11 ++ packages/vectors3/src/cos.ts | 2 +- packages/vectors3/src/dist-chebyshev.ts | 4 +- packages/vectors3/src/dist-manhattan.ts | 4 +- packages/vectors3/src/distsq.ts | 4 +- packages/vectors3/src/div.ts | 2 +- packages/vectors3/src/divn.ts | 2 +- packages/vectors3/src/dot.ts | 4 +- packages/vectors3/src/eqdelta.ts | 4 +- packages/vectors3/src/exp.ts | 2 +- packages/vectors3/src/floor.ts | 2 +- packages/vectors3/src/fract.ts | 2 +- packages/vectors3/src/index.ts | 13 +- packages/vectors3/src/internal/accessors.ts | 29 ++++ packages/vectors3/src/internal/avec.ts | 34 +++++ .../vectors3/src/{ => internal}/codegen.ts | 0 packages/vectors3/src/{ => internal}/vop.ts | 0 packages/vectors3/src/invert.ts | 2 +- packages/vectors3/src/log.ts | 2 +- packages/vectors3/src/madd.ts | 2 +- packages/vectors3/src/maddn.ts | 2 +- packages/vectors3/src/magsq.ts | 4 +- packages/vectors3/src/major.ts | 2 +- packages/vectors3/src/max.ts | 2 +- packages/vectors3/src/min.ts | 2 +- packages/vectors3/src/minor.ts | 2 +- packages/vectors3/src/mix-bilinear.ts | 2 +- packages/vectors3/src/mix.ts | 2 +- packages/vectors3/src/mixn.ts | 2 +- packages/vectors3/src/mod.ts | 2 +- packages/vectors3/src/modn.ts | 2 +- packages/vectors3/src/mul.ts | 2 +- packages/vectors3/src/muln.ts | 2 +- packages/vectors3/src/polar.ts | 2 +- packages/vectors3/src/pow.ts | 2 +- packages/vectors3/src/pown.ts | 2 +- packages/vectors3/src/random.ts | 2 +- packages/vectors3/src/reflect.ts | 6 + packages/vectors3/src/refract.ts | 14 ++ packages/vectors3/src/set.ts | 2 +- packages/vectors3/src/setn.ts | 2 +- packages/vectors3/src/sign.ts | 2 +- packages/vectors3/src/sin.ts | 2 +- packages/vectors3/src/smoothstep.ts | 2 +- packages/vectors3/src/sqrt.ts | 2 +- packages/vectors3/src/step.ts | 2 +- packages/vectors3/src/sub.ts | 2 +- packages/vectors3/src/subn.ts | 2 +- packages/vectors3/src/tan.ts | 2 +- packages/vectors3/src/trunc.ts | 2 +- packages/vectors3/src/vec2.ts | 125 ++++++++++++++++ packages/vectors3/src/vec3.ts | 128 +++++++++++++++++ packages/vectors3/src/vec4.ts | 135 ++++++++++++++++++ 62 files changed, 581 insertions(+), 59 deletions(-) create mode 100644 packages/vectors3/src/clamp.ts create mode 100644 packages/vectors3/src/clampn.ts create mode 100644 packages/vectors3/src/internal/accessors.ts create mode 100644 packages/vectors3/src/internal/avec.ts rename packages/vectors3/src/{ => internal}/codegen.ts (100%) rename packages/vectors3/src/{ => internal}/vop.ts (100%) create mode 100644 packages/vectors3/src/reflect.ts create mode 100644 packages/vectors3/src/refract.ts create mode 100644 packages/vectors3/src/vec2.ts create mode 100644 packages/vectors3/src/vec3.ts create mode 100644 packages/vectors3/src/vec4.ts diff --git a/packages/vectors3/src/abs.ts b/packages/vectors3/src/abs.ts index aad77f2c0f..b16e80d60a 100644 --- a/packages/vectors3/src/abs.ts +++ b/packages/vectors3/src/abs.ts @@ -1,5 +1,5 @@ import { MultiVecOpV, VecOpV } from "./api"; -import { defFnOp } from "./codegen"; +import { defFnOp } from "./internal/codegen"; export const [abs, abs2, abs3, abs4] = defFnOp("Math.abs"); diff --git a/packages/vectors3/src/acos.ts b/packages/vectors3/src/acos.ts index 4336b53f3f..8618663a8d 100644 --- a/packages/vectors3/src/acos.ts +++ b/packages/vectors3/src/acos.ts @@ -1,5 +1,5 @@ import { MultiVecOpV, VecOpV } from "./api"; -import { defFnOp } from "./codegen"; +import { defFnOp } from "./internal/codegen"; export const [acos, acos2, acos3, acos4] = defFnOp("Math.acos"); diff --git a/packages/vectors3/src/add.ts b/packages/vectors3/src/add.ts index 7b1a3a7261..08c4c2322f 100644 --- a/packages/vectors3/src/add.ts +++ b/packages/vectors3/src/add.ts @@ -1,5 +1,5 @@ import { MultiVecOpVV, VecOpVV } from "./api"; -import { defOp } from "./codegen"; +import { defOp } from "./internal/codegen"; export const [add, add2, add3, add4] = defOp(([o, a, b]) => `${o}=${a}+${b};`); diff --git a/packages/vectors3/src/addn.ts b/packages/vectors3/src/addn.ts index 234b7411df..773b220def 100644 --- a/packages/vectors3/src/addn.ts +++ b/packages/vectors3/src/addn.ts @@ -1,5 +1,5 @@ import { MultiVecOpVN, VecOpVN } from "./api"; -import { defOp } from "./codegen"; +import { defOp } from "./internal/codegen"; export const [addN, addN2, addN3, addN4] = defOp(([o, a]) => `${o}=${a}+n;`, "o,a,n"); diff --git a/packages/vectors3/src/api.ts b/packages/vectors3/src/api.ts index 67dce8e848..ee7a59a21b 100644 --- a/packages/vectors3/src/api.ts +++ b/packages/vectors3/src/api.ts @@ -1,4 +1,4 @@ -import { ILength } from "@thi.ng/api/api"; +import { ILength, ICopy, IEmpty, IEqualsDelta } from "@thi.ng/api/api"; export interface Vec extends Iterable, @@ -7,6 +7,17 @@ export interface Vec extends [id: number]: number; } +export interface IVector extends + Vec, + ICopy, + IEmpty, + IEqualsDelta { + + buf: Vec; + i: number; + s: number; +} + export interface ReadonlyVec extends Iterable, ILength { @@ -24,6 +35,7 @@ export type VecOpVV = (out: Vec, a: ReadonlyVec, b: ReadonlyVec) => Vec; export type VecOpVN = (out: Vec, a: ReadonlyVec, n: number) => Vec; export type VecOpVVV = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => Vec; export type VecOpVVN = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, n: number) => Vec; +export type VecOpVNN = (out: Vec, a: ReadonlyVec, u: number, v: number) => Vec; export type VecOpVVVVNN = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, u: number, v: number) => Vec; export type VecOpVO = (out: Vec, a: ReadonlyVec, b?: T) => Vec; @@ -41,6 +53,7 @@ export interface MultiVecOpVV extends VecOpVV, MultiVecOp { } export interface MultiVecOpVN extends VecOpVN, MultiVecOp { } export interface MultiVecOpVVV extends VecOpVVV, MultiVecOp { } export interface MultiVecOpVVN extends VecOpVVN, MultiVecOp { } +export interface MultiVecOpVNN extends VecOpVNN, MultiVecOp { } export interface MultiVecOpVVVVNN extends VecOpVVVVNN, MultiVecOp { } export interface MultiVecOpVO extends VecOpVO, MultiVecOp> { } @@ -52,5 +65,13 @@ export interface MultiVecOpRoV extends VecOpRoV, MultiVecOp> { export interface MultiVecOpRoVV extends VecOpRoVV, MultiVecOp> { } export interface MultiVecOpRoVVO extends VecOpRoVVO, MultiVecOp> { } -export const ZERO4 = Object.freeze([0, 0, 0, 0]); +const mi = -Infinity; +const mx = Infinity; +export const MIN4 = Object.freeze([mi, mi, mi, mi]); +export const MAX4 = Object.freeze([mx, mx, mx, mx]); export const ONE4 = Object.freeze([1, 1, 1, 1]); +export const ZERO4 = Object.freeze([0, 0, 0, 0]); +export const X4 = Object.freeze([1, 0, 0, 0]); +export const Y4 = Object.freeze([0, 1, 0, 0]); +export const Z4 = Object.freeze([0, 0, 1, 0]); +export const W4 = Object.freeze([0, 0, 0, 1]); diff --git a/packages/vectors3/src/asin.ts b/packages/vectors3/src/asin.ts index 4c6275ed3d..1138ce5a55 100644 --- a/packages/vectors3/src/asin.ts +++ b/packages/vectors3/src/asin.ts @@ -1,5 +1,5 @@ import { MultiVecOpV, VecOpV } from "./api"; -import { defFnOp } from "./codegen"; +import { defFnOp } from "./internal/codegen"; export const [asin, asin2, asin3, asin4] = defFnOp("Math.asin"); diff --git a/packages/vectors3/src/cartesian.ts b/packages/vectors3/src/cartesian.ts index 468ce3fa53..318ad18cb5 100644 --- a/packages/vectors3/src/cartesian.ts +++ b/packages/vectors3/src/cartesian.ts @@ -1,5 +1,5 @@ import { MultiVecOpVO, ReadonlyVec, ZERO4 } from "./api"; -import { vop } from "./vop"; +import { vop } from "./internal/vop"; const cos = Math.cos; const sin = Math.sin; diff --git a/packages/vectors3/src/ceil.ts b/packages/vectors3/src/ceil.ts index 26e61dba43..42df323bcf 100644 --- a/packages/vectors3/src/ceil.ts +++ b/packages/vectors3/src/ceil.ts @@ -1,5 +1,5 @@ import { MultiVecOpV, VecOpV } from "./api"; -import { defFnOp } from "./codegen"; +import { defFnOp } from "./internal/codegen"; export const [ceil, ceil2, ceil3, ceil4] = defFnOp("Math.ceil"); diff --git a/packages/vectors3/src/clamp.ts b/packages/vectors3/src/clamp.ts new file mode 100644 index 0000000000..9cd30708a3 --- /dev/null +++ b/packages/vectors3/src/clamp.ts @@ -0,0 +1,10 @@ +import { clamp as _clamp } from "@thi.ng/math/interval"; +import { MultiVecOpVVV, VecOpVVV } from "./api"; +import { defHofOp } from "./internal/codegen"; + +export const [clamp, clamp2, clamp3, clamp4] = + defHofOp( + _clamp, + ([o, a, b, c]) => `${o}=op(${a},${b},${c});`, + "o,a,b,c" + ); diff --git a/packages/vectors3/src/clampn.ts b/packages/vectors3/src/clampn.ts new file mode 100644 index 0000000000..099c92b936 --- /dev/null +++ b/packages/vectors3/src/clampn.ts @@ -0,0 +1,11 @@ +import { clamp as _clamp } from "@thi.ng/math/interval"; +import { MultiVecOpVNN, VecOpVNN } from "./api"; +import { defHofOp } from "./internal/codegen"; + +export const [clampN, clampN2, clampN3, clampN4] = + defHofOp( + _clamp, + ([o, a]) => `${o}=op(${a},n,m);`, + "o,a,n,m", + "o,a" + ); diff --git a/packages/vectors3/src/cos.ts b/packages/vectors3/src/cos.ts index 0f7807c649..786614add8 100644 --- a/packages/vectors3/src/cos.ts +++ b/packages/vectors3/src/cos.ts @@ -1,5 +1,5 @@ import { MultiVecOpV, VecOpV } from "./api"; -import { defFnOp } from "./codegen"; +import { defFnOp } from "./internal/codegen"; export const [cos, cos2, cos3, cos4] = defFnOp("Math.cos"); diff --git a/packages/vectors3/src/dist-chebyshev.ts b/packages/vectors3/src/dist-chebyshev.ts index da7155bf92..0d9930dbbb 100644 --- a/packages/vectors3/src/dist-chebyshev.ts +++ b/packages/vectors3/src/dist-chebyshev.ts @@ -1,6 +1,6 @@ import { MultiVecOpRoVV } from "./api"; -import { compile } from "./codegen"; -import { vop } from "./vop"; +import { compile } from "./internal/codegen"; +import { vop } from "./internal/vop"; const $ = (dim: number) => distChebyshev.add( diff --git a/packages/vectors3/src/dist-manhattan.ts b/packages/vectors3/src/dist-manhattan.ts index 75865791e6..62ee55eb89 100644 --- a/packages/vectors3/src/dist-manhattan.ts +++ b/packages/vectors3/src/dist-manhattan.ts @@ -1,6 +1,6 @@ import { MultiVecOpRoVV } from "./api"; -import { compile, compileG } from "./codegen"; -import { vop } from "./vop"; +import { compile, compileG } from "./internal/codegen"; +import { vop } from "./internal/vop"; const $ = (dim: number) => distManhattan.add( diff --git a/packages/vectors3/src/distsq.ts b/packages/vectors3/src/distsq.ts index 4c7294b142..5d6ced5926 100644 --- a/packages/vectors3/src/distsq.ts +++ b/packages/vectors3/src/distsq.ts @@ -1,6 +1,6 @@ import { MultiVecOpRoVV } from "./api"; -import { compile, compileG } from "./codegen"; -import { vop } from "./vop"; +import { compile, compileG } from "./internal/codegen"; +import { vop } from "./internal/vop"; const tpl = ([a, b]) => `t=${a}-${b};sum+=t*t;`; const pre = "let t,sum=0;"; diff --git a/packages/vectors3/src/div.ts b/packages/vectors3/src/div.ts index b31864a2aa..b286cf90c9 100644 --- a/packages/vectors3/src/div.ts +++ b/packages/vectors3/src/div.ts @@ -1,5 +1,5 @@ import { MultiVecOpVV, VecOpVV } from "./api"; -import { defOp } from "./codegen"; +import { defOp } from "./internal/codegen"; export const [div, div2, div3, div4] = defOp(([o, a, b]) => `${o}=${a}/${b};`); diff --git a/packages/vectors3/src/divn.ts b/packages/vectors3/src/divn.ts index 32d49b647b..0892cc4305 100644 --- a/packages/vectors3/src/divn.ts +++ b/packages/vectors3/src/divn.ts @@ -1,5 +1,5 @@ import { MultiVecOpVN, VecOpVN } from "./api"; -import { defOp } from "./codegen"; +import { defOp } from "./internal/codegen"; export const [divN, divN2, divN3, divN4] = defOp(([o, a]) => `${o}=${a}/n;`, "o,a,n"); diff --git a/packages/vectors3/src/dot.ts b/packages/vectors3/src/dot.ts index b88072034f..43c6edd295 100644 --- a/packages/vectors3/src/dot.ts +++ b/packages/vectors3/src/dot.ts @@ -1,6 +1,6 @@ import { MultiVecOpRoVV } from "./api"; -import { compile, compileG } from "./codegen"; -import { vop } from "./vop"; +import { compile, compileG } from "./internal/codegen"; +import { vop } from "./internal/vop"; const $ = (dim: number) => dot.add( diff --git a/packages/vectors3/src/eqdelta.ts b/packages/vectors3/src/eqdelta.ts index c006d7530a..b53e075cf1 100644 --- a/packages/vectors3/src/eqdelta.ts +++ b/packages/vectors3/src/eqdelta.ts @@ -1,9 +1,9 @@ -import { vop } from "./vop"; +import { vop } from "./internal/vop"; import { MultiVecOpRoVVO, ReadonlyVec } from "./api"; import { EPS } from "@thi.ng/math/api"; import { eqDelta as _eq } from "@thi.ng/math/eqdelta"; import { implementsFunction } from "@thi.ng/checks/implements-function"; -import { compileHOF } from "./codegen"; +import { compileHOF } from "./internal/codegen"; const $ = (dim) => eqDelta.add( diff --git a/packages/vectors3/src/exp.ts b/packages/vectors3/src/exp.ts index 11d149c6ed..5c5c0c0e07 100644 --- a/packages/vectors3/src/exp.ts +++ b/packages/vectors3/src/exp.ts @@ -1,5 +1,5 @@ import { MultiVecOpV, VecOpV } from "./api"; -import { defFnOp } from "./codegen"; +import { defFnOp } from "./internal/codegen"; export const [exp, exp2, exp3, exp4] = defFnOp("Math.exp"); diff --git a/packages/vectors3/src/floor.ts b/packages/vectors3/src/floor.ts index a215593bb9..ea1bd54171 100644 --- a/packages/vectors3/src/floor.ts +++ b/packages/vectors3/src/floor.ts @@ -1,5 +1,5 @@ import { MultiVecOpV, VecOpV } from "./api"; -import { defFnOp } from "./codegen"; +import { defFnOp } from "./internal/codegen"; export const [floor, floor2, floor3, floor4] = defFnOp("Math.floor"); diff --git a/packages/vectors3/src/fract.ts b/packages/vectors3/src/fract.ts index cbbecd5023..11ee356b2c 100644 --- a/packages/vectors3/src/fract.ts +++ b/packages/vectors3/src/fract.ts @@ -1,6 +1,6 @@ import { fract as _fract } from "@thi.ng/math/prec"; import { MultiVecOpV, VecOpV } from "./api"; -import { defHofOp } from "./codegen"; +import { defHofOp } from "./internal/codegen"; export const [fract, fract2, fract3, fract4] = defHofOp(_fract); diff --git a/packages/vectors3/src/index.ts b/packages/vectors3/src/index.ts index 04313b743e..4f42caa7f9 100644 --- a/packages/vectors3/src/index.ts +++ b/packages/vectors3/src/index.ts @@ -1,6 +1,10 @@ export * from "./api"; -export * from "./codegen"; -export * from "./vop"; +export * from "./internal/codegen"; +export * from "./internal/vop"; + +export * from "./vec2"; +export * from "./vec3"; +export * from "./vec4"; export * from "./abs"; export * from "./acos"; @@ -11,6 +15,8 @@ export * from "./asin"; export * from "./bisect"; export * from "./cartesian"; export * from "./ceil"; +export * from "./clamp"; +export * from "./clampn"; export * from "./compare"; export * from "./copy"; export * from "./cos"; @@ -28,6 +34,7 @@ export * from "./exp"; export * from "./floor"; export * from "./fract"; export * from "./heading"; +export * from "./invert"; export * from "./limit"; export * from "./log"; export * from "./madd"; @@ -52,6 +59,8 @@ export * from "./polar"; export * from "./pow"; export * from "./pown"; export * from "./random"; +export * from "./reflect"; +export * from "./refract"; export * from "./rotate-around-axis"; export * from "./rotate-around-point"; export * from "./rotate"; diff --git a/packages/vectors3/src/internal/accessors.ts b/packages/vectors3/src/internal/accessors.ts new file mode 100644 index 0000000000..95510fdcc3 --- /dev/null +++ b/packages/vectors3/src/internal/accessors.ts @@ -0,0 +1,29 @@ +export const declareIndices = ( + proto: any, + props: string[], + strided = true, + defNumeric = true) => { + + const get = (i: number) => + strided ? + function () { return this.buf[this.i + i * this.s]; } : + function () { return this.buf[this.i + i]; }; + + const set = (i: number) => + strided ? + function (n: number) { this.buf[this.i + i * this.s] = n; } : + function (n: number) { this.buf[this.i + i] = n; }; + + props.forEach((id, i) => { + defNumeric && Object.defineProperty(proto, i, { + get: get(i), + set: set(i), + enumerable: true, + }); + Object.defineProperty(proto, id, { + get: get(i), + set: set(i), + enumerable: true, + }); + }); +}; diff --git a/packages/vectors3/src/internal/avec.ts b/packages/vectors3/src/internal/avec.ts new file mode 100644 index 0000000000..6e7605e038 --- /dev/null +++ b/packages/vectors3/src/internal/avec.ts @@ -0,0 +1,34 @@ +import { Vec } from "../api"; + +export abstract class AVec { + + buf: Vec; + i: number; + s: number; + + constructor(buf: Vec, i = 0, s = 1) { + this.buf = buf; + this.i = i; + this.s = s; + } + + abstract get length(): number; + + abstract [Symbol.iterator](): IterableIterator; + + get dim() { + return 1; + } + + get offset() { + return this.i; + } + + get shape() { + return [this.length]; + } + + get stride() { + return [this.s]; + } +} diff --git a/packages/vectors3/src/codegen.ts b/packages/vectors3/src/internal/codegen.ts similarity index 100% rename from packages/vectors3/src/codegen.ts rename to packages/vectors3/src/internal/codegen.ts diff --git a/packages/vectors3/src/vop.ts b/packages/vectors3/src/internal/vop.ts similarity index 100% rename from packages/vectors3/src/vop.ts rename to packages/vectors3/src/internal/vop.ts diff --git a/packages/vectors3/src/invert.ts b/packages/vectors3/src/invert.ts index 8b9c36d72f..64bde8064b 100644 --- a/packages/vectors3/src/invert.ts +++ b/packages/vectors3/src/invert.ts @@ -1,5 +1,5 @@ import { MultiVecOpV, VecOpV } from "./api"; -import { defOp } from "./codegen"; +import { defOp } from "./internal/codegen"; export const [invert, invert2, invert3, invert4] = defOp(([o, a]) => `${o}=1/${a};`); diff --git a/packages/vectors3/src/log.ts b/packages/vectors3/src/log.ts index 189d778de8..138a22a29d 100644 --- a/packages/vectors3/src/log.ts +++ b/packages/vectors3/src/log.ts @@ -1,5 +1,5 @@ import { MultiVecOpV, VecOpV } from "./api"; -import { defFnOp } from "./codegen"; +import { defFnOp } from "./internal/codegen"; export const [log, log2, log3, log4] = defFnOp("Math.log"); diff --git a/packages/vectors3/src/madd.ts b/packages/vectors3/src/madd.ts index 18db242f53..0056701c77 100644 --- a/packages/vectors3/src/madd.ts +++ b/packages/vectors3/src/madd.ts @@ -1,5 +1,5 @@ import { MultiVecOpVVV, VecOpVVV } from "./api"; -import { defOp } from "./codegen"; +import { defOp } from "./internal/codegen"; export const [madd, madd2, madd3, madd4] = defOp( diff --git a/packages/vectors3/src/maddn.ts b/packages/vectors3/src/maddn.ts index 926e56ac82..cf1bd32f7d 100644 --- a/packages/vectors3/src/maddn.ts +++ b/packages/vectors3/src/maddn.ts @@ -1,5 +1,5 @@ import { MultiVecOpVVN, VecOpVVN } from "./api"; -import { defOp } from "./codegen"; +import { defOp } from "./internal/codegen"; export const [maddN, maddN2, maddN3, maddN4] = defOp( diff --git a/packages/vectors3/src/magsq.ts b/packages/vectors3/src/magsq.ts index 93b822bf9c..b736b1ac8f 100644 --- a/packages/vectors3/src/magsq.ts +++ b/packages/vectors3/src/magsq.ts @@ -1,6 +1,6 @@ import { MultiVecOpRoV } from "./api"; -import { compile, compileG } from "./codegen"; -import { vop } from "./vop"; +import { compile, compileG } from "./internal/codegen"; +import { vop } from "./internal/vop"; const $ = (dim: number) => magSq.add( diff --git a/packages/vectors3/src/major.ts b/packages/vectors3/src/major.ts index fa81adac4d..a864b4c417 100644 --- a/packages/vectors3/src/major.ts +++ b/packages/vectors3/src/major.ts @@ -1,6 +1,6 @@ import { max2id, max3id, max4id } from "@thi.ng/math/interval"; import { MultiVecOpRoV } from "./api"; -import { vop } from "./vop"; +import { vop } from "./internal/vop"; const abs = Math.abs; diff --git a/packages/vectors3/src/max.ts b/packages/vectors3/src/max.ts index 6144848314..020df3486b 100644 --- a/packages/vectors3/src/max.ts +++ b/packages/vectors3/src/max.ts @@ -1,5 +1,5 @@ import { MultiVecOpVV, VecOpVV } from "./api"; -import { defOp } from "./codegen"; +import { defOp } from "./internal/codegen"; export const [max, max2, max3, max4] = defOp(([o, a, b]) => `${o}=Math.max(${a},${b});`); diff --git a/packages/vectors3/src/min.ts b/packages/vectors3/src/min.ts index ebfb751bef..b118587dcf 100644 --- a/packages/vectors3/src/min.ts +++ b/packages/vectors3/src/min.ts @@ -1,5 +1,5 @@ import { MultiVecOpVV, VecOpVV } from "./api"; -import { defOp } from "./codegen"; +import { defOp } from "./internal/codegen"; export const [min, min2, min3, min4] = defOp(([o, a, b]) => `${o}=Math.min(${a},${b});`); diff --git a/packages/vectors3/src/minor.ts b/packages/vectors3/src/minor.ts index 4cf4475574..ca8d4542a3 100644 --- a/packages/vectors3/src/minor.ts +++ b/packages/vectors3/src/minor.ts @@ -1,6 +1,6 @@ import { min2id, min3id, min4id } from "@thi.ng/math/interval"; import { MultiVecOpRoV } from "./api"; -import { vop } from "./vop"; +import { vop } from "./internal/vop"; const abs = Math.abs; diff --git a/packages/vectors3/src/mix-bilinear.ts b/packages/vectors3/src/mix-bilinear.ts index 77768c6527..446c8a2aba 100644 --- a/packages/vectors3/src/mix-bilinear.ts +++ b/packages/vectors3/src/mix-bilinear.ts @@ -1,6 +1,6 @@ import { mixBilinear as _mix } from "@thi.ng/math/mix"; import { MultiVecOpVVVVNN, VecOpVVVVNN } from "./api"; -import { defHofOp } from "./codegen"; +import { defHofOp } from "./internal/codegen"; export const [mixBilinear, mixBilinear2, mixBilinear3, mixBilinear4] = defHofOp( diff --git a/packages/vectors3/src/mix.ts b/packages/vectors3/src/mix.ts index f551ee4f02..09b3b8a8b2 100644 --- a/packages/vectors3/src/mix.ts +++ b/packages/vectors3/src/mix.ts @@ -1,5 +1,5 @@ import { MultiVecOpVVV, VecOpVVV } from "./api"; -import { defOp } from "./codegen"; +import { defOp } from "./internal/codegen"; export const [mix, mix2, mix3, mix4] = defOp( diff --git a/packages/vectors3/src/mixn.ts b/packages/vectors3/src/mixn.ts index 5fa8d5e62a..2c1015353a 100644 --- a/packages/vectors3/src/mixn.ts +++ b/packages/vectors3/src/mixn.ts @@ -1,5 +1,5 @@ import { MultiVecOpVVN, VecOpVVN } from "./api"; -import { defOp } from "./codegen"; +import { defOp } from "./internal/codegen"; export const [mixN, mixN2, mixN3, mixN4] = defOp( diff --git a/packages/vectors3/src/mod.ts b/packages/vectors3/src/mod.ts index a2e80b3174..c5bb5091cc 100644 --- a/packages/vectors3/src/mod.ts +++ b/packages/vectors3/src/mod.ts @@ -1,5 +1,5 @@ import { MultiVecOpVV, VecOpVV } from "./api"; -import { defOp } from "./codegen"; +import { defOp } from "./internal/codegen"; export const [mod, mod2, mod3, mod4] = defOp(([o, a, b]) => `${o}=${a}%${b};`); diff --git a/packages/vectors3/src/modn.ts b/packages/vectors3/src/modn.ts index d43841c3e9..d047fe8f53 100644 --- a/packages/vectors3/src/modn.ts +++ b/packages/vectors3/src/modn.ts @@ -1,5 +1,5 @@ import { MultiVecOpVN, VecOpVN } from "./api"; -import { defOp } from "./codegen"; +import { defOp } from "./internal/codegen"; export const [modN, modN2, modN3, modN4] = defOp(([o, a]) => `${o}=${a}%n;`, "o,a,n"); diff --git a/packages/vectors3/src/mul.ts b/packages/vectors3/src/mul.ts index f6ae2f7a36..a22f0fe28f 100644 --- a/packages/vectors3/src/mul.ts +++ b/packages/vectors3/src/mul.ts @@ -1,5 +1,5 @@ import { MultiVecOpVV, VecOpVV } from "./api"; -import { defOp } from "./codegen"; +import { defOp } from "./internal/codegen"; export const [mul, mul2, mul3, mul4] = defOp(([o, a, b]) => `${o}=${a}*${b};`); diff --git a/packages/vectors3/src/muln.ts b/packages/vectors3/src/muln.ts index 60fc1aacf0..65a7a43fc1 100644 --- a/packages/vectors3/src/muln.ts +++ b/packages/vectors3/src/muln.ts @@ -1,5 +1,5 @@ import { MultiVecOpVN, VecOpVN } from "./api"; -import { defOp } from "./codegen"; +import { defOp } from "./internal/codegen"; export const [mulN, mulN2, mulN3, mulN4] = defOp(([o, a]) => `${o}=${a}*n;`, "o,a,n"); diff --git a/packages/vectors3/src/polar.ts b/packages/vectors3/src/polar.ts index 05829f6f09..0c01cc7400 100644 --- a/packages/vectors3/src/polar.ts +++ b/packages/vectors3/src/polar.ts @@ -1,5 +1,5 @@ import { MultiVecOpV } from "./api"; -import { vop } from "./vop"; +import { vop } from "./internal/vop"; import { mag } from "./mag"; const sqrt = Math.sqrt; diff --git a/packages/vectors3/src/pow.ts b/packages/vectors3/src/pow.ts index a6928fdd6b..2c8be0fade 100644 --- a/packages/vectors3/src/pow.ts +++ b/packages/vectors3/src/pow.ts @@ -1,5 +1,5 @@ import { MultiVecOpVV, VecOpVV } from "./api"; -import { defOp } from "./codegen"; +import { defOp } from "./internal/codegen"; export const [pow, pow2, pow3, pow4] = defOp(([o, a, b]) => `${o}=Math.pow(${a},${b});`); diff --git a/packages/vectors3/src/pown.ts b/packages/vectors3/src/pown.ts index b7f21a6b9d..fa29c44a2d 100644 --- a/packages/vectors3/src/pown.ts +++ b/packages/vectors3/src/pown.ts @@ -1,5 +1,5 @@ import { MultiVecOpVN, VecOpVN } from "./api"; -import { defOp } from "./codegen"; +import { defOp } from "./internal/codegen"; export const [powN, powN2, powN3, powN4] = defOp(([o, a]) => `${o}=Math.pow(${a},n);`, "o,a,n"); diff --git a/packages/vectors3/src/random.ts b/packages/vectors3/src/random.ts index 49c9ad68ae..a4f0811286 100644 --- a/packages/vectors3/src/random.ts +++ b/packages/vectors3/src/random.ts @@ -1,7 +1,7 @@ import { IRandom } from "@thi.ng/random/api"; import { SYSTEM } from "@thi.ng/random/system"; import { MultiVecOpOOO, Vec, VecOpOOO } from "./api"; -import { defHofOp } from "./codegen"; +import { defHofOp } from "./internal/codegen"; import { normalize } from "./normalize"; export const [random, random2, random3, random4] = diff --git a/packages/vectors3/src/reflect.ts b/packages/vectors3/src/reflect.ts new file mode 100644 index 0000000000..4a26cff6bc --- /dev/null +++ b/packages/vectors3/src/reflect.ts @@ -0,0 +1,6 @@ +import { VecOpVV } from "./api"; +import { dot } from "./dot"; +import { maddN } from "./maddn"; + +export const reflect: VecOpVV = + (out, a, b) => maddN(out, a, b, -2 * dot(a, b)); diff --git a/packages/vectors3/src/refract.ts b/packages/vectors3/src/refract.ts new file mode 100644 index 0000000000..16d2ebfd0e --- /dev/null +++ b/packages/vectors3/src/refract.ts @@ -0,0 +1,14 @@ +import { VecOpVVN } from "./api"; +import { dot } from "./dot"; +import { maddN } from "./maddn"; +import { mulN } from "./muln"; +import { zero } from "./setn"; + +export const refract: VecOpVVN = + (out, a, n, eta) => { + const d = dot(a, n); + const k = 1 - eta * eta * (1 - d * d); + return k < 0 ? + zero(out) : + maddN(out, mulN(out, a, eta), n, -(eta * d + Math.sqrt(k))); + }; diff --git a/packages/vectors3/src/set.ts b/packages/vectors3/src/set.ts index 21be3cca6c..99f2e05cd7 100644 --- a/packages/vectors3/src/set.ts +++ b/packages/vectors3/src/set.ts @@ -1,5 +1,5 @@ import { MultiVecOpV, VecOpV } from "./api"; -import { defOp } from "./codegen"; +import { defOp } from "./internal/codegen"; export const [set, set2, set3, set4] = defOp(([o, a]) => `${o}=${a};`); diff --git a/packages/vectors3/src/setn.ts b/packages/vectors3/src/setn.ts index 3284dd2180..7b0fbb67c7 100644 --- a/packages/vectors3/src/setn.ts +++ b/packages/vectors3/src/setn.ts @@ -1,5 +1,5 @@ import { MultiVecOpN, Vec, VecOpN } from "./api"; -import { defOp } from "./codegen"; +import { defOp } from "./internal/codegen"; export const [setN, setN2, setN3, setN4] = defOp(([a]) => `${a}=n;`, "a,n", "a", "a", 0); diff --git a/packages/vectors3/src/sign.ts b/packages/vectors3/src/sign.ts index 616cdb1491..7f05994fc8 100644 --- a/packages/vectors3/src/sign.ts +++ b/packages/vectors3/src/sign.ts @@ -1,5 +1,5 @@ import { MultiVecOpV, VecOpV } from "./api"; -import { defFnOp } from "./codegen"; +import { defFnOp } from "./internal/codegen"; export const [sign, sign2, sign3, sign4] = defFnOp("Math.sign"); diff --git a/packages/vectors3/src/sin.ts b/packages/vectors3/src/sin.ts index 0eb5c4b6fc..913976c0b1 100644 --- a/packages/vectors3/src/sin.ts +++ b/packages/vectors3/src/sin.ts @@ -1,5 +1,5 @@ import { MultiVecOpV, VecOpV } from "./api"; -import { defFnOp } from "./codegen"; +import { defFnOp } from "./internal/codegen"; export const [sin, sin2, sin3, sin4] = defFnOp("Math.sin"); diff --git a/packages/vectors3/src/smoothstep.ts b/packages/vectors3/src/smoothstep.ts index f6ca21cf9f..5f43b54ea5 100644 --- a/packages/vectors3/src/smoothstep.ts +++ b/packages/vectors3/src/smoothstep.ts @@ -1,6 +1,6 @@ import { smoothStep as _step } from "@thi.ng/math/step"; import { MultiVecOpV, VecOpV } from "./api"; -import { defHofOp } from "./codegen"; +import { defHofOp } from "./internal/codegen"; export const [smoothStep, smoothStep2, smoothStep3, smoothStep4] = defHofOp( diff --git a/packages/vectors3/src/sqrt.ts b/packages/vectors3/src/sqrt.ts index df451e298f..84d98828a7 100644 --- a/packages/vectors3/src/sqrt.ts +++ b/packages/vectors3/src/sqrt.ts @@ -1,5 +1,5 @@ import { MultiVecOpV, VecOpV } from "./api"; -import { defFnOp } from "./codegen"; +import { defFnOp } from "./internal/codegen"; export const [sqrt, sqrt2, sqrt3, sqrt4] = defFnOp("Math.sqrt"); diff --git a/packages/vectors3/src/step.ts b/packages/vectors3/src/step.ts index e26c2fe986..82070f7d75 100644 --- a/packages/vectors3/src/step.ts +++ b/packages/vectors3/src/step.ts @@ -1,6 +1,6 @@ import { step as _step } from "@thi.ng/math/step"; import { MultiVecOpV, VecOpV } from "./api"; -import { defHofOp } from "./codegen"; +import { defHofOp } from "./internal/codegen"; export const [step, step2, step3, step4] = defHofOp( diff --git a/packages/vectors3/src/sub.ts b/packages/vectors3/src/sub.ts index d6f29f9355..9d4107e7b3 100644 --- a/packages/vectors3/src/sub.ts +++ b/packages/vectors3/src/sub.ts @@ -1,5 +1,5 @@ import { MultiVecOpVV, VecOpVV } from "./api"; -import { defOp } from "./codegen"; +import { defOp } from "./internal/codegen"; export const [sub, sub2, sub3, sub4] = defOp(([o, a, b]) => `${o}=${a}-${b};`); diff --git a/packages/vectors3/src/subn.ts b/packages/vectors3/src/subn.ts index 275610a0ea..16f313b4b7 100644 --- a/packages/vectors3/src/subn.ts +++ b/packages/vectors3/src/subn.ts @@ -1,5 +1,5 @@ import { MultiVecOpVN, VecOpVN } from "./api"; -import { defOp } from "./codegen"; +import { defOp } from "./internal/codegen"; export const [subN, subN2, subN3, subN4] = defOp(([o, a]) => `${o}=${a}-n;`, "o,a,n"); diff --git a/packages/vectors3/src/tan.ts b/packages/vectors3/src/tan.ts index 468023243b..07558363ff 100644 --- a/packages/vectors3/src/tan.ts +++ b/packages/vectors3/src/tan.ts @@ -1,5 +1,5 @@ import { MultiVecOpV, VecOpV } from "./api"; -import { defFnOp } from "./codegen"; +import { defFnOp } from "./internal/codegen"; export const [tan, tan2, tan3, tan4] = defFnOp("Math.tan"); diff --git a/packages/vectors3/src/trunc.ts b/packages/vectors3/src/trunc.ts index a9829defd9..abb8161ed8 100644 --- a/packages/vectors3/src/trunc.ts +++ b/packages/vectors3/src/trunc.ts @@ -1,5 +1,5 @@ import { MultiVecOpV, VecOpV } from "./api"; -import { defFnOp } from "./codegen"; +import { defFnOp } from "./internal/codegen"; export const [trunc, trunc2, trunc3, trunc4] = defFnOp("Math.trunc"); diff --git a/packages/vectors3/src/vec2.ts b/packages/vectors3/src/vec2.ts new file mode 100644 index 0000000000..b9536a5500 --- /dev/null +++ b/packages/vectors3/src/vec2.ts @@ -0,0 +1,125 @@ +import { EPS } from "@thi.ng/math/api"; +import { + IVector, + MAX4, + MIN4, + ONE4, + ReadonlyVec, + Vec, + X4, + Y4, + Z4, + ZERO4 +} from "./api"; +import { eqDelta2 } from "./eqdelta"; +import { declareIndices } from "./internal/accessors"; +import { AVec } from "./internal/avec"; + +export class Vec2 extends AVec implements + IVector { + + /** + * Returns array of memory mapped `Vec2` instances using given + * backing array and stride settings: The `cstride` is the step size + * between individual XY vector components. `estride` is the step + * size between successive vectors. This arrangement allows for + * different storage approaches, incl. SOA, AOS, striped / + * interleaved etc. + * + * @param buf backing array + * @param n num vectors + * @param start start index + * @param cstride component stride + * @param estride element stride + */ + static mapBuffer(buf: Vec, n: number = buf.length >> 1, start = 0, cstride = 1, estride = 2) { + const res: Vec2[] = []; + while (--n >= 0) { + res.push(new Vec2(buf, start, cstride)); + start += estride; + } + return res; + } + + /** + * Merges given `src` iterable of `Vec2`s into single array `buf`. + * Vectors will be arranged according to given component and element + * strides, starting at `start` index. It's the user's + * responsibility to ensure the target buffer has sufficient + * capacity to hold the input vectors. See `Vec2.mapBuffer` for the + * inverse operation. Returns `buf`. + * + * @param buf + * @param src + * @param start + * @param cstride + * @param estride + */ + static intoBuffer(buf: Vec, src: Iterable>, start = 0, cstride = 1, estride = 2) { + for (let v of src) { + buf[start] = v[0]; + buf[start + cstride] = v[1]; + start += estride; + } + return buf; + } + + static readonly X_AXIS = new Vec2(X4); + static readonly Y_AXIS = new Vec2(Y4); + static readonly Z_AXIS = new Vec2(Z4); + static readonly MIN = new Vec2(MIN4); + static readonly MAX = new Vec2(MAX4); + static readonly ZERO = new Vec2(ZERO4); + static readonly ONE = new Vec2(ONE4); + + x: number; + y: number; + [id: number]: number; + + constructor(buf?: Vec, i = 0, s = 1) { + super(buf || [0, 0], i, s); + } + + *[Symbol.iterator]() { + yield this.x; + yield this.y; + } + + get length() { + return 2; + } + + copy() { + return new Vec2([this.x, this.y]); + } + + empty() { + return new Vec2(); + } + + eqDelta(v: ReadonlyVec, eps = EPS) { + return eqDelta2(this, v, eps); + } + + toJSON() { + return [this.x, this.y]; + } + + toString() { + return `[${this.x}, ${this.y}]`; + } +} + +declareIndices(Vec2.prototype, ["x", "y"]); + +export const vec2 = + (x = 0, y = 0) => new Vec2([x, y]); + +export const vec2n = + (n: number) => new Vec2([n, n]); + +export const asVec2 = + (x: Vec) => + x instanceof Vec2 ? + x : + new Vec2(x.length >= 2 ? x : [x[0] || 0, x[1] || 0]); diff --git a/packages/vectors3/src/vec3.ts b/packages/vectors3/src/vec3.ts new file mode 100644 index 0000000000..976dcf47f6 --- /dev/null +++ b/packages/vectors3/src/vec3.ts @@ -0,0 +1,128 @@ +import { EPS } from "@thi.ng/math/api"; +import { + IVector, + MAX4, + MIN4, + ONE4, + ReadonlyVec, + Vec, + X4, + Y4, + Z4, + ZERO4 +} from "./api"; +import { eqDelta3 } from "./eqdelta"; +import { declareIndices } from "./internal/accessors"; +import { AVec } from "./internal/avec"; + +export class Vec3 extends AVec implements + IVector { + + /** + * Returns array of memory mapped `Vec3` instances using given + * backing array and stride settings: The `cstride` is the step size + * between individual XYZ vector components. `estride` is the step + * size between successive vectors. This arrangement allows for + * different storage approaches, incl. SOA, AOS, striped / + * interleaved etc. + * + * @param buf backing array + * @param n num vectors + * @param start start index + * @param cstride component stride + * @param estride element stride + */ + static mapBuffer(buf: Vec, n: number = (buf.length / 3) | 0, start = 0, cstride = 1, estride = 3) { + const res: Vec3[] = []; + while (--n >= 0) { + res.push(new Vec3(buf, start, cstride)); + start += estride; + } + return res; + } + + /** + * Merges given `src` iterable of `Vec3`s into single array `buf`. + * Vectors will be arranged according to given component and element + * strides, starting at `start` index. It's the user's + * responsibility to ensure the target buffer has sufficient + * capacity to hold the input vectors. See `Vec3.mapBuffer` for the + * inverse operation. Returns `buf`. + * + * @param buf + * @param src + * @param start + * @param cstride + * @param estride + */ + static intoBuffer(buf: Vec, src: Iterable>, start = 0, cstride = 1, estride = 3) { + for (let v of src) { + buf[start] = v[0]; + buf[start + cstride] = v[1]; + buf[start + 2 * cstride] = v[2]; + start += estride; + } + return buf; + } + + static readonly X_AXIS = new Vec3(X4); + static readonly Y_AXIS = new Vec3(Y4); + static readonly Z_AXIS = new Vec3(Z4); + static readonly MIN = new Vec3(MIN4); + static readonly MAX = new Vec3(MAX4); + static readonly ZERO = new Vec3(ZERO4); + static readonly ONE = new Vec3(ONE4); + + x: number; + y: number; + z: number; + [id: number]: number; + + constructor(buf?: Vec, i = 0, s = 1) { + super(buf || [0, 0, 0], i, s); + } + + *[Symbol.iterator]() { + yield this.x; + yield this.y; + yield this.z; + } + + get length() { + return 3; + } + + copy() { + return new Vec3([this.x, this.y, this.z]); + } + + empty() { + return new Vec3(); + } + + eqDelta(v: ReadonlyVec, eps = EPS) { + return eqDelta3(this, v, eps); + } + + toJSON() { + return [this.x, this.y, this.z]; + } + + toString() { + return `[${this.x}, ${this.y}, ${this.z}]`; + } +} + +declareIndices(Vec3.prototype, ["x", "y", "z"]); + +export const vec3 = + (x = 0, y = 0, z = 0) => new Vec3([x, y, z]); + +export const vec3n = + (n: number) => new Vec3([n, n, n]); + +export const asVec3 = + (x: Vec) => + x instanceof Vec3 ? + x : + new Vec3(x.length >= 3 ? x : [x[0] || 0, x[1] || 0, x[2] || 0]); diff --git a/packages/vectors3/src/vec4.ts b/packages/vectors3/src/vec4.ts new file mode 100644 index 0000000000..de25de57ea --- /dev/null +++ b/packages/vectors3/src/vec4.ts @@ -0,0 +1,135 @@ +import { EPS } from "@thi.ng/math/api"; +import { + IVector, + MAX4, + MIN4, + ONE4, + ReadonlyVec, + Vec, + X4, + Y4, + Z4, + ZERO4 +} from "./api"; +import { eqDelta4 } from "./eqdelta"; +import { declareIndices } from "./internal/accessors"; +import { AVec } from "./internal/avec"; + +export class Vec4 extends AVec implements + IVector { + + /** + * Returns array of memory mapped `Vec4` instances using given + * backing array and stride settings: The `cstride` is the step size + * between individual XYZ vector components. `estride` is the step + * size between successive vectors. This arrangement allows for + * different storage approaches, incl. SOA, AOS, striped / + * interleaved etc. + * + * @param buf backing array + * @param n num vectors + * @param start start index + * @param cstride component stride + * @param estride element stride + */ + static mapBuffer(buf: Vec, n: number = buf.length >> 2, start = 0, cstride = 1, estride = 4) { + const res: Vec4[] = []; + while (--n >= 0) { + res.push(new Vec4(buf, start, cstride)); + start += estride; + } + return res; + } + + /** + * Merges given `src` iterable of `Vec4`s into single array `buf`. + * Vectors will be arranged according to given component and element + * strides, starting at `start` index. It's the user's + * responsibility to ensure the target buffer has sufficient + * capacity to hold the input vectors. See `Vec4.mapBuffer` for the + * inverse operation. Returns `buf`. + * + * @param buf + * @param src + * @param start + * @param cstride + * @param estride + */ + static intoBuffer(buf: Vec, src: Iterable>, start = 0, cstride = 1, estride = 3) { + for (let v of src) { + buf[start] = v[0]; + buf[start + cstride] = v[1]; + buf[start + 2 * cstride] = v[2]; + buf[start + 3 * cstride] = v[3]; + start += estride; + } + return buf; + } + + static readonly X_AXIS = new Vec4(X4); + static readonly Y_AXIS = new Vec4(Y4); + static readonly Z_AXIS = new Vec4(Z4); + static readonly MIN = new Vec4(MIN4); + static readonly MAX = new Vec4(MAX4); + static readonly ZERO = new Vec4(ZERO4); + static readonly ONE = new Vec4(ONE4); + + x: number; + y: number; + z: number; + w: number; + [id: number]: number; + + constructor(buf?: Vec, i = 0, s = 1) { + super(buf || [0, 0, 0, 0], i, s); + } + + *[Symbol.iterator]() { + yield this.x; + yield this.y; + yield this.z; + yield this.w; + } + + get length() { + return 4; + } + + copy() { + return new Vec4([this.x, this.y, this.z, this.w]); + } + + empty() { + return new Vec4(); + } + + eqDelta(v: ReadonlyVec, eps = EPS) { + return eqDelta4(this, v, eps); + } + + toJSON() { + return [this.x, this.y, this.z, this.w]; + } + + toString() { + return `[${this.x}, ${this.y}, ${this.z}, ${this.w}]`; + } +} + +declareIndices(Vec4.prototype, ["x", "y", "z", "w"]); + +export const vec4 = + (x = 0, y = 0, z = 0, w = 0) => new Vec4([x, y, z, w]); + +export const vec4n = + (n: number) => new Vec4([n, n, n, n]); + +export const asVec4 = + (x: Vec) => + x instanceof Vec4 ? + x : + new Vec4( + x.length >= 4 ? + x : + [x[0] || 0, x[1] || 0, x[2] || 0, x[3] || 0] + ); From b4fffe85526145d59410665e7dd7736799f120a2 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 25 Nov 2018 16:52:53 +0000 Subject: [PATCH 038/333] feat(vectors): add cosh, sinh, tanh, round, jitter, wrap --- packages/vectors3/src/cosh.ts | 5 +++++ packages/vectors3/src/index.ts | 6 ++++++ packages/vectors3/src/jitter.ts | 10 ++++++++++ packages/vectors3/src/round.ts | 11 +++++++++++ packages/vectors3/src/sinh.ts | 5 +++++ packages/vectors3/src/tanh.ts | 5 +++++ packages/vectors3/src/wrap.ts | 10 ++++++++++ 7 files changed, 52 insertions(+) create mode 100644 packages/vectors3/src/cosh.ts create mode 100644 packages/vectors3/src/jitter.ts create mode 100644 packages/vectors3/src/round.ts create mode 100644 packages/vectors3/src/sinh.ts create mode 100644 packages/vectors3/src/tanh.ts create mode 100644 packages/vectors3/src/wrap.ts diff --git a/packages/vectors3/src/cosh.ts b/packages/vectors3/src/cosh.ts new file mode 100644 index 0000000000..417b3bd067 --- /dev/null +++ b/packages/vectors3/src/cosh.ts @@ -0,0 +1,5 @@ +import { MultiVecOpV, VecOpV } from "./api"; +import { defFnOp } from "./internal/codegen"; + +export const [cosh, cosh2, cosh3, cosh4] = + defFnOp("Math.cosh"); diff --git a/packages/vectors3/src/index.ts b/packages/vectors3/src/index.ts index 4f42caa7f9..40d16e7ef0 100644 --- a/packages/vectors3/src/index.ts +++ b/packages/vectors3/src/index.ts @@ -20,6 +20,7 @@ export * from "./clampn"; export * from "./compare"; export * from "./copy"; export * from "./cos"; +export * from "./cosh"; export * from "./cross"; export * from "./dist"; export * from "./dist-chebyshev"; @@ -35,6 +36,7 @@ export * from "./floor"; export * from "./fract"; export * from "./heading"; export * from "./invert"; +export * from "./jitter"; export * from "./limit"; export * from "./log"; export * from "./madd"; @@ -64,14 +66,18 @@ export * from "./refract"; export * from "./rotate-around-axis"; export * from "./rotate-around-point"; export * from "./rotate"; +export * from "./round"; export * from "./set"; export * from "./setn"; export * from "./sign"; export * from "./sin"; +export * from "./sinh"; export * from "./sqrt"; export * from "./step"; export * from "./smoothstep"; export * from "./sub"; export * from "./subn"; export * from "./tan"; +export * from "./tanh"; export * from "./trunc"; +export * from "./wrap"; diff --git a/packages/vectors3/src/jitter.ts b/packages/vectors3/src/jitter.ts new file mode 100644 index 0000000000..ecc355694e --- /dev/null +++ b/packages/vectors3/src/jitter.ts @@ -0,0 +1,10 @@ +import { IRandom } from "@thi.ng/random/api"; +import { SYSTEM } from "@thi.ng/random/system"; +import { add } from "./add"; +import { ReadonlyVec, Vec } from "./api"; +import { randNorm } from "./random"; +import { zeroes } from "./setn"; + +export const jitter = + (out: Vec, a: ReadonlyVec, n = 1, rnd: IRandom = SYSTEM) => + add(out, randNorm(zeroes(a.length), n, rnd), a); diff --git a/packages/vectors3/src/round.ts b/packages/vectors3/src/round.ts new file mode 100644 index 0000000000..0a6942216f --- /dev/null +++ b/packages/vectors3/src/round.ts @@ -0,0 +1,11 @@ +import { roundTo as _round } from "@thi.ng/math/prec"; +import { MultiVecOpVO, VecOpVO } from "./api"; +import { defHofOp } from "./internal/codegen"; + +export const [round, round2, round3, round4] = + defHofOp, VecOpVO>( + _round, + ([o, a]) => `${o}=op(${a},n);`, + "o,a,n=1", + "o,a" + ); diff --git a/packages/vectors3/src/sinh.ts b/packages/vectors3/src/sinh.ts new file mode 100644 index 0000000000..3925ba0ece --- /dev/null +++ b/packages/vectors3/src/sinh.ts @@ -0,0 +1,5 @@ +import { MultiVecOpV, VecOpV } from "./api"; +import { defFnOp } from "./internal/codegen"; + +export const [sinh, sinh2, sinh3, sinh4] = + defFnOp("Math.sinh"); diff --git a/packages/vectors3/src/tanh.ts b/packages/vectors3/src/tanh.ts new file mode 100644 index 0000000000..18e849fe32 --- /dev/null +++ b/packages/vectors3/src/tanh.ts @@ -0,0 +1,5 @@ +import { MultiVecOpV, VecOpV } from "./api"; +import { defFnOp } from "./internal/codegen"; + +export const [tanh, tanh2, tanh3, tanh4] = + defFnOp("Math.tanh"); diff --git a/packages/vectors3/src/wrap.ts b/packages/vectors3/src/wrap.ts new file mode 100644 index 0000000000..64e5dd68a5 --- /dev/null +++ b/packages/vectors3/src/wrap.ts @@ -0,0 +1,10 @@ +import { wrap as _wrap } from "@thi.ng/math/interval"; +import { MultiVecOpVVV, VecOpVVV } from "./api"; +import { defHofOp } from "./internal/codegen"; + +export const [wrap, wrap2, wrap3, wrap4] = + defHofOp( + _wrap, + ([o, a, b, c]) => `${o}=op(${a},${b},${c});`, + "o,a,b,c" + ); From 52273cde520e92967d0ed2c97d70fe47f7021ce4 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 25 Nov 2018 23:41:59 +0000 Subject: [PATCH 039/333] feat(vectors): re-add (some) strided ops, update codegens, simplify --- packages/vectors3/src/add.ts | 3 +- packages/vectors3/src/addn.ts | 3 +- packages/vectors3/src/adds.ts | 6 + packages/vectors3/src/api.ts | 4 + packages/vectors3/src/copy.ts | 4 +- packages/vectors3/src/div.ts | 3 +- packages/vectors3/src/divn.ts | 3 +- packages/vectors3/src/divs.ts | 6 + packages/vectors3/src/dot.ts | 5 +- packages/vectors3/src/dots.ts | 21 +++ packages/vectors3/src/empty.ts | 4 +- packages/vectors3/src/eqdelta.ts | 4 +- packages/vectors3/src/index.ts | 8 + packages/vectors3/src/internal/codegen.ts | 165 +++++++++++++++----- packages/vectors3/src/internal/templates.ts | 8 + packages/vectors3/src/magsq.ts | 2 +- packages/vectors3/src/mul.ts | 3 +- packages/vectors3/src/muln.ts | 3 +- packages/vectors3/src/muls.ts | 6 + packages/vectors3/src/ortho-normal.ts | 6 +- packages/vectors3/src/perpendicular.ts | 10 +- packages/vectors3/src/set.ts | 3 +- packages/vectors3/src/setn.ts | 3 +- packages/vectors3/src/sets.ts | 6 + packages/vectors3/src/setsn.ts | 6 + packages/vectors3/src/sub.ts | 3 +- packages/vectors3/src/subn.ts | 3 +- packages/vectors3/src/subs.ts | 6 + packages/vectors3/src/swizzle.ts | 57 ++++++- 29 files changed, 294 insertions(+), 70 deletions(-) create mode 100644 packages/vectors3/src/adds.ts create mode 100644 packages/vectors3/src/divs.ts create mode 100644 packages/vectors3/src/dots.ts create mode 100644 packages/vectors3/src/internal/templates.ts create mode 100644 packages/vectors3/src/muls.ts create mode 100644 packages/vectors3/src/sets.ts create mode 100644 packages/vectors3/src/setsn.ts create mode 100644 packages/vectors3/src/subs.ts diff --git a/packages/vectors3/src/add.ts b/packages/vectors3/src/add.ts index 08c4c2322f..bb7d12a9fb 100644 --- a/packages/vectors3/src/add.ts +++ b/packages/vectors3/src/add.ts @@ -1,5 +1,6 @@ import { MultiVecOpVV, VecOpVV } from "./api"; import { defOp } from "./internal/codegen"; +import { MATH } from "./internal/templates"; export const [add, add2, add3, add4] = - defOp(([o, a, b]) => `${o}=${a}+${b};`); + defOp(MATH("+")); diff --git a/packages/vectors3/src/addn.ts b/packages/vectors3/src/addn.ts index 773b220def..c86530310a 100644 --- a/packages/vectors3/src/addn.ts +++ b/packages/vectors3/src/addn.ts @@ -1,5 +1,6 @@ import { MultiVecOpVN, VecOpVN } from "./api"; import { defOp } from "./internal/codegen"; +import { MATH_N } from "./internal/templates"; export const [addN, addN2, addN3, addN4] = - defOp(([o, a]) => `${o}=${a}+n;`, "o,a,n"); + defOp(MATH_N("+"), "o,a,n"); diff --git a/packages/vectors3/src/adds.ts b/packages/vectors3/src/adds.ts new file mode 100644 index 0000000000..13908e35f3 --- /dev/null +++ b/packages/vectors3/src/adds.ts @@ -0,0 +1,6 @@ +import { VecOpSVV } from "./api"; +import { defOpS } from "./internal/codegen"; +import { MATH } from "./internal/templates"; + +export const [addS2, addS3, addS4] = + defOpS(MATH("+")); diff --git a/packages/vectors3/src/api.ts b/packages/vectors3/src/api.ts index ee7a59a21b..ad729b07be 100644 --- a/packages/vectors3/src/api.ts +++ b/packages/vectors3/src/api.ts @@ -47,6 +47,10 @@ export type VecOpRoV = (a: ReadonlyVec) => T; export type VecOpRoVV = (a: ReadonlyVec, b: ReadonlyVec) => T; export type VecOpRoVVO = (a: ReadonlyVec, b: ReadonlyVec, c: O) => T; +export type VecOpSV = (out: Vec, a: ReadonlyVec, io?: number, ia?: number, so?: number, sa?: number) => Vec; +export type VecOpSVV = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, io?: number, ia?: number, ib?: number, so?: number, sa?: number, sb?: number) => Vec; +export type VecOpSRoVV = (a: ReadonlyVec, b: ReadonlyVec, ia?: number, ib?: number, sa?: number, sb?: number) => Vec; + export interface MultiVecOpV extends VecOpV, MultiVecOp { } export interface MultiVecOpN extends VecOpN, MultiVecOp { } export interface MultiVecOpVV extends VecOpVV, MultiVecOp { } diff --git a/packages/vectors3/src/copy.ts b/packages/vectors3/src/copy.ts index 5db5b48755..60fda83629 100644 --- a/packages/vectors3/src/copy.ts +++ b/packages/vectors3/src/copy.ts @@ -1,8 +1,8 @@ import { implementsFunction } from "@thi.ng/checks/implements-function"; -import { ReadonlyVec } from "./api"; +import { ReadonlyVec, Vec } from "./api"; export const copy = - (v: ReadonlyVec) => + (v: ReadonlyVec): Vec => implementsFunction(v, "copy") ? (v).copy() : [...v]; diff --git a/packages/vectors3/src/div.ts b/packages/vectors3/src/div.ts index b286cf90c9..1ac6b113b5 100644 --- a/packages/vectors3/src/div.ts +++ b/packages/vectors3/src/div.ts @@ -1,5 +1,6 @@ import { MultiVecOpVV, VecOpVV } from "./api"; import { defOp } from "./internal/codegen"; +import { MATH } from "./internal/templates"; export const [div, div2, div3, div4] = - defOp(([o, a, b]) => `${o}=${a}/${b};`); + defOp(MATH("/")); diff --git a/packages/vectors3/src/divn.ts b/packages/vectors3/src/divn.ts index 0892cc4305..1c44c438a3 100644 --- a/packages/vectors3/src/divn.ts +++ b/packages/vectors3/src/divn.ts @@ -1,5 +1,6 @@ import { MultiVecOpVN, VecOpVN } from "./api"; import { defOp } from "./internal/codegen"; +import { MATH_N } from "./internal/templates"; export const [divN, divN2, divN3, divN4] = - defOp(([o, a]) => `${o}=${a}/n;`, "o,a,n"); + defOp(MATH_N("/"), "o,a,n"); diff --git a/packages/vectors3/src/divs.ts b/packages/vectors3/src/divs.ts new file mode 100644 index 0000000000..5960a124ec --- /dev/null +++ b/packages/vectors3/src/divs.ts @@ -0,0 +1,6 @@ +import { VecOpSVV } from "./api"; +import { defOpS } from "./internal/codegen"; +import { MATH } from "./internal/templates"; + +export const [divS2, divS3, divS4] = + defOpS(MATH("/")); diff --git a/packages/vectors3/src/dot.ts b/packages/vectors3/src/dot.ts index 43c6edd295..b6a0bfb64f 100644 --- a/packages/vectors3/src/dot.ts +++ b/packages/vectors3/src/dot.ts @@ -1,5 +1,6 @@ import { MultiVecOpRoVV } from "./api"; import { compile, compileG } from "./internal/codegen"; +import { DOT, DOT_G } from "./internal/templates"; import { vop } from "./internal/vop"; const $ = (dim: number) => @@ -7,7 +8,7 @@ const $ = (dim: number) => dim, compile( dim, - ([a, b]) => `${a}*${b}`, + DOT, "a,b", undefined, null, @@ -20,7 +21,7 @@ const $ = (dim: number) => export const dot: MultiVecOpRoVV = vop(); dot.default( - compileG(([a, b]) => `sum+=${a}*${b};`, "a,b", undefined, "sum", "let sum=0;") + compileG(DOT_G, "a,b", undefined, "sum", "let sum=0;") ); export const dot2 = $(2); diff --git a/packages/vectors3/src/dots.ts b/packages/vectors3/src/dots.ts new file mode 100644 index 0000000000..29eb193862 --- /dev/null +++ b/packages/vectors3/src/dots.ts @@ -0,0 +1,21 @@ +import { VecOpSRoVV } from "./api"; +import { compile, SARGS_V } from "./internal/codegen"; +import { DOT } from "./internal/templates"; + +const $ = + (dim: number): VecOpSRoVV => + compile( + dim, + DOT, + `o,a,${SARGS_V}`, + "o,a", + null, + "+", + "return ", + ";", + true + ); + +export const dotS2 = $(2); +export const dotS3 = $(3); +export const dotS4 = $(4); diff --git a/packages/vectors3/src/empty.ts b/packages/vectors3/src/empty.ts index 37c2219efd..3f79560bc9 100644 --- a/packages/vectors3/src/empty.ts +++ b/packages/vectors3/src/empty.ts @@ -1,9 +1,9 @@ -import { ReadonlyVec } from "./api"; import { implementsFunction } from "@thi.ng/checks/implements-function"; +import { ReadonlyVec, Vec } from "./api"; import { zeroes } from "./setn"; export const empty = - (v: ReadonlyVec) => + (v: ReadonlyVec): Vec => implementsFunction(v, "empty") ? (v).empty() : zeroes(v.length); diff --git a/packages/vectors3/src/eqdelta.ts b/packages/vectors3/src/eqdelta.ts index b53e075cf1..dbb6773ebd 100644 --- a/packages/vectors3/src/eqdelta.ts +++ b/packages/vectors3/src/eqdelta.ts @@ -32,7 +32,7 @@ eqDelta.default( if (implementsFunction(v2, "eqDelta")) { return (v2).eqDelta(v1, eps); } - return eqDeltaStrided(v1, v2, v1.length, eps); + return eqDeltaS(v1, v2, v1.length, eps); } ); @@ -53,7 +53,7 @@ export const eqDelta4 = $(4); * @param sa stride a * @param sb stride b */ -export const eqDeltaStrided = ( +export const eqDeltaS = ( a: ReadonlyVec, b: ReadonlyVec, n: number, diff --git a/packages/vectors3/src/index.ts b/packages/vectors3/src/index.ts index 40d16e7ef0..51b00efb4c 100644 --- a/packages/vectors3/src/index.ts +++ b/packages/vectors3/src/index.ts @@ -10,6 +10,7 @@ export * from "./abs"; export * from "./acos"; export * from "./add"; export * from "./addn"; +export * from "./adds"; export * from "./angle-between"; export * from "./asin"; export * from "./bisect"; @@ -28,7 +29,9 @@ export * from "./dist-manhattan"; export * from "./distsq"; export * from "./div"; export * from "./divn"; +export * from "./divs"; export * from "./dot"; +export * from "./dots"; export * from "./empty"; export * from "./eqdelta"; export * from "./exp"; @@ -54,6 +57,7 @@ export * from "./mod"; export * from "./modn"; export * from "./mul"; export * from "./muln"; +export * from "./muls"; export * from "./neg"; export * from "./normalize"; export * from "./perpendicular"; @@ -69,6 +73,8 @@ export * from "./rotate"; export * from "./round"; export * from "./set"; export * from "./setn"; +export * from "./sets"; +export * from "./setsn"; export * from "./sign"; export * from "./sin"; export * from "./sinh"; @@ -77,6 +83,8 @@ export * from "./step"; export * from "./smoothstep"; export * from "./sub"; export * from "./subn"; +export * from "./subs"; +export * from "./swizzle"; export * from "./tan"; export * from "./tanh"; export * from "./trunc"; diff --git a/packages/vectors3/src/internal/codegen.ts b/packages/vectors3/src/internal/codegen.ts index a5d53917f2..297543d746 100644 --- a/packages/vectors3/src/internal/codegen.ts +++ b/packages/vectors3/src/internal/codegen.ts @@ -6,20 +6,64 @@ import { transduce } from "@thi.ng/transducers/transduce"; import { map } from "@thi.ng/transducers/xform/map"; import { mapIndexed } from "@thi.ng/transducers/xform/map-indexed"; import { take } from "@thi.ng/transducers/xform/take"; +import { FN } from "./templates"; import { vop } from "./vop"; +export const ARGS_V = "o,a"; +export const ARGS_VV = "o,a,b"; + +export const SARGS_V = "io=0,ia=0,so=1,sa=1"; +export const SARGS_VV = "io=0,ia=0,ib=0,so=1,sa=1,sb=1"; +export const SARGS_VVV = "io=0,ia=0,ib=0,ic=0,so=1,sa=1,sb=1,sc=1"; + export type Template = (syms: string[], i?: number) => string; -export const indices = (sym: string) => map((i) => `${sym}[${i}]`, range()); +/** + * HOF array index lookup gen to provide optimized versions of: + * + * ``` + * lookup("a")(0) // a[ia] + * lookup("a")(1) // a[ia * sa] + * lookup("a")(2) // a[ia + 2 * sa] + * ``` + * + * @param sym + */ +const lookup = + (sym: string) => + (i) => i > 1 ? + `${sym}[i${sym}+${i}*s${sym}]` : + i == 1 ? `${sym}[i${sym}+s${sym}]` : + `${sym}[i${sym}]`; + +/** + * Infinite iterator of strided index lookups for `sym`. + * + * @param sym + */ +const indicesStrided = + (sym: string) => map(lookup(sym), range()); + +/** + * Infinite iterator of simple (non-strided) index lookups for `sym`. + * + * @param sym + */ +const indices = + (sym: string) => map((i) => `${sym}[${i}]`, range()); /** - * Takes a vector size `dim`, a code template function and an array of - * symbol names participating in the template. For each symbol, creates - * iterator of index lookups (e.g. `a[0]`), forms them into tuples and - * passes them to template to generate code. If the optional `ret` arg - * is not `null` (default `"a"`), appends a `return` statement to the - * result array, using `ret` as return value. Returns array of source - * code lines. + * Code generator for loop-unrolled vector operations. Takes a vector + * size `dim`, a code template function `tpl` and an array of symbol + * names participating in the template. For each symbol, creates + * iterator of index lookups (e.g. `a[0]` or `a[ia+k*sa]`), forms them + * into tuples and passes them to template to generate code and joins + * generated result with `opJoin` separator (default: + * `""`). + * + * If the optional `ret` arg is not `null` (default `"a"`), appends a + * `return` statement to the result array, using `ret` as return value. + * Returns array of source code lines. * * The optional `pre` and `post` strings can be used to wrap the * generated code. `post` will be injected **before** the generated @@ -32,36 +76,55 @@ export const indices = (sym: string) => map((i) => `${sym}[${i}]`, range()); * @param opJoin * @param pre * @param post + * @param strided */ -export const assemble = ( +const assemble = ( dim: number, tpl: Template, syms: string, ret = "a", opJoin = "", pre = "", - post = "") => + post = "", + strided = false) => [ pre, transduce( - comp(take(dim), mapIndexed((i, x: string[]) => tpl(x, i))), + comp( + take(dim), + mapIndexed((i, x: string[]) => tpl(x, i)) + ), str(opJoin), - tuples.apply(null, [...map(indices, syms.split(","))]) + tuples.apply( + null, + syms.split(",").map( + strided ? + indicesStrided : + indices, + ) + ) ), post, ret !== null ? `return ${ret};` : "" ]; -export const assembleG = ( +const assembleG = ( tpl: Template, syms: string, ret = "a", pre?: string, - post?: string) => [ + post?: string, + strided = false) => [ pre, "for(let i=a.length;--i>=0;) {", - tpl(syms.split(",").map((x) => `${x}[i]`)), + tpl( + syms.split(",").map( + strided ? + (x) => `${x}[i${x}+i*s${x}]` : + (x) => `${x}[i]` + ) + ), "}", post, ret !== null ? `return ${ret};` : "" @@ -75,9 +138,13 @@ export const compile = ( ret = "a", opJoin?: string, pre?: string, - post?: string) => + post?: string, + strided = false) => - new Function(args, assemble(dim, tpl, syms, ret, opJoin, pre, post).join("")); + new Function( + args, + assemble(dim, tpl, syms, ret, opJoin, pre, post, strided).join("") + ); export const compileHOF = ( dim: number, @@ -89,11 +156,14 @@ export const compileHOF = ( ret = "a", opJoin = "", pre?: string, - post?: string) => { + post?: string, + strided = false) => { return new Function( hofArgs, - `return (${args})=>{${assemble(dim, tpl, syms, ret, opJoin, pre, post).join("\n")}}` + `return (${args})=>{${ + assemble(dim, tpl, syms, ret, opJoin, pre, post, strided).join("") + }}` )(...fns); }; @@ -103,9 +173,13 @@ export const compileG = ( syms = args, ret = "a", pre?: string, - post?: string) => + post?: string, + strided = false) => - new Function(args, assembleG(tpl, syms, ret, pre, post).join("")); + new Function( + args, + assembleG(tpl, syms, ret, pre, post, strided).join("") + ); export const compileGHOF = ( fns: any[], @@ -115,38 +189,55 @@ export const compileGHOF = ( syms = args, ret = "a", pre?: string, - post?: string) => + post?: string, + strided = false) => new Function( hofArgs, - `return (${args})=>{${assembleG(tpl, syms, ret, pre, post).join("\n")}}` + `return (${args})=>{${ + assembleG(tpl, syms, ret, pre, post, strided).join("") + }}` )(...fns); -export const defOp = (tpl: Template, args?: string, syms?: string, ret = "o", dispatch = 1): [M, V, V, V] => { - const fn: any = vop(dispatch); - args = args || "o,a,b"; - syms = syms || args; - const $ = (dim) => fn.add(dim, compile(dim, tpl, args, syms, ret)); - fn.default(compileG(tpl, args, syms, ret)); - return [fn, $(2), $(3), $(4)]; -}; +export const defOp = ( + tpl: Template, + args = ARGS_VV, + syms?: string, + ret = "o", + dispatch = 1): [M, V, V, V] => { -export const defFnOp = (op: string, tpl?: Template, args?: string, syms?: string, ret = "o", dispatch = 1): [M, V, V, V] => { - const fn: any = vop(dispatch); - tpl = tpl || (([o, a]) => `${o}=${op}(${a});`); - args = args || "o,a"; syms = syms || args; + const fn: any = vop(dispatch); const $ = (dim) => fn.add(dim, compile(dim, tpl, args, syms, ret)); fn.default(compileG(tpl, args, syms, ret)); return [fn, $(2), $(3), $(4)]; }; -export const defHofOp = (op, tpl?: Template, args?: string, syms?: string, ret = "o", dispatch = 1): [M, V, V, V] => { +export const defFnOp = + (op: string) => defOp(FN(op), ARGS_V); + +export const defHofOp = ( + op, + tpl?: Template, + args?: string, + syms?: string, + ret = "o", + dispatch = 1): [M, V, V, V] => { + const fn: any = vop(dispatch); tpl = tpl || (([o, a]) => `${o}=op(${a});`); - args = args || "o,a"; + args = args || ARGS_V; syms = syms || args; const $ = (dim) => compileHOF(dim, [op], tpl, "op", args, syms, ret); fn.default(compileGHOF([op], tpl, "op", args, syms, ret)); return [fn, $(2), $(3), $(4)]; }; + +export const defOpS = ( + tpl: Template, + args = `${ARGS_VV},${SARGS_VV}`, + syms = ARGS_VV, + ret = "o", + sizes = [2, 3, 4]): V[] => + + sizes.map((dim) => compile(dim, tpl, args, syms, ret, "", "", "", true)); diff --git a/packages/vectors3/src/internal/templates.ts b/packages/vectors3/src/internal/templates.ts new file mode 100644 index 0000000000..093c00e839 --- /dev/null +++ b/packages/vectors3/src/internal/templates.ts @@ -0,0 +1,8 @@ +export const MATH = (op: string) => ([o, a, b]) => `${o}=${a}${op}${b};` +export const MATH_N = (op: string) => ([o, a]) => `${o}=${a}${op}n;` +export const FN = (op: string) => ([o, a]) => `${o}=${op}(${a});` + +export const DOT = ([a, b]) => `${a}*${b}`; +export const DOT_G = ([a, b]) => `sum+=${a}*${b};`; +export const SET = ([o, a]) => `${o}=${a};`; +export const SET_N = ([a]) => `${a}=n;` diff --git a/packages/vectors3/src/magsq.ts b/packages/vectors3/src/magsq.ts index b736b1ac8f..f2533c874b 100644 --- a/packages/vectors3/src/magsq.ts +++ b/packages/vectors3/src/magsq.ts @@ -9,7 +9,7 @@ const $ = (dim: number) => dim, ([a]) => `${a}*${a}`, "a", - undefined, + "a", null, "+", "return ", diff --git a/packages/vectors3/src/mul.ts b/packages/vectors3/src/mul.ts index a22f0fe28f..9755527c5b 100644 --- a/packages/vectors3/src/mul.ts +++ b/packages/vectors3/src/mul.ts @@ -1,5 +1,6 @@ import { MultiVecOpVV, VecOpVV } from "./api"; import { defOp } from "./internal/codegen"; +import { MATH } from "./internal/templates"; export const [mul, mul2, mul3, mul4] = - defOp(([o, a, b]) => `${o}=${a}*${b};`); + defOp(MATH("*")); diff --git a/packages/vectors3/src/muln.ts b/packages/vectors3/src/muln.ts index 65a7a43fc1..efc8480649 100644 --- a/packages/vectors3/src/muln.ts +++ b/packages/vectors3/src/muln.ts @@ -1,5 +1,6 @@ import { MultiVecOpVN, VecOpVN } from "./api"; import { defOp } from "./internal/codegen"; +import { MATH_N } from "./internal/templates"; export const [mulN, mulN2, mulN3, mulN4] = - defOp(([o, a]) => `${o}=${a}*n;`, "o,a,n"); + defOp(MATH_N("*"), "o,a,n"); diff --git a/packages/vectors3/src/muls.ts b/packages/vectors3/src/muls.ts new file mode 100644 index 0000000000..f07d896cd6 --- /dev/null +++ b/packages/vectors3/src/muls.ts @@ -0,0 +1,6 @@ +import { VecOpSVV } from "./api"; +import { defOpS } from "./internal/codegen"; +import { MATH } from "./internal/templates"; + +export const [mulS2, mulS3, mulS4] = + defOpS(MATH("*")); diff --git a/packages/vectors3/src/ortho-normal.ts b/packages/vectors3/src/ortho-normal.ts index cd73d3ac31..a018c59131 100644 --- a/packages/vectors3/src/ortho-normal.ts +++ b/packages/vectors3/src/ortho-normal.ts @@ -1,7 +1,7 @@ -import { ReadonlyVec, Vec } from "./api"; +import { VecOpVVV } from "./api"; import { cross3 } from "./cross"; import { sub3 } from "./sub"; -export const orthoNormal3 = - (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => +export const orthoNormal3: VecOpVVV = + (out, a, b, c) => cross3(out, sub3(out, c, a), sub3([], b, a)); diff --git a/packages/vectors3/src/perpendicular.ts b/packages/vectors3/src/perpendicular.ts index a15de5254e..49b49d6911 100644 --- a/packages/vectors3/src/perpendicular.ts +++ b/packages/vectors3/src/perpendicular.ts @@ -1,15 +1,15 @@ -import { ReadonlyVec, Vec } from "./api"; +import { VecOpV } from "./api"; -export const perpendicularLeft2 = - (out: Vec, a: ReadonlyVec) => { +export const perpendicularLeft2: VecOpV = + (out, a) => { const x = a[0]; out[0] = -a[1]; out[1] = x; return out; }; -export const perpendicularRight2 = - (out: Vec, a: ReadonlyVec) => { +export const perpendicularRight2: VecOpV = + (out, a) => { const x = -a[0]; out[0] = a[1]; out[1] = x; diff --git a/packages/vectors3/src/set.ts b/packages/vectors3/src/set.ts index 99f2e05cd7..149e3a304d 100644 --- a/packages/vectors3/src/set.ts +++ b/packages/vectors3/src/set.ts @@ -1,5 +1,6 @@ import { MultiVecOpV, VecOpV } from "./api"; import { defOp } from "./internal/codegen"; +import { SET } from "./internal/templates"; export const [set, set2, set3, set4] = - defOp(([o, a]) => `${o}=${a};`); + defOp(SET, "o,a"); diff --git a/packages/vectors3/src/setn.ts b/packages/vectors3/src/setn.ts index 7b0fbb67c7..e3fa0f7132 100644 --- a/packages/vectors3/src/setn.ts +++ b/packages/vectors3/src/setn.ts @@ -1,8 +1,9 @@ import { MultiVecOpN, Vec, VecOpN } from "./api"; import { defOp } from "./internal/codegen"; +import { SET_N } from "./internal/templates"; export const [setN, setN2, setN3, setN4] = - defOp(([a]) => `${a}=n;`, "a,n", "a", "a", 0); + defOp(SET_N, "a,n", "a", "a", 0); export const zero = (a: Vec) => setN(a, 0); export const one = (a: Vec) => setN(a, 1); diff --git a/packages/vectors3/src/sets.ts b/packages/vectors3/src/sets.ts new file mode 100644 index 0000000000..234158a246 --- /dev/null +++ b/packages/vectors3/src/sets.ts @@ -0,0 +1,6 @@ +import { VecOpSV } from "./api"; +import { defOpS, SARGS_V } from "./internal/codegen"; +import { SET } from "./internal/templates"; + +export const [setS2, setS3, setS4] = + defOpS(SET, `o,a,${SARGS_V}`, "o,a"); diff --git a/packages/vectors3/src/setsn.ts b/packages/vectors3/src/setsn.ts new file mode 100644 index 0000000000..a7d285c3a8 --- /dev/null +++ b/packages/vectors3/src/setsn.ts @@ -0,0 +1,6 @@ +import { VecOpSV } from "./api"; +import { defOpS } from "./internal/codegen"; +import { SET_N } from "./internal/templates"; + +export const [setSN2, setSN3, setSN4] = + defOpS(SET_N, "o,n,io=0,so=1", "o"); diff --git a/packages/vectors3/src/sub.ts b/packages/vectors3/src/sub.ts index 9d4107e7b3..e4696d8172 100644 --- a/packages/vectors3/src/sub.ts +++ b/packages/vectors3/src/sub.ts @@ -1,5 +1,6 @@ import { MultiVecOpVV, VecOpVV } from "./api"; import { defOp } from "./internal/codegen"; +import { MATH } from "./internal/templates"; export const [sub, sub2, sub3, sub4] = - defOp(([o, a, b]) => `${o}=${a}-${b};`); + defOp(MATH("-")); diff --git a/packages/vectors3/src/subn.ts b/packages/vectors3/src/subn.ts index 16f313b4b7..560bbb60f4 100644 --- a/packages/vectors3/src/subn.ts +++ b/packages/vectors3/src/subn.ts @@ -1,5 +1,6 @@ import { MultiVecOpVN, VecOpVN } from "./api"; import { defOp } from "./internal/codegen"; +import { MATH_N } from "./internal/templates"; export const [subN, subN2, subN3, subN4] = - defOp(([o, a]) => `${o}=${a}-n;`, "o,a,n"); + defOp(MATH_N("-"), "o,a,n"); diff --git a/packages/vectors3/src/subs.ts b/packages/vectors3/src/subs.ts new file mode 100644 index 0000000000..455bcff401 --- /dev/null +++ b/packages/vectors3/src/subs.ts @@ -0,0 +1,6 @@ +import { VecOpSVV } from "./api"; +import { defOpS } from "./internal/codegen"; +import { MATH } from "./internal/templates"; + +export const [subS2, subS3, subS4] = + defOpS(MATH("-")); diff --git a/packages/vectors3/src/swizzle.ts b/packages/vectors3/src/swizzle.ts index 0ad363cf8e..9abf035bc8 100644 --- a/packages/vectors3/src/swizzle.ts +++ b/packages/vectors3/src/swizzle.ts @@ -1,13 +1,58 @@ import { ReadonlyVec, Vec } from "./api"; +/** + * Places a re-ordered 2D version of vector `a` into `out`. MUST be + * separate instances. The given coord indices must be valid for `a`. + * No bounds checking. + * + * @param out + * @param a + * @param x new x coord index + * @param y new y coord index + */ export const swizzle2 = - (out: Vec, b: ReadonlyVec, x: number, y: number) => - (out[0] = b[x] || 0, out[1] = b[y] || 0, out); + (out: Vec, a: ReadonlyVec, x: number, y: number) => ( + out[0] = a[x] || 0, + out[1] = a[y] || 0, + out + ); +/** + * Places a re-ordered 3D version of vector `a` into `out`. MUST be + * separate instances. The given coord indices must be valid for `a`. + * No bounds checking. + * + * @param out + * @param a + * @param x new x coord index + * @param y new y coord index + * @param z new z coord index + */ export const swizzle3 = - (out: Vec, b: ReadonlyVec, x: number, y: number, z: number) => - (out[0] = b[x] || 0, out[1] = b[y] || 0, out[2] = b[z] || 0, out); + (out: Vec, a: ReadonlyVec, x: number, y: number, z: number) => ( + out[0] = a[x] || 0, + out[1] = a[y] || 0, + out[2] = a[z] || 0, + out + ); +/** + * Places a re-ordered 4D version of vector `a` into `out`. MUST be + * separate instances. The given coord indices must be valid for `a`. + * No bounds checking. + * + * @param out + * @param a + * @param x new x coord index + * @param y new y coord index + * @param z new z coord index + * @param w new w coord index + */ export const swizzle4 = - (out: Vec, b: ReadonlyVec, x: number, y: number, z: number, w: number) => - (out[0] = b[x] || 0, out[1] = b[y] || 0, out[2] = b[z] || 0, out[3] = b[w] || 0, out); + (out: Vec, a: ReadonlyVec, x: number, y: number, z: number, w: number) => ( + out[0] = a[x] || 0, + out[1] = a[y] || 0, + out[2] = a[z] || 0, + out[3] = a[w] || 0, + out + ); From f940672e52c2b4b8dd63d1b2f393bcddf436d96c Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 26 Nov 2018 04:16:13 +0000 Subject: [PATCH 040/333] feat(matrices): extract matrix ops to own package --- packages/matrices/.npmignore | 11 ++ packages/matrices/LICENSE | 201 +++++++++++++++++++++++++++ packages/matrices/README.md | 40 ++++++ packages/matrices/package.json | 41 ++++++ packages/matrices/src/api.ts | 40 ++++++ packages/matrices/src/concat.ts | 20 +++ packages/matrices/src/convert.ts | 10 ++ packages/matrices/src/identity.ts | 23 +++ packages/matrices/src/index.ts | 8 ++ packages/matrices/src/mul.ts | 63 +++++++++ packages/matrices/src/mulv.ts | 41 ++++++ packages/matrices/src/set-values.ts | 14 ++ packages/matrices/src/set.ts | 12 ++ packages/matrices/test/index.ts | 6 + packages/matrices/test/tsconfig.json | 10 ++ packages/matrices/tsconfig.json | 9 ++ 16 files changed, 549 insertions(+) create mode 100644 packages/matrices/.npmignore create mode 100644 packages/matrices/LICENSE create mode 100644 packages/matrices/README.md create mode 100644 packages/matrices/package.json create mode 100644 packages/matrices/src/api.ts create mode 100644 packages/matrices/src/concat.ts create mode 100644 packages/matrices/src/convert.ts create mode 100644 packages/matrices/src/identity.ts create mode 100644 packages/matrices/src/index.ts create mode 100644 packages/matrices/src/mul.ts create mode 100644 packages/matrices/src/mulv.ts create mode 100644 packages/matrices/src/set-values.ts create mode 100644 packages/matrices/src/set.ts create mode 100644 packages/matrices/test/index.ts create mode 100644 packages/matrices/test/tsconfig.json create mode 100644 packages/matrices/tsconfig.json diff --git a/packages/matrices/.npmignore b/packages/matrices/.npmignore new file mode 100644 index 0000000000..ec83d74c9d --- /dev/null +++ b/packages/matrices/.npmignore @@ -0,0 +1,11 @@ +build +coverage +dev +doc +export +src* +test +.nyc_output +tsconfig.json +*.tgz +*.html diff --git a/packages/matrices/LICENSE b/packages/matrices/LICENSE new file mode 100644 index 0000000000..8dada3edaf --- /dev/null +++ b/packages/matrices/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/matrices/README.md b/packages/matrices/README.md new file mode 100644 index 0000000000..c5b0477ef9 --- /dev/null +++ b/packages/matrices/README.md @@ -0,0 +1,40 @@ +# @thi.ng/matrices + +[![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/matrices.svg)](https://www.npmjs.com/package/@thi.ng/matrices) +![npm downloads](https://img.shields.io/npm/dm/@thi.ng/matrices.svg) +[![Twitter Follow](https://img.shields.io/twitter/follow/thing_umbrella.svg?style=flat-square&label=twitter)](https://twitter.com/thing_umbrella) + +This project is part of the +[@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo. + + + + + +## About + +TODO... + +## Installation + +```bash +yarn add @thi.ng/matrices +``` + +## Dependencies + +- TODO... + +## Usage examples + +```ts +import * as m from "@thi.ng/matrices"; +``` + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/packages/matrices/package.json b/packages/matrices/package.json new file mode 100644 index 0000000000..f8d77b154e --- /dev/null +++ b/packages/matrices/package.json @@ -0,0 +1,41 @@ +{ + "name": "@thi.ng/matrices", + "version": "0.0.1", + "description": "TODO", + "main": "./index.js", + "typings": "./index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/thi-ng/umbrella.git" + }, + "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/matrices", + "author": "Karsten Schmidt ", + "license": "Apache-2.0", + "scripts": { + "build": "yarn run clean && tsc --declaration", + "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "cover": "yarn test && nyc report --reporter=lcov", + "doc": "node_modules/.bin/typedoc --mode modules --out doc src", + "pub": "yarn run build && yarn publish --access public", + "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + }, + "devDependencies": { + "@types/mocha": "^5.2.5", + "@types/node": "^10.12.0", + "mocha": "^5.2.0", + "nyc": "^13.1.0", + "typedoc": "^0.13.0", + "typescript": "^3.1.3" + }, + "dependencies": { + "@thi.ng/api": "^4.2.3", + "@thi.ng/vectors3": "^0.0.1" + }, + "keywords": [ + "ES6", + "typescript" + ], + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/packages/matrices/src/api.ts b/packages/matrices/src/api.ts new file mode 100644 index 0000000000..2dee065cbc --- /dev/null +++ b/packages/matrices/src/api.ts @@ -0,0 +1,40 @@ +import { Vec, ReadonlyVec, IVector, MultiVecOp } from "@thi.ng/vectors3/api"; + +export type Mat = Vec; +export type ReadonlyMat = ReadonlyVec; +export type IMatrix = IVector; +export type MultiMatOp = MultiVecOp; + +export type MatOp1 = (out: Mat) => Mat; +export type MatOpM = (out: Mat, a: ReadonlyMat) => Mat; +export type MatOpN = (out: Mat, n: number) => Mat; +export type MatOpMM = (out: Mat, a: ReadonlyMat, b: ReadonlyMat) => Mat; +export type MatOpMV = (out: Vec, a: ReadonlyMat, b: ReadonlyVec) => Mat; + +export interface MultiMatOp1 extends MatOp1, MultiMatOp { } +export interface MultiMatOpM extends MatOpM, MultiMatOp { } +export interface MultiMatOpN extends MatOpN, MultiMatOp { } + +export const IDENT22 = [ + 1, 0, + 0, 1 +]; + +export const IDENT23 = [ + 1, 0, + 0, 1, + 0, 0 +]; + +export const IDENT33 = [ + 1, 0, 0, + 0, 1, 0, + 0, 0, 1 +]; + +export const IDENT44 = [ + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 +]; diff --git a/packages/matrices/src/concat.ts b/packages/matrices/src/concat.ts new file mode 100644 index 0000000000..cc8bff6d1a --- /dev/null +++ b/packages/matrices/src/concat.ts @@ -0,0 +1,20 @@ +import { Mat, MatOpMM, ReadonlyMat } from "./api"; +import { + mul22, + mul23, + mul33, + mul44 +} from "./mul"; + +const $ = + (mul: MatOpMM) => + (out: Mat, a: ReadonlyMat, b: ReadonlyMat, ...xs: ReadonlyMat[]) => + xs.reduce( + (acc: Mat, x) => mul(acc, acc, x), + mul(out, a, b) + ); + +export const concat22 = $(mul22); +export const concat23 = $(mul23); +export const concat33 = $(mul33); +export const concat44 = $(mul44); diff --git a/packages/matrices/src/convert.ts b/packages/matrices/src/convert.ts new file mode 100644 index 0000000000..1b459e2a50 --- /dev/null +++ b/packages/matrices/src/convert.ts @@ -0,0 +1,10 @@ +import { setS3 } from "@thi.ng/vectors3/sets"; +import { MatOpM } from "./api"; + +export const mat44to33: MatOpM = + (m33, m44) => ( + setS3(m33, m44), + setS3(m33, m44, 3, 4), + setS3(m33, m44, 6, 8), + m33 + ); diff --git a/packages/matrices/src/identity.ts b/packages/matrices/src/identity.ts new file mode 100644 index 0000000000..02e6bb81c9 --- /dev/null +++ b/packages/matrices/src/identity.ts @@ -0,0 +1,23 @@ +import { vop } from "@thi.ng/vectors3/internal/vop"; +import { + IDENT22, + IDENT23, + IDENT33, + IDENT44, + MultiMatOp1 +} from "./api"; +import { set } from "./set"; + +export const identity: MultiMatOp1 = vop(); + +export const identity22 = + identity.add(4, (m) => set(m, IDENT22)); + +export const identity23 = + identity.add(6, (m) => set(m, IDENT23)); + +export const identity33 = + identity.add(9, (m) => set(m, IDENT33)); + +export const identity44 = + identity.add(9, (m) => set(m, IDENT44)); diff --git a/packages/matrices/src/index.ts b/packages/matrices/src/index.ts new file mode 100644 index 0000000000..37d6cf0a03 --- /dev/null +++ b/packages/matrices/src/index.ts @@ -0,0 +1,8 @@ +export * from "./api"; + +export * from "./concat"; +export * from "./convert"; +export * from "./identity"; +export * from "./mul"; +export * from "./mulv"; +export * from "./set"; diff --git a/packages/matrices/src/mul.ts b/packages/matrices/src/mul.ts new file mode 100644 index 0000000000..85177281c0 --- /dev/null +++ b/packages/matrices/src/mul.ts @@ -0,0 +1,63 @@ +import { dotS2, dotS3, dotS4 } from "@thi.ng/vectors3/dots"; +import { MatOpMM } from "./api"; +import { + setValues22, + setValues23, + setValues33, + setValues44 +} from "./set-values"; + +export const mul22: MatOpMM = + (out, a, b) => setValues22( + out, + dotS2(a, b, 0, 0, 2), + dotS2(a, b, 1, 0, 2), + dotS2(a, b, 0, 2, 2), + dotS2(a, b, 1, 2, 2), + ); + +export const mul23: MatOpMM = + (out, a, b) => setValues23( + out, + dotS2(a, b, 0, 0, 2), + dotS2(a, b, 1, 0, 2), + dotS2(a, b, 0, 2, 2), + dotS2(a, b, 1, 2, 2), + dotS2(a, b, 0, 4, 2) + a[4], + dotS2(a, b, 1, 4, 2) + a[5], + ); + +export const mul33: MatOpMM = + (out, a, b) => setValues33( + out, + dotS3(a, b, 0, 0, 3), + dotS3(a, b, 1, 0, 3), + dotS3(a, b, 2, 0, 3), + dotS3(a, b, 0, 3, 3), + dotS3(a, b, 1, 3, 3), + dotS3(a, b, 2, 3, 3), + dotS3(a, b, 0, 6, 3), + dotS3(a, b, 1, 6, 3), + dotS3(a, b, 2, 6, 3) + ); + +export const mul44: MatOpMM = + (out, a, b) => setValues44( + out, + dotS4(a, b, 0, 0, 4), + dotS4(a, b, 1, 0, 4), + dotS4(a, b, 2, 0, 4), + dotS4(a, b, 3, 0, 4), + dotS4(a, b, 0, 4, 4), + dotS4(a, b, 1, 4, 4), + dotS4(a, b, 2, 4, 4), + dotS4(a, b, 3, 4, 4), + dotS4(a, b, 0, 8, 4), + dotS4(a, b, 1, 8, 4), + dotS4(a, b, 2, 8, 4), + dotS4(a, b, 3, 8, 4), + dotS4(a, b, 0, 12, 4), + dotS4(a, b, 1, 12, 4), + dotS4(a, b, 2, 12, 4), + dotS4(a, b, 3, 12, 4) + ); diff --git a/packages/matrices/src/mulv.ts b/packages/matrices/src/mulv.ts new file mode 100644 index 0000000000..cba7ba0d5b --- /dev/null +++ b/packages/matrices/src/mulv.ts @@ -0,0 +1,41 @@ +import { dotS2, dotS3, dotS4 } from "@thi.ng/vectors3/dots"; +import { MatOpMV } from "./api"; + +export const mulV22: MatOpMV = + (out, m, v) => ( + out[0] = dotS2(m, v, 0, 0, 2), + out[1] = dotS2(m, v, 1, 0, 2), + out + ); + +export const mulV23: MatOpMV = + (out, m, v) => ( + out[0] = dotS2(m, v, 0, 0, 2) + m[4], + out[1] = dotS2(m, v, 1, 0, 2) + m[5], + out + ); + +export const mulV33: MatOpMV = + (out, m, v) => ( + out[0] = dotS3(m, v, 0, 0, 3), + out[1] = dotS3(m, v, 1, 0, 3), + out[2] = dotS3(m, v, 2, 0, 3), + out + ); + +export const mulV344: MatOpMV = + (out, m, v) => ( + out[0] = dotS3(m, v, 0, 0, 4) + m[12], + out[1] = dotS3(m, v, 1, 0, 4) + m[13], + out[2] = dotS3(m, v, 2, 0, 4) + m[14], + out + ); + +export const mulV44: MatOpMV = + (out, m, v) => ( + out[0] = dotS4(m, v, 0, 0, 4), + out[1] = dotS4(m, v, 1, 0, 4), + out[2] = dotS4(m, v, 2, 0, 4), + out[3] = dotS4(m, v, 3, 0, 4), + out + ); diff --git a/packages/matrices/src/set-values.ts b/packages/matrices/src/set-values.ts new file mode 100644 index 0000000000..c16fef6c14 --- /dev/null +++ b/packages/matrices/src/set-values.ts @@ -0,0 +1,14 @@ +import { Mat } from "./api"; +import { set23, set22, set33, set44 } from "./set"; + +export const setValues22 = + (mat: Mat, ...xs: number[]) => set22(mat, xs); + +export const setValues23 = + (mat: Mat, ...xs: number[]) => set23(mat, xs); + +export const setValues33 = + (mat: Mat, ...xs: number[]) => set33(mat, xs); + +export const setValues44 = + (mat: Mat, ...xs: number[]) => set44(mat, xs); \ No newline at end of file diff --git a/packages/matrices/src/set.ts b/packages/matrices/src/set.ts new file mode 100644 index 0000000000..b6cb2d6e0b --- /dev/null +++ b/packages/matrices/src/set.ts @@ -0,0 +1,12 @@ +import { set as _set, set4 } from "@thi.ng/vectors3/set"; +import { compile } from "@thi.ng/vectors3/internal/codegen"; +import { SET } from "@thi.ng/vectors3/internal/templates"; +import { MatOpM } from "./api"; + +const $ = (dim) => _set.add(dim, compile(dim, SET, "o,a")); + +export const set: MatOpM = _set; +export const set22: MatOpM = set4 +export const set23: MatOpM = $(6); +export const set33: MatOpM = $(9); +export const set44: MatOpM = $(16); diff --git a/packages/matrices/test/index.ts b/packages/matrices/test/index.ts new file mode 100644 index 0000000000..e020e6a654 --- /dev/null +++ b/packages/matrices/test/index.ts @@ -0,0 +1,6 @@ +// import * as assert from "assert"; +// import * as m from "../src/index"; + +describe("matrices", () => { + it("tests pending"); +}); diff --git a/packages/matrices/test/tsconfig.json b/packages/matrices/test/tsconfig.json new file mode 100644 index 0000000000..bcf29ace54 --- /dev/null +++ b/packages/matrices/test/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "../build" + }, + "include": [ + "./**/*.ts", + "../src/**/*.ts" + ] +} diff --git a/packages/matrices/tsconfig.json b/packages/matrices/tsconfig.json new file mode 100644 index 0000000000..bd6481a5a6 --- /dev/null +++ b/packages/matrices/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "." + }, + "include": [ + "./src/**/*.ts" + ] +} From 18ffdb79fb56f60308d34f64e6361c01944ac2de Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 26 Nov 2018 04:17:35 +0000 Subject: [PATCH 041/333] fix(vectors): update VecOpSRoVV & dotS impls --- packages/vectors3/src/api.ts | 2 +- packages/vectors3/src/dots.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/vectors3/src/api.ts b/packages/vectors3/src/api.ts index ad729b07be..76343d1581 100644 --- a/packages/vectors3/src/api.ts +++ b/packages/vectors3/src/api.ts @@ -49,7 +49,7 @@ export type VecOpRoVVO = (a: ReadonlyVec, b: ReadonlyVec, c: O) => T; export type VecOpSV = (out: Vec, a: ReadonlyVec, io?: number, ia?: number, so?: number, sa?: number) => Vec; export type VecOpSVV = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, io?: number, ia?: number, ib?: number, so?: number, sa?: number, sb?: number) => Vec; -export type VecOpSRoVV = (a: ReadonlyVec, b: ReadonlyVec, ia?: number, ib?: number, sa?: number, sb?: number) => Vec; +export type VecOpSRoVV = (a: ReadonlyVec, b: ReadonlyVec, ia?: number, ib?: number, sa?: number, sb?: number) => T; export interface MultiVecOpV extends VecOpV, MultiVecOp { } export interface MultiVecOpN extends VecOpN, MultiVecOp { } diff --git a/packages/vectors3/src/dots.ts b/packages/vectors3/src/dots.ts index 29eb193862..786ff0eaef 100644 --- a/packages/vectors3/src/dots.ts +++ b/packages/vectors3/src/dots.ts @@ -3,7 +3,7 @@ import { compile, SARGS_V } from "./internal/codegen"; import { DOT } from "./internal/templates"; const $ = - (dim: number): VecOpSRoVV => + (dim: number): VecOpSRoVV => compile( dim, DOT, From b697fd5d850a203f4bfd059b7a13404172509bf4 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 26 Nov 2018 04:59:12 +0000 Subject: [PATCH 042/333] refactor(vectors): update codegens --- packages/vectors3/src/internal/codegen.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/vectors3/src/internal/codegen.ts b/packages/vectors3/src/internal/codegen.ts index 297543d746..4e012e2169 100644 --- a/packages/vectors3/src/internal/codegen.ts +++ b/packages/vectors3/src/internal/codegen.ts @@ -219,16 +219,15 @@ export const defFnOp = export const defHofOp = ( op, tpl?: Template, - args?: string, + args = ARGS_V, syms?: string, ret = "o", dispatch = 1): [M, V, V, V] => { - const fn: any = vop(dispatch); - tpl = tpl || (([o, a]) => `${o}=op(${a});`); - args = args || ARGS_V; + tpl = tpl || FN("op"); syms = syms || args; const $ = (dim) => compileHOF(dim, [op], tpl, "op", args, syms, ret); + const fn: any = vop(dispatch); fn.default(compileGHOF([op], tpl, "op", args, syms, ret)); return [fn, $(2), $(3), $(4)]; }; From e19f622327ec5295fa5664a998c4fdeab9736cfa Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 26 Nov 2018 17:25:09 +0000 Subject: [PATCH 043/333] feat(vectors): add faceForward, invSqrt & dotValues* fns --- packages/vectors3/src/dot-values.ts | 35 +++++++++++++++++++++++++++ packages/vectors3/src/face-forward.ts | 10 ++++++++ packages/vectors3/src/index.ts | 3 +++ packages/vectors3/src/invsqrt.ts | 5 ++++ 4 files changed, 53 insertions(+) create mode 100644 packages/vectors3/src/dot-values.ts create mode 100644 packages/vectors3/src/face-forward.ts create mode 100644 packages/vectors3/src/invsqrt.ts diff --git a/packages/vectors3/src/dot-values.ts b/packages/vectors3/src/dot-values.ts new file mode 100644 index 0000000000..df82496786 --- /dev/null +++ b/packages/vectors3/src/dot-values.ts @@ -0,0 +1,35 @@ +/** + * Returns pairwise product sum of args (in order). + * + * @param a + * @param b + * @param c + * @param d + */ +export const dotValues4 = + (a: number, b: number, c: number, d: number) => + a * b + c * d; + +/** + * Returns pairwise product sum of args (in order). + * + * @param a + * @param b + * @param c + * @param d + */ +export const dotValues6 = + (a: number, b: number, c: number, d: number, e: number, f: number) => + a * b + c * d + e * f; + +/** + * Returns pairwise product sum of args (in order). + * + * @param a + * @param b + * @param c + * @param d + */ +export const dotValues8 = + (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => + a * b + c * d + e * f + g * h; diff --git a/packages/vectors3/src/face-forward.ts b/packages/vectors3/src/face-forward.ts new file mode 100644 index 0000000000..b8c1565d68 --- /dev/null +++ b/packages/vectors3/src/face-forward.ts @@ -0,0 +1,10 @@ +import { VecOpVVV } from "./api"; +import { dot } from "./dot"; +import { mulN } from "./muln"; +import { set } from "./set"; + +export const faceForward: VecOpVVV = + (out, n, i, nref) => + dot(nref, i) < 0 ? + out === n ? out : set(out, n) : + mulN(out, n, -1); diff --git a/packages/vectors3/src/index.ts b/packages/vectors3/src/index.ts index 51b00efb4c..c6616a599f 100644 --- a/packages/vectors3/src/index.ts +++ b/packages/vectors3/src/index.ts @@ -32,13 +32,16 @@ export * from "./divn"; export * from "./divs"; export * from "./dot"; export * from "./dots"; +export * from "./dot-values"; export * from "./empty"; export * from "./eqdelta"; export * from "./exp"; +export * from "./face-forward"; export * from "./floor"; export * from "./fract"; export * from "./heading"; export * from "./invert"; +export * from "./invsqrt"; export * from "./jitter"; export * from "./limit"; export * from "./log"; diff --git a/packages/vectors3/src/invsqrt.ts b/packages/vectors3/src/invsqrt.ts new file mode 100644 index 0000000000..f948bd5480 --- /dev/null +++ b/packages/vectors3/src/invsqrt.ts @@ -0,0 +1,5 @@ +import { MultiVecOpV, VecOpV } from "./api"; +import { defOp } from "./internal/codegen"; + +export const [invSqrt, invSqrt2, invSqrt3, invSqrt4] = + defOp(([o, a]) => `${o}=1/Math.sqrt(${a});`); From f04e79e9a0df81f84d9b62e961aca4380d7d58e0 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 26 Nov 2018 17:34:40 +0000 Subject: [PATCH 044/333] feat(matrices): add more matrix ops, optimize & simplify --- packages/matrices/src/api.ts | 4 +- packages/matrices/src/concat.ts | 27 ++----- packages/matrices/src/convert.ts | 13 ++- packages/matrices/src/determinant.ts | 57 +++++++++++++ packages/matrices/src/index.ts | 10 +++ packages/matrices/src/invert.ts | 91 +++++++++++++++++++++ packages/matrices/src/mul.ts | 111 ++++++++++++++------------ packages/matrices/src/mulv.ts | 76 ++++++++++-------- packages/matrices/src/rotation.ts | 98 +++++++++++++++++++++++ packages/matrices/src/scale-center.ts | 20 +++++ packages/matrices/src/scale.ts | 53 ++++++++++++ packages/matrices/src/shear.ts | 35 ++++++++ packages/matrices/src/skew.ts | 44 ++++++++++ packages/matrices/src/translation.ts | 16 ++++ packages/matrices/src/transpose.ts | 29 +++++++ 15 files changed, 579 insertions(+), 105 deletions(-) create mode 100644 packages/matrices/src/determinant.ts create mode 100644 packages/matrices/src/invert.ts create mode 100644 packages/matrices/src/rotation.ts create mode 100644 packages/matrices/src/scale-center.ts create mode 100644 packages/matrices/src/scale.ts create mode 100644 packages/matrices/src/shear.ts create mode 100644 packages/matrices/src/skew.ts create mode 100644 packages/matrices/src/translation.ts create mode 100644 packages/matrices/src/transpose.ts diff --git a/packages/matrices/src/api.ts b/packages/matrices/src/api.ts index 2dee065cbc..eac4410c8b 100644 --- a/packages/matrices/src/api.ts +++ b/packages/matrices/src/api.ts @@ -9,11 +9,13 @@ export type MatOp1 = (out: Mat) => Mat; export type MatOpM = (out: Mat, a: ReadonlyMat) => Mat; export type MatOpN = (out: Mat, n: number) => Mat; export type MatOpMM = (out: Mat, a: ReadonlyMat, b: ReadonlyMat) => Mat; -export type MatOpMV = (out: Vec, a: ReadonlyMat, b: ReadonlyVec) => Mat; +export type MatOpMV = (out: Vec, a: ReadonlyMat, b: ReadonlyVec) => Vec; export interface MultiMatOp1 extends MatOp1, MultiMatOp { } export interface MultiMatOpM extends MatOpM, MultiMatOp { } export interface MultiMatOpN extends MatOpN, MultiMatOp { } +export interface MultiMatOpMM extends MatOpMM, MultiMatOp { } +export interface MultiMatOpMV extends MatOpMV, MultiMatOp { } export const IDENT22 = [ 1, 0, diff --git a/packages/matrices/src/concat.ts b/packages/matrices/src/concat.ts index cc8bff6d1a..6d32b0bd6d 100644 --- a/packages/matrices/src/concat.ts +++ b/packages/matrices/src/concat.ts @@ -1,20 +1,9 @@ -import { Mat, MatOpMM, ReadonlyMat } from "./api"; -import { - mul22, - mul23, - mul33, - mul44 -} from "./mul"; +import { Mat, ReadonlyMat } from "./api"; +import { mul } from "./mul"; -const $ = - (mul: MatOpMM) => - (out: Mat, a: ReadonlyMat, b: ReadonlyMat, ...xs: ReadonlyMat[]) => - xs.reduce( - (acc: Mat, x) => mul(acc, acc, x), - mul(out, a, b) - ); - -export const concat22 = $(mul22); -export const concat23 = $(mul23); -export const concat33 = $(mul33); -export const concat44 = $(mul44); +export const concat = + (out: Mat, a: ReadonlyMat, b: ReadonlyMat, ...xs: ReadonlyMat[]) => + xs.reduce( + (acc: Mat, x) => mul(acc, acc, x), + mul(out, a, b) + ); diff --git a/packages/matrices/src/convert.ts b/packages/matrices/src/convert.ts index 1b459e2a50..0873ff5c63 100644 --- a/packages/matrices/src/convert.ts +++ b/packages/matrices/src/convert.ts @@ -1,6 +1,17 @@ -import { setS3 } from "@thi.ng/vectors3/sets"; +import { ZERO4 } from "@thi.ng/vectors3/api"; +import { setS3, setS4 } from "@thi.ng/vectors3/sets"; import { MatOpM } from "./api"; +export const mat33to44: MatOpM = + (m44, m33) => ( + setS3(m44, m33, 0, 0), + setS3(m44, m33, 4, 3), + setS3(m44, m33, 8, 6), + setS3(m44, ZERO4, 12), + setS4(m44, [0, 0, 0, 1], 3, 0, 4), + m44 + ); + export const mat44to33: MatOpM = (m33, m44) => ( setS3(m33, m44), diff --git a/packages/matrices/src/determinant.ts b/packages/matrices/src/determinant.ts new file mode 100644 index 0000000000..620dd1ea73 --- /dev/null +++ b/packages/matrices/src/determinant.ts @@ -0,0 +1,57 @@ +import { dotValues4, dotValues6 } from "@thi.ng/vectors3/dot-values"; +import { ReadonlyMat } from "./api"; + +const dp4 = dotValues4; +const dp6 = dotValues6; + +export const det22 = + (m: ReadonlyMat) => + dp4(m[0], m[3], -m[1], m[2]); + +export const det23 = det22; + +export const det33 = + (m: ReadonlyMat) => { + const [ + m00, m01, m02, + m10, m11, m12, + m20, m21, m22 + ] = m; + const d01 = dp4(m22, m11, -m12, m21); + const d11 = dp4(m12, m20, -m22, m10); + const d21 = dp4(m21, m10, -m11, m20); + return dp6(m00, d01, m01, d11, m02, d21); + }; + +export const detCoeffs44 = + (m: ReadonlyMat) => { + const [ + m00, m01, m02, m03, + m10, m11, m12, m13, + m20, m21, m22, m23, + m30, m31, m32, m33 + ] = m; + return [ + dp4(m00, m11, -m01, m10), + dp4(m00, m12, -m02, m10), + dp4(m00, m13, -m03, m10), + dp4(m01, m12, -m02, m11), + dp4(m01, m13, -m03, m11), + dp4(m02, m13, -m03, m12), + dp4(m20, m31, -m21, m30), + dp4(m20, m32, -m22, m30), + dp4(m20, m33, -m23, m30), + dp4(m21, m32, -m22, m31), + dp4(m21, m33, -m23, m31), + dp4(m22, m33, -m23, m32) + ]; + }; + +export const det44FromCoeffs = + (d: number[]) => + dp6(d[0], d[11], -d[1], d[10], d[2], d[9]) + + dp6(d[3], d[8], -d[4], d[7], d[5], d[6]); + +export const det44 = + (m: ReadonlyMat) => + det44FromCoeffs(detCoeffs44(m)); diff --git a/packages/matrices/src/index.ts b/packages/matrices/src/index.ts index 37d6cf0a03..809056d8a5 100644 --- a/packages/matrices/src/index.ts +++ b/packages/matrices/src/index.ts @@ -2,7 +2,17 @@ export * from "./api"; export * from "./concat"; export * from "./convert"; +export * from "./determinant"; export * from "./identity"; +export * from "./invert"; export * from "./mul"; export * from "./mulv"; +export * from "./rotation"; +export * from "./scale"; +export * from "./scale-center"; export * from "./set"; +export * from "./set-values"; +export * from "./shear"; +export * from "./skew"; +export * from "./translation"; +export * from "./transpose"; diff --git a/packages/matrices/src/invert.ts b/packages/matrices/src/invert.ts new file mode 100644 index 0000000000..1408c0784b --- /dev/null +++ b/packages/matrices/src/invert.ts @@ -0,0 +1,91 @@ +import { dotValues4, dotValues6 } from "@thi.ng/vectors3/dot-values"; +import { MatOpM } from "./api"; +import { setValues23, setValues22, setValues44, setValues33 } from "./set-values"; +import { detCoeffs44, det44FromCoeffs } from "./determinant"; + +const dp4 = dotValues4; +const dp6 = dotValues6; + +export const invert22: MatOpM = + (out, m) => { + const [m00, m01, m10, m11] = m; + let det = dp4(m00, m11, -m01, m10); + if (det === 0) return; + det = 1.0 / det; + return setValues22( + out, + m11 * det, + -m01 * det, + -m10 * det, + m00 * det, + ); + }; + +export const invert23: MatOpM = + (out, m) => { + const [m00, m01, m10, m11, m20, m21] = m; + let det = dp4(m00, m11, -m01, m10); + if (det === 0) return; + det = 1.0 / det; + return setValues23( + out, + m11 * det, + -m01 * det, + -m10 * det, + m00 * det, + dp4(m10, m21, -m11, m20) * det, + dp4(m01, m20, -m00, m21) * det + ); + }; + +export const invert33: MatOpM = + (out, m) => { + const [m00, m01, m02, m10, m11, m12, m20, m21, m22] = m; + const d01 = dp4(m22, m11, -m12, m21); + const d11 = dp4(m12, m20, -m22, m10); + const d21 = dp4(m21, m10, -m11, m20); + let det = dp6(m00, d01, m01, d11, m02, d21); + if (det === 0) return; + det = 1.0 / det; + return setValues33( + out, + d01 * det, + dp4(-m22, m01, m02, m21) * det, + dp4(m12, m01, -m02, m11) * det, + d11 * det, + dp4(m22, m00, -m02, m20) * det, + dp4(-m12, m00, m02, m10) * det, + d21 * det, + dp4(-m21, m00, m01, m20) * det, + dp4(m11, m00, -m01, m10) * det, + ); + }; + +export const invert44: MatOpM = + (out, m) => { + const coeffs = detCoeffs44(m); + let det = det44FromCoeffs(coeffs); + if (det === 0) return; + det = 1.0 / det; + const [m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33] = m; + const [d00, d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11] = coeffs; + return setValues44( + out, + dp6(m11, d11, -m12, d10, m13, d09) * det, + dp6(-m01, d11, m02, d10, -m03, d09) * det, + dp6(m31, d05, - m32, d04, m33, d03) * det, + dp6(-m21, d05, m22, d04, -m23, d03) * det, + dp6(-m10, d11, m12, d08, -m13, d07) * det, + dp6(m00, d11, -m02, d08, m03, d07) * det, + dp6(-m30, d05, m32, d02, -m33, d01) * det, + dp6(m20, d05, -m22, d02, m23, d01) * det, + dp6(m10, d10, -m11, d08, m13, d06) * det, + dp6(-m00, d10, m01, d08, -m03, d06) * det, + dp6(m30, d04, -m31, d02, m33, d00) * det, + dp6(-m20, d04, m21, d02, -m23, d00) * det, + dp6(-m10, d09, m11, d07, -m12, d06) * det, + dp6(m00, d09, -m01, d07, m02, d06) * det, + dp6(-m30, d03, m31, d01, -m32, d00) * det, + dp6(m20, d03, -m21, d01, m22, d00) * det + ); + }; diff --git a/packages/matrices/src/mul.ts b/packages/matrices/src/mul.ts index 85177281c0..86704b25de 100644 --- a/packages/matrices/src/mul.ts +++ b/packages/matrices/src/mul.ts @@ -1,5 +1,6 @@ import { dotS2, dotS3, dotS4 } from "@thi.ng/vectors3/dots"; -import { MatOpMM } from "./api"; +import { vop } from "@thi.ng/vectors3/internal/vop"; +import { MultiMatOpMM } from "./api"; import { setValues22, setValues23, @@ -7,57 +8,63 @@ import { setValues44 } from "./set-values"; -export const mul22: MatOpMM = - (out, a, b) => setValues22( - out, - dotS2(a, b, 0, 0, 2), - dotS2(a, b, 1, 0, 2), - dotS2(a, b, 0, 2, 2), - dotS2(a, b, 1, 2, 2), - ); +export const mul: MultiMatOpMM = vop(1); -export const mul23: MatOpMM = - (out, a, b) => setValues23( - out, - dotS2(a, b, 0, 0, 2), - dotS2(a, b, 1, 0, 2), - dotS2(a, b, 0, 2, 2), - dotS2(a, b, 1, 2, 2), - dotS2(a, b, 0, 4, 2) + a[4], - dotS2(a, b, 1, 4, 2) + a[5], - ); +export const mul22 = + mul.add(4, (out, a, b) => + setValues22( + out, + dotS2(a, b, 0, 0, 2), + dotS2(a, b, 1, 0, 2), + dotS2(a, b, 0, 2, 2), + dotS2(a, b, 1, 2, 2) + )); -export const mul33: MatOpMM = - (out, a, b) => setValues33( - out, - dotS3(a, b, 0, 0, 3), - dotS3(a, b, 1, 0, 3), - dotS3(a, b, 2, 0, 3), - dotS3(a, b, 0, 3, 3), - dotS3(a, b, 1, 3, 3), - dotS3(a, b, 2, 3, 3), - dotS3(a, b, 0, 6, 3), - dotS3(a, b, 1, 6, 3), - dotS3(a, b, 2, 6, 3) - ); +export const mul23 = + mul.add(6, (out, a, b) => + setValues23( + out, + dotS2(a, b, 0, 0, 2), + dotS2(a, b, 1, 0, 2), + dotS2(a, b, 0, 2, 2), + dotS2(a, b, 1, 2, 2), + dotS2(a, b, 0, 4, 2) + a[4], + dotS2(a, b, 1, 4, 2) + a[5] + )); -export const mul44: MatOpMM = - (out, a, b) => setValues44( - out, - dotS4(a, b, 0, 0, 4), - dotS4(a, b, 1, 0, 4), - dotS4(a, b, 2, 0, 4), - dotS4(a, b, 3, 0, 4), - dotS4(a, b, 0, 4, 4), - dotS4(a, b, 1, 4, 4), - dotS4(a, b, 2, 4, 4), - dotS4(a, b, 3, 4, 4), - dotS4(a, b, 0, 8, 4), - dotS4(a, b, 1, 8, 4), - dotS4(a, b, 2, 8, 4), - dotS4(a, b, 3, 8, 4), - dotS4(a, b, 0, 12, 4), - dotS4(a, b, 1, 12, 4), - dotS4(a, b, 2, 12, 4), - dotS4(a, b, 3, 12, 4) - ); +export const mul33 = + mul.add(9, (out, a, b) => + setValues33( + out, + dotS3(a, b, 0, 0, 3), + dotS3(a, b, 1, 0, 3), + dotS3(a, b, 2, 0, 3), + dotS3(a, b, 0, 3, 3), + dotS3(a, b, 1, 3, 3), + dotS3(a, b, 2, 3, 3), + dotS3(a, b, 0, 6, 3), + dotS3(a, b, 1, 6, 3), + dotS3(a, b, 2, 6, 3) + )); + +export const mul44 = + mul.add(16, (out, a, b) => + setValues44( + out, + dotS4(a, b, 0, 0, 4), + dotS4(a, b, 1, 0, 4), + dotS4(a, b, 2, 0, 4), + dotS4(a, b, 3, 0, 4), + dotS4(a, b, 0, 4, 4), + dotS4(a, b, 1, 4, 4), + dotS4(a, b, 2, 4, 4), + dotS4(a, b, 3, 4, 4), + dotS4(a, b, 0, 8, 4), + dotS4(a, b, 1, 8, 4), + dotS4(a, b, 2, 8, 4), + dotS4(a, b, 3, 8, 4), + dotS4(a, b, 0, 12, 4), + dotS4(a, b, 1, 12, 4), + dotS4(a, b, 2, 12, 4), + dotS4(a, b, 3, 12, 4) + )); diff --git a/packages/matrices/src/mulv.ts b/packages/matrices/src/mulv.ts index cba7ba0d5b..ec00da299e 100644 --- a/packages/matrices/src/mulv.ts +++ b/packages/matrices/src/mulv.ts @@ -1,41 +1,53 @@ import { dotS2, dotS3, dotS4 } from "@thi.ng/vectors3/dots"; -import { MatOpMV } from "./api"; +import { MatOpMV, MultiMatOpMV } from "./api"; +import { vop } from "@thi.ng/vectors3/internal/vop"; + +export const mulV: MultiMatOpMV = vop(1); export const mulV22: MatOpMV = - (out, m, v) => ( - out[0] = dotS2(m, v, 0, 0, 2), - out[1] = dotS2(m, v, 1, 0, 2), - out - ); + mulV.add(4, (out, m, v) => { + const x = dotS2(m, v, 0, 0, 2); + out[1] = dotS2(m, v, 1, 0, 2); + out[0] = x; + return out; + }); export const mulV23: MatOpMV = - (out, m, v) => ( - out[0] = dotS2(m, v, 0, 0, 2) + m[4], - out[1] = dotS2(m, v, 1, 0, 2) + m[5], - out - ); + mulV.add(6, (out, m, v) => { + const x = dotS2(m, v, 0, 0, 2) + m[4]; + out[1] = dotS2(m, v, 1, 0, 2) + m[5]; + out[0] = x; + return out; + }); export const mulV33: MatOpMV = - (out, m, v) => ( - out[0] = dotS3(m, v, 0, 0, 3), - out[1] = dotS3(m, v, 1, 0, 3), - out[2] = dotS3(m, v, 2, 0, 3), - out - ); - -export const mulV344: MatOpMV = - (out, m, v) => ( - out[0] = dotS3(m, v, 0, 0, 4) + m[12], - out[1] = dotS3(m, v, 1, 0, 4) + m[13], - out[2] = dotS3(m, v, 2, 0, 4) + m[14], - out - ); + mulV.add(9, (out, m, v) => { + const x = dotS3(m, v, 0, 0, 3); + const y = dotS3(m, v, 1, 0, 3); + out[2] = dotS3(m, v, 2, 0, 3); + out[1] = y; + out[0] = x; + return out; + }); export const mulV44: MatOpMV = - (out, m, v) => ( - out[0] = dotS4(m, v, 0, 0, 4), - out[1] = dotS4(m, v, 1, 0, 4), - out[2] = dotS4(m, v, 2, 0, 4), - out[3] = dotS4(m, v, 3, 0, 4), - out - ); + mulV.add(16, (out, m, v) => { + const x = dotS4(m, v, 0, 0, 4); + const y = dotS4(m, v, 1, 0, 4); + const z = dotS4(m, v, 2, 0, 4); + out[3] = dotS4(m, v, 3, 0, 4); + out[2] = z; + out[1] = y; + out[0] = x; + return out; + }); + +export const mulV344: MatOpMV = + (out, m, v) => { + const x = dotS3(m, v, 0, 0, 4) + m[12]; + const y = dotS3(m, v, 1, 0, 4) + m[13]; + out[2] = dotS3(m, v, 2, 0, 4) + m[14]; + out[1] = y; + out[0] = x; + return out; + }; diff --git a/packages/matrices/src/rotation.ts b/packages/matrices/src/rotation.ts new file mode 100644 index 0000000000..5452f556fe --- /dev/null +++ b/packages/matrices/src/rotation.ts @@ -0,0 +1,98 @@ +import { sincos } from "@thi.ng/math/angle"; +import { Mat } from "./api"; +import { + setValues22, + setValues23, + setValues33, + setValues44 +} from "./set-values"; + +export const rotation22 = + (m: Mat, theta: number) => { + const [s, c] = sincos(theta); + return setValues22( + m, + c, s, + -s, c, + ); + }; + +export const rotation23 = + (m: Mat, theta: number) => { + const [s, c] = sincos(theta); + return setValues23( + m, + c, s, + -s, c, + 0, 0 + ); + }; + +export const rotationX33 = + (m: Mat, theta: number) => { + const [s, c] = sincos(theta); + return setValues33( + m, + 1, 0, 0, + 0, c, s, + 0, -s, c, + ); + }; + +export const rotationY33 = + (m: Mat, theta: number) => { + const [s, c] = sincos(theta); + return setValues33( + m, + c, 0, -s, + 0, 1, 0, + s, 0, c, + ); + }; + +export const rotationZ33 = + (m: Mat, theta: number) => { + const [s, c] = sincos(theta); + return setValues33( + m, + c, s, 0, + -s, c, 0, + 0, 0, 1, + ); + }; + +export const rotationX44 = + (m: Mat, theta: number) => { + const [s, c] = sincos(theta); + return setValues44( + m, + 1, 0, 0, 0, + 0, c, s, 0, + 0, -s, c, 0, + 0, 0, 0, 1 + ); + }; + +export const rotationY44 = + (m: Mat, theta: number) => { + const [s, c] = sincos(theta); + return setValues44( + m, + c, 0, -s, 0, + 0, 1, 0, 0, + s, 0, c, 0, + 0, 0, 0, 1 + ); + }; + +export const rotationZ44 = + (m: Mat, theta: number) => { + const [s, c] = sincos(theta); + return setValues44( + m, + c, s, 0, 0, + -s, c, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + ); + }; diff --git a/packages/matrices/src/scale-center.ts b/packages/matrices/src/scale-center.ts new file mode 100644 index 0000000000..e4fe20e4c8 --- /dev/null +++ b/packages/matrices/src/scale-center.ts @@ -0,0 +1,20 @@ +import { ReadonlyVec } from "@thi.ng/vectors3/api"; +import { mulN2, mulN3 } from "@thi.ng/vectors3/muln"; +import { Mat } from "./api"; +import { concat } from "./concat"; +import { scale23, scale44 } from "./scale"; +import { translation23, translation44 } from "./translation"; + +export const scaleWithCenter23 = (m: Mat, p: ReadonlyVec, s: number | ReadonlyVec) => + concat( + translation23(m, p), + scale23([], s), + translation23([], mulN2([], p, -1)) + ); + +export const scaleWithCenter44 = (m: Mat, p: ReadonlyVec, s: number | ReadonlyVec) => + concat( + translation44(m, p), + scale44([], s), + translation44([], mulN3([], p, -1)) + ); diff --git a/packages/matrices/src/scale.ts b/packages/matrices/src/scale.ts new file mode 100644 index 0000000000..fc111bde77 --- /dev/null +++ b/packages/matrices/src/scale.ts @@ -0,0 +1,53 @@ +import { isNumber } from "@thi.ng/checks/is-number"; +import { ReadonlyVec } from "@thi.ng/vectors3/api"; +import { Mat } from "./api"; +import { + setValues22, + setValues23, + setValues33, + setValues44 +} from "./set-values"; + +export const scale22 = + (m: Mat, s: number | ReadonlyVec) => ( + s = isNumber(s) ? [s, s] : s, + setValues22( + m, + s[0], 0, + 0, s[1] + ) + ); + +export const scale23 = + (m: Mat, s: number | ReadonlyVec) => ( + s = isNumber(s) ? [s, s] : s, + setValues23( + m, + s[0], 0, + 0, s[1], + 0, 0 + ) + ); + +export const scale33 = + (m: Mat, s: number | ReadonlyVec) => ( + s = isNumber(s) ? [s, s, s] : s, + setValues33( + m, + s[0], 0, 0, + 0, s[1], 0, + 0, 0, s[2] + ) + ); + +export const scale44 = + (m: Mat, s: number | ReadonlyVec) => ( + s = isNumber(s) ? [s, s, s] : s, + setValues44( + m, + s[0], 0, 0, 0, + 0, s[1], 0, 0, + 0, 0, s[2], 0, + 0, 0, 0, s[3] !== undefined ? s[3] : 1 + ) + ); diff --git a/packages/matrices/src/shear.ts b/packages/matrices/src/shear.ts new file mode 100644 index 0000000000..95510530e6 --- /dev/null +++ b/packages/matrices/src/shear.ts @@ -0,0 +1,35 @@ +import { Mat, MatOp1 } from "./api"; +import { identity33, identity44, identity23, identity22 } from "./identity"; + +const $ = + (f: MatOp1) => + (i: number) => + (m: Mat, x: number) => + (f(m), m[i] = x, m); + +const $22 = $(identity22); +const $23 = $(identity23); +const $33 = $(identity33); +const $44 = $(identity44); + +// https://stackoverflow.com/a/13211288/294515 + +export const shearX22 = $22(2); +export const shearY22 = $22(1); + +export const shearX23 = $23(2); +export const shearY23 = $23(1); + +export const shearXY33 = $33(3); +export const shearXZ33 = $33(6); +export const shearYX33 = $33(1); +export const shearYZ33 = $33(7); +export const shearZX33 = $33(2); +export const shearZY33 = $33(5); + +export const shearXY44 = $44(4); +export const shearXZ44 = $44(8); +export const shearYX44 = $44(1); +export const shearYZ44 = $44(9); +export const shearZX44 = $44(2); +export const shearZY44 = $44(6); diff --git a/packages/matrices/src/skew.ts b/packages/matrices/src/skew.ts new file mode 100644 index 0000000000..57119778e9 --- /dev/null +++ b/packages/matrices/src/skew.ts @@ -0,0 +1,44 @@ +import { Mat, MatOpN } from "./api"; +import { + shearX22, + shearX23, + shearXY33, + shearXY44, + shearXZ33, + shearXZ44, + shearY22, + shearY23, + shearYX33, + shearYX44, + shearYZ33, + shearYZ44, + shearZX33, + shearZX44, + shearZY33, + shearZY44 +} from "./shear"; + +const $ = + (f: MatOpN) => + (m: Mat, theta: number) => + f(m, Math.tan(theta)); + +export const skewX22 = $(shearX22); +export const skewY22 = $(shearY22); + +export const skewX23 = $(shearX23); +export const skewY23 = $(shearY23); + +export const skewXY33 = $(shearXY33); +export const skewXZ33 = $(shearXZ33); +export const skewYX33 = $(shearYX33); +export const skewYZ33 = $(shearYZ33); +export const skewZX33 = $(shearZX33); +export const skewZY33 = $(shearZY33); + +export const skewXY44 = $(shearXY44); +export const skewXZ44 = $(shearXZ44); +export const skewYX44 = $(shearYX44); +export const skewYZ44 = $(shearYZ44); +export const skewZX44 = $(shearZX44); +export const skewZY44 = $(shearZY44); \ No newline at end of file diff --git a/packages/matrices/src/translation.ts b/packages/matrices/src/translation.ts new file mode 100644 index 0000000000..76701324d2 --- /dev/null +++ b/packages/matrices/src/translation.ts @@ -0,0 +1,16 @@ +import { ReadonlyVec } from "@thi.ng/vectors3/api"; +import { Mat } from "./api"; +import { setValues23, setValues44 } from "./set-values"; + +export const translation23 = + (m: Mat, v: ReadonlyVec) => + setValues23(m || [], 1, 0, 0, 1, v[0], v[1]); + +export const translation44 = + (m: Mat, v: ReadonlyVec) => + setValues44(m, + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + v[0], v[1], v[2], 1, + ); diff --git a/packages/matrices/src/transpose.ts b/packages/matrices/src/transpose.ts new file mode 100644 index 0000000000..b58ef5fb60 --- /dev/null +++ b/packages/matrices/src/transpose.ts @@ -0,0 +1,29 @@ +import { MatOpM } from "./api"; +import { setValues22, setValues33, setValues44 } from "./set-values"; + +export const transpose22: MatOpM = + (out, m) => + setValues22( + out, + m[0], m[2], + m[1], m[3], + ); + +export const transpose33: MatOpM = + (out, m) => + setValues33( + out, + m[0], m[3], m[6], + m[1], m[4], m[7], + m[2], m[5], m[8], + ); + +export const transpose44: MatOpM = + (out, m) => + setValues44( + out, + m[0], m[4], m[8], m[12], + m[1], m[5], m[9], m[13], + m[2], m[6], m[10], m[14], + m[3], m[7], m[11], m[15], + ); From 35babfc6fee6eea849fb712460db024d631cd37e Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 27 Nov 2018 09:03:55 +0000 Subject: [PATCH 045/333] feat(matrices): add more matrix ops --- packages/matrices/src/add.ts | 7 +++++++ packages/matrices/src/addn.ts | 7 +++++++ packages/matrices/src/api.ts | 8 ++++++++ packages/matrices/src/column.ts | 17 +++++++++++++++++ packages/matrices/src/diag.ts | 17 +++++++++++++++++ packages/matrices/src/div.ts | 7 +++++++ packages/matrices/src/divn.ts | 7 +++++++ packages/matrices/src/index.ts | 9 +++++++++ packages/matrices/src/internal/codegen.ts | 13 +++++++++++++ packages/matrices/src/muln.ts | 7 +++++++ packages/matrices/src/row.ts | 17 +++++++++++++++++ packages/matrices/src/sub.ts | 7 +++++++ packages/matrices/src/subn.ts | 7 +++++++ 13 files changed, 130 insertions(+) create mode 100644 packages/matrices/src/add.ts create mode 100644 packages/matrices/src/addn.ts create mode 100644 packages/matrices/src/column.ts create mode 100644 packages/matrices/src/diag.ts create mode 100644 packages/matrices/src/div.ts create mode 100644 packages/matrices/src/divn.ts create mode 100644 packages/matrices/src/internal/codegen.ts create mode 100644 packages/matrices/src/muln.ts create mode 100644 packages/matrices/src/row.ts create mode 100644 packages/matrices/src/sub.ts create mode 100644 packages/matrices/src/subn.ts diff --git a/packages/matrices/src/add.ts b/packages/matrices/src/add.ts new file mode 100644 index 0000000000..3e8e6c23fa --- /dev/null +++ b/packages/matrices/src/add.ts @@ -0,0 +1,7 @@ +import { add as _add, add4 } from "@thi.ng/vectors3/add"; +import { MatOpMM, MultiMatOpMM } from "./api"; +import { defMath } from "./internal/codegen"; + +export const add: MultiMatOpMM = _add; +export const add22: MatOpMM = add4; +export const [add23, add33, add44] = defMath(add, "+"); diff --git a/packages/matrices/src/addn.ts b/packages/matrices/src/addn.ts new file mode 100644 index 0000000000..32fc89d702 --- /dev/null +++ b/packages/matrices/src/addn.ts @@ -0,0 +1,7 @@ +import { addN as _addN, addN4 } from "@thi.ng/vectors3/addn"; +import { MatOpMN, MultiMatOpMN } from "./api"; +import { defMathN } from "./internal/codegen"; + +export const addN: MultiMatOpMN = _addN; +export const addN22: MatOpMN = addN4; +export const [addN23, addN33, addN44] = defMathN(addN, "+"); diff --git a/packages/matrices/src/api.ts b/packages/matrices/src/api.ts index eac4410c8b..6786b681d1 100644 --- a/packages/matrices/src/api.ts +++ b/packages/matrices/src/api.ts @@ -10,12 +10,20 @@ export type MatOpM = (out: Mat, a: ReadonlyMat) => Mat; export type MatOpN = (out: Mat, n: number) => Mat; export type MatOpMM = (out: Mat, a: ReadonlyMat, b: ReadonlyMat) => Mat; export type MatOpMV = (out: Vec, a: ReadonlyMat, b: ReadonlyVec) => Vec; +export type MatOpMN = (out: Mat, a: ReadonlyMat, n: number) => Mat; + +export type VecOpM = (out: Vec, a: ReadonlyMat) => Vec; +export type VecOpMN = (out: Vec, a: ReadonlyMat, n: number) => Vec; export interface MultiMatOp1 extends MatOp1, MultiMatOp { } export interface MultiMatOpM extends MatOpM, MultiMatOp { } export interface MultiMatOpN extends MatOpN, MultiMatOp { } export interface MultiMatOpMM extends MatOpMM, MultiMatOp { } export interface MultiMatOpMV extends MatOpMV, MultiMatOp { } +export interface MultiMatOpMN extends MatOpMN, MultiMatOp { } + +export interface MultiVecOpM extends VecOpM, MultiMatOp { } +export interface MultiVecOpMN extends VecOpMN, MultiMatOp { } export const IDENT22 = [ 1, 0, diff --git a/packages/matrices/src/column.ts b/packages/matrices/src/column.ts new file mode 100644 index 0000000000..fcd815824c --- /dev/null +++ b/packages/matrices/src/column.ts @@ -0,0 +1,17 @@ +import { vop } from "@thi.ng/vectors3/internal/vop"; +import { setS2, setS3, setS4 } from "@thi.ng/vectors3/sets"; +import { MultiVecOpMN, VecOpMN } from "./api"; + +export const column: MultiVecOpMN = vop(1); + +export const column22: VecOpMN = + column.add(4, (out, m, n) => setS2(out, m, 0, n * 2)); + +export const column23: VecOpMN = + column.add(6, column22); + +export const column33: VecOpMN = + column.add(9, (out, m, n) => setS3(out, m, 0, n * 3)); + +export const column44: VecOpMN = + column.add(16, (out, m, n) => setS4(out, m, 0, n * 4)); diff --git a/packages/matrices/src/diag.ts b/packages/matrices/src/diag.ts new file mode 100644 index 0000000000..a392ffd9fe --- /dev/null +++ b/packages/matrices/src/diag.ts @@ -0,0 +1,17 @@ +import { vop } from "@thi.ng/vectors3/internal/vop"; +import { setS2, setS3, setS4 } from "@thi.ng/vectors3/sets"; +import { MultiVecOpM } from "./api"; + +export const diag: MultiVecOpM = vop(1); + +export const diag22 = + diag.add(4, (out, m) => setS2(out, m, 0, 0, 1, 3)); + +export const diag23 = + diag.add(6, diag22); + +export const diag33 = + diag.add(9, (out, m) => setS3(out, m, 0, 0, 1, 4)); + +export const diag44 = + diag.add(16, (out, m) => setS4(out, m, 0, 0, 1, 5)); diff --git a/packages/matrices/src/div.ts b/packages/matrices/src/div.ts new file mode 100644 index 0000000000..22a69bb051 --- /dev/null +++ b/packages/matrices/src/div.ts @@ -0,0 +1,7 @@ +import { div as _div, div4 } from "@thi.ng/vectors3/div"; +import { MatOpMM, MultiMatOpMM } from "./api"; +import { defMath } from "./internal/codegen"; + +export const div: MultiMatOpMM = _div; +export const div22: MatOpMM = div4; +export const [div23, div33, div44] = defMath(div, "/"); diff --git a/packages/matrices/src/divn.ts b/packages/matrices/src/divn.ts new file mode 100644 index 0000000000..deae8796cb --- /dev/null +++ b/packages/matrices/src/divn.ts @@ -0,0 +1,7 @@ +import { divN as _divN, divN4 } from "@thi.ng/vectors3/divn"; +import { MatOpMN, MultiMatOpMN } from "./api"; +import { defMathN } from "./internal/codegen"; + +export const divN: MultiMatOpMN = _divN; +export const divN22: MatOpMN = divN4; +export const [divN23, divN33, divN44] = defMathN(divN, "/"); diff --git a/packages/matrices/src/index.ts b/packages/matrices/src/index.ts index 809056d8a5..9cfbabce17 100644 --- a/packages/matrices/src/index.ts +++ b/packages/matrices/src/index.ts @@ -1,18 +1,27 @@ export * from "./api"; +export * from "./add"; +export * from "./addn"; export * from "./concat"; export * from "./convert"; export * from "./determinant"; +export * from "./diag"; +export * from "./div"; +export * from "./divn"; export * from "./identity"; export * from "./invert"; export * from "./mul"; +export * from "./muln"; export * from "./mulv"; export * from "./rotation"; +export * from "./row"; export * from "./scale"; export * from "./scale-center"; export * from "./set"; export * from "./set-values"; export * from "./shear"; export * from "./skew"; +export * from "./sub"; +export * from "./subn"; export * from "./translation"; export * from "./transpose"; diff --git a/packages/matrices/src/internal/codegen.ts b/packages/matrices/src/internal/codegen.ts new file mode 100644 index 0000000000..bf69e405c3 --- /dev/null +++ b/packages/matrices/src/internal/codegen.ts @@ -0,0 +1,13 @@ +import { compile } from "@thi.ng/vectors3/internal/codegen"; +import { MATH, MATH_N } from "@thi.ng/vectors3/internal/templates"; +import { MultiMatOpMM, MultiMatOpMN } from "../api"; + +const DEFAULT_SIZES = [6, 9, 16]; + +export const defMath = + (fn: MultiMatOpMM, op: string, sizes = DEFAULT_SIZES) => + sizes.map((n) => fn.add(n, compile(n, MATH(op), "o,a,b", undefined, "o"))); + +export const defMathN = + (fn: MultiMatOpMN, op: string, sizes = DEFAULT_SIZES) => + sizes.map((n) => fn.add(n, compile(n, MATH_N(op), "o,a,n", "o,a", "o"))); diff --git a/packages/matrices/src/muln.ts b/packages/matrices/src/muln.ts new file mode 100644 index 0000000000..23fe1d003d --- /dev/null +++ b/packages/matrices/src/muln.ts @@ -0,0 +1,7 @@ +import { mulN as _mulN, mulN4 } from "@thi.ng/vectors3/muln"; +import { MatOpMN, MultiMatOpMN } from "./api"; +import { defMathN } from "./internal/codegen"; + +export const mulN: MultiMatOpMN = _mulN; +export const mulN22: MatOpMN = mulN4; +export const [mulN23, mulN33, mulN44] = defMathN(mulN, "*"); diff --git a/packages/matrices/src/row.ts b/packages/matrices/src/row.ts new file mode 100644 index 0000000000..2f3fcd4f8b --- /dev/null +++ b/packages/matrices/src/row.ts @@ -0,0 +1,17 @@ +import { vop } from "@thi.ng/vectors3/internal/vop"; +import { setS2, setS3, setS4 } from "@thi.ng/vectors3/sets"; +import { MultiVecOpMN } from "./api"; + +export const row: MultiVecOpMN = vop(1); + +export const row22 = + row.add(4, (out, m, n) => setS2(out, m, 0, n, 1, 2)); + +export const row23 = + row.add(6, (out, m, n) => setS3(out, m, 0, n, 1, 2)); + +export const row33 = + row.add(9, (out, m, n) => setS3(out, m, 0, n, 1, 3)); + +export const row44 = + row.add(16, (out, m, n) => setS4(out, m, 0, n, 1, 4)); diff --git a/packages/matrices/src/sub.ts b/packages/matrices/src/sub.ts new file mode 100644 index 0000000000..0d15f69a19 --- /dev/null +++ b/packages/matrices/src/sub.ts @@ -0,0 +1,7 @@ +import { sub as _sub, sub4 } from "@thi.ng/vectors3/sub"; +import { MatOpMM, MultiMatOpMM } from "./api"; +import { defMath } from "./internal/codegen"; + +export const sub: MultiMatOpMM = _sub; +export const sub22: MatOpMM = sub4; +export const [sub23, sub33, sub44] = defMath(sub, "-"); diff --git a/packages/matrices/src/subn.ts b/packages/matrices/src/subn.ts new file mode 100644 index 0000000000..c5d1bee338 --- /dev/null +++ b/packages/matrices/src/subn.ts @@ -0,0 +1,7 @@ +import { subN as _subN, subN4 } from "@thi.ng/vectors3/subn"; +import { MatOpMN, MultiMatOpMN } from "./api"; +import { defMathN } from "./internal/codegen"; + +export const subN: MultiMatOpMN = _subN; +export const subN22: MatOpMN = subN4; +export const [subN23, subN33, subN44] = defMathN(subN, "-"); From 97ac629d1d9ccc6f0b35782bd0526991e1ecc806 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 27 Nov 2018 11:50:55 +0000 Subject: [PATCH 046/333] feat(vectors): add/update ops, add docstrings - add fromHomogeneous3/4() - add swap*() - update order & re-export orthoNormal3() - update arg order step() / smoothStep() - update `out` handling in: - normalize() - perpendicular*() - cartesian() / polar() - simplify cartesian2() - add docs --- packages/vectors3/src/cartesian.ts | 39 +++++++++++++++++---- packages/vectors3/src/compare.ts | 30 ++++++++++++++++ packages/vectors3/src/homogeneous.ts | 16 +++++++++ packages/vectors3/src/index.ts | 2 ++ packages/vectors3/src/madd.ts | 3 ++ packages/vectors3/src/maddn.ts | 3 ++ packages/vectors3/src/major.ts | 6 ++++ packages/vectors3/src/minor.ts | 6 ++++ packages/vectors3/src/normalize.ts | 16 ++++++--- packages/vectors3/src/ortho-normal.ts | 16 ++++++++- packages/vectors3/src/perpendicular.ts | 14 ++++++++ packages/vectors3/src/polar.ts | 25 +++++++++++++ packages/vectors3/src/random.ts | 26 +++++++++++--- packages/vectors3/src/rotate-around-axis.ts | 6 ++-- packages/vectors3/src/smoothstep.ts | 15 ++++++-- packages/vectors3/src/step.ts | 14 ++++++-- packages/vectors3/src/swizzle.ts | 11 +++++- 17 files changed, 224 insertions(+), 24 deletions(-) create mode 100644 packages/vectors3/src/homogeneous.ts diff --git a/packages/vectors3/src/cartesian.ts b/packages/vectors3/src/cartesian.ts index 318ad18cb5..a55cfb0809 100644 --- a/packages/vectors3/src/cartesian.ts +++ b/packages/vectors3/src/cartesian.ts @@ -1,24 +1,49 @@ +import { cossin } from "@thi.ng/math/angle"; import { MultiVecOpVO, ReadonlyVec, ZERO4 } from "./api"; import { vop } from "./internal/vop"; +import { maddN } from "./maddn"; const cos = Math.cos; const sin = Math.sin; +/** + * Converts polar vector `v` to cartesian coordinates and adds optional + * `offset`. See `polar()` for reverse operation. If `out` is null, + * modifies `v` in place. + * + * @param out + * @param v + * @param offset + */ export const cartesian: MultiVecOpVO = vop(1); +/** + * Converts 2D polar vector `v` to cartesian coordinates and adds + * optional `offset`. See `polar()` for reverse operation. If `out` is + * null, modifies `v` in place. + * + * @param out + * @param v + * @param offset + */ export const cartesian2 = cartesian.add(2, - (out, a, b = ZERO4) => { - const r = a[0]; - const t = a[1]; - out[0] = r * cos(t) + b[0]; - out[1] = r * sin(t) + b[1]; - return out; - }); + (out, a, b = ZERO4) => maddN(out || a, b, cossin(a[1]), a[0]) + ); +/** + * Converts 3D polar vector `v` to cartesian coordinates and adds + * optional `offset`. See `polar()` for reverse operation. If `out` is + * null, modifies `v` in place. + * + * @param out + * @param v + * @param offset + */ export const cartesian3 = cartesian.add(3, (out, a, b = ZERO4) => { + !out && (out = a); const r = a[0]; const theta = a[1]; const phi = a[2]; diff --git a/packages/vectors3/src/compare.ts b/packages/vectors3/src/compare.ts index e396356789..a2b60b202e 100644 --- a/packages/vectors3/src/compare.ts +++ b/packages/vectors3/src/compare.ts @@ -1,6 +1,15 @@ import { Comparator } from "@thi.ng/api/api"; import { ReadonlyVec } from "./api"; +/** + * Returns a new 2D vector comparator using given component order. The + * comparator returns the signed index+1 of the first differing + * component, e.g. if order is `0,1`, a return value of -2 means that + * `a.y < b.y`. + * + * @param o1 + * @param o2 + */ export const comparator2 = (o1: number, o2: number): Comparator => (a, b): number => { @@ -15,6 +24,16 @@ export const comparator2 = ax < bx ? -1 : 1; }; +/** + * Returns a new 3D vector comparator using given component order. The + * comparator returns the signed index+1 of the first differing + * component, e.g. if order is `0,1,2`, a return value of -3 means that + * `a.z < b.z`. + * + * @param o1 + * @param o2 + * @param o3 + */ export const comparator3 = (o1: number, o2: number, o3: number): Comparator => (a, b): number => { @@ -33,6 +52,17 @@ export const comparator3 = ax < bx ? -1 : 1; }; +/** + * Returns a new 4D vector comparator using given component order. The + * comparator returns the signed index+1 of the first differing + * component, e.g. if order is `0,1,2,3`, a return value of -4 means + * that `a.w < b.w`. + * + * @param o1 + * @param o2 + * @param o3 + * @param o4 + */ export const comparator4 = (o1: number, o2: number, o3: number, o4: number): Comparator => (a, b): number => { diff --git a/packages/vectors3/src/homogeneous.ts b/packages/vectors3/src/homogeneous.ts new file mode 100644 index 0000000000..128d6d1f0c --- /dev/null +++ b/packages/vectors3/src/homogeneous.ts @@ -0,0 +1,16 @@ +import { MultiVecOpV } from "./api"; +import { vop } from "./internal/vop"; + +export const fromHomogeneous: MultiVecOpV = vop(1); + +export const fromHomogeneous3 = + fromHomogeneous.add(3, + (out, [x, y, w]) => + (out[0] = x / w, out[1] = y / w, out) + ); + +export const fromHomogeneous4 = + fromHomogeneous.add(4, + (out, [x, y, z, w]) => + (out[0] = x / w, out[1] = y / w, out[2] = z / w, out) + ); diff --git a/packages/vectors3/src/index.ts b/packages/vectors3/src/index.ts index c6616a599f..133f72deab 100644 --- a/packages/vectors3/src/index.ts +++ b/packages/vectors3/src/index.ts @@ -40,6 +40,7 @@ export * from "./face-forward"; export * from "./floor"; export * from "./fract"; export * from "./heading"; +export * from "./homogeneous"; export * from "./invert"; export * from "./invsqrt"; export * from "./jitter"; @@ -63,6 +64,7 @@ export * from "./muln"; export * from "./muls"; export * from "./neg"; export * from "./normalize"; +export * from "./ortho-normal"; export * from "./perpendicular"; export * from "./polar"; export * from "./pow"; diff --git a/packages/vectors3/src/madd.ts b/packages/vectors3/src/madd.ts index 0056701c77..6095caa3d6 100644 --- a/packages/vectors3/src/madd.ts +++ b/packages/vectors3/src/madd.ts @@ -1,6 +1,9 @@ import { MultiVecOpVVV, VecOpVVV } from "./api"; import { defOp } from "./internal/codegen"; +/** + * Returns `out = a + b * c`. + */ export const [madd, madd2, madd3, madd4] = defOp( ([o, a, b, c]) => `${o}=${a}+${b}*${c};`, diff --git a/packages/vectors3/src/maddn.ts b/packages/vectors3/src/maddn.ts index cf1bd32f7d..f8d05b2b44 100644 --- a/packages/vectors3/src/maddn.ts +++ b/packages/vectors3/src/maddn.ts @@ -1,6 +1,9 @@ import { MultiVecOpVVN, VecOpVVN } from "./api"; import { defOp } from "./internal/codegen"; +/** + * Returns `out = a + b * n`. + */ export const [maddN, maddN2, maddN3, maddN4] = defOp( ([o, a, b]) => `${o}=${a}+${b}*n;`, diff --git a/packages/vectors3/src/major.ts b/packages/vectors3/src/major.ts index a864b4c417..bc83e70b29 100644 --- a/packages/vectors3/src/major.ts +++ b/packages/vectors3/src/major.ts @@ -4,6 +4,12 @@ import { vop } from "./internal/vop"; const abs = Math.abs; +/** + * Returns index of major component/axis in `v`, i.e. where `|v[i]|` is + * the largest. + * + * @param v + */ export const major: MultiVecOpRoV = vop(); major.default((a) => { diff --git a/packages/vectors3/src/minor.ts b/packages/vectors3/src/minor.ts index ca8d4542a3..dab5f09de8 100644 --- a/packages/vectors3/src/minor.ts +++ b/packages/vectors3/src/minor.ts @@ -4,6 +4,12 @@ import { vop } from "./internal/vop"; const abs = Math.abs; +/** + * Returns index of minor component/axis in `v`, i.e. where `|v[i]|` is + * the smallest. + * + * @param v + */ export const minor: MultiVecOpRoV = vop(); minor.default((a) => { diff --git a/packages/vectors3/src/normalize.ts b/packages/vectors3/src/normalize.ts index aed17e25a7..7362c25484 100644 --- a/packages/vectors3/src/normalize.ts +++ b/packages/vectors3/src/normalize.ts @@ -1,10 +1,18 @@ import { EPS } from "@thi.ng/math/api"; -import { ReadonlyVec, Vec } from "./api"; +import { VecOpVO } from "./api"; import { mag } from "./mag"; import { mulN } from "./muln"; -export const normalize = - (out: Vec, v: ReadonlyVec, n = 1) => { +/** + * Normalizes vector to given (optional) length (default: 1). If `out` + * is null, modifies `v` in place. + * + * @param out + * @param v + * @param n + */ +export const normalize: VecOpVO = + (out, v, n = 1) => { let m = mag(v); - return m >= EPS ? mulN(out, v, n / m) : v; + return m >= EPS ? mulN(out || v, v, n / m) : v; }; diff --git a/packages/vectors3/src/ortho-normal.ts b/packages/vectors3/src/ortho-normal.ts index a018c59131..213e81f1cf 100644 --- a/packages/vectors3/src/ortho-normal.ts +++ b/packages/vectors3/src/ortho-normal.ts @@ -2,6 +2,20 @@ import { VecOpVVV } from "./api"; import { cross3 } from "./cross"; import { sub3 } from "./sub"; +/** + * Produces a vector which is perpendicular/normal to the plane spanned + * by given 3 input vectors. + * + * ``` + * orthoNormal3([], [0,0,0], [1,0,0], [0,1,0]) + * // [0,0,1] + * ``` + * + * @param out + * @param a + * @param b + * @param c + */ export const orthoNormal3: VecOpVVV = (out, a, b, c) => - cross3(out, sub3(out, c, a), sub3([], b, a)); + cross3(out, sub3(out, b, a), sub3([], c, a)); diff --git a/packages/vectors3/src/perpendicular.ts b/packages/vectors3/src/perpendicular.ts index 49b49d6911..180b6416f9 100644 --- a/packages/vectors3/src/perpendicular.ts +++ b/packages/vectors3/src/perpendicular.ts @@ -1,15 +1,29 @@ import { VecOpV } from "./api"; +/** + * Produces a perpendicular vector to `v`, i.e. `[-y,x]`. + * + * @param out + * @param v + */ export const perpendicularLeft2: VecOpV = (out, a) => { + !out && (out = a); const x = a[0]; out[0] = -a[1]; out[1] = x; return out; }; +/** + * Produces a perpendicular vector to `v`, i.e. `[y,-x]`. + * + * @param out + * @param v + */ export const perpendicularRight2: VecOpV = (out, a) => { + !out && (out = a); const x = -a[0]; out[0] = a[1]; out[1] = x; diff --git a/packages/vectors3/src/polar.ts b/packages/vectors3/src/polar.ts index 0c01cc7400..f06b482c48 100644 --- a/packages/vectors3/src/polar.ts +++ b/packages/vectors3/src/polar.ts @@ -6,16 +6,41 @@ const sqrt = Math.sqrt; const asin = Math.asin; const atan2 = Math.atan2; +/** + * Converts cartesian vector `v` to polar coordinates. See `cartesian()` + * for reverse operation. If `out` is null, modifies `v` in place. + * + * @param out + * @param v + */ export const polar: MultiVecOpV = vop(1); +/** + * Converts 2D cartesian vector `v` to polar coordinates, i.e. `[r,θ]` + * (angle in radians). See `cartesian()` for reverse operation. If `out` + * is null, modifies `v` in place. + * + * @param out + * @param v + */ export const polar2 = polar.add(2, (out, a) => { + !out && (out = a); const x = a[0]; out[0] = mag(a); out[1] = atan2(a[1], x); return out; }); +/** + * Converts 3D cartesian vector `v` to spherical coordinates, i.e. + * `[r,θ,Ï•]` (angles in radians). See `cartesian()` for reverse + * operation. If `out` is null, modifies `v` in place. + * + * @param out + * @param v + */ export const polar3 = polar.add(3, (out, a) => { + !out && (out = a); const x = a[0]; const y = a[1]; const z = a[2]; diff --git a/packages/vectors3/src/random.ts b/packages/vectors3/src/random.ts index a4f0811286..306f8f9b36 100644 --- a/packages/vectors3/src/random.ts +++ b/packages/vectors3/src/random.ts @@ -4,6 +4,15 @@ import { MultiVecOpOOO, Vec, VecOpOOO } from "./api"; import { defHofOp } from "./internal/codegen"; import { normalize } from "./normalize"; +/** + * Sets `v` to random vector, with each component in interval `[n..m)`. + * If no `rnd` instance is given, uses `SYSTEM`, i.e. `Math.random`. + * + * @param v + * @param n default -1 + * @param m default 1 + * @param rnd + */ export const [random, random2, random3, random4] = defHofOp, VecOpOOO>( SYSTEM, @@ -14,7 +23,16 @@ export const [random, random2, random3, random4] = 0 ); -export const randNorm = (v: Vec, n = 1, rnd: IRandom = SYSTEM) => { - v = random(v, -1, 1, rnd); - return normalize(v, v, n); -}; +/** + * Sets `v` to random vector, normalized to length `n` (default: 1). If no + * `rnd` instance is given, uses `SYSTEM`, i.e. `Math.random`. + * + * @param v + * @param n + * @param rnd + */ +export const randNorm = + (v: Vec, n = 1, rnd: IRandom = SYSTEM) => { + v = random(v, -1, 1, rnd); + return normalize(v, v, n); + }; diff --git a/packages/vectors3/src/rotate-around-axis.ts b/packages/vectors3/src/rotate-around-axis.ts index 82b2937228..60bf727f8e 100644 --- a/packages/vectors3/src/rotate-around-axis.ts +++ b/packages/vectors3/src/rotate-around-axis.ts @@ -21,8 +21,8 @@ export const rotateAroundAxis3 = const s = Math.sin(theta); const c = Math.cos(theta); - out[0] = (ax * uvw + (x * (ay * ay + az * az) - ax * (vy + wz)) * c + (-wy + vz) * s); - out[1] = (ay * uvw + (y * (ax * ax + az * az) - ay * (ux + wz)) * c + (wx - uz) * s); - out[2] = (az * uvw + (z * (ax * ax + ay * ay) - az * (ux + vy)) * c + (-vx + uy) * s); + out[0] = ax * uvw + (x * (ay * ay + az * az) - ax * (vy + wz)) * c + (-wy + vz) * s; + out[1] = ay * uvw + (y * (ax * ax + az * az) - ay * (ux + wz)) * c + (wx - uz) * s; + out[2] = az * uvw + (z * (ax * ax + ay * ay) - az * (ux + vy)) * c + (-vx + uy) * s; return v; }; diff --git a/packages/vectors3/src/smoothstep.ts b/packages/vectors3/src/smoothstep.ts index 5f43b54ea5..d2ea556d7d 100644 --- a/packages/vectors3/src/smoothstep.ts +++ b/packages/vectors3/src/smoothstep.ts @@ -2,9 +2,20 @@ import { smoothStep as _step } from "@thi.ng/math/step"; import { MultiVecOpV, VecOpV } from "./api"; import { defHofOp } from "./internal/codegen"; +/** + * Like GLSL `smoothstep()` + * + * @param out + * @param e1 + * @param e2 + * @param v + */ export const [smoothStep, smoothStep2, smoothStep3, smoothStep4] = defHofOp( _step, - ([o, a, e1, e2]) => `${o}=op(${e1},${e2},${a});`, - "o,a,e1,e2" + ([o, e1, e2, a]) => `${o}=op(${e1},${e2},${a});`, + "o,e1,e2,a", + undefined, + "o", + 3 ); diff --git a/packages/vectors3/src/step.ts b/packages/vectors3/src/step.ts index 82070f7d75..2e22dc8151 100644 --- a/packages/vectors3/src/step.ts +++ b/packages/vectors3/src/step.ts @@ -2,9 +2,19 @@ import { step as _step } from "@thi.ng/math/step"; import { MultiVecOpV, VecOpV } from "./api"; import { defHofOp } from "./internal/codegen"; +/** + * Like GLSL `step()` + * + * @param out + * @param e + * @param v + */ export const [step, step2, step3, step4] = defHofOp( _step, - ([o, a, e]) => `${o}=op(${e},${a});`, - "o,a,e" + ([o, e, a]) => `${o}=op(${e},${a});`, + "o,e,a", + undefined, + "o", + 2 ); diff --git a/packages/vectors3/src/swizzle.ts b/packages/vectors3/src/swizzle.ts index 9abf035bc8..47ac098acf 100644 --- a/packages/vectors3/src/swizzle.ts +++ b/packages/vectors3/src/swizzle.ts @@ -1,4 +1,4 @@ -import { ReadonlyVec, Vec } from "./api"; +import { ReadonlyVec, Vec, VecOpV } from "./api"; /** * Places a re-ordered 2D version of vector `a` into `out`. MUST be @@ -56,3 +56,12 @@ export const swizzle4 = out[3] = a[w] || 0, out ); + +export const swapXY: VecOpV = + (out, v) => swizzle3(out, v, 1, 0, 2); + +export const swapXZ: VecOpV = + (out, v) => swizzle3(out, v, 2, 1, 0); + +export const swapYZ: VecOpV = + (out, v) => swizzle3(out, v, 0, 2, 1); From f1a5cf121faef1c0976537a0f29056a1d3a72acc Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 27 Nov 2018 11:52:52 +0000 Subject: [PATCH 047/333] feat(matrices): add M44 factories --- packages/matrices/src/frustum.ts | 44 ++++++++++++++++++++++++++++ packages/matrices/src/index.ts | 5 ++++ packages/matrices/src/lookat.ts | 26 ++++++++++++++++ packages/matrices/src/normal-mat.ts | 15 ++++++++++ packages/matrices/src/ortho.ts | 23 +++++++++++++++ packages/matrices/src/perspective.ts | 13 ++++++++ 6 files changed, 126 insertions(+) create mode 100644 packages/matrices/src/frustum.ts create mode 100644 packages/matrices/src/lookat.ts create mode 100644 packages/matrices/src/normal-mat.ts create mode 100644 packages/matrices/src/ortho.ts create mode 100644 packages/matrices/src/perspective.ts diff --git a/packages/matrices/src/frustum.ts b/packages/matrices/src/frustum.ts new file mode 100644 index 0000000000..a38afac27a --- /dev/null +++ b/packages/matrices/src/frustum.ts @@ -0,0 +1,44 @@ +import { DEG2RAD } from "@thi.ng/math/api"; +import { Mat } from "./api"; +import { setValues44 } from "./set-values"; + +export const frustum = ( + out: Mat, + left: number, + right: number, + bottom: number, + top: number, + near: number, + far: number) => { + + const dx = 1 / (right - left); + const dy = 1 / (top - bottom); + const dz = 1 / (far - near); + + return setValues44( + out, + near * 2 * dx, 0, 0, 0, + 0, near * 2 * dy, 0, 0, + (right + left) * dx, (top + bottom) * dy, -(far + near) * dz, -1, + 0, 0, -(far * near * 2) * dz, 0, + ); +}; + +export const frustumBounds = ( + fovy: number, + aspect: number, + near: number, + far: number) => { + + const top = near * Math.tan(fovy * DEG2RAD / 2); + const right = top * aspect; + + return { + left: -right, + right, + bottom: -top, + top, + near, + far + }; +}; diff --git a/packages/matrices/src/index.ts b/packages/matrices/src/index.ts index 9cfbabce17..e60fac687c 100644 --- a/packages/matrices/src/index.ts +++ b/packages/matrices/src/index.ts @@ -8,11 +8,16 @@ export * from "./determinant"; export * from "./diag"; export * from "./div"; export * from "./divn"; +export * from "./frustum"; export * from "./identity"; export * from "./invert"; +export * from "./lookat"; export * from "./mul"; export * from "./muln"; export * from "./mulv"; +export * from "./normal-mat"; +export * from "./ortho"; +export * from "./perspective"; export * from "./rotation"; export * from "./row"; export * from "./scale"; diff --git a/packages/matrices/src/lookat.ts b/packages/matrices/src/lookat.ts new file mode 100644 index 0000000000..ac1ba2a838 --- /dev/null +++ b/packages/matrices/src/lookat.ts @@ -0,0 +1,26 @@ +import { ReadonlyVec } from "@thi.ng/vectors3/api"; +import { cross3 } from "@thi.ng/vectors3/cross"; +import { dot3 } from "@thi.ng/vectors3/dot"; +import { normalize } from "@thi.ng/vectors3/normalize"; +import { sub3 } from "@thi.ng/vectors3/sub"; +import { Mat } from "./api"; +import { setValues44 } from "./set-values"; + +export const lookAt = ( + out: Mat, + eye: ReadonlyVec, + target: ReadonlyVec, + up: ReadonlyVec) => { + + const z = normalize(null, sub3([], eye, target)); + const x = normalize(null, cross3([], up, z)); + const y = normalize(null, cross3([], z, x)); + + return setValues44( + out, + x[0], y[0], z[0], 0, + x[1], y[1], z[1], 0, + x[2], y[2], z[2], 0, + -dot3(eye, x), -dot3(eye, y), -dot3(eye, z), 1, + ); +}; diff --git a/packages/matrices/src/normal-mat.ts b/packages/matrices/src/normal-mat.ts new file mode 100644 index 0000000000..d7b8ae4a18 --- /dev/null +++ b/packages/matrices/src/normal-mat.ts @@ -0,0 +1,15 @@ +import { MatOpM } from "./api"; +import { mat44to33 } from "./convert"; +import { invert33 } from "./invert"; +import { transpose33 } from "./transpose"; + +/** + * Converts given M44 to a M33 normal matrix, i.e. the transposed + * inverted version of its upper-left 3x3 region. + * + * @param out + * @param m + */ +export const normal44: MatOpM = + (out, m) => + transpose33(out, invert33(out, mat44to33(out, m))); diff --git a/packages/matrices/src/ortho.ts b/packages/matrices/src/ortho.ts new file mode 100644 index 0000000000..8dff5486ef --- /dev/null +++ b/packages/matrices/src/ortho.ts @@ -0,0 +1,23 @@ +import { Mat } from "./api"; +import { setValues44 } from "./set-values"; + +export const ortho = ( + out: Mat, + left: number, + right: number, + bottom: number, + top: number, + near: number, + far: number) => { + + const dx = 1 / (right - left); + const dy = 1 / (top - bottom); + const dz = 1 / (far - near); + return setValues44( + out, + 2 * dx, 0, 0, 0, + 0, 2 * dy, 0, 0, + 0, 0, -2 * dz, 0, + -(left + right) * dx, -(top + bottom) * dy, -(far + near) * dz, 1, + ); +}; diff --git a/packages/matrices/src/perspective.ts b/packages/matrices/src/perspective.ts new file mode 100644 index 0000000000..2efbf8296a --- /dev/null +++ b/packages/matrices/src/perspective.ts @@ -0,0 +1,13 @@ +import { Mat } from "./api"; +import { frustum, frustumBounds } from "./frustum"; + +export const perspective = ( + out: Mat, + fov: number, + aspect: number, + near: number, + far: number) => { + + const f = frustumBounds(fov, aspect, near, far); + return frustum(out, f.left, f.right, f.bottom, f.top, f.near, f.far); +}; From 28fd0f1f6c02cb1bf0845ea1ad8c79e4115b57f3 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 27 Nov 2018 12:46:22 +0000 Subject: [PATCH 048/333] feat(vectors): add sum() --- packages/vectors3/src/index.ts | 1 + packages/vectors3/src/sum.ts | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 packages/vectors3/src/sum.ts diff --git a/packages/vectors3/src/index.ts b/packages/vectors3/src/index.ts index 133f72deab..38f42e4563 100644 --- a/packages/vectors3/src/index.ts +++ b/packages/vectors3/src/index.ts @@ -89,6 +89,7 @@ export * from "./smoothstep"; export * from "./sub"; export * from "./subn"; export * from "./subs"; +export * from "./sum"; export * from "./swizzle"; export * from "./tan"; export * from "./tanh"; diff --git a/packages/vectors3/src/sum.ts b/packages/vectors3/src/sum.ts new file mode 100644 index 0000000000..d13b73217b --- /dev/null +++ b/packages/vectors3/src/sum.ts @@ -0,0 +1,17 @@ +import { MultiVecOpRoV } from "./api"; +import { vop } from "./internal/vop"; +import { reduce } from "@thi.ng/transducers/reduce"; +import { add } from "@thi.ng/transducers/rfn/add"; + +/** + * Returns component sum of vector `v`. + * + * @param v + */ +export const sum: MultiVecOpRoV = vop(0); + +sum.default((v) => reduce(add(), v)); + +export const sum2 = sum.add(2, (a) => a[0] + a[1]); +export const sum3 = sum.add(2, (a) => a[0] + a[1] + a[2]); +export const sum4 = sum.add(2, (a) => a[0] + a[1] + a[2] + a[3]); From 16d56a3715d985e98158fe99be1222ec010a1eee Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 27 Nov 2018 12:47:44 +0000 Subject: [PATCH 049/333] feat(matrices): add trace() --- packages/matrices/src/index.ts | 1 + packages/matrices/src/mulv.ts | 51 ++++++++++++++++++++++++++++++++++ packages/matrices/src/trace.ts | 11 ++++++++ 3 files changed, 63 insertions(+) create mode 100644 packages/matrices/src/trace.ts diff --git a/packages/matrices/src/index.ts b/packages/matrices/src/index.ts index e60fac687c..a7c4c1ed24 100644 --- a/packages/matrices/src/index.ts +++ b/packages/matrices/src/index.ts @@ -28,5 +28,6 @@ export * from "./shear"; export * from "./skew"; export * from "./sub"; export * from "./subn"; +export * from "./trace"; export * from "./translation"; export * from "./transpose"; diff --git a/packages/matrices/src/mulv.ts b/packages/matrices/src/mulv.ts index ec00da299e..d77190e05f 100644 --- a/packages/matrices/src/mulv.ts +++ b/packages/matrices/src/mulv.ts @@ -2,8 +2,24 @@ import { dotS2, dotS3, dotS4 } from "@thi.ng/vectors3/dots"; import { MatOpMV, MultiMatOpMV } from "./api"; import { vop } from "@thi.ng/vectors3/internal/vop"; +/** + * Matrix-vector multiplication. Supports in-place modification, i.e. if + * `out === v`. + * + * @param out + * @param m + * @param v + */ export const mulV: MultiMatOpMV = vop(1); +/** + * Multiplies M22 `m` with 2D vector `v`. Supports in-place + * modification, i.e. if `out === v`. + * + * @param out + * @param m + * @param v + */ export const mulV22: MatOpMV = mulV.add(4, (out, m, v) => { const x = dotS2(m, v, 0, 0, 2); @@ -12,6 +28,14 @@ export const mulV22: MatOpMV = return out; }); +/** + * Multiplies M23 `m` with 2D vector `v`. Supports in-place + * modification, i.e. if `out === v`. + * + * @param out + * @param m + * @param v + */ export const mulV23: MatOpMV = mulV.add(6, (out, m, v) => { const x = dotS2(m, v, 0, 0, 2) + m[4]; @@ -20,6 +44,14 @@ export const mulV23: MatOpMV = return out; }); +/** + * Multiplies M33 `m` with 3D vector `v`. Supports in-place + * modification, i.e. if `out === v`. + * + * @param out + * @param m + * @param v + */ export const mulV33: MatOpMV = mulV.add(9, (out, m, v) => { const x = dotS3(m, v, 0, 0, 3); @@ -30,8 +62,17 @@ export const mulV33: MatOpMV = return out; }); +/** + * Multiplies M44 `m` with 4D vector `v`. Supports in-place + * modification, i.e. if `out === v`. + * + * @param out + * @param m + * @param v + */ export const mulV44: MatOpMV = mulV.add(16, (out, m, v) => { + !out && (out = v); const x = dotS4(m, v, 0, 0, 4); const y = dotS4(m, v, 1, 0, 4); const z = dotS4(m, v, 2, 0, 4); @@ -42,8 +83,18 @@ export const mulV44: MatOpMV = return out; }); +/** + * Multiplies M44 `m` with 3D vector `v` and assumes `w=1`, i.e. the + * vector is interpreted as `[x,y,z,1]` and the last row of `m` is + * `[0,0,0,1]`. Supports in-place modification, i.e. if `out === v`. + * + * @param out + * @param m + * @param v + */ export const mulV344: MatOpMV = (out, m, v) => { + !out && (out = v); const x = dotS3(m, v, 0, 0, 4) + m[12]; const y = dotS3(m, v, 1, 0, 4) + m[13]; out[2] = dotS3(m, v, 2, 0, 4) + m[14]; diff --git a/packages/matrices/src/trace.ts b/packages/matrices/src/trace.ts new file mode 100644 index 0000000000..ea08e6e1a4 --- /dev/null +++ b/packages/matrices/src/trace.ts @@ -0,0 +1,11 @@ +import { sum } from "@thi.ng/vectors3/sum"; +import { diag } from "./diag"; +import { ReadonlyMat } from "./api"; + +/** + * Returns matrix trace of `m`, i.e. component sum of `diag(m)`. + * + * @param m + */ +export const trace = + (m: ReadonlyMat) => sum(diag([], m)); From d9e1b2eca6367c4be655d91bb4b95024e7a0a645 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 27 Nov 2018 14:13:17 +0000 Subject: [PATCH 050/333] feat(matrices): add viewport(), project/unproject(), update invert() --- packages/matrices/src/index.ts | 2 ++ packages/matrices/src/invert.ts | 21 ++++++++------ packages/matrices/src/project.ts | 48 +++++++++++++++++++++++++++++++ packages/matrices/src/viewport.ts | 23 +++++++++++++++ 4 files changed, 85 insertions(+), 9 deletions(-) create mode 100644 packages/matrices/src/project.ts create mode 100644 packages/matrices/src/viewport.ts diff --git a/packages/matrices/src/index.ts b/packages/matrices/src/index.ts index a7c4c1ed24..cc5e11072d 100644 --- a/packages/matrices/src/index.ts +++ b/packages/matrices/src/index.ts @@ -18,6 +18,7 @@ export * from "./mulv"; export * from "./normal-mat"; export * from "./ortho"; export * from "./perspective"; +export * from "./project"; export * from "./rotation"; export * from "./row"; export * from "./scale"; @@ -31,3 +32,4 @@ export * from "./subn"; export * from "./trace"; export * from "./translation"; export * from "./transpose"; +export * from "./viewport"; diff --git a/packages/matrices/src/invert.ts b/packages/matrices/src/invert.ts index 1408c0784b..606e02a673 100644 --- a/packages/matrices/src/invert.ts +++ b/packages/matrices/src/invert.ts @@ -1,13 +1,16 @@ import { dotValues4, dotValues6 } from "@thi.ng/vectors3/dot-values"; -import { MatOpM } from "./api"; +import { MatOpM, MultiMatOpM } from "./api"; import { setValues23, setValues22, setValues44, setValues33 } from "./set-values"; import { detCoeffs44, det44FromCoeffs } from "./determinant"; +import { vop } from "@thi.ng/vectors3/internal/vop"; const dp4 = dotValues4; const dp6 = dotValues6; +export const invert: MultiMatOpM = vop(1); + export const invert22: MatOpM = - (out, m) => { + invert.add(4, (out, m) => { const [m00, m01, m10, m11] = m; let det = dp4(m00, m11, -m01, m10); if (det === 0) return; @@ -19,10 +22,10 @@ export const invert22: MatOpM = -m10 * det, m00 * det, ); - }; + }); export const invert23: MatOpM = - (out, m) => { + invert.add(6, (out, m) => { const [m00, m01, m10, m11, m20, m21] = m; let det = dp4(m00, m11, -m01, m10); if (det === 0) return; @@ -36,10 +39,10 @@ export const invert23: MatOpM = dp4(m10, m21, -m11, m20) * det, dp4(m01, m20, -m00, m21) * det ); - }; + }); export const invert33: MatOpM = - (out, m) => { + invert.add(9, (out, m) => { const [m00, m01, m02, m10, m11, m12, m20, m21, m22] = m; const d01 = dp4(m22, m11, -m12, m21); const d11 = dp4(m12, m20, -m22, m10); @@ -59,10 +62,10 @@ export const invert33: MatOpM = dp4(-m21, m00, m01, m20) * det, dp4(m11, m00, -m01, m10) * det, ); - }; + }); export const invert44: MatOpM = - (out, m) => { + invert.add(16, (out, m) => { const coeffs = detCoeffs44(m); let det = det44FromCoeffs(coeffs); if (det === 0) return; @@ -88,4 +91,4 @@ export const invert44: MatOpM = dp6(-m30, d03, m31, d01, -m32, d00) * det, dp6(m20, d03, -m21, d01, m22, d00) * det ); - }; + }); diff --git a/packages/matrices/src/project.ts b/packages/matrices/src/project.ts new file mode 100644 index 0000000000..f890be4557 --- /dev/null +++ b/packages/matrices/src/project.ts @@ -0,0 +1,48 @@ +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { divN3 } from "@thi.ng/vectors3/divn"; +import { dotValues6 } from "@thi.ng/vectors3/dot-values"; +import { fromHomogeneous4 } from "@thi.ng/vectors3/homogeneous"; +import { ReadonlyMat } from "./api"; +import { invert23, invert44 } from "./invert"; +import { mulV23, mulV344, mulV44 } from "./mulv"; + +/** + * Transforms given point `p` (4D, homogeneous) with M44 `mvp`, applies + * perspective divide and then transforms XY components with M23 `view` + * matrix. Returns 3D vector. The result Z component can be used for + * depth sorting. + * + * @param out + * @param mvp + * @param view + * @param p + */ +export const project = + (out: Vec, mvp: ReadonlyMat, view: ReadonlyMat, p: ReadonlyVec) => + mulV23(out, view, fromHomogeneous4(out, mulV44([], mvp, p))); + +/** + * Reverse operation of project. If `invert` is true (default: false), + * both `mvp` and `view` matrices will be inverted first + * (non-destructively), else they're both assumed to be inverted + * already. + * + * @param out + * @param mvp + * @param view + * @param p + * @param invert + */ +export const unproject = + (out: Vec, mvp: ReadonlyMat, view: ReadonlyMat, p: ReadonlyVec, doInvert = false) => { + if (doInvert) { + mvp = invert44([], mvp); + view = invert23([], view); + } + const q = [...mulV23([], view, p), p[2] * 2 - 1]; + return divN3( + out, + mulV344(out, mvp, q), + dotValues6(q[0], mvp[3], q[1], mvp[7], q[2], mvp[11]) + mvp[15] + ); + }; diff --git a/packages/matrices/src/viewport.ts b/packages/matrices/src/viewport.ts new file mode 100644 index 0000000000..c5fc5315a3 --- /dev/null +++ b/packages/matrices/src/viewport.ts @@ -0,0 +1,23 @@ +import { Mat } from "./api"; +import { mul23 } from "./mul"; +import { scale23 } from "./scale"; +import { translation23 } from "./translation"; + +/** + * Produces a M23 viewport matrix to transform projected coordinates to + * screen space. + * + * @param out + * @param left + * @param right + * @param bottom + * @param top + */ +export const viewport = + (out: Mat, left: number, right: number, bottom: number, top: number) => { + const x = (left + right) / 2; + const y = (bottom + top) / 2; + const w = (right - left) / 2; + const h = (top - bottom) / 2; + return mul23(out, translation23(out, [x, y]), scale23([], [w, h])); + }; From a373e55bee9392e8d2348a68a1399004d72cd084 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 27 Nov 2018 15:15:00 +0000 Subject: [PATCH 051/333] feat(vectors): update `out` default behavior & codegens, bugfixes - where possible inject behavior to use 2nd arg as default `out`, iff given `out=null` - update def*() codegens - fix normalize() / limit() --- packages/vectors3/src/cross.ts | 1 + packages/vectors3/src/face-forward.ts | 6 ++++-- packages/vectors3/src/homogeneous.ts | 16 +++++++++++---- packages/vectors3/src/internal/codegen.ts | 24 ++++++++++++++++------- packages/vectors3/src/jitter.ts | 3 +-- packages/vectors3/src/limit.ts | 10 ++++++++-- packages/vectors3/src/normalize.ts | 10 ++++++++-- packages/vectors3/src/set.ts | 2 +- packages/vectors3/src/setn.ts | 2 +- packages/vectors3/src/sets.ts | 2 +- packages/vectors3/src/setsn.ts | 2 +- 11 files changed, 55 insertions(+), 23 deletions(-) diff --git a/packages/vectors3/src/cross.ts b/packages/vectors3/src/cross.ts index 6a182665a2..5944897860 100644 --- a/packages/vectors3/src/cross.ts +++ b/packages/vectors3/src/cross.ts @@ -6,6 +6,7 @@ export const cross2 = export const cross3 = (out: Vec, a: ReadonlyVec, b: ReadonlyVec) => { + !out && (out = a); const x = a[1] * b[2] - a[2] * b[1]; const y = a[2] * b[0] - a[0] * b[2]; out[2] = a[0] * b[1] - a[1] * b[0]; diff --git a/packages/vectors3/src/face-forward.ts b/packages/vectors3/src/face-forward.ts index b8c1565d68..9a7c5edf7f 100644 --- a/packages/vectors3/src/face-forward.ts +++ b/packages/vectors3/src/face-forward.ts @@ -4,7 +4,9 @@ import { mulN } from "./muln"; import { set } from "./set"; export const faceForward: VecOpVVV = - (out, n, i, nref) => - dot(nref, i) < 0 ? + (out, n, i, nref) => { + !out && (out = n); + return dot(nref, i) < 0 ? out === n ? out : set(out, n) : mulN(out, n, -1); + }; diff --git a/packages/vectors3/src/homogeneous.ts b/packages/vectors3/src/homogeneous.ts index 128d6d1f0c..dd33a1658b 100644 --- a/packages/vectors3/src/homogeneous.ts +++ b/packages/vectors3/src/homogeneous.ts @@ -5,12 +5,20 @@ export const fromHomogeneous: MultiVecOpV = vop(1); export const fromHomogeneous3 = fromHomogeneous.add(3, - (out, [x, y, w]) => - (out[0] = x / w, out[1] = y / w, out) + (out, [x, y, w]) => ( + !out && (out = []), + out[0] = x / w, + out[1] = y / w, + out + ) ); export const fromHomogeneous4 = fromHomogeneous.add(4, - (out, [x, y, z, w]) => - (out[0] = x / w, out[1] = y / w, out[2] = z / w, out) + (out, [x, y, z, w]) => ( + !out && (out = []), + out[0] = x / w, + out[1] = y / w, + out[2] = z / w, out + ) ); diff --git a/packages/vectors3/src/internal/codegen.ts b/packages/vectors3/src/internal/codegen.ts index 4e012e2169..676b8b1146 100644 --- a/packages/vectors3/src/internal/codegen.ts +++ b/packages/vectors3/src/internal/codegen.ts @@ -130,6 +130,9 @@ const assembleG = ( ret !== null ? `return ${ret};` : "" ]; +export const defaultOut = + (o: string, args: string) => `!${o} && (${o}=${args.split(",")[1]});` + export const compile = ( dim: number, tpl: Template, @@ -204,12 +207,14 @@ export const defOp = ( args = ARGS_VV, syms?: string, ret = "o", - dispatch = 1): [M, V, V, V] => { + dispatch = 1, + pre?: string): [M, V, V, V] => { syms = syms || args; + pre = pre != null ? pre : defaultOut(ret, args); const fn: any = vop(dispatch); - const $ = (dim) => fn.add(dim, compile(dim, tpl, args, syms, ret)); - fn.default(compileG(tpl, args, syms, ret)); + const $ = (dim) => fn.add(dim, compile(dim, tpl, args, syms, ret, "", pre)); + fn.default(compileG(tpl, args, syms, ret, pre)); return [fn, $(2), $(3), $(4)]; }; @@ -222,13 +227,15 @@ export const defHofOp = ( args = ARGS_V, syms?: string, ret = "o", - dispatch = 1): [M, V, V, V] => { + dispatch = 1, + pre?: string): [M, V, V, V] => { tpl = tpl || FN("op"); syms = syms || args; - const $ = (dim) => compileHOF(dim, [op], tpl, "op", args, syms, ret); + pre = pre != null ? pre : defaultOut(ret, args); + const $ = (dim) => compileHOF(dim, [op], tpl, "op", args, syms, ret, "", pre); const fn: any = vop(dispatch); - fn.default(compileGHOF([op], tpl, "op", args, syms, ret)); + fn.default(compileGHOF([op], tpl, "op", args, syms, ret, pre)); return [fn, $(2), $(3), $(4)]; }; @@ -237,6 +244,9 @@ export const defOpS = ( args = `${ARGS_VV},${SARGS_VV}`, syms = ARGS_VV, ret = "o", + pre?: string, sizes = [2, 3, 4]): V[] => - sizes.map((dim) => compile(dim, tpl, args, syms, ret, "", "", "", true)); + sizes.map( + (dim) => compile(dim, tpl, args, syms, ret, "", pre != null ? pre : defaultOut(ret, args), "", true) + ); diff --git a/packages/vectors3/src/jitter.ts b/packages/vectors3/src/jitter.ts index ecc355694e..d473a82525 100644 --- a/packages/vectors3/src/jitter.ts +++ b/packages/vectors3/src/jitter.ts @@ -3,8 +3,7 @@ import { SYSTEM } from "@thi.ng/random/system"; import { add } from "./add"; import { ReadonlyVec, Vec } from "./api"; import { randNorm } from "./random"; -import { zeroes } from "./setn"; export const jitter = (out: Vec, a: ReadonlyVec, n = 1, rnd: IRandom = SYSTEM) => - add(out, randNorm(zeroes(a.length), n, rnd), a); + add(out, randNorm(new Array(a.length), n, rnd), a); diff --git a/packages/vectors3/src/limit.ts b/packages/vectors3/src/limit.ts index 8d0bff7893..bce2ea6ad8 100644 --- a/packages/vectors3/src/limit.ts +++ b/packages/vectors3/src/limit.ts @@ -1,9 +1,15 @@ import { ReadonlyVec, Vec } from "./api"; import { mag } from "./mag"; import { mulN } from "./muln"; +import { set } from "./set"; export const limit = (out: Vec, v: ReadonlyVec, n: number) => { - let m = mag(v); - return m > n ? mulN(out, v, n / m) : v; + !out && (out = v); + const m = mag(v); + return m > n ? + mulN(out, v, n / m) : + out === v ? + out : + set(out, v); }; diff --git a/packages/vectors3/src/normalize.ts b/packages/vectors3/src/normalize.ts index 7362c25484..c9e1499741 100644 --- a/packages/vectors3/src/normalize.ts +++ b/packages/vectors3/src/normalize.ts @@ -2,6 +2,7 @@ import { EPS } from "@thi.ng/math/api"; import { VecOpVO } from "./api"; import { mag } from "./mag"; import { mulN } from "./muln"; +import { set } from "./set"; /** * Normalizes vector to given (optional) length (default: 1). If `out` @@ -13,6 +14,11 @@ import { mulN } from "./muln"; */ export const normalize: VecOpVO = (out, v, n = 1) => { - let m = mag(v); - return m >= EPS ? mulN(out || v, v, n / m) : v; + !out && (out = v); + const m = mag(v); + return m >= EPS ? + mulN(out, v, n / m) : + out === v ? + out : + set(out, v); }; diff --git a/packages/vectors3/src/set.ts b/packages/vectors3/src/set.ts index 149e3a304d..568a729645 100644 --- a/packages/vectors3/src/set.ts +++ b/packages/vectors3/src/set.ts @@ -3,4 +3,4 @@ import { defOp } from "./internal/codegen"; import { SET } from "./internal/templates"; export const [set, set2, set3, set4] = - defOp(SET, "o,a"); + defOp(SET, "o,a", undefined, "o", 1, ""); diff --git a/packages/vectors3/src/setn.ts b/packages/vectors3/src/setn.ts index e3fa0f7132..8b7a09de78 100644 --- a/packages/vectors3/src/setn.ts +++ b/packages/vectors3/src/setn.ts @@ -3,7 +3,7 @@ import { defOp } from "./internal/codegen"; import { SET_N } from "./internal/templates"; export const [setN, setN2, setN3, setN4] = - defOp(SET_N, "a,n", "a", "a", 0); + defOp(SET_N, "a,n", "a", "a", 0, ""); export const zero = (a: Vec) => setN(a, 0); export const one = (a: Vec) => setN(a, 1); diff --git a/packages/vectors3/src/sets.ts b/packages/vectors3/src/sets.ts index 234158a246..07c4cee6d7 100644 --- a/packages/vectors3/src/sets.ts +++ b/packages/vectors3/src/sets.ts @@ -3,4 +3,4 @@ import { defOpS, SARGS_V } from "./internal/codegen"; import { SET } from "./internal/templates"; export const [setS2, setS3, setS4] = - defOpS(SET, `o,a,${SARGS_V}`, "o,a"); + defOpS(SET, `o,a,${SARGS_V}`, "o,a", "o", ""); diff --git a/packages/vectors3/src/setsn.ts b/packages/vectors3/src/setsn.ts index a7d285c3a8..30501cd5b3 100644 --- a/packages/vectors3/src/setsn.ts +++ b/packages/vectors3/src/setsn.ts @@ -3,4 +3,4 @@ import { defOpS } from "./internal/codegen"; import { SET_N } from "./internal/templates"; export const [setSN2, setSN3, setSN4] = - defOpS(SET_N, "o,n,io=0,so=1", "o"); + defOpS(SET_N, "o,n,io=0,so=1", "o", "o", ""); From 28f04ac17e77b8ca4095347595eefe82dffb728f Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 27 Nov 2018 18:13:24 +0000 Subject: [PATCH 052/333] feat(vectors): add project(), signedArea2(), update orthoNormal3() --- packages/vectors3/src/index.ts | 2 ++ packages/vectors3/src/ortho-normal.ts | 15 ++++++++++----- packages/vectors3/src/project.ts | 16 ++++++++++++++++ packages/vectors3/src/signed-area.ts | 22 ++++++++++++++++++++++ 4 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 packages/vectors3/src/project.ts create mode 100644 packages/vectors3/src/signed-area.ts diff --git a/packages/vectors3/src/index.ts b/packages/vectors3/src/index.ts index 38f42e4563..fb83dd37db 100644 --- a/packages/vectors3/src/index.ts +++ b/packages/vectors3/src/index.ts @@ -69,6 +69,7 @@ export * from "./perpendicular"; export * from "./polar"; export * from "./pow"; export * from "./pown"; +export * from "./project"; export * from "./random"; export * from "./reflect"; export * from "./refract"; @@ -81,6 +82,7 @@ export * from "./setn"; export * from "./sets"; export * from "./setsn"; export * from "./sign"; +export * from "./signed-area"; export * from "./sin"; export * from "./sinh"; export * from "./sqrt"; diff --git a/packages/vectors3/src/ortho-normal.ts b/packages/vectors3/src/ortho-normal.ts index 213e81f1cf..ee76c27976 100644 --- a/packages/vectors3/src/ortho-normal.ts +++ b/packages/vectors3/src/ortho-normal.ts @@ -1,10 +1,12 @@ -import { VecOpVVV } from "./api"; import { cross3 } from "./cross"; import { sub3 } from "./sub"; +import { normalize } from "./normalize"; +import { Vec, ReadonlyVec } from "./api"; /** * Produces a vector which is perpendicular/normal to the plane spanned - * by given 3 input vectors. + * by given 3 input vectors. If `normalize` is true (default), the + * result vector will be normalized. * * ``` * orthoNormal3([], [0,0,0], [1,0,0], [0,1,0]) @@ -15,7 +17,10 @@ import { sub3 } from "./sub"; * @param a * @param b * @param c + * @param normalize */ -export const orthoNormal3: VecOpVVV = - (out, a, b, c) => - cross3(out, sub3(out, b, a), sub3([], c, a)); +export const orthoNormal3 = + (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, doNormalize = true) => ( + cross3(out, sub3(out, b, a), sub3([], c, a)), + doNormalize ? normalize(out, out) : out + ); diff --git a/packages/vectors3/src/project.ts b/packages/vectors3/src/project.ts new file mode 100644 index 0000000000..183e654250 --- /dev/null +++ b/packages/vectors3/src/project.ts @@ -0,0 +1,16 @@ +import { ReadonlyVec, Vec } from "./api"; +import { dot } from "./dot"; +import { magSq } from "./magsq"; +import { mulN } from "./muln"; + +/** + * Returns vector projection of `v` onto `dir`. + * + * https://en.wikipedia.org/wiki/Vector_projection + * + * @param dir + * @param v + */ +export const project = + (out: Vec, dir: ReadonlyVec, v: ReadonlyVec) => + mulN(out, dir, dot(v, dir) / magSq(dir)); diff --git a/packages/vectors3/src/signed-area.ts b/packages/vectors3/src/signed-area.ts new file mode 100644 index 0000000000..4ea96d7d94 --- /dev/null +++ b/packages/vectors3/src/signed-area.ts @@ -0,0 +1,22 @@ +import { ReadonlyVec } from "./api"; + +/** + * Returns area*2 of the 2D triangle defined by the input vectors. This + * is a useful classifier for many geometry processing tasks. In + * addition to the triangle area, the result can also be interpreted as + * follows: + * + * - > 0: points are ordered anti-clockwise + * - < 0: points are ordered clockwise + * - 0: points are co-linear + * + * @param a + * @param b + * @param c + */ +export const signedArea2 = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => { + const ax = a[0]; + const ay = a[1]; + return (b[0] - ax) * (c[1] - ay) - (c[0] - ax) * (b[1] - ay); + }; From 27f65f9edf32dbf37bc8bbd4eb529324bd44e72d Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 27 Nov 2018 18:41:55 +0000 Subject: [PATCH 053/333] feat(matrices): add rotationAroundAxis33/44() --- packages/matrices/src/index.ts | 1 + packages/matrices/src/rotation-around-axis.ts | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 packages/matrices/src/rotation-around-axis.ts diff --git a/packages/matrices/src/index.ts b/packages/matrices/src/index.ts index cc5e11072d..4ff1f0a767 100644 --- a/packages/matrices/src/index.ts +++ b/packages/matrices/src/index.ts @@ -19,6 +19,7 @@ export * from "./normal-mat"; export * from "./ortho"; export * from "./perspective"; export * from "./project"; +export * from "./rotation-around-axis"; export * from "./rotation"; export * from "./row"; export * from "./scale"; diff --git a/packages/matrices/src/rotation-around-axis.ts b/packages/matrices/src/rotation-around-axis.ts new file mode 100644 index 0000000000..8da41b40e3 --- /dev/null +++ b/packages/matrices/src/rotation-around-axis.ts @@ -0,0 +1,27 @@ +import { ReadonlyVec } from "@thi.ng/vectors3/api"; +import { Mat } from "./api"; +import { mat33to44 } from "./convert"; +import { setValues33 } from "./set-values"; + +export const rotationAroundAxis33 = + (out: Mat, [x, y, z]: ReadonlyVec, theta: number) => { + const s = Math.sin(theta); + const c = Math.cos(theta); + const t = 1 - c; + return setValues33( + out, + x * x * t + c, + y * x * t + z * s, + z * x * t - y * s, + x * y * t - z * s, + y * y * t + c, + z * y * t + x * s, + x * z * t + y * s, + y * z * t - x * s, + z * z * t + c + ); + }; + +export const rotationAroundAxis44 = + (out: Mat, axis: ReadonlyVec, theta: number) => + mat33to44(out, rotationAroundAxis33([], axis, theta)); From 4a8295b739de77638fe3371065eb97cf0bf872dc Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 27 Nov 2018 23:27:13 +0000 Subject: [PATCH 054/333] feature(vectors): update swizzle*() to support in-place updates --- packages/vectors3/src/swizzle.ts | 33 +++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/packages/vectors3/src/swizzle.ts b/packages/vectors3/src/swizzle.ts index 47ac098acf..a71b75c463 100644 --- a/packages/vectors3/src/swizzle.ts +++ b/packages/vectors3/src/swizzle.ts @@ -1,9 +1,8 @@ import { ReadonlyVec, Vec, VecOpV } from "./api"; /** - * Places a re-ordered 2D version of vector `a` into `out`. MUST be - * separate instances. The given coord indices must be valid for `a`. - * No bounds checking. + * Places a re-ordered 2D version of vector `a` into `out`. The given + * coord indices must be valid for `a`. No bounds checking. * * @param out * @param a @@ -12,15 +11,15 @@ import { ReadonlyVec, Vec, VecOpV } from "./api"; */ export const swizzle2 = (out: Vec, a: ReadonlyVec, x: number, y: number) => ( - out[0] = a[x] || 0, + x = a[x] || 0, out[1] = a[y] || 0, + out[0] = x, out ); /** - * Places a re-ordered 3D version of vector `a` into `out`. MUST be - * separate instances. The given coord indices must be valid for `a`. - * No bounds checking. + * Places a re-ordered 3D version of vector `a` into `out`. The given + * coord indices must be valid for `a`. No bounds checking. * * @param out * @param a @@ -30,16 +29,17 @@ export const swizzle2 = */ export const swizzle3 = (out: Vec, a: ReadonlyVec, x: number, y: number, z: number) => ( - out[0] = a[x] || 0, - out[1] = a[y] || 0, + x = a[x] || 0, + y = a[y] || 0, out[2] = a[z] || 0, + out[1] = y, + out[0] = x, out ); /** - * Places a re-ordered 4D version of vector `a` into `out`. MUST be - * separate instances. The given coord indices must be valid for `a`. - * No bounds checking. + * Places a re-ordered 4D version of vector `a` into `out`. The given + * coord indices must be valid for `a`. No bounds checking. * * @param out * @param a @@ -50,10 +50,13 @@ export const swizzle3 = */ export const swizzle4 = (out: Vec, a: ReadonlyVec, x: number, y: number, z: number, w: number) => ( - out[0] = a[x] || 0, - out[1] = a[y] || 0, - out[2] = a[z] || 0, + x = a[x] || 0, + y = a[y] || 0, + z = a[z] || 0, out[3] = a[w] || 0, + out[2] = z, + out[1] = y, + out[0] = x, out ); From c3d1914139758a380eef0924e31a4fd08df4e3c2 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 27 Nov 2018 23:28:04 +0000 Subject: [PATCH 055/333] feat(vectors): add Vec2/3/4.iterator() --- packages/vectors3/src/vec2.ts | 13 ++++++++++--- packages/vectors3/src/vec3.ts | 7 +++++++ packages/vectors3/src/vec4.ts | 7 +++++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/packages/vectors3/src/vec2.ts b/packages/vectors3/src/vec2.ts index b9536a5500..4d055f2482 100644 --- a/packages/vectors3/src/vec2.ts +++ b/packages/vectors3/src/vec2.ts @@ -27,14 +27,14 @@ export class Vec2 extends AVec implements * interleaved etc. * * @param buf backing array - * @param n num vectors + * @param num num vectors * @param start start index * @param cstride component stride * @param estride element stride */ - static mapBuffer(buf: Vec, n: number = buf.length >> 1, start = 0, cstride = 1, estride = 2) { + static mapBuffer(buf: Vec, num: number = buf.length >> 1, start = 0, cstride = 1, estride = 2) { const res: Vec2[] = []; - while (--n >= 0) { + while (--num >= 0) { res.push(new Vec2(buf, start, cstride)); start += estride; } @@ -64,6 +64,13 @@ export class Vec2 extends AVec implements return buf; } + static *iterator(buf: Vec, num: number, start = 0, cstride = 1, estride = 2) { + while (num-- > 0) { + yield new Vec2(buf, start, cstride); + start += estride; + } + } + static readonly X_AXIS = new Vec2(X4); static readonly Y_AXIS = new Vec2(Y4); static readonly Z_AXIS = new Vec2(Z4); diff --git a/packages/vectors3/src/vec3.ts b/packages/vectors3/src/vec3.ts index 976dcf47f6..c494a54bd0 100644 --- a/packages/vectors3/src/vec3.ts +++ b/packages/vectors3/src/vec3.ts @@ -65,6 +65,13 @@ export class Vec3 extends AVec implements return buf; } + static *iterator(buf: Vec, num: number, start = 0, cstride = 1, estride = 3) { + while (num-- > 0) { + yield new Vec3(buf, start, cstride); + start += estride; + } + } + static readonly X_AXIS = new Vec3(X4); static readonly Y_AXIS = new Vec3(Y4); static readonly Z_AXIS = new Vec3(Z4); diff --git a/packages/vectors3/src/vec4.ts b/packages/vectors3/src/vec4.ts index de25de57ea..0f12f2f89a 100644 --- a/packages/vectors3/src/vec4.ts +++ b/packages/vectors3/src/vec4.ts @@ -66,6 +66,13 @@ export class Vec4 extends AVec implements return buf; } + static *iterator(buf: Vec, num: number, start = 0, cstride = 1, estride = 4) { + while (num-- > 0) { + yield new Vec4(buf, start, cstride); + start += estride; + } + } + static readonly X_AXIS = new Vec4(X4); static readonly Y_AXIS = new Vec4(Y4); static readonly Z_AXIS = new Vec4(Z4); From 1fe9650d5303a40db5a9485dcbbabfa49eb9c03c Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 27 Nov 2018 23:28:38 +0000 Subject: [PATCH 056/333] feat(vectors): add mapBuffer*() fns --- packages/vectors3/src/index.ts | 1 + packages/vectors3/src/map.ts | 176 +++++++++++++++++++++++++++++++++ 2 files changed, 177 insertions(+) create mode 100644 packages/vectors3/src/map.ts diff --git a/packages/vectors3/src/index.ts b/packages/vectors3/src/index.ts index fb83dd37db..3d5d88a0ba 100644 --- a/packages/vectors3/src/index.ts +++ b/packages/vectors3/src/index.ts @@ -51,6 +51,7 @@ export * from "./maddn"; export * from "./mag"; export * from "./magsq"; export * from "./major"; +export * from "./map"; export * from "./max"; export * from "./min"; export * from "./minor"; diff --git a/packages/vectors3/src/map.ts b/packages/vectors3/src/map.ts new file mode 100644 index 0000000000..0d871eeffb --- /dev/null +++ b/packages/vectors3/src/map.ts @@ -0,0 +1,176 @@ +import { IVector, VecOpV, VecOpVV, VecOpVN, VecOpVVV, VecOpVVN } from "./api"; + +/** + * Like `mapBufferVV`, but for `VecOpV` type ops and hence only using + * single input. + * + * ``` + * // 4x 2D vectors in SOA layout, i.e. [x1,x2,x3,x4,y1,y2,y3,y4] + * buf = [1,3,5,7,2,4,6,8]; + * + * // use `swapXY` to swizzle each vector and use AOS for output + * res = mapBufferV(swapXY, new Vec2(), new Vec2(buf,0,4), 4, 2, 1); + * // [ 2, 1, 4, 3, 6, 5, 8, 7 ] + * + * // unpack result for demonstration purposes + * [...Vec2.iterator(res, 4)].map(v => [...v]); + * // [ [ 2, 1 ], [ 4, 3 ], [ 6, 5 ], [ 8, 7 ] ] + * ``` + * + * @param op + * @param out + * @param a + * @param num + * @param so + * @param sa + */ +export const mapBufferV = ( + op: VecOpV, + out: IVector, + a: IVector, + num: number, + so = out.length * out.s, + sa = a.length * a.s) => { + + while (num-- > 0) { + op(out, a); + out.i += so; + a.i += sa; + } + return out.buf; +}; + +/** + * Like `mapBufferVV`, but for `VecOpVN` type ops and hence using + * a single vector input buffer `a` and a scalar `n`. + * + * @param op + * @param out + * @param a + * @param n + * @param num + * @param so + * @param sa + */ +export const mapBufferVN = ( + op: VecOpVN, + out: IVector, + a: IVector, + n: number, + num: number, + so = out.length * out.s, + sa = a.length * a.s) => { + + while (num-- > 0) { + op(out, a, n); + out.i += so; + a.i += sa; + } + return out.buf; +}; + +/** + * Vec2/3/4 view based buffer transformation for `VecOpVV` type ops and + * supporting arbitrary component and element layouts of all input and + * output buffers. The given pre-initialized vectors MUST be separate + * instances, are used as sliding cursors / views of their respective + * backing buffers and will be modified as part of the transformation + * process (though the input buffers themselves are treated as + * immutable, unless `out` is configured to use one of the input + * buffers). + * + * In each iteration `op` is called via `op(out, a, b)`, followed by + * cursor updates to process the next vector. No bounds checking is + * performed. + * + * This function returns `out`'s backing buffer. + * + * ``` + * // each input buffer contains 2 2D vectors, but using + * // different strided data layouts + * mapBufferVV( + * // transformation function + * add, + * // init output buffer view + * new Vec2(), + * // wrap 1st input buffer & configure offset & component stride + * new Vec2([1,0,2,0,0,0,0,0,3,0,4,0,0,0,0,0], 0, 2), + * // wrap 2nd input buffer + * new Vec2([0,10,0,0,20,0,0,30,0,0,40], 1, 3), + * 2, // num vectors + * 2, // output element stride + * 8, // input #1 element stride + * 6 // input #2 element stride + * ); + * // [ 11, 22, 33, 44 ] + * ``` + * + * @param op + * @param out + * @param a + * @param b + * @param num + * @param so + * @param sa + * @param sb + */ +export const mapBufferVV = ( + op: VecOpVV, + out: IVector, + a: IVector, + b: IVector, + num: number, + so = out.length * out.s, + sa = a.length * a.s, + sb = b.length * b.s) => { + + while (num-- > 0) { + op(out, a, b); + out.i += so; + a.i += sa; + b.i += sb; + } + return out.buf; +}; + +export const mapBufferVVV = ( + op: VecOpVVV, + out: IVector, + a: IVector, + b: IVector, + c: IVector, + num: number, + so = out.length * out.s, + sa = a.length * a.s, + sb = b.length * b.s, + sc = c.length * c.s) => { + + while (num-- > 0) { + op(out, a, b, c); + out.i += so; + a.i += sa; + b.i += sb; + c.i += sc; + } + return out.buf; +}; + +export const mapBufferVVN = ( + op: VecOpVVN, + out: IVector, + a: IVector, + b: IVector, + n: number, + num: number, + so = out.length * out.s, + sa = a.length * a.s, + sb = b.length * b.s) => { + + while (num-- > 0) { + op(out, a, b, n); + out.i += so; + a.i += sa; + b.i += sb; + } + return out.buf; +}; From 63458c2c5bacb633daee4e9a2a96723ee7f224cd Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 28 Nov 2018 11:41:53 +0000 Subject: [PATCH 057/333] feat(vectors): add proxied gvec(), update mapBuffer*() docs --- packages/vectors3/src/gvec.ts | 99 +++++++++++++++++++++ packages/vectors3/src/index.ts | 1 + packages/vectors3/src/map.ts | 152 +++++++++++++++++++-------------- 3 files changed, 188 insertions(+), 64 deletions(-) create mode 100644 packages/vectors3/src/gvec.ts diff --git a/packages/vectors3/src/gvec.ts b/packages/vectors3/src/gvec.ts new file mode 100644 index 0000000000..9a0ec00ff6 --- /dev/null +++ b/packages/vectors3/src/gvec.ts @@ -0,0 +1,99 @@ +import { range } from "@thi.ng/transducers/iter/range"; +import { map } from "@thi.ng/transducers/xform/map"; +import { Vec } from "./api"; + +/** + * Wrapper for strided, arbitrary length vectors. Wraps given buffer in + * ES6 `Proxy` with custom property getters/setters and implements ES6 + * `Iterable` interface. Furthermore, exposes read/write access to + * `IVector` properties: + * + * - `i` - start index + * - `s` - component stride + * - `buf` - backing buffer (readonly) + * - `length` - vector size + * + * Array index access uses bounds checking against [0..`size`) interval, + * but, for performance reasons, **not** against the actual wrapped + * buffer. + * + * Note: ES6 Proxy use is approx. 10x slower than standard array + * accesses. If several computations are to be performed on such vectors + * it will be much more efficient to first copy them to compact arrays + * and then copy result back if needed. + * + * ``` + * // 3D vector w/ stride length of 4 + * a = gvec([1,0,0,0,2,0,0,0,3,0,0,0], 3, 0, 4); + * a[0] // 1 + * a[1] // 2 + * a[2] // 3 + * + * [...a] + * // [1, 2, 3] + * + * add([], a, a) + * // [2, 4, 6] + * + * add() + * ``` + * + * @param buf + * @param size + * @param i + * @param s + */ +export const gvec = (buf: Vec, size: number, i = 0, s = 1) => + new Proxy(buf, { + get: (obj, id) => { + switch (id) { + case Symbol.iterator: + return function* () { + for (let j = 0, ii = i, ss = s; j < size; j++) { + yield obj[ii + j * ss]; + } + }; + case "length": + return size; + case "buf": + return buf; + case "i": + return i; + case "s": + return s; + default: + let j = parseInt(id); + return !isNaN(j) && j >= 0 && j < size ? + obj[i + j * s] : + undefined; + } + }, + set: (obj, id, value) => { + const j = parseInt(id); + if (!isNaN(j) && j >= 0 && j < size) { + obj[i + (id | 0) * s] = value; + } else { + switch (id) { + case "i": + i = value; + break; + case "s": + s = value; + break; + case "length": + size = value; + break; + default: + return false; + } + } + return true + }, + has: (_, id) => + (id >= 0 && id < size) || + id === "i" || + id == "s" || + id == "length", + ownKeys: () => + [...map(String, range(size)), "i", "s", "length"], + }); diff --git a/packages/vectors3/src/index.ts b/packages/vectors3/src/index.ts index 3d5d88a0ba..39e8e5372c 100644 --- a/packages/vectors3/src/index.ts +++ b/packages/vectors3/src/index.ts @@ -39,6 +39,7 @@ export * from "./exp"; export * from "./face-forward"; export * from "./floor"; export * from "./fract"; +export * from "./gvec"; export * from "./heading"; export * from "./homogeneous"; export * from "./invert"; diff --git a/packages/vectors3/src/map.ts b/packages/vectors3/src/map.ts index 0d871eeffb..dee9c78814 100644 --- a/packages/vectors3/src/map.ts +++ b/packages/vectors3/src/map.ts @@ -1,68 +1,127 @@ import { IVector, VecOpV, VecOpVV, VecOpVN, VecOpVVV, VecOpVVN } from "./api"; /** - * Like `mapBufferVV`, but for `VecOpV` type ops and hence only using - * single input. + * Vec2/3/4 view based buffer transformation for `VecOpVV` type ops and + * supporting arbitrary component and element layouts of all input and + * output buffers. The given pre-initialized vectors MUST be separate + * instances, are used as sliding cursors / views of their respective + * backing buffers and will be modified as part of the transformation + * process (though the input buffers themselves are treated as + * immutable, unless `out` is configured to use one of the input + * buffers). + * + * In each iteration `op` is called via `op(out, a, b)`, followed by + * cursor updates to process the next vector. No bounds checking is + * performed. + * + * This function returns `out`'s backing buffer. * * ``` - * // 4x 2D vectors in SOA layout, i.e. [x1,x2,x3,x4,y1,y2,y3,y4] - * buf = [1,3,5,7,2,4,6,8]; + * // each input buffer contains 2 2D vectors, but using + * // different strided data layouts + * mapBufferVV( + * // transformation function + * add, + * // init output buffer view + * new Vec2(), + * // wrap 1st input buffer & configure offset & component stride + * new Vec2([1,0,2,0,0,0,0,0,3,0,4,0,0,0,0,0], 0, 2), + * // wrap 2nd input buffer + * new Vec2([0,10,0,0,20,0,0,30,0,0,40], 1, 3), + * 2, // num vectors + * 2, // output element stride + * 8, // input #1 element stride + * 6 // input #2 element stride + * ); + * // [ 11, 22, 33, 44 ] + * ``` * - * // use `swapXY` to swizzle each vector and use AOS for output - * res = mapBufferV(swapXY, new Vec2(), new Vec2(buf,0,4), 4, 2, 1); - * // [ 2, 1, 4, 3, 6, 5, 8, 7 ] + * `Vec2/3/4.iterator()` combined with transducers can be used to + * achieve the same (and more flexible) transformations, but will incur + * more intermediate object allocations. `mapBuffer*()` functions only + * use (and mutate) the provided vector instances and do not allocate + * any further objects. * - * // unpack result for demonstration purposes - * [...Vec2.iterator(res, 4)].map(v => [...v]); - * // [ [ 2, 1 ], [ 4, 3 ], [ 6, 5 ], [ 8, 7 ] ] + * ``` + * // output buffer + * const out = new Array(4); + * + * tx.run( + * tx.map(([o, a, b]) => add(o, a, b)), + * tx.tuples( + * Vec2.iterator(out, 2), + * Vec2.iterator([1,0,2,0,0,0,0,0,3,0,4,0,0,0,0,0], 2, 0, 2, 8), + * Vec2.iterator([0,10,0,0,20,0,0,30,0,0,40], 2, 1, 3, 6), + * ) + * ); + * + * out + * // [ 11, 22, 33, 44 ] * ``` * * @param op * @param out * @param a + * @param b * @param num * @param so * @param sa + * @param sb */ -export const mapBufferV = ( - op: VecOpV, +export const mapBufferVV = ( + op: VecOpVV, out: IVector, a: IVector, + b: IVector, num: number, so = out.length * out.s, - sa = a.length * a.s) => { + sa = a.length * a.s, + sb = b.length * b.s) => { while (num-- > 0) { - op(out, a); + op(out, a, b); out.i += so; a.i += sa; + b.i += sb; } return out.buf; }; /** - * Like `mapBufferVV`, but for `VecOpVN` type ops and hence using - * a single vector input buffer `a` and a scalar `n`. + * Like `mapBufferVV`, but for `VecOpV` type ops and hence only using + * single input. + * + * ``` + * // 4x 2D vectors in SOA layout + * // i.e. [x1, x2, x3, x4, y1, y2, y3, y4] + * buf = [1, 3, 5, 7, 2, 4, 6, 8]; + * + * // use `swapXY` to swizzle each vector and use AOS for output + * res = mapBufferV(swapXY, new Vec2(), new Vec2(buf, 0, 4), 4, 2, 1); + * // [ 2, 1, 4, 3, 6, 5, 8, 7 ] + * + * // unpack result for demonstration purposes + * [...Vec2.iterator(res, 4)].map(v => [...v]); + * // [ [ 2, 1 ], [ 4, 3 ], [ 6, 5 ], [ 8, 7 ] ] + * ``` * * @param op * @param out * @param a - * @param n * @param num * @param so * @param sa */ -export const mapBufferVN = ( - op: VecOpVN, +export const mapBufferV = ( + op: VecOpV, out: IVector, a: IVector, - n: number, num: number, so = out.length * out.s, sa = a.length * a.s) => { while (num-- > 0) { - op(out, a, n); + op(out, a); out.i += so; a.i += sa; } @@ -70,65 +129,30 @@ export const mapBufferVN = ( }; /** - * Vec2/3/4 view based buffer transformation for `VecOpVV` type ops and - * supporting arbitrary component and element layouts of all input and - * output buffers. The given pre-initialized vectors MUST be separate - * instances, are used as sliding cursors / views of their respective - * backing buffers and will be modified as part of the transformation - * process (though the input buffers themselves are treated as - * immutable, unless `out` is configured to use one of the input - * buffers). - * - * In each iteration `op` is called via `op(out, a, b)`, followed by - * cursor updates to process the next vector. No bounds checking is - * performed. - * - * This function returns `out`'s backing buffer. - * - * ``` - * // each input buffer contains 2 2D vectors, but using - * // different strided data layouts - * mapBufferVV( - * // transformation function - * add, - * // init output buffer view - * new Vec2(), - * // wrap 1st input buffer & configure offset & component stride - * new Vec2([1,0,2,0,0,0,0,0,3,0,4,0,0,0,0,0], 0, 2), - * // wrap 2nd input buffer - * new Vec2([0,10,0,0,20,0,0,30,0,0,40], 1, 3), - * 2, // num vectors - * 2, // output element stride - * 8, // input #1 element stride - * 6 // input #2 element stride - * ); - * // [ 11, 22, 33, 44 ] - * ``` + * Like `mapBufferVV`, but for `VecOpVN` type ops and hence using + * a single vector input buffer `a` and a scalar `n`. * * @param op * @param out * @param a - * @param b + * @param n * @param num * @param so * @param sa - * @param sb */ -export const mapBufferVV = ( - op: VecOpVV, +export const mapBufferVN = ( + op: VecOpVN, out: IVector, a: IVector, - b: IVector, + n: number, num: number, so = out.length * out.s, - sa = a.length * a.s, - sb = b.length * b.s) => { + sa = a.length * a.s) => { while (num-- > 0) { - op(out, a, b); + op(out, a, n); out.i += so; a.i += sa; - b.i += sb; } return out.buf; }; From 6cb3b92bf7d5b9f20ff7b9c12eef512f272b5d99 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 28 Nov 2018 17:31:55 +0000 Subject: [PATCH 058/333] feat(vectors): add IVector interface impls for gvec() --- packages/vectors3/src/api.ts | 7 ++++++- packages/vectors3/src/gvec.ts | 33 ++++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/packages/vectors3/src/api.ts b/packages/vectors3/src/api.ts index 76343d1581..9e38ad36f0 100644 --- a/packages/vectors3/src/api.ts +++ b/packages/vectors3/src/api.ts @@ -1,4 +1,9 @@ -import { ILength, ICopy, IEmpty, IEqualsDelta } from "@thi.ng/api/api"; +import { + ICopy, + IEmpty, + IEqualsDelta, + ILength, +} from "@thi.ng/api/api"; export interface Vec extends Iterable, diff --git a/packages/vectors3/src/gvec.ts b/packages/vectors3/src/gvec.ts index 9a0ec00ff6..a2160fc192 100644 --- a/packages/vectors3/src/gvec.ts +++ b/packages/vectors3/src/gvec.ts @@ -1,21 +1,24 @@ import { range } from "@thi.ng/transducers/iter/range"; import { map } from "@thi.ng/transducers/xform/map"; -import { Vec } from "./api"; +import { Vec, IVector } from "./api"; +import { zeroes } from "./setn"; +import { eqDeltaS } from "./eqdelta"; +import { EPS } from "@thi.ng/math/api"; /** * Wrapper for strided, arbitrary length vectors. Wraps given buffer in - * ES6 `Proxy` with custom property getters/setters and implements ES6 - * `Iterable` interface. Furthermore, exposes read/write access to - * `IVector` properties: + * ES6 `Proxy` with custom property getters/setters and implements the + * ES6 `Iterable` interface and this libraries `IVector` methods and + * read/write access of the following properties: * * - `i` - start index * - `s` - component stride * - `buf` - backing buffer (readonly) * - `length` - vector size * - * Array index access uses bounds checking against [0..`size`) interval, - * but, for performance reasons, **not** against the actual wrapped - * buffer. + * Array index access uses bounds checking against the [0..`size`) + * interval, but, for performance reasons, **not** against the actual + * wrapped buffer. * * Note: ES6 Proxy use is approx. 10x slower than standard array * accesses. If several computations are to be performed on such vectors @@ -43,8 +46,8 @@ import { Vec } from "./api"; * @param i * @param s */ -export const gvec = (buf: Vec, size: number, i = 0, s = 1) => - new Proxy(buf, { +export const gvec = (buf: Vec, size: number, i = 0, s = 1): IVector => + new Proxy(buf, { get: (obj, id) => { switch (id) { case Symbol.iterator: @@ -61,6 +64,18 @@ export const gvec = (buf: Vec, size: number, i = 0, s = 1) => return i; case "s": return s; + case "copy": + return function () { + const res = []; + for (let j = 0; j < size; j++) { + res[j] = obj[i + j * s]; + } + return res; + }; + case "empty": + return () => zeroes(size); + case "eqDelta": + return (o, eps = EPS) => eqDeltaS(buf, o, size, eps, i, 0, s, 1); default: let j = parseInt(id); return !isNaN(j) && j >= 0 && j < size ? From ea6bafaf8224d5f7cac961367552a87d8d5ee7a7 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 28 Nov 2018 17:33:12 +0000 Subject: [PATCH 059/333] feat(malloc): expose SIZEOF, add wrap() --- packages/malloc/src/api.ts | 15 +++++++++++++++ packages/malloc/src/index.ts | 1 + packages/malloc/src/pool.ts | 35 +++++------------------------------ packages/malloc/src/wrap.ts | 18 ++++++++++++++++++ 4 files changed, 39 insertions(+), 30 deletions(-) create mode 100644 packages/malloc/src/wrap.ts diff --git a/packages/malloc/src/api.ts b/packages/malloc/src/api.ts index b3a8c7ff83..5dd3de270d 100644 --- a/packages/malloc/src/api.ts +++ b/packages/malloc/src/api.ts @@ -12,6 +12,18 @@ export const enum Type { F64 }; +export const SIZEOF = { + [Type.U8]: 1, + [Type.U8C]: 1, + [Type.I8]: 1, + [Type.U16]: 2, + [Type.I16]: 2, + [Type.U32]: 4, + [Type.I32]: 4, + [Type.F32]: 4, + [Type.F64]: 8, +}; + export interface MemBlock { addr: number; size: number; @@ -64,3 +76,6 @@ export interface IMemPool extends IRelease { stats(): MemPoolStats; } + +export type BlockCtor = + (buf: ArrayBuffer, addr: number, num: number) => TypedArray; diff --git a/packages/malloc/src/index.ts b/packages/malloc/src/index.ts index 73537bab37..3d894796d0 100644 --- a/packages/malloc/src/index.ts +++ b/packages/malloc/src/index.ts @@ -1,2 +1,3 @@ export * from "./api"; export * from "./pool"; +export * from "./wrap"; diff --git a/packages/malloc/src/pool.ts b/packages/malloc/src/pool.ts index 79e49c6e6c..7d506abe88 100644 --- a/packages/malloc/src/pool.ts +++ b/packages/malloc/src/pool.ts @@ -1,4 +1,4 @@ -import { IObjectOf, TypedArray } from "@thi.ng/api"; +import { TypedArray } from "@thi.ng/api"; import { align } from "@thi.ng/binary/align"; import { isNumber } from "@thi.ng/checks/is-number"; import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; @@ -6,36 +6,11 @@ import { IMemPool, MemBlock, MemPoolOpts, + MemPoolStats, + SIZEOF, Type, - MemPoolStats } from "./api"; - -type BlockCtor = - (buf: ArrayBuffer, addr: number, num: number) => TypedArray; - -const CTORS: IObjectOf = { - [Type.U8]: (buf, addr, num) => new Uint8Array(buf, addr, num), - [Type.U8C]: (buf, addr, num) => new Uint8ClampedArray(buf, addr, num), - [Type.I8]: (buf, addr, num) => new Int8Array(buf, addr, num), - [Type.U16]: (buf, addr, num) => new Uint16Array(buf, addr, num), - [Type.I16]: (buf, addr, num) => new Int16Array(buf, addr, num), - [Type.U32]: (buf, addr, num) => new Uint32Array(buf, addr, num), - [Type.I32]: (buf, addr, num) => new Int32Array(buf, addr, num), - [Type.F32]: (buf, addr, num) => new Float32Array(buf, addr, num), - [Type.F64]: (buf, addr, num) => new Float64Array(buf, addr, num), -}; - -const SIZEOF = { - [Type.U8]: 1, - [Type.U8C]: 1, - [Type.I8]: 1, - [Type.U16]: 2, - [Type.I16]: 2, - [Type.U32]: 4, - [Type.I32]: 4, - [Type.F32]: 4, - [Type.F64]: 8, -}; +import { wrap } from "./wrap"; export class MemPool implements IMemPool { @@ -102,7 +77,7 @@ export class MemPool implements mallocAs(type: Type, num: number): TypedArray { const addr = this.malloc(num * SIZEOF[type]); return addr ? - CTORS[type](this.buf, addr, num) : + wrap(type, this.buf, addr, num) : null; } diff --git a/packages/malloc/src/wrap.ts b/packages/malloc/src/wrap.ts new file mode 100644 index 0000000000..f0330275bb --- /dev/null +++ b/packages/malloc/src/wrap.ts @@ -0,0 +1,18 @@ +import { BlockCtor, Type } from "./api"; +import { IObjectOf } from "@thi.ng/api/api"; + +const CTORS: IObjectOf = { + [Type.U8]: (buf, addr, num) => new Uint8Array(buf, addr, num), + [Type.U8C]: (buf, addr, num) => new Uint8ClampedArray(buf, addr, num), + [Type.I8]: (buf, addr, num) => new Int8Array(buf, addr, num), + [Type.U16]: (buf, addr, num) => new Uint16Array(buf, addr, num), + [Type.I16]: (buf, addr, num) => new Int16Array(buf, addr, num), + [Type.U32]: (buf, addr, num) => new Uint32Array(buf, addr, num), + [Type.I32]: (buf, addr, num) => new Int32Array(buf, addr, num), + [Type.F32]: (buf, addr, num) => new Float32Array(buf, addr, num), + [Type.F64]: (buf, addr, num) => new Float64Array(buf, addr, num), +}; + +export const wrap = + (type: Type, buf: ArrayBuffer, addr: number, num: number) => + CTORS[type](buf, addr, num); \ No newline at end of file From 48d5d572354a9431cdeca00d9f52279899ba62f4 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 28 Nov 2018 17:38:53 +0000 Subject: [PATCH 060/333] feat(vector-pools): add VecPool, VecArrayList & VecLinkedList --- packages/vector-pools/.npmignore | 11 ++ packages/vector-pools/LICENSE | 201 +++++++++++++++++++++++ packages/vector-pools/README.md | 47 ++++++ packages/vector-pools/package.json | 42 +++++ packages/vector-pools/src/alist.ts | 75 +++++++++ packages/vector-pools/src/api.ts | 21 +++ packages/vector-pools/src/array-list.ts | 64 ++++++++ packages/vector-pools/src/index.ts | 0 packages/vector-pools/src/linked-list.ts | 155 +++++++++++++++++ packages/vector-pools/src/pool.ts | 91 ++++++++++ packages/vector-pools/src/wrap.ts | 19 +++ packages/vector-pools/test/index.ts | 6 + packages/vector-pools/test/tsconfig.json | 10 ++ packages/vector-pools/tsconfig.json | 9 + 14 files changed, 751 insertions(+) create mode 100644 packages/vector-pools/.npmignore create mode 100644 packages/vector-pools/LICENSE create mode 100644 packages/vector-pools/README.md create mode 100644 packages/vector-pools/package.json create mode 100644 packages/vector-pools/src/alist.ts create mode 100644 packages/vector-pools/src/api.ts create mode 100644 packages/vector-pools/src/array-list.ts create mode 100644 packages/vector-pools/src/index.ts create mode 100644 packages/vector-pools/src/linked-list.ts create mode 100644 packages/vector-pools/src/pool.ts create mode 100644 packages/vector-pools/src/wrap.ts create mode 100644 packages/vector-pools/test/index.ts create mode 100644 packages/vector-pools/test/tsconfig.json create mode 100644 packages/vector-pools/tsconfig.json diff --git a/packages/vector-pools/.npmignore b/packages/vector-pools/.npmignore new file mode 100644 index 0000000000..ec83d74c9d --- /dev/null +++ b/packages/vector-pools/.npmignore @@ -0,0 +1,11 @@ +build +coverage +dev +doc +export +src* +test +.nyc_output +tsconfig.json +*.tgz +*.html diff --git a/packages/vector-pools/LICENSE b/packages/vector-pools/LICENSE new file mode 100644 index 0000000000..8dada3edaf --- /dev/null +++ b/packages/vector-pools/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/vector-pools/README.md b/packages/vector-pools/README.md new file mode 100644 index 0000000000..abd92336b2 --- /dev/null +++ b/packages/vector-pools/README.md @@ -0,0 +1,47 @@ +# @thi.ng/vector-pools + +[![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/vector-pools.svg)](https://www.npmjs.com/package/@thi.ng/vector-pools) +![npm downloads](https://img.shields.io/npm/dm/@thi.ng/vector-pools.svg) +[![Twitter Follow](https://img.shields.io/twitter/follow/thing_umbrella.svg?style=flat-square&label=twitter)](https://twitter.com/thing_umbrella) + +This project is part of the +[@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo. + + + +- [About](#about) +- [Installation](#installation) +- [Dependencies](#dependencies) +- [Usage examples](#usage-examples) +- [Authors](#authors) +- [License](#license) + + + +## About + +TODO... + +## Installation + +```bash +yarn add @thi.ng/vector-pools +``` + +## Dependencies + +- TODO... + +## Usage examples + +```ts +import * as vp from "@thi.ng/vector-pools"; +``` + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/packages/vector-pools/package.json b/packages/vector-pools/package.json new file mode 100644 index 0000000000..71edf5da38 --- /dev/null +++ b/packages/vector-pools/package.json @@ -0,0 +1,42 @@ +{ + "name": "@thi.ng/vector-pools", + "version": "0.0.1", + "description": "TODO", + "main": "./index.js", + "typings": "./index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/thi-ng/umbrella.git" + }, + "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/vector-pool", + "author": "Karsten Schmidt ", + "license": "Apache-2.0", + "scripts": { + "build": "yarn run clean && tsc --declaration", + "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "cover": "yarn test && nyc report --reporter=lcov", + "doc": "node_modules/.bin/typedoc --mode modules --out doc src", + "pub": "yarn run build && yarn publish --access public", + "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + }, + "devDependencies": { + "@types/mocha": "^5.2.5", + "@types/node": "^10.12.0", + "mocha": "^5.2.0", + "nyc": "^13.1.0", + "typedoc": "^0.13.0", + "typescript": "^3.1.3" + }, + "dependencies": { + "@thi.ng/api": "^4.2.3", + "@thi.ng/malloc": "^0.2.0", + "@thi.ng/vectors3": "^0.0.1" + }, + "keywords": [ + "ES6", + "typescript" + ], + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/packages/vector-pools/src/alist.ts b/packages/vector-pools/src/alist.ts new file mode 100644 index 0000000000..44b6e5796e --- /dev/null +++ b/packages/vector-pools/src/alist.ts @@ -0,0 +1,75 @@ +import { IVector, Vec } from "@thi.ng/vectors3/api"; +import { wrap } from "./wrap"; +import { VecFactory } from "./api"; + +export abstract class AVecList> { + + buffer: Vec; + factory: VecFactory; + + start: number; + capacity: number; + curr: number; + size: number; + estride: number; + cstride: number; + + _free: T[]; + + constructor( + buffer: Vec, + capacity: number, + size: number, + factory: VecFactory = wrap, + cstride = 1, + estride = size, + start = 0) { + + this.buffer = buffer; + this.size = size; + this.factory = factory; + this.cstride = cstride; + this.estride = estride; + this.start = this.curr = start; + this.capacity = capacity; + this._free = []; + } + + abstract [Symbol.iterator](): IterableIterator; + + abstract get length(): number; + + abstract add(): T; + + abstract insert(i: number): T; + + abstract remove(v: T): boolean; + + indices(res: Vec = [], i = 0, local = true) { + const start = this.start; + const estride = this.estride; + if (local) { + for (let v of this) { + res[i++] = (v.i - start) / estride; + } + } else { + for (let v of this) { + res[i++] = v.i; + } + } + return res; + } + + protected alloc() { + let v: T; + if (this._free.length > 0) { + v = this._free.pop(); + } else { + if (this.length < this.capacity) { + v = this.factory(this.buffer, this.size, this.curr, this.cstride); + this.curr += this.estride; + } + } + return v; + } +} diff --git a/packages/vector-pools/src/api.ts b/packages/vector-pools/src/api.ts new file mode 100644 index 0000000000..24a43c120b --- /dev/null +++ b/packages/vector-pools/src/api.ts @@ -0,0 +1,21 @@ +import { IRelease, TypedArray } from "@thi.ng/api/api"; +import { Type } from "@thi.ng/malloc/api"; +import { IVector, Vec } from "@thi.ng/vectors3/api"; + +export interface IVecPool extends IRelease { + + malloc(size: number, type?: Type): TypedArray; + + mallocWrapped(size: number, stride?: number, type?: Type): IVector; + + mallocArray(num: number, size: number, cstride?: number, estride?: number, type?: Type): IVector[]; + + free(vec: IVector | TypedArray): boolean; + + freeAll(); +} + +export type VecFactory = + (buf: Vec, size: number, index: number, stride: number) => IVector; + +export { Type }; diff --git a/packages/vector-pools/src/array-list.ts b/packages/vector-pools/src/array-list.ts new file mode 100644 index 0000000000..9c24347fe8 --- /dev/null +++ b/packages/vector-pools/src/array-list.ts @@ -0,0 +1,64 @@ +import { IVector, Vec } from "@thi.ng/vectors3/api"; +import { AVecList } from "./alist"; +import { VecFactory } from "./api"; + +export class VecArrayList> extends AVecList { + + items: T[]; + + /** + * + * @param buffer + * @param capacity + * @param size + * @param cstride + * @param estride + * @param start + */ + constructor( + buffer: Vec, + capacity: number, + size: number, + factory?: VecFactory, + cstride = 1, + estride = size, + start = 0) { + + super(buffer, capacity, size, factory, cstride, estride, start); + this.items = []; + } + + *[Symbol.iterator]() { + yield* this.items; + } + + get length() { + return this.items.length; + } + + add() { + const v: T = this.alloc(); + if (v) { + this.items.push(v); + } + return v; + } + + insert(i: number) { + if (!this.length && i !== 0) return; + const v: T = this.alloc(); + if (v) { + this.items.splice(i, 0, v); + } + return v; + } + + remove(v: T) { + const idx = this.items.indexOf(v); + if (idx >= 0) { + this._free.push(v); + this.items.splice(idx, 1); + return true; + } + } +} diff --git a/packages/vector-pools/src/index.ts b/packages/vector-pools/src/index.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/vector-pools/src/linked-list.ts b/packages/vector-pools/src/linked-list.ts new file mode 100644 index 0000000000..762aae9e4b --- /dev/null +++ b/packages/vector-pools/src/linked-list.ts @@ -0,0 +1,155 @@ +import { IVector, Vec } from "@thi.ng/vectors3/api"; +import { AVecList } from "./alist"; +import { VecFactory } from "./api"; + +export class VecLinkedList> extends AVecList { + + head: T; + tail: T; + closed: boolean; + + protected _length: number; + + /** + * + * @param closed + * @param buffer + * @param capacity + * @param size + * @param factory + * @param cstride + * @param estride + * @param start + */ + constructor( + closed: boolean, + buffer: Vec, + capacity: number, + size: number, + factory?: VecFactory, + cstride = 1, + estride = size, + start = 0) { + + super(buffer, capacity, size, factory, cstride, estride, start); + this.closed = closed; + this.head = null; + this.tail = null; + this._length = 0; + } + + *[Symbol.iterator]() { + if (this._length) { + let v: any = this.head; + const first = v; + do { + yield v; + v = v.next; + } while (v && v !== first); + } + } + + get length() { + return this._length; + } + + add(): T { + const v: any = this.alloc(); + if (v) { + if (this.tail) { + v.prev = this.tail; + (this.tail).next = v; + this.tail = v; + if (this.closed) { + v.next = this.head; + (this.head).prev = v; + } + this._length++; + } else { + this.tail = this.head = v; + v.next = v.prev = this.closed ? v : null; + this._length++; + } + } + return v; + } + + insert(i: number): T { + if (!this._length) { + return i === 0 ? this.add() : undefined; + } + const q: any = this.nth(i); + if (!q) return; + const v: any = this.alloc(); + if (v) { + v.next = q; + v.prev = q.prev; + if (q.prev) { + q.prev.next = v; + } else { + this.head = v; + } + q.prev = v; + this._length++; + } + return v; + } + + remove(vec: T): boolean { + if (this.has(vec)) { + this._length--; + this._free.push(vec); + const v: any = vec; + if (v.prev) { + v.prev.next = v.next; + } + if (this.head === v) { + this.head = this._length ? v.next : null; + } + if (v.next) { + v.next.prev = v.prev; + } + if (this.tail === v) { + this.tail = this._length ? v.prev : null; + } + delete v.prev; + delete v.next; + return true; + } + } + + has(value: T) { + let v: any = this.head; + const first = v; + do { + if (v === value) { + return true; + } + v = v.next; + } while (v && v !== first); + return false; + } + + nth(n: number): T { + if (n < 0) { + n += this._length; + } + if (n < 0 || n >= this._length) { + return; + } + let v; + if (n <= this._length >> 1) { + v = this.head; + while (n-- > 0 && v) { + v = v.next; + } + } else { + v = this.tail; + n = this._length - n - 1; + while (n-- > 0 && v) { + v = v.prev; + } + } + return v; + } +} diff --git a/packages/vector-pools/src/pool.ts b/packages/vector-pools/src/pool.ts new file mode 100644 index 0000000000..8c41846e06 --- /dev/null +++ b/packages/vector-pools/src/pool.ts @@ -0,0 +1,91 @@ +import { TypedArray } from "@thi.ng/api"; +import { isTypedArray } from "@thi.ng/checks/is-typedarray"; +import { + MemPool, + MemPoolOpts, + MemPoolStats, + Type +} from "@thi.ng/malloc"; +import { IVecPool, IVector } from "@thi.ng/vectors3//api"; +import { wrap } from "./wrap"; + +export class VecPool implements + IVecPool { + + pool: MemPool; + + constructor(pool: MemPool); + constructor(buf: number | ArrayBuffer, opts?: Partial); + constructor(pool: any, opts?: Partial) { + this.pool = !(pool instanceof MemPool) ? + new MemPool(pool, opts) : + pool; + } + + stats(): MemPoolStats { + return this.pool.stats(); + } + + malloc(size: number, type: Type = Type.F32): TypedArray { + return this.pool.callocAs(type, size); + } + + mallocWrapped(size: number, stride = 1, type: Type = Type.F32): IVector { + const buf = this.pool.callocAs(type, size * stride); + return wrap(buf, size, 0, stride); + + } + + /** + * Intended to provide individual vector views of a larger + * underlying buffer. Attempts to allocate a single block of + * sufficient memory to hold `num` vectors of `size` elements and if + * successful returns array of vectors mapping the buffer with given + * stride lengths (both component and element strides can be + * provided). + * + * *Note:* Since all result vectors share the same continuous memory + * block, freeing any of them from the pool will invalidate all of + * them. + * + * Also see: + * - `Vec2.mapBuffer()` + * - `Vec3.mapBuffer()` + * - `Vec4.mapBuffer()` + * - `NDArray1.mapBuffer()` + * + * @param num + * @param size + * @param cstride + * @param estride + * @param type + */ + mallocArray(num: number, size: number, cstride = 1, estride = size, type: Type = Type.F32): IVector[] { + const buf = this.malloc(Math.max(cstride, estride, size) * num, type); + if (!buf) return; + const res: IVector[] = []; + for (let i = 0; i < num; i += estride) { + res.push(wrap(buf, size, i, cstride)); + } + return res; + } + + free(vec: IVector | TypedArray) { + const buf = (vec).buf; + return buf ? + isTypedArray(buf) ? + this.pool.free(buf) : + false : + this.pool.free(vec); + } + + freeAll() { + this.pool.freeAll(); + } + + release() { + const res = this.pool.release(); + res && delete this.pool; + return res; + } +} diff --git a/packages/vector-pools/src/wrap.ts b/packages/vector-pools/src/wrap.ts new file mode 100644 index 0000000000..0d2440b396 --- /dev/null +++ b/packages/vector-pools/src/wrap.ts @@ -0,0 +1,19 @@ +import { IVector, Vec } from "@thi.ng/vectors3/api"; +import { gvec } from "@thi.ng/vectors3/gvec"; +import { Vec2 } from "@thi.ng/vectors3/vec2"; +import { Vec3 } from "@thi.ng/vectors3/vec3"; +import { Vec4 } from "@thi.ng/vectors3/vec4"; + +export const wrap = + (buf: Vec, size: number, idx: number, stride: number): IVector => { + switch (size) { + case 2: + return new Vec2(buf, idx, stride); + case 3: + return new Vec3(buf, idx, stride); + case 4: + return new Vec4(buf, idx, stride); + default: + return gvec(buf, size, idx, stride); + } + }; diff --git a/packages/vector-pools/test/index.ts b/packages/vector-pools/test/index.ts new file mode 100644 index 0000000000..b8c58a8837 --- /dev/null +++ b/packages/vector-pools/test/index.ts @@ -0,0 +1,6 @@ +// import * as assert from "assert"; +// import * as vp from "../src/index"; + +describe("vector-pools", () => { + it("tests pending"); +}); diff --git a/packages/vector-pools/test/tsconfig.json b/packages/vector-pools/test/tsconfig.json new file mode 100644 index 0000000000..bcf29ace54 --- /dev/null +++ b/packages/vector-pools/test/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "../build" + }, + "include": [ + "./**/*.ts", + "../src/**/*.ts" + ] +} diff --git a/packages/vector-pools/tsconfig.json b/packages/vector-pools/tsconfig.json new file mode 100644 index 0000000000..bd6481a5a6 --- /dev/null +++ b/packages/vector-pools/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "." + }, + "include": [ + "./src/**/*.ts" + ] +} From c31ce8adc9b8249db8d0a21270f61f0bdfa6b60e Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 28 Nov 2018 18:13:53 +0000 Subject: [PATCH 061/333] refactor(vector-pools): various minor updates & fixes --- packages/vector-pools/src/alist.ts | 2 +- packages/vector-pools/src/index.ts | 6 ++++++ packages/vector-pools/src/linked-list.ts | 7 ++++--- packages/vector-pools/src/pool.ts | 3 ++- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/vector-pools/src/alist.ts b/packages/vector-pools/src/alist.ts index 44b6e5796e..82f9c281b1 100644 --- a/packages/vector-pools/src/alist.ts +++ b/packages/vector-pools/src/alist.ts @@ -25,7 +25,7 @@ export abstract class AVecList> { estride = size, start = 0) { - this.buffer = buffer; + this.buffer = buffer || new Float32Array(size * capacity); this.size = size; this.factory = factory; this.cstride = cstride; diff --git a/packages/vector-pools/src/index.ts b/packages/vector-pools/src/index.ts index e69de29bb2..0b30724ca7 100644 --- a/packages/vector-pools/src/index.ts +++ b/packages/vector-pools/src/index.ts @@ -0,0 +1,6 @@ +export * from "./api"; +export * from "./alist"; +export * from "./array-list"; +export * from "./linked-list"; +export * from "./pool"; +export * from "./wrap"; diff --git a/packages/vector-pools/src/linked-list.ts b/packages/vector-pools/src/linked-list.ts index 762aae9e4b..0c6e458616 100644 --- a/packages/vector-pools/src/linked-list.ts +++ b/packages/vector-pools/src/linked-list.ts @@ -6,7 +6,7 @@ export class VecLinkedList> extends AVecList { head: T; tail: T; - closed: boolean; + readonly closed: boolean; protected _length: number; @@ -82,12 +82,13 @@ export class VecLinkedList> extends AVecList { if (!q) return; const v: any = this.alloc(); if (v) { + if (this.head === q) { + this.head = v; + } v.next = q; v.prev = q.prev; if (q.prev) { q.prev.next = v; - } else { - this.head = v; } q.prev = v; this._length++; diff --git a/packages/vector-pools/src/pool.ts b/packages/vector-pools/src/pool.ts index 8c41846e06..7a4b623be8 100644 --- a/packages/vector-pools/src/pool.ts +++ b/packages/vector-pools/src/pool.ts @@ -6,7 +6,8 @@ import { MemPoolStats, Type } from "@thi.ng/malloc"; -import { IVecPool, IVector } from "@thi.ng/vectors3//api"; +import { IVector } from "@thi.ng/vectors3/api"; +import { IVecPool } from "./api"; import { wrap } from "./wrap"; export class VecPool implements From d381ace26acb5c7ba78c5e85148894629880cddc Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 29 Nov 2018 14:17:15 +0000 Subject: [PATCH 062/333] feat(api): add assert() --- packages/api/src/assert.ts | 15 +++++++++++++++ packages/api/src/index.ts | 1 + 2 files changed, 16 insertions(+) create mode 100644 packages/api/src/assert.ts diff --git a/packages/api/src/assert.ts b/packages/api/src/assert.ts new file mode 100644 index 0000000000..0dd2a212d0 --- /dev/null +++ b/packages/api/src/assert.ts @@ -0,0 +1,15 @@ +/** + * Takes a `test` result or predicate function without args and throws + * error with given `msg` if test failed (i.e. is falsy). The function + * is only enabled if `NODE_ENV != "production"` or if + * `UMBRELLA_ASSERTS = 1`. + */ +export const assert = + (process.env.NODE_ENV !== "production" || + process.env.UMBRELLA_ASSERTS === "1") ? + (test: boolean | (() => boolean), msg = "assertion failed") => { + if ((typeof test === "function" && !test()) || !test) { + throw new Error(msg); + } + } : + () => { }; diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts index 4da35daf6f..ab4e536fe8 100644 --- a/packages/api/src/index.ts +++ b/packages/api/src/index.ts @@ -6,3 +6,4 @@ export { } export * from "./api"; +export * from "./assert"; From 25b97891c8d511a49408afb7b55bc9c33cf02270 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 30 Nov 2018 01:50:57 +0000 Subject: [PATCH 063/333] refactor(vectors): add StridedVec, update IVector, AVec --- packages/vectors3/src/api.ts | 21 ++++++++++++--------- packages/vectors3/src/internal/avec.ts | 20 ++------------------ 2 files changed, 14 insertions(+), 27 deletions(-) diff --git a/packages/vectors3/src/api.ts b/packages/vectors3/src/api.ts index 9e38ad36f0..242415d79f 100644 --- a/packages/vectors3/src/api.ts +++ b/packages/vectors3/src/api.ts @@ -12,21 +12,24 @@ export interface Vec extends [id: number]: number; } -export interface IVector extends - Vec, - ICopy, - IEmpty, - IEqualsDelta { +export interface ReadonlyVec extends + Iterable, + ILength { + readonly [id: number]: number; +} +export interface StridedVec { buf: Vec; i: number; s: number; } -export interface ReadonlyVec extends - Iterable, - ILength { - readonly [id: number]: number; +export interface IVector extends + Vec, + ICopy, + IEmpty, + IEqualsDelta, + StridedVec { } export interface MultiVecOp { diff --git a/packages/vectors3/src/internal/avec.ts b/packages/vectors3/src/internal/avec.ts index 6e7605e038..d28d6fe279 100644 --- a/packages/vectors3/src/internal/avec.ts +++ b/packages/vectors3/src/internal/avec.ts @@ -1,6 +1,6 @@ -import { Vec } from "../api"; +import { StridedVec, Vec } from "../api"; -export abstract class AVec { +export abstract class AVec implements StridedVec { buf: Vec; i: number; @@ -15,20 +15,4 @@ export abstract class AVec { abstract get length(): number; abstract [Symbol.iterator](): IterableIterator; - - get dim() { - return 1; - } - - get offset() { - return this.i; - } - - get shape() { - return [this.length]; - } - - get stride() { - return [this.s]; - } } From 019c0af35e155731f795158174eb585417227547 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 30 Nov 2018 01:51:59 +0000 Subject: [PATCH 064/333] feat(vector-pools): add AttribPool, refactor lists --- packages/vector-pools/src/alist.ts | 46 ++-- packages/vector-pools/src/api.ts | 18 +- packages/vector-pools/src/array-list.ts | 22 +- packages/vector-pools/src/attrib-pool.ts | 293 +++++++++++++++++++++++ packages/vector-pools/src/index.ts | 1 + packages/vector-pools/src/linked-list.ts | 14 +- 6 files changed, 359 insertions(+), 35 deletions(-) create mode 100644 packages/vector-pools/src/attrib-pool.ts diff --git a/packages/vector-pools/src/alist.ts b/packages/vector-pools/src/alist.ts index 82f9c281b1..295ae0a064 100644 --- a/packages/vector-pools/src/alist.ts +++ b/packages/vector-pools/src/alist.ts @@ -1,8 +1,8 @@ -import { IVector, Vec } from "@thi.ng/vectors3/api"; -import { wrap } from "./wrap"; +import { StridedVec, Vec } from "@thi.ng/vectors3/api"; import { VecFactory } from "./api"; +import { wrap } from "./wrap"; -export abstract class AVecList> { +export abstract class AVecList { buffer: Vec; factory: VecFactory; @@ -14,17 +14,27 @@ export abstract class AVecList> { estride: number; cstride: number; - _free: T[]; + freeIDs: number[]; + /** + * + * @param buffer + * @param capacity + * @param size + * @param start + * @param cstride + * @param estride + * @param factory + */ constructor( buffer: Vec, capacity: number, size: number, - factory: VecFactory = wrap, + start = 0, cstride = 1, estride = size, - start = 0) { - + factory: VecFactory = wrap, + ) { this.buffer = buffer || new Float32Array(size * capacity); this.size = size; this.factory = factory; @@ -32,7 +42,7 @@ export abstract class AVecList> { this.estride = estride; this.start = this.curr = start; this.capacity = capacity; - this._free = []; + this.freeIDs = []; } abstract [Symbol.iterator](): IterableIterator; @@ -45,6 +55,10 @@ export abstract class AVecList> { abstract remove(v: T): boolean; + abstract has(v: T): boolean; + + abstract nth(n: number): T; + indices(res: Vec = [], i = 0, local = true) { const start = this.start; const estride = this.estride; @@ -61,15 +75,15 @@ export abstract class AVecList> { } protected alloc() { - let v: T; - if (this._free.length > 0) { - v = this._free.pop(); + let idx: number; + if (this.freeIDs.length > 0) { + idx = this.freeIDs.pop(); + } else if (this.length >= this.capacity) { + return; } else { - if (this.length < this.capacity) { - v = this.factory(this.buffer, this.size, this.curr, this.cstride); - this.curr += this.estride; - } + idx = this.curr; + this.curr += this.estride; } - return v; + return this.factory(this.buffer, this.size, idx, this.cstride); } } diff --git a/packages/vector-pools/src/api.ts b/packages/vector-pools/src/api.ts index 24a43c120b..f4b97f16a3 100644 --- a/packages/vector-pools/src/api.ts +++ b/packages/vector-pools/src/api.ts @@ -1,21 +1,29 @@ import { IRelease, TypedArray } from "@thi.ng/api/api"; import { Type } from "@thi.ng/malloc/api"; -import { IVector, Vec } from "@thi.ng/vectors3/api"; +import { StridedVec, Vec, ReadonlyVec } from "@thi.ng/vectors3/api"; + +export interface AttribSpec { + type: Type; + size: number; + default: number | ReadonlyVec; + byteOffset: number; + stride?: number; +} export interface IVecPool extends IRelease { malloc(size: number, type?: Type): TypedArray; - mallocWrapped(size: number, stride?: number, type?: Type): IVector; + mallocWrapped(size: number, stride?: number, type?: Type): StridedVec; - mallocArray(num: number, size: number, cstride?: number, estride?: number, type?: Type): IVector[]; + mallocArray(num: number, size: number, cstride?: number, estride?: number, type?: Type): StridedVec[]; - free(vec: IVector | TypedArray): boolean; + free(vec: StridedVec | TypedArray): boolean; freeAll(); } export type VecFactory = - (buf: Vec, size: number, index: number, stride: number) => IVector; + (buf: Vec, size: number, index: number, stride: number) => StridedVec; export { Type }; diff --git a/packages/vector-pools/src/array-list.ts b/packages/vector-pools/src/array-list.ts index 9c24347fe8..e602058643 100644 --- a/packages/vector-pools/src/array-list.ts +++ b/packages/vector-pools/src/array-list.ts @@ -1,8 +1,8 @@ -import { IVector, Vec } from "@thi.ng/vectors3/api"; +import { StridedVec, Vec } from "@thi.ng/vectors3/api"; import { AVecList } from "./alist"; import { VecFactory } from "./api"; -export class VecArrayList> extends AVecList { +export class VecArrayList extends AVecList { items: T[]; @@ -19,12 +19,12 @@ export class VecArrayList> extends AVecList { buffer: Vec, capacity: number, size: number, - factory?: VecFactory, + start = 0, cstride = 1, estride = size, - start = 0) { - - super(buffer, capacity, size, factory, cstride, estride, start); + factory?: VecFactory, + ) { + super(buffer, capacity, size, cstride, estride, start, factory); this.items = []; } @@ -56,9 +56,17 @@ export class VecArrayList> extends AVecList { remove(v: T) { const idx = this.items.indexOf(v); if (idx >= 0) { - this._free.push(v); + this.freeIDs.push(v.i); this.items.splice(idx, 1); return true; } } + + has(v: T) { + return this.items.indexOf(v) >= 0; + } + + nth(n: number) { + return this.items[n]; + } } diff --git a/packages/vector-pools/src/attrib-pool.ts b/packages/vector-pools/src/attrib-pool.ts new file mode 100644 index 0000000000..7c79a2abf6 --- /dev/null +++ b/packages/vector-pools/src/attrib-pool.ts @@ -0,0 +1,293 @@ +import { IObjectOf, IRelease, TypedArray } from "@thi.ng/api/api"; +import { assert } from "@thi.ng/api/assert"; +import { align } from "@thi.ng/binary/align"; +import { Pow2 } from "@thi.ng/binary/api"; +import { SIZEOF, MemPoolOpts } from "@thi.ng/malloc/api"; +import { MemPool } from "@thi.ng/malloc/pool"; +import { wrap } from "@thi.ng/malloc/wrap"; +import { range } from "@thi.ng/transducers/iter/range"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { AttribSpec } from "./api"; + +/* + * WASM mem : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... + * typedarr : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... offset = 4 (bytes) + * pos (f32) : X X X X X Y Y Y Y X ... offset = 0 (bytes), size = 2 (f32) + * uv (f32) : U U U U V V V V ... offset = 8 (bytes), size = 2 (f32) + * col (u16) : R R G G B B A A ... offset = 16 (bytes), size = 4 (u16) + * + * global stride: 16 + */ +export class AttribPool implements + IRelease { + + attribs: IObjectOf; + order: string[]; + specs: IObjectOf; + pool: MemPool; + addr: number; + capacity: number; + + byteStride: number; + maxAttribSize: number; + + constructor( + pool: number | ArrayBuffer | MemPool, + capacity: number, + specs: IObjectOf, + poolOpts?: MemPoolOpts + ) { + this.pool = !(pool instanceof MemPool) ? + new MemPool(pool, poolOpts) : + pool; + this.capacity = capacity; + this.specs = {}; + this.attribs = {}; + this.order = []; + this.byteStride = 1; + this.maxAttribSize = 1; + this.initAttribs(specs, true); + } + + release(releasePool = true) { + if (releasePool && this.pool) { + this.pool.release(); + } + delete this.pool; + delete this.attribs; + delete this.specs; + return true; + } + + initAttribs(specs: IObjectOf, alloc = false) { + const [newStride, maxSize] = this.computeStride(specs); + this.maxAttribSize = maxSize; + if (newStride != this.byteStride) { + this.realignAttribs(newStride); + } + this.validateAttribs(specs, newStride); + this.byteStride = newStride; + if (alloc) { + const addr = this.pool.malloc(this.capacity * this.byteStride); + assert(addr > 0, `out of memory`); + this.addr = addr; + } + this.initDefaults(specs); + } + + getAttrib(id: string) { + return this.attribs[id]; + } + + getAttribVal(id: string, i: number): number | Vec { + if (i >= this.capacity) return; + const spec = this.specs[id]; + assert(!!spec, `invalid attrib: ${id}`); + i *= spec.stride; + return spec.size > 1 ? + this.attribs[id].subarray(i, i + spec.size) : + this.attribs[id][i]; + } + + *attribValues(id: string) { + const buf = this.attribs[id]; + assert(!!buf, `invalid attrib: ${id}`); + const spec = this.specs[id]; + const stride = spec.stride; + const size = spec.size; + if (size > 1) { + for (let i = 0, j = 0, n = this.capacity; i < n; i++ , j += stride) { + yield buf.subarray(j, j + size); + } + } else { + for (let i = 0, n = this.capacity; i < n; i++) { + yield buf[i * stride]; + } + } + } + + setAttribVal(id: string, index: number, v: number | ReadonlyVec) { + const spec = this.specs[id]; + assert(!!spec, `invalid attrib: ${id}`); + this.ensure(index); + const buf = this.attribs[id]; + index *= spec.stride; + const isNum = typeof v === "number"; + assert( + () => (!isNum && spec.size > 1) || (isNum && spec.size === 1), + `incompatible value for attrib: ${id}` + ); + if (!isNum) { + assert( + (v).length <= spec.size, + `wrong attrib val size, expected ${spec.size}, got ${(v).length}` + ); + buf.set(v, index); + } else { + buf[index] = v; + } + return this; + } + + removeAttrib(id: string) { + if (!this.attribs[id]) return false; + delete this.attribs[id]; + delete this.specs[id]; + this.updateOrder(); + const [stride, size] = this.computeStride(this.specs, false); + this.maxAttribSize = size; + this.realignAttribs(stride); + } + + ensure(newCapacity: number, fill = false) { + if (newCapacity < this.capacity) return; + // TODO add realloc() + const newAddr = this.pool.malloc(newCapacity * this.byteStride); + assert(newAddr > 0, `out of memory`); + for (let id in this.specs) { + const a = this.specs[id]; + const buf = wrap( + a.type, + this.pool.buf, + newAddr + (a.byteOffset || 0), + (newCapacity - 1) * a.stride + a.size + ); + buf.set(this.attribs[id]); + this.attribs[id] = buf; + } + if (fill) { + // TODO fill remainder with default values? + this.setDefaults(this.specs, this.capacity, newCapacity); + } + this.pool.free(this.addr); + this.addr = newAddr; + this.capacity = newCapacity; + } + + protected computeStride(specs: IObjectOf, inclExisting = true) { + let maxStride = inclExisting ? this.byteStride : 1; + let maxSize = inclExisting ? this.maxAttribSize : 1; + for (let id in specs) { + const a = specs[id]; + const size = SIZEOF[a.type]; + maxSize = Math.max(maxSize, size); + maxStride = Math.max(maxStride, a.byteOffset + a.size * size); + } + return [align(maxStride, maxSize), maxSize]; + } + + protected validateAttribs(specs: IObjectOf, stride = this.byteStride) { + for (let id in specs) { + assert(!this.attribs[id], `attrib: ${id} already exists`); + const a = specs[id]; + const size = SIZEOF[a.type]; + const isNum = typeof a.default === "number"; + assert( + () => (!isNum && a.size === (a.default).length) || (isNum && a.size === 1), + `incompatible default value for attrib: ${id}, expected size ${a.size}` + ); + assert( + a.byteOffset % size === 0, + `invalid offset for attrib: ${id}, expected multiple of ${size}` + ); + a.stride = stride / size; + this.specs[id] = a; + } + this.updateOrder(); + } + + protected updateOrder() { + this.order = Object.keys(this.specs).sort((a, b) => this.specs[a].byteOffset - this.specs[b].byteOffset); + } + + protected initDefaults(specs: IObjectOf, start = 0, end = this.capacity) { + for (let id in specs) { + const a = specs[id]; + this.attribs[id] = wrap( + a.type, + this.pool.buf, + this.addr + (a.byteOffset || 0), + (this.capacity - 1) * a.stride + a.size + ); + } + this.setDefaults(specs, start, end); + } + + protected setDefaults(specs: IObjectOf, start = 0, end = this.capacity) { + for (let id in specs) { + const buf = this.attribs[id]; + const a = specs[id]; + const s = a.stride; + const v = a.default; + if (typeof v === "number") { + for (let i = start; i < end; i++) { + buf[i * s] = v; + } + } else { + for (let i = start; i < end; i++) { + buf.set(v, i * s); + } + } + } + } + + protected realignAttribs(newByteStride: number) { + if (this.order.length === 0 || newByteStride === this.byteStride) return; + console.warn(`realigning ${this.byteStride} -> ${newByteStride}...`); + const grow = newByteStride > this.byteStride; + let newAddr = this.addr; + if (grow) { + // TODO realloc + newAddr = this.pool.malloc(this.capacity * newByteStride); + assert(newAddr > 0, `out of memory`); + } + const sameBlock = newAddr === this.addr; + const num = this.capacity - 1; + const attribs = this.attribs; + const newAttribs: IObjectOf<[TypedArray, number]> = {}; + const specs = this.specs; + const order = grow ? [...this.order].reverse() : this.order; + // create resized attrib views (in old or new address space) + for (let id in specs) { + const a = specs[id]; + const dStride = newByteStride / SIZEOF[a.type]; + newAttribs[id] = [ + wrap( + a.type, + this.pool.buf, + newAddr + a.byteOffset, + num * dStride + a.size + ), + dStride + ]; + } + // process in opposite directions based on new stride size + for (let i of newByteStride < this.byteStride ? range(num + 1) : range(num, -1, -1)) { + // ...in offset order to avoid successor attrib vals + for (let id of order) { + const a = specs[id]; + const sStride = a.stride; + const src = attribs[id]; + const [dest, dStride] = newAttribs[id]; + if (typeof a.default === "number") { + dest[i * dStride] = src[i * sStride]; + } else { + const j = i * sStride; + sameBlock ? + (grow ? dest : src).copyWithin(i * dStride, j, j + a.size) : + dest.set(src.subarray(j, j + a.size), i * dStride); + } + } + } + if (this.addr != newAddr) { + this.pool.free(this.addr); + this.addr = newAddr; + } + this.byteStride = newByteStride; + for (let id in newAttribs) { + const a = newAttribs[id]; + attribs[id] = a[0]; + specs[id].stride = a[1]; + } + } +} diff --git a/packages/vector-pools/src/index.ts b/packages/vector-pools/src/index.ts index 0b30724ca7..92c8f045e9 100644 --- a/packages/vector-pools/src/index.ts +++ b/packages/vector-pools/src/index.ts @@ -1,6 +1,7 @@ export * from "./api"; export * from "./alist"; export * from "./array-list"; +export * from "./attrib-pool"; export * from "./linked-list"; export * from "./pool"; export * from "./wrap"; diff --git a/packages/vector-pools/src/linked-list.ts b/packages/vector-pools/src/linked-list.ts index 0c6e458616..f4b6d24581 100644 --- a/packages/vector-pools/src/linked-list.ts +++ b/packages/vector-pools/src/linked-list.ts @@ -1,8 +1,8 @@ -import { IVector, Vec } from "@thi.ng/vectors3/api"; +import { StridedVec, Vec } from "@thi.ng/vectors3/api"; import { AVecList } from "./alist"; import { VecFactory } from "./api"; -export class VecLinkedList> extends AVecList { +export class VecLinkedList extends AVecList { head: T; tail: T; @@ -26,12 +26,12 @@ export class VecLinkedList> extends AVecList { buffer: Vec, capacity: number, size: number, - factory?: VecFactory, + start = 0, cstride = 1, estride = size, - start = 0) { - - super(buffer, capacity, size, factory, cstride, estride, start); + factory?: VecFactory + ) { + super(buffer, capacity, size, cstride, estride, start, factory); this.closed = closed; this.head = null; this.tail = null; @@ -99,7 +99,7 @@ export class VecLinkedList> extends AVecList { remove(vec: T): boolean { if (this.has(vec)) { this._length--; - this._free.push(vec); + this.freeIDs.push(vec.i); const v: any = vec; if (v.prev) { v.prev.next = v.next; From 4fe2047eb59f30e5bd812d6b162cdc995ea069c3 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 30 Nov 2018 15:07:43 +0000 Subject: [PATCH 065/333] feat(vector-pools): add GLType alias, AttribPoolOpts, update pool impls --- packages/vector-pools/src/api.ts | 63 +++++++++++-- packages/vector-pools/src/attrib-pool.ts | 89 ++++++++++++++----- packages/vector-pools/src/convert.ts | 23 +++++ packages/vector-pools/src/index.ts | 2 +- .../vector-pools/src/{pool.ts => vec-pool.ts} | 28 ++++-- 5 files changed, 168 insertions(+), 37 deletions(-) create mode 100644 packages/vector-pools/src/convert.ts rename packages/vector-pools/src/{pool.ts => vec-pool.ts} (75%) diff --git a/packages/vector-pools/src/api.ts b/packages/vector-pools/src/api.ts index f4b97f16a3..433565bb4b 100644 --- a/packages/vector-pools/src/api.ts +++ b/packages/vector-pools/src/api.ts @@ -1,22 +1,27 @@ import { IRelease, TypedArray } from "@thi.ng/api/api"; -import { Type } from "@thi.ng/malloc/api"; +import { Type, MemPoolOpts } from "@thi.ng/malloc/api"; import { StridedVec, Vec, ReadonlyVec } from "@thi.ng/vectors3/api"; export interface AttribSpec { - type: Type; + type: GLType | Type; size: number; - default: number | ReadonlyVec; + default?: number | ReadonlyVec; byteOffset: number; stride?: number; } +export interface AttribPoolOpts { + resizable: boolean; + mempool: MemPoolOpts; +} + export interface IVecPool extends IRelease { - malloc(size: number, type?: Type): TypedArray; + malloc(size: number, type?: GLType | Type): TypedArray; - mallocWrapped(size: number, stride?: number, type?: Type): StridedVec; + mallocWrapped(size: number, stride?: number, type?: GLType | Type): StridedVec; - mallocArray(num: number, size: number, cstride?: number, estride?: number, type?: Type): StridedVec[]; + mallocArray(num: number, size: number, cstride?: number, estride?: number, type?: GLType | Type): StridedVec[]; free(vec: StridedVec | TypedArray): boolean; @@ -26,4 +31,48 @@ export interface IVecPool extends IRelease { export type VecFactory = (buf: Vec, size: number, index: number, stride: number) => StridedVec; -export { Type }; +/** + * WebGL numeric type constants. These can be used by classes in this + * package as aliases for thi.ng/malloc's `Type` enum (see `GL2TYPE` LUT + * below), but also then used directly when initializing WebGL buffers + * from given attribute buffer specs. + * + * See `AttribPool` & readme examples for more details. + */ +export const enum GLType { + I8 = 0x1400, + U8 = 0x1401, + I16 = 0x1402, + U16 = 0x1403, + I32 = 0x1404, + U32 = 0x1405, + F32 = 0x1406, +}; + +/** + * Conversion from `GLType` to `Type`. + */ +export const GL2TYPE = { + [GLType.I8]: Type.I8, + [GLType.U8]: Type.U8, + [GLType.I16]: Type.I16, + [GLType.U16]: Type.U16, + [GLType.I32]: Type.I32, + [GLType.I32]: Type.I32, + [GLType.U32]: Type.U32, + [GLType.F32]: Type.F32, +}; + +/** + * Conversion from `Type` to `GLType`. + */ +export const TYPE2GL = { + [Type.I8]: GLType.I8, + [Type.U8]: GLType.U8, + [Type.I16]: GLType.I16, + [Type.U16]: GLType.U16, + [Type.I32]: GLType.I32, + [Type.I32]: GLType.I32, + [Type.U32]: GLType.U32, + [Type.F32]: GLType.F32, +}; diff --git a/packages/vector-pools/src/attrib-pool.ts b/packages/vector-pools/src/attrib-pool.ts index 7c79a2abf6..228d3cd090 100644 --- a/packages/vector-pools/src/attrib-pool.ts +++ b/packages/vector-pools/src/attrib-pool.ts @@ -2,12 +2,16 @@ import { IObjectOf, IRelease, TypedArray } from "@thi.ng/api/api"; import { assert } from "@thi.ng/api/assert"; import { align } from "@thi.ng/binary/align"; import { Pow2 } from "@thi.ng/binary/api"; -import { SIZEOF, MemPoolOpts } from "@thi.ng/malloc/api"; +import { SIZEOF } from "@thi.ng/malloc/api"; import { MemPool } from "@thi.ng/malloc/pool"; import { wrap } from "@thi.ng/malloc/wrap"; import { range } from "@thi.ng/transducers/iter/range"; import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { AttribSpec } from "./api"; +import { asNativeType } from "./convert"; +import { + AttribPoolOpts, + AttribSpec, +} from "./api"; /* * WASM mem : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... @@ -24,6 +28,7 @@ export class AttribPool implements attribs: IObjectOf; order: string[]; specs: IObjectOf; + opts: AttribPoolOpts; pool: MemPool; addr: number; capacity: number; @@ -35,11 +40,16 @@ export class AttribPool implements pool: number | ArrayBuffer | MemPool, capacity: number, specs: IObjectOf, - poolOpts?: MemPoolOpts + opts?: AttribPoolOpts ) { + this.opts = { + resizable: true, + ...opts + }; this.pool = !(pool instanceof MemPool) ? - new MemPool(pool, poolOpts) : + new MemPool(pool, this.opts.mempool) : pool; + this.opts = opts; this.capacity = capacity; this.specs = {}; this.attribs = {}; @@ -49,6 +59,10 @@ export class AttribPool implements this.initAttribs(specs, true); } + bytes() { + return new Uint8Array(this.pool.buf, this.addr, this.capacity * this.byteStride); + } + release(releasePool = true) { if (releasePool && this.pool) { this.pool.release(); @@ -75,11 +89,7 @@ export class AttribPool implements this.initDefaults(specs); } - getAttrib(id: string) { - return this.attribs[id]; - } - - getAttribVal(id: string, i: number): number | Vec { + attribValue(id: string, i: number): number | Vec { if (i >= this.capacity) return; const spec = this.specs[id]; assert(!!spec, `invalid attrib: ${id}`); @@ -106,7 +116,7 @@ export class AttribPool implements } } - setAttribVal(id: string, index: number, v: number | ReadonlyVec) { + setAttribValue(id: string, index: number, v: number | ReadonlyVec) { const spec = this.specs[id]; assert(!!spec, `invalid attrib: ${id}`); this.ensure(index); @@ -122,13 +132,41 @@ export class AttribPool implements (v).length <= spec.size, `wrong attrib val size, expected ${spec.size}, got ${(v).length}` ); - buf.set(v, index); + buf.set(v, index); } else { buf[index] = v; } return this; } + setAttribValues(id: string, vals: (number | ReadonlyVec)[]) { + const spec = this.specs[id]; + assert(!!spec, `invalid attrib: ${id}`); + const n = vals.length; + const v = vals[0]; + const stride = spec.stride; + this.ensure(n); + const buf = this.attribs[id]; + const isNum = typeof v === "number"; + assert( + () => (!isNum && spec.size > 1) || (isNum && spec.size === 1), + `incompatible value(s) for attrib: ${id}` + ); + if (!isNum) { + assert( + (v).length <= spec.size, + `wrong attrib val size, expected ${spec.size}, got ${(v).length}` + ); + for (let i = 0; i < n; i++) { + buf.set(vals[i], i * stride); + } + } else { + for (let i = 0; i < n; i++) { + buf[i * stride] = vals[i]; + } + } + } + removeAttrib(id: string) { if (!this.attribs[id]) return false; delete this.attribs[id]; @@ -140,14 +178,15 @@ export class AttribPool implements } ensure(newCapacity: number, fill = false) { - if (newCapacity < this.capacity) return; + if (newCapacity <= this.capacity) return; + assert(this.opts.resizable, `pool resizing disabled`); // TODO add realloc() const newAddr = this.pool.malloc(newCapacity * this.byteStride); assert(newAddr > 0, `out of memory`); for (let id in this.specs) { const a = this.specs[id]; const buf = wrap( - a.type, + asNativeType(a.type), this.pool.buf, newAddr + (a.byteOffset || 0), (newCapacity - 1) * a.stride + a.size @@ -156,7 +195,6 @@ export class AttribPool implements this.attribs[id] = buf; } if (fill) { - // TODO fill remainder with default values? this.setDefaults(this.specs, this.capacity, newCapacity); } this.pool.free(this.addr); @@ -169,7 +207,7 @@ export class AttribPool implements let maxSize = inclExisting ? this.maxAttribSize : 1; for (let id in specs) { const a = specs[id]; - const size = SIZEOF[a.type]; + const size = SIZEOF[asNativeType(a.type)]; maxSize = Math.max(maxSize, size); maxStride = Math.max(maxStride, a.byteOffset + a.size * size); } @@ -180,7 +218,7 @@ export class AttribPool implements for (let id in specs) { assert(!this.attribs[id], `attrib: ${id} already exists`); const a = specs[id]; - const size = SIZEOF[a.type]; + const size = SIZEOF[asNativeType(a.type)]; const isNum = typeof a.default === "number"; assert( () => (!isNum && a.size === (a.default).length) || (isNum && a.size === 1), @@ -197,14 +235,16 @@ export class AttribPool implements } protected updateOrder() { - this.order = Object.keys(this.specs).sort((a, b) => this.specs[a].byteOffset - this.specs[b].byteOffset); + this.order = Object.keys(this.specs).sort( + (a, b) => this.specs[a].byteOffset - this.specs[b].byteOffset + ); } protected initDefaults(specs: IObjectOf, start = 0, end = this.capacity) { for (let id in specs) { const a = specs[id]; this.attribs[id] = wrap( - a.type, + asNativeType(a.type), this.pool.buf, this.addr + (a.byteOffset || 0), (this.capacity - 1) * a.stride + a.size @@ -215,8 +255,9 @@ export class AttribPool implements protected setDefaults(specs: IObjectOf, start = 0, end = this.capacity) { for (let id in specs) { - const buf = this.attribs[id]; const a = specs[id]; + if (a.default == null) continue; + const buf = this.attribs[id]; const s = a.stride; const v = a.default; if (typeof v === "number") { @@ -225,7 +266,7 @@ export class AttribPool implements } } else { for (let i = start; i < end; i++) { - buf.set(v, i * s); + buf.set(v, i * s); } } } @@ -237,9 +278,12 @@ export class AttribPool implements const grow = newByteStride > this.byteStride; let newAddr = this.addr; if (grow) { + assert(this.opts.resizable, `pool resizing disabled`); // TODO realloc newAddr = this.pool.malloc(this.capacity * newByteStride); assert(newAddr > 0, `out of memory`); + } else if (!this.opts.resizable) { + return; } const sameBlock = newAddr === this.addr; const num = this.capacity - 1; @@ -250,10 +294,11 @@ export class AttribPool implements // create resized attrib views (in old or new address space) for (let id in specs) { const a = specs[id]; - const dStride = newByteStride / SIZEOF[a.type]; + const type = asNativeType(a.type); + const dStride = newByteStride / SIZEOF[type]; newAttribs[id] = [ wrap( - a.type, + type, this.pool.buf, newAddr + a.byteOffset, num * dStride + a.size diff --git a/packages/vector-pools/src/convert.ts b/packages/vector-pools/src/convert.ts new file mode 100644 index 0000000000..1017824142 --- /dev/null +++ b/packages/vector-pools/src/convert.ts @@ -0,0 +1,23 @@ +import { Type } from "@thi.ng/malloc/api"; +import { GL2TYPE, GLType, TYPE2GL } from "./api"; + +/** + * Returns canonical `Type` value of `type` by first attempting to + * resolve it as `GLType` enum. + * + * ``` + * nativeType(GLType.F32) => Type.F32 + * nativeType(Type.F32) => Type.F32 + * ``` + * + * @param type + */ +export const asNativeType = (type: GLType | Type): Type => { + const t = GL2TYPE[type]; + return t !== undefined ? t : type; +}; + +export const asGLType = (type: GLType | Type): GLType => { + const t = TYPE2GL[type]; + return t !== undefined ? t : type; +}; diff --git a/packages/vector-pools/src/index.ts b/packages/vector-pools/src/index.ts index 92c8f045e9..2a262e8c89 100644 --- a/packages/vector-pools/src/index.ts +++ b/packages/vector-pools/src/index.ts @@ -3,5 +3,5 @@ export * from "./alist"; export * from "./array-list"; export * from "./attrib-pool"; export * from "./linked-list"; -export * from "./pool"; +export * from "./vec-pool"; export * from "./wrap"; diff --git a/packages/vector-pools/src/pool.ts b/packages/vector-pools/src/vec-pool.ts similarity index 75% rename from packages/vector-pools/src/pool.ts rename to packages/vector-pools/src/vec-pool.ts index 7a4b623be8..8d5199f61f 100644 --- a/packages/vector-pools/src/pool.ts +++ b/packages/vector-pools/src/vec-pool.ts @@ -7,7 +7,8 @@ import { Type } from "@thi.ng/malloc"; import { IVector } from "@thi.ng/vectors3/api"; -import { IVecPool } from "./api"; +import { GLType, IVecPool } from "./api"; +import { asNativeType } from "./convert"; import { wrap } from "./wrap"; export class VecPool implements @@ -27,12 +28,16 @@ export class VecPool implements return this.pool.stats(); } - malloc(size: number, type: Type = Type.F32): TypedArray { - return this.pool.callocAs(type, size); + malloc(size: number, type: GLType | Type = Type.F32): TypedArray { + return this.pool.callocAs(asNativeType(type), size); } - mallocWrapped(size: number, stride = 1, type: Type = Type.F32): IVector { - const buf = this.pool.callocAs(type, size * stride); + mallocWrapped( + size: number, + stride = 1, + type: GLType | Type = Type.F32 + ): IVector { + const buf = this.pool.callocAs(asNativeType(type), size * stride); return wrap(buf, size, 0, stride); } @@ -61,8 +66,17 @@ export class VecPool implements * @param estride * @param type */ - mallocArray(num: number, size: number, cstride = 1, estride = size, type: Type = Type.F32): IVector[] { - const buf = this.malloc(Math.max(cstride, estride, size) * num, type); + mallocArray( + num: number, + size: number, + cstride = 1, + estride = size, + type: GLType | Type = Type.F32 + ): IVector[] { + const buf = this.malloc( + Math.max(cstride, estride, size) * num, + asNativeType(type) + ); if (!buf) return; const res: IVector[] = []; for (let i = 0; i < num; i += estride) { From fd54d3239a9dde8c7cdc1edbdbcd2d90b1581ea1 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 30 Nov 2018 15:08:03 +0000 Subject: [PATCH 066/333] feat(vector-pools): update readme, add examples --- packages/vector-pools/README.md | 187 +++++++++++++++++++++++++++++++- 1 file changed, 184 insertions(+), 3 deletions(-) diff --git a/packages/vector-pools/README.md b/packages/vector-pools/README.md index abd92336b2..e958b7e3ec 100644 --- a/packages/vector-pools/README.md +++ b/packages/vector-pools/README.md @@ -13,6 +13,8 @@ This project is part of the - [Installation](#installation) - [Dependencies](#dependencies) - [Usage examples](#usage-examples) + - [WebGL geometry definition / manipulation](#webgl-geometry-definition--manipulation) + - [WASM interop](#wasm-interop) - [Authors](#authors) - [License](#license) @@ -20,7 +22,16 @@ This project is part of the ## About -TODO... +This still unreleased package provides various data structures for +managing & working with memory mapped vectors. Together with +[@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/master/packages/vectors3) +(also still unreleased) these structures enable high-level, +zero-copy* manipulation of the underlying memory region and +are largely intended for WebGL & WASM use cases, e.g. to provide JS +friendly views of a structured data region of a WebGL or WASM memory +buffer. + +* The only copying taking place is to GPU memory ## Installation @@ -30,12 +41,182 @@ yarn add @thi.ng/vector-pools ## Dependencies -- TODO... +- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/master/packages/api) +- [@thi.ng/malloc](https://github.com/thi-ng/umbrella/tree/master/packages/malloc) +- [@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/master/packages/vectors3) ## Usage examples +### WebGL geometry definition / manipulation + +```ts +import { AttribPool, GLType } from "@thi.ng/vector-pools"; +import * as v from "@thi.ng/vectors3"; + +// ...Webgl boilerplate omitted +const gl = ... + +// create an interleaved (AOS layout) attribute buffer w/ default values +const geo = new AttribPool( + // initial size in bytes (or provide ArrayBuffer or @thi.ng/malloc/MemPool) + 0x200, + // num elements + 4, + // attrib specs (data mapping layout) + { + pos: { type: GLType.F32, size: 3, default: [0, 0, 0], byteOffset: 0 }, + uv: { type: GLType.F32, size: 2, default: [0, 0], byteOffset: 12 }, + col: { type: GLType.F32, size: 3, default: [1, 1, 1], byteOffset: 20 }, + id: { type: GLType.U16, size: 1, default: 0, byteOffset: 32 } + } +); + +// computed overall stride length +geo.byteStrength +// 36 + +// set attrib values +geo.setAttribValues("pos", [[-5, 0, 0], [5, 0, 0], [5, 5, 0], [-5, 5, 0]]); +geo.setAttribValues("uv", [[0, 0], [1, 0], [1, 1], [0, 1]]); +geo.setAttribValues("id", [0, 1, 2, 3]); + +// get view of individual attrib val +geo.attribValue("pos", 3) +// Float32Array [ -5, 5, 0 ] + +// zero-copy direct manipulation of attrib val +v.mulN(null, geo.attribValue("pos", 3), 2); +// Float32Array [ -10, 10, 0 ] + +// get iterator of mapped attrib vals (e.g. for batch processing) +[...geo.attribValues("pos")] +// [ Float32Array [ -5, 0, 0 ], +// Float32Array [ 5, 0, 0 ], +// Float32Array [ 5, 5, 0 ], +// Float32Array [ -10, 10, 0 ] ] + +// use with transducers, e.g. to compute map positions to colors +tx.run( + tx.map(([pos, col]) => v.maddN(col, [0.5, 0.5, 0.5], v.normalize(col, pos), 0.5)), + tx.tuples(geo.attribValues("pos"), geo.attribValues("col")) +); + +// updated colors +[...geo.attribValues("col")] +// [ Float32Array [ 0, 0.5, 0.5 ], +// Float32Array [ 1, 0.5, 0.5 ], +// Float32Array [ 0.8535534143447876, 0.8535534143447876, 0.5 ], +// Float32Array [ 0.1464466154575348, 0.8535534143447876, 0.5 ] ] + +// dynamically add another attrib +// this will change the overall stride length and re-align all existing attribs +geo.initAttribs({ + normal: { type: GLType.F32, size: 3, default: [0, 0, 1], byteOffset: 36 } +}); + +// updated overall stride length +geo.byteStrength +// 48 + +// only need to use & bind single (interleaved) buffer +// containing all attribs +buf = gl.createBuffer(); +gl.bindBuffer(gl.ARRAY_BUFFER, buf); +gl.bufferData(gl.ARRAY_BUFFER, geo.bytes(), gl.STATIC_DRAW); + +// helper fn to bind a single shader attrib +const initAttrib = (gl, loc, attrib) => { + gl.enableVertexAttribArray(loc); + gl.vertexAttribPointer( + loc, + attrib.size, + attrib.type, + false, + attrib.byteStride, // computed by pool + attrib.byteOffset + ); +}; + +initAttrib(gl, attribLocPosition, geo.specs.pos); +initAttrib(gl, attribLocNormal, geo.specs.normal); +initAttrib(gl, attribLocUV, geo.specs.uv); +initAttrib(gl, attribLocID, geo.specs.id); +``` + +### WASM interop + +```c +// main.c + +#include +#include + +typedef struct { + float pos[3]; + float uv[2]; + float col[3]; + uint16_t id; +} Vertex; + +const Vertex vertices[4]; + +int main() { + return 0; +} + +Vertex vertices[4] = { + {.pos = {-5, 0, 0}, .uv = {0, 0}, .col = {1, 0, 0}, .id = 0}, + {.pos = {5, 0, 0}, .uv = {1, 0}, .col = {0, 1, 0}, .id = 1}, + {.pos = {5, 5, 0}, .uv = {1, 1}, .col = {0, 0, 1}, .id = 2}, + {.pos = {-5, 5, 0}, .uv = {0, 1}, .col = {1, 0, 1}, .id = 3}, +}; + +int main() { return 0; } + +EMSCRIPTEN_KEEPALIVE Vertex* getVertices() { + return vertices; +} + +EMSCRIPTEN_KEEPALIVE int getNumVertices() { + return sizeof(vertices) / sizeof(Vertex); +} +``` + ```ts -import * as vp from "@thi.ng/vector-pools"; +// ... WASM / Emscripten boilerplate omitted +const Module = ... + +// +const geo = new vp.AttribPool( + // map WASM memory + Module.buffer, + // num elements (obtained from C function) + Module._getNumVertices(), + // attrib specs (data mapping layout) + // don't specify attrib defaults to avoid overriding + // values already initialized by WASM code + { + pos: { type: vp.GLType.F32, size: 3, byteOffset: 0 }, + uv: { type: vp.GLType.F32, size: 2, byteOffset: 12 }, + col: { type: vp.GLType.F32, size: 3, byteOffset: 20 }, + id: { type: vp.GLType.U16, size: 1, byteOffset: 32 } + }, + // pool options + { + // don't allow resizing (since we're mapping a fixed sized C array) + resizable: false, + // initialize mem pool to start @ C `vertices` array + mempool: { + start: Module._getVertices(), + } + } +); + +[...geo.attribValues("pos")] +// [ Float32Array [ -5, 0, 0 ], +// Float32Array [ 5, 0, 0 ], +// Float32Array [ 5, 5, 0 ], +// Float32Array [ -5, 5, 0 ] ] ``` ## Authors From 3a51a42d012c4fa9f44c27dcb01bed1be55f820c Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 30 Nov 2018 15:12:33 +0000 Subject: [PATCH 067/333] docs(vector-pools): fix readme links --- packages/vector-pools/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/vector-pools/README.md b/packages/vector-pools/README.md index e958b7e3ec..64a136f7ab 100644 --- a/packages/vector-pools/README.md +++ b/packages/vector-pools/README.md @@ -24,7 +24,7 @@ This project is part of the This still unreleased package provides various data structures for managing & working with memory mapped vectors. Together with -[@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/master/packages/vectors3) +[@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3) (also still unreleased) these structures enable high-level, zero-copy* manipulation of the underlying memory region and are largely intended for WebGL & WASM use cases, e.g. to provide JS @@ -43,7 +43,7 @@ yarn add @thi.ng/vector-pools - [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/master/packages/api) - [@thi.ng/malloc](https://github.com/thi-ng/umbrella/tree/master/packages/malloc) -- [@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/master/packages/vectors3) +- [@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/vec-refactor/packages/vectors3) ## Usage examples From 27ea8c4a333121720e28825d2dbd56433581a78f Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 30 Nov 2018 15:19:55 +0000 Subject: [PATCH 068/333] minor(vector-pools): fix typos in readme --- packages/vector-pools/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/vector-pools/README.md b/packages/vector-pools/README.md index 64a136f7ab..5f4a2b5e61 100644 --- a/packages/vector-pools/README.md +++ b/packages/vector-pools/README.md @@ -72,7 +72,7 @@ const geo = new AttribPool( ); // computed overall stride length -geo.byteStrength +geo.byteStride // 36 // set attrib values @@ -115,7 +115,7 @@ geo.initAttribs({ }); // updated overall stride length -geo.byteStrength +geo.byteStride // 48 // only need to use & bind single (interleaved) buffer From 21d107d95f8c3e8a15f0d47dc816ce7a55cf705b Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 30 Nov 2018 15:39:55 +0000 Subject: [PATCH 069/333] docs(vector-pools): update/fix readme --- packages/vector-pools/README.md | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/packages/vector-pools/README.md b/packages/vector-pools/README.md index 5f4a2b5e61..cdd0fbc54c 100644 --- a/packages/vector-pools/README.md +++ b/packages/vector-pools/README.md @@ -43,7 +43,7 @@ yarn add @thi.ng/vector-pools - [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/master/packages/api) - [@thi.ng/malloc](https://github.com/thi-ng/umbrella/tree/master/packages/malloc) -- [@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/vec-refactor/packages/vectors3) +- [@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3) ## Usage examples @@ -52,6 +52,7 @@ yarn add @thi.ng/vector-pools ```ts import { AttribPool, GLType } from "@thi.ng/vector-pools"; import * as v from "@thi.ng/vectors3"; +import * as tx from "@thi.ng/transducers"; // ...Webgl boilerplate omitted const gl = ... @@ -95,7 +96,7 @@ v.mulN(null, geo.attribValue("pos", 3), 2); // Float32Array [ 5, 5, 0 ], // Float32Array [ -10, 10, 0 ] ] -// use with transducers, e.g. to compute map positions to colors +// use with transducers, e.g. to map positions to colors tx.run( tx.map(([pos, col]) => v.maddN(col, [0.5, 0.5, 0.5], v.normalize(col, pos), 0.5)), tx.tuples(geo.attribValues("pos"), geo.attribValues("col")) @@ -158,13 +159,7 @@ typedef struct { uint16_t id; } Vertex; -const Vertex vertices[4]; - -int main() { - return 0; -} - -Vertex vertices[4] = { +Vertex vertices[] = { {.pos = {-5, 0, 0}, .uv = {0, 0}, .col = {1, 0, 0}, .id = 0}, {.pos = {5, 0, 0}, .uv = {1, 0}, .col = {0, 1, 0}, .id = 1}, {.pos = {5, 5, 0}, .uv = {1, 1}, .col = {0, 0, 1}, .id = 2}, From b415c803baa44c3709fde986513d4db12a0e50bd Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 30 Nov 2018 16:00:40 +0000 Subject: [PATCH 070/333] refactor(vector-pools): update AttribPool internals - rename initAttribs() => addAttribs() - rename validateAttribs() => validateSpecs() - rename realignAttribs() => realign() - re-order checks in attribValue() --- packages/vector-pools/README.md | 2 +- packages/vector-pools/src/attrib-pool.ts | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/vector-pools/README.md b/packages/vector-pools/README.md index cdd0fbc54c..5cc54f3582 100644 --- a/packages/vector-pools/README.md +++ b/packages/vector-pools/README.md @@ -111,7 +111,7 @@ tx.run( // dynamically add another attrib // this will change the overall stride length and re-align all existing attribs -geo.initAttribs({ +geo.addAttribs({ normal: { type: GLType.F32, size: 3, default: [0, 0, 1], byteOffset: 36 } }); diff --git a/packages/vector-pools/src/attrib-pool.ts b/packages/vector-pools/src/attrib-pool.ts index 228d3cd090..2ce68fa8e8 100644 --- a/packages/vector-pools/src/attrib-pool.ts +++ b/packages/vector-pools/src/attrib-pool.ts @@ -20,7 +20,7 @@ import { * uv (f32) : U U U U V V V V ... offset = 8 (bytes), size = 2 (f32) * col (u16) : R R G G B B A A ... offset = 16 (bytes), size = 4 (u16) * - * global stride: 16 + * global stride: 24 */ export class AttribPool implements IRelease { @@ -56,7 +56,7 @@ export class AttribPool implements this.order = []; this.byteStride = 1; this.maxAttribSize = 1; - this.initAttribs(specs, true); + this.addAttribs(specs, true); } bytes() { @@ -73,13 +73,13 @@ export class AttribPool implements return true; } - initAttribs(specs: IObjectOf, alloc = false) { + addAttribs(specs: IObjectOf, alloc = false) { const [newStride, maxSize] = this.computeStride(specs); this.maxAttribSize = maxSize; if (newStride != this.byteStride) { - this.realignAttribs(newStride); + this.realign(newStride); } - this.validateAttribs(specs, newStride); + this.validateSpecs(specs, newStride); this.byteStride = newStride; if (alloc) { const addr = this.pool.malloc(this.capacity * this.byteStride); @@ -90,9 +90,9 @@ export class AttribPool implements } attribValue(id: string, i: number): number | Vec { - if (i >= this.capacity) return; const spec = this.specs[id]; assert(!!spec, `invalid attrib: ${id}`); + if (i >= this.capacity) return; i *= spec.stride; return spec.size > 1 ? this.attribs[id].subarray(i, i + spec.size) : @@ -174,7 +174,7 @@ export class AttribPool implements this.updateOrder(); const [stride, size] = this.computeStride(this.specs, false); this.maxAttribSize = size; - this.realignAttribs(stride); + this.realign(stride); } ensure(newCapacity: number, fill = false) { @@ -214,7 +214,7 @@ export class AttribPool implements return [align(maxStride, maxSize), maxSize]; } - protected validateAttribs(specs: IObjectOf, stride = this.byteStride) { + protected validateSpecs(specs: IObjectOf, stride = this.byteStride) { for (let id in specs) { assert(!this.attribs[id], `attrib: ${id} already exists`); const a = specs[id]; @@ -272,7 +272,7 @@ export class AttribPool implements } } - protected realignAttribs(newByteStride: number) { + protected realign(newByteStride: number) { if (this.order.length === 0 || newByteStride === this.byteStride) return; console.warn(`realigning ${this.byteStride} -> ${newByteStride}...`); const grow = newByteStride > this.byteStride; From 84ab9b253d3c8f363e2a2b30542e18b5af7726a7 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 30 Nov 2018 16:51:18 +0000 Subject: [PATCH 071/333] docs(vectors): update readme --- packages/vectors3/README.md | 194 +++++++++++++++++++++++++++++++++++- 1 file changed, 192 insertions(+), 2 deletions(-) diff --git a/packages/vectors3/README.md b/packages/vectors3/README.md index 74e319094d..e72b043ece 100644 --- a/packages/vectors3/README.md +++ b/packages/vectors3/README.md @@ -9,11 +9,55 @@ This project is part of the +- [About](#about) + - [Features](#features) +- [Installation](#installation) +- [Dependencies](#dependencies) +- [Usage examples](#usage-examples) + - [API](#api) +- [Authors](#authors) +- [License](#license) + ## About -TODO... +**This still unreleased package will soon replace the existing +[@thi.ng/vectors](https://github.com/thi-ng/umbrella/tree/master/packages/vectors) +package.** + +This package provides 100+ functions & supporting types to perform +vector operations on fixed and arbitrary-length vectors, both packed and +strided (i.e. where individual vector components are not successive +array elements, for example in SOA layouts). + +### Features + +- Small & fast: The vast majority of these functions are code generated + with fixed-sized versions not using any loops. +- Unified API: Most functions are implemented as multi-methods, + dispatching to any potentially optimized versions based on given + vector arguments. +- Each function is defined in its own submodule. In addition to the + generic multi-method base function, all fixed-length optimized + versions are exported too. E.g. If `add` performs vector addition on + arbitrary-length vectors, `add2`, `add3`, `add4` are the optimized + version for fixed-length vectors... +- Extensible. Custom vector ops can be defined in a similar manner using + the provided code generation helpers. +- Immutable by default. Each operation producing a vector result takes + an output vector as first argument. If `null`, the vector given as 2nd + argument will be used as output (i.e. for mutation). +- Strided vector support is handled via the + [`Vec2/3/4`](https://github.com/thi-ng/umbrella/feature/vec-refactor/packages/vectors3/src/vec2.ts) + class wrappers and the + [`gvec()`](https://github.com/thi-ng/umbrella/feature/vec-refactor/packages/vectors3/src/gvec.ts) + proxy (for generic, arbitrary-length vectors). These types behave like + normal arrays (for read/write operations) and are also iterable. A + subset of functions (suffixed with `S`, e.g. `addS` vs. `add`) also + support striding without the need for extra class wrappers. This is + handled via additional index and stride arguments for each + input/output vector. ## Installation @@ -23,14 +67,160 @@ yarn add @thi.ng/vectors3 ## Dependencies -- TODO... +- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/master/packages/api) +- [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/master/packages/checks) +- [@thi.ng/equiv](https://github.com/thi-ng/umbrella/tree/master/packages/equiv) +- [@thi.ng/math](https://github.com/thi-ng/umbrella/tree/master/packages/math) +- [@thi.ng/random](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/random) +- [@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/master/packages/transducers) ## Usage examples ```ts import * as v from "@thi.ng/vectors3"; + +v.add([], [1, 2, 3, 4], [10, 20, 30, 40]) +// [11, 22, 33, 44] + +// multiply-add (o = a + b * c) +v.madd([], [1,2], [10, 20], [0.5, 0.25]); +// [6, 7] + +// scalar addition +v.addN([], gvec([0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0], 3, 1, 4), 10) +// [11, 12, 13] + +v.dist([1,2], [100, 200]) +// 221.37072977247917 + +v.distManhattan([1,2], [100, 200]) +// 297 + +v.distChebyshev([1,2], [100, 200]) +// 198 + +v.mixN([], [1, 2], [10, 20], 0.5); +// [5.5, 11] + +v.fromHomogeneous([], [100, 200, 0.5]) +// [200, 400] + +v.swizzle4([], [1, 2], 1, 1, 0, 0) +// [ 2, 2, 1, 1 ] ``` +### API + +(Incomplete) list of functions: + +- abs +- acos +- add +- addN +- addS +- angleBetween +- asin +- bisect +- cartesian +- ceil +- clamp +- clampN +- compare +- copy +- cos +- cosh +- cross +- distChebyshev +- distManhattan +- dist +- distSq +- div +- divN +- divS +- dotValues +- dot +- dotS +- empty +- eqDelta +- exp +- faceForward +- floor +- fract +- gvec +- headingXY +- headingXZ +- headingYZ +- fromHomogeneous +- invert +- invSqrt +- jitter +- limit +- log +- madd +- maddN +- mag +- magSq +- major +- max +- min +- minor +- mixBilinear +- mix +- mixN +- mod +- modN +- mul +- mulN +- mulS +- neg +- normalize +- one +- ones +- orthoNormal +- perpendicularLeft +- perpendicularRight +- polar +- pow +- powN +- project +- random +- randNorm +- reflect +- refract +- rotateAroundAxis +- rotateAroundPoint +- rotateX +- rotateY +- rotateZ +- round +- set +- setN +- setS +- setSN +- sign +- sin +- sinh +- smoothstep +- sqrt +- step +- sub +- subN +- subS +- sum +- swizzle +- tan +- tanh +- trunc +- vec2 +- vec2n +- vec3 +- vec3n +- vec4 +- vec4n +- wrap +- zero +- zeroes + ## Authors - Karsten Schmidt From 9f36a68158c2e957190f1747037955f683784454 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 30 Nov 2018 17:03:58 +0000 Subject: [PATCH 072/333] docs(vectors): update readme --- packages/vectors3/README.md | 45 ++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/packages/vectors3/README.md b/packages/vectors3/README.md index e72b043ece..066724fa0b 100644 --- a/packages/vectors3/README.md +++ b/packages/vectors3/README.md @@ -31,33 +31,46 @@ vector operations on fixed and arbitrary-length vectors, both packed and strided (i.e. where individual vector components are not successive array elements, for example in SOA layouts). +Use the supporting +[@thi.ng/vector-pools](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vector-pools) +package to directly operate on memory mapped data. + ### Features - Small & fast: The vast majority of these functions are code generated with fixed-sized versions not using any loops. -- Unified API: Most functions are implemented as multi-methods, - dispatching to any potentially optimized versions based on given - vector arguments. -- Each function is defined in its own submodule. In addition to the - generic multi-method base function, all fixed-length optimized - versions are exported too. E.g. If `add` performs vector addition on +- Unified API: Any `ArrayLike` type can be used as vector containers + (e.g. JS arrays, typed arrays, custom impls). Most functions are + implemented as multi-methods, dispatching to any potentially optimized + versions based on given vector arguments. +- Each function is defined in its own submodule / file. In addition to + each generic multi-method base function, all fixed-length optimized + versions are exported too. E.g. If [`add`](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/add.ts) performs vector addition on arbitrary-length vectors, `add2`, `add3`, `add4` are the optimized version for fixed-length vectors... - Extensible. Custom vector ops can be defined in a similar manner using - the provided code generation helpers. + the provided code generation helpers (see [vop.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/vop.ts) and + [codegen.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/codegen.ts) + for details). - Immutable by default. Each operation producing a vector result takes an output vector as first argument. If `null`, the vector given as 2nd argument will be used as output (i.e. for mutation). -- Strided vector support is handled via the - [`Vec2/3/4`](https://github.com/thi-ng/umbrella/feature/vec-refactor/packages/vectors3/src/vec2.ts) +- Strided vector support is handled via the lightweight + [`Vec2/3/4`](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/vec2.ts) class wrappers and the - [`gvec()`](https://github.com/thi-ng/umbrella/feature/vec-refactor/packages/vectors3/src/gvec.ts) + [`gvec()`](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/gvec.ts) proxy (for generic, arbitrary-length vectors). These types behave like normal arrays (for read/write operations) and are also iterable. A - subset of functions (suffixed with `S`, e.g. `addS` vs. `add`) also - support striding without the need for extra class wrappers. This is - handled via additional index and stride arguments for each - input/output vector. + subset of functions (suffixed with `S`, e.g. + [`addS`](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/adds.ts) + vs. `add`) also support striding without the need for extra class + wrappers. This is handled via additional index and stride arguments + for each input/output vector. These functions are only available for + sizes 2 / 3 / 4, though. +- Random vector functions support the `IRandom` interface defined by + [@thi.ng/random](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/random) + to work with custom (P)RNGs. If omitted, the built-in `Math.random()` + will be used. ## Installation @@ -67,10 +80,10 @@ yarn add @thi.ng/vectors3 ## Dependencies -- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/master/packages/api) +- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/api) - [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/master/packages/checks) - [@thi.ng/equiv](https://github.com/thi-ng/umbrella/tree/master/packages/equiv) -- [@thi.ng/math](https://github.com/thi-ng/umbrella/tree/master/packages/math) +- [@thi.ng/math](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/math) - [@thi.ng/random](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/random) - [@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/master/packages/transducers) From 87510f743f92d590f6bf673e52b64d4d11d48af0 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 30 Nov 2018 22:41:17 +0000 Subject: [PATCH 073/333] feat(vectors): add addWeighted, eqDeltaArray, mixCubic, mixQuadratic --- packages/vectors3/README.md | 5 ++++ packages/vectors3/src/add-weighted.ts | 39 ++++++++++++++++++++++++++ packages/vectors3/src/eqdelta.ts | 11 ++++++++ packages/vectors3/src/index.ts | 3 ++ packages/vectors3/src/mix-cubic.ts | 10 +++++++ packages/vectors3/src/mix-quadratic.ts | 8 ++++++ 6 files changed, 76 insertions(+) create mode 100644 packages/vectors3/src/add-weighted.ts create mode 100644 packages/vectors3/src/mix-cubic.ts create mode 100644 packages/vectors3/src/mix-quadratic.ts diff --git a/packages/vectors3/README.md b/packages/vectors3/README.md index 066724fa0b..3d140ae9cb 100644 --- a/packages/vectors3/README.md +++ b/packages/vectors3/README.md @@ -131,6 +131,7 @@ v.swizzle4([], [1, 2], 1, 1, 0, 0) - add - addN - addS +- addWeighted - angleBetween - asin - bisect @@ -155,6 +156,8 @@ v.swizzle4([], [1, 2], 1, 1, 0, 0) - dotS - empty - eqDelta +- eqDeltaS +- eqDeltaArray - exp - faceForward - floor @@ -178,6 +181,8 @@ v.swizzle4([], [1, 2], 1, 1, 0, 0) - min - minor - mixBilinear +- mixCubic +- mixQuadratic - mix - mixN - mod diff --git a/packages/vectors3/src/add-weighted.ts b/packages/vectors3/src/add-weighted.ts new file mode 100644 index 0000000000..0a21d0ea0c --- /dev/null +++ b/packages/vectors3/src/add-weighted.ts @@ -0,0 +1,39 @@ +import { ReadonlyVec, Vec } from "./api"; +import { maddN } from "./maddn"; +import { mulN } from "./muln"; + +export const addWeighted2 = + (out: Vec, a: ReadonlyVec, b: ReadonlyVec, wa: number, wb: number) => + maddN(out, + mulN(out, a, wa), + b, wb); + +export const addWeighted3 = + (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, wa: number, wb: number, wc: number) => + maddN(out, + maddN(out, + mulN(out, a, wa), + b, wb), + c, wc); + +export const addWeighted4 = + (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, + wa: number, wb: number, wc: number, wd: number) => + maddN(out, + maddN(out, + maddN(out, + mulN(out, a, wa), b, wb), + c, wc), + d, wd); + +export const addWeighted5 = + (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, e: ReadonlyVec, + wa: number, wb: number, wc: number, wd: number, we: number) => + maddN(out, + maddN(out, + maddN(out, + maddN(out, + mulN(out, a, wa), b, wb), + c, wc), + d, wd), + e, we); diff --git a/packages/vectors3/src/eqdelta.ts b/packages/vectors3/src/eqdelta.ts index dbb6773ebd..a0db5f3297 100644 --- a/packages/vectors3/src/eqdelta.ts +++ b/packages/vectors3/src/eqdelta.ts @@ -70,3 +70,14 @@ export const eqDeltaS = ( } return true; }; + +export const eqDeltaArray = (a: ReadonlyVec[], b: ReadonlyVec[], eps = EPS) => { + if (a === b) return true; + if (a.length !== b.length) return false; + for (let i = a.length; --i >= 0;) { + if (!eqDelta(a[i], b[i], eps)) { + return false; + } + } + return true; +}; diff --git a/packages/vectors3/src/index.ts b/packages/vectors3/src/index.ts index 39e8e5372c..814c1cc096 100644 --- a/packages/vectors3/src/index.ts +++ b/packages/vectors3/src/index.ts @@ -8,6 +8,7 @@ export * from "./vec4"; export * from "./abs"; export * from "./acos"; +export * from "./add-weighted"; export * from "./add"; export * from "./addn"; export * from "./adds"; @@ -57,6 +58,8 @@ export * from "./max"; export * from "./min"; export * from "./minor"; export * from "./mix-bilinear"; +export * from "./mix-cubic"; +export * from "./mix-quadratic"; export * from "./mix"; export * from "./mixn"; export * from "./mod"; diff --git a/packages/vectors3/src/mix-cubic.ts b/packages/vectors3/src/mix-cubic.ts new file mode 100644 index 0000000000..e29dcd3e16 --- /dev/null +++ b/packages/vectors3/src/mix-cubic.ts @@ -0,0 +1,10 @@ +import { ReadonlyVec, Vec } from "./api"; +import { addWeighted4 } from "./add-weighted"; + +export const mixCubic = + (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, t: number) => { + const s = 1 - t; + const s2 = s * s; + const t2 = t * t; + return addWeighted4(out, a, b, c, d, s2 * s, 3 * s2 * t, 3 * t2 * s, t2 * t); + }; diff --git a/packages/vectors3/src/mix-quadratic.ts b/packages/vectors3/src/mix-quadratic.ts new file mode 100644 index 0000000000..1cfee23f72 --- /dev/null +++ b/packages/vectors3/src/mix-quadratic.ts @@ -0,0 +1,8 @@ +import { addWeighted3 } from "./add-weighted"; +import { ReadonlyVec, Vec } from "./api"; + +export const mixQuadratic = + (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, t: number) => { + const s = 1 - t; + return addWeighted3(out, a, b, c, s * s, 2 * s * t, t * t); + }; From 68806d93a008d86d8b05d8995e4f27fc75befffc Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 30 Nov 2018 23:37:46 +0000 Subject: [PATCH 074/333] feat(vectors): add 2d/3d constants, update Vec2/3 --- packages/vectors3/src/api.ts | 16 ++++++++++++++++ packages/vectors3/src/vec2.ts | 26 ++++++++++++-------------- packages/vectors3/src/vec3.ts | 28 ++++++++++++++-------------- 3 files changed, 42 insertions(+), 28 deletions(-) diff --git a/packages/vectors3/src/api.ts b/packages/vectors3/src/api.ts index 242415d79f..204aa503b4 100644 --- a/packages/vectors3/src/api.ts +++ b/packages/vectors3/src/api.ts @@ -79,6 +79,22 @@ export interface MultiVecOpRoVVO extends VecOpRoVVO, MultiVecOp Date: Sat, 1 Dec 2018 01:15:03 +0000 Subject: [PATCH 075/333] refactor(geom): update everything to use new vectors package --- packages/geom2/package.json | 9 +- packages/geom2/src/api.ts | 47 ++++---- packages/geom2/src/arc.ts | 35 +++--- packages/geom2/src/bezier.ts | 103 +++++------------- packages/geom2/src/circle.ts | 43 ++++---- packages/geom2/src/container2.ts | 20 ++-- packages/geom2/src/ellipse.ts | 26 ++--- packages/geom2/src/internal/arc.ts | 8 +- packages/geom2/src/internal/barycentric.ts | 29 +++-- packages/geom2/src/internal/bounds.ts | 25 ++--- packages/geom2/src/internal/centroid.ts | 26 ++--- packages/geom2/src/internal/circumcenter.ts | 2 +- packages/geom2/src/internal/closest-point.ts | 25 ++--- packages/geom2/src/internal/corner.ts | 43 ++------ packages/geom2/src/internal/direction.ts | 12 +- .../internal/douglas\342\200\223peucker.ts" | 10 +- packages/geom2/src/internal/edges.ts | 2 +- packages/geom2/src/internal/graham-scan.ts | 8 +- .../geom2/src/internal/greiner-hormann.ts | 2 +- packages/geom2/src/internal/liang-barsky.ts | 13 +-- .../geom2/src/internal/line-intersection.ts | 7 +- packages/geom2/src/internal/offset.ts | 8 +- packages/geom2/src/internal/perimeter.ts | 3 +- packages/geom2/src/internal/polygon.ts | 4 +- packages/geom2/src/internal/sampler.ts | 21 ++-- packages/geom2/src/internal/subdiv-curve.ts | 33 ++---- .../geom2/src/internal/sutherland-hodgeman.ts | 2 +- packages/geom2/src/internal/transform.ts | 8 +- packages/geom2/src/internal/warp.ts | 2 +- packages/geom2/src/line.ts | 21 ++-- packages/geom2/src/path.ts | 62 +++++------ packages/geom2/src/polygon.ts | 21 ++-- packages/geom2/src/polyline.ts | 21 ++-- packages/geom2/src/quad.ts | 13 ++- packages/geom2/src/rect.ts | 47 ++++---- packages/geom2/src/tessellate.ts | 16 +-- packages/geom2/src/triangle.ts | 47 ++++---- packages/geom2/test/clip.ts | 10 +- 38 files changed, 363 insertions(+), 471 deletions(-) diff --git a/packages/geom2/package.json b/packages/geom2/package.json index 86a3474005..ed74bfe0b9 100644 --- a/packages/geom2/package.json +++ b/packages/geom2/package.json @@ -31,11 +31,12 @@ "@thi.ng/api": "^4.2.3", "@thi.ng/checks": "^1.5.13", "@thi.ng/defmulti": "^0.5.0", - "@thi.ng/hiccup": "^2.4.3", - "@thi.ng/hiccup-svg": "^2.0.4", + "@thi.ng/hiccup": "^2.6.0", + "@thi.ng/hiccup-svg": "^2.0.6", "@thi.ng/malloc": "^0.2.0", - "@thi.ng/math": "^0.2.0", - "@thi.ng/vectors2": "^0.0.1" + "@thi.ng/math": "^0.2.1", + "@thi.ng/matrices": "^0.0.1", + "@thi.ng/vectors3": "^0.0.1" }, "keywords": [ "ES6", diff --git a/packages/geom2/src/api.ts b/packages/geom2/src/api.ts index 9386aa1366..c0d6e1a4f7 100644 --- a/packages/geom2/src/api.ts +++ b/packages/geom2/src/api.ts @@ -12,21 +12,18 @@ import { } from "@thi.ng/defmulti"; import { equiv } from "@thi.ng/equiv"; import { cossin } from "@thi.ng/math/angle"; -import { - add, - copy, - IMatrix, - max, - min, - mixNewN, - mul, - ReadonlyVec, - rotateZ, - subNew, - Vec, - neg -} from "@thi.ng/vectors2/api"; -import { perpendicularLeft2, set2 } from "@thi.ng/vectors2/vec2"; +import { ReadonlyMat } from "@thi.ng/matrices/api"; +import { add } from "@thi.ng/vectors3/add"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { copy } from "@thi.ng/vectors3/copy"; +import { mixN } from "@thi.ng/vectors3/mixn"; +import { mul } from "@thi.ng/vectors3/mul"; +import { min } from "@thi.ng/vectors3/min"; +import { max } from "@thi.ng/vectors3/max"; +import { neg } from "@thi.ng/vectors3/neg"; +import { sub } from "@thi.ng/vectors3/sub"; +import { perpendicularLeft2 } from "@thi.ng/vectors3/perpendicular"; +import { rotateZ } from "@thi.ng/vectors3/rotate"; import { subdivKernel3 } from "./internal/subdiv-curve"; import { warpPoints } from "./internal/warp"; @@ -231,8 +228,8 @@ export const bounds = defmulti(dispatch); export const center: MultiFn1O = defmulti(dispatch); center.add(DEFAULT, (x, origin?) => { - const delta = neg(centroid(x)); - return translate(x, origin ? add(delta, origin) : delta); + const delta = neg(null, centroid(x)); + return translate(x, origin ? add(null, delta, origin) : delta); }); export const centroid: MultiFn1O = defmulti(dispatch); @@ -271,7 +268,7 @@ export const isEmpty = defmulti(dispatch); export const mapPoint: MultiFn2O = defmulti(dispatch); export const normalAt: MultiFn2O = defmulti(dispatch); -normalAt.add(DEFAULT, (shape, t, n = 1) => perpendicularLeft2(tangentAt(shape, t, n))); +normalAt.add(DEFAULT, (shape, t, n = 1) => perpendicularLeft2(null, tangentAt(shape, t, n))); export const offset: MultiFn2O = defmulti(dispatch); @@ -300,7 +297,7 @@ export const tangentAt: MultiFn2O = defmulti(dispat export const tessellate = defmulti, Vec[][]>(dispatch); -export const transform = defmulti, IShape>(dispatch); +export const transform = defmulti(dispatch); export const translate = defmulti(dispatch); @@ -431,7 +428,7 @@ export class Arc2 implements } pointAtTheta(theta: number, pos: Vec = []) { - return add(rotateZ(mul(set2(pos, cossin(theta)), this.r), this.axis), this.pos); + return add(null, rotateZ(null, mul(pos, cossin(theta), this.r), this.axis), this.pos); } toHiccup() { @@ -489,7 +486,7 @@ export class Cubic2 extends PointContainer implements IHiccupPathSegment { static fromLine(a: Vec, b: Vec, attribs?: Attribs) { - return new Cubic2([a, mixNewN(a, b, 1 / 3), mixNewN(b, a, 1 / 3), b], attribs); + return new Cubic2([a, mixN([], a, b, 1 / 3), mixN([], b, a, 1 / 3), b], attribs); } constructor(points: Vec[], attribs?: Attribs) { @@ -721,7 +718,7 @@ export class Quadratic2 extends PointContainer implements IHiccupPathSegment { static fromLine(a: Vec, b: Vec, attribs?: Attribs) { - return new Quadratic2([a, mixNewN(a, b, 0.5), b], attribs); + return new Quadratic2([a, mixN([], a, b, 0.5), b], attribs); } constructor(points: Vec[], attribs?: Attribs) { @@ -752,9 +749,9 @@ export class Rect2 implements IShape { static fromMinMax(mi: Vec, mx: Vec, attribs?: Attribs) { - const _mi = min(copy(mi), mx); - const _mx = max(copy(mx), mi); - return new Rect2(_mi, subNew(_mx, _mi), attribs); + const _mi = min([], mi, mx); + const _mx = max([], mx, mi); + return new Rect2(_mi, sub(null, _mx, _mi), attribs); } pos: Vec; diff --git a/packages/geom2/src/arc.ts b/packages/geom2/src/arc.ts index be9e2c14bb..24e6bf4491 100644 --- a/packages/geom2/src/arc.ts +++ b/packages/geom2/src/arc.ts @@ -16,17 +16,19 @@ import { push } from "@thi.ng/transducers/rfn/push"; import { transduce } from "@thi.ng/transducers/transduce"; import { filter } from "@thi.ng/transducers/xform/filter"; import { map } from "@thi.ng/transducers/xform/map"; +import { abs2 } from "@thi.ng/vectors3/abs"; +import { add2 } from "@thi.ng/vectors3/add"; +import { angleBetween } from "@thi.ng/vectors3/angle-between"; import { - abs, - add, - angleBetween, - magSq, - mulN, + MAX2, + MIN2, ReadonlyVec, - subNew, - Vec -} from "@thi.ng/vectors2/api"; -import { Vec2 } from "@thi.ng/vectors2/vec2"; + Vec, + X2 +} from "@thi.ng/vectors3/api"; +import { magSq2 } from "@thi.ng/vectors3/magsq"; +import { mulN2 } from "@thi.ng/vectors3/muln"; +import { sub2 } from "@thi.ng/vectors3/sub"; import "./bezier"; import { bounds as _bounds } from "./internal/bounds"; import { Sampler } from "./internal/sampler"; @@ -57,17 +59,17 @@ export function arcFrom2Points( large = false, clockwise = true) { - const r = abs([...radii]); + const r = abs2([], radii); const co = Math.cos(axisTheta); const si = Math.sin(axisTheta); - const m = mulN(subNew(a, b), 0.5); + const m = mulN2(null, sub2([], a, b), 0.5); const px = co * m[0] + si * m[1]; const py = -si * m[0] + co * m[1]; const px2 = px * px; const py2 = py * py; const l = px2 / (r[0] * r[0]) + py2 / (r[1] * r[1]); - l > 1 && mulN(r, Math.sqrt(l)); + l > 1 && mulN2(null, r, Math.sqrt(l)); const rx2 = r[0] * r[0]; const ry2 = r[1] * r[1]; @@ -81,7 +83,7 @@ export function arcFrom2Points( const d1 = [(px - tc[0]) / r[0], (py - tc[1]) / r[1]]; const d2 = [(-px - tc[0]) / r[0], (-py - tc[1]) / r[1]]; - const theta = angleBetween(Vec2.X_AXIS, d1, true); + const theta = angleBetween(X2, d1, true); let delta = angleBetween(d1, d2, true); if (clockwise && delta < 0) { @@ -106,14 +108,15 @@ implementations( const [sphi, cphi] = sincos(arc.axis); const dx = cphi * (p[0] - q[0]) / 2 + sphi * (p[1] - q[1]) / 2; const dy = -sphi * (p[0] - q[0]) / 2 + cphi * (p[1] - q[1]) / 2; - if ((dx === 0 && dy === 0) || magSq(arc.r) < EPS) { + if ((dx === 0 && dy === 0) || magSq2(arc.r) < EPS) { return [Cubic2.fromLine(p, q, { ...arc.attribs })]; } const mapP = (x: number, y: number) => { x *= rx; y *= ry; - return add( + return add2( + null, [ cphi * x - sphi * y, sphi * x + cphi * y @@ -163,7 +166,7 @@ implementations( ) ] ); - return Rect2.fromMinMax(..._bounds(pts, [...Vec2.MAX], [...Vec2.MIN])); + return Rect2.fromMinMax(..._bounds(pts, [...MAX2], [...MIN2])); }, centroid, diff --git a/packages/geom2/src/bezier.ts b/packages/geom2/src/bezier.ts index 2f849877ec..64df4bbf12 100644 --- a/packages/geom2/src/bezier.ts +++ b/packages/geom2/src/bezier.ts @@ -3,21 +3,8 @@ import { isPlainObject } from "@thi.ng/checks/is-plain-object"; import { implementations } from "@thi.ng/defmulti"; import { clamp01 } from "@thi.ng/math/interval"; import { mixCubic as _mixC, mixQuadratic as _mixQ } from "@thi.ng/math/mix"; -import { - copy, - maddN, - max, - min, - mixNewN, - mulNewN, - MultiVecOpNewVVVN, - MultiVecOpNewVVVVN, - ReadonlyVec, - Vec -} from "@thi.ng/vectors2/api"; -import { compile } from "@thi.ng/vectors2/internal/codegen"; -import { vop } from "@thi.ng/vectors2/internal/ops"; -import { Mat23 } from "@thi.ng/vectors2/mat23"; +import { Vec } from "@thi.ng/vectors3/api"; +import { Mat } from "@thi.ng/matrices/api"; import { asCubic, asPolyline, @@ -38,6 +25,12 @@ import { } from "./api"; import { Sampler } from "./internal/sampler"; import { transformPoints } from "./internal/transform"; +import { mixCubic } from "@thi.ng/vectors3/mix-cubic"; +import { mixQuadratic } from "@thi.ng/vectors3/mix-quadratic"; +import { copy } from "@thi.ng/vectors3/copy"; +import { mixN } from "@thi.ng/vectors3/mixn"; +import { min } from "@thi.ng/vectors3/min"; +import { max } from "@thi.ng/vectors3/max"; export function cubic2(points: Vec[], attribs?: Attribs): Cubic2 { return new Cubic2(points, attribs); @@ -47,44 +40,6 @@ export function quadratic2(points: Vec[], attribs?: Attribs): Quadratic2 { return new Quadratic2(points, attribs); } -const compileMixQ = (dim: number) => - compile( - dim, - ([a, b, c, o]) => `${o} = ${a}*wa + ${b}*wb + ${c}*wc;`, - "a,b,c,t,o=[]", - "a,b,c,o", - "o", - "const s=1-t, wa=s*s, wb=2*s*t, wc=t*t;" - ); - -const compileMixC = (dim: number) => - compile( - dim, - ([a, b, c, d, o]) => `${o} = ${a}*wa + ${b}*wb + ${c}*wc + ${d}*wd;`, - "a,b,c,d,t,o=[]", - "a,b,c,d,o", - "o", - "const s=1-t, s2=s*s, t2=t*t, wa=s2*s, wb=3*s2*t, wc=3*t2*s, wd=t2*t;" - ); - -export const mixQuadratic: MultiVecOpNewVVVN = vop(); -mixQuadratic.add(2, compileMixQ(2)); -mixQuadratic.add(3, compileMixQ(3)); -mixQuadratic.default((a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, t: number, o: Vec = []) => { - const s = 1 - t; - return maddN(maddN(mulNewN(a, s * s, o), b, 2 * s * t), c, t * t); -}); - -export const mixCubic: MultiVecOpNewVVVVN = vop(); -mixCubic.add(2, compileMixC(2)); -mixCubic.add(3, compileMixC(3)); -mixCubic.default((a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, t: number, o: Vec = []) => { - const s = 1 - t; - const s2 = s * s; - const t2 = t * t; - return maddN(maddN(maddN(mulNewN(a, s2 * s, o), b, 3 * s2 * t), c, 3 * t2 * s), d, t2 * t); -}); - const cubicAxisBounds = (pa: number, pb: number, pc: number, pd: number) => { let a = 3 * pd - 9 * pc + 9 * pb - 3 * pa; let b = 6 * pa - 12 * pb + 6 * pc; @@ -139,7 +94,7 @@ implementations( pointAt, (curve: Cubic2, t: number) => { const pts = curve.points; - return mixCubic(pts[0], pts[1], pts[2], pts[3], t); + return mixCubic([], pts[0], pts[1], pts[2], pts[3], t); }, splitAt, @@ -151,12 +106,12 @@ implementations( const c2 = new Cubic2([copy(a), copy(b), copy(c), copy(d)]); return t <= 0 ? [c1, c2] : [c2, c1]; } - const ab = mixNewN(a, b, t); - const bc = mixNewN(b, c, t); - const cd = mixNewN(c, d, t); - const abc = mixNewN(ab, bc, t); - const bcd = mixNewN(bc, cd, t); - const p = mixNewN(abc, bcd, t); + const ab = mixN([], a, b, t); + const bc = mixN([], b, c, t); + const cd = mixN([], c, d, t); + const abc = mixN([], ab, bc, t); + const bcd = mixN([], bc, cd, t); + const p = mixN([], abc, bcd, t); return [ new Cubic2([[a[0], a[1]], [ab[0], ab[1]], [abc[0], abc[1]], [p[0], p[1]]]), new Cubic2([[p[0], p[1]], [bcd[0], bcd[1]], [cd[0], cd[1]], [d[0], d[1]]]) @@ -164,7 +119,7 @@ implementations( }, transform, - (curve: Cubic2, mat: Mat23) => + (curve: Cubic2, mat: Mat) => new Cubic2( transformPoints(curve.points, mat), { ...curve.attribs } @@ -189,7 +144,7 @@ implementations( const [a, b, c, d] = curve.points; const delta = 1 / opts.num; for (let t = 0; t < opts.num; t++) { - res.push(mixCubic(a, b, c, d, t * delta)); + res.push(mixCubic([], a, b, c, d, t * delta)); } opts.last && res.push([d[0], d[1]]); return res; @@ -212,8 +167,8 @@ implementations( new Cubic2( [ copy(a), - mixNewN(a, b, 2 / 3), - mixNewN(c, b, 2 / 3), + mixN([], a, b, 2 / 3), + mixN([], c, b, 2 / 3), copy(c) ], { ...curve.attribs } @@ -228,8 +183,8 @@ implementations( bounds, (curve: Quadratic2) => { const [a, b, c] = curve.points; - const mi = min(copy(a), c); - const ma = max(copy(a), c); + const mi = min([], a, c); + const ma = max([], a, c); const solve = (a, b, c) => { const t = clamp01((a - b) / (a - 2.0 * b + c)); const s = 1 - t; @@ -240,8 +195,8 @@ implementations( solve(a[0], b[0], c[0]), solve(a[1], b[1], c[1]), ]; - min(mi, q); - max(ma, q); + min(null, mi, q); + max(null, ma, q); } return Rect2.fromMinMax(mi, ma); }, @@ -249,7 +204,7 @@ implementations( pointAt, (curve: Quadratic2, t: number) => { const pts = curve.points; - return mixQuadratic(pts[0], pts[1], pts[2], t); + return mixQuadratic([], pts[0], pts[1], pts[2], t); }, splitAt, @@ -261,9 +216,9 @@ implementations( const c2 = new Quadratic2([copy(a), copy(b), copy(c)]); return t <= 0 ? [c1, c2] : [c2, c1]; } - const ab = mixNewN(a, b, t); - const bc = mixNewN(b, c, t); - const p = mixNewN(ab, bc, t); + const ab = mixN([], a, b, t); + const bc = mixN([], b, c, t); + const p = mixN([], ab, bc, t); return [ new Quadratic2([copy(a), ab, p]), new Quadratic2([p, bc, copy(c)]) @@ -271,7 +226,7 @@ implementations( }, transform, - (curve: Quadratic2, mat: Mat23) => + (curve: Quadratic2, mat: Mat) => new Quadratic2( transformPoints(curve.points, mat), { ...curve.attribs } @@ -296,7 +251,7 @@ implementations( const delta = 1 / opts.num; const [a, b, c] = curve.points; for (let t = 0; t < opts.num; t++) { - res.push(mixQuadratic(a, b, c, t * delta)); + res.push(mixQuadratic([], a, b, c, t * delta)); } opts.last && res.push([c[0], c[1]]); return res; diff --git a/packages/geom2/src/circle.ts b/packages/geom2/src/circle.ts index 59a9516c43..7338c98c24 100644 --- a/packages/geom2/src/circle.ts +++ b/packages/geom2/src/circle.ts @@ -2,21 +2,17 @@ import { isNumber } from "@thi.ng/checks/is-number"; import { implementations } from "@thi.ng/defmulti"; import { sign } from "@thi.ng/math/abs"; import { EPS, PI, TAU } from "@thi.ng/math/api"; -import { - add, - addNew, - cartesian, - copy, - dist, - distSq, - mixNewN, - mulN, - normalize, - ReadonlyVec, - subNew, - subNewN, - Vec -} from "@thi.ng/vectors2/api"; +import { add2 } from "@thi.ng/vectors3/add"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { cartesian2 } from "@thi.ng/vectors3/cartesian"; +import { copy } from "@thi.ng/vectors3/copy"; +import { dist } from "@thi.ng/vectors3/dist"; +import { distSq2 } from "@thi.ng/vectors3/distsq"; +import { mixN2 } from "@thi.ng/vectors3/mixn"; +import { mulN2 } from "@thi.ng/vectors3/muln"; +import { normalize } from "@thi.ng/vectors3/normalize"; +import { sub2 } from "@thi.ng/vectors3/sub"; +import { subN2 } from "@thi.ng/vectors3/subn"; import { circumCenter } from "./internal/circumcenter"; import "./polygon"; import { @@ -45,7 +41,7 @@ export function circle(pos: Vec, r = 1, attribs?: Attribs): Circle2 { export const circleFrom2Points = (a: ReadonlyVec, b: ReadonlyVec, attribs?: Attribs) => - new Circle2(mixNewN(a, b, 0.5), dist(a, b) / 2, attribs); + new Circle2(mixN2([], a, b, 0.5), dist(a, b) / 2, attribs); export const circleFrom3Points = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, attribs?: Attribs) => { @@ -65,7 +61,10 @@ implementations( bounds, (circle: Circle2) => - new Rect2(subNewN(circle.pos, circle.r), mulN([2, 2], circle.r)), + new Rect2( + subN2([], circle.pos, circle.r), + mulN2(null, [2, 2], circle.r) + ), centroid, (circle: Circle2) => copy(circle.pos), @@ -84,23 +83,23 @@ implementations( closestPoint, (circle: Circle2, p: ReadonlyVec) => - add(normalize(subNew(p, circle.pos), circle.r), circle.pos), + add2(null, normalize(null, sub2([], p, circle.pos), circle.r), circle.pos), perimeter, (circle: Circle2) => TAU * circle.r, pointAt, (circle: Circle2, t: number) => - cartesian([circle.r, TAU * t], circle.pos), + cartesian2(null, [circle.r, TAU * t], circle.pos), pointInside, (circle: Circle2, p: ReadonlyVec) => - distSq(circle.pos, p) <= circle.r * circle.r, + distSq2(circle.pos, p) <= circle.r * circle.r, translate, (circle: Circle2, delta: ReadonlyVec) => new Circle2( - addNew(circle.pos, delta), + add2([], circle.pos, delta), circle.r, { ...circle.attribs } ), @@ -123,7 +122,7 @@ implementations( const delta = TAU / num; last && num++; for (let i = 0; i < num; i++) { - buf[i] = cartesian([r, i * delta], pos); + buf[i] = cartesian2(null, [r, i * delta], pos); } return buf; } diff --git a/packages/geom2/src/container2.ts b/packages/geom2/src/container2.ts index 75818af37c..39a679d652 100644 --- a/packages/geom2/src/container2.ts +++ b/packages/geom2/src/container2.ts @@ -1,7 +1,6 @@ import { implementations } from "@thi.ng/defmulti"; -import { Vec } from "@thi.ng/vectors2/api"; -import { Mat23 } from "@thi.ng/vectors2/mat23"; -import { Vec2 } from "@thi.ng/vectors2/vec2"; +import { Mat } from "@thi.ng/matrices/api"; +import { MAX2, MIN2, Vec } from "@thi.ng/vectors3/api"; import { Attribs, bounds, @@ -22,7 +21,7 @@ import { transformPoints } from "./internal/transform"; export function points(points: Vec[], attribs?: Attribs) { return new PointContainer(Type.POINTS2, points, attribs); -}; +} implementations( Type.POINTS2, @@ -31,20 +30,22 @@ implementations( bounds, (pc: PointContainer) => - Rect2.fromMinMax(..._bounds(pc.points, [...Vec2.MAX], [...Vec2.MIN])), + Rect2.fromMinMax(..._bounds(pc.points, [...MAX2], [...MIN2])), centroid, - (pc: PointContainer) => _centroid(pc.points), + (pc: PointContainer) => + _centroid(pc.points), convexHull, (pc: PointContainer) => new Polygon2(grahamScan2(pc.points), { ...pc.attribs }), flip, - (pc: PointContainer) => pc.flip(), + (pc: PointContainer) => + pc.flip(), transform, - (pc: PointContainer, mat: Mat23) => + (pc: PointContainer, mat: Mat) => new PointContainer( pc.type, transformPoints(pc.points, mat), @@ -52,5 +53,6 @@ implementations( ), vertices, - (pc: PointContainer) => pc.points + (pc: PointContainer) => + pc.points ); diff --git a/packages/geom2/src/ellipse.ts b/packages/geom2/src/ellipse.ts index 16473e4ef9..7a69538c08 100644 --- a/packages/geom2/src/ellipse.ts +++ b/packages/geom2/src/ellipse.ts @@ -2,16 +2,12 @@ import { isNumber } from "@thi.ng/checks/is-number"; import { implementations } from "@thi.ng/defmulti"; import { cossin } from "@thi.ng/math/angle"; import { PI, TAU } from "@thi.ng/math/api"; -import { - addNew, - copy, - maddNew, - mulNewN, - ones, - ReadonlyVec, - subNew, - Vec -} from "@thi.ng/vectors2/api"; +import { add2 } from "@thi.ng/vectors3/add"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { copy } from "@thi.ng/vectors3/copy"; +import { madd2 } from "@thi.ng/vectors3/madd"; +import { mulN2 } from "@thi.ng/vectors3/muln"; +import { sub2 } from "@thi.ng/vectors3/sub"; import "./polygon"; import { perimeter, @@ -32,7 +28,7 @@ import { SamplingOpts, } from "./api"; -export function ellipse(pos: Vec, r = ones(2), attribs?: Attribs): Ellipse2 { +export function ellipse(pos: Vec, r = [1, 1], attribs?: Attribs): Ellipse2 { return new Ellipse2(pos, r, attribs); } @@ -50,7 +46,7 @@ implementations( bounds, (ellipse: Ellipse2) => - new Rect2(subNew(ellipse.pos, ellipse.r), mulNewN(ellipse.r, 2)), + new Rect2(sub2([], ellipse.pos, ellipse.r), mulN2([], ellipse.r, 2)), centroid, (ellipse: Ellipse2) => copy(ellipse.pos), @@ -72,12 +68,12 @@ implementations( pointAt, (ellipse: Ellipse2, t: number) => - maddNew(ellipse.pos, cossin(t * TAU), ellipse.r), + madd2([], ellipse.pos, cossin(t * TAU), ellipse.r), translate, (ellipse: Ellipse2, delta: ReadonlyVec) => new Ellipse2( - addNew(ellipse.pos, delta), + add2([], ellipse.pos, delta), ellipse.r, { ...ellipse.attribs } ), @@ -98,7 +94,7 @@ implementations( const delta = TAU / num; last && num++; for (let i = 0; i < num; i++) { - buf[i] = maddNew(pos, cossin(i * delta), r); + buf[i] = madd2([], pos, cossin(i * delta), r); } return buf; } diff --git a/packages/geom2/src/internal/arc.ts b/packages/geom2/src/internal/arc.ts index aa83e0b555..5dff2c5d1a 100644 --- a/packages/geom2/src/internal/arc.ts +++ b/packages/geom2/src/internal/arc.ts @@ -1,6 +1,7 @@ -import { TAU } from "@thi.ng/math/api"; import { atan2Abs, cossin } from "@thi.ng/math/angle"; -import { ReadonlyVec, Vec, maddNew } from "@thi.ng/vectors2/api"; +import { TAU } from "@thi.ng/math/api"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { madd } from "@thi.ng/vectors3/madd"; export const arcVertices = ( o: ReadonlyVec, @@ -17,7 +18,8 @@ export const arcVertices = ( const ts = (outwards ? -theta : TAU - theta) / res; verts.push(a); for (let i = 1; i < res; i++) { - verts.push(maddNew(o, cossin(ta + ts * i), r)); + const p = cossin(ta + ts * i); + verts.push(madd(p, o, p, r)); } verts.push(b); return verts; diff --git a/packages/geom2/src/internal/barycentric.ts b/packages/geom2/src/internal/barycentric.ts index d73b9d0916..76130a1f7d 100644 --- a/packages/geom2/src/internal/barycentric.ts +++ b/packages/geom2/src/internal/barycentric.ts @@ -1,21 +1,17 @@ -import { - dot, - maddN, - mulNewN, - ReadonlyVec, - setS, - subNew, - Vec, - zero -} from "@thi.ng/vectors2/api"; import { eqDelta } from "@thi.ng/math/eqdelta"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { dot } from "@thi.ng/vectors3/dot"; +import { maddN } from "@thi.ng/vectors3/maddn"; +import { mulN } from "@thi.ng/vectors3/muln"; +import { zero } from "@thi.ng/vectors3/setn"; +import { sub } from "@thi.ng/vectors3/sub"; export const toBarycentric = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, p: ReadonlyVec, out: Vec = []) => { - const u = subNew(b, a); - const v = subNew(c, a); - const w = subNew(p, a); + const u = sub([], b, a); + const v = sub([], c, a); + const w = sub([], p, a); const d00 = dot(u, u); const d01 = dot(u, v); const d11 = dot(v, v); @@ -29,9 +25,12 @@ export const toBarycentric = const s = (d11 * d20 - d01 * d21) / denom; const t = (d00 * d21 - d01 * d20) / denom; - return setS(out, 1 - s - t, s, t); + out[0] = 1 - s - t; + out[1] = s; + out[2] = t; + return out; }; export const fromBarycentric = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, p: ReadonlyVec, out: Vec) => - maddN(maddN(mulNewN(a, p[0], out), b, p[1]), c, p[2]); + maddN(null, maddN(null, mulN(out, a, p[0]), b, p[1]), c, p[2]); diff --git a/packages/geom2/src/internal/bounds.ts b/packages/geom2/src/internal/bounds.ts index c89c1d13e1..17ce076de0 100644 --- a/packages/geom2/src/internal/bounds.ts +++ b/packages/geom2/src/internal/bounds.ts @@ -1,11 +1,8 @@ -import { - addNew, - max, - min, - ReadonlyVec, - sub, - Vec -} from "@thi.ng/vectors2/api"; +import { add } from "@thi.ng/vectors3/add"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { max } from "@thi.ng/vectors3/max"; +import { min } from "@thi.ng/vectors3/min"; +import { sub } from "@thi.ng/vectors3/sub"; import { bounds as _bounds, IShape, union } from "../api"; export const bounds = @@ -13,8 +10,8 @@ export const bounds = for (let i = pts.length; --i >= 0;) { const p = pts[i]; - min(vmin, p); - max(vmax, p); + min(null, vmin, p); + max(null, vmax, p); } return [vmin, vmax]; }; @@ -32,8 +29,8 @@ export const collBounds = export const unionBounds = (pos1: ReadonlyVec, size1: ReadonlyVec, pos2: ReadonlyVec, size2: ReadonlyVec): [Vec, Vec] => { - const p = addNew(pos1, size1); - const q = addNew(pos2, size2); - const pos = min([...pos1], pos2); - return [pos, sub(max(p, q), pos)]; + const p = add([], pos1, size1); + const q = add([], pos2, size2); + const pos = min([], pos1, pos2); + return [pos, sub(null, max(null, p, q), pos)]; }; diff --git a/packages/geom2/src/internal/centroid.ts b/packages/geom2/src/internal/centroid.ts index 7e973a7b5b..34ee9bc271 100644 --- a/packages/geom2/src/internal/centroid.ts +++ b/packages/geom2/src/internal/centroid.ts @@ -1,13 +1,9 @@ import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { - add, - divN, - empty, - ReadonlyVec, - setS, - Vec -} from "@thi.ng/vectors2/api"; -import { cross2 } from "@thi.ng/vectors2/vec2"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { cross2 } from "@thi.ng/vectors3/cross"; +import { empty } from "@thi.ng/vectors3/empty"; +import { add } from "@thi.ng/vectors3/add"; +import { divN } from "@thi.ng/vectors3/divn"; export const centroid = (pts: ReadonlyVec[], c?: Vec) => { @@ -15,13 +11,13 @@ export const centroid = !num && illegalArgs("no points available"); !c && (c = empty(pts[0])); for (let i = num; --i >= 0;) { - add(c, pts[i]); + add(c, c, pts[i]); } - return divN(c, num); + return divN(null, c, num); }; export const centerOfWeight2 = - (pts: ReadonlyVec[], c?: Vec) => { + (pts: ReadonlyVec[], c: Vec = []) => { let area = 0; let x = 0; let y = 0; @@ -32,7 +28,7 @@ export const centerOfWeight2 = y += (i[1] + j[1]) * z; } area = 1 / (area * 3); - x *= area; - y *= area; - return c ? setS(c, x, y) : [x, y]; + c[0] = x * area; + c[1] = y * area; + return c; }; diff --git a/packages/geom2/src/internal/circumcenter.ts b/packages/geom2/src/internal/circumcenter.ts index 56e1777dc7..f2217896f1 100644 --- a/packages/geom2/src/internal/circumcenter.ts +++ b/packages/geom2/src/internal/circumcenter.ts @@ -1,5 +1,5 @@ import { EPS } from "@thi.ng/math/api"; -import { ReadonlyVec } from "@thi.ng/vectors2/api"; +import { ReadonlyVec } from "@thi.ng/vectors3/api"; export const circumCenter = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, eps = EPS) => { diff --git a/packages/geom2/src/internal/closest-point.ts b/packages/geom2/src/internal/closest-point.ts index 047a28a185..c085aa6826 100644 --- a/packages/geom2/src/internal/closest-point.ts +++ b/packages/geom2/src/internal/closest-point.ts @@ -1,14 +1,11 @@ -import { - distSq, - dot, - empty, - magSq, - mixNewN, - ReadonlyVec, - set, - subNew, - Vec, -} from "@thi.ng/vectors2/api"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { distSq } from "@thi.ng/vectors3/distsq"; +import { dot } from "@thi.ng/vectors3/dot"; +import { empty } from "@thi.ng/vectors3/empty"; +import { magSq } from "@thi.ng/vectors3/magsq"; +import { mixN } from "@thi.ng/vectors3/mixn"; +import { set } from "@thi.ng/vectors3/set"; +import { sub } from "@thi.ng/vectors3/sub"; export const closestPoint = (p: ReadonlyVec, pts: Vec[]) => { @@ -28,10 +25,10 @@ export const closestPoint = export const closestCoeff = (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec) => { - const d = subNew(b, a); + const d = sub([], b, a); const l = magSq(d); if (l > 1e-6) { - return dot(subNew(p, a), d) / l; + return dot(sub([], p, a), d) / l; } }; @@ -57,7 +54,7 @@ export const closestPointSegment = set(out, a) : t >= 1.0 ? set(out, b) : - mixNewN(a, b, t, out); + mixN(out, a, b, t); } }; diff --git a/packages/geom2/src/internal/corner.ts b/packages/geom2/src/internal/corner.ts index 5479545c0f..9394756620 100644 --- a/packages/geom2/src/internal/corner.ts +++ b/packages/geom2/src/internal/corner.ts @@ -1,35 +1,24 @@ import { sign } from "@thi.ng/math/abs"; import { EPS } from "@thi.ng/math/api"; -import { - dot, - magSq, - mulNewN, - ReadonlyVec -} from "@thi.ng/vectors2/api"; - -export const signedArea = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => { - const ax = a[0]; - const ay = a[1]; - return (b[0] - ax) * (c[1] - ay) - (c[0] - ax) * (b[1] - ay); - }; +import { ReadonlyVec } from "@thi.ng/vectors3/api"; +import { signedArea2 } from "@thi.ng/vectors3/signed-area"; export const classify = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, eps = EPS) => - sign(signedArea(a, b, c), eps); + sign(signedArea2(a, b, c), eps); export const clockwise2 = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => - signedArea(a, b, c) < 0; + signedArea2(a, b, c) < 0; export const classifyPointInTriangle2 = (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => { const s = clockwise2(a, b, c) ? 1 : -1; return sign( Math.min( - s * signedArea(a, c, p), - s * signedArea(b, a, p), - s * signedArea(c, b, p) + s * signedArea2(a, c, p), + s * signedArea2(b, a, p), + s * signedArea2(c, b, p) ) ); }; @@ -37,19 +26,7 @@ export const classifyPointInTriangle2 = export const pointInTriangle2 = (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => { const s = clockwise2(a, b, c) ? 1 : -1; - return s * signedArea(a, c, p) >= 0 && - s * signedArea(b, a, p) >= 0 && - s * signedArea(c, b, p) >= 0; + return s * signedArea2(a, c, p) >= 0 && + s * signedArea2(b, a, p) >= 0 && + s * signedArea2(c, b, p) >= 0; }; - -/** - * Returns vector projection of `v` onto `dir`. - * - * https://en.wikipedia.org/wiki/Vector_projection - * - * @param dir - * @param v - */ -export const project = - (dir: ReadonlyVec, v: ReadonlyVec) => - mulNewN(dir, dot(v, dir) / magSq(dir)); diff --git a/packages/geom2/src/internal/direction.ts b/packages/geom2/src/internal/direction.ts index a5418a08dc..487391c27f 100644 --- a/packages/geom2/src/internal/direction.ts +++ b/packages/geom2/src/internal/direction.ts @@ -1,14 +1,16 @@ -import { ReadonlyVec, normalize, subNew } from "@thi.ng/vectors2/api"; -import { perpendicularLeft2, perpendicularRight2 } from "@thi.ng/vectors2/vec2"; +import { ReadonlyVec } from "@thi.ng/vectors3/api"; +import { normalize } from "@thi.ng/vectors3/normalize"; +import { perpendicularLeft2, perpendicularRight2 } from "@thi.ng/vectors3/perpendicular"; +import { sub } from "@thi.ng/vectors3/sub"; export const direction = (a: ReadonlyVec, b: ReadonlyVec, n = 1) => - normalize(subNew(b, a), n); + normalize(null, sub([], b, a), n); export const normalL2 = (a: ReadonlyVec, b: ReadonlyVec, n = 1) => - perpendicularLeft2(direction(a, b, n)); + perpendicularLeft2(null, direction(a, b, n)); export const normalR2 = (a: ReadonlyVec, b: ReadonlyVec, n = 1) => - perpendicularRight2(direction(a, b, n)); + perpendicularRight2(null, direction(a, b, n)); diff --git "a/packages/geom2/src/internal/douglas\342\200\223peucker.ts" "b/packages/geom2/src/internal/douglas\342\200\223peucker.ts" index 3bb09c75a4..2e3fcf7db3 100644 --- "a/packages/geom2/src/internal/douglas\342\200\223peucker.ts" +++ "b/packages/geom2/src/internal/douglas\342\200\223peucker.ts" @@ -1,5 +1,7 @@ +import { EPS } from "@thi.ng/math/api"; import { peek } from "@thi.ng/transducers/func/peek"; -import { Vec, eqDelta } from "@thi.ng/vectors2/api"; +import { Vec } from "@thi.ng/vectors3/api"; +import { eqDelta } from "@thi.ng/vectors3/eqdelta"; import { farthestPointSegment } from "./closest-point"; // https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm @@ -9,10 +11,8 @@ export const douglasPeucker2 = let num = pts.length; const visited: boolean[] = []; - if (num <= 2) { - return pts.slice(); - } - if (closed && !eqDelta(pts[0], peek(pts))) { + if (num <= 2) return pts.slice(); + if (closed && !eqDelta(pts[0], peek(pts), EPS)) { pts = pts.slice(); pts.push(pts[0]); num++; diff --git a/packages/geom2/src/internal/edges.ts b/packages/geom2/src/internal/edges.ts index df255610c8..188a55e420 100644 --- a/packages/geom2/src/internal/edges.ts +++ b/packages/geom2/src/internal/edges.ts @@ -1,7 +1,7 @@ import { wrap } from "@thi.ng/transducers/iter/wrap"; import { partition } from "@thi.ng/transducers/xform/partition"; import { VecPair } from "../api"; -import { Vec } from "@thi.ng/vectors2/api"; +import { Vec } from "@thi.ng/vectors3/api"; export const edges = (vertices: Iterable, closed = false) => >partition( diff --git a/packages/geom2/src/internal/graham-scan.ts b/packages/geom2/src/internal/graham-scan.ts index a132ceb817..42252fb3ad 100644 --- a/packages/geom2/src/internal/graham-scan.ts +++ b/packages/geom2/src/internal/graham-scan.ts @@ -1,6 +1,6 @@ -import { Vec } from "@thi.ng/vectors2/api"; -import { signedArea } from "./corner"; -import { comparator2 } from "@thi.ng/vectors2/vec2"; +import { Vec } from "@thi.ng/vectors3/api"; +import { comparator2 } from "@thi.ng/vectors3/compare"; +import { signedArea2 } from "@thi.ng/vectors3/signed-area"; /** * Returns array of points defining the 2D Convex Hull of `pts` using @@ -18,7 +18,7 @@ export const grahamScan2 = pts = pts.slice().sort(comparator2(0, 1)); const scan = (p: Vec, thresh: number) => { - while (h >= thresh && signedArea(res[h - 2], res[h - 1], p) >= 0) { + while (h >= thresh && signedArea2(res[h - 2], res[h - 1], p) >= 0) { res.pop(); h--; } diff --git a/packages/geom2/src/internal/greiner-hormann.ts b/packages/geom2/src/internal/greiner-hormann.ts index fd3e9774b6..f1ee65af3c 100644 --- a/packages/geom2/src/internal/greiner-hormann.ts +++ b/packages/geom2/src/internal/greiner-hormann.ts @@ -1,7 +1,7 @@ import { ICopy } from "@thi.ng/api/api"; import { equivArrayLike } from "@thi.ng/equiv"; import { mapcat } from "@thi.ng/transducers/xform/mapcat"; -import { Vec } from "@thi.ng/vectors2/api"; +import { Vec } from "@thi.ng/vectors3/api"; import { ClipMode, LineIntersectionType, VecPair } from "../api"; import { edges as _edges } from "./edges"; import { intersectLines2 } from "./line-intersection"; diff --git a/packages/geom2/src/internal/liang-barsky.ts b/packages/geom2/src/internal/liang-barsky.ts index a2ec19e91d..e08962d10a 100644 --- a/packages/geom2/src/internal/liang-barsky.ts +++ b/packages/geom2/src/internal/liang-barsky.ts @@ -1,11 +1,11 @@ import { EPS } from "@thi.ng/math/api"; -import { Vec, setS } from "@thi.ng/vectors2/api"; +import { Vec } from "@thi.ng/vectors3/api"; // https://en.wikipedia.org/wiki/Liang%E2%80%93Barsky_algorithm // https://github.com/thi-ng/c-thing/blob/master/src/geom/clip/liangbarsky.c export const liangBarsky2 = - (la: Vec, lb: Vec, tl: Vec, br: Vec, ca?: Vec, cb?: Vec): [Vec, Vec, number, number] => { + (la: Vec, lb: Vec, tl: Vec, br: Vec, ca: Vec = [], cb: Vec = []): [Vec, Vec, number, number] => { const lax = la[0]; const lay = la[1]; const dx = lb[0] - lax; @@ -43,11 +43,10 @@ export const liangBarsky2 = return; } - !ca && (ca = [0, 0]); - !cb && (cb = [0, 0]); - - setS(ca, a * dx + lax, a * dy + lay); - setS(cb, b * dx + lax, b * dy + lay); + ca[0] = a * dx + lax; + ca[1] = a * dy + lay; + cb[0] = b * dx + lax; + cb[1] = b * dy + lay; return [ca, cb, a, b]; }; diff --git a/packages/geom2/src/internal/line-intersection.ts b/packages/geom2/src/internal/line-intersection.ts index 6f8f5704ec..0817c142ff 100644 --- a/packages/geom2/src/internal/line-intersection.ts +++ b/packages/geom2/src/internal/line-intersection.ts @@ -1,7 +1,8 @@ -import { LineIntersection, LineIntersectionType } from "../api"; -import { ReadonlyVec, mixNewN } from "@thi.ng/vectors2/api"; import { EPS } from "@thi.ng/math/api"; import { eqDelta } from "@thi.ng/math/eqdelta"; +import { ReadonlyVec } from "@thi.ng/vectors3/api"; +import { mixN2 } from "@thi.ng/vectors3/mixn"; +import { LineIntersection, LineIntersectionType } from "../api"; import { closestPointSegment } from "./closest-point"; export const intersectLines2 = ( @@ -40,7 +41,7 @@ export const intersectLines2 = ( type: (eps < alpha && alpha < ieps) && (eps < beta && beta < ieps) ? LineIntersectionType.INTERSECT : LineIntersectionType.INTERSECT_OUTSIDE, - isec: mixNewN(a, b, alpha), + isec: mixN2([], a, b, alpha), alpha, beta, det, diff --git a/packages/geom2/src/internal/offset.ts b/packages/geom2/src/internal/offset.ts index 396fcc075c..1d6e45fbd0 100644 --- a/packages/geom2/src/internal/offset.ts +++ b/packages/geom2/src/internal/offset.ts @@ -1,4 +1,6 @@ -import { addNew, subNew, Vec } from "@thi.ng/vectors2/api"; +import { add2 } from "@thi.ng/vectors3/add"; +import { Vec } from "@thi.ng/vectors3/api"; +import { sub2 } from "@thi.ng/vectors3/sub"; import { ClipMode, VecPair } from "../api"; import { arcVertices } from "./arc"; import { normalL2 } from "./direction"; @@ -42,8 +44,8 @@ export const offsetLine = ([ea, eb]: VecPair, dist: number, res: number) => { const verts: Vec[] = []; const r = [dist, dist]; const n = normalL2(ea, eb, dist); - const e1 = [addNew(ea, n), addNew(eb, n)]; - const e2 = [subNew(eb, n), subNew(ea, n)]; + const e1 = [add2([], ea, n), add2([], eb, n)]; + const e2 = [sub2([], eb, n), sub2([], ea, n)]; arcVertices(ea, e2[1], e1[0], r, verts, true, res); return arcVertices(eb, e1[1], e2[0], r, verts, true, res); }; diff --git a/packages/geom2/src/internal/perimeter.ts b/packages/geom2/src/internal/perimeter.ts index def47278b2..5d838313c3 100644 --- a/packages/geom2/src/internal/perimeter.ts +++ b/packages/geom2/src/internal/perimeter.ts @@ -1,4 +1,5 @@ -import { dist, ReadonlyVec } from "@thi.ng/vectors2/api"; +import { ReadonlyVec } from "@thi.ng/vectors3/api"; +import { dist } from "@thi.ng/vectors3/dist"; export const perimeter = (pts: ReadonlyVec[], closed = false) => { diff --git a/packages/geom2/src/internal/polygon.ts b/packages/geom2/src/internal/polygon.ts index b604886066..2f4ae24b29 100644 --- a/packages/geom2/src/internal/polygon.ts +++ b/packages/geom2/src/internal/polygon.ts @@ -1,5 +1,5 @@ -import { ReadonlyVec } from "@thi.ng/vectors2/api"; -import { cross2 } from "@thi.ng/vectors2/vec2"; +import { ReadonlyVec } from "@thi.ng/vectors3/api"; +import { cross2 } from "@thi.ng/vectors3/cross"; export const polygonArea = (pts: ReadonlyVec[]) => { diff --git a/packages/geom2/src/internal/sampler.ts b/packages/geom2/src/internal/sampler.ts index 69bda6d4b7..552db9fbe9 100644 --- a/packages/geom2/src/internal/sampler.ts +++ b/packages/geom2/src/internal/sampler.ts @@ -1,13 +1,10 @@ import { peek } from "@thi.ng/transducers/func/peek"; -import { - copy, - dist, - mixNewN, - ReadonlyVec, - Vec, - subNew, - normalize -} from "@thi.ng/vectors2/api"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { copy } from "@thi.ng/vectors3/copy"; +import { dist } from "@thi.ng/vectors3/dist"; +import { mixN } from "@thi.ng/vectors3/mixn"; +import { normalize } from "@thi.ng/vectors3/normalize"; +import { sub } from "@thi.ng/vectors3/sub"; import { VecPair } from "../api"; export class Sampler { @@ -41,7 +38,7 @@ export class Sampler { const t0 = t * idx[n]; for (let i = 1; i <= n; i++) { if (idx[i] >= t0) { - return mixNewN(pts[i - 1], pts[i], (t0 - idx[i - 1]) / (idx[i] - idx[i - 1])); + return mixN([], pts[i - 1], pts[i], (t0 - idx[i - 1]) / (idx[i] - idx[i - 1])); } } } @@ -58,7 +55,7 @@ export class Sampler { tangentAt(t: number, n = 1) { const seg = this.segmentAt(t); return seg ? - normalize(subNew(seg[1], seg[0]), n) : + normalize(null, sub([], seg[1], seg[0]), n) : undefined; } @@ -94,7 +91,7 @@ export class Sampler { while (ct >= index[i] && i < n) { i++; } if (i >= n) break; const p = index[i - 1]; - result.push(mixNewN(pts[i - 1], pts[i], (ct - p) / (index[i] - p))); + result.push(mixN([], pts[i - 1], pts[i], (ct - p) / (index[i] - p))); } if (includeLast) { result.push(copy(peek(pts))); diff --git a/packages/geom2/src/internal/subdiv-curve.ts b/packages/geom2/src/internal/subdiv-curve.ts index 3e3a73c7aa..808dc1a64c 100644 --- a/packages/geom2/src/internal/subdiv-curve.ts +++ b/packages/geom2/src/internal/subdiv-curve.ts @@ -5,46 +5,29 @@ import { transduce } from "@thi.ng/transducers/transduce"; import { indexed } from "@thi.ng/transducers/xform/indexed"; import { mapcat } from "@thi.ng/transducers/xform/mapcat"; import { partition } from "@thi.ng/transducers/xform/partition"; -import { - maddN, - mulNewN, - ReadonlyVec, - Vec -} from "@thi.ng/vectors2/api"; +import { addWeighted2, addWeighted3, addWeighted5 } from "@thi.ng/vectors3/add-weighted"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; import { SubdivKernel } from "../api"; -const madd2 = - (a: ReadonlyVec, b: ReadonlyVec, ua: number, ub: number) => - maddN(mulNewN(a, ua), b, ub); - -const madd3 = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, ua: number, ub: number, uc: number) => - maddN(maddN(mulNewN(a, ua), b, ub), c, uc); - -const madd5 = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, e: ReadonlyVec, - ua: number, ub: number, uc: number, ud: number, ue: number) => - maddN(maddN(maddN(maddN(mulNewN(a, ua), b, ub), c, uc), d, ud), e, ue); - export const subdivKernel2 = ([ua, ub]: number[], [va, vb]: number[]) => ([a, b]: ReadonlyVec[]) => [ - madd2(a, b, ua, ub), - madd2(a, b, va, vb), + addWeighted2([], a, b, ua, ub), + addWeighted2([], a, b, va, vb), ]; export const subdivKernel3 = ([ua, ub, uc]: number[], [va, vb, vc]: number[]) => ([a, b, c]: ReadonlyVec[]) => [ - madd3(a, b, c, ua, ub, uc), - madd3(a, b, c, va, vb, vc), + addWeighted3([], a, b, c, ua, ub, uc), + addWeighted3([], a, b, c, va, vb, vc), ]; export const subdivKernel5 = ([ua, ub, uc, ud, ue]: number[], [va, vb, vc, vd, ve]: number[]) => ([a, b, c, d, e]: ReadonlyVec[]) => [ - madd5(a, b, c, d, e, ua, ub, uc, ud, ue), - madd5(a, b, c, d, e, va, vb, vc, vd, ve), + addWeighted5([], a, b, c, d, e, ua, ub, uc, ud, ue), + addWeighted5([], a, b, c, d, e, va, vb, vc, vd, ve), ]; /** diff --git a/packages/geom2/src/internal/sutherland-hodgeman.ts b/packages/geom2/src/internal/sutherland-hodgeman.ts index d35b8012a9..73d141a1aa 100644 --- a/packages/geom2/src/internal/sutherland-hodgeman.ts +++ b/packages/geom2/src/internal/sutherland-hodgeman.ts @@ -1,4 +1,4 @@ -import { ReadonlyVec } from "@thi.ng/vectors2/api"; +import { ReadonlyVec } from "@thi.ng/vectors3/api"; import { classify } from "./corner"; import { intersectLines2 } from "./line-intersection"; diff --git a/packages/geom2/src/internal/transform.ts b/packages/geom2/src/internal/transform.ts index fd11e1b866..f43255be68 100644 --- a/packages/geom2/src/internal/transform.ts +++ b/packages/geom2/src/internal/transform.ts @@ -1,4 +1,6 @@ -import { IMatrix, ReadonlyVec } from "@thi.ng/vectors2/api"; +import { Mat } from "@thi.ng/matrices/api"; +import { mulV } from "@thi.ng/matrices/mulv"; +import { ReadonlyVec } from "@thi.ng/vectors3/api"; -export const transformPoints = (pts: ReadonlyVec[], mat: IMatrix) => - pts.map((p) => mat.mulV(p)); +export const transformPoints = (pts: ReadonlyVec[], mat: Mat) => + pts.map((p) => mulV([], mat, p)); diff --git a/packages/geom2/src/internal/warp.ts b/packages/geom2/src/internal/warp.ts index 121212aa65..0363277a2e 100644 --- a/packages/geom2/src/internal/warp.ts +++ b/packages/geom2/src/internal/warp.ts @@ -1,4 +1,4 @@ -import { ReadonlyVec } from "@thi.ng/vectors2/api"; +import { ReadonlyVec } from "@thi.ng/vectors3/api"; import { IShape, mapPoint, unmapPoint } from "../api"; export const warpPoints = diff --git a/packages/geom2/src/line.ts b/packages/geom2/src/line.ts index 34462c488e..285e6f4e34 100644 --- a/packages/geom2/src/line.ts +++ b/packages/geom2/src/line.ts @@ -1,12 +1,10 @@ import { implementations } from "@thi.ng/defmulti"; -import { - dist, - mixNewN, - ReadonlyVec, - subNew, - Vec -} from "@thi.ng/vectors2/api"; -import { Mat23 } from "@thi.ng/vectors2/mat23"; +import { Mat } from "@thi.ng/matrices/api"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { dist } from "@thi.ng/vectors3/dist"; +import { mixN } from "@thi.ng/vectors3/mixn"; +import { sub } from "@thi.ng/vectors3/sub"; +import { direction } from "./internal/direction"; import { intersectLines2 } from "./internal/line-intersection"; import { offsetLine } from "./internal/offset"; import { transformPoints } from "./internal/transform"; @@ -33,14 +31,13 @@ import { vertices, resample, } from "./api"; -import { direction } from "./internal/direction"; export function line(a: Vec, b: Vec, attribs?: Attribs) { return new Line2([a, b], attribs); } export const lineNormal = (a: ReadonlyVec, b: ReadonlyVec, out?: Vec) => - subNew(b, a, out); + sub(out, b, a); implementations( Type.LINE2, @@ -69,7 +66,7 @@ implementations( centroid, (line: Line2, c: Vec = []) => - mixNewN(line.a, line.b, 0.5, c), + mixN(c, line.a, line.b, 0.5), intersectLine, (l1: Line2, l2: Line2) => @@ -91,7 +88,7 @@ implementations( direction(line.a, line.b, n), transform, - (line: Line2, mat: Mat23) => + (line: Line2, mat: Mat) => new Line2( transformPoints(line.points, mat), { ...line.attribs } diff --git a/packages/geom2/src/path.ts b/packages/geom2/src/path.ts index 0a84b30357..61406d7bfa 100644 --- a/packages/geom2/src/path.ts +++ b/packages/geom2/src/path.ts @@ -2,6 +2,7 @@ import { isNumber } from "@thi.ng/checks/is-number"; import { implementations } from "@thi.ng/defmulti"; import { rad } from "@thi.ng/math/angle"; import { eqDelta } from "@thi.ng/math/eqdelta"; +import { Mat } from "@thi.ng/matrices/api"; import { comp } from "@thi.ng/transducers/func/comp"; import { ensureArray } from "@thi.ng/transducers/func/ensure-array"; import { peek } from "@thi.ng/transducers/func/peek"; @@ -9,20 +10,13 @@ import { iterator1 } from "@thi.ng/transducers/iterator"; import { filter } from "@thi.ng/transducers/xform/filter"; import { map } from "@thi.ng/transducers/xform/map"; import { mapcat } from "@thi.ng/transducers/xform/mapcat"; -import { - add, - addNew, - copy, - maddNewN, - mulN, - ReadonlyVec, - set, - sub, - subNew, - Vec, - zeroes -} from "@thi.ng/vectors2/api"; -import { Mat23 } from "@thi.ng/vectors2/mat23"; +import { add2, add } from "@thi.ng/vectors3/add"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { maddN } from "@thi.ng/vectors3/maddn"; +import { mulV } from "@thi.ng/matrices/mulv"; +import { zeroes } from "@thi.ng/vectors3/setn"; +import { mulN2 } from "@thi.ng/vectors3/muln"; +import { set2 } from "@thi.ng/vectors3/set"; import { Arc2, asCubic, @@ -51,6 +45,8 @@ import { collBounds } from "./internal/bounds"; import "./polygon"; import "./polyline"; import { douglasPeucker2 } from "./internal/douglas–peucker"; +import { copy } from "@thi.ng/vectors3/copy"; +import { sub2 } from "@thi.ng/vectors3/sub"; const CMD_RE = /[achlmqstvz]/i; @@ -61,7 +57,7 @@ export function path(segments?: PathSegment[], attribs?: Attribs) { export const roundedRect = (pos: Vec, size: Vec, r: number | Vec) => { r = isNumber(r) ? [r, r] : r; const b = new PathBuilder(); - const [w, h] = maddNewN(size, r, -2); + const [w, h] = maddN([], size, r, -2); b.moveTo([pos[0] + r[0], pos[1]]); b.hlineTo(w, true); b.arcTo(r, r, 0, false, true, true); @@ -229,7 +225,7 @@ implementations( }, transform, - (path: Path2, mat: Mat23) => + (path: Path2, mat: Mat) => new Path2( [...mapcat((s) => transformSegment(s, mat), path.segments)], { ...path.attribs } @@ -246,7 +242,7 @@ implementations( } : { type: s.type, - point: addNew(s.point, delta) + point: add2([], s.point, delta) } ), { ...path.attribs } @@ -301,8 +297,8 @@ export class PathBuilder { this.paths.push(this.curr); } p = this.updateCurrent(p, relative); - set(this.startP, p); - set(this.bezierP, p); + set2(this.startP, p); + set2(this.bezierP, p); this.curr.add({ point: p, type: SegmentType.MOVE, @@ -318,14 +314,14 @@ export class PathBuilder { ]), type: SegmentType.LINE, }); - set(this.bezierP, this.currP); + set2(this.bezierP, this.currP); return this; } hlineTo(x: number, relative = false): PathBuilder { const prev = copy(this.currP); this.currP[0] = relative ? this.currP[0] + x : x; - set(this.bezierP, this.currP); + set2(this.bezierP, this.currP); this.curr.add({ geo: new Line2([prev, copy(this.currP)]), type: SegmentType.LINE, @@ -336,7 +332,7 @@ export class PathBuilder { vlineTo(y: number, relative = false): PathBuilder { const prev = copy(this.currP); this.currP[1] = relative ? this.currP[1] + y : y; - set(this.bezierP, this.currP); + set2(this.bezierP, this.currP); this.curr.add({ geo: new Line2([prev, copy(this.currP)]), type: SegmentType.LINE, @@ -347,7 +343,7 @@ export class PathBuilder { // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#Cubic_B%C3%A9zier_Curve cubicTo(cp1: Vec, cp2: Vec, p: Vec, relative = false) { const c2 = this.absPoint(cp2, relative); - set(this.bezierP, c2); + set2(this.bezierP, c2); this.curr.add({ geo: new Cubic2([ copy(this.currP), @@ -363,7 +359,7 @@ export class PathBuilder { // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#Quadratic_B%C3%A9zier_Curve quadraticTo(cp: Vec, p: Vec, relative = false) { const c1 = this.absPoint(cp, relative); - set(this.bezierP, c1); + set2(this.bezierP, c1); this.curr.add({ geo: new Quadratic2([ copy(this.currP), @@ -379,10 +375,10 @@ export class PathBuilder { const prevMode = peek(this.curr.segments).type; const c1 = copy(this.currP); if (prevMode === SegmentType.CUBIC) { - add(c1, subNew(c1, this.bezierP)); + add2(null, sub2([], c1, this.bezierP), c1); } const c2 = this.absPoint(cp2, relative); - set(this.bezierP, c2); + set2(this.bezierP, c2); this.curr.add({ geo: new Cubic2([ copy(this.currP), @@ -399,9 +395,9 @@ export class PathBuilder { const prevMode = peek(this.curr.segments).type; const c1 = copy(this.currP); if (prevMode === SegmentType.QUADRATIC) { - sub(mulN(c1, 2), this.bezierP); + sub2(null, mulN2(null, c1, 2), this.bezierP); } - set(this.bezierP, c1); + set2(this.bezierP, c1); this.curr.add({ geo: new Quadratic2([ copy(this.currP), @@ -429,7 +425,7 @@ export class PathBuilder { ), type: SegmentType.ARC, }); - set(this.bezierP, this.currP); + set2(this.bezierP, this.currP); return this; } @@ -443,16 +439,16 @@ export class PathBuilder { } protected updateCurrent(p: Vec, relative: boolean) { - p = copy(relative ? add(this.currP, p) : set(this.currP, p)); + p = copy(relative ? add2(null, this.currP, p) : set2(this.currP, p)); return p; } protected absPoint(p: Vec, relative: boolean) { - return relative ? add(p, this.currP) : p; + return relative ? add(null, p, this.currP) : p; } } -const transformSegment = (s: PathSegment, mat: Mat23): Iterable => { +const transformSegment = (s: PathSegment, mat: Mat): Iterable => { if (s.geo) { return s.geo instanceof Arc2 ? map( @@ -468,7 +464,7 @@ const transformSegment = (s: PathSegment, mat: Mat23): Iterable => }]; } return s.point ? - [{ type: s.type, point: mat.mulV(s.point) }] : + [{ type: s.type, point: mulV([], mat, s.point) }] : [{ ...s }]; }; diff --git a/packages/geom2/src/polygon.ts b/packages/geom2/src/polygon.ts index 156a56ccb1..318fbf54d1 100644 --- a/packages/geom2/src/polygon.ts +++ b/packages/geom2/src/polygon.ts @@ -1,6 +1,7 @@ import { isPlainObject } from "@thi.ng/checks/is-plain-object"; import { implementations } from "@thi.ng/defmulti"; import { TAU } from "@thi.ng/math/api"; +import { Mat } from "@thi.ng/matrices/api"; import { Reducer } from "@thi.ng/transducers/api"; import { cycle } from "@thi.ng/transducers/iter/cycle"; import { normRange } from "@thi.ng/transducers/iter/norm-range"; @@ -11,16 +12,12 @@ import { push } from "@thi.ng/transducers/rfn/push"; import { transduce } from "@thi.ng/transducers/transduce"; import { map } from "@thi.ng/transducers/xform/map"; import { partition } from "@thi.ng/transducers/xform/partition"; -import { - addNew, - cartesian, - ReadonlyVec, - Vec -} from "@thi.ng/vectors2/api"; -import { Mat23 } from "@thi.ng/vectors2/mat23"; +import { add2 } from "@thi.ng/vectors3/add"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { cartesian2 } from "@thi.ng/vectors3/cartesian"; +import { signedArea2 } from "@thi.ng/vectors3/signed-area"; import "./container2"; import { centerOfWeight2 } from "./internal/centroid"; -import { signedArea } from "./internal/corner"; import { edges as _edges } from "./internal/edges"; import { booleanOp } from "./internal/greiner-hormann"; import { offset as _offset } from "./internal/offset"; @@ -74,7 +71,7 @@ export function polygon(points: Vec[], attribs?: Attribs): Polygon2 { export const star = (r: number, n: number, profile: number[]) => { const total = n * profile.length; const pts = transduce( - map(([i, p]) => cartesian([r * p, i * TAU])), + map(([i, p]) => cartesian2(null, [r * p, i * TAU])), push(), tuples(normRange(total, false), cycle(profile)) ); @@ -85,7 +82,7 @@ const convexityReducer: Reducer = [ () => 0, (x) => x, (type, [a, b, c]) => { - const t = signedArea(a, b, c); + const t = signedArea2(a, b, c); if (t < 0) { type |= 1; } else if (t > 0) { @@ -208,7 +205,7 @@ implementations( tessellatePoints(poly.points, tessel), transform, - (poly: Polygon2, mat: Mat23) => + (poly: Polygon2, mat: Mat) => new Polygon2( transformPoints(poly.points, mat), { ...poly.attribs } @@ -217,7 +214,7 @@ implementations( translate, (poly: Polygon2, delta: ReadonlyVec) => new Polygon2( - poly.points.map((p) => addNew(p, delta)), + poly.points.map((p) => add2([], p, delta)), { ...poly.attribs } ), diff --git a/packages/geom2/src/polyline.ts b/packages/geom2/src/polyline.ts index 4bdc1f1010..1b11933cc7 100644 --- a/packages/geom2/src/polyline.ts +++ b/packages/geom2/src/polyline.ts @@ -1,16 +1,16 @@ import { isPlainObject } from "@thi.ng/checks/is-plain-object"; import { implementations } from "@thi.ng/defmulti"; +import { Mat } from "@thi.ng/matrices/api"; +import { map } from "@thi.ng/transducers/xform/map"; +import { add2 } from "@thi.ng/vectors3/add"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; import { - addNew, - ReadonlyVec, - Vec -} from "@thi.ng/vectors2/api"; -import { Mat23 } from "@thi.ng/vectors2/mat23"; -import { + asCubic, Attribs, bounds, centroid, convexHull, + Cubic2, DEFAULT_SAMPLES, edges, flip, @@ -27,9 +27,7 @@ import { transform, translate, Type, - vertices, - asCubic, - Cubic2 + vertices } from "./api"; import "./container2"; import { centroid as _centroid } from "./internal/centroid"; @@ -40,7 +38,6 @@ import { Sampler } from "./internal/sampler"; import { subdivideCurve } from "./internal/subdiv-curve"; import { transformPoints } from "./internal/transform"; import { douglasPeucker2 } from "./internal/douglas–peucker"; -import { map } from "@thi.ng/transducers/xform/map"; export function polyline(points: Vec[], attribs?: Attribs): Polyline2 { return new Polyline2(points, attribs); @@ -100,7 +97,7 @@ implementations( new Sampler(line.points, false).tangentAt(t, n), transform, - (line: Polyline2, mat: Mat23) => + (line: Polyline2, mat: Mat) => new Polyline2( transformPoints(line.points, mat), { ...line.attribs } @@ -109,7 +106,7 @@ implementations( translate, (line: Polyline2, delta: ReadonlyVec) => new Polyline2( - line.points.map((p) => addNew(p, delta)), + line.points.map((p) => add2([], p, delta)), { ...line.attribs } ), diff --git a/packages/geom2/src/quad.ts b/packages/geom2/src/quad.ts index 21634eeb56..f5f2705df1 100644 --- a/packages/geom2/src/quad.ts +++ b/packages/geom2/src/quad.ts @@ -1,7 +1,8 @@ import { implementations } from "@thi.ng/defmulti"; -import { addNew, ReadonlyVec, Vec } from "@thi.ng/vectors2/api"; -import { Mat23 } from "@thi.ng/vectors2/mat23"; -import { mixBilinear2 } from "@thi.ng/vectors2/vec2"; +import { Mat } from "@thi.ng/matrices/api"; +import { add2 } from "@thi.ng/vectors3/add"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { mixBilinear2 } from "@thi.ng/vectors3/mix-bilinear"; import { area, Attribs, @@ -51,7 +52,7 @@ implementations( }, transform, - (quad: Quad2, mat: Mat23) => + (quad: Quad2, mat: Mat) => new Quad2( transformPoints(quad.points, mat), { ...quad.attribs } @@ -60,14 +61,14 @@ implementations( translate, (quad: Quad2, delta: ReadonlyVec) => new Quad2( - quad.points.map((p) => addNew(p, delta)), + quad.points.map((p) => add2([], p, delta)), { ...quad.attribs } ), unmapPoint, (quad: Quad2, p: ReadonlyVec, out?: Vec) => { const pts = quad.points; - return mixBilinear2(pts[0], pts[1], pts[3], pts[2], p[0], p[1], out); + return mixBilinear2(out, pts[0], pts[1], pts[3], pts[2], p[0], p[1]); }, ); diff --git a/packages/geom2/src/rect.ts b/packages/geom2/src/rect.ts index 9677382756..0809247408 100644 --- a/packages/geom2/src/rect.ts +++ b/packages/geom2/src/rect.ts @@ -1,19 +1,16 @@ import { implementations } from "@thi.ng/defmulti"; -import { - addNew, - copy, - div, - madd, - maddNewN, - ReadonlyVec, - set, - subNew, - Vec -} from "@thi.ng/vectors2/api"; -import { Mat23 } from "@thi.ng/vectors2/mat23"; +import { Mat } from "@thi.ng/matrices/api"; +import { add2 } from "@thi.ng/vectors3/add"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { copy } from "@thi.ng/vectors3/copy"; +import { div2 } from "@thi.ng/vectors3/div"; +import { madd2 } from "@thi.ng/vectors3/madd"; +import { maddN2 } from "@thi.ng/vectors3/maddn"; +import { sub } from "@thi.ng/vectors3/sub"; import { unionBounds } from "./internal/bounds"; import { edges as _edges } from "./internal/edges"; import { booleanOp } from "./internal/greiner-hormann"; +import { Sampler } from "./internal/sampler"; import { sutherlandHodgeman } from "./internal/sutherland-hodgeman"; import { transformPoints } from "./internal/transform"; import "./polygon"; @@ -44,7 +41,6 @@ import { pointAt, pointInside, } from "./api"; -import { Sampler } from "./internal/sampler"; export function rect(pos: Vec, size: Vec, attribs?: Attribs) { return new Rect2(pos, size, attribs); @@ -63,13 +59,15 @@ implementations( }, area, - (rect: Rect2) => rect.size[0] * rect.size[1], + (rect: Rect2) => + rect.size[0] * rect.size[1], bounds, (rect: Rect2) => rect, centroid, - (rect: Rect2, o?: Vec) => maddNewN(rect.pos, rect.size, 0.5, o), + (rect: Rect2, o?: Vec) => + maddN2(o, rect.pos, rect.size, 0.5), clipConvex, (rect: Rect2, boundary: IShape) => @@ -83,12 +81,12 @@ implementations( _edges(vertices(rect, opts), true), mapPoint, - (rect: Rect2, p: ReadonlyVec, out?: Vec) => { - return div(subNew(p, rect.pos, out), rect.size); - }, + (rect: Rect2, p: ReadonlyVec, out: Vec = []) => + div2(null, sub(out, p, rect.pos), rect.size), perimeter, - (rect: Rect2) => 2 * (rect.size[0] + rect.size[1]), + (rect: Rect2) => + 2 * (rect.size[0] + rect.size[1]), pointAt, (rect: Rect2, t: number) => @@ -106,7 +104,7 @@ implementations( tessellatePoints(vertices(rect), tessel, iter), transform, - (rect: Rect2, mat: Mat23) => + (rect: Rect2, mat: Mat) => new Polygon2( transformPoints(vertices(rect), mat), { ...rect.attribs } @@ -115,7 +113,7 @@ implementations( translate, (rect: Rect2, delta: ReadonlyVec) => new Rect2( - addNew(rect.pos, delta), + add2([], rect.pos, delta), copy(rect.size), { ...rect.attribs } ), @@ -128,14 +126,13 @@ implementations( .map((pts) => new Polygon2(pts, { ...r1.attribs })), unmapPoint, - (rect: Rect2, p: ReadonlyVec, out?: Vec) => { - return madd((out ? set(out, rect.pos) : copy(rect.pos)), rect.size, p); - }, + (rect: Rect2, p: ReadonlyVec, out: Vec = []) => + madd2(out, rect.pos, rect.size, p), vertices, (rect: Rect2, opts: number | Partial) => { const p = rect.pos; - const q = addNew(p, rect.size); + const q = add2([], p, rect.size); const verts = [copy(p), [q[0], p[1]], q, [p[0], q[1]]]; return opts != null ? vertices(new Polygon2(verts), opts) : diff --git a/packages/geom2/src/tessellate.ts b/packages/geom2/src/tessellate.ts index 61ada46b72..6815524d35 100644 --- a/packages/geom2/src/tessellate.ts +++ b/packages/geom2/src/tessellate.ts @@ -12,17 +12,19 @@ import { map } from "@thi.ng/transducers/xform/map"; import { mapcat } from "@thi.ng/transducers/xform/mapcat"; import { partition } from "@thi.ng/transducers/xform/partition"; import { scan } from "@thi.ng/transducers/xform/scan"; -import { mixNewN, ReadonlyVec, Vec } from "@thi.ng/vectors2/api"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { mixN } from "@thi.ng/vectors3/mixn"; +import { signedArea2 } from "@thi.ng/vectors3/signed-area"; import { Tessellator } from "./api"; import { centroid } from "./internal/centroid"; -import { pointInTriangle2, signedArea } from "./internal/corner"; +import { pointInTriangle2 } from "./internal/corner"; import { polygonArea } from "./internal/polygon"; const snip = (points: ReadonlyVec[], u: number, v: number, w: number, n: number, ids: number[]) => { const a = points[ids[u]]; const b = points[ids[v]]; const c = points[ids[w]]; - if (signedArea(a, b, c) > 0) { + if (signedArea2(a, b, c) > 0) { for (let i = 0; i < n; i++) { if (i !== u && i !== v && i !== w) { if (pointInTriangle2(points[ids[i]], a, b, c)) { @@ -80,7 +82,7 @@ export const quadFan = (points: ReadonlyVec[]) => { return transduce( comp( partition(3, 1), - map(([a, b, c]) => [mixNewN(a, b, 0.5), b, mixNewN(b, c, 0.5), p]) + map(([a, b, c]) => [mixN([], a, b, 0.5), b, mixN([], b, c, 0.5), p]) ), push(), wrap(points, 1, true, true) @@ -93,7 +95,7 @@ export const edgeSplit = (points: ReadonlyVec[]) => { comp( partition(2, 1), mapcat(([a, b]) => { - const m = mixNewN(a, b, 0.5); + const m = mixN([], a, b, 0.5); return [[a, m, c], [m, b, c]]; })), push(), @@ -105,7 +107,7 @@ export const rimTris = (points: ReadonlyVec[]) => { const edgeCentroids = transduce( comp( partition(2, 1), - map((e) => mixNewN(e[0], e[1], 0.5)) + map((e) => mixN([], e[0], e[1], 0.5)) ), push(), wrap(points, 1, false, true) @@ -124,7 +126,7 @@ export const rimTris = (points: ReadonlyVec[]) => { export const inset = (inset = 0.5, keepInterior = false) => (points: ReadonlyVec[]) => { const c = centroid(points); - const inner = points.map((p) => mixNewN(p, c, inset)); + const inner = points.map((p) => mixN([], p, c, inset)); return transduce( comp( partition(2, 1), diff --git a/packages/geom2/src/triangle.ts b/packages/geom2/src/triangle.ts index 6821dabe57..f442c733d9 100644 --- a/packages/geom2/src/triangle.ts +++ b/packages/geom2/src/triangle.ts @@ -1,18 +1,15 @@ import { implementations } from "@thi.ng/defmulti"; import { PI } from "@thi.ng/math/api"; -import { - add, - addNew, - divN, - maddN, - mag, - normalize, - ReadonlyVec, - subNew, - Vec -} from "@thi.ng/vectors2/api"; -import { Mat23 } from "@thi.ng/vectors2/mat23"; -import { perpendicularLeft2 } from "@thi.ng/vectors2/vec2"; +import { Mat } from "@thi.ng/matrices/api"; +import { add } from "@thi.ng/vectors3/add"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { divN } from "@thi.ng/vectors3/divn"; +import { maddN } from "@thi.ng/vectors3/maddn"; +import { mag } from "@thi.ng/vectors3/mag"; +import { normalize } from "@thi.ng/vectors3/normalize"; +import { perpendicularLeft2 } from "@thi.ng/vectors3/perpendicular"; +import { signedArea2 } from "@thi.ng/vectors3/signed-area"; +import { sub } from "@thi.ng/vectors3/sub"; import { area, Attribs, @@ -20,29 +17,29 @@ import { centroid, classifyPoint, clipConvex, + convexHull, edges, perimeter, pointInside, + resample, tessellate, transform, translate, Triangle2, Type, - vertices, - convexHull, - resample + vertices } from "./api"; -import { classifyPointInTriangle2, pointInTriangle2, signedArea } from "./internal/corner"; +import { classifyPointInTriangle2, pointInTriangle2 } from "./internal/corner"; import { transformPoints } from "./internal/transform"; export function triangle(a: Vec, b: Vec, c: Vec, attribs?: Attribs) { return new Triangle2([a, b, c], attribs); } -export const equilateralTriangle = (a: Vec, b: Vec) => { - const dir = subNew(b, a); - const c = normalize(perpendicularLeft2(dir), mag(dir) * Math.sin(PI / 3)); - return new Triangle2([a, b, maddN(c, dir, 0.5)]); +export const equilateralTriangle2 = (a: Vec, b: Vec) => { + const dir = sub([], b, a); + const c = normalize(null, perpendicularLeft2([], dir), mag(dir) * Math.sin(PI / 3)); + return new Triangle2([a, b, maddN(null, c, dir, 0.5)]); }; implementations( @@ -64,14 +61,14 @@ implementations( area, (tri: Triangle2, signed = true) => { - const area = 0.5 * signedArea(...<[Vec, Vec, Vec]>tri.points); + const area = 0.5 * signedArea2(...<[Vec, Vec, Vec]>tri.points); return signed ? area : Math.abs(area); }, centroid, (tri: Triangle2, c?: Vec) => { const pts = tri.points; - return divN(add(addNew(pts[0], pts[1], c), pts[2]), 3); + return divN(null, add(null, add(c, pts[0], pts[1]), pts[2]), 3); }, classifyPoint, @@ -86,7 +83,7 @@ implementations( pointInTriangle2(p, ...<[Vec, Vec, Vec]>tri.points), transform, - (tri: Triangle2, mat: Mat23) => + (tri: Triangle2, mat: Mat) => new Triangle2( transformPoints(tri.points, mat), { ...tri.attribs } @@ -95,7 +92,7 @@ implementations( translate, (tri: Triangle2, delta: ReadonlyVec) => new Triangle2( - tri.points.map((p) => addNew(p, delta)), + tri.points.map((p) => add([], p, delta)), { ...tri.attribs } ), ); diff --git a/packages/geom2/test/clip.ts b/packages/geom2/test/clip.ts index 25379e306c..45917c6d08 100644 --- a/packages/geom2/test/clip.ts +++ b/packages/geom2/test/clip.ts @@ -1,4 +1,4 @@ -import { Mat23 } from "@thi.ng/vectors2/mat23"; +import { translation23 } from "@thi.ng/matrices/translation"; import * as fs from "fs"; import * as g from "../src"; @@ -15,22 +15,22 @@ fs.writeFileSync("clip-test.svg", stroke: "black" }, g.group( - { transform: Mat23.translation(0, 0) }, + { transform: translation23([], [0, 0]) }, g.group({ "stroke-width": 5 }, ...g.union(a, b)), a, b ), g.group( - { transform: Mat23.translation(160, 0) }, + { transform: translation23([], [160, 0]) }, g.group({ "stroke-width": 5 }, ...g.difference(a, b)), a, b ), g.group( - { transform: Mat23.translation(0, 160) }, + { transform: translation23([], [0, 160]) }, g.group({ "stroke-width": 5 }, ...g.difference(b, a)), a, b ), g.group( - { transform: Mat23.translation(160, 160) }, + { transform: translation23([], [160, 160]) }, g.group({ "stroke-width": 5 }, ...g.intersection(a, b)), a, b ), From 896855de3f9c31506d6431e539a4db8f8129f90c Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 1 Dec 2018 22:06:33 +0000 Subject: [PATCH 076/333] feat(geom): re-add arcLength() impls, update imports --- packages/geom2/src/api.ts | 9 ++++-- packages/geom2/src/circle.ts | 30 ++++++++++-------- packages/geom2/src/ellipse.ts | 34 +++++++++++++-------- packages/geom2/src/internal/arc-length.ts | 15 +++++++++ packages/geom2/src/line.ts | 19 +++++++----- packages/geom2/src/polygon.ts | 34 ++++++++++++--------- packages/geom2/src/polyline.ts | 6 ++++ packages/geom2/src/quad.ts | 2 ++ packages/geom2/src/rect.ts | 37 +++++++++++++---------- packages/geom2/src/triangle.ts | 2 ++ 10 files changed, 124 insertions(+), 64 deletions(-) create mode 100644 packages/geom2/src/internal/arc-length.ts diff --git a/packages/geom2/src/api.ts b/packages/geom2/src/api.ts index c0d6e1a4f7..cc30721665 100644 --- a/packages/geom2/src/api.ts +++ b/packages/geom2/src/api.ts @@ -7,6 +7,7 @@ import { import { DEFAULT, defmulti, + MultiFn1, MultiFn1O, MultiFn2O } from "@thi.ng/defmulti"; @@ -16,14 +17,14 @@ import { ReadonlyMat } from "@thi.ng/matrices/api"; import { add } from "@thi.ng/vectors3/add"; import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; import { copy } from "@thi.ng/vectors3/copy"; +import { max } from "@thi.ng/vectors3/max"; +import { min } from "@thi.ng/vectors3/min"; import { mixN } from "@thi.ng/vectors3/mixn"; import { mul } from "@thi.ng/vectors3/mul"; -import { min } from "@thi.ng/vectors3/min"; -import { max } from "@thi.ng/vectors3/max"; import { neg } from "@thi.ng/vectors3/neg"; -import { sub } from "@thi.ng/vectors3/sub"; import { perpendicularLeft2 } from "@thi.ng/vectors3/perpendicular"; import { rotateZ } from "@thi.ng/vectors3/rotate"; +import { sub } from "@thi.ng/vectors3/sub"; import { subdivKernel3 } from "./internal/subdiv-curve"; import { warpPoints } from "./internal/warp"; @@ -209,6 +210,8 @@ export type VecPair = [Vec, Vec]; const dispatch = (x: IShape) => x.type; +export const arcLength: MultiFn1 = defmulti(dispatch); + export const area: MultiFn1O = defmulti(dispatch); area.add(DEFAULT, () => 0); diff --git a/packages/geom2/src/circle.ts b/packages/geom2/src/circle.ts index 7338c98c24..4639a7efdb 100644 --- a/packages/geom2/src/circle.ts +++ b/packages/geom2/src/circle.ts @@ -13,27 +13,28 @@ import { mulN2 } from "@thi.ng/vectors3/muln"; import { normalize } from "@thi.ng/vectors3/normalize"; import { sub2 } from "@thi.ng/vectors3/sub"; import { subN2 } from "@thi.ng/vectors3/subn"; -import { circumCenter } from "./internal/circumcenter"; -import "./polygon"; import { - perimeter, + arcLength, area, + Attribs, bounds, + center, centroid, Circle2, - Type, - Attribs, - Rect2, - vertices, + classifyPoint, + closestPoint, DEFAULT_SAMPLES, + perimeter, pointAt, pointInside, - classifyPoint, - closestPoint, - translate, - center, + Rect2, SamplingOpts, + translate, + Type, + vertices } from "./api"; +import { circumCenter } from "./internal/circumcenter"; +import "./polygon"; export function circle(pos: Vec, r = 1, attribs?: Attribs): Circle2 { return new Circle2(pos, r, attribs); @@ -56,8 +57,13 @@ implementations( null, + arcLength, + (circle: Circle2) => + TAU * circle.r, + area, - (circle: Circle2) => PI * circle.r * circle.r, + (circle: Circle2) => + PI * circle.r * circle.r, bounds, (circle: Circle2) => diff --git a/packages/geom2/src/ellipse.ts b/packages/geom2/src/ellipse.ts index 7a69538c08..8241f8e9a6 100644 --- a/packages/geom2/src/ellipse.ts +++ b/packages/geom2/src/ellipse.ts @@ -8,25 +8,26 @@ import { copy } from "@thi.ng/vectors3/copy"; import { madd2 } from "@thi.ng/vectors3/madd"; import { mulN2 } from "@thi.ng/vectors3/muln"; import { sub2 } from "@thi.ng/vectors3/sub"; -import "./polygon"; import { - perimeter, + arcLength, area, + asPolygon, + Attribs, bounds, + center, centroid, - Ellipse2, - Type, - Attribs, - Rect2, - vertices, - Polygon2, - asPolygon, DEFAULT_SAMPLES, + Ellipse2, + perimeter, pointAt, - center, - translate, + Polygon2, + Rect2, SamplingOpts, + translate, + Type, + vertices } from "./api"; +import "./polygon"; export function ellipse(pos: Vec, r = [1, 1], attribs?: Attribs): Ellipse2 { return new Ellipse2(pos, r, attribs); @@ -37,8 +38,17 @@ implementations( null, + arcLength, + (ellipse: Ellipse2) => { + const [a, b] = ellipse.r; + // Ramanujan approximation + // https://www.mathsisfun.com/geometry/ellipse-perimeter.html + return PI * ((3 * (a + b)) - Math.sqrt((3 * a + b) * (3 * b + a))); + }, + area, - (ellipse: Ellipse2) => PI * ellipse.r[0] * ellipse.r[1], + (ellipse: Ellipse2) => + PI * ellipse.r[0] * ellipse.r[1], asPolygon, (ellipse: Ellipse2, opts) => diff --git a/packages/geom2/src/internal/arc-length.ts b/packages/geom2/src/internal/arc-length.ts new file mode 100644 index 0000000000..a5536bf54e --- /dev/null +++ b/packages/geom2/src/internal/arc-length.ts @@ -0,0 +1,15 @@ +import { ReadonlyVec } from "@thi.ng/vectors3/api"; +import { dist } from "@thi.ng/vectors3/dist"; + +export const arcLength = (pts: ReadonlyVec[], closed = false) => { + const num = pts.length; + if (num < 2) return 0; + let res = 0; + let p = pts[0]; + let q = pts[1]; + for (let i = 1; i < num; i++ , p = q, q = pts[i]) { + res += dist(p, q); + } + closed && (res += dist(p, pts[0])); + return res; +}; diff --git a/packages/geom2/src/line.ts b/packages/geom2/src/line.ts index 285e6f4e34..588db06647 100644 --- a/packages/geom2/src/line.ts +++ b/packages/geom2/src/line.ts @@ -4,12 +4,8 @@ import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; import { dist } from "@thi.ng/vectors3/dist"; import { mixN } from "@thi.ng/vectors3/mixn"; import { sub } from "@thi.ng/vectors3/sub"; -import { direction } from "./internal/direction"; -import { intersectLines2 } from "./internal/line-intersection"; -import { offsetLine } from "./internal/offset"; -import { transformPoints } from "./internal/transform"; -import "./polygon"; import { + arcLength, asCubic, asPolyline, Attribs, @@ -24,13 +20,18 @@ import { Polygon2, Polyline2, Rect2, + resample, tangentAt, transform, Type, VecPair, - vertices, - resample, + vertices } from "./api"; +import { direction } from "./internal/direction"; +import { intersectLines2 } from "./internal/line-intersection"; +import { offsetLine } from "./internal/offset"; +import { transformPoints } from "./internal/transform"; +import "./polygon"; export function line(a: Vec, b: Vec, attribs?: Attribs) { return new Line2([a, b], attribs); @@ -52,6 +53,10 @@ implementations( ], }, + arcLength, + (line: Line2) => + dist(line.a, line.b), + asCubic, (line: Line2) => [Cubic2.fromLine(line.a, line.b, { ...line.attribs })], diff --git a/packages/geom2/src/polygon.ts b/packages/geom2/src/polygon.ts index 318fbf54d1..010ed29586 100644 --- a/packages/geom2/src/polygon.ts +++ b/packages/geom2/src/polygon.ts @@ -16,20 +16,10 @@ import { add2 } from "@thi.ng/vectors3/add"; import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; import { cartesian2 } from "@thi.ng/vectors3/cartesian"; import { signedArea2 } from "@thi.ng/vectors3/signed-area"; -import "./container2"; -import { centerOfWeight2 } from "./internal/centroid"; -import { edges as _edges } from "./internal/edges"; -import { booleanOp } from "./internal/greiner-hormann"; -import { offset as _offset } from "./internal/offset"; -import { perimeter as _perimeter } from "./internal/perimeter"; -import { pointInside as _pointInside, polygonArea } from "./internal/polygon"; -import { Sampler } from "./internal/sampler"; -import { subdivideCurve } from "./internal/subdiv-curve"; -import { sutherlandHodgeman } from "./internal/sutherland-hodgeman"; -import { transformPoints } from "./internal/transform"; -import { tessellatePoints } from "./tessellate"; import { + arcLength, area, + asPolygon, Attribs, bounds, centroid, @@ -59,10 +49,22 @@ import { translate, Type, union, - vertices, - asPolygon, + vertices } from "./api"; +import "./container2"; +import { centerOfWeight2 } from "./internal/centroid"; +import { edges as _edges } from "./internal/edges"; +import { booleanOp } from "./internal/greiner-hormann"; +import { offset as _offset } from "./internal/offset"; +import { perimeter as _perimeter } from "./internal/perimeter"; +import { pointInside as _pointInside, polygonArea } from "./internal/polygon"; +import { Sampler } from "./internal/sampler"; +import { subdivideCurve } from "./internal/subdiv-curve"; +import { sutherlandHodgeman } from "./internal/sutherland-hodgeman"; +import { transformPoints } from "./internal/transform"; +import { tessellatePoints } from "./tessellate"; import { douglasPeucker2 } from "./internal/douglas–peucker"; +import { arcLength as _arcLength } from "./internal/arc-length"; export function polygon(points: Vec[], attribs?: Attribs): Polygon2 { return new Polygon2(points, attribs); @@ -118,6 +120,10 @@ implementations( ] }, + arcLength, + (poly: Polygon2) => + _arcLength(poly.points, true), + area, (poly: Polygon2, signed = true) => { const area = polygonArea(poly.points); diff --git a/packages/geom2/src/polyline.ts b/packages/geom2/src/polyline.ts index 1b11933cc7..f18d2ebad1 100644 --- a/packages/geom2/src/polyline.ts +++ b/packages/geom2/src/polyline.ts @@ -5,6 +5,7 @@ import { map } from "@thi.ng/transducers/xform/map"; import { add2 } from "@thi.ng/vectors3/add"; import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; import { + arcLength, asCubic, Attribs, bounds, @@ -30,6 +31,7 @@ import { vertices } from "./api"; import "./container2"; +import { arcLength as _arcLength } from "./internal/arc-length"; import { centroid as _centroid } from "./internal/centroid"; import { edges as _edges } from "./internal/edges"; import { offset as _offset } from "./internal/offset"; @@ -55,6 +57,10 @@ implementations( ], }, + arcLength, + (poly: Polygon2) => + _arcLength(poly.points), + asCubic, (line: Polyline2) => map((e) => Cubic2.fromLine(...e), _edges(line.points)), diff --git a/packages/geom2/src/quad.ts b/packages/geom2/src/quad.ts index f5f2705df1..8e34f977e7 100644 --- a/packages/geom2/src/quad.ts +++ b/packages/geom2/src/quad.ts @@ -4,6 +4,7 @@ import { add2 } from "@thi.ng/vectors3/add"; import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; import { mixBilinear2 } from "@thi.ng/vectors3/mix-bilinear"; import { + arcLength, area, Attribs, bounds, @@ -39,6 +40,7 @@ implementations( flip, ], [Type.POLYGON2]: [ + arcLength, area, centroid, clipConvex, diff --git a/packages/geom2/src/rect.ts b/packages/geom2/src/rect.ts index 0809247408..f44b9b0b14 100644 --- a/packages/geom2/src/rect.ts +++ b/packages/geom2/src/rect.ts @@ -7,40 +7,41 @@ import { div2 } from "@thi.ng/vectors3/div"; import { madd2 } from "@thi.ng/vectors3/madd"; import { maddN2 } from "@thi.ng/vectors3/maddn"; import { sub } from "@thi.ng/vectors3/sub"; -import { unionBounds } from "./internal/bounds"; -import { edges as _edges } from "./internal/edges"; -import { booleanOp } from "./internal/greiner-hormann"; -import { Sampler } from "./internal/sampler"; -import { sutherlandHodgeman } from "./internal/sutherland-hodgeman"; -import { transformPoints } from "./internal/transform"; -import "./polygon"; -import { tessellatePoints } from "./tessellate"; import { + arcLength, area, Attribs, bounds, centroid, clipConvex, ClipMode, + edges, IShape, mapPoint, perimeter, + pointAt, + pointInside, Polygon2, Rect2, + resample, + SamplingOpts, tessellate, Tessellator, + transform, + translate, Type, union, unmapPoint, - vertices, - transform, - SamplingOpts, - edges, - translate, - resample, - pointAt, - pointInside, + vertices } from "./api"; +import { unionBounds } from "./internal/bounds"; +import { edges as _edges } from "./internal/edges"; +import { booleanOp } from "./internal/greiner-hormann"; +import { Sampler } from "./internal/sampler"; +import { sutherlandHodgeman } from "./internal/sutherland-hodgeman"; +import { transformPoints } from "./internal/transform"; +import "./polygon"; +import { tessellatePoints } from "./tessellate"; export function rect(pos: Vec, size: Vec, attribs?: Attribs) { return new Rect2(pos, size, attribs); @@ -58,6 +59,10 @@ implementations( ] }, + arcLength, + (rect: Rect2) => + 2 * (rect.size[0] * rect.size[1]), + area, (rect: Rect2) => rect.size[0] * rect.size[1], diff --git a/packages/geom2/src/triangle.ts b/packages/geom2/src/triangle.ts index f442c733d9..d48ea690c4 100644 --- a/packages/geom2/src/triangle.ts +++ b/packages/geom2/src/triangle.ts @@ -11,6 +11,7 @@ import { perpendicularLeft2 } from "@thi.ng/vectors3/perpendicular"; import { signedArea2 } from "@thi.ng/vectors3/signed-area"; import { sub } from "@thi.ng/vectors3/sub"; import { + arcLength, area, Attribs, bounds, @@ -50,6 +51,7 @@ implementations( bounds, ], [Type.POLYGON2]: [ + arcLength, clipConvex, edges, perimeter, From 0b351e12f9c6d6fe1db3a77f376fdbfe90647014 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 1 Dec 2018 23:17:21 +0000 Subject: [PATCH 077/333] refactor(examples): move gradient defs (mandelbrot) --- examples/mandelbrot/src/gradient.ts | 10 ++++++++++ examples/mandelbrot/src/worker.ts | 15 ++------------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/examples/mandelbrot/src/gradient.ts b/examples/mandelbrot/src/gradient.ts index 752fd1d0b4..092227cd2a 100644 --- a/examples/mandelbrot/src/gradient.ts +++ b/examples/mandelbrot/src/gradient.ts @@ -6,7 +6,9 @@ import { tuples } from "@thi.ng/transducers/iter/tuples"; import { push } from "@thi.ng/transducers/rfn/push"; import { transduce } from "@thi.ng/transducers/transduce"; import { map } from "@thi.ng/transducers/xform/map"; +import { partial } from "@thi.ng/compose/partial"; +// see http://dev.thi.ng/gradients/ // see http://dev.thi.ng/gradients/ const cosColor = (dc: number[], amp: number[], fmod: number[], phase: number[], t: number) => @@ -29,3 +31,11 @@ export const cosineGradient = (n: number, spec: number[][]) => { normRange(n - 1) ); }; + +export const GRADIENTS = [ + [[0.5, 0.5, 0.5], [0.5, 0.5, 0.5], [-1.0, -1.0, -1.0], [0.00, 0.10, 0.20]], + [[0.500, 0.500, 0.500], [0.500, 0.500, 0.500], [0.500, 0.618, 0.500], [-1.000, 0.828, -0.152]], + [[0.402, 0.654, 0.247], [0.835, 0.668, 0.420], [1.226, 1.553, 1.445], [2.684, 6.256, 4.065]], + [[0.500, 0.500, 0.500], [0.500, 0.500, 0.500], [0.500, 0.500, 0.500], [0.500, 0.500, 0.500]], + [[0.5, 0.5, 0.5], [1.000, 1.000, 1.000], [10.000, 10.000, 10.000], [0.000, 0.000, 0.000]], +].map(partial(cosineGradient, 256)); diff --git a/examples/mandelbrot/src/worker.ts b/examples/mandelbrot/src/worker.ts index 45e889820f..19480517f9 100644 --- a/examples/mandelbrot/src/worker.ts +++ b/examples/mandelbrot/src/worker.ts @@ -1,16 +1,5 @@ -import { partial } from "@thi.ng/compose/partial"; import { fit01 } from "@thi.ng/math/fit"; -import { cosineGradient } from "./gradient"; - -// see http://dev.thi.ng/gradients/ - -const gradients = [ - [[0.5, 0.5, 0.5], [0.5, 0.5, 0.5], [-1.0, -1.0, -1.0], [0.00, 0.10, 0.20]], - [[0.500, 0.500, 0.500], [0.500, 0.500, 0.500], [0.500, 0.618, 0.500], [-1.000, 0.828, -0.152]], - [[0.402, 0.654, 0.247], [0.835, 0.668, 0.420], [1.226, 1.553, 1.445], [2.684, 6.256, 4.065]], - [[0.500, 0.500, 0.500], [0.500, 0.500, 0.500], [0.500, 0.500, 0.500], [0.500, 0.500, 0.500]], - [[0.5, 0.5, 0.5], [1.000, 1.000, 1.000], [10.000, 10.000, 10.000], [0.000, 0.000, 0.000]], -].map(partial(cosineGradient, 256)); +import { GRADIENTS } from "./gradient"; // host message listener & responder const $self: any = self; @@ -36,7 +25,7 @@ const mandelbrot = (x0: number, y0: number, n: number) => { // generates new fractal image based on given config tuple const render = ({ x1, y1, x2, y2, iter, w, h, gradient }) => { - const grad = gradients[gradient]; + const grad = GRADIENTS[gradient]; const pix = new Uint32Array(w * h); for (let y = 0, i = 0; y < h; y++) { for (let x = 0; x < w; x++) { From 57836390a7ed41be43209b10c17256f3106c429d Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 1 Dec 2018 23:22:44 +0000 Subject: [PATCH 078/333] refactor(examples): update geom-tessel example to use new geom lib --- examples/geom-tessel/src/index.ts | 138 +++++++++++++++++++----------- 1 file changed, 90 insertions(+), 48 deletions(-) diff --git a/examples/geom-tessel/src/index.ts b/examples/geom-tessel/src/index.ts index 3e11ac592c..d7f0e66c7a 100644 --- a/examples/geom-tessel/src/index.ts +++ b/examples/geom-tessel/src/index.ts @@ -1,17 +1,46 @@ import { partial } from "@thi.ng/compose/partial"; -import { IArcLength, ICentroid, Tessellator } from "@thi.ng/geom/api"; -import { circle2 } from "@thi.ng/geom/circle2"; -import { polygon2, Polygon2 } from "@thi.ng/geom/polygon2"; -import { edgeSplit, quadFan, triFan } from "@thi.ng/geom/tessellate"; +import { + arcLength, + asPolygon, + centroid, + IShape, + Polygon2, + tessellate, + Tessellator, + vertices +} from "@thi.ng/geom2/api"; +import { circle } from "@thi.ng/geom2/circle"; +import { polygon } from "@thi.ng/geom2/polygon"; +import { + edgeSplit, + inset, + quadFan, + triFan +} from "@thi.ng/geom2/tessellate"; import { canvas } from "@thi.ng/hdom-canvas"; -import { start } from "@thi.ng/hdom/start"; import { deg } from "@thi.ng/math/angle"; -import { TAU } from "@thi.ng/math/api"; -import { fit01 } from "@thi.ng/math/fit"; -import { Vec2 } from "@thi.ng/vectors/vec2"; +import { fit01, fit11 } from "@thi.ng/math/fit"; +import { fromInterval } from "@thi.ng/rstream/from/interval"; +import { sync } from "@thi.ng/rstream/stream-sync"; +import { updateDOM } from "@thi.ng/transducers-hdom"; +import { cycle } from "@thi.ng/transducers/iter/cycle"; +import { map } from "@thi.ng/transducers/xform/map"; +import { take } from "@thi.ng/transducers/xform/take"; +import { Vec } from "@thi.ng/vectors3/api"; +import { polar } from "@thi.ng/vectors3/polar"; type Tint = (p: Polygon2) => string; +const MIN_RES = 3; +const MAX_RES = 30; +// const MAX_RES = MIN_RES; + +// const SUBDIVS = [quadFan]; +// const SUBDIVS = [triFan]; +// const SUBDIVS = [edgeSplit]; +const SUBDIVS = [quadFan, triFan, edgeSplit, quadFan]; +// const SUBDIVS = [...take(4, cycle([quadFan]))]; + const W = 600; const W2 = W / 2; @@ -19,11 +48,11 @@ const W2 = W / 2; * Creates a color by mapping the centroid of given shape from cartesian * space to HSL. */ -const centroidToHSL = (p: ICentroid) => { - const c = p.centroid().toPolar(); - const h = deg(c.y); - const s = fit01(c.x / W2, 0, 100); - const l = fit01(c.x / W2, 100, 50); +const centroidToHSL = (p: IShape) => { + const c = polar(null, centroid(p)); + const h = deg(c[1]); + const s = fit01(c[0] / W2, 0, 100); + const l = fit01(c[0] / W2, 100, 50); return `hsl(${h},${s}%,${l}%)`; }; @@ -31,56 +60,69 @@ const centroidToHSL = (p: ICentroid) => { * Creates an HSL color from the arc length / circumference of the given * shape. */ -const arclengthToHSL = (max: number, p: IArcLength) => - `hsl(${fit01(p.arcLength() / max, 0, 360)},100%,50%)`; +const arclengthToHSL = (max: number, p: IShape) => + `hsl(${fit01(arcLength(p) / max, 0, 360)},100%,50%)`; /** * Converts given point array into a polygon and computes fill color * with provided `tint` function. */ -const tintedPoly = (tint: Tint, points: Vec2[]) => { - const p = polygon2(points); - p.attribs = { fill: tint(p) }; +const tintedPoly = (tint: Tint, points: Vec[]) => { + const p = polygon(points); + p.attribs = { + fill: tint(p), + // stroke: tint(p), + }; return p; }; /** * Creates a regular polygon, then recursively subdivides it and tints */ -const tessellation = (t: number, tessel: Tessellator[], tint: Tint) => { - return circle2(W2) - .toPolygon(Math.floor(12 + 9 * Math.sin(t))) - .tessellate(tessel) - .map(partial(tintedPoly, tint)); +const tessellation = (t: number, tessel: Tessellator[], tint: Tint) => { + return tessellate( + asPolygon(circle([0, 0], W2), Math.floor(fit11(Math.sin(t), MIN_RES, MAX_RES))), + tessel + ).map(partial(tintedPoly, tint)); }; -const cancel = start(() => { - const t = Date.now() * 0.005; - // create tessellation - // resulting array contains Polygon2 values - // Polygon2 implements the .toHiccup() method for - // auto-conversion during hdom tree normalization - const cells = tessellation( - t, - [quadFan, triFan, edgeSplit, quadFan], - partial(arclengthToHSL, 250) - ); - return ["div.ma2.sans-serif", - ["div", `Cells: ${cells.length}`], - [canvas, - { width: 600, height: 600 }, - ["g", - { - translate: [300, 300], - rotate: (t / 10) % TAU, - stroke: "#000", - weight: 0.25 - }, - ...cells]]]; -}); +const main = sync({ + src: { + time: fromInterval(16), + } +}).transform( + // root component function + map(({ time }) => { + time *= 0.1; + // create tessellation + // resulting array contains Polygon2 values + // Polygon2 implements the .toHiccup() method for + // auto-conversion during hdom tree normalization + const cells = tessellation( + time, + SUBDIVS, + partial(arclengthToHSL, 250) + ); + return ["div.ma2.sans-serif", + ["div", `Cells: ${cells.length}`], + [canvas, + { width: 600, height: 600 }, + // ["polygon", { stroke: "black" }, vertices(asPolygon(circle([300, 300], 300), 3))], + ["g", + { + translate: [300, 300], + // rotate: (time / 10) % TAU, + stroke: "#000", + weight: 0.25 + }, + ...cells] + ]]; + }), + updateDOM() +); // HMR handling if (process.env.NODE_ENV !== "production") { const hot = (module).hot; - hot && hot.dispose(cancel); + hot && hot.dispose(() => main.done()); } From aa1282986be68b62e74f3127808c72e9c085065f Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 17 Dec 2018 00:49:58 +0000 Subject: [PATCH 079/333] build: update deps --- packages/geom2/package.json | 18 +++++++++--------- packages/matrices/package.json | 6 +++--- packages/vector-pools/package.json | 8 ++++---- packages/vectors2/package.json | 14 +++++++------- packages/vectors3/package.json | 10 +++++----- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/packages/geom2/package.json b/packages/geom2/package.json index ed74bfe0b9..0c55025a33 100644 --- a/packages/geom2/package.json +++ b/packages/geom2/package.json @@ -21,20 +21,20 @@ }, "devDependencies": { "@types/mocha": "^5.2.5", - "@types/node": "^10.12.0", + "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", "typedoc": "^0.13.0", - "typescript": "^3.1.3" + "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.3", - "@thi.ng/checks": "^1.5.13", - "@thi.ng/defmulti": "^0.5.0", - "@thi.ng/hiccup": "^2.6.0", - "@thi.ng/hiccup-svg": "^2.0.6", - "@thi.ng/malloc": "^0.2.0", - "@thi.ng/math": "^0.2.1", + "@thi.ng/api": "^4.2.4", + "@thi.ng/checks": "^1.5.14", + "@thi.ng/defmulti": "^0.5.1", + "@thi.ng/hiccup": "^2.7.1", + "@thi.ng/hiccup-svg": "^2.0.9", + "@thi.ng/malloc": "^0.2.1", + "@thi.ng/math": "^0.2.2", "@thi.ng/matrices": "^0.0.1", "@thi.ng/vectors3": "^0.0.1" }, diff --git a/packages/matrices/package.json b/packages/matrices/package.json index f8d77b154e..1e0a18fcb4 100644 --- a/packages/matrices/package.json +++ b/packages/matrices/package.json @@ -21,14 +21,14 @@ }, "devDependencies": { "@types/mocha": "^5.2.5", - "@types/node": "^10.12.0", + "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", "typedoc": "^0.13.0", - "typescript": "^3.1.3" + "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.3", + "@thi.ng/api": "^4.2.4", "@thi.ng/vectors3": "^0.0.1" }, "keywords": [ diff --git a/packages/vector-pools/package.json b/packages/vector-pools/package.json index 71edf5da38..0bf3674b94 100644 --- a/packages/vector-pools/package.json +++ b/packages/vector-pools/package.json @@ -21,15 +21,15 @@ }, "devDependencies": { "@types/mocha": "^5.2.5", - "@types/node": "^10.12.0", + "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", "typedoc": "^0.13.0", - "typescript": "^3.1.3" + "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.3", - "@thi.ng/malloc": "^0.2.0", + "@thi.ng/api": "^4.2.4", + "@thi.ng/malloc": "^0.2.1", "@thi.ng/vectors3": "^0.0.1" }, "keywords": [ diff --git a/packages/vectors2/package.json b/packages/vectors2/package.json index 129342e389..5876e5ae38 100644 --- a/packages/vectors2/package.json +++ b/packages/vectors2/package.json @@ -21,21 +21,21 @@ }, "devDependencies": { "@types/mocha": "^5.2.5", - "@types/node": "^10.12.0", + "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", "typedoc": "^0.13.0", - "typescript": "^3.1.3" + "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.3", - "@thi.ng/checks": "^1.5.13", + "@thi.ng/api": "^4.2.4", + "@thi.ng/checks": "^1.5.14", "@thi.ng/equiv": "^0.1.13", "@thi.ng/errors": "^0.1.11", - "@thi.ng/malloc": "^0.2.0", - "@thi.ng/math": "^0.2.1", + "@thi.ng/malloc": "^0.2.1", + "@thi.ng/math": "^0.2.2", "@thi.ng/random": "^0.1.0", - "@thi.ng/strings": "^0.6.0", + "@thi.ng/strings": "^0.7.1", "@thi.ng/transducers": "^2.2.2" }, "keywords": [ diff --git a/packages/vectors3/package.json b/packages/vectors3/package.json index f53515f018..995925da0d 100644 --- a/packages/vectors3/package.json +++ b/packages/vectors3/package.json @@ -21,18 +21,18 @@ }, "devDependencies": { "@types/mocha": "^5.2.5", - "@types/node": "^10.12.0", + "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", "typedoc": "^0.13.0", - "typescript": "^3.1.3" + "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.3", - "@thi.ng/checks": "^1.5.13", + "@thi.ng/api": "^4.2.4", + "@thi.ng/checks": "^1.5.14", "@thi.ng/equiv": "^0.1.13", "@thi.ng/errors": "^0.1.11", - "@thi.ng/math": "^0.2.1", + "@thi.ng/math": "^0.2.2", "@thi.ng/random": "^0.1.0", "@thi.ng/transducers": "^2.2.2" }, From 8b582cb50ee598133677e80acb50bd2259805832 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 21 Dec 2018 00:45:36 +0000 Subject: [PATCH 080/333] refactor(vectors): extract & reuse Vec2/3/4 static fns, add copyView() --- packages/vectors3/src/api.ts | 4 ++ packages/vectors3/src/internal/vec-utils.ts | 46 +++++++++++++++++++++ packages/vectors3/src/vec2.ts | 29 +++++-------- packages/vectors3/src/vec3.ts | 34 ++++++--------- packages/vectors3/src/vec4.ts | 33 ++++++--------- 5 files changed, 86 insertions(+), 60 deletions(-) create mode 100644 packages/vectors3/src/internal/vec-utils.ts diff --git a/packages/vectors3/src/api.ts b/packages/vectors3/src/api.ts index 204aa503b4..75630036ec 100644 --- a/packages/vectors3/src/api.ts +++ b/packages/vectors3/src/api.ts @@ -32,6 +32,10 @@ export interface IVector extends StridedVec { } +export interface VectorConstructor { + new(buf: Vec, offset?: number, stride?: number): T; +} + export interface MultiVecOp { add(dim: number, op: VOP): VOP; default(op: VOP): VOP; diff --git a/packages/vectors3/src/internal/vec-utils.ts b/packages/vectors3/src/internal/vec-utils.ts new file mode 100644 index 0000000000..3c4463b3e6 --- /dev/null +++ b/packages/vectors3/src/internal/vec-utils.ts @@ -0,0 +1,46 @@ +import { Vec, VecOpSV, VectorConstructor } from "../api"; + +export const mapBuffer = ( + ctor: VectorConstructor, + buf: Vec, + num: number, + start: number, + cstride: number, + estride: number +) => { + const res: T[] = []; + while (--num >= 0) { + res.push(new ctor(buf, start, cstride)); + start += estride; + } + return res; +}; + +export const intoBuffer = ( + set: VecOpSV, + buf: Vec, + src: Iterable, + start: number, + cstride: number, + estride: number +) => { + for (let v of src) { + set(buf, v, start, 0, cstride, 1); + start += estride; + } + return buf; +}; + +export function* vecIterator( + ctor: VectorConstructor, + buf: Vec, + num: number, + start: number, + cstride: number, + estride: number) { + + while (num-- > 0) { + yield new ctor(buf, start, cstride); + start += estride; + } +} diff --git a/packages/vectors3/src/vec2.ts b/packages/vectors3/src/vec2.ts index e773181593..5a78615921 100644 --- a/packages/vectors3/src/vec2.ts +++ b/packages/vectors3/src/vec2.ts @@ -13,6 +13,8 @@ import { import { eqDelta2 } from "./eqdelta"; import { declareIndices } from "./internal/accessors"; import { AVec } from "./internal/avec"; +import { intoBuffer, mapBuffer, vecIterator } from "./internal/vec-utils"; +import { setS2 } from "./sets"; export class Vec2 extends AVec implements IVector { @@ -32,12 +34,7 @@ export class Vec2 extends AVec implements * @param estride element stride */ static mapBuffer(buf: Vec, num: number = buf.length >> 1, start = 0, cstride = 1, estride = 2) { - const res: Vec2[] = []; - while (--num >= 0) { - res.push(new Vec2(buf, start, cstride)); - start += estride; - } - return res; + return mapBuffer(Vec2, buf, num, start, cstride, estride); } /** @@ -54,20 +51,12 @@ export class Vec2 extends AVec implements * @param cstride * @param estride */ - static intoBuffer(buf: Vec, src: Iterable>, start = 0, cstride = 1, estride = 2) { - for (let v of src) { - buf[start] = v[0]; - buf[start + cstride] = v[1]; - start += estride; - } - return buf; + static intoBuffer(buf: Vec, src: Iterable, start = 0, cstride = 1, estride = 2) { + return intoBuffer(setS2, buf, src, start, cstride, estride); } - static *iterator(buf: Vec, num: number, start = 0, cstride = 1, estride = 2) { - while (num-- > 0) { - yield new Vec2(buf, start, cstride); - start += estride; - } + static iterator(buf: Vec, num: number, start = 0, cstride = 1, estride = 2) { + return vecIterator(Vec2, buf, num, start, cstride, estride); } static readonly X_AXIS = new Vec2(X2); @@ -98,6 +87,10 @@ export class Vec2 extends AVec implements return new Vec2([this.x, this.y]); } + copyView() { + return new Vec2(this.buf, this.i, this.s); + } + empty() { return new Vec2(); } diff --git a/packages/vectors3/src/vec3.ts b/packages/vectors3/src/vec3.ts index 80b560ecc3..2e764d8950 100644 --- a/packages/vectors3/src/vec3.ts +++ b/packages/vectors3/src/vec3.ts @@ -14,6 +14,8 @@ import { import { eqDelta3 } from "./eqdelta"; import { declareIndices } from "./internal/accessors"; import { AVec } from "./internal/avec"; +import { intoBuffer, mapBuffer, vecIterator } from "./internal/vec-utils"; +import { setS3 } from "./sets"; export class Vec3 extends AVec implements IVector { @@ -27,18 +29,13 @@ export class Vec3 extends AVec implements * interleaved etc. * * @param buf backing array - * @param n num vectors + * @param num num vectors * @param start start index * @param cstride component stride * @param estride element stride */ - static mapBuffer(buf: Vec, n: number = (buf.length / 3) | 0, start = 0, cstride = 1, estride = 3) { - const res: Vec3[] = []; - while (--n >= 0) { - res.push(new Vec3(buf, start, cstride)); - start += estride; - } - return res; + static mapBuffer(buf: Vec, num: number = (buf.length / 3) | 0, start = 0, cstride = 1, estride = 3) { + return mapBuffer(Vec3, buf, num, start, cstride, estride); } /** @@ -55,21 +52,12 @@ export class Vec3 extends AVec implements * @param cstride * @param estride */ - static intoBuffer(buf: Vec, src: Iterable>, start = 0, cstride = 1, estride = 3) { - for (let v of src) { - buf[start] = v[0]; - buf[start + cstride] = v[1]; - buf[start + 2 * cstride] = v[2]; - start += estride; - } - return buf; + static intoBuffer(buf: Vec, src: Iterable, start = 0, cstride = 1, estride = 3) { + return intoBuffer(setS3, buf, src, start, cstride, estride); } - static *iterator(buf: Vec, num: number, start = 0, cstride = 1, estride = 3) { - while (num-- > 0) { - yield new Vec3(buf, start, cstride); - start += estride; - } + static iterator(buf: Vec, num: number, start = 0, cstride = 1, estride = 3) { + return vecIterator(Vec3, buf, num, start, cstride, estride); } static readonly X_AXIS = new Vec3(X3); @@ -103,6 +91,10 @@ export class Vec3 extends AVec implements return new Vec3([this.x, this.y, this.z]); } + copyView() { + return new Vec3(this.buf, this.i, this.s); + } + empty() { return new Vec3(); } diff --git a/packages/vectors3/src/vec4.ts b/packages/vectors3/src/vec4.ts index 0f12f2f89a..1606e5cad0 100644 --- a/packages/vectors3/src/vec4.ts +++ b/packages/vectors3/src/vec4.ts @@ -14,6 +14,8 @@ import { import { eqDelta4 } from "./eqdelta"; import { declareIndices } from "./internal/accessors"; import { AVec } from "./internal/avec"; +import { intoBuffer, mapBuffer, vecIterator } from "./internal/vec-utils"; +import { setS4 } from "./sets"; export class Vec4 extends AVec implements IVector { @@ -27,18 +29,13 @@ export class Vec4 extends AVec implements * interleaved etc. * * @param buf backing array - * @param n num vectors + * @param num num vectors * @param start start index * @param cstride component stride * @param estride element stride */ - static mapBuffer(buf: Vec, n: number = buf.length >> 2, start = 0, cstride = 1, estride = 4) { - const res: Vec4[] = []; - while (--n >= 0) { - res.push(new Vec4(buf, start, cstride)); - start += estride; - } - return res; + static mapBuffer(buf: Vec, num: number = buf.length >> 2, start = 0, cstride = 1, estride = 4) { + return mapBuffer(Vec4, buf, num, start, cstride, estride); } /** @@ -55,22 +52,12 @@ export class Vec4 extends AVec implements * @param cstride * @param estride */ - static intoBuffer(buf: Vec, src: Iterable>, start = 0, cstride = 1, estride = 3) { - for (let v of src) { - buf[start] = v[0]; - buf[start + cstride] = v[1]; - buf[start + 2 * cstride] = v[2]; - buf[start + 3 * cstride] = v[3]; - start += estride; - } - return buf; + static intoBuffer(buf: Vec, src: Iterable, start = 0, cstride = 1, estride = 4) { + return intoBuffer(setS4, buf, src, start, cstride, estride); } static *iterator(buf: Vec, num: number, start = 0, cstride = 1, estride = 4) { - while (num-- > 0) { - yield new Vec4(buf, start, cstride); - start += estride; - } + return vecIterator(Vec4, buf, num, start, cstride, estride); } static readonly X_AXIS = new Vec4(X4); @@ -106,6 +93,10 @@ export class Vec4 extends AVec implements return new Vec4([this.x, this.y, this.z, this.w]); } + copyView() { + return new Vec4(this.buf, this.i, this.s); + } + empty() { return new Vec4(); } From b130a944379c3981dd3dcc3edb72addcb1435188 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 21 Dec 2018 00:46:26 +0000 Subject: [PATCH 081/333] refactor(vectors): rename mapBufferV* fns => mapV* --- packages/vectors3/src/map.ts | 61 ++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/packages/vectors3/src/map.ts b/packages/vectors3/src/map.ts index dee9c78814..ffae6cf559 100644 --- a/packages/vectors3/src/map.ts +++ b/packages/vectors3/src/map.ts @@ -11,7 +11,7 @@ import { IVector, VecOpV, VecOpVV, VecOpVN, VecOpVVV, VecOpVVN } from "./api"; * buffers). * * In each iteration `op` is called via `op(out, a, b)`, followed by - * cursor updates to process the next vector. No bounds checking is + * cursor updates to process the next vector view. No bounds checking is * performed. * * This function returns `out`'s backing buffer. @@ -19,7 +19,7 @@ import { IVector, VecOpV, VecOpVV, VecOpVN, VecOpVVV, VecOpVVN } from "./api"; * ``` * // each input buffer contains 2 2D vectors, but using * // different strided data layouts - * mapBufferVV( + * mapVV( * // transformation function * add, * // init output buffer view @@ -36,11 +36,11 @@ import { IVector, VecOpV, VecOpVV, VecOpVN, VecOpVVV, VecOpVVN } from "./api"; * // [ 11, 22, 33, 44 ] * ``` * - * `Vec2/3/4.iterator()` combined with transducers can be used to - * achieve the same (and more flexible) transformations, but will incur - * more intermediate object allocations. `mapBuffer*()` functions only - * use (and mutate) the provided vector instances and do not allocate - * any further objects. + * Alternatively, `Vec2/3/4.iterator()` combined with transducers can be + * used to achieve the same (and more flexible) transformations, but + * will incur more intermediate object allocations. `mapV*()` + * functions only use (and mutate) the provided vector instances and do + * not allocate any further objects. * * ``` * // output buffer @@ -68,7 +68,7 @@ import { IVector, VecOpV, VecOpVV, VecOpVN, VecOpVVV, VecOpVVN } from "./api"; * @param sa * @param sb */ -export const mapBufferVV = ( +export const mapVV = ( op: VecOpVV, out: IVector, a: IVector, @@ -88,7 +88,7 @@ export const mapBufferVV = ( }; /** - * Like `mapBufferVV`, but for `VecOpV` type ops and hence only using + * Like `mapVV`, but for `VecOpV` type ops and hence only using * single input. * * ``` @@ -97,7 +97,7 @@ export const mapBufferVV = ( * buf = [1, 3, 5, 7, 2, 4, 6, 8]; * * // use `swapXY` to swizzle each vector and use AOS for output - * res = mapBufferV(swapXY, new Vec2(), new Vec2(buf, 0, 4), 4, 2, 1); + * res = mapV(swapXY, new Vec2(), new Vec2(buf, 0, 4), 4, 2, 1); * // [ 2, 1, 4, 3, 6, 5, 8, 7 ] * * // unpack result for demonstration purposes @@ -112,7 +112,7 @@ export const mapBufferVV = ( * @param so * @param sa */ -export const mapBufferV = ( +export const mapV = ( op: VecOpV, out: IVector, a: IVector, @@ -129,8 +129,8 @@ export const mapBufferV = ( }; /** - * Like `mapBufferVV`, but for `VecOpVN` type ops and hence using - * a single vector input buffer `a` and a scalar `n`. + * Like `mapVV`, but for `VecOpVN` type ops and hence using a single + * vector input buffer `a` and a scalar `n`. * * @param op * @param out @@ -140,7 +140,7 @@ export const mapBufferV = ( * @param so * @param sa */ -export const mapBufferVN = ( +export const mapVN = ( op: VecOpVN, out: IVector, a: IVector, @@ -157,7 +157,22 @@ export const mapBufferVN = ( return out.buf; }; -export const mapBufferVVV = ( +/** + * Like `mapVV`, but for `VecOpVVV` type ops and hence using three + * vector input buffers `a`, `b`, `c`. + * + * @param op + * @param out + * @param a + * @param b + * @param c + * @param num + * @param so + * @param sa + * @param sb + * @param sc + */ +export const mapVVV = ( op: VecOpVVV, out: IVector, a: IVector, @@ -179,7 +194,21 @@ export const mapBufferVVV = ( return out.buf; }; -export const mapBufferVVN = ( +/** + * Like `mapVV`, but for `VecOpVVN` type ops and hence using two + * vector input buffers `a`, `b` and a scalar `n`. + * + * @param op + * @param out + * @param a + * @param b + * @param n + * @param num + * @param so + * @param sa + * @param sb + */ +export const mapVVN = ( op: VecOpVVN, out: IVector, a: IVector, From c8e25bb04bdfd16c30eaf6e0ba596525d705bcc0 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 21 Dec 2018 00:46:39 +0000 Subject: [PATCH 082/333] build(vectors): update deps --- packages/vectors3/package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/vectors3/package.json b/packages/vectors3/package.json index 995925da0d..cdb87a1adf 100644 --- a/packages/vectors3/package.json +++ b/packages/vectors3/package.json @@ -30,11 +30,11 @@ "dependencies": { "@thi.ng/api": "^4.2.4", "@thi.ng/checks": "^1.5.14", - "@thi.ng/equiv": "^0.1.13", - "@thi.ng/errors": "^0.1.11", + "@thi.ng/equiv": "^0.1.15", + "@thi.ng/errors": "^0.1.12", "@thi.ng/math": "^0.2.2", - "@thi.ng/random": "^0.1.0", - "@thi.ng/transducers": "^2.2.2" + "@thi.ng/random": "^0.1.1", + "@thi.ng/transducers": "^2.2.7" }, "keywords": [ "algebra", From e2874932f58f5abfcec00465d15b32c0bdd24f81 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 21 Dec 2018 00:47:47 +0000 Subject: [PATCH 083/333] build(geom): update deps --- packages/geom2/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/geom2/package.json b/packages/geom2/package.json index 0c55025a33..9116446eba 100644 --- a/packages/geom2/package.json +++ b/packages/geom2/package.json @@ -31,8 +31,8 @@ "@thi.ng/api": "^4.2.4", "@thi.ng/checks": "^1.5.14", "@thi.ng/defmulti": "^0.5.1", - "@thi.ng/hiccup": "^2.7.1", - "@thi.ng/hiccup-svg": "^2.0.9", + "@thi.ng/hiccup": "^2.7.2", + "@thi.ng/hiccup-svg": "^2.0.10", "@thi.ng/malloc": "^0.2.1", "@thi.ng/math": "^0.2.2", "@thi.ng/matrices": "^0.0.1", From 0b51ef1c1a13c18bf808ef3cc43cad9965949b57 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 22 Dec 2018 21:30:03 +0000 Subject: [PATCH 084/333] feat(color): add new package --- packages/color/.npmignore | 11 ++ packages/color/LICENSE | 201 +++++++++++++++++++++++++ packages/color/README.md | 53 +++++++ packages/color/package.json | 47 ++++++ packages/color/src/api.ts | 45 ++++++ packages/color/src/clamp.ts | 14 ++ packages/color/src/convert.ts | 132 ++++++++++++++++ packages/color/src/cosine-gradients.ts | 69 +++++++++ packages/color/src/ensure-alpha.ts | 7 + packages/color/src/ensure-hue.ts | 2 + packages/color/src/hsla-css.ts | 14 ++ packages/color/src/hsla-hsva.ts | 14 ++ packages/color/src/hsla-rgba.ts | 41 +++++ packages/color/src/hsva-css.ts | 7 + packages/color/src/hsva-hsla.ts | 16 ++ packages/color/src/hsva-rgba.ts | 35 +++++ packages/color/src/index.ts | 25 +++ packages/color/src/int-css.ts | 10 ++ packages/color/src/int-rgba.ts | 12 ++ packages/color/src/invert.ts | 13 ++ packages/color/src/luminance.ts | 14 ++ packages/color/src/matrix.ts | 178 ++++++++++++++++++++++ packages/color/src/names.ts | 149 ++++++++++++++++++ packages/color/src/parse-css.ts | 81 ++++++++++ packages/color/src/rgba-css.ts | 15 ++ packages/color/src/rgba-hsla.ts | 41 +++++ packages/color/src/rgba-hsva.ts | 31 ++++ packages/color/src/rgba-int.ts | 12 ++ packages/color/test/index.ts | 6 + packages/color/test/tsconfig.json | 10 ++ packages/color/tsconfig.json | 9 ++ 31 files changed, 1314 insertions(+) create mode 100644 packages/color/.npmignore create mode 100644 packages/color/LICENSE create mode 100644 packages/color/README.md create mode 100644 packages/color/package.json create mode 100644 packages/color/src/api.ts create mode 100644 packages/color/src/clamp.ts create mode 100644 packages/color/src/convert.ts create mode 100644 packages/color/src/cosine-gradients.ts create mode 100644 packages/color/src/ensure-alpha.ts create mode 100644 packages/color/src/ensure-hue.ts create mode 100644 packages/color/src/hsla-css.ts create mode 100644 packages/color/src/hsla-hsva.ts create mode 100644 packages/color/src/hsla-rgba.ts create mode 100644 packages/color/src/hsva-css.ts create mode 100644 packages/color/src/hsva-hsla.ts create mode 100644 packages/color/src/hsva-rgba.ts create mode 100644 packages/color/src/index.ts create mode 100644 packages/color/src/int-css.ts create mode 100644 packages/color/src/int-rgba.ts create mode 100644 packages/color/src/invert.ts create mode 100644 packages/color/src/luminance.ts create mode 100644 packages/color/src/matrix.ts create mode 100644 packages/color/src/names.ts create mode 100644 packages/color/src/parse-css.ts create mode 100644 packages/color/src/rgba-css.ts create mode 100644 packages/color/src/rgba-hsla.ts create mode 100644 packages/color/src/rgba-hsva.ts create mode 100644 packages/color/src/rgba-int.ts create mode 100644 packages/color/test/index.ts create mode 100644 packages/color/test/tsconfig.json create mode 100644 packages/color/tsconfig.json diff --git a/packages/color/.npmignore b/packages/color/.npmignore new file mode 100644 index 0000000000..ec83d74c9d --- /dev/null +++ b/packages/color/.npmignore @@ -0,0 +1,11 @@ +build +coverage +dev +doc +export +src* +test +.nyc_output +tsconfig.json +*.tgz +*.html diff --git a/packages/color/LICENSE b/packages/color/LICENSE new file mode 100644 index 0000000000..8dada3edaf --- /dev/null +++ b/packages/color/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/color/README.md b/packages/color/README.md new file mode 100644 index 0000000000..8809beb1f7 --- /dev/null +++ b/packages/color/README.md @@ -0,0 +1,53 @@ +# @thi.ng/color + +[![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/color.svg)](https://www.npmjs.com/package/@thi.ng/color) +![npm downloads](https://img.shields.io/npm/dm/@thi.ng/color.svg) +[![Twitter Follow](https://img.shields.io/twitter/follow/thing_umbrella.svg?style=flat-square&label=twitter)](https://twitter.com/thing_umbrella) + +This project is part of the +[@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo. + + + +- [About](#about) +- [Installation](#installation) +- [Dependencies](#dependencies) +- [Usage examples](#usage-examples) +- [Authors](#authors) +- [License](#license) + + + +## About + +TODO... + +## Installation + +```bash +yarn add @thi.ng/color +``` + +## Dependencies + +- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/master/packages/api) +- [@thi.ng/compose](https://github.com/thi-ng/umbrella/tree/master/packages/compose) +- [@thi.ng/defmulti](https://github.com/thi-ng/umbrella/tree/master/packages/defmulti) +- [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/master/packages/errors) +- [@thi.ng/strings](https://github.com/thi-ng/umbrella/tree/master/packages/strings) +- [@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/master/packages/transducers) +- [@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3) + +## Usage examples + +```ts +import * as c from "@thi.ng/color"; +``` + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/packages/color/package.json b/packages/color/package.json new file mode 100644 index 0000000000..7e60c1f2ee --- /dev/null +++ b/packages/color/package.json @@ -0,0 +1,47 @@ +{ + "name": "@thi.ng/color", + "version": "0.0.1", + "description": "TODO", + "main": "./index.js", + "typings": "./index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/thi-ng/umbrella.git" + }, + "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/color", + "author": "Karsten Schmidt ", + "license": "Apache-2.0", + "scripts": { + "build": "yarn run clean && tsc --declaration", + "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "cover": "yarn test && nyc report --reporter=lcov", + "doc": "node_modules/.bin/typedoc --mode modules --out doc src", + "pub": "yarn run build && yarn publish --access public", + "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + }, + "devDependencies": { + "@types/mocha": "^5.2.5", + "@types/node": "^10.12.15", + "mocha": "^5.2.0", + "nyc": "^13.1.0", + "typedoc": "^0.13.0", + "typescript": "^3.2.2" + }, + "dependencies": { + "@thi.ng/api": "^4.2.4", + "@thi.ng/compose": "^0.2.2", + "@thi.ng/defmulti": "^0.5.1", + "@thi.ng/errors": "^0.1.12", + "@thi.ng/strings": "^0.7.1", + "@thi.ng/transducers": "^2.2.7", + "@thi.ng/vectors3": "^0.0.1" + }, + "keywords": [ + "ES6", + "color", + "typescript" + ], + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/packages/color/src/api.ts b/packages/color/src/api.ts new file mode 100644 index 0000000000..ac9429ad51 --- /dev/null +++ b/packages/color/src/api.ts @@ -0,0 +1,45 @@ +import { Vec, ReadonlyVec } from "@thi.ng/vectors3/api"; +import { float } from "@thi.ng/strings/float"; +import { percent } from "@thi.ng/strings/percent"; + +export type Color = Vec; +export type ReadonlyColor = ReadonlyVec; + +export type ColorMatrix = [ + number, number, number, number, number, + number, number, number, number, number, + number, number, number, number, number, + number, number, number, number, number +]; + +export type CosCoeffs = [number, number, number, number]; +export type CosGradientSpec = [CosCoeffs, CosCoeffs, CosCoeffs, CosCoeffs]; + +export enum ColorMode { + CSS, + RGBA, + HSVA, + HSLA, + INT_RGBA +} + +// RGBA constants + +export const BLACK = Object.freeze([0, 0, 0, 1]); +export const WHITE = Object.freeze([1, 1, 1, 1]); + +export const RED = Object.freeze([1, 0, 0, 1]); +export const GREEN = Object.freeze([0, 1, 0, 1]); +export const BLUE = Object.freeze([0, 0, 1, 1]); + +export const CYAN = Object.freeze([0, 1, 1, 1]); +export const MAGENTA = Object.freeze([1, 0, 1, 1]); +export const YELLOW = Object.freeze([1, 1, 0, 1]); + +export const RGB_LUMINANCE = [0.299, 0.587, 0.114]; + +// internal helpers + +export const FF = float(2); +export const PC = percent(2); +export const INV8BIT = 1 / 0xff; diff --git a/packages/color/src/clamp.ts b/packages/color/src/clamp.ts new file mode 100644 index 0000000000..975a35639b --- /dev/null +++ b/packages/color/src/clamp.ts @@ -0,0 +1,14 @@ +import { clamp01 } from "@thi.ng/math/interval"; +import { setC4 } from "@thi.ng/vectors3/setc"; +import { Color, ReadonlyColor } from "./api"; +import { ensureAlpha } from "./ensure-alpha"; + +export const clamp = + (out: Color, src: ReadonlyColor, alpha = 1) => + setC4( + out || src, + clamp01(src[0]), + clamp01(src[1]), + clamp01(src[2]), + ensureAlpha(src[3], alpha) + ); diff --git a/packages/color/src/convert.ts b/packages/color/src/convert.ts new file mode 100644 index 0000000000..314df70aa8 --- /dev/null +++ b/packages/color/src/convert.ts @@ -0,0 +1,132 @@ +import { defmulti, Implementation3, MultiFn3 } from "@thi.ng/defmulti"; +import { Color, ColorMode, ReadonlyColor } from "./api"; +import { hslaCss } from "./hsla-css"; +import { hslaRgba } from "./hsla-rgba"; +import { hsvaCss } from "./hsva-css"; +import { hsvaRgba } from "./hsva-rgba"; +import { intCss } from "./int-css"; +import { intRgba } from "./int-rgba"; +import { parseCss } from "./parse-css"; +import { rgbaCss } from "./rgba-css"; +import { rgbaHsla } from "./rgba-hsla"; +import { rgbaHsva } from "./rgba-hsva"; +import { rgbaInt } from "./rgba-int"; + +export const convert: MultiFn3 = + defmulti((...args: any[]) => convID(args[1], args[2])); + +export const asRGBA = (col: string | number | ReadonlyColor, mode: ColorMode) => + convert(col, ColorMode.RGBA, mode); + +export const asHSLA = (col: string | number | ReadonlyColor, mode: ColorMode) => + convert(col, ColorMode.HSLA, mode); + +export const asHSVA = (col: string | number | ReadonlyColor, mode: ColorMode) => + convert(col, ColorMode.HSLA, mode); + +export const asCSS = (col: string | number | ReadonlyColor, mode: ColorMode) => + convert(col, ColorMode.CSS, mode); + +const convID = + (dest: ColorMode, src: ColorMode) => + `${ColorMode[dest]}-${ColorMode[src]}`; + +const defConversion = ( + dest: ColorMode, + src: ColorMode, + impl: Implementation3 +) => + convert.add( + convID(dest, src), + impl + ); + +// CSS + +defConversion( + ColorMode.HSLA, ColorMode.CSS, + (x: string) => parseCss(x, ColorMode.HSLA) +); + +defConversion( + ColorMode.HSVA, ColorMode.CSS, + (x: string) => parseCss(x, ColorMode.HSVA) +); + +defConversion( + ColorMode.INT_RGBA, ColorMode.CSS, + (x: string) => parseCss(x, ColorMode.INT_RGBA) +); + +defConversion( + ColorMode.RGBA, ColorMode.CSS, + (x: string) => parseCss(x, ColorMode.RGBA) +); + +// Int + +defConversion( + ColorMode.CSS, ColorMode.INT_RGBA, + (x: number) => intCss(x) +); + +defConversion( + ColorMode.HSLA, ColorMode.INT_RGBA, + (x: number) => rgbaHsla(null, intRgba([], x)) +); + +defConversion( + ColorMode.HSVA, ColorMode.INT_RGBA, + (x: number) => rgbaHsva(null, intRgba([], x)) +); + +defConversion( + ColorMode.RGBA, ColorMode.INT_RGBA, + (x: number) => intRgba([], x) +); + +// HSLA + +defConversion( + ColorMode.CSS, ColorMode.HSLA, + (x: ReadonlyColor) => hslaCss(x) +); + +defConversion( + ColorMode.RGBA, ColorMode.HSLA, + (x: ReadonlyColor) => hslaRgba([], x) +); + +// HSVA + +defConversion( + ColorMode.CSS, ColorMode.HSVA, + (x: ReadonlyColor) => hsvaCss(x) +); + +defConversion( + ColorMode.RGBA, ColorMode.HSVA, + (x: ReadonlyColor) => hsvaRgba([], x) +); + +// RGBA + +defConversion( + ColorMode.CSS, ColorMode.RGBA, + (x: ReadonlyColor) => rgbaCss(x) +); + +defConversion( + ColorMode.HSLA, ColorMode.RGBA, + (x: ReadonlyColor) => rgbaHsla([], x) +); + +defConversion( + ColorMode.HSVA, ColorMode.RGBA, + (x: ReadonlyColor) => rgbaHsva([], x) +); + +defConversion( + ColorMode.INT_RGBA, ColorMode.RGBA, + (x: ReadonlyColor) => rgbaInt(x) +); diff --git a/packages/color/src/cosine-gradients.ts b/packages/color/src/cosine-gradients.ts new file mode 100644 index 0000000000..f9ec69fb66 --- /dev/null +++ b/packages/color/src/cosine-gradients.ts @@ -0,0 +1,69 @@ +import { IObjectOf } from "@thi.ng/api/api"; +import { partial } from "@thi.ng/compose/partial"; +import { TAU } from "@thi.ng/math/api"; +import { clamp01 } from "@thi.ng/math/interval"; +import { normRange } from "@thi.ng/transducers/iter/norm-range"; +import { tuples } from "@thi.ng/transducers/iter/tuples"; +import { push } from "@thi.ng/transducers/rfn/push"; +import { transduce } from "@thi.ng/transducers/transduce"; +import { map } from "@thi.ng/transducers/xform/map"; +import { Color, CosGradientSpec, ReadonlyColor } from "./api"; +import { clamp } from "./clamp"; + +// see http://dev.thi.ng/gradients/ - unlike the clojure version, these +// presets are for RGBA (though the alpha channel is configured to +// always be 1.0) + +export const GRADIENTS: IObjectOf = { + "blue-cyan": [[0, 0.5, 0.5, 1], [0, 0.5, 0.5, 0], [0, 0.5, 0.3333, 0], [0, 0.5, 0.6666, 0]], + "blue-magenta-orange": [[0.938, 0.328, 0.718, 1], [0.659, 0.438, 0.328, 0], [0.388, 0.388, 0.296, 0], [2.538, 2.478, 0.168, 0]], + "blue-white-red": [[0.660, 0.56, 0.680, 1], [0.718, 0.438, 0.720, 0], [0.520, 0.8, 0.520, 0], [-0.430, -0.397, -0.083, 0]], + "cyan-magenta": [[0.610, 0.498, 0.650, 1], [0.388, 0.498, 0.350, 0], [0.530, 0.498, 0.620, 0], [3.438, 3.012, 4.025, 0]], + "green-blue-orange": [[0.892, 0.725, 0, 1], [0.878, 0.278, 0.725, 0], [0.332, 0.518, 0.545, 0], [2.440, 5.043, 0.732, 0]], + "green-cyan": [[0, 0.5, 0.5, 1], [0, 0.5, 0.5, 0], [0, 0.3333, 0.5, 0], [0, 0.6666, 0.5, 0]], + "green-magenta": [[0.6666, 0.5, 0.5, 1], [0.5, 0.6666, 0.5, 0], [0.6666, 0.666, 0.5, 0], [0.2, 0, 0.5, 0]], + "green-red": [[0.5, 0.5, 0, 1], [0.5, 0.5, 0, 0], [0.5, 0.5, 0, 0], [0.5, 0, 0, 0]], + "magenta-green": [[0.590, 0.811, 0.120, 1], [0.410, 0.392, 0.590, 0], [0.940, 0.548, 0.278, 0], [-4.242, -6.611, -4.045, 0]], + "orange-blue": [[0.5, 0.5, 0.5, 1], [0.5, 0.5, 0.5, 0], [0.8, 0.8, 0.5, 0], [0, 0.2, 0.5, 0]], + "orange-magenta-blue": [[0.821, 0.328, 0.242, 1], [0.659, 0.481, 0.896, 0], [0.612, 0.340, 0.296, 0], [2.820, 3.026, -0.273, 0]], + "rainbow1": [[0.5, 0.5, 0.5, 1], [0.5, 0.5, 0.5, 0], [1.0, 1.0, 1.0, 0], [0, 0.3333, 0.6666, 0]], + "rainbow2": [[0.5, 0.5, 0.5, 1], [0.666, 0.666, 0.666, 0], [1.0, 1.0, 1.0, 0], [0, 0.3333, 0.6666, 0]], + "rainbow3": [[0.5, 0.5, 0.5, 1], [0.75, 0.75, 0.75, 0], [1.0, 1.0, 1.0, 0], [0, 0.3333, 0.6666, 0]], + "rainbow4": [[0.5, 0.5, 0.5, 1], [1, 1, 1, 0], [1.0, 1.0, 1.0, 0], [0, 0.3333, 0.6666, 0]], + "red-blue": [[0.5, 0, 0.5, 1], [0.5, 0, 0.5, 0], [0.5, 0, 0.5, 0], [0, 0, 0.5, 0]], + "yellow-green-blue": [[0.650, 0.5, 0.310, 1], [-0.650, 0.5, 0.6, 0], [0.333, 0.278, 0.278, 0], [0.660, 0, 0.667, 0]], + "yellow-magenta-cyan": [[1, 0.5, 0.5, 1], [0.5, 0.5, 0.5, 0], [0.75, 1.0, 0.6666, 0], [0.8, 1.0, 0.3333, 0]], + "yellow-purple-magenta": [[0.731, 1.098, 0.192, 1], [0.358, 1.090, 0.657, 0], [1.077, 0.360, 0.328, 0], [0.965, 2.265, 0.837, 0]], + "yellow-red": [[0.5, 0.5, 0, 1], [0.5, 0.5, 0, 0], [0.1, 0.5, 0, 0], [0, 0, 0, 0]], +}; + +export const cosineColor = + (spec: CosGradientSpec, t: number): Color => + transduce( + map( + ([a, b, c, d]) => clamp01(a + b * Math.cos(TAU * (c * t + d))) + ), + push(), + tuples(...spec) + ); + +export const cosineGradient = + (n: number, spec: CosGradientSpec) => + transduce( + map(partial(cosineColor, spec)), + push(), + normRange(n - 1) + ); + +export const cosineCoeffs = + (src: ReadonlyColor, dest: ReadonlyColor) => { + src = clamp([], src); + dest = clamp([], dest); + const amp = [...map(([a, b]) => 0.5 * (a - b), tuples(src, dest))]; + return [ + [...map(([s, a]) => s - a, tuples(src, amp))], + amp, + [-0.5, -0.5, -0.5, -0.5], + [0, 0, 0, 0] + ]; + }; diff --git a/packages/color/src/ensure-alpha.ts b/packages/color/src/ensure-alpha.ts new file mode 100644 index 0000000000..136efc6acb --- /dev/null +++ b/packages/color/src/ensure-alpha.ts @@ -0,0 +1,7 @@ +import { clamp01 } from "@thi.ng/math/interval"; + +export const ensureAlpha = + (x: number, def = 1) => + x != undefined ? + clamp01(x) : + def; diff --git a/packages/color/src/ensure-hue.ts b/packages/color/src/ensure-hue.ts new file mode 100644 index 0000000000..5e39ae2192 --- /dev/null +++ b/packages/color/src/ensure-hue.ts @@ -0,0 +1,2 @@ +export const ensureHue = + (x: number) => (x = x % 1, x < 0 ? x + 1 : x); diff --git a/packages/color/src/hsla-css.ts b/packages/color/src/hsla-css.ts new file mode 100644 index 0000000000..8fb3f7fa2d --- /dev/null +++ b/packages/color/src/hsla-css.ts @@ -0,0 +1,14 @@ +import { clamp01 } from "@thi.ng/math/interval"; +import { FF, PC, ReadonlyColor } from "./api"; +import { ensureAlpha } from "./ensure-alpha"; + +export const hslaCss = + (hsla: ReadonlyColor) => { + const h = FF(clamp01(hsla[0]) * 360); + const s = PC(clamp01(hsla[1])); + const l = PC(clamp01(hsla[2])); + const a = ensureAlpha(hsla[3]); + return (a < 1) ? + `hsla(${h},${s},${l},${FF(a)})` : + `hsl(${h},${s},${l})` + }; diff --git a/packages/color/src/hsla-hsva.ts b/packages/color/src/hsla-hsva.ts new file mode 100644 index 0000000000..18ba2428c1 --- /dev/null +++ b/packages/color/src/hsla-hsva.ts @@ -0,0 +1,14 @@ +import { Color, ReadonlyColor } from "./api"; +import { clamp } from "./clamp"; + +export const hslaHsva = + (out: Color, hsla: ReadonlyColor) => { + out = clamp(out || hsla, hsla); + const s = out[1]; + const l = out[2]; + const l2 = 2 * l; + const v = (l2 + s * (1 - Math.abs(l2 - 1))) * 0.5; + out[1] = 2 * (v - l) / v; + out[2] = v; + return out; + }; diff --git a/packages/color/src/hsla-rgba.ts b/packages/color/src/hsla-rgba.ts new file mode 100644 index 0000000000..0ebcf75488 --- /dev/null +++ b/packages/color/src/hsla-rgba.ts @@ -0,0 +1,41 @@ +import { SIXTH, THIRD, TWO_THIRD } from "@thi.ng/math/api"; +import { clamp01 } from "@thi.ng/math/interval"; +import { setC3 } from "@thi.ng/vectors3/setc"; +import { Color, ReadonlyColor } from "./api"; +import { clamp } from "./clamp"; +import { ensureHue } from "./ensure-hue"; + +export const hslaRgba = + (out: Color, hsla: ReadonlyColor) => { + out = clamp(out || hsla, hsla); + const h = out[0]; + const s = out[1]; + const l = out[2]; + if (s > 1e-6) { + const f2 = (l < 0.5) ? + (l * (s + 1)) : + (l + s) - (l * s); + const f1 = 2 * l - f2; + return setC3( + out, + hslHue(f1, f2, h + THIRD), + hslHue(f1, f2, h), + hslHue(f1, f2, h - THIRD), + ); + } + return setC3(out, l, l, l); + }; + +const hslHue = + (f1: number, f2: number, h: number) => { + h = ensureHue(h); + return clamp01( + (h < SIXTH) ? + f1 + (f2 - f1) * 6 * h : + (h < 0.5) ? + f2 : + (h < TWO_THIRD) ? + f1 + (f2 - f1) * (TWO_THIRD - h) * 6 : + f1 + ); + }; diff --git a/packages/color/src/hsva-css.ts b/packages/color/src/hsva-css.ts new file mode 100644 index 0000000000..91a2ab0800 --- /dev/null +++ b/packages/color/src/hsva-css.ts @@ -0,0 +1,7 @@ +import { ReadonlyColor } from "./api"; +import { hsvaHsla } from "./hsva-hsla"; +import { hslaCss } from "./hsla-css"; + +export const hsvaCss = + (hsva: ReadonlyColor) => + hslaCss(hsvaHsla([], hsva)); diff --git a/packages/color/src/hsva-hsla.ts b/packages/color/src/hsva-hsla.ts new file mode 100644 index 0000000000..72706a2990 --- /dev/null +++ b/packages/color/src/hsva-hsla.ts @@ -0,0 +1,16 @@ +import { ReadonlyColor, Color } from "./api"; +import { clamp } from "./clamp"; + +export const hsvaHsla = + (out: Color, hsva: ReadonlyColor) => { + out = clamp(out || hsva, hsva); + let s = out[1]; + const v = out[2]; + const l = (2 - s) * v / 2; + s = l && l < 1 ? + s * v / (l < 0.5 ? l * 2 : 2 - l * 2) : + s; + out[1] = s; + out[2] = l; + return out; + }; \ No newline at end of file diff --git a/packages/color/src/hsva-rgba.ts b/packages/color/src/hsva-rgba.ts new file mode 100644 index 0000000000..6e097482c0 --- /dev/null +++ b/packages/color/src/hsva-rgba.ts @@ -0,0 +1,35 @@ +import { setC3 } from "@thi.ng/vectors3/setc"; +import { Color, ReadonlyColor } from "./api"; +import { clamp } from "./clamp"; + +export const hsvaRgba = + (out: Color, hsva: ReadonlyColor) => { + out = clamp(out || hsva, hsva); + let h = out[0]; + const s = out[1]; + const v = out[2]; + if (s > 1e-6) { + h = (h * 6) % 6; + h < 0 && (h += 6); + const i = h | 0; + const f = h - i; + const p = v * (1 - s); + const q = v * (1 - s * f); + const t = v * (1 - s * (1 - f)); + switch (i) { + case 0: + return setC3(out, v, t, p); + case 1: + return setC3(out, q, v, p); + case 2: + return setC3(out, p, v, t); + case 3: + return setC3(out, p, q, v); + case 4: + return setC3(out, t, p, v); + default: + return setC3(out, v, p, q); + } + } + return setC3(out, v, v, v); + }; diff --git a/packages/color/src/index.ts b/packages/color/src/index.ts new file mode 100644 index 0000000000..a35726d540 --- /dev/null +++ b/packages/color/src/index.ts @@ -0,0 +1,25 @@ +export * from "./api"; +export * from "./names"; + +export * from "./convert"; +export * from "./parse-css"; + +export * from "./hsla-css"; +export * from "./hsla-hsva"; +export * from "./hsla-rgba"; +export * from "./hsva-css"; +export * from "./hsva-hsla"; +export * from "./hsva-rgba"; +export * from "./int-css"; +export * from "./int-rgba"; +export * from "./rgba-css"; +export * from "./rgba-hsla"; +export * from "./rgba-hsva"; +export * from "./rgba-int"; + +export * from "./invert"; +export * from "./luminance"; + +export * from "./cosine-gradients"; + +export * from "./matrix"; diff --git a/packages/color/src/int-css.ts b/packages/color/src/int-css.ts new file mode 100644 index 0000000000..aafb9b4fb6 --- /dev/null +++ b/packages/color/src/int-css.ts @@ -0,0 +1,10 @@ +import { U24 } from "@thi.ng/strings/radix"; +import { INV8BIT, FF } from "./api"; + +export const intCss = + (rgba: number) => { + const a = rgba >>> 24; + return (a < 255) ? + `rgba(${(rgba >> 16) & 0xff},${(rgba >> 8) & 0xff},${rgba & 0xff},${FF(a * INV8BIT)})` : + `#${U24(rgba)}`; + }; diff --git a/packages/color/src/int-rgba.ts b/packages/color/src/int-rgba.ts new file mode 100644 index 0000000000..f0c8c6b95e --- /dev/null +++ b/packages/color/src/int-rgba.ts @@ -0,0 +1,12 @@ +import { setC4 } from "@thi.ng/vectors3/setc"; +import { Color, INV8BIT } from "./api"; + +export const intRgba = + (out: Color, src: number) => + setC4( + out || [], + (src >>> 16 & 0xff) * INV8BIT, + (src >>> 8 & 0xff) * INV8BIT, + (src & 0xff) * INV8BIT, + (src >>> 24 & 0xff) * INV8BIT + ); diff --git a/packages/color/src/invert.ts b/packages/color/src/invert.ts new file mode 100644 index 0000000000..789c25cf11 --- /dev/null +++ b/packages/color/src/invert.ts @@ -0,0 +1,13 @@ +import { ONE3 } from "@thi.ng/vectors3/api"; +import { sub3 } from "@thi.ng/vectors3/sub"; +import { Color, ReadonlyColor } from "./api"; +import { clamp } from "./clamp"; + +export const invertRGB = + (out: Color, rgba: ReadonlyColor) => ( + out = clamp(out || rgba, rgba), + sub3(out, ONE3, out) + ); + +export const invertInt = + (rgb: number) => rgb ^ 0xffffff; diff --git a/packages/color/src/luminance.ts b/packages/color/src/luminance.ts new file mode 100644 index 0000000000..2702cd56ff --- /dev/null +++ b/packages/color/src/luminance.ts @@ -0,0 +1,14 @@ +import { dot3 } from "@thi.ng/vectors3/dot"; +import { INV8BIT, ReadonlyColor, RGB_LUMINANCE } from "./api"; + +export const luminanceRGB = + (rgb: ReadonlyColor, weights = RGB_LUMINANCE) => + dot3(rgb, weights); + +export const luminanceInt = + (rgb: number) => { + const r = (rgb >>> 16) & 0xff; + const g = (rgb >>> 8) & 0xff; + const b = rgb & 0xff; + return ((r * 76 + g * 150 + b * 29) >>> 3) * INV8BIT; + }; diff --git a/packages/color/src/matrix.ts b/packages/color/src/matrix.ts new file mode 100644 index 0000000000..fcd88b4210 --- /dev/null +++ b/packages/color/src/matrix.ts @@ -0,0 +1,178 @@ +import { clamp01 } from "@thi.ng/math/interval"; +import { mix } from "@thi.ng/math/mix"; +import { dotS4 } from "@thi.ng/vectors3/dots"; +import { setC4 } from "@thi.ng/vectors3/setc"; +import { + Color, + ColorMatrix, + ReadonlyColor, + RGB_LUMINANCE +} from "./api"; + +// https://drafts.fxtf.org/filter-effects/#feColorMatrixElement + +const S0 = 0.072; +const S1 = 0.213; +const S2 = 0.285; +const S3 = 0.715; +const S4 = 0.787; +const S5 = 0.928; +const S6 = 0.140; +const S7 = 0.143; +const S8 = 0.283; + +export const applyMatrix = + (out: Color, mat: ColorMatrix, rgba: ReadonlyColor, clamped = true) => + clamped ? + setC4( + out || rgba, + clamp01(dotS4(rgba, mat, 0, 0) + mat[4]), + clamp01(dotS4(rgba, mat, 0, 5) + mat[9]), + clamp01(dotS4(rgba, mat, 0, 10) + mat[14]), + clamp01(dotS4(rgba, mat, 0, 15) + mat[19]) + ) : + setC4( + out || rgba, + dotS4(rgba, mat, 0, 0) + mat[4], + dotS4(rgba, mat, 0, 5) + mat[9], + dotS4(rgba, mat, 0, 10) + mat[14], + dotS4(rgba, mat, 0, 15) + mat[19] + ); + +export const mulMatrix = + (a: ColorMatrix, b: ColorMatrix): ColorMatrix => [ + dotS4(a, b, 0, 0, 1, 5), + dotS4(a, b, 0, 1, 1, 5), + dotS4(a, b, 0, 2, 1, 5), + dotS4(a, b, 0, 3, 1, 5), + dotS4(a, b, 0, 4, 1, 5) + a[4], + dotS4(a, b, 5, 0, 1, 5), + dotS4(a, b, 5, 1, 1, 5), + dotS4(a, b, 5, 2, 1, 5), + dotS4(a, b, 5, 3, 1, 5), + dotS4(a, b, 5, 4, 1, 5) + a[9], + dotS4(a, b, 10, 0, 1, 5), + dotS4(a, b, 10, 1, 1, 5), + dotS4(a, b, 10, 2, 1, 5), + dotS4(a, b, 10, 3, 1, 5), + dotS4(a, b, 10, 4, 1, 5) + a[14], + dotS4(a, b, 15, 0, 1, 5), + dotS4(a, b, 15, 1, 1, 5), + dotS4(a, b, 15, 2, 1, 5), + dotS4(a, b, 15, 3, 1, 5), + dotS4(a, b, 15, 4, 1, 5) + a[19], + ]; + +export const concatMatrices = + (mat: ColorMatrix, ...xs: ColorMatrix[]) => + xs.reduce(mulMatrix, mat); + +export const IDENTITY: ColorMatrix = + [ + 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0 + ]; + +export const brightness = + (x: number): ColorMatrix => + [ + 1, 0, 0, 0, x, + 0, 1, 0, 0, x, + 0, 0, 1, 0, x, + 0, 0, 0, 1, 0 + ]; + +export const contrast = + (x: number, o = 0.5 * (1 - x)): ColorMatrix => + [ + x, 0, 0, 0, o, + 0, x, 0, 0, o, + 0, 0, x, 0, o, + 0, 0, 0, 1, 0 + ]; + +export const exposure = + (x: number): ColorMatrix => + [ + x, 0, 0, 0, 0, + 0, x, 0, 0, 0, + 0, 0, x, 0, 0, + 0, 0, 0, 1, 0 + ]; + +export const saturation = + (x: number): ColorMatrix => + [ + S1 + S4 * x, S3 - S3 * x, S0 - S0 * x, 0, 0, + S1 - S1 * x, S3 + S2 * x, S0 - S0 * x, 0, 0, + S1 - S1 * x, S3 - S3 * x, S0 + S5 * x, 0, 0, + 0, 0, 0, 1, 0 + ]; + +export const hueRotation = + (theta: number): ColorMatrix => { + const s = Math.sin(theta); + const c = Math.cos(theta); + return [ + S1 + c * S4 - s * S1, + S3 - c * S3 - s * S3, + S0 - c * S0 + s * S5, + 0, 0, + S1 - c * S1 + s * S7, + S3 + c * S2 + s * S6, + S0 - c * S0 - s * S8, + 0, 0, + S1 - c * S1 - s * S4, + S3 - c * S3 + s * S3, + S0 + c * S5 + s * S0, + 0, 0, + 0, 0, 0, 1, 0, + ]; + }; + +export const temperature = + (x: number): ColorMatrix => + [ + 1 + x, 0, 0, 0, 0, + 0, 1, 0, 0, 0, + 0, 0, 1 - x, 0, 0, + 0, 0, 0, 1, 0 + ]; + +export const sepia = + (x = 1): ColorMatrix => + [ + mix(1, 0.393, x), 0.769 * x, 0.189 * x, 0, 0, + 0.349 * x, mix(1, 0.686, x), 0.168 * x, 0, 0, + 0.272 * x, 0.534 * x, mix(1, 0.131, x), 0, 0, + 0, 0, 0, 1, 0 + ]; + +export const tint = + (x: number): ColorMatrix => + [ + 1 + x, 0, 0, 0, 0, + 0, 1, 0, 0, 0, + 0, 0, 1 + x, 0, 0, + 0, 0, 0, 1, 0 + ]; + +export const grayscale = + (x = 0, [r, g, b] = RGB_LUMINANCE): ColorMatrix => + [ + r, g, b, 0, x, + r, g, b, 0, x, + r, g, b, 0, x, + 0, 0, 0, 1, 0 + ]; + +export const luminanceAlpha = + ([r, g, b] = RGB_LUMINANCE): ColorMatrix => + [ + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + r, g, b, 0, 0 + ]; diff --git a/packages/color/src/names.ts b/packages/color/src/names.ts new file mode 100644 index 0000000000..f51bd4bc0f --- /dev/null +++ b/packages/color/src/names.ts @@ -0,0 +1,149 @@ +export const CSS_NAMES = { + aliceblue: "f0f8ff", + antiquewhite: "faebd7", + aqua: "0ff", + aquamarine: "7fffd4", + azure: "f0ffff", + beige: "f5f5dc", + bisque: "ffe4c4", + black: "000", + blanchedalmond: "ffebcd", + blue: "00f", + blueviolet: "8a2be2", + brown: "a52a2a", + burlywood: "deb887", + cadetblue: "5f9ea0", + chartreuse: "7fff00", + chocolate: "d2691e", + coral: "ff7f50", + cornflowerblue: "6495ed", + cornsilk: "fff8dc", + crimson: "dc143c", + cyan: "0ff", + darkblue: "00008b", + darkcyan: "008b8b", + darkgoldenrod: "b8860b", + darkgray: "a9a9a9", + darkgreen: "006400", + darkgrey: "a9a9a9", + darkkhaki: "bdb76b", + darkmagenta: "8b008b", + darkolivegreen: "556b2f", + darkorange: "ff8c00", + darkorchid: "9932cc", + darkred: "8b0000", + darksalmon: "e9967a", + darkseagreen: "8fbc8f", + darkslateblue: "483d8b", + darkslategray: "2f4f4f", + darkslategrey: "2f4f4f", + darkturquoise: "00ced1", + darkviolet: "9400d3", + deeppink: "ff1493", + deepskyblue: "00bfff", + dimgray: "696969", + dimgrey: "696969", + dodgerblue: "1e90ff", + firebrick: "b22222", + floralwhite: "fffaf0", + forestgreen: "228b22", + fuchsia: "f0f", + gainsboro: "dcdcdc", + ghostwhite: "f8f8ff", + gold: "ffd700", + goldenrod: "daa520", + gray: "808080", + grey: "808080", + green: "008000", + greenyellow: "adff2f", + honeydew: "f0fff0", + hotpink: "ff69b4", + indianred: "cd5c5c", + indigo: "4b0082", + ivory: "fffff0", + khaki: "f0e68c", + lavender: "e6e6fa", + lavenderblush: "fff0f5", + lawngreen: "7cfc00", + lemonchiffon: "fffacd", + lightblue: "add8e6", + lightcoral: "f08080", + lightcyan: "e0ffff", + lightgoldenrodyellow: "fafad2", + lightgray: "d3d3d3", + lightgreen: "90ee90", + lightgrey: "d3d3d3", + lightpink: "ffb6c1", + lightsalmon: "ffa07a", + lightseagreen: "20b2aa", + lightskyblue: "87cefa", + lightslategray: "789", + lightslategrey: "789", + lightsteelblue: "b0c4de", + lightyellow: "ffffe0", + lime: "0f0", + limegreen: "32cd32", + linen: "faf0e6", + magenta: "f0f", + maroon: "800000", + mediumaquamarine: "66cdaa", + mediumblue: "0000cd", + mediumorchid: "ba55d3", + mediumpurple: "9370db", + mediumseagreen: "3cb371", + mediumslateblue: "7b68ee", + mediumspringgreen: "00fa9a", + mediumturquoise: "48d1cc", + mediumvioletred: "c71585", + midnightblue: "191970", + mintcream: "f5fffa", + mistyrose: "ffe4e1", + moccasin: "ffe4b5", + navajowhite: "ffdead", + navy: "000080", + oldlace: "fdf5e6", + olive: "808000", + olivedrab: "6b8e23", + orange: "ffa500", + orangered: "ff4500", + orchid: "da70d6", + palegoldenrod: "eee8aa", + palegreen: "98fb98", + paleturquoise: "afeeee", + palevioletred: "db7093", + papayawhip: "ffefd5", + peachpuff: "ffdab9", + peru: "cd853f", + pink: "ffc0cb", + plum: "dda0dd", + powderblue: "b0e0e6", + purple: "800080", + red: "f00", + rosybrown: "bc8f8f", + royalblue: "4169e1", + saddlebrown: "8b4513", + salmon: "fa8072", + sandybrown: "f4a460", + seagreen: "2e8b57", + seashell: "fff5ee", + sienna: "a0522d", + silver: "c0c0c0", + skyblue: "87ceeb", + slateblue: "6a5acd", + slategray: "708090", + slategrey: "708090", + snow: "fffafa", + springgreen: "00ff7f", + steelblue: "4682b4", + tan: "d2b48c", + teal: "008080", + thistle: "d8bfd8", + tomato: "ff6347", + turquoise: "40e0d0", + violet: "ee82ee", + wheat: "f5deb3", + white: "fff", + whitesmoke: "f5f5f5", + yellow: "ff0", + yellowgreen: "9acd32", +}; diff --git a/packages/color/src/parse-css.ts b/packages/color/src/parse-css.ts new file mode 100644 index 0000000000..19403bcbb9 --- /dev/null +++ b/packages/color/src/parse-css.ts @@ -0,0 +1,81 @@ +import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { maybeParseFloat, maybeParseInt } from "@thi.ng/strings/parse"; +import { Color, ColorMode, INV8BIT } from "./api"; +import { convert } from "./convert"; +import { CSS_NAMES } from "./names"; +import { clamp01 } from "@thi.ng/math/interval"; + +const RE_HEX = /^#?([0-9a-f]{3,8})$/i; +const RE_CSS = /^(rgb|hsl)a?\(\s*([0-9.]+?),\s*([0-9.]+%?),\s*([0-9.]+%?),?\s*([0-9.]+)?\s*\)$/; + +export const parseCss = + (col: string, mode = ColorMode.RGBA) => { + let res: Color | number; + let resMode: ColorMode; + if (col.charAt(0) === "#") { + resMode = ColorMode.INT_RGBA; + res = parseHex(col); + } else { + const match = RE_CSS.exec(col); + if (match) { + if (match[1] === "rgb" || match[1] === "rgba") { + resMode = ColorMode.RGBA; + res = [ + parseChannel(match[2]), + parseChannel(match[3]), + parseChannel(match[4]), + maybeParseFloat(match[5], 1) + ]; + } else { + resMode = ColorMode.HSLA; + res = [ + maybeParseFloat(match[2]) / 360, + parseChannel(match[3]), + parseChannel(match[4]), + maybeParseFloat(match[5], 1) + ]; + } + } else { + const c = CSS_NAMES[col]; + !c && illegalArgs(`invalid color: "${col}"`); + resMode = ColorMode.INT_RGBA; + res = parseHex(c); + } + } + if (res && resMode != mode) { + return convert(res, mode, resMode); + } + return res; + }; + +export const parseHex = + (src: string): number => { + const match = RE_HEX.exec(src); + if (match) { + const hex = match[1]; + switch (hex.length) { + case 3: { + const [r, g, b] = hex; + return (maybeParseInt(`${r}${r}${g}${g}${b}${b}`, 0, 16) | 0xff000000) >>> 0; + } + case 4: { + const [a, r, g, b] = hex; + return (maybeParseInt(`${a}${a}${r}${r}${g}${g}${b}${b}`, 0, 16)) >>> 0; + } + case 6: + return (maybeParseInt(hex, 0, 16) | 0xff000000) >>> 0; + case 8: + return maybeParseInt(hex, 0, 16) >>> 0; + default: + } + } + illegalArgs(`invalid hex color: "${src}"`); + }; + +const parseChannel = + (c: string) => + clamp01( + c.indexOf("%") > 0 ? + maybeParseFloat(c) * 0.01 : + maybeParseFloat(c) * INV8BIT + ); diff --git a/packages/color/src/rgba-css.ts b/packages/color/src/rgba-css.ts new file mode 100644 index 0000000000..0eb453b006 --- /dev/null +++ b/packages/color/src/rgba-css.ts @@ -0,0 +1,15 @@ +import { clamp01 } from "@thi.ng/math/interval"; +import { U24 } from "@thi.ng/strings/radix"; +import { FF, ReadonlyColor } from "./api"; +import { ensureAlpha } from "./ensure-alpha"; + +export const rgbaCss = + (rgba: ReadonlyColor) => { + const r = (clamp01(rgba[0]) * 0xff) | 0; + const g = (clamp01(rgba[1]) * 0xff) | 0; + const b = (clamp01(rgba[2]) * 0xff) | 0; + const a = ensureAlpha(rgba[3]); + return (a < 1) ? + `rgba(${r},${g},${b},${FF(a)})` : + `#${U24(r << 16 | g << 8 | b)}` + }; diff --git a/packages/color/src/rgba-hsla.ts b/packages/color/src/rgba-hsla.ts new file mode 100644 index 0000000000..efdbbcc186 --- /dev/null +++ b/packages/color/src/rgba-hsla.ts @@ -0,0 +1,41 @@ +import { SIXTH, THIRD, TWO_THIRD } from "@thi.ng/math/api"; +import { setC3 } from "@thi.ng/vectors3/setc"; +import { Color, ReadonlyColor } from "./api"; +import { clamp } from "./clamp"; + +export const rgbaHsla = + (out: Color, rgba: ReadonlyColor) => { + out = clamp(out || rgba, rgba); + const r = out[0]; + const g = out[1]; + const b = out[2]; + const f1 = Math.min(r, g, b); + const f2 = Math.max(r, g, b); + const l = (f1 + f2) * 0.5; + const d = f2 - f1; + let h: number; + let s: number; + if (d > 1e-6) { + s = (l < 0.5) ? + (d / (f1 + f2)) : + (d / (2 - f2 - f1)); + const d2 = d * 0.5; + const id = 1 / d; + const dr = ((f2 - r) * SIXTH + d2) * id; + const dg = ((f2 - g) * SIXTH + d2) * id; + const db = ((f2 - b) * SIXTH + d2) * id; + h = (f2 === r) ? + (db - dg) : + (f2 === g) ? + (THIRD + dr - db) : + (TWO_THIRD + dg - dr); + h = (h < 0) ? + h + 1 : + (h >= 1) ? + h - 1 : + h; + } else { + h = s = 0; + } + return setC3(out, h, s, l); + }; diff --git a/packages/color/src/rgba-hsva.ts b/packages/color/src/rgba-hsva.ts new file mode 100644 index 0000000000..e99493d45f --- /dev/null +++ b/packages/color/src/rgba-hsva.ts @@ -0,0 +1,31 @@ +import { setC3 } from "@thi.ng/vectors3/setc"; +import { Color, ReadonlyColor } from "./api"; +import { clamp } from "./clamp"; + +export const rgbaHsva = + (out: Color, rgba: ReadonlyColor) => { + out = clamp(out || rgba, rgba); + const r = out[0]; + const g = out[1]; + const b = out[2]; + const v = Math.max(r, g, b); + const d = v - Math.min(r, g, b); + let h = 0, s = 0; + if (v > 1e-6) { + s = d / v; + } + if (s > 1e-6) { + if (r === v) { + h = (g - b) / d; + } else if (g === v) { + h = 2 + (b - r) / d; + } else { + h = 4 + (r - g) / d; + } + h /= 6; + if (h < 0) { + h++; + } + } + return setC3(out, h, s, v); + }; diff --git a/packages/color/src/rgba-int.ts b/packages/color/src/rgba-int.ts new file mode 100644 index 0000000000..4b16ad35e0 --- /dev/null +++ b/packages/color/src/rgba-int.ts @@ -0,0 +1,12 @@ +import { clamp01 } from "@thi.ng/math/interval"; +import { ReadonlyColor } from "./api"; +import { ensureAlpha } from "./ensure-alpha"; + +export const rgbaInt = + (rgba: ReadonlyColor) => + ( + ((ensureAlpha(rgba[3]) * 0xff) << 24) | + ((clamp01(rgba[0]) * 0xff) << 16) | + ((clamp01(rgba[1]) * 0xff) << 8) | + (clamp01(rgba[2]) * 0xff) + ) >>> 0; diff --git a/packages/color/test/index.ts b/packages/color/test/index.ts new file mode 100644 index 0000000000..b24042baaf --- /dev/null +++ b/packages/color/test/index.ts @@ -0,0 +1,6 @@ +// import * as assert from "assert"; +// import * as c from "../src/index"; + +describe("color", () => { + it("tests pending"); +}); diff --git a/packages/color/test/tsconfig.json b/packages/color/test/tsconfig.json new file mode 100644 index 0000000000..bcf29ace54 --- /dev/null +++ b/packages/color/test/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "../build" + }, + "include": [ + "./**/*.ts", + "../src/**/*.ts" + ] +} diff --git a/packages/color/tsconfig.json b/packages/color/tsconfig.json new file mode 100644 index 0000000000..f6c291a0a0 --- /dev/null +++ b/packages/color/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "." + }, + "include": [ + "./src/**/*.ts" + ] +} \ No newline at end of file From eb5f63915cf36b679617b4f9c33aa8d3d5b3a3f3 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 22 Dec 2018 21:31:13 +0000 Subject: [PATCH 085/333] feat(vectors): add setC() --- packages/vectors3/src/index.ts | 1 + packages/vectors3/src/setc.ts | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 packages/vectors3/src/setc.ts diff --git a/packages/vectors3/src/index.ts b/packages/vectors3/src/index.ts index 814c1cc096..356357f299 100644 --- a/packages/vectors3/src/index.ts +++ b/packages/vectors3/src/index.ts @@ -83,6 +83,7 @@ export * from "./rotate-around-point"; export * from "./rotate"; export * from "./round"; export * from "./set"; +export * from "./setc"; export * from "./setn"; export * from "./sets"; export * from "./setsn"; diff --git a/packages/vectors3/src/setc.ts b/packages/vectors3/src/setc.ts new file mode 100644 index 0000000000..b7b50035df --- /dev/null +++ b/packages/vectors3/src/setc.ts @@ -0,0 +1,33 @@ +import { Vec } from "./api"; + +export const setC2 = + (out: Vec, x: number, y: number) => ( + out[0] = x, + out[1] = y, + out + ); + +export const setC3 = + (out: Vec, x: number, y: number, z: number) => ( + out[0] = x, + out[1] = y, + out[2] = z, + out + ); + +export const setC4 = + (out: Vec, x: number, y: number, z: number, w: number) => ( + out[0] = x, + out[1] = y, + out[2] = z, + out[3] = w, + out + ); + +export const setC = + (out: Vec, ...xs: number[]) => { + for (let i = 0, n = xs.length; i < n; i++) { + out[i] = xs[i]; + } + return out; + }; From 8fa05c3d3222ddff6fbd5746e995d6157a172e9a Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 22 Dec 2018 21:31:39 +0000 Subject: [PATCH 086/333] feat(math): add constants --- packages/math/src/api.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/math/src/api.ts b/packages/math/src/api.ts index 3382fb9122..af3a19daf2 100644 --- a/packages/math/src/api.ts +++ b/packages/math/src/api.ts @@ -11,4 +11,8 @@ export const RAD2DEG = 180 / PI; export const SQRT2 = Math.SQRT2; export const SQRT3 = Math.sqrt(3); +export const THIRD = 1 / 3; +export const TWO_THIRD = 2 / 3; +export const SIXTH = 1 / 6; + export let EPS = 1e-6; From a5d2f98ede236bbe6939d20fdb7d63657d2092b9 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 23 Dec 2018 16:12:16 +0000 Subject: [PATCH 087/333] feat(color): add Porter-Duff ops, pre/post-multiply, update types --- packages/color/README.md | 90 +++++++++++++++++++++- packages/color/src/api.ts | 5 +- packages/color/src/convert.ts | 14 ++-- packages/color/src/hsva-hsla.ts | 7 +- packages/color/src/index.ts | 1 + packages/color/src/matrix.ts | 12 ++- packages/color/src/mix.ts | 17 +++++ packages/color/src/parse-css.ts | 6 +- packages/color/src/porter-duff.ts | 119 ++++++++++++++++++++++++++++++ packages/color/src/premultiply.ts | 45 +++++++++++ 10 files changed, 296 insertions(+), 20 deletions(-) create mode 100644 packages/color/src/mix.ts create mode 100644 packages/color/src/porter-duff.ts create mode 100644 packages/color/src/premultiply.ts diff --git a/packages/color/README.md b/packages/color/README.md index 8809beb1f7..253dddf283 100644 --- a/packages/color/README.md +++ b/packages/color/README.md @@ -10,6 +10,10 @@ This project is part of the - [About](#about) + - [Color spaces](#color-spaces) + - [RGBA transformations](#rgba-transformations) + - [RGBA Porter-Duff compositing](#rgba-porter-duff-compositing) + - [Cosine gradients](#cosine-gradients) - [Installation](#installation) - [Dependencies](#dependencies) - [Usage examples](#usage-examples) @@ -20,7 +24,70 @@ This project is part of the ## About -TODO... +### Color spaces + +Color space conversions (any direction) between: + +- CSS (string, hex3/hex4/hex6/hex8, `rgba()`, `hsla()`, color names) +- ARGB (uint32, `0xaarrggbb`) +- RGBA (float4, `[r,g,b,a]`) +- HSLA (float4, `[h,s,l,a]`) +- HSVA (float4, `[h,s,v,a]`) + +RGBA, HSLA, HSVA colors can be stored as plain, typed or custom +array-like types of normalized values (`[0,1]` interval). + +### RGBA transformations + +RGBA color matrix transformations, including parametric preset +transforms: + +- brightness +- contrast +- exposure +- saturation (luminance aware) +- hue rotation +- color temperature (warm / cold) +- sepia (w/ fade amount) +- tint (green / purple) +- grayscale (luminance aware) +- invert (also available as non-matrix op) +- luminance to alpha + +### RGBA Porter-Duff compositing + +![porter-duff compositing modes](https://raw.githubusercontent.com/thi-ng/umbrella/feature/color/assets/porterduff.png) + +[Image source](http://www.svgopen.org/2005/papers/abstractsvgopen/#PorterDuffMap) + +### Cosine gradients + +- [Original article](http://www.iquilezles.org/www/articles/palettes/palettes.htm) +- [Gradient generator](http://dev.thi.ng/gradients/) + +The following presets are bundled (in [`cosine-gradients.ts`](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/color/src/cosine-gradients.ts)): +| | | +|----------------------------------------------------------------|------------------------------------------------------------------| +| ![](http://media.thi.ng/color/presets/rainbow1.svg) | ![](http://media.thi.ng/color/presets/rainbow2.svg) | +| rainbow1 | rainbow2 | +| ![](http://media.thi.ng/color/presets/rainbow3.svg) | ![](http://media.thi.ng/color/presets/rainbow4.svg) | +| rainbow3 | rainbow4 | +| ![](http://media.thi.ng/color/presets/yellow-magenta-cyan.svg) | ![](http://media.thi.ng/color/presets/orange-blue.svg) | +| yellow-magenta-cyan preset | orange-blue | +| ![](http://media.thi.ng/color/presets/green-magenta.svg) | ![](http://media.thi.ng/color/presets/green-red.svg) | +| green-magenta | green-red | +| ![](http://media.thi.ng/color/presets/green-cyan.svg) | ![](http://media.thi.ng/color/presets/blue-cyan.svg) | +| green-cyan | blue-cyan | +| ![](http://media.thi.ng/color/presets/yellow-red.svg) | ![](http://media.thi.ng/color/presets/red-blue.svg) | +| yellow-red | red-blue | +| ![](http://media.thi.ng/color/presets/yellow-green-blue.svg) | ![](http://media.thi.ng/color/presets/blue-white-red.svg) | +| yellow-green-blue | blue-white-red | +| ![](http://media.thi.ng/color/presets/cyan-magenta.svg) | ![](http://media.thi.ng/color/presets/yellow-purple-magenta.svg) | +| cyan-magenta | yellow-purple-magenta | +| ![](http://media.thi.ng/color/presets/green-blue-orange.svg) | ![](http://media.thi.ng/color/presets/orange-magenta-blue.svg) | +| green-blue-orange | orange-magenta-blue | +| ![](http://media.thi.ng/color/presets/blue-magenta-orange.svg) | ![](http://media.thi.ng/color/presets/magenta-green.svg) | +| blue-magenta-orange | magenta-green | ## Installation @@ -41,7 +108,26 @@ yarn add @thi.ng/color ## Usage examples ```ts -import * as c from "@thi.ng/color"; +import * as col from "@thi.ng/color"; + +// route #1: asXXX() converters: CSS -> ARGB (int) -> RGBA +const a = col.asRGBA("#3cf", col.ColorMode.CSS); +// [0.2, 0.8, 1, 1] + +// route #2: parseCSS(): CSS -> HSLA -> RGBA +const b = col.parseCss("hsla(30,100%,50%,0.75)", col.ColorMode.RGBA); +// [ 1, 0.5, 0, 0.75 ] + +// route #3: convert() multi-method: HSVA -> RGBA +const c = col.convert([0.5, 1, 1, 1], col.ColorMode.RGBA, col.ColorMode.HSVA); +// [ 0, 1, 1, 1 ] + +col.luminanceRGB(a) +// 0.6434 + +// apply color matrix (RGBA only) +col.applyMatrix([], col.saturation(1.25), a) +// [ 0.07835000000000002, 0.82835, 1, 1 ] ``` ## Authors diff --git a/packages/color/src/api.ts b/packages/color/src/api.ts index ac9429ad51..5a6b1a43dd 100644 --- a/packages/color/src/api.ts +++ b/packages/color/src/api.ts @@ -2,6 +2,7 @@ import { Vec, ReadonlyVec } from "@thi.ng/vectors3/api"; import { float } from "@thi.ng/strings/float"; import { percent } from "@thi.ng/strings/percent"; + export type Color = Vec; export type ReadonlyColor = ReadonlyVec; @@ -16,11 +17,11 @@ export type CosCoeffs = [number, number, number, number]; export type CosGradientSpec = [CosCoeffs, CosCoeffs, CosCoeffs, CosCoeffs]; export enum ColorMode { - CSS, RGBA, HSVA, HSLA, - INT_RGBA + INT_ARGB, + CSS, } // RGBA constants diff --git a/packages/color/src/convert.ts b/packages/color/src/convert.ts index 314df70aa8..e3e938585d 100644 --- a/packages/color/src/convert.ts +++ b/packages/color/src/convert.ts @@ -54,8 +54,8 @@ defConversion( ); defConversion( - ColorMode.INT_RGBA, ColorMode.CSS, - (x: string) => parseCss(x, ColorMode.INT_RGBA) + ColorMode.INT_ARGB, ColorMode.CSS, + (x: string) => parseCss(x, ColorMode.INT_ARGB) ); defConversion( @@ -66,22 +66,22 @@ defConversion( // Int defConversion( - ColorMode.CSS, ColorMode.INT_RGBA, + ColorMode.CSS, ColorMode.INT_ARGB, (x: number) => intCss(x) ); defConversion( - ColorMode.HSLA, ColorMode.INT_RGBA, + ColorMode.HSLA, ColorMode.INT_ARGB, (x: number) => rgbaHsla(null, intRgba([], x)) ); defConversion( - ColorMode.HSVA, ColorMode.INT_RGBA, + ColorMode.HSVA, ColorMode.INT_ARGB, (x: number) => rgbaHsva(null, intRgba([], x)) ); defConversion( - ColorMode.RGBA, ColorMode.INT_RGBA, + ColorMode.RGBA, ColorMode.INT_ARGB, (x: number) => intRgba([], x) ); @@ -127,6 +127,6 @@ defConversion( ); defConversion( - ColorMode.INT_RGBA, ColorMode.RGBA, + ColorMode.INT_ARGB, ColorMode.RGBA, (x: ReadonlyColor) => rgbaInt(x) ); diff --git a/packages/color/src/hsva-hsla.ts b/packages/color/src/hsva-hsla.ts index 72706a2990..7a37ab11fb 100644 --- a/packages/color/src/hsva-hsla.ts +++ b/packages/color/src/hsva-hsla.ts @@ -4,13 +4,12 @@ import { clamp } from "./clamp"; export const hsvaHsla = (out: Color, hsva: ReadonlyColor) => { out = clamp(out || hsva, hsva); - let s = out[1]; + const s = out[1]; const v = out[2]; const l = (2 - s) * v / 2; - s = l && l < 1 ? + out[2] = l; + out[1] = l && l < 1 ? s * v / (l < 0.5 ? l * 2 : 2 - l * 2) : s; - out[1] = s; - out[2] = l; return out; }; \ No newline at end of file diff --git a/packages/color/src/index.ts b/packages/color/src/index.ts index a35726d540..42500767b9 100644 --- a/packages/color/src/index.ts +++ b/packages/color/src/index.ts @@ -23,3 +23,4 @@ export * from "./luminance"; export * from "./cosine-gradients"; export * from "./matrix"; +export * from "./porter-duff"; diff --git a/packages/color/src/matrix.ts b/packages/color/src/matrix.ts index fcd88b4210..4ce4af5f0c 100644 --- a/packages/color/src/matrix.ts +++ b/packages/color/src/matrix.ts @@ -22,8 +22,8 @@ const S7 = 0.143; const S8 = 0.283; export const applyMatrix = - (out: Color, mat: ColorMatrix, rgba: ReadonlyColor, clamped = true) => - clamped ? + (out: Color, mat: ColorMatrix, rgba: ReadonlyColor, clampOut = true) => + clampOut ? setC4( out || rgba, clamp01(dotS4(rgba, mat, 0, 0) + mat[4]), @@ -75,6 +75,14 @@ export const IDENTITY: ColorMatrix = 0, 0, 0, 1, 0 ]; +export const INVERT: ColorMatrix = + [ + -1, 0, 0, 0, 1, + 0, -1, 0, 0, 1, + 0, 0, -1, 0, 1, + 0, 0, 0, 1, 0 + ]; + export const brightness = (x: number): ColorMatrix => [ diff --git a/packages/color/src/mix.ts b/packages/color/src/mix.ts new file mode 100644 index 0000000000..d13fd79743 --- /dev/null +++ b/packages/color/src/mix.ts @@ -0,0 +1,17 @@ +import { mixN4 } from "@thi.ng/vectors3/mixn"; +import { Color, ReadonlyColor } from "./api"; +import { setC4 } from "@thi.ng/vectors3/setc"; +import { mix as _mix } from "@thi.ng/math/mix"; + +export const mix: (out: Color, a: ReadonlyColor, b: ReadonlyColor, t: number) => Color = + mixN4; + +export const mixAlpha = + (out: Color, a: ReadonlyColor, b: ReadonlyColor) => + setC4( + out || a, + _mix(a[0], b[0], a[3]), + _mix(a[0], b[0], a[3]), + _mix(a[0], b[0], a[3]), + a[3] + ); diff --git a/packages/color/src/parse-css.ts b/packages/color/src/parse-css.ts index 19403bcbb9..b9934bf356 100644 --- a/packages/color/src/parse-css.ts +++ b/packages/color/src/parse-css.ts @@ -1,9 +1,9 @@ import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { clamp01 } from "@thi.ng/math/interval"; import { maybeParseFloat, maybeParseInt } from "@thi.ng/strings/parse"; import { Color, ColorMode, INV8BIT } from "./api"; import { convert } from "./convert"; import { CSS_NAMES } from "./names"; -import { clamp01 } from "@thi.ng/math/interval"; const RE_HEX = /^#?([0-9a-f]{3,8})$/i; const RE_CSS = /^(rgb|hsl)a?\(\s*([0-9.]+?),\s*([0-9.]+%?),\s*([0-9.]+%?),?\s*([0-9.]+)?\s*\)$/; @@ -13,7 +13,7 @@ export const parseCss = let res: Color | number; let resMode: ColorMode; if (col.charAt(0) === "#") { - resMode = ColorMode.INT_RGBA; + resMode = ColorMode.INT_ARGB; res = parseHex(col); } else { const match = RE_CSS.exec(col); @@ -38,7 +38,7 @@ export const parseCss = } else { const c = CSS_NAMES[col]; !c && illegalArgs(`invalid color: "${col}"`); - resMode = ColorMode.INT_RGBA; + resMode = ColorMode.INT_ARGB; res = parseHex(c); } } diff --git a/packages/color/src/porter-duff.ts b/packages/color/src/porter-duff.ts new file mode 100644 index 0000000000..ebd82a4ad0 --- /dev/null +++ b/packages/color/src/porter-duff.ts @@ -0,0 +1,119 @@ +import { setC4 } from "@thi.ng/vectors3/setc"; +import { setN4 } from "@thi.ng/vectors3/setn"; +import { Color, ReadonlyColor } from "./api"; +import { postmultiply, premultiply } from "./premultiply"; + +// http://ssp.impulsetrain.com/porterduff.html +// https://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending + +/** + * General Porter-Duff operator for **pre-multiplied** RGBA. Use + * `porderDiffP` for applying pre & post multiplication of input and + * output colors. + * + * Reference: + * https://drafts.fxtf.org/compositing-1/#advancedcompositing + * http://www.svgopen.org/2005/papers/abstractsvgopen/#PorterDuffMap + * + * @param out writes to `dest` if null + * @param src + * @param dest + * @param f blend function + * @param x factor of "both" region + * @param y factor of "src" region + * @param z factor of "dest" region + */ +export const porterDuff = ( + out: Color, + src: ReadonlyColor, + dest: ReadonlyColor, + f: (s: number, d: number) => number, + x: 0 | 1, + y: 0 | 1, + z: 0 | 1 +): Color => { + const sa = src[3]; + const da = dest[3]; + const sda = sa * da; + const sy = y * sa * (1 - da); + const sz = z * da * (1 - sa); + const dot = y ? + z ? + (s: number, d: number) => f(s, d) * sda + s * sy + d * sz : + (s: number, d: number) => f(s, d) * sda + s * sy : + z ? + (s: number, d: number) => f(s, d) * sda + d * sz : + (s: number, d: number) => f(s, d) * sda; + return setC4( + out || dest, + dot(src[0], dest[0]), + dot(src[1], dest[1]), + dot(src[2], dest[2]), + x * sda + sy + sz + ); +}; + +/** + * Like `porterDuff`, but pre-multiplies alpha for both input colors and + * then post-multiplies alpha to output. + * + * @param out + * @param src + * @param dest + * @param mode + */ +export const porterDuffP = ( + out: Color, + src: ReadonlyColor, + dest: ReadonlyColor, + mode: (out: Color, _: ReadonlyColor, dest: ReadonlyColor) => Color +) => + postmultiply(null, mode(null, premultiply([], src), premultiply(out, dest))); + +export const clear = + (out: Color, _: ReadonlyColor, dest: ReadonlyColor) => + setN4(out || dest, 0); + +export const src = + (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => + porterDuff(out, src, dest, (s) => s, 1, 1, 0); + +export const dest = + (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => + porterDuff(out, src, dest, (_, d) => d, 1, 0, 1); + +export const srcOver = + (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => + porterDuff(out, src, dest, (s) => s, 1, 1, 1); + +export const destOver = + (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => + porterDuff(out, src, dest, (_, d) => d, 1, 1, 1); + +export const srcIn = + (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => + porterDuff(out, src, dest, (s) => s, 1, 0, 0); + +export const destIn = + (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => + porterDuff(out, src, dest, (_, d) => d, 1, 0, 0); + +export const srcOut = + (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => + porterDuff(out, src, dest, (s) => s, 0, 1, 0); + +export const destOut = + (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => + porterDuff(out, src, dest, (_, d) => d, 0, 0, 1); + +export const srcAtop = + (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => + porterDuff(out, src, dest, (s) => s, 1, 0, 1); + +export const destAtop = + (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => + porterDuff(out, src, dest, (_, d) => d, 1, 1, 0); + +export const xor = + (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => + porterDuff(out, src, dest, () => 0, 0, 1, 1); diff --git a/packages/color/src/premultiply.ts b/packages/color/src/premultiply.ts new file mode 100644 index 0000000000..f8f1072d71 --- /dev/null +++ b/packages/color/src/premultiply.ts @@ -0,0 +1,45 @@ +import { Color, ReadonlyColor } from "./api"; +import { set } from "@thi.ng/vectors3/set"; +import { setC4 } from "@thi.ng/vectors3/setc"; + +/** + * Multiplies RGB channels w/ alpha channel. + * Assumes alpha is in [0 .. 1] interval. + * + * @param out + * @param rgba + */ +export const premultiply = + (out: Color, rgba: ReadonlyColor) => { + const a = rgba[3]; + return setC4( + out || rgba, + rgba[0] * a, + rgba[1] * a, + rgba[2] * a, + a + ); + }; + +/** + * Reverse operation of `premultiply`. Divides RGB channels by alpha, + * unless alpha is zero. Does NOT clamp result. + * + * @param out + * @param rgba + */ +export const postmultiply = + (out: Color, rgba: ReadonlyColor) => { + const a = rgba[3]; + return a > 0 ? + setC4( + out || rgba, + rgba[0] / a, + rgba[1] / a, + rgba[2] / a, + a + ) : + !out && out != rgba ? + set(out, rgba) : + rgba; + }; From 404ac54b9365ef553d3a90f4d50658ad3058c4a7 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 24 Dec 2018 01:41:15 +0000 Subject: [PATCH 088/333] feat(color): add HSI converters, add clampH(), minor refactors --- packages/color/README.md | 5 +++-- packages/color/src/api.ts | 1 + packages/color/src/clamp.ts | 11 ++++++++++ packages/color/src/convert.ts | 23 ++++++++++++++++++++ packages/color/src/hsia-rgba.ts | 37 +++++++++++++++++++++++++++++++++ packages/color/src/hsla-css.ts | 3 ++- packages/color/src/hsla-hsva.ts | 4 ++-- packages/color/src/hsla-rgba.ts | 8 +++---- packages/color/src/hsva-hsla.ts | 4 ++-- packages/color/src/hsva-rgba.ts | 8 +++---- packages/color/src/index.ts | 3 +++ packages/color/src/rgba-hsia.ts | 29 ++++++++++++++++++++++++++ 12 files changed, 120 insertions(+), 16 deletions(-) create mode 100644 packages/color/src/hsia-rgba.ts create mode 100644 packages/color/src/rgba-hsia.ts diff --git a/packages/color/README.md b/packages/color/README.md index 253dddf283..fb3381739f 100644 --- a/packages/color/README.md +++ b/packages/color/README.md @@ -10,7 +10,7 @@ This project is part of the - [About](#about) - - [Color spaces](#color-spaces) + - [Color modes](#color-modes) - [RGBA transformations](#rgba-transformations) - [RGBA Porter-Duff compositing](#rgba-porter-duff-compositing) - [Cosine gradients](#cosine-gradients) @@ -24,13 +24,14 @@ This project is part of the ## About -### Color spaces +### Color modes Color space conversions (any direction) between: - CSS (string, hex3/hex4/hex6/hex8, `rgba()`, `hsla()`, color names) - ARGB (uint32, `0xaarrggbb`) - RGBA (float4, `[r,g,b,a]`) +- HSIA (float4, `[h,s,i,a]`) - HSLA (float4, `[h,s,l,a]`) - HSVA (float4, `[h,s,v,a]`) diff --git a/packages/color/src/api.ts b/packages/color/src/api.ts index 5a6b1a43dd..47b64ed647 100644 --- a/packages/color/src/api.ts +++ b/packages/color/src/api.ts @@ -20,6 +20,7 @@ export enum ColorMode { RGBA, HSVA, HSLA, + HSIA, INT_ARGB, CSS, } diff --git a/packages/color/src/clamp.ts b/packages/color/src/clamp.ts index 975a35639b..d7134caffc 100644 --- a/packages/color/src/clamp.ts +++ b/packages/color/src/clamp.ts @@ -2,6 +2,7 @@ import { clamp01 } from "@thi.ng/math/interval"; import { setC4 } from "@thi.ng/vectors3/setc"; import { Color, ReadonlyColor } from "./api"; import { ensureAlpha } from "./ensure-alpha"; +import { ensureHue } from "./ensure-hue"; export const clamp = (out: Color, src: ReadonlyColor, alpha = 1) => @@ -12,3 +13,13 @@ export const clamp = clamp01(src[2]), ensureAlpha(src[3], alpha) ); + +export const clampH = + (out: Color, src: ReadonlyColor, alpha = 1) => + setC4( + out || src, + ensureHue(src[0]), + clamp01(src[1]), + clamp01(src[2]), + ensureAlpha(src[3], alpha) + ); diff --git a/packages/color/src/convert.ts b/packages/color/src/convert.ts index e3e938585d..6e93ea0ecd 100644 --- a/packages/color/src/convert.ts +++ b/packages/color/src/convert.ts @@ -11,6 +11,7 @@ import { rgbaCss } from "./rgba-css"; import { rgbaHsla } from "./rgba-hsla"; import { rgbaHsva } from "./rgba-hsva"; import { rgbaInt } from "./rgba-int"; +import { hsiaRgba } from "./hsia-rgba"; export const convert: MultiFn3 = defmulti((...args: any[]) => convID(args[1], args[2])); @@ -85,6 +86,28 @@ defConversion( (x: number) => intRgba([], x) ); +// HSIA + +defConversion( + ColorMode.CSS, ColorMode.HSIA, + (x: ReadonlyColor) => rgbaCss(hsiaRgba([], x)) +); + +defConversion( + ColorMode.HSLA, ColorMode.HSIA, + (x: ReadonlyColor) => rgbaHsla(null, hsiaRgba([], x)) +); + +defConversion( + ColorMode.HSVA, ColorMode.HSIA, + (x: ReadonlyColor) => rgbaHsva(null, hsiaRgba([], x)) +); + +defConversion( + ColorMode.RGBA, ColorMode.HSIA, + (x: ReadonlyColor) => hsiaRgba([], x) +); + // HSLA defConversion( diff --git a/packages/color/src/hsia-rgba.ts b/packages/color/src/hsia-rgba.ts new file mode 100644 index 0000000000..92469dea94 --- /dev/null +++ b/packages/color/src/hsia-rgba.ts @@ -0,0 +1,37 @@ +import { setC3 } from "@thi.ng/vectors3/setc"; +import { Color, ReadonlyColor } from "./api"; +import { clampH } from "./clamp"; + +// https://en.wikipedia.org/wiki/HSL_and_HSV#From_HSI + +export const hsiaRgba = + (out: Color, hsia: ReadonlyColor) => { + out = clampH(out || hsia, hsia); + const s = out[1]; + const i = out[2]; + if (s < 1e-6) { + return setC3(out, i, i, i); + } + const h = (out[0] * 6) % 6; + const m = i * (1 - s); + const z = 1 - Math.abs(h % 2 - 1); + let c = 3 * i * s / (1 + z); + const x = c * z + m; + c += m; + switch (h | 0) { + case 0: + return setC3(out, c, x, m); + case 1: + return setC3(out, x, c, m); + case 2: + return setC3(out, m, c, x); + case 3: + return setC3(out, m, x, c); + case 4: + return setC3(out, x, m, c); + case 5: + return setC3(out, c, m, x); + default: + return setC3(out, m, m, m); + } + }; diff --git a/packages/color/src/hsla-css.ts b/packages/color/src/hsla-css.ts index 8fb3f7fa2d..449ea799ba 100644 --- a/packages/color/src/hsla-css.ts +++ b/packages/color/src/hsla-css.ts @@ -1,10 +1,11 @@ import { clamp01 } from "@thi.ng/math/interval"; import { FF, PC, ReadonlyColor } from "./api"; import { ensureAlpha } from "./ensure-alpha"; +import { ensureHue } from "./ensure-hue"; export const hslaCss = (hsla: ReadonlyColor) => { - const h = FF(clamp01(hsla[0]) * 360); + const h = FF(ensureHue(hsla[0]) * 360); const s = PC(clamp01(hsla[1])); const l = PC(clamp01(hsla[2])); const a = ensureAlpha(hsla[3]); diff --git a/packages/color/src/hsla-hsva.ts b/packages/color/src/hsla-hsva.ts index 18ba2428c1..b3107f4d45 100644 --- a/packages/color/src/hsla-hsva.ts +++ b/packages/color/src/hsla-hsva.ts @@ -1,9 +1,9 @@ import { Color, ReadonlyColor } from "./api"; -import { clamp } from "./clamp"; +import { clampH } from "./clamp"; export const hslaHsva = (out: Color, hsla: ReadonlyColor) => { - out = clamp(out || hsla, hsla); + out = clampH(out || hsla, hsla); const s = out[1]; const l = out[2]; const l2 = 2 * l; diff --git a/packages/color/src/hsla-rgba.ts b/packages/color/src/hsla-rgba.ts index 0ebcf75488..8700c5f880 100644 --- a/packages/color/src/hsla-rgba.ts +++ b/packages/color/src/hsla-rgba.ts @@ -2,18 +2,18 @@ import { SIXTH, THIRD, TWO_THIRD } from "@thi.ng/math/api"; import { clamp01 } from "@thi.ng/math/interval"; import { setC3 } from "@thi.ng/vectors3/setc"; import { Color, ReadonlyColor } from "./api"; -import { clamp } from "./clamp"; +import { clampH } from "./clamp"; import { ensureHue } from "./ensure-hue"; export const hslaRgba = (out: Color, hsla: ReadonlyColor) => { - out = clamp(out || hsla, hsla); + out = clampH(out || hsla, hsla); const h = out[0]; const s = out[1]; const l = out[2]; if (s > 1e-6) { - const f2 = (l < 0.5) ? - (l * (s + 1)) : + const f2 = l < 0.5 ? + l * (s + 1) : (l + s) - (l * s); const f1 = 2 * l - f2; return setC3( diff --git a/packages/color/src/hsva-hsla.ts b/packages/color/src/hsva-hsla.ts index 7a37ab11fb..c42213a0ff 100644 --- a/packages/color/src/hsva-hsla.ts +++ b/packages/color/src/hsva-hsla.ts @@ -1,9 +1,9 @@ import { ReadonlyColor, Color } from "./api"; -import { clamp } from "./clamp"; +import { clampH } from "./clamp"; export const hsvaHsla = (out: Color, hsva: ReadonlyColor) => { - out = clamp(out || hsva, hsva); + out = clampH(out || hsva, hsva); const s = out[1]; const v = out[2]; const l = (2 - s) * v / 2; diff --git a/packages/color/src/hsva-rgba.ts b/packages/color/src/hsva-rgba.ts index 6e097482c0..f25b824994 100644 --- a/packages/color/src/hsva-rgba.ts +++ b/packages/color/src/hsva-rgba.ts @@ -1,16 +1,14 @@ import { setC3 } from "@thi.ng/vectors3/setc"; import { Color, ReadonlyColor } from "./api"; -import { clamp } from "./clamp"; +import { clampH } from "./clamp"; export const hsvaRgba = (out: Color, hsva: ReadonlyColor) => { - out = clamp(out || hsva, hsva); - let h = out[0]; + out = clampH(out || hsva, hsva); const s = out[1]; const v = out[2]; if (s > 1e-6) { - h = (h * 6) % 6; - h < 0 && (h += 6); + const h = (out[0] * 6) % 6; const i = h | 0; const f = h - i; const p = v * (1 - s); diff --git a/packages/color/src/index.ts b/packages/color/src/index.ts index 42500767b9..495ed243fd 100644 --- a/packages/color/src/index.ts +++ b/packages/color/src/index.ts @@ -4,6 +4,7 @@ export * from "./names"; export * from "./convert"; export * from "./parse-css"; +export * from "./hsia-rgba"; export * from "./hsla-css"; export * from "./hsla-hsva"; export * from "./hsla-rgba"; @@ -13,6 +14,7 @@ export * from "./hsva-rgba"; export * from "./int-css"; export * from "./int-rgba"; export * from "./rgba-css"; +export * from "./rgba-hsia"; export * from "./rgba-hsla"; export * from "./rgba-hsva"; export * from "./rgba-int"; @@ -24,3 +26,4 @@ export * from "./cosine-gradients"; export * from "./matrix"; export * from "./porter-duff"; + diff --git a/packages/color/src/rgba-hsia.ts b/packages/color/src/rgba-hsia.ts new file mode 100644 index 0000000000..7622e220eb --- /dev/null +++ b/packages/color/src/rgba-hsia.ts @@ -0,0 +1,29 @@ +import { setC3 } from "@thi.ng/vectors3/setc"; +import { Color, ReadonlyColor } from "./api"; +import { clamp } from "./clamp"; +import { SQRT3, THIRD, TAU } from "@thi.ng/math/api"; +import { atan2Abs } from "@thi.ng/math/angle"; + +// https://en.wikipedia.org/wiki/HSL_and_HSV#Hue_and_chroma + +const SQRT32 = SQRT3 / 2; + +export const rgbaHsia = + (out: Color, rgba: ReadonlyColor) => { + out = clamp(out || rgba, rgba); + const r = out[0]; + const g = out[1]; + const b = out[2]; + const i = THIRD * (r + g + b); + return i < 1e-6 || (r === g && r === b) ? + setC3(out, 0, 0, i) : + setC3( + out, + atan2Abs( + SQRT32 * (g - b), + 0.5 * (2 * r - g - b) + ) / TAU, + 1 - Math.min(r, g, b) / i, + i + ); + }; From 610699ab93dd8d6b1bf663d2e7d641cb0e14b916 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 24 Dec 2018 15:38:30 +0000 Subject: [PATCH 089/333] feat(color): add RGBA/HSLA wrapper types, update convert --- packages/color/src/api.ts | 4 ++ packages/color/src/clamp.ts | 17 +++++++++ packages/color/src/convert.ts | 69 ++++++++++++++++++++++++----------- packages/color/src/hsla.ts | 54 +++++++++++++++++++++++++++ packages/color/src/index.ts | 2 + packages/color/src/rgba.ts | 51 ++++++++++++++++++++++++++ 6 files changed, 176 insertions(+), 21 deletions(-) create mode 100644 packages/color/src/hsla.ts create mode 100644 packages/color/src/rgba.ts diff --git a/packages/color/src/api.ts b/packages/color/src/api.ts index 47b64ed647..652ca1bf72 100644 --- a/packages/color/src/api.ts +++ b/packages/color/src/api.ts @@ -25,6 +25,10 @@ export enum ColorMode { CSS, } +export interface IColor { + readonly mode: ColorMode; +} + // RGBA constants export const BLACK = Object.freeze([0, 0, 0, 1]); diff --git a/packages/color/src/clamp.ts b/packages/color/src/clamp.ts index d7134caffc..fdbf74d6b5 100644 --- a/packages/color/src/clamp.ts +++ b/packages/color/src/clamp.ts @@ -4,6 +4,15 @@ import { Color, ReadonlyColor } from "./api"; import { ensureAlpha } from "./ensure-alpha"; import { ensureHue } from "./ensure-hue"; +/** + * Clamps all color channels to [0,1] interval and calls `ensureAlpha()` + * to ensure alpha channel is defined (if missing sets it to `alpha` + * (default: 1)). + * + * @param out + * @param src + * @param alpha + */ export const clamp = (out: Color, src: ReadonlyColor, alpha = 1) => setC4( @@ -14,6 +23,14 @@ export const clamp = ensureAlpha(src[3], alpha) ); +/** + * Similar to `clamp`, but calls `ensureHue()` to fold (instead of + * clamping) the hue into [0,1] interval. + * + * @param out + * @param src + * @param alpha + */ export const clampH = (out: Color, src: ReadonlyColor, alpha = 1) => setC4( diff --git a/packages/color/src/convert.ts b/packages/color/src/convert.ts index 6e93ea0ecd..25468b47ab 100644 --- a/packages/color/src/convert.ts +++ b/packages/color/src/convert.ts @@ -1,5 +1,12 @@ -import { defmulti, Implementation3, MultiFn3 } from "@thi.ng/defmulti"; -import { Color, ColorMode, ReadonlyColor } from "./api"; +import { defmulti, Implementation3, MultiFn2O } from "@thi.ng/defmulti"; +import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { + Color, + ColorMode, + IColor, + ReadonlyColor +} from "./api"; +import { hsiaRgba } from "./hsia-rgba"; import { hslaCss } from "./hsla-css"; import { hslaRgba } from "./hsla-rgba"; import { hsvaCss } from "./hsva-css"; @@ -8,29 +15,44 @@ import { intCss } from "./int-css"; import { intRgba } from "./int-rgba"; import { parseCss } from "./parse-css"; import { rgbaCss } from "./rgba-css"; +import { rgbaHsia } from "./rgba-hsia"; import { rgbaHsla } from "./rgba-hsla"; import { rgbaHsva } from "./rgba-hsva"; import { rgbaInt } from "./rgba-int"; -import { hsiaRgba } from "./hsia-rgba"; - -export const convert: MultiFn3 = - defmulti((...args: any[]) => convID(args[1], args[2])); - -export const asRGBA = (col: string | number | ReadonlyColor, mode: ColorMode) => - convert(col, ColorMode.RGBA, mode); - -export const asHSLA = (col: string | number | ReadonlyColor, mode: ColorMode) => - convert(col, ColorMode.HSLA, mode); -export const asHSVA = (col: string | number | ReadonlyColor, mode: ColorMode) => - convert(col, ColorMode.HSLA, mode); - -export const asCSS = (col: string | number | ReadonlyColor, mode: ColorMode) => - convert(col, ColorMode.CSS, mode); +export const convert: MultiFn2O = + defmulti( + (col, mdest, msrc) => + (col).mode !== undefined ? + `${ColorMode[mdest]}-${ColorMode[(col).mode]}` : + msrc !== undefined ? + `${ColorMode[mdest]}-${ColorMode[msrc]}` : + illegalArgs(`missing src color mode`) + ); -const convID = - (dest: ColorMode, src: ColorMode) => - `${ColorMode[dest]}-${ColorMode[src]}`; +export function asRGBA(col: IColor): Color; +export function asRGBA(col: string | number | ReadonlyColor, mode: ColorMode): Color; +export function asRGBA(col: any, mode?: ColorMode) { + return convert(col, ColorMode.RGBA, mode); +} + +export function asHSLA(col: IColor): Color; +export function asHSLA(col: string | number | ReadonlyColor, mode: ColorMode): Color; +export function asHSLA(col: any, mode?: ColorMode) { + return convert(col, ColorMode.HSLA, mode); +} + +export function asHSVA(col: IColor): Color; +export function asHSVA(col: string | number | ReadonlyColor, mode: ColorMode): Color; +export function asHSVA(col: any, mode?: ColorMode) { + return convert(col, ColorMode.HSVA, mode); +} + +export function asCSS(col: IColor): string; +export function asCSS(col: string | number | ReadonlyColor, mode: ColorMode): string; +export function asCSS(col: any, mode?: ColorMode) { + return convert(col, ColorMode.CSS, mode); +} const defConversion = ( dest: ColorMode, @@ -38,7 +60,7 @@ const defConversion = ( impl: Implementation3 ) => convert.add( - convID(dest, src), + `${ColorMode[dest]}-${ColorMode[src]}`, impl ); @@ -139,6 +161,11 @@ defConversion( (x: ReadonlyColor) => rgbaCss(x) ); +defConversion( + ColorMode.HSIA, ColorMode.RGBA, + (x: ReadonlyColor) => rgbaHsia([], x) +); + defConversion( ColorMode.HSLA, ColorMode.RGBA, (x: ReadonlyColor) => rgbaHsla([], x) diff --git a/packages/color/src/hsla.ts b/packages/color/src/hsla.ts new file mode 100644 index 0000000000..ae68ced3d2 --- /dev/null +++ b/packages/color/src/hsla.ts @@ -0,0 +1,54 @@ +import { EPS } from "@thi.ng/math/api"; +import { IVector, Vec } from "@thi.ng/vectors3/api"; +import { eqDelta4 } from "@thi.ng/vectors3/eqdelta"; +import { declareIndices } from "@thi.ng/vectors3/internal/accessors"; +import { AVec } from "@thi.ng/vectors3/internal/avec"; +import { ColorMode, IColor } from "./api"; + +export class HSLA extends AVec implements + IColor, + IVector { + + h: number; + s: number; + l: number; + a: number; + [id: number]: number; + + constructor(buf?: Vec, i = 0, s = 1) { + super(buf || [0, 0, 0, 0], i, s); + } + + *[Symbol.iterator]() { + yield this[0]; + yield this[1]; + yield this[2]; + yield this[3]; + } + + get mode() { + return ColorMode.HSLA; + } + + get length() { + return 4; + } + + copy() { + return new HSLA([this[0], this[1], this[2], this[3]]); + } + + copyView() { + return new HSLA(this.buf, this.offset, this.stride); + } + + empty() { + return new HSLA(); + } + + eqDelta(o: HSLA, eps = EPS): boolean { + return eqDelta4(this, o, eps); + } +} + +declareIndices(HSLA.prototype, ["h", "s", "v", "a"]); diff --git a/packages/color/src/index.ts b/packages/color/src/index.ts index 495ed243fd..b9f58aff0b 100644 --- a/packages/color/src/index.ts +++ b/packages/color/src/index.ts @@ -27,3 +27,5 @@ export * from "./cosine-gradients"; export * from "./matrix"; export * from "./porter-duff"; +export * from "./hsla"; +export * from "./rgba"; diff --git a/packages/color/src/rgba.ts b/packages/color/src/rgba.ts new file mode 100644 index 0000000000..28739ed77b --- /dev/null +++ b/packages/color/src/rgba.ts @@ -0,0 +1,51 @@ +import { EPS } from "@thi.ng/math/api"; +import { IVector, Vec } from "@thi.ng/vectors3/api"; +import { eqDelta4 } from "@thi.ng/vectors3/eqdelta"; +import { declareIndices } from "@thi.ng/vectors3/internal/accessors"; +import { AVec } from "@thi.ng/vectors3/internal/avec"; +import { ColorMode, IColor } from "./api"; + +export class RGBA extends AVec implements + IColor, + IVector { + + r: number; + g: number; + b: number; + a: number; + [id: number]: number; + + constructor(buf?: Vec, offset = 0, stride = 1) { + super(buf || [0, 0, 0, 0], offset, stride); + } + + *[Symbol.iterator]() { + yield* [this.r, this.g, this.b, this.a]; + } + + get mode() { + return ColorMode.RGBA; + } + + get length() { + return 4; + } + + copy() { + return new RGBA([this.r, this.g, this.b, this.a]); + } + + copyView() { + return new RGBA(this.buf, this.offset, this.stride); + } + + empty() { + return new RGBA(); + } + + eqDelta(o: RGBA, eps = EPS): boolean { + return eqDelta4(this, o, eps); + } +} + +declareIndices(RGBA.prototype, ["r", "g", "b", "a"]); From c2556c2ecc868792a309fa5c67103014e43dc749 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 24 Dec 2018 15:40:51 +0000 Subject: [PATCH 090/333] refactor(vectors): update declareIndices, extract single declareIndex fn --- packages/vectors3/src/internal/accessors.ts | 51 +++++++++++---------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/packages/vectors3/src/internal/accessors.ts b/packages/vectors3/src/internal/accessors.ts index 95510fdcc3..2bddb24b6b 100644 --- a/packages/vectors3/src/internal/accessors.ts +++ b/packages/vectors3/src/internal/accessors.ts @@ -1,29 +1,32 @@ -export const declareIndices = ( +export const declareIndex = ( proto: any, - props: string[], + id: string, + i: number, strided = true, - defNumeric = true) => { - - const get = (i: number) => - strided ? - function () { return this.buf[this.i + i * this.s]; } : - function () { return this.buf[this.i + i]; }; + defNumeric = true +) => { + const get = strided ? + function () { return this.buf[this.i + i * this.s]; } : + function () { return this.buf[this.i + i]; }; + const set = strided ? + function (n: number) { this.buf[this.i + i * this.s] = n; } : + function (n: number) { this.buf[this.i + i] = n; }; - const set = (i: number) => - strided ? - function (n: number) { this.buf[this.i + i * this.s] = n; } : - function (n: number) { this.buf[this.i + i] = n; }; - - props.forEach((id, i) => { - defNumeric && Object.defineProperty(proto, i, { - get: get(i), - set: set(i), - enumerable: true, - }); - Object.defineProperty(proto, id, { - get: get(i), - set: set(i), - enumerable: true, - }); + defNumeric && Object.defineProperty(proto, i, { + get, + set, + enumerable: true, + }); + Object.defineProperty(proto, id, { + get, + set, + enumerable: true, }); }; + +export const declareIndices = ( + proto: any, + props: string[], + strided?: boolean, + defNumeric?: boolean +) => props.forEach((id, i) => declareIndex(proto, id, i, strided, defNumeric)); From 6e6a33ce30e97b71949652d03bb6756a928933b2 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 24 Dec 2018 15:41:49 +0000 Subject: [PATCH 091/333] refactor(vectors): update IVector (rename fields), add ICopyView --- packages/vectors3/src/api.ts | 9 ++++- packages/vectors3/src/internal/avec.ts | 10 ++--- packages/vectors3/src/map.ts | 56 +++++++++++++------------- packages/vectors3/src/vec2.ts | 6 +-- packages/vectors3/src/vec3.ts | 6 +-- packages/vectors3/src/vec4.ts | 6 +-- 6 files changed, 49 insertions(+), 44 deletions(-) diff --git a/packages/vectors3/src/api.ts b/packages/vectors3/src/api.ts index 75630036ec..7c6b9956be 100644 --- a/packages/vectors3/src/api.ts +++ b/packages/vectors3/src/api.ts @@ -20,18 +20,23 @@ export interface ReadonlyVec extends export interface StridedVec { buf: Vec; - i: number; - s: number; + offset: number; + stride: number; } export interface IVector extends Vec, ICopy, + ICopyView, IEmpty, IEqualsDelta, StridedVec { } +export interface ICopyView { + copyView(): T; +} + export interface VectorConstructor { new(buf: Vec, offset?: number, stride?: number): T; } diff --git a/packages/vectors3/src/internal/avec.ts b/packages/vectors3/src/internal/avec.ts index d28d6fe279..335b95efa9 100644 --- a/packages/vectors3/src/internal/avec.ts +++ b/packages/vectors3/src/internal/avec.ts @@ -3,13 +3,13 @@ import { StridedVec, Vec } from "../api"; export abstract class AVec implements StridedVec { buf: Vec; - i: number; - s: number; + offset: number; + stride: number; - constructor(buf: Vec, i = 0, s = 1) { + constructor(buf: Vec, offset = 0, stride = 1) { this.buf = buf; - this.i = i; - this.s = s; + this.offset = offset; + this.stride = stride; } abstract get length(): number; diff --git a/packages/vectors3/src/map.ts b/packages/vectors3/src/map.ts index ffae6cf559..495ff8d463 100644 --- a/packages/vectors3/src/map.ts +++ b/packages/vectors3/src/map.ts @@ -74,15 +74,15 @@ export const mapVV = ( a: IVector, b: IVector, num: number, - so = out.length * out.s, - sa = a.length * a.s, - sb = b.length * b.s) => { + so = out.length * out.stride, + sa = a.length * a.stride, + sb = b.length * b.stride) => { while (num-- > 0) { op(out, a, b); - out.i += so; - a.i += sa; - b.i += sb; + out.offset += so; + a.offset += sa; + b.offset += sb; } return out.buf; }; @@ -117,13 +117,13 @@ export const mapV = ( out: IVector, a: IVector, num: number, - so = out.length * out.s, - sa = a.length * a.s) => { + so = out.length * out.stride, + sa = a.length * a.stride) => { while (num-- > 0) { op(out, a); - out.i += so; - a.i += sa; + out.offset += so; + a.offset += sa; } return out.buf; }; @@ -146,13 +146,13 @@ export const mapVN = ( a: IVector, n: number, num: number, - so = out.length * out.s, - sa = a.length * a.s) => { + so = out.length * out.stride, + sa = a.length * a.stride) => { while (num-- > 0) { op(out, a, n); - out.i += so; - a.i += sa; + out.offset += so; + a.offset += sa; } return out.buf; }; @@ -179,17 +179,17 @@ export const mapVVV = ( b: IVector, c: IVector, num: number, - so = out.length * out.s, - sa = a.length * a.s, - sb = b.length * b.s, - sc = c.length * c.s) => { + so = out.length * out.stride, + sa = a.length * a.stride, + sb = b.length * b.stride, + sc = c.length * c.stride) => { while (num-- > 0) { op(out, a, b, c); - out.i += so; - a.i += sa; - b.i += sb; - c.i += sc; + out.offset += so; + a.offset += sa; + b.offset += sb; + c.offset += sc; } return out.buf; }; @@ -215,15 +215,15 @@ export const mapVVN = ( b: IVector, n: number, num: number, - so = out.length * out.s, - sa = a.length * a.s, - sb = b.length * b.s) => { + so = out.length * out.stride, + sa = a.length * a.stride, + sb = b.length * b.stride) => { while (num-- > 0) { op(out, a, b, n); - out.i += so; - a.i += sa; - b.i += sb; + out.offset += so; + a.offset += sa; + b.offset += sb; } return out.buf; }; diff --git a/packages/vectors3/src/vec2.ts b/packages/vectors3/src/vec2.ts index 5a78615921..9137a8f8bd 100644 --- a/packages/vectors3/src/vec2.ts +++ b/packages/vectors3/src/vec2.ts @@ -70,8 +70,8 @@ export class Vec2 extends AVec implements y: number; [id: number]: number; - constructor(buf?: Vec, i = 0, s = 1) { - super(buf || [0, 0], i, s); + constructor(buf?: Vec, offset = 0, stride = 1) { + super(buf || [0, 0], offset, stride); } *[Symbol.iterator]() { @@ -88,7 +88,7 @@ export class Vec2 extends AVec implements } copyView() { - return new Vec2(this.buf, this.i, this.s); + return new Vec2(this.buf, this.offset, this.stride); } empty() { diff --git a/packages/vectors3/src/vec3.ts b/packages/vectors3/src/vec3.ts index 2e764d8950..8193ca712c 100644 --- a/packages/vectors3/src/vec3.ts +++ b/packages/vectors3/src/vec3.ts @@ -73,8 +73,8 @@ export class Vec3 extends AVec implements z: number; [id: number]: number; - constructor(buf?: Vec, i = 0, s = 1) { - super(buf || [0, 0, 0], i, s); + constructor(buf?: Vec, offset = 0, stride = 1) { + super(buf || [0, 0, 0], offset, stride); } *[Symbol.iterator]() { @@ -92,7 +92,7 @@ export class Vec3 extends AVec implements } copyView() { - return new Vec3(this.buf, this.i, this.s); + return new Vec3(this.buf, this.offset, this.stride); } empty() { diff --git a/packages/vectors3/src/vec4.ts b/packages/vectors3/src/vec4.ts index 1606e5cad0..c728f60083 100644 --- a/packages/vectors3/src/vec4.ts +++ b/packages/vectors3/src/vec4.ts @@ -74,8 +74,8 @@ export class Vec4 extends AVec implements w: number; [id: number]: number; - constructor(buf?: Vec, i = 0, s = 1) { - super(buf || [0, 0, 0, 0], i, s); + constructor(buf?: Vec, offset = 0, stride = 1) { + super(buf || [0, 0, 0, 0], offset, stride); } *[Symbol.iterator]() { @@ -94,7 +94,7 @@ export class Vec4 extends AVec implements } copyView() { - return new Vec4(this.buf, this.i, this.s); + return new Vec4(this.buf, this.offset, this.stride); } empty() { From 0c0fce6ace29fa7b77e9f6b8dba8a6dffd8fe97f Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 24 Dec 2018 15:45:25 +0000 Subject: [PATCH 092/333] feat(vectors): update gvec, add generic setS() - add gvec copyView() - gvec copy() returns new gvec() - memoize ownKeys() - intern strings --- packages/vectors3/src/gvec.ts | 159 +++++++++++++++++++--------------- packages/vectors3/src/sets.ts | 10 ++- 2 files changed, 97 insertions(+), 72 deletions(-) diff --git a/packages/vectors3/src/gvec.ts b/packages/vectors3/src/gvec.ts index a2160fc192..66f37fbd58 100644 --- a/packages/vectors3/src/gvec.ts +++ b/packages/vectors3/src/gvec.ts @@ -1,22 +1,40 @@ +import { memoize1 } from "@thi.ng/memoize/memoize1"; import { range } from "@thi.ng/transducers/iter/range"; import { map } from "@thi.ng/transducers/xform/map"; import { Vec, IVector } from "./api"; import { zeroes } from "./setn"; import { eqDeltaS } from "./eqdelta"; import { EPS } from "@thi.ng/math/api"; +import { setS } from "./sets"; + +const B = "buf"; +const L = "length"; +const O = "offset"; +const S = "stride"; + +const keys = memoize1((size: number) => + [...map(String, range(size)), L, O, S]); /** * Wrapper for strided, arbitrary length vectors. Wraps given buffer in - * ES6 `Proxy` with custom property getters/setters and implements the - * ES6 `Iterable` interface and this libraries `IVector` methods and - * read/write access of the following properties: + * ES6 `Proxy` with custom property getters/setters and implements the following + * interfaces: + * + * - `Iterable` (ES6) + * - `ICopy` + * - `IEmpty` + * - `IEqualsDelta` + * - `IVector` * - * - `i` - start index - * - `s` - component stride + * Read/write access for the following properties: + * + * - array indices in the [0 .. `size`) interval + * - `offset` - start index + * - `stride` - component stride * - `buf` - backing buffer (readonly) * - `length` - vector size * - * Array index access uses bounds checking against the [0..`size`) + * Array index access uses bounds checking against the [0 .. `size`) * interval, but, for performance reasons, **not** against the actual * wrapped buffer. * @@ -43,72 +61,71 @@ import { EPS } from "@thi.ng/math/api"; * * @param buf * @param size - * @param i - * @param s + * @param offset + * @param stride */ -export const gvec = (buf: Vec, size: number, i = 0, s = 1): IVector => - new Proxy(buf, { - get: (obj, id) => { - switch (id) { - case Symbol.iterator: - return function* () { - for (let j = 0, ii = i, ss = s; j < size; j++) { - yield obj[ii + j * ss]; - } - }; - case "length": - return size; - case "buf": - return buf; - case "i": - return i; - case "s": - return s; - case "copy": - return function () { - const res = []; - for (let j = 0; j < size; j++) { - res[j] = obj[i + j * s]; - } - return res; - }; - case "empty": - return () => zeroes(size); - case "eqDelta": - return (o, eps = EPS) => eqDeltaS(buf, o, size, eps, i, 0, s, 1); - default: - let j = parseInt(id); - return !isNaN(j) && j >= 0 && j < size ? - obj[i + j * s] : - undefined; - } - }, - set: (obj, id, value) => { - const j = parseInt(id); - if (!isNaN(j) && j >= 0 && j < size) { - obj[i + (id | 0) * s] = value; - } else { +export const gvec = + (buf: Vec, size: number, offset = 0, stride = 1): IVector => + new Proxy(buf, { + get: (obj, id) => { switch (id) { - case "i": - i = value; - break; - case "s": - s = value; - break; - case "length": - size = value; - break; + case Symbol.iterator: + return function* () { + for (let j = 0, ii = offset, ss = stride; j < size; j++) { + yield obj[ii + j * ss]; + } + }; + case L: + return size; + case B: + return buf; + case O: + return offset; + case S: + return stride; + case "copy": + return () => + gvec(setS([], obj, 0, offset, 1, stride), size); + case "copyView": + return () => + gvec(obj, size, offset, stride); + case "empty": + return () => zeroes(size); + case "eqDelta": + return (o, eps = EPS) => + eqDeltaS(buf, o, size, eps, offset, 0, stride, 1); default: - return false; + let j = parseInt(id); + return !isNaN(j) && j >= 0 && j < size ? + obj[offset + j * stride] : + undefined; + } + }, + set: (obj, id, value) => { + const j = parseInt(id); + if (!isNaN(j) && j >= 0 && j < size) { + obj[offset + (id | 0) * stride] = value; + } else { + switch (id) { + case O: + offset = value; + break; + case S: + stride = value; + break; + case L: + size = value; + break; + default: + return false; + } } - } - return true - }, - has: (_, id) => - (id >= 0 && id < size) || - id === "i" || - id == "s" || - id == "length", - ownKeys: () => - [...map(String, range(size)), "i", "s", "length"], - }); + return true + }, + has: (_, id) => + (id >= 0 && id < size) || + id === O || + id == S || + id == L, + ownKeys: () => keys(size), + }); diff --git a/packages/vectors3/src/sets.ts b/packages/vectors3/src/sets.ts index 07c4cee6d7..eb5258c9b7 100644 --- a/packages/vectors3/src/sets.ts +++ b/packages/vectors3/src/sets.ts @@ -1,6 +1,14 @@ -import { VecOpSV } from "./api"; +import { VecOpSV, ReadonlyVec, Vec } from "./api"; import { defOpS, SARGS_V } from "./internal/codegen"; import { SET } from "./internal/templates"; export const [setS2, setS3, setS4] = defOpS(SET, `o,a,${SARGS_V}`, "o,a", "o", ""); + +export const setS = + (out: Vec, a: ReadonlyVec, n: number, io = 0, ia = 0, so = 1, sa = 1) => { + for (let i = 0; i < n; i++) { + out[io + i * so] = a[ia + i * sa]; + } + return out; + }; From 5620483b1412aa95d80a4a80510d8314e9175f00 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 24 Dec 2018 15:50:45 +0000 Subject: [PATCH 093/333] refactor(vector-pools): update IVector refs (new field names) --- packages/vector-pools/src/alist.ts | 4 ++-- packages/vector-pools/src/array-list.ts | 2 +- packages/vector-pools/src/linked-list.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/vector-pools/src/alist.ts b/packages/vector-pools/src/alist.ts index 295ae0a064..22c8e77177 100644 --- a/packages/vector-pools/src/alist.ts +++ b/packages/vector-pools/src/alist.ts @@ -64,11 +64,11 @@ export abstract class AVecList { const estride = this.estride; if (local) { for (let v of this) { - res[i++] = (v.i - start) / estride; + res[i++] = (v.offset - start) / estride; } } else { for (let v of this) { - res[i++] = v.i; + res[i++] = v.offset; } } return res; diff --git a/packages/vector-pools/src/array-list.ts b/packages/vector-pools/src/array-list.ts index e602058643..21997e14a3 100644 --- a/packages/vector-pools/src/array-list.ts +++ b/packages/vector-pools/src/array-list.ts @@ -56,7 +56,7 @@ export class VecArrayList extends AVecList { remove(v: T) { const idx = this.items.indexOf(v); if (idx >= 0) { - this.freeIDs.push(v.i); + this.freeIDs.push(v.offset); this.items.splice(idx, 1); return true; } diff --git a/packages/vector-pools/src/linked-list.ts b/packages/vector-pools/src/linked-list.ts index f4b6d24581..cfd4fb758f 100644 --- a/packages/vector-pools/src/linked-list.ts +++ b/packages/vector-pools/src/linked-list.ts @@ -99,7 +99,7 @@ export class VecLinkedList extends AVecList { remove(vec: T): boolean { if (this.has(vec)) { this._length--; - this.freeIDs.push(vec.i); + this.freeIDs.push(vec.offset); const v: any = vec; if (v.prev) { v.prev.next = v.next; From aa5ad9762280e468f22f743d677051822aceea22 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 24 Dec 2018 16:07:31 +0000 Subject: [PATCH 094/333] fix(vectors): update field names in declareIndex() --- packages/vectors3/src/internal/accessors.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/vectors3/src/internal/accessors.ts b/packages/vectors3/src/internal/accessors.ts index 2bddb24b6b..44f5dec4dd 100644 --- a/packages/vectors3/src/internal/accessors.ts +++ b/packages/vectors3/src/internal/accessors.ts @@ -1,18 +1,18 @@ export const declareIndex = ( proto: any, id: string, - i: number, + idx: number, strided = true, defNumeric = true ) => { const get = strided ? - function () { return this.buf[this.i + i * this.s]; } : - function () { return this.buf[this.i + i]; }; + function () { return this.buf[this.offset + idx * this.stride]; } : + function () { return this.buf[this.offset + idx]; }; const set = strided ? - function (n: number) { this.buf[this.i + i * this.s] = n; } : - function (n: number) { this.buf[this.i + i] = n; }; + function (n: number) { this.buf[this.offset + idx * this.stride] = n; } : + function (n: number) { this.buf[this.offset + idx] = n; }; - defNumeric && Object.defineProperty(proto, i, { + defNumeric && Object.defineProperty(proto, idx, { get, set, enumerable: true, From 7a735f2d84f071eea182277a730b74893e64c2ad Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 25 Dec 2018 01:09:28 +0000 Subject: [PATCH 095/333] refactor(vectors): update gvec, Vec2/3/4, extract iterator impl --- packages/vectors3/src/gvec.ts | 13 +++++-------- packages/vectors3/src/internal/vec-utils.ts | 12 ++++++++++++ packages/vectors3/src/vec2.ts | 12 ++++++++---- packages/vectors3/src/vec3.ts | 13 ++++++++----- packages/vectors3/src/vec4.ts | 14 ++++++++------ 5 files changed, 41 insertions(+), 23 deletions(-) diff --git a/packages/vectors3/src/gvec.ts b/packages/vectors3/src/gvec.ts index 66f37fbd58..701355e35c 100644 --- a/packages/vectors3/src/gvec.ts +++ b/packages/vectors3/src/gvec.ts @@ -1,10 +1,11 @@ +import { EPS } from "@thi.ng/math/api"; import { memoize1 } from "@thi.ng/memoize/memoize1"; import { range } from "@thi.ng/transducers/iter/range"; import { map } from "@thi.ng/transducers/xform/map"; -import { Vec, IVector } from "./api"; -import { zeroes } from "./setn"; +import { IVector, Vec } from "./api"; import { eqDeltaS } from "./eqdelta"; -import { EPS } from "@thi.ng/math/api"; +import { values } from "./internal/vec-utils"; +import { zeroes } from "./setn"; import { setS } from "./sets"; const B = "buf"; @@ -70,11 +71,7 @@ export const gvec = get: (obj, id) => { switch (id) { case Symbol.iterator: - return function* () { - for (let j = 0, ii = offset, ss = stride; j < size; j++) { - yield obj[ii + j * ss]; - } - }; + return () => values(obj, size, offset, stride); case L: return size; case B: diff --git a/packages/vectors3/src/internal/vec-utils.ts b/packages/vectors3/src/internal/vec-utils.ts index 3c4463b3e6..387d4d9174 100644 --- a/packages/vectors3/src/internal/vec-utils.ts +++ b/packages/vectors3/src/internal/vec-utils.ts @@ -44,3 +44,15 @@ export function* vecIterator( start += estride; } } + +export function* values( + buf: Vec, + num: number, + start: number, + stride: number +) { + while (num-- > 0) { + yield buf[start]; + start += stride; + } +} diff --git a/packages/vectors3/src/vec2.ts b/packages/vectors3/src/vec2.ts index 9137a8f8bd..ce2b7033b6 100644 --- a/packages/vectors3/src/vec2.ts +++ b/packages/vectors3/src/vec2.ts @@ -13,7 +13,12 @@ import { import { eqDelta2 } from "./eqdelta"; import { declareIndices } from "./internal/accessors"; import { AVec } from "./internal/avec"; -import { intoBuffer, mapBuffer, vecIterator } from "./internal/vec-utils"; +import { + intoBuffer, + mapBuffer, + values, + vecIterator +} from "./internal/vec-utils"; import { setS2 } from "./sets"; export class Vec2 extends AVec implements @@ -74,9 +79,8 @@ export class Vec2 extends AVec implements super(buf || [0, 0], offset, stride); } - *[Symbol.iterator]() { - yield this.x; - yield this.y; + [Symbol.iterator]() { + return values(this.buf, 2, this.offset, this.stride); } get length() { diff --git a/packages/vectors3/src/vec3.ts b/packages/vectors3/src/vec3.ts index 8193ca712c..76a768e52b 100644 --- a/packages/vectors3/src/vec3.ts +++ b/packages/vectors3/src/vec3.ts @@ -14,7 +14,12 @@ import { import { eqDelta3 } from "./eqdelta"; import { declareIndices } from "./internal/accessors"; import { AVec } from "./internal/avec"; -import { intoBuffer, mapBuffer, vecIterator } from "./internal/vec-utils"; +import { + intoBuffer, + mapBuffer, + values, + vecIterator +} from "./internal/vec-utils"; import { setS3 } from "./sets"; export class Vec3 extends AVec implements @@ -77,10 +82,8 @@ export class Vec3 extends AVec implements super(buf || [0, 0, 0], offset, stride); } - *[Symbol.iterator]() { - yield this.x; - yield this.y; - yield this.z; + [Symbol.iterator]() { + return values(this.buf, 3, this.offset, this.stride); } get length() { diff --git a/packages/vectors3/src/vec4.ts b/packages/vectors3/src/vec4.ts index c728f60083..d8b4532917 100644 --- a/packages/vectors3/src/vec4.ts +++ b/packages/vectors3/src/vec4.ts @@ -14,7 +14,12 @@ import { import { eqDelta4 } from "./eqdelta"; import { declareIndices } from "./internal/accessors"; import { AVec } from "./internal/avec"; -import { intoBuffer, mapBuffer, vecIterator } from "./internal/vec-utils"; +import { + intoBuffer, + mapBuffer, + values, + vecIterator +} from "./internal/vec-utils"; import { setS4 } from "./sets"; export class Vec4 extends AVec implements @@ -78,11 +83,8 @@ export class Vec4 extends AVec implements super(buf || [0, 0, 0, 0], offset, stride); } - *[Symbol.iterator]() { - yield this.x; - yield this.y; - yield this.z; - yield this.w; + [Symbol.iterator]() { + return values(this.buf, 4, this.offset, this.stride); } get length() { From 5788646f7d082b241d35bd997ffa96c139ddfc4a Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 26 Dec 2018 19:31:25 +0000 Subject: [PATCH 096/333] feat(color): add/update class wrappers --- packages/color/package.json | 2 +- packages/color/src/api.ts | 3 +- packages/color/src/argb.ts | 30 +++++++++ packages/color/src/clamp.ts | 4 +- packages/color/src/css.ts | 30 +++++++++ packages/color/src/hsia.ts | 65 +++++++++++++++++++ packages/color/src/hsla-css.ts | 4 +- packages/color/src/hsla-rgba.ts | 2 +- packages/color/src/hsla.ts | 31 ++++++--- packages/color/src/hsva.ts | 65 +++++++++++++++++++ packages/color/src/index.ts | 4 ++ packages/color/src/int-css.ts | 10 +-- packages/color/src/int-rgba.ts | 7 +- packages/color/src/internal/ctor-args.ts | 7 ++ .../color/src/{ => internal}/ensure-alpha.ts | 0 .../color/src/{ => internal}/ensure-hue.ts | 0 packages/color/src/parse-css.ts | 4 +- packages/color/src/rgba-css.ts | 2 +- packages/color/src/rgba-int.ts | 2 +- packages/color/src/rgba.ts | 22 +++++-- 20 files changed, 263 insertions(+), 31 deletions(-) create mode 100644 packages/color/src/argb.ts create mode 100644 packages/color/src/css.ts create mode 100644 packages/color/src/hsia.ts create mode 100644 packages/color/src/hsva.ts create mode 100644 packages/color/src/internal/ctor-args.ts rename packages/color/src/{ => internal}/ensure-alpha.ts (100%) rename packages/color/src/{ => internal}/ensure-hue.ts (100%) diff --git a/packages/color/package.json b/packages/color/package.json index 7e60c1f2ee..301c1227be 100644 --- a/packages/color/package.json +++ b/packages/color/package.json @@ -13,7 +13,7 @@ "license": "Apache-2.0", "scripts": { "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc internal", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn run build && yarn publish --access public", diff --git a/packages/color/src/api.ts b/packages/color/src/api.ts index 652ca1bf72..76efe0a9d2 100644 --- a/packages/color/src/api.ts +++ b/packages/color/src/api.ts @@ -1,7 +1,6 @@ -import { Vec, ReadonlyVec } from "@thi.ng/vectors3/api"; import { float } from "@thi.ng/strings/float"; import { percent } from "@thi.ng/strings/percent"; - +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; export type Color = Vec; export type ReadonlyColor = ReadonlyVec; diff --git a/packages/color/src/argb.ts b/packages/color/src/argb.ts new file mode 100644 index 0000000000..d024c0a445 --- /dev/null +++ b/packages/color/src/argb.ts @@ -0,0 +1,30 @@ +import { ICopy, IDeref } from "@thi.ng/api/api"; +import { ColorMode, IColor } from "./api"; + +export const argb = + (x: number) => + new ARGB(x >>> 0); + +export class ARGB implements + IColor, + ICopy, + IDeref { + + value: number; + + constructor(col: number) { + this.value = col; + } + + get mode() { + return ColorMode.INT_ARGB; + } + + copy() { + return new ARGB(this.value); + } + + deref() { + return this.value; + } +} diff --git a/packages/color/src/clamp.ts b/packages/color/src/clamp.ts index fdbf74d6b5..22a7706e80 100644 --- a/packages/color/src/clamp.ts +++ b/packages/color/src/clamp.ts @@ -1,8 +1,8 @@ import { clamp01 } from "@thi.ng/math/interval"; import { setC4 } from "@thi.ng/vectors3/setc"; import { Color, ReadonlyColor } from "./api"; -import { ensureAlpha } from "./ensure-alpha"; -import { ensureHue } from "./ensure-hue"; +import { ensureAlpha } from "./internal/ensure-alpha"; +import { ensureHue } from "./internal/ensure-hue"; /** * Clamps all color channels to [0,1] interval and calls `ensureAlpha()` diff --git a/packages/color/src/css.ts b/packages/color/src/css.ts new file mode 100644 index 0000000000..82a308626d --- /dev/null +++ b/packages/color/src/css.ts @@ -0,0 +1,30 @@ +import { ICopy, IDeref } from "@thi.ng/api/api"; +import { ColorMode, IColor } from "./api"; + +export const css = + (col: string) => + new CSS(col); + +export class CSS implements + IColor, + ICopy, + IDeref { + + value: string; + + constructor(col: string) { + this.value = col; + } + + get mode() { + return ColorMode.CSS; + } + + copy() { + return new CSS(this.value); + } + + deref() { + return this.value; + } +} diff --git a/packages/color/src/hsia.ts b/packages/color/src/hsia.ts new file mode 100644 index 0000000000..a6cdb8a8e9 --- /dev/null +++ b/packages/color/src/hsia.ts @@ -0,0 +1,65 @@ +import { IDeref } from "@thi.ng/api/api"; +import { EPS } from "@thi.ng/math/api"; +import { IVector, Vec } from "@thi.ng/vectors3/api"; +import { eqDelta4 } from "@thi.ng/vectors3/eqdelta"; +import { declareIndices } from "@thi.ng/vectors3/internal/accessors"; +import { AVec } from "@thi.ng/vectors3/internal/avec"; +import { values } from "@thi.ng/vectors3/internal/vec-utils"; +import { Color, ColorMode, IColor } from "./api"; +import { ensureArgs } from "./internal/ctor-args"; + +export function hsia(rgba: Color): HSIA +export function hsia(h: number, s: number, i: number, a?: number): HSIA; +export function hsia(...args: any[]) { + return new HSIA(ensureArgs(args)); +} + +export class HSIA extends AVec implements + IColor, + IDeref, + IVector { + + h: number; + s: number; + i: number; + a: number; + [id: number]: number; + + constructor(buf?: Vec, offset = 0, stride = 1) { + super(buf || [0, 0, 0, 0], offset, stride); + } + + [Symbol.iterator]() { + return values(this.buf, 4, this.offset, this.stride); + } + + get mode() { + return ColorMode.HSIA; + } + + get length() { + return 4; + } + + copy() { + return new HSIA(this.deref()); + } + + copyView() { + return new HSIA(this.buf, this.offset, this.stride); + } + + empty() { + return new HSIA(); + } + + deref(): Color { + return [this[0], this[1], this[2], this[3]]; + } + + eqDelta(o: HSIA, eps = EPS): boolean { + return eqDelta4(this, o, eps); + } +} + +declareIndices(HSIA.prototype, ["h", "s", "i", "a"]); diff --git a/packages/color/src/hsla-css.ts b/packages/color/src/hsla-css.ts index 449ea799ba..cb1cdc3d03 100644 --- a/packages/color/src/hsla-css.ts +++ b/packages/color/src/hsla-css.ts @@ -1,7 +1,7 @@ import { clamp01 } from "@thi.ng/math/interval"; import { FF, PC, ReadonlyColor } from "./api"; -import { ensureAlpha } from "./ensure-alpha"; -import { ensureHue } from "./ensure-hue"; +import { ensureAlpha } from "./internal/ensure-alpha"; +import { ensureHue } from "./internal/ensure-hue"; export const hslaCss = (hsla: ReadonlyColor) => { diff --git a/packages/color/src/hsla-rgba.ts b/packages/color/src/hsla-rgba.ts index 8700c5f880..17bffc7725 100644 --- a/packages/color/src/hsla-rgba.ts +++ b/packages/color/src/hsla-rgba.ts @@ -3,7 +3,7 @@ import { clamp01 } from "@thi.ng/math/interval"; import { setC3 } from "@thi.ng/vectors3/setc"; import { Color, ReadonlyColor } from "./api"; import { clampH } from "./clamp"; -import { ensureHue } from "./ensure-hue"; +import { ensureHue } from "./internal/ensure-hue"; export const hslaRgba = (out: Color, hsla: ReadonlyColor) => { diff --git a/packages/color/src/hsla.ts b/packages/color/src/hsla.ts index ae68ced3d2..ecc4533c52 100644 --- a/packages/color/src/hsla.ts +++ b/packages/color/src/hsla.ts @@ -1,12 +1,22 @@ +import { IDeref } from "@thi.ng/api/api"; import { EPS } from "@thi.ng/math/api"; import { IVector, Vec } from "@thi.ng/vectors3/api"; import { eqDelta4 } from "@thi.ng/vectors3/eqdelta"; import { declareIndices } from "@thi.ng/vectors3/internal/accessors"; import { AVec } from "@thi.ng/vectors3/internal/avec"; -import { ColorMode, IColor } from "./api"; +import { values } from "@thi.ng/vectors3/internal/vec-utils"; +import { Color, ColorMode, IColor } from "./api"; +import { ensureArgs } from "./internal/ctor-args"; + +export function hsla(rgba: Color): HSLA +export function hsla(h: number, s: number, l: number, a?: number): HSLA; +export function hsla(...args: any[]) { + return new HSLA(ensureArgs(args)); +} export class HSLA extends AVec implements IColor, + IDeref, IVector { h: number; @@ -15,15 +25,12 @@ export class HSLA extends AVec implements a: number; [id: number]: number; - constructor(buf?: Vec, i = 0, s = 1) { - super(buf || [0, 0, 0, 0], i, s); + constructor(buf?: Vec, offset = 0, stride = 1) { + super(buf || [0, 0, 0, 0], offset, stride); } - *[Symbol.iterator]() { - yield this[0]; - yield this[1]; - yield this[2]; - yield this[3]; + [Symbol.iterator]() { + return values(this.buf, 4, this.offset, this.stride); } get mode() { @@ -35,13 +42,17 @@ export class HSLA extends AVec implements } copy() { - return new HSLA([this[0], this[1], this[2], this[3]]); + return new HSLA(this.deref()); } copyView() { return new HSLA(this.buf, this.offset, this.stride); } + deref(): Color { + return [this[0], this[1], this[2], this[3]]; + } + empty() { return new HSLA(); } @@ -51,4 +62,4 @@ export class HSLA extends AVec implements } } -declareIndices(HSLA.prototype, ["h", "s", "v", "a"]); +declareIndices(HSLA.prototype, ["h", "s", "l", "a"]); diff --git a/packages/color/src/hsva.ts b/packages/color/src/hsva.ts new file mode 100644 index 0000000000..f4c058029d --- /dev/null +++ b/packages/color/src/hsva.ts @@ -0,0 +1,65 @@ +import { IDeref } from "@thi.ng/api/api"; +import { EPS } from "@thi.ng/math/api"; +import { IVector, Vec } from "@thi.ng/vectors3/api"; +import { eqDelta4 } from "@thi.ng/vectors3/eqdelta"; +import { declareIndices } from "@thi.ng/vectors3/internal/accessors"; +import { AVec } from "@thi.ng/vectors3/internal/avec"; +import { values } from "@thi.ng/vectors3/internal/vec-utils"; +import { Color, ColorMode, IColor } from "./api"; +import { ensureArgs } from "./internal/ctor-args"; + +export function hsva(rgba: Color): HSVA +export function hsva(h: number, s: number, v: number, a?: number): HSVA; +export function hsva(...args: any[]) { + return new HSVA(ensureArgs(args)); +} + +export class HSVA extends AVec implements + IColor, + IDeref, + IVector { + + h: number; + s: number; + v: number; + a: number; + [id: number]: number; + + constructor(buf?: Vec, offset = 0, stride = 1) { + super(buf || [0, 0, 0, 0], offset, stride); + } + + [Symbol.iterator]() { + return values(this.buf, 4, this.offset, this.stride); + } + + get mode() { + return ColorMode.HSVA; + } + + get length() { + return 4; + } + + copy() { + return new HSVA(this.deref()); + } + + copyView() { + return new HSVA(this.buf, this.offset, this.stride); + } + + deref(): Color { + return [this[0], this[1], this[2], this[3]]; + } + + empty() { + return new HSVA(); + } + + eqDelta(o: HSVA, eps = EPS): boolean { + return eqDelta4(this, o, eps); + } +} + +declareIndices(HSVA.prototype, ["h", "s", "v", "a"]); diff --git a/packages/color/src/index.ts b/packages/color/src/index.ts index b9f58aff0b..58bbc181cf 100644 --- a/packages/color/src/index.ts +++ b/packages/color/src/index.ts @@ -27,5 +27,9 @@ export * from "./cosine-gradients"; export * from "./matrix"; export * from "./porter-duff"; +export * from "./argb"; +export * from "./css"; +export * from "./hsia"; export * from "./hsla"; +export * from "./hsva"; export * from "./rgba"; diff --git a/packages/color/src/int-css.ts b/packages/color/src/int-css.ts index aafb9b4fb6..4759b60b22 100644 --- a/packages/color/src/int-css.ts +++ b/packages/color/src/int-css.ts @@ -1,10 +1,12 @@ import { U24 } from "@thi.ng/strings/radix"; import { INV8BIT, FF } from "./api"; +import { IDeref } from "@thi.ng/api/api"; export const intCss = - (rgba: number) => { - const a = rgba >>> 24; + (argb: number | IDeref) => { + argb = typeof argb === "number" ? argb : argb.deref(); + const a = argb >>> 24; return (a < 255) ? - `rgba(${(rgba >> 16) & 0xff},${(rgba >> 8) & 0xff},${rgba & 0xff},${FF(a * INV8BIT)})` : - `#${U24(rgba)}`; + `rgba(${(argb >> 16) & 0xff},${(argb >> 8) & 0xff},${argb & 0xff},${FF(a * INV8BIT)})` : + `#${U24(argb & 0xffffff)}`; }; diff --git a/packages/color/src/int-rgba.ts b/packages/color/src/int-rgba.ts index f0c8c6b95e..bee40af003 100644 --- a/packages/color/src/int-rgba.ts +++ b/packages/color/src/int-rgba.ts @@ -1,12 +1,15 @@ import { setC4 } from "@thi.ng/vectors3/setc"; import { Color, INV8BIT } from "./api"; +import { IDeref } from "@thi.ng/api/api"; export const intRgba = - (out: Color, src: number) => - setC4( + (out: Color, src: number | IDeref) => { + src = typeof src === "number" ? src : src.deref(); + return setC4( out || [], (src >>> 16 & 0xff) * INV8BIT, (src >>> 8 & 0xff) * INV8BIT, (src & 0xff) * INV8BIT, (src >>> 24 & 0xff) * INV8BIT ); + }; diff --git a/packages/color/src/internal/ctor-args.ts b/packages/color/src/internal/ctor-args.ts new file mode 100644 index 0000000000..56131a3f06 --- /dev/null +++ b/packages/color/src/internal/ctor-args.ts @@ -0,0 +1,7 @@ +export const ensureArgs = + (args: any[]) => + typeof args[0] === "number" ? + args.length < 4 ? + (args.push(1), args) : + args : + args[0]; diff --git a/packages/color/src/ensure-alpha.ts b/packages/color/src/internal/ensure-alpha.ts similarity index 100% rename from packages/color/src/ensure-alpha.ts rename to packages/color/src/internal/ensure-alpha.ts diff --git a/packages/color/src/ensure-hue.ts b/packages/color/src/internal/ensure-hue.ts similarity index 100% rename from packages/color/src/ensure-hue.ts rename to packages/color/src/internal/ensure-hue.ts diff --git a/packages/color/src/parse-css.ts b/packages/color/src/parse-css.ts index b9934bf356..330e71df04 100644 --- a/packages/color/src/parse-css.ts +++ b/packages/color/src/parse-css.ts @@ -4,12 +4,14 @@ import { maybeParseFloat, maybeParseInt } from "@thi.ng/strings/parse"; import { Color, ColorMode, INV8BIT } from "./api"; import { convert } from "./convert"; import { CSS_NAMES } from "./names"; +import { IDeref } from "@thi.ng/api/api"; const RE_HEX = /^#?([0-9a-f]{3,8})$/i; const RE_CSS = /^(rgb|hsl)a?\(\s*([0-9.]+?),\s*([0-9.]+%?),\s*([0-9.]+%?),?\s*([0-9.]+)?\s*\)$/; export const parseCss = - (col: string, mode = ColorMode.RGBA) => { + (col: string | IDeref, mode = ColorMode.RGBA) => { + col = typeof col === "string" ? col : col.deref(); let res: Color | number; let resMode: ColorMode; if (col.charAt(0) === "#") { diff --git a/packages/color/src/rgba-css.ts b/packages/color/src/rgba-css.ts index 0eb453b006..cc3dae340a 100644 --- a/packages/color/src/rgba-css.ts +++ b/packages/color/src/rgba-css.ts @@ -1,7 +1,7 @@ import { clamp01 } from "@thi.ng/math/interval"; import { U24 } from "@thi.ng/strings/radix"; import { FF, ReadonlyColor } from "./api"; -import { ensureAlpha } from "./ensure-alpha"; +import { ensureAlpha } from "./internal/ensure-alpha"; export const rgbaCss = (rgba: ReadonlyColor) => { diff --git a/packages/color/src/rgba-int.ts b/packages/color/src/rgba-int.ts index 4b16ad35e0..98cb5452a1 100644 --- a/packages/color/src/rgba-int.ts +++ b/packages/color/src/rgba-int.ts @@ -1,6 +1,6 @@ import { clamp01 } from "@thi.ng/math/interval"; import { ReadonlyColor } from "./api"; -import { ensureAlpha } from "./ensure-alpha"; +import { ensureAlpha } from "./internal/ensure-alpha"; export const rgbaInt = (rgba: ReadonlyColor) => diff --git a/packages/color/src/rgba.ts b/packages/color/src/rgba.ts index 28739ed77b..3ce9537c99 100644 --- a/packages/color/src/rgba.ts +++ b/packages/color/src/rgba.ts @@ -1,12 +1,22 @@ +import { IDeref } from "@thi.ng/api/api"; import { EPS } from "@thi.ng/math/api"; import { IVector, Vec } from "@thi.ng/vectors3/api"; import { eqDelta4 } from "@thi.ng/vectors3/eqdelta"; import { declareIndices } from "@thi.ng/vectors3/internal/accessors"; import { AVec } from "@thi.ng/vectors3/internal/avec"; -import { ColorMode, IColor } from "./api"; +import { values } from "@thi.ng/vectors3/internal/vec-utils"; +import { Color, ColorMode, IColor } from "./api"; +import { ensureArgs } from "./internal/ctor-args"; + +export function rgba(rgba: Color): RGBA +export function rgba(r: number, g: number, b: number, a?: number): RGBA; +export function rgba(...args: any[]) { + return new RGBA(ensureArgs(args)); +} export class RGBA extends AVec implements IColor, + IDeref, IVector { r: number; @@ -19,8 +29,8 @@ export class RGBA extends AVec implements super(buf || [0, 0, 0, 0], offset, stride); } - *[Symbol.iterator]() { - yield* [this.r, this.g, this.b, this.a]; + [Symbol.iterator]() { + return values(this.buf, 4, this.offset, this.stride); } get mode() { @@ -32,13 +42,17 @@ export class RGBA extends AVec implements } copy() { - return new RGBA([this.r, this.g, this.b, this.a]); + return new RGBA(this.deref()); } copyView() { return new RGBA(this.buf, this.offset, this.stride); } + deref(): Color { + return [this[0], this[1], this[2], this[3]]; + } + empty() { return new RGBA(); } From ef4562a2c8a9770e7f955f68490f56574af72c45 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 27 Dec 2018 12:12:20 +0000 Subject: [PATCH 097/333] build: update deps --- packages/vectors2/package.json | 8 ++++---- packages/vectors3/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/vectors2/package.json b/packages/vectors2/package.json index 5876e5ae38..0dfe6c1b80 100644 --- a/packages/vectors2/package.json +++ b/packages/vectors2/package.json @@ -30,13 +30,13 @@ "dependencies": { "@thi.ng/api": "^4.2.4", "@thi.ng/checks": "^1.5.14", - "@thi.ng/equiv": "^0.1.13", - "@thi.ng/errors": "^0.1.11", + "@thi.ng/equiv": "^0.1.15", + "@thi.ng/errors": "^0.1.12", "@thi.ng/malloc": "^0.2.1", "@thi.ng/math": "^0.2.2", - "@thi.ng/random": "^0.1.0", + "@thi.ng/random": "^0.1.1", "@thi.ng/strings": "^0.7.1", - "@thi.ng/transducers": "^2.2.2" + "@thi.ng/transducers": "^2.2.8" }, "keywords": [ "ES6", diff --git a/packages/vectors3/package.json b/packages/vectors3/package.json index cdb87a1adf..876035c360 100644 --- a/packages/vectors3/package.json +++ b/packages/vectors3/package.json @@ -34,7 +34,7 @@ "@thi.ng/errors": "^0.1.12", "@thi.ng/math": "^0.2.2", "@thi.ng/random": "^0.1.1", - "@thi.ng/transducers": "^2.2.7" + "@thi.ng/transducers": "^2.2.8" }, "keywords": [ "algebra", From d0b1e60ef4ca8d7d52a9f4ac321893fd6d5cf82c Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 27 Dec 2018 13:53:31 +0000 Subject: [PATCH 098/333] refactor(color): add AColor, re-use for existing wrappers, update deps --- packages/color/package.json | 2 +- packages/color/src/convert.ts | 6 +++++ packages/color/src/hsia.ts | 35 +++--------------------- packages/color/src/hsla.ts | 35 +++--------------------- packages/color/src/hsva.ts | 35 +++--------------------- packages/color/src/internal/acolor.ts | 39 +++++++++++++++++++++++++++ packages/color/src/rgba.ts | 35 +++--------------------- 7 files changed, 62 insertions(+), 125 deletions(-) create mode 100644 packages/color/src/internal/acolor.ts diff --git a/packages/color/package.json b/packages/color/package.json index 301c1227be..33fb3506af 100644 --- a/packages/color/package.json +++ b/packages/color/package.json @@ -29,7 +29,7 @@ }, "dependencies": { "@thi.ng/api": "^4.2.4", - "@thi.ng/compose": "^0.2.2", + "@thi.ng/compose": "^0.3.0", "@thi.ng/defmulti": "^0.5.1", "@thi.ng/errors": "^0.1.12", "@thi.ng/strings": "^0.7.1", diff --git a/packages/color/src/convert.ts b/packages/color/src/convert.ts index 25468b47ab..10200ffc3e 100644 --- a/packages/color/src/convert.ts +++ b/packages/color/src/convert.ts @@ -36,6 +36,12 @@ export function asRGBA(col: any, mode?: ColorMode) { return convert(col, ColorMode.RGBA, mode); } +export function asHSIA(col: IColor): Color; +export function asHSIA(col: string | number | ReadonlyColor, mode: ColorMode): Color; +export function asHSIA(col: any, mode?: ColorMode) { + return convert(col, ColorMode.HSIA, mode); +} + export function asHSLA(col: IColor): Color; export function asHSLA(col: string | number | ReadonlyColor, mode: ColorMode): Color; export function asHSLA(col: any, mode?: ColorMode) { diff --git a/packages/color/src/hsia.ts b/packages/color/src/hsia.ts index a6cdb8a8e9..f775270275 100644 --- a/packages/color/src/hsia.ts +++ b/packages/color/src/hsia.ts @@ -1,11 +1,7 @@ -import { IDeref } from "@thi.ng/api/api"; -import { EPS } from "@thi.ng/math/api"; -import { IVector, Vec } from "@thi.ng/vectors3/api"; -import { eqDelta4 } from "@thi.ng/vectors3/eqdelta"; +import { IVector } from "@thi.ng/vectors3/api"; import { declareIndices } from "@thi.ng/vectors3/internal/accessors"; -import { AVec } from "@thi.ng/vectors3/internal/avec"; -import { values } from "@thi.ng/vectors3/internal/vec-utils"; -import { Color, ColorMode, IColor } from "./api"; +import { Color, ColorMode } from "./api"; +import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ctor-args"; export function hsia(rgba: Color): HSIA @@ -14,33 +10,18 @@ export function hsia(...args: any[]) { return new HSIA(ensureArgs(args)); } -export class HSIA extends AVec implements - IColor, - IDeref, +export class HSIA extends AColor implements IVector { h: number; s: number; i: number; a: number; - [id: number]: number; - - constructor(buf?: Vec, offset = 0, stride = 1) { - super(buf || [0, 0, 0, 0], offset, stride); - } - - [Symbol.iterator]() { - return values(this.buf, 4, this.offset, this.stride); - } get mode() { return ColorMode.HSIA; } - get length() { - return 4; - } - copy() { return new HSIA(this.deref()); } @@ -52,14 +33,6 @@ export class HSIA extends AVec implements empty() { return new HSIA(); } - - deref(): Color { - return [this[0], this[1], this[2], this[3]]; - } - - eqDelta(o: HSIA, eps = EPS): boolean { - return eqDelta4(this, o, eps); - } } declareIndices(HSIA.prototype, ["h", "s", "i", "a"]); diff --git a/packages/color/src/hsla.ts b/packages/color/src/hsla.ts index ecc4533c52..cf1fe69fe9 100644 --- a/packages/color/src/hsla.ts +++ b/packages/color/src/hsla.ts @@ -1,11 +1,7 @@ -import { IDeref } from "@thi.ng/api/api"; -import { EPS } from "@thi.ng/math/api"; -import { IVector, Vec } from "@thi.ng/vectors3/api"; -import { eqDelta4 } from "@thi.ng/vectors3/eqdelta"; +import { IVector } from "@thi.ng/vectors3/api"; import { declareIndices } from "@thi.ng/vectors3/internal/accessors"; -import { AVec } from "@thi.ng/vectors3/internal/avec"; -import { values } from "@thi.ng/vectors3/internal/vec-utils"; -import { Color, ColorMode, IColor } from "./api"; +import { Color, ColorMode } from "./api"; +import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ctor-args"; export function hsla(rgba: Color): HSLA @@ -14,33 +10,18 @@ export function hsla(...args: any[]) { return new HSLA(ensureArgs(args)); } -export class HSLA extends AVec implements - IColor, - IDeref, +export class HSLA extends AColor implements IVector { h: number; s: number; l: number; a: number; - [id: number]: number; - - constructor(buf?: Vec, offset = 0, stride = 1) { - super(buf || [0, 0, 0, 0], offset, stride); - } - - [Symbol.iterator]() { - return values(this.buf, 4, this.offset, this.stride); - } get mode() { return ColorMode.HSLA; } - get length() { - return 4; - } - copy() { return new HSLA(this.deref()); } @@ -49,17 +30,9 @@ export class HSLA extends AVec implements return new HSLA(this.buf, this.offset, this.stride); } - deref(): Color { - return [this[0], this[1], this[2], this[3]]; - } - empty() { return new HSLA(); } - - eqDelta(o: HSLA, eps = EPS): boolean { - return eqDelta4(this, o, eps); - } } declareIndices(HSLA.prototype, ["h", "s", "l", "a"]); diff --git a/packages/color/src/hsva.ts b/packages/color/src/hsva.ts index f4c058029d..bbaa328c06 100644 --- a/packages/color/src/hsva.ts +++ b/packages/color/src/hsva.ts @@ -1,11 +1,7 @@ -import { IDeref } from "@thi.ng/api/api"; -import { EPS } from "@thi.ng/math/api"; -import { IVector, Vec } from "@thi.ng/vectors3/api"; -import { eqDelta4 } from "@thi.ng/vectors3/eqdelta"; +import { IVector } from "@thi.ng/vectors3/api"; import { declareIndices } from "@thi.ng/vectors3/internal/accessors"; -import { AVec } from "@thi.ng/vectors3/internal/avec"; -import { values } from "@thi.ng/vectors3/internal/vec-utils"; -import { Color, ColorMode, IColor } from "./api"; +import { Color, ColorMode } from "./api"; +import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ctor-args"; export function hsva(rgba: Color): HSVA @@ -14,33 +10,18 @@ export function hsva(...args: any[]) { return new HSVA(ensureArgs(args)); } -export class HSVA extends AVec implements - IColor, - IDeref, +export class HSVA extends AColor implements IVector { h: number; s: number; v: number; a: number; - [id: number]: number; - - constructor(buf?: Vec, offset = 0, stride = 1) { - super(buf || [0, 0, 0, 0], offset, stride); - } - - [Symbol.iterator]() { - return values(this.buf, 4, this.offset, this.stride); - } get mode() { return ColorMode.HSVA; } - get length() { - return 4; - } - copy() { return new HSVA(this.deref()); } @@ -49,17 +30,9 @@ export class HSVA extends AVec implements return new HSVA(this.buf, this.offset, this.stride); } - deref(): Color { - return [this[0], this[1], this[2], this[3]]; - } - empty() { return new HSVA(); } - - eqDelta(o: HSVA, eps = EPS): boolean { - return eqDelta4(this, o, eps); - } } declareIndices(HSVA.prototype, ["h", "s", "v", "a"]); diff --git a/packages/color/src/internal/acolor.ts b/packages/color/src/internal/acolor.ts new file mode 100644 index 0000000000..2a1e4dcd35 --- /dev/null +++ b/packages/color/src/internal/acolor.ts @@ -0,0 +1,39 @@ +import { EPS } from "@thi.ng/math/api"; +import { eqDelta4 } from "@thi.ng/vectors3/eqdelta"; +import { values } from "@thi.ng/vectors3/internal/vec-utils"; +import { Color, IColor } from "../api"; +import { IDeref } from "@thi.ng/api/api"; + +export abstract class AColor implements + IColor, + IDeref { + + buf: Color; + offset: number; + stride: number; + [id: number]: number; + + constructor(buf?: Color, offset = 0, stride = 1) { + this.buf = buf || [0, 0, 0, 0]; + this.offset = offset; + this.stride = stride; + } + + [Symbol.iterator]() { + return values(this.buf, 4, this.offset, this.stride); + } + + abstract get mode(); + + get length() { + return 4; + } + + deref(): Color { + return [this[0], this[1], this[2], this[3]]; + } + + eqDelta(o: T, eps = EPS): boolean { + return eqDelta4(this, o, eps); + } +} \ No newline at end of file diff --git a/packages/color/src/rgba.ts b/packages/color/src/rgba.ts index 3ce9537c99..08c43d06f6 100644 --- a/packages/color/src/rgba.ts +++ b/packages/color/src/rgba.ts @@ -1,11 +1,7 @@ -import { IDeref } from "@thi.ng/api/api"; -import { EPS } from "@thi.ng/math/api"; -import { IVector, Vec } from "@thi.ng/vectors3/api"; -import { eqDelta4 } from "@thi.ng/vectors3/eqdelta"; +import { IVector } from "@thi.ng/vectors3/api"; import { declareIndices } from "@thi.ng/vectors3/internal/accessors"; -import { AVec } from "@thi.ng/vectors3/internal/avec"; -import { values } from "@thi.ng/vectors3/internal/vec-utils"; -import { Color, ColorMode, IColor } from "./api"; +import { Color, ColorMode } from "./api"; +import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ctor-args"; export function rgba(rgba: Color): RGBA @@ -14,33 +10,18 @@ export function rgba(...args: any[]) { return new RGBA(ensureArgs(args)); } -export class RGBA extends AVec implements - IColor, - IDeref, +export class RGBA extends AColor implements IVector { r: number; g: number; b: number; a: number; - [id: number]: number; - - constructor(buf?: Vec, offset = 0, stride = 1) { - super(buf || [0, 0, 0, 0], offset, stride); - } - - [Symbol.iterator]() { - return values(this.buf, 4, this.offset, this.stride); - } get mode() { return ColorMode.RGBA; } - get length() { - return 4; - } - copy() { return new RGBA(this.deref()); } @@ -49,17 +30,9 @@ export class RGBA extends AVec implements return new RGBA(this.buf, this.offset, this.stride); } - deref(): Color { - return [this[0], this[1], this[2], this[3]]; - } - empty() { return new RGBA(); } - - eqDelta(o: RGBA, eps = EPS): boolean { - return eqDelta4(this, o, eps); - } } declareIndices(RGBA.prototype, ["r", "g", "b", "a"]); From 714381ded5fd5e7a2ff702adb8624eab4df03bd2 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 27 Dec 2018 13:54:24 +0000 Subject: [PATCH 099/333] perf(color): refactor porterDiff as HOF, update all PD ops, add docs --- packages/color/src/porter-duff.ts | 176 ++++++++++++++++++++---------- 1 file changed, 116 insertions(+), 60 deletions(-) diff --git a/packages/color/src/porter-duff.ts b/packages/color/src/porter-duff.ts index ebd82a4ad0..1dd3090573 100644 --- a/packages/color/src/porter-duff.ts +++ b/packages/color/src/porter-duff.ts @@ -7,50 +7,54 @@ import { postmultiply, premultiply } from "./premultiply"; // https://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending /** - * General Porter-Duff operator for **pre-multiplied** RGBA. Use + * General Porter-Duff HOF operator for **pre-multiplied** RGBA. Use * `porderDiffP` for applying pre & post multiplication of input and - * output colors. + * output colors. The returned function takes 3 arguments: + * + * - `out` color (if `null` or `undefined` writes to `dest`) + * - `src` color (background) + * - `dest` color (foreground) * * Reference: * https://drafts.fxtf.org/compositing-1/#advancedcompositing * http://www.svgopen.org/2005/papers/abstractsvgopen/#PorterDuffMap * - * @param out writes to `dest` if null - * @param src - * @param dest * @param f blend function * @param x factor of "both" region * @param y factor of "src" region * @param z factor of "dest" region */ export const porterDuff = ( - out: Color, - src: ReadonlyColor, - dest: ReadonlyColor, f: (s: number, d: number) => number, x: 0 | 1, y: 0 | 1, z: 0 | 1 -): Color => { - const sa = src[3]; - const da = dest[3]; - const sda = sa * da; - const sy = y * sa * (1 - da); - const sz = z * da * (1 - sa); +) => { const dot = y ? z ? - (s: number, d: number) => f(s, d) * sda + s * sy + d * sz : - (s: number, d: number) => f(s, d) * sda + s * sy : + (s: number, d: number, sda: number, sy: number, sz: number) => + f(s, d) * sda + s * sy + d * sz : + (s: number, d: number, sda: number, sy: number) => + f(s, d) * sda + s * sy : z ? - (s: number, d: number) => f(s, d) * sda + d * sz : - (s: number, d: number) => f(s, d) * sda; - return setC4( - out || dest, - dot(src[0], dest[0]), - dot(src[1], dest[1]), - dot(src[2], dest[2]), - x * sda + sy + sz - ); + (s: number, d: number, sda: number, _, sz: number) => + f(s, d) * sda + d * sz : + (s: number, d: number, sda: number) => + f(s, d) * sda; + return (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => { + const sa = src[3]; + const da = dest[3]; + const sda = sa * da; + const sy = y * sa * (1 - da); + const sz = z * da * (1 - sa); + return setC4( + out || dest, + dot(src[0], dest[0], sda, sy, sz), + dot(src[1], dest[1], sda, sy, sz), + dot(src[2], dest[2], sda, sy, sz), + x * sda + sy + sz + ); + }; }; /** @@ -66,54 +70,106 @@ export const porterDuffP = ( out: Color, src: ReadonlyColor, dest: ReadonlyColor, - mode: (out: Color, _: ReadonlyColor, dest: ReadonlyColor) => Color + mode: (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => Color ) => postmultiply(null, mode(null, premultiply([], src), premultiply(out, dest))); -export const clear = +/** + * Porter-Duff operator. None of the terms are used. Always results in + * [0, 0, 0, 0]. + * + * @see porterDuff + * + * @param out + * @param src + * @param dest + */ +export const composeClear = (out: Color, _: ReadonlyColor, dest: ReadonlyColor) => setN4(out || dest, 0); -export const src = - (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => - porterDuff(out, src, dest, (s) => s, 1, 1, 0); +/** + * Porter-Duff operator. Always results in `src` color, `dest` ignored. + * + * @see porterDuff + */ +export const composeSrc = porterDuff((s) => s, 1, 1, 0); -export const dest = - (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => - porterDuff(out, src, dest, (_, d) => d, 1, 0, 1); +/** + * Porter-Duff operator. Always results in `dest` color, `src` ignored. + * + * @see porterDuff + */ +export const composeDest = porterDuff((_, d) => d, 1, 0, 1); -export const srcOver = - (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => - porterDuff(out, src, dest, (s) => s, 1, 1, 1); +/** + * Porter-Duff operator. The source color is placed over the destination + * color. + * + * @see porterDuff + */ +export const composeSrcOver = porterDuff((s) => s, 1, 1, 1); -export const destOver = - (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => - porterDuff(out, src, dest, (_, d) => d, 1, 1, 1); +/** + * Porter-Duff operator. The destination color is placed over the source + * color. + * + * @see porterDuff + */ +export const composeDestOver = porterDuff((_, d) => d, 1, 1, 1); -export const srcIn = - (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => - porterDuff(out, src, dest, (s) => s, 1, 0, 0); +/** + * Porter-Duff operator. The source that overlaps the destination, + * replaces the destination. + * + * @see porterDuff + */ +export const composeSrcIn = porterDuff((s) => s, 1, 0, 0); -export const destIn = - (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => - porterDuff(out, src, dest, (_, d) => d, 1, 0, 0); +/** + * Porter-Duff operator. The destination that overlaps the source, + * replaces the source. + * + * @see porterDuff + */ +export const composeDestIn = porterDuff((_, d) => d, 1, 0, 0); -export const srcOut = - (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => - porterDuff(out, src, dest, (s) => s, 0, 1, 0); +/** + * Porter-Duff operator. The source that does not overlap the + * destination replaces the destination. + * + * @see porterDuff + */ +export const composeSrcOut = porterDuff((s) => s, 0, 1, 0); -export const destOut = - (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => - porterDuff(out, src, dest, (_, d) => d, 0, 0, 1); +/** + * Porter-Duff operator. The destination that does not overlap the + * source replaces the source. + * + * @see porterDuff + */ +export const composeDestOut = porterDuff((_, d) => d, 0, 0, 1); -export const srcAtop = - (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => - porterDuff(out, src, dest, (s) => s, 1, 0, 1); +/** + * Porter-Duff operator. The source that overlaps the destination is + * composited with the destination. + * + * @see porterDuff + */ +export const composeSrcAtop = porterDuff((s) => s, 1, 0, 1); -export const destAtop = - (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => - porterDuff(out, src, dest, (_, d) => d, 1, 1, 0); +/** + * Porter-Duff operator. The destination that overlaps the source is + * composited with the source and replaces the destination. + * + * @see porterDuff + */ +export const composeDestAtop = porterDuff((_, d) => d, 1, 1, 0); -export const xor = - (out: Color, src: ReadonlyColor, dest: ReadonlyColor) => - porterDuff(out, src, dest, () => 0, 0, 1, 1); +/** + * Porter-Duff operator. The non-overlapping regions of source and + * destination are combined. + * + * @see porterDuff + */ +export const composeXor = porterDuff(() => 0, 0, 1, 1); From e930d736c8a3c27e6a8cc288894be6c6477c7194 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 28 Dec 2018 03:33:05 +0000 Subject: [PATCH 100/333] feat(color): add more color spaces, refactor, rename, simplify --- packages/color/src/api.ts | 21 ++++++++- packages/color/src/convert.ts | 32 ++++++++------ packages/color/src/cosine-gradients.ts | 10 ++--- packages/color/src/hcya-rgba.ts | 26 +++++++++++ packages/color/src/hcya.ts | 38 ++++++++++++++++ packages/color/src/hsia-rgba.ts | 4 +- packages/color/src/hsla-css.ts | 10 ++--- packages/color/src/hsla-hsva.ts | 4 +- packages/color/src/hsla-rgba.ts | 4 +- packages/color/src/hsva-css.ts | 4 +- packages/color/src/hsva-hsla.ts | 4 +- packages/color/src/hsva-rgba.ts | 35 +++++---------- packages/color/src/hue-rgba.ts | 23 ++++++++++ packages/color/src/index.ts | 33 +++++++++----- packages/color/src/int-css.ts | 18 +++++--- packages/color/src/int-rgba.ts | 8 +++- packages/color/src/{argb.ts => int.ts} | 18 +++++--- packages/color/src/internal/mulv.ts | 39 ++++++++++++++++ packages/color/src/invert.ts | 6 +-- packages/color/src/kelvin-rgba.ts | 29 ++++++++++++ packages/color/src/linear.ts | 61 ++++++++++++++++++++++++++ packages/color/src/matrix.ts | 39 ++++++---------- packages/color/src/parse-css.ts | 4 +- packages/color/src/premultiply.ts | 42 +++++++++--------- packages/color/src/rgba-css.ts | 10 ++--- packages/color/src/rgba-hcva.ts | 30 +++++++++++++ packages/color/src/rgba-hcya.ts | 24 ++++++++++ packages/color/src/rgba-hsia.ts | 4 +- packages/color/src/rgba-hsla.ts | 44 +++---------------- packages/color/src/rgba-hsva.ts | 33 +++----------- packages/color/src/rgba-int.ts | 10 ++--- packages/color/src/rgba-xyza.ts | 17 +++++++ packages/color/src/rgba-ycbcra.ts | 16 +++++++ packages/color/src/xyza-rgba.ts | 12 +++++ packages/color/src/xyza.ts | 38 ++++++++++++++++ packages/color/src/ycbcr.ts | 38 ++++++++++++++++ packages/color/src/ycbcra-rgba.ts | 18 ++++++++ 37 files changed, 595 insertions(+), 211 deletions(-) create mode 100644 packages/color/src/hcya-rgba.ts create mode 100644 packages/color/src/hcya.ts create mode 100644 packages/color/src/hue-rgba.ts rename packages/color/src/{argb.ts => int.ts} (51%) create mode 100644 packages/color/src/internal/mulv.ts create mode 100644 packages/color/src/kelvin-rgba.ts create mode 100644 packages/color/src/linear.ts create mode 100644 packages/color/src/rgba-hcva.ts create mode 100644 packages/color/src/rgba-hcya.ts create mode 100644 packages/color/src/rgba-xyza.ts create mode 100644 packages/color/src/rgba-ycbcra.ts create mode 100644 packages/color/src/xyza-rgba.ts create mode 100644 packages/color/src/xyza.ts create mode 100644 packages/color/src/ycbcr.ts create mode 100644 packages/color/src/ycbcra-rgba.ts diff --git a/packages/color/src/api.ts b/packages/color/src/api.ts index 76efe0a9d2..2ebbc3c6e5 100644 --- a/packages/color/src/api.ts +++ b/packages/color/src/api.ts @@ -17,11 +17,14 @@ export type CosGradientSpec = [CosCoeffs, CosCoeffs, CosCoeffs, CosCoeffs]; export enum ColorMode { RGBA, + HCYA, HSVA, HSLA, HSIA, - INT_ARGB, + INT32, CSS, + XYZA, + YCBCRA } export interface IColor { @@ -43,6 +46,22 @@ export const YELLOW = Object.freeze([1, 1, 0, 1]); export const RGB_LUMINANCE = [0.299, 0.587, 0.114]; +export const SRGB_GAMMA = 1.0 / 2.2; +export const SRGB_INVERSE_GAMMA = 2.2; +export const SRGB_ALPHA = 0.055; + +export const RGB_XYZ = [ + 0.4124564, 0.3575761, 0.1804375, + 0.2126729, 0.7151522, 0.0721750, + 0.0193339, 0.1191920, 0.9503041 +]; + +export const XYZ_RGB = [ + 3.2404542, -1.5371385, -0.4985314, + -0.9692660, 1.8760108, 0.0415560, + 0.0556434, -0.2040259, 1.0572252 +]; + // internal helpers export const FF = float(2); diff --git a/packages/color/src/convert.ts b/packages/color/src/convert.ts index 10200ffc3e..357a4f93b4 100644 --- a/packages/color/src/convert.ts +++ b/packages/color/src/convert.ts @@ -11,8 +11,8 @@ import { hslaCss } from "./hsla-css"; import { hslaRgba } from "./hsla-rgba"; import { hsvaCss } from "./hsva-css"; import { hsvaRgba } from "./hsva-rgba"; -import { intCss } from "./int-css"; -import { intRgba } from "./int-rgba"; +import { int32Css } from "./int-css"; +import { int32Rgba } from "./int-rgba"; import { parseCss } from "./parse-css"; import { rgbaCss } from "./rgba-css"; import { rgbaHsia } from "./rgba-hsia"; @@ -36,6 +36,12 @@ export function asRGBA(col: any, mode?: ColorMode) { return convert(col, ColorMode.RGBA, mode); } +export function asHCYA(col: IColor): Color; +export function asHCYA(col: string | number | ReadonlyColor, mode: ColorMode): Color; +export function asHCYA(col: any, mode?: ColorMode) { + return convert(col, ColorMode.HCYA, mode); +} + export function asHSIA(col: IColor): Color; export function asHSIA(col: string | number | ReadonlyColor, mode: ColorMode): Color; export function asHSIA(col: any, mode?: ColorMode) { @@ -83,8 +89,8 @@ defConversion( ); defConversion( - ColorMode.INT_ARGB, ColorMode.CSS, - (x: string) => parseCss(x, ColorMode.INT_ARGB) + ColorMode.INT32, ColorMode.CSS, + (x: string) => parseCss(x, ColorMode.INT32) ); defConversion( @@ -95,23 +101,23 @@ defConversion( // Int defConversion( - ColorMode.CSS, ColorMode.INT_ARGB, - (x: number) => intCss(x) + ColorMode.CSS, ColorMode.INT32, + (x: number) => int32Css(x) ); defConversion( - ColorMode.HSLA, ColorMode.INT_ARGB, - (x: number) => rgbaHsla(null, intRgba([], x)) + ColorMode.HSLA, ColorMode.INT32, + (x: number) => rgbaHsla(null, int32Rgba([], x)) ); defConversion( - ColorMode.HSVA, ColorMode.INT_ARGB, - (x: number) => rgbaHsva(null, intRgba([], x)) + ColorMode.HSVA, ColorMode.INT32, + (x: number) => rgbaHsva(null, int32Rgba([], x)) ); defConversion( - ColorMode.RGBA, ColorMode.INT_ARGB, - (x: number) => intRgba([], x) + ColorMode.RGBA, ColorMode.INT32, + (x: number) => int32Rgba([], x) ); // HSIA @@ -183,6 +189,6 @@ defConversion( ); defConversion( - ColorMode.INT_ARGB, ColorMode.RGBA, + ColorMode.INT32, ColorMode.RGBA, (x: ReadonlyColor) => rgbaInt(x) ); diff --git a/packages/color/src/cosine-gradients.ts b/packages/color/src/cosine-gradients.ts index f9ec69fb66..205414cd43 100644 --- a/packages/color/src/cosine-gradients.ts +++ b/packages/color/src/cosine-gradients.ts @@ -56,12 +56,12 @@ export const cosineGradient = ); export const cosineCoeffs = - (src: ReadonlyColor, dest: ReadonlyColor) => { - src = clamp([], src); - dest = clamp([], dest); - const amp = [...map(([a, b]) => 0.5 * (a - b), tuples(src, dest))]; + (from: ReadonlyColor, to: ReadonlyColor) => { + from = clamp([], from); + to = clamp([], to); + const amp = [...map(([a, b]) => 0.5 * (a - b), tuples(from, to))]; return [ - [...map(([s, a]) => s - a, tuples(src, amp))], + [...map(([s, a]) => s - a, tuples(from, amp))], amp, [-0.5, -0.5, -0.5, -0.5], [0, 0, 0, 0] diff --git a/packages/color/src/hcya-rgba.ts b/packages/color/src/hcya-rgba.ts new file mode 100644 index 0000000000..82a6a1b7e8 --- /dev/null +++ b/packages/color/src/hcya-rgba.ts @@ -0,0 +1,26 @@ +import { clamp01 } from "@thi.ng/math/interval"; +import { dot3 } from "@thi.ng/vectors3/dot"; +import { setC3 } from "@thi.ng/vectors3/setc"; +import { Color, ReadonlyColor, RGB_LUMINANCE } from "./api"; +import { hueRgba } from "./hue-rgba"; +import { ensureAlpha } from "./internal/ensure-alpha"; + +export const hcyaRgba = + (out: Color, src: ReadonlyColor) => { + const h = src[0]; + let c = src[1]; + const y = src[2]; + const rgb = hueRgba(out || src, h, ensureAlpha(src[3])); + const lum = dot3(rgb, RGB_LUMINANCE); + if (y < lum) { + c *= y / lum; + } else if (lum < 1) { + c *= (1 - y) / (1 - lum); + } + return setC3( + rgb, + clamp01((rgb[0] - lum) * c + y), + clamp01((rgb[1] - lum) * c + y), + clamp01((rgb[2] - lum) * c + y), + ); + }; diff --git a/packages/color/src/hcya.ts b/packages/color/src/hcya.ts new file mode 100644 index 0000000000..53942f3d9b --- /dev/null +++ b/packages/color/src/hcya.ts @@ -0,0 +1,38 @@ +import { IVector } from "@thi.ng/vectors3/api"; +import { declareIndices } from "@thi.ng/vectors3/internal/accessors"; +import { Color, ColorMode } from "./api"; +import { AColor } from "./internal/acolor"; +import { ensureArgs } from "./internal/ctor-args"; + +export function hcya(hcya: Color): HCYA +export function hcya(h: number, c: number, y: number, a?: number): HCYA; +export function hcya(...args: any[]) { + return new HCYA(ensureArgs(args)); +} + +export class HCYA extends AColor implements + IVector { + + h: number; + s: number; + v: number; + a: number; + + get mode() { + return ColorMode.HCYA; + } + + copy() { + return new HCYA(this.deref()); + } + + copyView() { + return new HCYA(this.buf, this.offset, this.stride); + } + + empty() { + return new HCYA(); + } +} + +declareIndices(HCYA.prototype, ["h", "c", "y", "a"]); diff --git a/packages/color/src/hsia-rgba.ts b/packages/color/src/hsia-rgba.ts index 92469dea94..f7170aa848 100644 --- a/packages/color/src/hsia-rgba.ts +++ b/packages/color/src/hsia-rgba.ts @@ -5,8 +5,8 @@ import { clampH } from "./clamp"; // https://en.wikipedia.org/wiki/HSL_and_HSV#From_HSI export const hsiaRgba = - (out: Color, hsia: ReadonlyColor) => { - out = clampH(out || hsia, hsia); + (out: Color, src: ReadonlyColor) => { + out = clampH(out || src, src); const s = out[1]; const i = out[2]; if (s < 1e-6) { diff --git a/packages/color/src/hsla-css.ts b/packages/color/src/hsla-css.ts index cb1cdc3d03..033ea052c1 100644 --- a/packages/color/src/hsla-css.ts +++ b/packages/color/src/hsla-css.ts @@ -4,11 +4,11 @@ import { ensureAlpha } from "./internal/ensure-alpha"; import { ensureHue } from "./internal/ensure-hue"; export const hslaCss = - (hsla: ReadonlyColor) => { - const h = FF(ensureHue(hsla[0]) * 360); - const s = PC(clamp01(hsla[1])); - const l = PC(clamp01(hsla[2])); - const a = ensureAlpha(hsla[3]); + (src: ReadonlyColor) => { + const h = FF(ensureHue(src[0]) * 360); + const s = PC(clamp01(src[1])); + const l = PC(clamp01(src[2])); + const a = ensureAlpha(src[3]); return (a < 1) ? `hsla(${h},${s},${l},${FF(a)})` : `hsl(${h},${s},${l})` diff --git a/packages/color/src/hsla-hsva.ts b/packages/color/src/hsla-hsva.ts index b3107f4d45..f5ef5856e9 100644 --- a/packages/color/src/hsla-hsva.ts +++ b/packages/color/src/hsla-hsva.ts @@ -2,8 +2,8 @@ import { Color, ReadonlyColor } from "./api"; import { clampH } from "./clamp"; export const hslaHsva = - (out: Color, hsla: ReadonlyColor) => { - out = clampH(out || hsla, hsla); + (out: Color, src: ReadonlyColor) => { + out = clampH(out || src, src); const s = out[1]; const l = out[2]; const l2 = 2 * l; diff --git a/packages/color/src/hsla-rgba.ts b/packages/color/src/hsla-rgba.ts index 17bffc7725..b0ca91dcc1 100644 --- a/packages/color/src/hsla-rgba.ts +++ b/packages/color/src/hsla-rgba.ts @@ -6,8 +6,8 @@ import { clampH } from "./clamp"; import { ensureHue } from "./internal/ensure-hue"; export const hslaRgba = - (out: Color, hsla: ReadonlyColor) => { - out = clampH(out || hsla, hsla); + (out: Color, src: ReadonlyColor) => { + out = clampH(out || src, src); const h = out[0]; const s = out[1]; const l = out[2]; diff --git a/packages/color/src/hsva-css.ts b/packages/color/src/hsva-css.ts index 91a2ab0800..a338551a3c 100644 --- a/packages/color/src/hsva-css.ts +++ b/packages/color/src/hsva-css.ts @@ -3,5 +3,5 @@ import { hsvaHsla } from "./hsva-hsla"; import { hslaCss } from "./hsla-css"; export const hsvaCss = - (hsva: ReadonlyColor) => - hslaCss(hsvaHsla([], hsva)); + (src: ReadonlyColor) => + hslaCss(hsvaHsla([], src)); diff --git a/packages/color/src/hsva-hsla.ts b/packages/color/src/hsva-hsla.ts index c42213a0ff..f37d4374a1 100644 --- a/packages/color/src/hsva-hsla.ts +++ b/packages/color/src/hsva-hsla.ts @@ -2,8 +2,8 @@ import { ReadonlyColor, Color } from "./api"; import { clampH } from "./clamp"; export const hsvaHsla = - (out: Color, hsva: ReadonlyColor) => { - out = clampH(out || hsva, hsva); + (out: Color, src: ReadonlyColor) => { + out = clampH(out || src, src); const s = out[1]; const v = out[2]; const l = (2 - s) * v / 2; diff --git a/packages/color/src/hsva-rgba.ts b/packages/color/src/hsva-rgba.ts index f25b824994..74138104a3 100644 --- a/packages/color/src/hsva-rgba.ts +++ b/packages/color/src/hsva-rgba.ts @@ -1,33 +1,18 @@ import { setC3 } from "@thi.ng/vectors3/setc"; import { Color, ReadonlyColor } from "./api"; import { clampH } from "./clamp"; +import { hueRgba } from "./hue-rgba"; export const hsvaRgba = - (out: Color, hsva: ReadonlyColor) => { - out = clampH(out || hsva, hsva); + (out: Color, src: ReadonlyColor) => { + out = clampH(out || src, src); const s = out[1]; const v = out[2]; - if (s > 1e-6) { - const h = (out[0] * 6) % 6; - const i = h | 0; - const f = h - i; - const p = v * (1 - s); - const q = v * (1 - s * f); - const t = v * (1 - s * (1 - f)); - switch (i) { - case 0: - return setC3(out, v, t, p); - case 1: - return setC3(out, q, v, p); - case 2: - return setC3(out, p, v, t); - case 3: - return setC3(out, p, q, v); - case 4: - return setC3(out, t, p, v); - default: - return setC3(out, v, p, q); - } - } - return setC3(out, v, v, v); + hueRgba(out, src[0], out[3]); + return setC3( + out, + ((out[0] - 1) * s + 1) * v, + ((out[1] - 1) * s + 1) * v, + ((out[2] - 1) * s + 1) * v, + ); }; diff --git a/packages/color/src/hue-rgba.ts b/packages/color/src/hue-rgba.ts new file mode 100644 index 0000000000..76b70b5273 --- /dev/null +++ b/packages/color/src/hue-rgba.ts @@ -0,0 +1,23 @@ +import { clamp01 } from "@thi.ng/math/interval"; +import { setC4 } from "@thi.ng/vectors3/setc"; +import { Color } from "./api"; +import { ensureHue } from "./internal/ensure-hue"; + +/** + * Converts a normalized hue to RGBA with given optional `alpha` + * value (default: 1). + * + * @param out + * @param hue + */ +export const hueRgba = + (out: Color, hue: number, alpha = 1): Color => { + hue = ensureHue(hue) * 6; + return setC4( + out, + clamp01(Math.abs(hue - 3) - 1), + clamp01(2 - Math.abs(hue - 2)), + clamp01(2 - Math.abs(hue - 4)), + alpha + ); + }; diff --git a/packages/color/src/index.ts b/packages/color/src/index.ts index 58bbc181cf..d93c5a3154 100644 --- a/packages/color/src/index.ts +++ b/packages/color/src/index.ts @@ -1,9 +1,7 @@ export * from "./api"; export * from "./names"; -export * from "./convert"; -export * from "./parse-css"; - +export * from "./hcya-rgba"; export * from "./hsia-rgba"; export * from "./hsla-css"; export * from "./hsla-hsva"; @@ -11,25 +9,38 @@ export * from "./hsla-rgba"; export * from "./hsva-css"; export * from "./hsva-hsla"; export * from "./hsva-rgba"; +export * from "./hue-rgba"; export * from "./int-css"; export * from "./int-rgba"; +export * from "./kelvin-rgba"; export * from "./rgba-css"; +export * from "./rgba-hcva"; +export * from "./rgba-hcya"; export * from "./rgba-hsia"; export * from "./rgba-hsla"; export * from "./rgba-hsva"; export * from "./rgba-int"; +export * from "./rgba-xyza"; +export * from "./rgba-ycbcra"; +export * from "./xyza-rgba"; +export * from "./ycbcra-rgba"; -export * from "./invert"; -export * from "./luminance"; - -export * from "./cosine-gradients"; - -export * from "./matrix"; -export * from "./porter-duff"; +export * from "./convert"; +export * from "./parse-css"; -export * from "./argb"; +export * from "./int"; export * from "./css"; +export * from "./hcya"; export * from "./hsia"; export * from "./hsla"; export * from "./hsva"; export * from "./rgba"; +export * from "./xyza"; +export * from "./ycbcr"; + +export * from "./cosine-gradients"; +export * from "./invert"; +export * from "./linear"; +export * from "./luminance"; +export * from "./matrix"; +export * from "./porter-duff"; diff --git a/packages/color/src/int-css.ts b/packages/color/src/int-css.ts index 4759b60b22..2d0eec384e 100644 --- a/packages/color/src/int-css.ts +++ b/packages/color/src/int-css.ts @@ -2,11 +2,17 @@ import { U24 } from "@thi.ng/strings/radix"; import { INV8BIT, FF } from "./api"; import { IDeref } from "@thi.ng/api/api"; -export const intCss = - (argb: number | IDeref) => { - argb = typeof argb === "number" ? argb : argb.deref(); - const a = argb >>> 24; +export const int32Css = + (src: number | IDeref) => { + src = typeof src === "number" ? src : src.deref(); + const a = src >>> 24; return (a < 255) ? - `rgba(${(argb >> 16) & 0xff},${(argb >> 8) & 0xff},${argb & 0xff},${FF(a * INV8BIT)})` : - `#${U24(argb & 0xffffff)}`; + `rgba(${(src >> 16) & 0xff},${(src >> 8) & 0xff},${src & 0xff},${FF(a * INV8BIT)})` : + `#${U24(src & 0xffffff)}`; + }; + +export const int24Css = + (src: number | IDeref) => { + src = typeof src === "number" ? src : src.deref(); + return int32Css(src | 0xff000000); }; diff --git a/packages/color/src/int-rgba.ts b/packages/color/src/int-rgba.ts index bee40af003..17861a5a56 100644 --- a/packages/color/src/int-rgba.ts +++ b/packages/color/src/int-rgba.ts @@ -2,7 +2,7 @@ import { setC4 } from "@thi.ng/vectors3/setc"; import { Color, INV8BIT } from "./api"; import { IDeref } from "@thi.ng/api/api"; -export const intRgba = +export const int32Rgba = (out: Color, src: number | IDeref) => { src = typeof src === "number" ? src : src.deref(); return setC4( @@ -13,3 +13,9 @@ export const intRgba = (src >>> 24 & 0xff) * INV8BIT ); }; + +export const int24Rgba = + (out: Color, src: number | IDeref) => { + src = typeof src === "number" ? src : src.deref(); + return int32Rgba(out, src | 0xff000000); + }; diff --git a/packages/color/src/argb.ts b/packages/color/src/int.ts similarity index 51% rename from packages/color/src/argb.ts rename to packages/color/src/int.ts index d024c0a445..226f85779d 100644 --- a/packages/color/src/argb.ts +++ b/packages/color/src/int.ts @@ -1,27 +1,31 @@ import { ICopy, IDeref } from "@thi.ng/api/api"; import { ColorMode, IColor } from "./api"; -export const argb = +export const int32 = (x: number) => - new ARGB(x >>> 0); + new Int32(x); -export class ARGB implements +export const int24 = + (x: number) => + new Int32((x & 0xffffff) | 0xff000000); + +export class Int32 implements IColor, - ICopy, + ICopy, IDeref { value: number; constructor(col: number) { - this.value = col; + this.value = col >>> 0; } get mode() { - return ColorMode.INT_ARGB; + return ColorMode.INT32; } copy() { - return new ARGB(this.value); + return new Int32(this.value); } deref() { diff --git a/packages/color/src/internal/mulv.ts b/packages/color/src/internal/mulv.ts new file mode 100644 index 0000000000..8030bf9709 --- /dev/null +++ b/packages/color/src/internal/mulv.ts @@ -0,0 +1,39 @@ +import { dotS3, dotS4 } from "@thi.ng/vectors3/dots"; +import { Color, ReadonlyColor, ColorMatrix } from "../api"; +import { clamp01 } from "@thi.ng/math/interval"; +import { setC4 } from "@thi.ng/vectors3/setc"; +import { ensureAlpha } from "./ensure-alpha"; + +export const mulV33 = + (out: Color, mat: number[], src: ReadonlyColor, clampOut = true) => { + const x = dotS3(mat, src, 0, 0, 3); + const y = dotS3(mat, src, 1, 0, 3); + const z = dotS3(mat, src, 2, 0, 3); + const a = ensureAlpha(src[3]); + return clampOut ? + setC4( + out || src, + clamp01(x), + clamp01(y), + clamp01(z), + a + ) : + setC4(out || src, x, y, z, a); + }; + +export const mulV45 = + (out: Color, mat: ColorMatrix, src: ReadonlyColor, clampOut = true) => { + const x = dotS4(src, mat, 0, 0) + mat[4]; + const y = dotS4(src, mat, 0, 5) + mat[9]; + const z = dotS4(src, mat, 0, 10) + mat[14]; + const w = dotS4(src, mat, 0, 15) + mat[19]; + return clampOut ? + setC4( + out || src, + clamp01(x), + clamp01(y), + clamp01(z), + clamp01(w) + ) : + setC4(out || src, x, y, z, w); + }; diff --git a/packages/color/src/invert.ts b/packages/color/src/invert.ts index 789c25cf11..400854da52 100644 --- a/packages/color/src/invert.ts +++ b/packages/color/src/invert.ts @@ -4,10 +4,10 @@ import { Color, ReadonlyColor } from "./api"; import { clamp } from "./clamp"; export const invertRGB = - (out: Color, rgba: ReadonlyColor) => ( - out = clamp(out || rgba, rgba), + (out: Color, src: ReadonlyColor) => ( + out = clamp(out || src, src), sub3(out, ONE3, out) ); export const invertInt = - (rgb: number) => rgb ^ 0xffffff; + (src: number) => src ^ 0xffffff; diff --git a/packages/color/src/kelvin-rgba.ts b/packages/color/src/kelvin-rgba.ts new file mode 100644 index 0000000000..86ff5e0563 --- /dev/null +++ b/packages/color/src/kelvin-rgba.ts @@ -0,0 +1,29 @@ +import { clamp01 } from "@thi.ng/math/interval"; + +/** + * Based on: + * https://github.com/neilbartlett/color-temperature/blob/master/index.js + * http://www.zombieprototypes.com/?p=210 + * + * @param kelvin color temperature + * @param alpha + */ +export const kelvinRgba = + (kelvin: number, alpha = 1) => { + kelvin *= 0.01; + let t: number; + return kelvin < 66 ? + [1, + clamp01(-0.6088425710866344 - 0.001748900018414868 * (t = kelvin - 2) + 0.4097731842899564 * Math.log(t)), + kelvin < 20 ? + 0 : + clamp01(-0.9990954974165059 + 0.0032447435545127036 * (t = kelvin - 10) + 0.453646839257496 * Math.log(t)), + alpha + ] : + [ + clamp01(1.3803015908551253 + 0.0004478684462124118 * (t = kelvin - 55) - 0.15785750232675008 * Math.log(t)), + clamp01(1.2762722061615583 + 0.0003115080994769546 * (t = kelvin - 50) - 0.11013841706194392 * Math.log(t)), + 1, + alpha + ]; + }; diff --git a/packages/color/src/linear.ts b/packages/color/src/linear.ts new file mode 100644 index 0000000000..8d9049928f --- /dev/null +++ b/packages/color/src/linear.ts @@ -0,0 +1,61 @@ +import { SRGB_ALPHA, ReadonlyColor, Color } from "./api"; +import { setC4 } from "@thi.ng/vectors3/setc"; +import { ensureAlpha } from "./internal/ensure-alpha"; + +/** + * Maps a single linear RGB channel value to sRGB. + * + * https://en.wikipedia.org/wiki/SRGB + * + * @param x + */ +export const linearSrgb = + (x: number) => + x <= 0.0031308 ? + 12.92 * x : + (1.0 + SRGB_ALPHA) * Math.pow(x, 1.0 / 2.4) - SRGB_ALPHA; + +/** + * Maps a single linear sRGB channel value to linear RGB. + * + * https://en.wikipedia.org/wiki/SRGB + * + * @param x + */ +export const srgbLinear = + (x: number) => + x <= 0.04045 ? + x / 12.92 : + Math.pow((x + SRGB_ALPHA) / (1 + SRGB_ALPHA), 2.4); + +/** + * Converts linear RGB to sRGB. + * + * @param out + * @param src + */ +export const rgbaSrgba = + (out: Color, src: ReadonlyColor) => + setC4( + out || src, + linearSrgb(src[0]), + linearSrgb(src[1]), + linearSrgb(src[2]), + ensureAlpha(src[3]) + ); + +/** + * Converts sRGB to linear RGB. + * + * @param out + * @param src + */ +export const srgbaRgba = + (out: Color, src: ReadonlyColor) => + setC4( + out || src, + srgbLinear(src[0]), + srgbLinear(src[1]), + srgbLinear(src[2]), + ensureAlpha(src[3]) + ); diff --git a/packages/color/src/matrix.ts b/packages/color/src/matrix.ts index 4ce4af5f0c..289e48615a 100644 --- a/packages/color/src/matrix.ts +++ b/packages/color/src/matrix.ts @@ -1,13 +1,7 @@ -import { clamp01 } from "@thi.ng/math/interval"; import { mix } from "@thi.ng/math/mix"; import { dotS4 } from "@thi.ng/vectors3/dots"; -import { setC4 } from "@thi.ng/vectors3/setc"; -import { - Color, - ColorMatrix, - ReadonlyColor, - RGB_LUMINANCE -} from "./api"; +import { ColorMatrix, RGB_LUMINANCE } from "./api"; +import { mulV45 } from "./internal/mulv"; // https://drafts.fxtf.org/filter-effects/#feColorMatrixElement @@ -21,23 +15,18 @@ const S6 = 0.140; const S7 = 0.143; const S8 = 0.283; -export const applyMatrix = - (out: Color, mat: ColorMatrix, rgba: ReadonlyColor, clampOut = true) => - clampOut ? - setC4( - out || rgba, - clamp01(dotS4(rgba, mat, 0, 0) + mat[4]), - clamp01(dotS4(rgba, mat, 0, 5) + mat[9]), - clamp01(dotS4(rgba, mat, 0, 10) + mat[14]), - clamp01(dotS4(rgba, mat, 0, 15) + mat[19]) - ) : - setC4( - out || rgba, - dotS4(rgba, mat, 0, 0) + mat[4], - dotS4(rgba, mat, 0, 5) + mat[9], - dotS4(rgba, mat, 0, 10) + mat[14], - dotS4(rgba, mat, 0, 15) + mat[19] - ); +/** + * Transforms `src` RGBA color with given matrix and stores result in + * `out` (writes back to `src` if `out` is `null` or `undefined`). + * Unless `clampOut` is false, the result color will be clamped to `[0,1]` + * interval. + * + * @param out + * @param mat + * @param src + * @param clampOut + */ +export const transform = mulV45; export const mulMatrix = (a: ColorMatrix, b: ColorMatrix): ColorMatrix => [ diff --git a/packages/color/src/parse-css.ts b/packages/color/src/parse-css.ts index 330e71df04..e92481c70a 100644 --- a/packages/color/src/parse-css.ts +++ b/packages/color/src/parse-css.ts @@ -15,7 +15,7 @@ export const parseCss = let res: Color | number; let resMode: ColorMode; if (col.charAt(0) === "#") { - resMode = ColorMode.INT_ARGB; + resMode = ColorMode.INT32; res = parseHex(col); } else { const match = RE_CSS.exec(col); @@ -40,7 +40,7 @@ export const parseCss = } else { const c = CSS_NAMES[col]; !c && illegalArgs(`invalid color: "${col}"`); - resMode = ColorMode.INT_ARGB; + resMode = ColorMode.INT32; res = parseHex(c); } } diff --git a/packages/color/src/premultiply.ts b/packages/color/src/premultiply.ts index f8f1072d71..574340c5ed 100644 --- a/packages/color/src/premultiply.ts +++ b/packages/color/src/premultiply.ts @@ -3,43 +3,43 @@ import { set } from "@thi.ng/vectors3/set"; import { setC4 } from "@thi.ng/vectors3/setc"; /** - * Multiplies RGB channels w/ alpha channel. - * Assumes alpha is in [0 .. 1] interval. + * RGBA only. Multiplies RGB channels w/ alpha channel. Assumes alpha is + * in [0 .. 1] interval. Does NOT clamp result. * * @param out - * @param rgba + * @param src */ export const premultiply = - (out: Color, rgba: ReadonlyColor) => { - const a = rgba[3]; + (out: Color, src: ReadonlyColor) => { + const a = src[3]; return setC4( - out || rgba, - rgba[0] * a, - rgba[1] * a, - rgba[2] * a, + out || src, + src[0] * a, + src[1] * a, + src[2] * a, a ); }; /** - * Reverse operation of `premultiply`. Divides RGB channels by alpha, - * unless alpha is zero. Does NOT clamp result. + * RGBA only. Reverse operation of `premultiply`. Divides RGB channels + * by alpha, unless alpha is zero. Does NOT clamp result. * * @param out - * @param rgba + * @param src */ export const postmultiply = - (out: Color, rgba: ReadonlyColor) => { - const a = rgba[3]; + (out: Color, src: ReadonlyColor) => { + const a = src[3]; return a > 0 ? setC4( - out || rgba, - rgba[0] / a, - rgba[1] / a, - rgba[2] / a, + out || src, + src[0] / a, + src[1] / a, + src[2] / a, a ) : - !out && out != rgba ? - set(out, rgba) : - rgba; + !out && out != src ? + set(out, src) : + src; }; diff --git a/packages/color/src/rgba-css.ts b/packages/color/src/rgba-css.ts index cc3dae340a..3f5dae89ee 100644 --- a/packages/color/src/rgba-css.ts +++ b/packages/color/src/rgba-css.ts @@ -4,11 +4,11 @@ import { FF, ReadonlyColor } from "./api"; import { ensureAlpha } from "./internal/ensure-alpha"; export const rgbaCss = - (rgba: ReadonlyColor) => { - const r = (clamp01(rgba[0]) * 0xff) | 0; - const g = (clamp01(rgba[1]) * 0xff) | 0; - const b = (clamp01(rgba[2]) * 0xff) | 0; - const a = ensureAlpha(rgba[3]); + (src: ReadonlyColor) => { + const r = (clamp01(src[0]) * 0xff + 0.5) | 0; + const g = (clamp01(src[1]) * 0xff + 0.5) | 0; + const b = (clamp01(src[2]) * 0xff + 0.5) | 0; + const a = ensureAlpha(src[3]); return (a < 1) ? `rgba(${r},${g},${b},${FF(a)})` : `#${U24(r << 16 | g << 8 | b)}` diff --git a/packages/color/src/rgba-hcva.ts b/packages/color/src/rgba-hcva.ts new file mode 100644 index 0000000000..d27d2afa50 --- /dev/null +++ b/packages/color/src/rgba-hcva.ts @@ -0,0 +1,30 @@ +import { EPS } from "@thi.ng/math/api"; +import { clamp01 } from "@thi.ng/math/interval"; +import { setC3 } from "@thi.ng/vectors3/setc"; +import { Color, ReadonlyColor } from "./api"; +import { clamp } from "./clamp"; + +/** + * Based on: + * https://github.com/tobspr/GLSL-Color-Spaces/blob/master/ColorSpaces.inc.glsl#L159 + * + * @param out + * @param src + */ +export const rgbaHcva = + (out: Color, src: ReadonlyColor) => { + out = clamp(out || src, src); + const p = out[1] < out[2] ? + [out[2], out[1], -1, 2 / 3] : + [out[1], out[2], 0, -1 / 3]; + const q = out[0] < p[0] ? + [p[0], p[1], p[3], out[0]] : + [out[0], p[1], p[2], p[0]]; + const c = q[0] - Math.min(q[1], q[3]); + return setC3( + out, + clamp01(Math.abs((q[3] - q[1]) / (6 * c + EPS) + q[2])), + clamp01(c), + clamp01(q[0]) + ); + }; diff --git a/packages/color/src/rgba-hcya.ts b/packages/color/src/rgba-hcya.ts new file mode 100644 index 0000000000..368ee8495c --- /dev/null +++ b/packages/color/src/rgba-hcya.ts @@ -0,0 +1,24 @@ +import { EPS } from "@thi.ng/math/api"; +import { Color, ReadonlyColor } from "./api"; +import { hueRgba } from "./hue-rgba"; +import { luminanceRGB } from "./luminance"; +import { rgbaHcva } from "./rgba-hcva"; + +/** + * Ported from: + * https://github.com/tobspr/GLSL-Color-Spaces/blob/master/ColorSpaces.inc.glsl#L226 + * + * @param out + * @param src + */ +export const rgbaHcya = + (out: Color, src: ReadonlyColor) => { + const y = luminanceRGB(src); + out = rgbaHcva(out, src); + const z = luminanceRGB(hueRgba([], out[0])); + out[1] *= y < z ? + z / (y + EPS) : + (1 - z) / (1 + EPS - y); + out[2] = y; + return out; + }; diff --git a/packages/color/src/rgba-hsia.ts b/packages/color/src/rgba-hsia.ts index 7622e220eb..1b5aa687b5 100644 --- a/packages/color/src/rgba-hsia.ts +++ b/packages/color/src/rgba-hsia.ts @@ -9,8 +9,8 @@ import { atan2Abs } from "@thi.ng/math/angle"; const SQRT32 = SQRT3 / 2; export const rgbaHsia = - (out: Color, rgba: ReadonlyColor) => { - out = clamp(out || rgba, rgba); + (out: Color, src: ReadonlyColor) => { + out = clamp(out || src, src); const r = out[0]; const g = out[1]; const b = out[2]; diff --git a/packages/color/src/rgba-hsla.ts b/packages/color/src/rgba-hsla.ts index efdbbcc186..e93da12c8a 100644 --- a/packages/color/src/rgba-hsla.ts +++ b/packages/color/src/rgba-hsla.ts @@ -1,41 +1,11 @@ -import { SIXTH, THIRD, TWO_THIRD } from "@thi.ng/math/api"; -import { setC3 } from "@thi.ng/vectors3/setc"; +import { EPS } from "@thi.ng/math/api"; import { Color, ReadonlyColor } from "./api"; -import { clamp } from "./clamp"; +import { rgbaHcva } from "./rgba-hcva"; export const rgbaHsla = - (out: Color, rgba: ReadonlyColor) => { - out = clamp(out || rgba, rgba); - const r = out[0]; - const g = out[1]; - const b = out[2]; - const f1 = Math.min(r, g, b); - const f2 = Math.max(r, g, b); - const l = (f1 + f2) * 0.5; - const d = f2 - f1; - let h: number; - let s: number; - if (d > 1e-6) { - s = (l < 0.5) ? - (d / (f1 + f2)) : - (d / (2 - f2 - f1)); - const d2 = d * 0.5; - const id = 1 / d; - const dr = ((f2 - r) * SIXTH + d2) * id; - const dg = ((f2 - g) * SIXTH + d2) * id; - const db = ((f2 - b) * SIXTH + d2) * id; - h = (f2 === r) ? - (db - dg) : - (f2 === g) ? - (THIRD + dr - db) : - (TWO_THIRD + dg - dr); - h = (h < 0) ? - h + 1 : - (h >= 1) ? - h - 1 : - h; - } else { - h = s = 0; - } - return setC3(out, h, s, l); + (out: Color, src: ReadonlyColor) => { + out = rgbaHcva(out, src); + out[2] -= out[1] * 0.5; + out[1] /= 1 + EPS - Math.abs(out[2] * 2 - 1); + return out; }; diff --git a/packages/color/src/rgba-hsva.ts b/packages/color/src/rgba-hsva.ts index e99493d45f..fd35fc20d5 100644 --- a/packages/color/src/rgba-hsva.ts +++ b/packages/color/src/rgba-hsva.ts @@ -1,31 +1,10 @@ -import { setC3 } from "@thi.ng/vectors3/setc"; +import { EPS } from "@thi.ng/math/api"; import { Color, ReadonlyColor } from "./api"; -import { clamp } from "./clamp"; +import { rgbaHcva } from "./rgba-hcva"; export const rgbaHsva = - (out: Color, rgba: ReadonlyColor) => { - out = clamp(out || rgba, rgba); - const r = out[0]; - const g = out[1]; - const b = out[2]; - const v = Math.max(r, g, b); - const d = v - Math.min(r, g, b); - let h = 0, s = 0; - if (v > 1e-6) { - s = d / v; - } - if (s > 1e-6) { - if (r === v) { - h = (g - b) / d; - } else if (g === v) { - h = 2 + (b - r) / d; - } else { - h = 4 + (r - g) / d; - } - h /= 6; - if (h < 0) { - h++; - } - } - return setC3(out, h, s, v); + (out: Color, src: ReadonlyColor) => { + out = rgbaHcva(out, src); + out[1] /= out[2] + EPS; + return out; }; diff --git a/packages/color/src/rgba-int.ts b/packages/color/src/rgba-int.ts index 98cb5452a1..2e3d8a2a67 100644 --- a/packages/color/src/rgba-int.ts +++ b/packages/color/src/rgba-int.ts @@ -3,10 +3,10 @@ import { ReadonlyColor } from "./api"; import { ensureAlpha } from "./internal/ensure-alpha"; export const rgbaInt = - (rgba: ReadonlyColor) => + (src: ReadonlyColor) => ( - ((ensureAlpha(rgba[3]) * 0xff) << 24) | - ((clamp01(rgba[0]) * 0xff) << 16) | - ((clamp01(rgba[1]) * 0xff) << 8) | - (clamp01(rgba[2]) * 0xff) + ((ensureAlpha(src[3]) * 0xff) << 24) | + ((clamp01(src[0]) * 0xff) << 16) | + ((clamp01(src[1]) * 0xff) << 8) | + (clamp01(src[2]) * 0xff) ) >>> 0; diff --git a/packages/color/src/rgba-xyza.ts b/packages/color/src/rgba-xyza.ts new file mode 100644 index 0000000000..62cc5ce62c --- /dev/null +++ b/packages/color/src/rgba-xyza.ts @@ -0,0 +1,17 @@ +import { Color, ReadonlyColor, RGB_XYZ } from "./api"; +import { clamp } from "./clamp"; +import { mulV33 } from "./internal/mulv"; +import { ensureAlpha } from "./internal/ensure-alpha"; + +/** + * https://en.wikipedia.org/wiki/CIE_1931_color_space + * + * @param out + * @param src + */ +export const rgbaXyza = + (out: Color, src: ReadonlyColor) => { + out = mulV33(null, RGB_XYZ, clamp(out || src, src), false); + out[3] = ensureAlpha(src[3]); + return out; + }; diff --git a/packages/color/src/rgba-ycbcra.ts b/packages/color/src/rgba-ycbcra.ts new file mode 100644 index 0000000000..fc4245bb7b --- /dev/null +++ b/packages/color/src/rgba-ycbcra.ts @@ -0,0 +1,16 @@ +import { Color, ReadonlyColor } from "./api"; +import { luminanceRGB } from "./luminance"; +import { setC3 } from "@thi.ng/vectors3/setc"; +import { clamp } from "./clamp"; + +export const rgbaYcbcra = + (out: Color, src: ReadonlyColor) => { + out = clamp(out || src, src); + const y = luminanceRGB(src); + return setC3( + out, + y, + (src[2] - y) * 0.565, + (src[0] - y) * 0.713 + ); + }; diff --git a/packages/color/src/xyza-rgba.ts b/packages/color/src/xyza-rgba.ts new file mode 100644 index 0000000000..0be8df5a9f --- /dev/null +++ b/packages/color/src/xyza-rgba.ts @@ -0,0 +1,12 @@ +import { Color, ReadonlyColor, XYZ_RGB } from "./api"; +import { mulV33 } from "./internal/mulv"; + +/** + * https://en.wikipedia.org/wiki/CIE_1931_color_space + * + * @param out + * @param src + */ +export const xyzaRgba = + (out: Color, src: ReadonlyColor) => + mulV33(out || src, XYZ_RGB, src); diff --git a/packages/color/src/xyza.ts b/packages/color/src/xyza.ts new file mode 100644 index 0000000000..7ff869ab61 --- /dev/null +++ b/packages/color/src/xyza.ts @@ -0,0 +1,38 @@ +import { IVector } from "@thi.ng/vectors3/api"; +import { declareIndices } from "@thi.ng/vectors3/internal/accessors"; +import { Color, ColorMode } from "./api"; +import { AColor } from "./internal/acolor"; +import { ensureArgs } from "./internal/ctor-args"; + +export function xyza(rgba: Color): XYZA +export function xyza(r: number, g: number, b: number, a?: number): XYZA; +export function xyza(...args: any[]) { + return new XYZA(ensureArgs(args)); +} + +export class XYZA extends AColor implements + IVector { + + x: number; + y: number; + z: number; + a: number; + + get mode() { + return ColorMode.XYZA; + } + + copy() { + return new XYZA(this.deref()); + } + + copyView() { + return new XYZA(this.buf, this.offset, this.stride); + } + + empty() { + return new XYZA(); + } +} + +declareIndices(XYZA.prototype, ["x", "y", "z", "a"]); diff --git a/packages/color/src/ycbcr.ts b/packages/color/src/ycbcr.ts new file mode 100644 index 0000000000..f0e5c06a02 --- /dev/null +++ b/packages/color/src/ycbcr.ts @@ -0,0 +1,38 @@ +import { IVector } from "@thi.ng/vectors3/api"; +import { declareIndices } from "@thi.ng/vectors3/internal/accessors"; +import { Color, ColorMode } from "./api"; +import { AColor } from "./internal/acolor"; +import { ensureArgs } from "./internal/ctor-args"; + +export function ycbcra(rgba: Color): YCbCrA +export function ycbcra(r: number, g: number, b: number, a?: number): YCbCrA; +export function ycbcra(...args: any[]) { + return new YCbCrA(ensureArgs(args)); +} + +export class YCbCrA extends AColor implements + IVector { + + y: number; + b: number; + r: number; + a: number; + + get mode() { + return ColorMode.YCBCRA; + } + + copy() { + return new YCbCrA(this.deref()); + } + + copyView() { + return new YCbCrA(this.buf, this.offset, this.stride); + } + + empty() { + return new YCbCrA(); + } +} + +declareIndices(YCbCrA.prototype, ["y", "b", "r", "a"]); diff --git a/packages/color/src/ycbcra-rgba.ts b/packages/color/src/ycbcra-rgba.ts new file mode 100644 index 0000000000..77a4cc8a06 --- /dev/null +++ b/packages/color/src/ycbcra-rgba.ts @@ -0,0 +1,18 @@ +import { clamp01 } from "@thi.ng/math/interval"; +import { setC4 } from "@thi.ng/vectors3/setc"; +import { Color, ReadonlyColor } from "./api"; +import { ensureAlpha } from "./internal/ensure-alpha"; + +export const ycbcraRgba = + (out: Color, src: ReadonlyColor) => { + const y = src[0]; + const b = src[1]; + const r = src[2]; + return setC4( + out, + clamp01(y + 1.403 * r), + clamp01(y - 0.344 * b - 0.714 * r), + clamp01(y + 1.770 * b), + ensureAlpha(src[3]) + ); + }; From 1c28c22bcb80ce5bc53efb56868ea383537db2de Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 28 Dec 2018 03:43:43 +0000 Subject: [PATCH 101/333] fix(color): HCYA field names --- packages/color/src/hcya.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/color/src/hcya.ts b/packages/color/src/hcya.ts index 53942f3d9b..9a7cf67e3d 100644 --- a/packages/color/src/hcya.ts +++ b/packages/color/src/hcya.ts @@ -14,8 +14,8 @@ export class HCYA extends AColor implements IVector { h: number; - s: number; - v: number; + c: number; + y: number; a: number; get mode() { From 0a9456bf322acd34d2e17ea2e886ff1c24b77237 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 28 Dec 2018 04:09:55 +0000 Subject: [PATCH 102/333] docs(color): update readme --- packages/color/README.md | 48 ++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/packages/color/README.md b/packages/color/README.md index fb3381739f..490c0e3a49 100644 --- a/packages/color/README.md +++ b/packages/color/README.md @@ -28,20 +28,36 @@ This project is part of the Color space conversions (any direction) between: -- CSS (string, hex3/hex4/hex6/hex8, `rgba()`, `hsla()`, color names) -- ARGB (uint32, `0xaarrggbb`) -- RGBA (float4, `[r,g,b,a]`) -- HSIA (float4, `[h,s,i,a]`) -- HSLA (float4, `[h,s,l,a]`) -- HSVA (float4, `[h,s,v,a]`) - -RGBA, HSLA, HSVA colors can be stored as plain, typed or custom -array-like types of normalized values (`[0,1]` interval). +- CSS (string, hex3/hex4/hex6/hex8, `rgba()`, `hsla()`, named colors) +- INT32 (uint32, `0xaarrggbb`) +- RGBA (float4) +- HCYA (float4) +- HSIA (float4) +- HSLA (float4) +- HSVA (float4) +- XYZA (float4, CIE 1931) +- YCBCR (float4) + +Apart from `CSS` and `Int32` colors, all others can be stored as plain, +typed or custom array-like types of normalized values (`[0,1]` +interval). Where applicable, the hue too is stored in that range, NOT in +degrees. + +#### Class wrappers + +The package provides lightweight class wrappers for each color mode / +space. These wrappers act similarly to the `Vec2/3/4` wrappers in +[@thi.ng/vectors](https://github.com/thi-ng/umbrella/tree/master/packages/vectors3), +support striding (for mapped memory views), named channel accessor +aliases (in addition to array indexing) and are fully compatible with +all other functions. Wrapper factory functions are provided for +convenience. ### RGBA transformations -RGBA color matrix transformations, including parametric preset -transforms: +RGBA [color matrix +transformations](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/color/src/matrix.ts), +including parametric preset transforms: - brightness - contrast @@ -55,8 +71,16 @@ transforms: - invert (also available as non-matrix op) - luminance to alpha +Matrix transforms can be combined using matrix multiplication / +concatenation (`mulMatrix()` / `concatMatrices`). + ### RGBA Porter-Duff compositing +The package provides all 12 basic +[Porter-Duff](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/color/src/porter-duff.ts) +compositing / blending operators, both for colors with pre-multiplied +alpha and without. + ![porter-duff compositing modes](https://raw.githubusercontent.com/thi-ng/umbrella/feature/color/assets/porterduff.png) [Image source](http://www.svgopen.org/2005/papers/abstractsvgopen/#PorterDuffMap) @@ -112,7 +136,7 @@ yarn add @thi.ng/color import * as col from "@thi.ng/color"; // route #1: asXXX() converters: CSS -> ARGB (int) -> RGBA -const a = col.asRGBA("#3cf", col.ColorMode.CSS); +const a = col.asRGBA(col.css("#3cf")); // [0.2, 0.8, 1, 1] // route #2: parseCSS(): CSS -> HSLA -> RGBA From 460135145460e244ddde36f78f2f680d4447a753 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 28 Dec 2018 17:43:19 +0000 Subject: [PATCH 103/333] refactor(color): update conversions --- packages/color/src/api.ts | 2 + packages/color/src/convert.ts | 198 +++++++++++++++------ packages/color/src/hsla-rgba.ts | 44 ++--- packages/color/src/index.ts | 2 +- packages/color/src/kelvin-rgba.ts | 25 ++- packages/color/src/{linear.ts => srgba.ts} | 0 6 files changed, 176 insertions(+), 95 deletions(-) rename packages/color/src/{linear.ts => srgba.ts} (100%) diff --git a/packages/color/src/api.ts b/packages/color/src/api.ts index 2ebbc3c6e5..90f369586a 100644 --- a/packages/color/src/api.ts +++ b/packages/color/src/api.ts @@ -15,6 +15,8 @@ export type ColorMatrix = [ export type CosCoeffs = [number, number, number, number]; export type CosGradientSpec = [CosCoeffs, CosCoeffs, CosCoeffs, CosCoeffs]; +export type ColorConversion = (out: Color, src: ReadonlyColor) => Color; + export enum ColorMode { RGBA, HCYA, diff --git a/packages/color/src/convert.ts b/packages/color/src/convert.ts index 357a4f93b4..b69536d558 100644 --- a/packages/color/src/convert.ts +++ b/packages/color/src/convert.ts @@ -8,17 +8,34 @@ import { } from "./api"; import { hsiaRgba } from "./hsia-rgba"; import { hslaCss } from "./hsla-css"; +import { hslaHsva } from "./hsla-hsva"; import { hslaRgba } from "./hsla-rgba"; import { hsvaCss } from "./hsva-css"; +import { hsvaHsla } from "./hsva-hsla"; import { hsvaRgba } from "./hsva-rgba"; import { int32Css } from "./int-css"; import { int32Rgba } from "./int-rgba"; import { parseCss } from "./parse-css"; import { rgbaCss } from "./rgba-css"; +import { rgbaHcya } from "./rgba-hcya"; import { rgbaHsia } from "./rgba-hsia"; import { rgbaHsla } from "./rgba-hsla"; import { rgbaHsva } from "./rgba-hsva"; import { rgbaInt } from "./rgba-int"; +import { rgbaXyza } from "./rgba-xyza"; +import { rgbaYcbcra } from "./rgba-ycbcra"; +import { xyzaRgba } from "./xyza-rgba"; + +const RGBA_FNS = { + [ColorMode.CSS]: rgbaCss, + [ColorMode.INT32]: rgbaInt, + [ColorMode.HCYA]: rgbaHcya, + [ColorMode.HSIA]: rgbaHsia, + [ColorMode.HSLA]: rgbaHsla, + [ColorMode.HSVA]: rgbaHsva, + [ColorMode.XYZA]: rgbaXyza, + [ColorMode.YCBCRA]: rgbaYcbcra, +}; export const convert: MultiFn2O = defmulti( @@ -30,6 +47,12 @@ export const convert: MultiFn2Oconvert(col, ColorMode.CSS, mode); +} + export function asRGBA(col: IColor): Color; export function asRGBA(col: string | number | ReadonlyColor, mode: ColorMode): Color; export function asRGBA(col: any, mode?: ColorMode) { @@ -60,10 +83,16 @@ export function asHSVA(col: any, mode?: ColorMode) { return convert(col, ColorMode.HSVA, mode); } -export function asCSS(col: IColor): string; -export function asCSS(col: string | number | ReadonlyColor, mode: ColorMode): string; -export function asCSS(col: any, mode?: ColorMode) { - return convert(col, ColorMode.CSS, mode); +export function asXYZA(col: IColor): Color; +export function asXYZA(col: string | number | ReadonlyColor, mode: ColorMode): Color; +export function asXYZA(col: any, mode?: ColorMode) { + return convert(col, ColorMode.XYZA, mode); +} + +export function asYCbCrA(col: IColor): Color; +export function asYCbCrA(col: string | number | ReadonlyColor, mode: ColorMode): Color; +export function asYCbCrA(col: any, mode?: ColorMode) { + return convert(col, ColorMode.YCBCRA, mode); } const defConversion = ( @@ -78,43 +107,43 @@ const defConversion = ( // CSS -defConversion( - ColorMode.HSLA, ColorMode.CSS, - (x: string) => parseCss(x, ColorMode.HSLA) +[ + ColorMode.HCYA, + ColorMode.HSIA, + ColorMode.HSLA, + ColorMode.HSVA, + ColorMode.INT32, + ColorMode.RGBA, + ColorMode.XYZA, + ColorMode.YCBCRA +].forEach( + (id) => defConversion( + id, ColorMode.CSS, + (x: string) => parseCss(x, id) + ) ); -defConversion( - ColorMode.HSVA, ColorMode.CSS, - (x: string) => parseCss(x, ColorMode.HSVA) -); +// Int -defConversion( - ColorMode.INT32, ColorMode.CSS, - (x: string) => parseCss(x, ColorMode.INT32) +[ + ColorMode.HCYA, + ColorMode.HSIA, + ColorMode.HSLA, + ColorMode.HSVA, + ColorMode.XYZA, + ColorMode.YCBCRA, +].forEach( + (id) => defConversion( + id, ColorMode.INT32, + (x: number) => RGBA_FNS[id](null, int32Rgba([], x)) + ) ); -defConversion( - ColorMode.RGBA, ColorMode.CSS, - (x: string) => parseCss(x, ColorMode.RGBA) -); - -// Int - defConversion( ColorMode.CSS, ColorMode.INT32, (x: number) => int32Css(x) ); -defConversion( - ColorMode.HSLA, ColorMode.INT32, - (x: number) => rgbaHsla(null, int32Rgba([], x)) -); - -defConversion( - ColorMode.HSVA, ColorMode.INT32, - (x: number) => rgbaHsva(null, int32Rgba([], x)) -); - defConversion( ColorMode.RGBA, ColorMode.INT32, (x: number) => int32Rgba([], x) @@ -122,19 +151,19 @@ defConversion( // HSIA -defConversion( - ColorMode.CSS, ColorMode.HSIA, - (x: ReadonlyColor) => rgbaCss(hsiaRgba([], x)) -); - -defConversion( - ColorMode.HSLA, ColorMode.HSIA, - (x: ReadonlyColor) => rgbaHsla(null, hsiaRgba([], x)) -); - -defConversion( - ColorMode.HSVA, ColorMode.HSIA, - (x: ReadonlyColor) => rgbaHsva(null, hsiaRgba([], x)) +[ + ColorMode.CSS, + ColorMode.INT32, + ColorMode.HCYA, + ColorMode.HSLA, + ColorMode.HSVA, + ColorMode.XYZA, + ColorMode.YCBCRA, +].forEach( + (id) => defConversion( + id, ColorMode.HSIA, + (x: ReadonlyColor) => RGBA_FNS[id](null, hsiaRgba([], x)) + ) ); defConversion( @@ -144,11 +173,29 @@ defConversion( // HSLA +[ + ColorMode.HCYA, + ColorMode.HSIA, + ColorMode.INT32, + ColorMode.XYZA, + ColorMode.YCBCRA, +].forEach( + (id) => defConversion( + id, ColorMode.HSLA, + (x: ReadonlyColor) => RGBA_FNS[id](null, hslaRgba([], x)) + ) +); + defConversion( ColorMode.CSS, ColorMode.HSLA, (x: ReadonlyColor) => hslaCss(x) ); +defConversion( + ColorMode.HSVA, ColorMode.HSLA, + (x: ReadonlyColor) => hslaHsva([], x) +); + defConversion( ColorMode.RGBA, ColorMode.HSLA, (x: ReadonlyColor) => hslaRgba([], x) @@ -156,11 +203,29 @@ defConversion( // HSVA +[ + ColorMode.HCYA, + ColorMode.HSIA, + ColorMode.INT32, + ColorMode.XYZA, + ColorMode.YCBCRA, +].forEach( + (id) => defConversion( + id, ColorMode.HSVA, + (x: ReadonlyColor) => RGBA_FNS[id](null, hsvaRgba([], x)) + ) +); + defConversion( ColorMode.CSS, ColorMode.HSVA, (x: ReadonlyColor) => hsvaCss(x) ); +defConversion( + ColorMode.HSLA, ColorMode.HSVA, + (x: ReadonlyColor) => hsvaHsla([], x) +); + defConversion( ColorMode.RGBA, ColorMode.HSVA, (x: ReadonlyColor) => hsvaRgba([], x) @@ -168,27 +233,48 @@ defConversion( // RGBA -defConversion( - ColorMode.CSS, ColorMode.RGBA, - (x: ReadonlyColor) => rgbaCss(x) +[ + ColorMode.HCYA, + ColorMode.HSIA, + ColorMode.HSLA, + ColorMode.HSVA, + ColorMode.XYZA, + ColorMode.YCBCRA, +].forEach( + (id) => defConversion( + id, ColorMode.RGBA, + (x: ReadonlyColor) => RGBA_FNS[id]([], x) + ) ); defConversion( - ColorMode.HSIA, ColorMode.RGBA, - (x: ReadonlyColor) => rgbaHsia([], x) + ColorMode.CSS, ColorMode.RGBA, + (x: ReadonlyColor) => rgbaCss(x) ); defConversion( - ColorMode.HSLA, ColorMode.RGBA, - (x: ReadonlyColor) => rgbaHsla([], x) + ColorMode.INT32, ColorMode.RGBA, + (x: ReadonlyColor) => rgbaInt(x) ); -defConversion( - ColorMode.HSVA, ColorMode.RGBA, - (x: ReadonlyColor) => rgbaHsva([], x) +// XYZA + +[ + ColorMode.CSS, + ColorMode.HCYA, + ColorMode.HSIA, + ColorMode.HSLA, + ColorMode.HSVA, + ColorMode.INT32, + ColorMode.YCBCRA, +].forEach( + (id) => defConversion( + id, ColorMode.RGBA, + (x: ReadonlyColor) => RGBA_FNS[id](xyzaRgba([], x)) + ) ); defConversion( - ColorMode.INT32, ColorMode.RGBA, - (x: ReadonlyColor) => rgbaInt(x) + ColorMode.RGBA, ColorMode.XYZA, + (x: ReadonlyColor) => xyzaRgba([], x) ); diff --git a/packages/color/src/hsla-rgba.ts b/packages/color/src/hsla-rgba.ts index b0ca91dcc1..01d2ce8b51 100644 --- a/packages/color/src/hsla-rgba.ts +++ b/packages/color/src/hsla-rgba.ts @@ -1,41 +1,19 @@ -import { SIXTH, THIRD, TWO_THIRD } from "@thi.ng/math/api"; import { clamp01 } from "@thi.ng/math/interval"; import { setC3 } from "@thi.ng/vectors3/setc"; import { Color, ReadonlyColor } from "./api"; -import { clampH } from "./clamp"; -import { ensureHue } from "./internal/ensure-hue"; +import { hueRgba } from "./hue-rgba"; +import { ensureAlpha } from "./internal/ensure-alpha"; export const hslaRgba = (out: Color, src: ReadonlyColor) => { - out = clampH(out || src, src); - const h = out[0]; - const s = out[1]; - const l = out[2]; - if (s > 1e-6) { - const f2 = l < 0.5 ? - l * (s + 1) : - (l + s) - (l * s); - const f1 = 2 * l - f2; - return setC3( - out, - hslHue(f1, f2, h + THIRD), - hslHue(f1, f2, h), - hslHue(f1, f2, h - THIRD), - ); - } - return setC3(out, l, l, l); - }; - -const hslHue = - (f1: number, f2: number, h: number) => { - h = ensureHue(h); - return clamp01( - (h < SIXTH) ? - f1 + (f2 - f1) * 6 * h : - (h < 0.5) ? - f2 : - (h < TWO_THIRD) ? - f1 + (f2 - f1) * (TWO_THIRD - h) * 6 : - f1 + const s = clamp01(src[1]); + const l = clamp01(src[2]); + out = hueRgba(out || src, src[0], ensureAlpha(src[3])); + const c = (1 - Math.abs(2 * l - 1)) * s; + return setC3( + out, + (out[0] - 0.5) * c + l, + (out[1] - 0.5) * c + l, + (out[2] - 0.5) * c + l ); }; diff --git a/packages/color/src/index.ts b/packages/color/src/index.ts index d93c5a3154..c07d0f0d51 100644 --- a/packages/color/src/index.ts +++ b/packages/color/src/index.ts @@ -22,6 +22,7 @@ export * from "./rgba-hsva"; export * from "./rgba-int"; export * from "./rgba-xyza"; export * from "./rgba-ycbcra"; +export * from "./srgba"; export * from "./xyza-rgba"; export * from "./ycbcra-rgba"; @@ -40,7 +41,6 @@ export * from "./ycbcr"; export * from "./cosine-gradients"; export * from "./invert"; -export * from "./linear"; export * from "./luminance"; export * from "./matrix"; export * from "./porter-duff"; diff --git a/packages/color/src/kelvin-rgba.ts b/packages/color/src/kelvin-rgba.ts index 86ff5e0563..2c5bb049f9 100644 --- a/packages/color/src/kelvin-rgba.ts +++ b/packages/color/src/kelvin-rgba.ts @@ -1,12 +1,27 @@ import { clamp01 } from "@thi.ng/math/interval"; +const G1 = -0.6088425710866344; +const G2 = -0.001748900018414868; +const G3 = 0.4097731842899564; +const G4 = 1.2762722061615583; +const G5 = 0.0003115080994769546; +const G6 = 0.11013841706194392; +const R1 = 1.3803015908551253; +const R2 = 0.0004478684462124118; +const R3 = -0.15785750232675008; +const B1 = -0.9990954974165059; +const B2 = 0.0032447435545127036; +const B3 = 0.453646839257496; + /** * Based on: * https://github.com/neilbartlett/color-temperature/blob/master/index.js * http://www.zombieprototypes.com/?p=210 * + * Uses adjusted coefficients to produce normalized RGB values. + * * @param kelvin color temperature - * @param alpha + * @param alpha target alpha channel */ export const kelvinRgba = (kelvin: number, alpha = 1) => { @@ -14,15 +29,15 @@ export const kelvinRgba = let t: number; return kelvin < 66 ? [1, - clamp01(-0.6088425710866344 - 0.001748900018414868 * (t = kelvin - 2) + 0.4097731842899564 * Math.log(t)), + clamp01(G1 + G2 * (t = kelvin - 2) + G3 * Math.log(t)), kelvin < 20 ? 0 : - clamp01(-0.9990954974165059 + 0.0032447435545127036 * (t = kelvin - 10) + 0.453646839257496 * Math.log(t)), + clamp01(B1 + B2 * (t = kelvin - 10) + B3 * Math.log(t)), alpha ] : [ - clamp01(1.3803015908551253 + 0.0004478684462124118 * (t = kelvin - 55) - 0.15785750232675008 * Math.log(t)), - clamp01(1.2762722061615583 + 0.0003115080994769546 * (t = kelvin - 50) - 0.11013841706194392 * Math.log(t)), + clamp01(R1 + R2 * (t = kelvin - 55) + R3 * Math.log(t)), + clamp01(G4 + G5 * (t = kelvin - 50) - G6 * Math.log(t)), 1, alpha ]; diff --git a/packages/color/src/linear.ts b/packages/color/src/srgba.ts similarity index 100% rename from packages/color/src/linear.ts rename to packages/color/src/srgba.ts From dbbb26cff19e9c2078ae6b11cd2b73c18fa822dd Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 28 Dec 2018 17:45:08 +0000 Subject: [PATCH 104/333] feat(color): add multiCosineGradient() --- packages/color/src/cosine-gradients.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/color/src/cosine-gradients.ts b/packages/color/src/cosine-gradients.ts index 205414cd43..d1332e06c5 100644 --- a/packages/color/src/cosine-gradients.ts +++ b/packages/color/src/cosine-gradients.ts @@ -2,6 +2,7 @@ import { IObjectOf } from "@thi.ng/api/api"; import { partial } from "@thi.ng/compose/partial"; import { TAU } from "@thi.ng/math/api"; import { clamp01 } from "@thi.ng/math/interval"; +import { interpolate } from "@thi.ng/transducers/iter/interpolate"; import { normRange } from "@thi.ng/transducers/iter/norm-range"; import { tuples } from "@thi.ng/transducers/iter/tuples"; import { push } from "@thi.ng/transducers/rfn/push"; @@ -67,3 +68,12 @@ export const cosineCoeffs = [0, 0, 0, 0] ]; }; + +export const multiCosineGradient = + (n: number, ...stops: [number, ReadonlyColor][]) => + interpolate( + n, + cosineCoeffs, + cosineColor, + ...stops + ); From 04c38372e04ef4b2fd5451298f67aca2e38597b9 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 28 Dec 2018 22:02:45 +0000 Subject: [PATCH 105/333] refactor(color): update converters --- packages/color/src/api.ts | 2 +- packages/color/src/convert.ts | 109 ++++++++++++++++------------------ 2 files changed, 52 insertions(+), 59 deletions(-) diff --git a/packages/color/src/api.ts b/packages/color/src/api.ts index 90f369586a..4e0830e133 100644 --- a/packages/color/src/api.ts +++ b/packages/color/src/api.ts @@ -15,7 +15,7 @@ export type ColorMatrix = [ export type CosCoeffs = [number, number, number, number]; export type CosGradientSpec = [CosCoeffs, CosCoeffs, CosCoeffs, CosCoeffs]; -export type ColorConversion = (out: Color, src: ReadonlyColor) => Color; +export type ColorConversion = (out: Color, src: T) => Color; export enum ColorMode { RGBA, diff --git a/packages/color/src/convert.ts b/packages/color/src/convert.ts index b69536d558..efc08e8ba0 100644 --- a/packages/color/src/convert.ts +++ b/packages/color/src/convert.ts @@ -2,6 +2,7 @@ import { defmulti, Implementation3, MultiFn2O } from "@thi.ng/defmulti"; import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; import { Color, + ColorConversion, ColorMode, IColor, ReadonlyColor @@ -25,6 +26,7 @@ import { rgbaInt } from "./rgba-int"; import { rgbaXyza } from "./rgba-xyza"; import { rgbaYcbcra } from "./rgba-ycbcra"; import { xyzaRgba } from "./xyza-rgba"; +import { ycbcraRgba } from "./ycbcra-rgba"; const RGBA_FNS = { [ColorMode.CSS]: rgbaCss, @@ -105,6 +107,23 @@ const defConversion = ( impl ); +const defConversions = ( + src: ColorMode, + toRGBA: ColorConversion, + ...dest: ColorMode[] +) => { + defConversion( + ColorMode.RGBA, src, + (x: any) => toRGBA([], x) + ); + dest.forEach( + (id) => defConversion( + id, src, + (x: any) => RGBA_FNS[id](null, toRGBA([], x)) + ) + ); +}; + // CSS [ @@ -125,18 +144,15 @@ const defConversion = ( // Int -[ +defConversions( + ColorMode.INT32, + int32Rgba, ColorMode.HCYA, ColorMode.HSIA, ColorMode.HSLA, ColorMode.HSVA, ColorMode.XYZA, - ColorMode.YCBCRA, -].forEach( - (id) => defConversion( - id, ColorMode.INT32, - (x: number) => RGBA_FNS[id](null, int32Rgba([], x)) - ) + ColorMode.YCBCRA ); defConversion( @@ -144,46 +160,30 @@ defConversion( (x: number) => int32Css(x) ); -defConversion( - ColorMode.RGBA, ColorMode.INT32, - (x: number) => int32Rgba([], x) -); - // HSIA -[ +defConversions( + ColorMode.HSIA, + hsiaRgba, ColorMode.CSS, ColorMode.INT32, ColorMode.HCYA, ColorMode.HSLA, ColorMode.HSVA, ColorMode.XYZA, - ColorMode.YCBCRA, -].forEach( - (id) => defConversion( - id, ColorMode.HSIA, - (x: ReadonlyColor) => RGBA_FNS[id](null, hsiaRgba([], x)) - ) -); - -defConversion( - ColorMode.RGBA, ColorMode.HSIA, - (x: ReadonlyColor) => hsiaRgba([], x) + ColorMode.YCBCRA ); // HSLA -[ +defConversions( + ColorMode.HSLA, + hslaRgba, ColorMode.HCYA, ColorMode.HSIA, ColorMode.INT32, ColorMode.XYZA, - ColorMode.YCBCRA, -].forEach( - (id) => defConversion( - id, ColorMode.HSLA, - (x: ReadonlyColor) => RGBA_FNS[id](null, hslaRgba([], x)) - ) + ColorMode.YCBCRA ); defConversion( @@ -196,24 +196,16 @@ defConversion( (x: ReadonlyColor) => hslaHsva([], x) ); -defConversion( - ColorMode.RGBA, ColorMode.HSLA, - (x: ReadonlyColor) => hslaRgba([], x) -); - // HSVA -[ +defConversions( + ColorMode.HSVA, + hsvaRgba, ColorMode.HCYA, ColorMode.HSIA, ColorMode.INT32, ColorMode.XYZA, - ColorMode.YCBCRA, -].forEach( - (id) => defConversion( - id, ColorMode.HSVA, - (x: ReadonlyColor) => RGBA_FNS[id](null, hsvaRgba([], x)) - ) + ColorMode.YCBCRA ); defConversion( @@ -226,11 +218,6 @@ defConversion( (x: ReadonlyColor) => hsvaHsla([], x) ); -defConversion( - ColorMode.RGBA, ColorMode.HSVA, - (x: ReadonlyColor) => hsvaRgba([], x) -); - // RGBA [ @@ -259,22 +246,28 @@ defConversion( // XYZA -[ +defConversions( + ColorMode.XYZA, + xyzaRgba, ColorMode.CSS, ColorMode.HCYA, ColorMode.HSIA, ColorMode.HSLA, ColorMode.HSVA, ColorMode.INT32, - ColorMode.YCBCRA, -].forEach( - (id) => defConversion( - id, ColorMode.RGBA, - (x: ReadonlyColor) => RGBA_FNS[id](xyzaRgba([], x)) - ) + ColorMode.YCBCRA ); -defConversion( - ColorMode.RGBA, ColorMode.XYZA, - (x: ReadonlyColor) => xyzaRgba([], x) +// YCbCr + +defConversions( + ColorMode.YCBCRA, + ycbcraRgba, + ColorMode.CSS, + ColorMode.HCYA, + ColorMode.HSIA, + ColorMode.HSLA, + ColorMode.HSVA, + ColorMode.INT32, + ColorMode.XYZA ); From a5c53c38407b2b5bb692dbcf2de9ef45e77d6959 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 29 Dec 2018 00:52:27 +0000 Subject: [PATCH 106/333] fix(color): add/update conversions --- packages/color/src/convert.ts | 43 +++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/packages/color/src/convert.ts b/packages/color/src/convert.ts index efc08e8ba0..e1f0af73dd 100644 --- a/packages/color/src/convert.ts +++ b/packages/color/src/convert.ts @@ -27,17 +27,7 @@ import { rgbaXyza } from "./rgba-xyza"; import { rgbaYcbcra } from "./rgba-ycbcra"; import { xyzaRgba } from "./xyza-rgba"; import { ycbcraRgba } from "./ycbcra-rgba"; - -const RGBA_FNS = { - [ColorMode.CSS]: rgbaCss, - [ColorMode.INT32]: rgbaInt, - [ColorMode.HCYA]: rgbaHcya, - [ColorMode.HSIA]: rgbaHsia, - [ColorMode.HSLA]: rgbaHsla, - [ColorMode.HSVA]: rgbaHsva, - [ColorMode.XYZA]: rgbaXyza, - [ColorMode.YCBCRA]: rgbaYcbcra, -}; +import { hcyaRgba } from "./hcya-rgba"; export const convert: MultiFn2O = defmulti( @@ -119,7 +109,7 @@ const defConversions = ( dest.forEach( (id) => defConversion( id, src, - (x: any) => RGBA_FNS[id](null, toRGBA([], x)) + (x: any) => convert(toRGBA([], x), id, ColorMode.RGBA) ) ); }; @@ -160,6 +150,19 @@ defConversion( (x: number) => int32Css(x) ); +// HCYA + +defConversions( + ColorMode.HCYA, + hcyaRgba, + ColorMode.CSS, + ColorMode.INT32, + ColorMode.HSLA, + ColorMode.HSVA, + ColorMode.XYZA, + ColorMode.YCBCRA +); + // HSIA defConversions( @@ -221,16 +224,16 @@ defConversion( // RGBA [ - ColorMode.HCYA, - ColorMode.HSIA, - ColorMode.HSLA, - ColorMode.HSVA, - ColorMode.XYZA, - ColorMode.YCBCRA, + [ColorMode.HCYA, rgbaHcya], + [ColorMode.HSIA, rgbaHsia], + [ColorMode.HSLA, rgbaHsla], + [ColorMode.HSVA, rgbaHsva], + [ColorMode.XYZA, rgbaXyza], + [ColorMode.YCBCRA, rgbaYcbcra] ].forEach( - (id) => defConversion( + ([id, fn]: [ColorMode, ColorConversion]) => defConversion( id, ColorMode.RGBA, - (x: ReadonlyColor) => RGBA_FNS[id]([], x) + (x: ReadonlyColor) => fn([], x) ) ); From 0546839db49d412b5ea3d99868b19bdb938965c6 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 29 Dec 2018 01:15:19 +0000 Subject: [PATCH 107/333] refactor(color): ColorMode const enum, update convert() dispatcher --- packages/color/src/api.ts | 2 +- packages/color/src/convert.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/color/src/api.ts b/packages/color/src/api.ts index 4e0830e133..227b2d663b 100644 --- a/packages/color/src/api.ts +++ b/packages/color/src/api.ts @@ -17,7 +17,7 @@ export type CosGradientSpec = [CosCoeffs, CosCoeffs, CosCoeffs, CosCoeffs]; export type ColorConversion = (out: Color, src: T) => Color; -export enum ColorMode { +export const enum ColorMode { RGBA, HCYA, HSVA, diff --git a/packages/color/src/convert.ts b/packages/color/src/convert.ts index e1f0af73dd..7825cf098e 100644 --- a/packages/color/src/convert.ts +++ b/packages/color/src/convert.ts @@ -33,9 +33,9 @@ export const convert: MultiFn2O (col).mode !== undefined ? - `${ColorMode[mdest]}-${ColorMode[(col).mode]}` : + `${mdest}-${(col).mode}` : msrc !== undefined ? - `${ColorMode[mdest]}-${ColorMode[msrc]}` : + `${mdest}-${msrc}` : illegalArgs(`missing src color mode`) ); @@ -93,7 +93,7 @@ const defConversion = ( impl: Implementation3 ) => convert.add( - `${ColorMode[dest]}-${ColorMode[src]}`, + `${dest}-${src}`, impl ); From b0d28788d9a27fc40a082e8fed6fc73c07ad4a25 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 29 Dec 2018 03:23:31 +0000 Subject: [PATCH 108/333] refactor(color): update multiCosineGradient(), update readme --- packages/color/README.md | 76 +++++++++++++++++++++----- packages/color/src/cosine-gradients.ts | 2 + 2 files changed, 65 insertions(+), 13 deletions(-) diff --git a/packages/color/README.md b/packages/color/README.md index 490c0e3a49..e214b9e9f4 100644 --- a/packages/color/README.md +++ b/packages/color/README.md @@ -14,6 +14,7 @@ This project is part of the - [RGBA transformations](#rgba-transformations) - [RGBA Porter-Duff compositing](#rgba-porter-duff-compositing) - [Cosine gradients](#cosine-gradients) + - [Multi-stop gradients](#multi-stop-gradients) - [Installation](#installation) - [Dependencies](#dependencies) - [Usage examples](#usage-examples) @@ -26,23 +27,29 @@ This project is part of the ### Color modes -Color space conversions (any direction) between: +Fast color space conversions (any direction) between: - CSS (string, hex3/hex4/hex6/hex8, `rgba()`, `hsla()`, named colors) -- INT32 (uint32, `0xaarrggbb`) -- RGBA (float4) - HCYA (float4) - HSIA (float4) - HSLA (float4) - HSVA (float4) -- XYZA (float4, CIE 1931) -- YCBCR (float4) +- Int32 (uint32, `0xaarrggbb`) +- RGBA (float4) +- XYZA (float4, aka CIE 1931) +- YCbCr (float4) Apart from `CSS` and `Int32` colors, all others can be stored as plain, -typed or custom array-like types of normalized values (`[0,1]` +typed or custom array-like types of (mostly) normalized values (`[0,1]` interval). Where applicable, the hue too is stored in that range, NOT in degrees. +Apart from conversions, most other operations provided by this package +are only supporting RGBA colors. These can also be converted to/from +sRGB (i.e. linear vs gamma corrected). Additionally, RGBA colors can be +pre-multiplied (and post-multiplied) with their alpha channel (see +[Porter-Duff](#rgba-porter-duff-compositing) section below). + #### Class wrappers The package provides lightweight class wrappers for each color mode / @@ -81,9 +88,9 @@ The package provides all 12 basic compositing / blending operators, both for colors with pre-multiplied alpha and without. -![porter-duff compositing modes](https://raw.githubusercontent.com/thi-ng/umbrella/feature/color/assets/porterduff.png) +![porter-duff compositing modes](https://raw.githubusercontent.com/thi-ng/umbrella/feature/vec-refactor/assets/porterduff.png) -[Image source](http://www.svgopen.org/2005/papers/abstractsvgopen/#PorterDuffMap) +([Image source](http://www.svgopen.org/2005/papers/abstractsvgopen/#PorterDuffMap)) ### Cosine gradients @@ -91,6 +98,7 @@ alpha and without. - [Gradient generator](http://dev.thi.ng/gradients/) The following presets are bundled (in [`cosine-gradients.ts`](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/color/src/cosine-gradients.ts)): + | | | |----------------------------------------------------------------|------------------------------------------------------------------| | ![](http://media.thi.ng/color/presets/rainbow1.svg) | ![](http://media.thi.ng/color/presets/rainbow2.svg) | @@ -114,6 +122,36 @@ The following presets are bundled (in [`cosine-gradients.ts`](https://github.com | ![](http://media.thi.ng/color/presets/blue-magenta-orange.svg) | ![](http://media.thi.ng/color/presets/magenta-green.svg) | | blue-magenta-orange | magenta-green | +### Multi-stop gradients + +The `multiCosineGradient()` function returns an iterator of RGBA colors +based on given gradient stops. This iterator computes a cosine gradient between each color stop and yields a sequence of RGBA values. + +```ts +const gradient = col.multiCosineGradient( + // num colors to produce + 10, + // gradient stops (normalized positions, only RGBA colors supported) + [0.1, col.RED], [0.5, col.GREEN], [0.9, col.BLUE] +); + +for(let c of gradient) { + console.log(col.rgbaCss(c)); +} + +// #ff0000 +// #ff0000 +// #da2500 +// #807f00 +// #25da00 +// #00ff00 +// #00da25 +// #00807f +// #0025da +// #0000ff +// #0000ff +``` + ## Installation ```bash @@ -135,24 +173,36 @@ yarn add @thi.ng/color ```ts import * as col from "@thi.ng/color"; -// route #1: asXXX() converters: CSS -> ARGB (int) -> RGBA +// route #1: asXXX() converters: string -> CSS -> ARGB (int) -> RGBA const a = col.asRGBA(col.css("#3cf")); // [0.2, 0.8, 1, 1] -// route #2: parseCSS(): CSS -> HSLA -> RGBA +// route #2: parseCSS(): string -> HSLA -> RGBA const b = col.parseCss("hsla(30,100%,50%,0.75)", col.ColorMode.RGBA); // [ 1, 0.5, 0, 0.75 ] // route #3: convert() multi-method: HSVA -> RGBA -const c = col.convert([0.5, 1, 1, 1], col.ColorMode.RGBA, col.ColorMode.HSVA); -// [ 0, 1, 1, 1 ] +const c = col.convert("rgb(0,255,255)", col.ColorMode.HSVA, col.ColorMode.CSS); +// [ 0.4999999722222268, 0.9999990000010001, 1, 1 ] + +// route #4: direct conversion +col.rgbaHsla([], [1,0.5,0,1]) col.luminanceRGB(a) // 0.6434 // apply color matrix (RGBA only) -col.applyMatrix([], col.saturation(1.25), a) +col.transform([], col.saturation(1.25), a) // [ 0.07835000000000002, 0.82835, 1, 1 ] + +// combine matrix transformations +filter = col.concatMatrices( + col.saturation(0.5), // 50% saturation + col.brightness(0.1), // +10% brightness +); + +col.transform([], filter, col.RED); +// [ 0.7065, 0.2065, 0.2065, 1 ] ``` ## Authors diff --git a/packages/color/src/cosine-gradients.ts b/packages/color/src/cosine-gradients.ts index d1332e06c5..8107cbc240 100644 --- a/packages/color/src/cosine-gradients.ts +++ b/packages/color/src/cosine-gradients.ts @@ -73,6 +73,8 @@ export const multiCosineGradient = (n: number, ...stops: [number, ReadonlyColor][]) => interpolate( n, + 0, + 1, cosineCoeffs, cosineColor, ...stops From f2cac2863cc432823d5dc8cf7c9f2b1dc3628f60 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 29 Dec 2018 15:45:59 +0000 Subject: [PATCH 109/333] refactor(color): update type factory fns & ensureArgs() --- packages/color/src/hcya.ts | 4 ++-- packages/color/src/hsia.ts | 4 ++-- packages/color/src/hsla.ts | 4 ++-- packages/color/src/hsva.ts | 4 ++-- packages/color/src/int.ts | 21 ++++++++++++++++----- packages/color/src/internal/ctor-args.ts | 21 +++++++++++++++------ packages/color/src/rgba.ts | 4 ++-- packages/color/src/xyza.ts | 4 ++-- packages/color/src/ycbcr.ts | 4 ++-- 9 files changed, 45 insertions(+), 25 deletions(-) diff --git a/packages/color/src/hcya.ts b/packages/color/src/hcya.ts index 9a7cf67e3d..9848810b40 100644 --- a/packages/color/src/hcya.ts +++ b/packages/color/src/hcya.ts @@ -4,8 +4,8 @@ import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ctor-args"; -export function hcya(hcya: Color): HCYA -export function hcya(h: number, c: number, y: number, a?: number): HCYA; +export function hcya(col: Color): HCYA +export function hcya(h?: number, c?: number, y?: number, a?: number): HCYA; export function hcya(...args: any[]) { return new HCYA(ensureArgs(args)); } diff --git a/packages/color/src/hsia.ts b/packages/color/src/hsia.ts index f775270275..ca911f86ab 100644 --- a/packages/color/src/hsia.ts +++ b/packages/color/src/hsia.ts @@ -4,8 +4,8 @@ import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ctor-args"; -export function hsia(rgba: Color): HSIA -export function hsia(h: number, s: number, i: number, a?: number): HSIA; +export function hsia(col: Color): HSIA +export function hsia(h?: number, s?: number, i?: number, a?: number): HSIA; export function hsia(...args: any[]) { return new HSIA(ensureArgs(args)); } diff --git a/packages/color/src/hsla.ts b/packages/color/src/hsla.ts index cf1fe69fe9..cdc8687bd0 100644 --- a/packages/color/src/hsla.ts +++ b/packages/color/src/hsla.ts @@ -4,8 +4,8 @@ import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ctor-args"; -export function hsla(rgba: Color): HSLA -export function hsla(h: number, s: number, l: number, a?: number): HSLA; +export function hsla(col: Color): HSLA +export function hsla(h?: number, s?: number, l?: number, a?: number): HSLA; export function hsla(...args: any[]) { return new HSLA(ensureArgs(args)); } diff --git a/packages/color/src/hsva.ts b/packages/color/src/hsva.ts index bbaa328c06..d2939f2f7f 100644 --- a/packages/color/src/hsva.ts +++ b/packages/color/src/hsva.ts @@ -4,8 +4,8 @@ import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ctor-args"; -export function hsva(rgba: Color): HSVA -export function hsva(h: number, s: number, v: number, a?: number): HSVA; +export function hsva(col: Color): HSVA +export function hsva(h?: number, s?: number, v?: number, a?: number): HSVA; export function hsva(...args: any[]) { return new HSVA(ensureArgs(args)); } diff --git a/packages/color/src/int.ts b/packages/color/src/int.ts index 226f85779d..d96b88ffc8 100644 --- a/packages/color/src/int.ts +++ b/packages/color/src/int.ts @@ -1,13 +1,24 @@ import { ICopy, IDeref } from "@thi.ng/api/api"; import { ColorMode, IColor } from "./api"; +/** + * Returns new `Int32` wrapping given ARGB int. + * + * @param rgba + */ export const int32 = - (x: number) => - new Int32(x); - + (rgba: number) => + new Int32(rgba); + +/** + * Returns new `Int32` wrapping given 24bit RGB color and setting alpha + * channel set to 100% opaque. + * + * @param rgb + */ export const int24 = - (x: number) => - new Int32((x & 0xffffff) | 0xff000000); + (rgb: number) => + new Int32((rgb & 0xffffff) | 0xff000000); export class Int32 implements IColor, diff --git a/packages/color/src/internal/ctor-args.ts b/packages/color/src/internal/ctor-args.ts index 56131a3f06..6eac8e2149 100644 --- a/packages/color/src/internal/ctor-args.ts +++ b/packages/color/src/internal/ctor-args.ts @@ -1,7 +1,16 @@ export const ensureArgs = - (args: any[]) => - typeof args[0] === "number" ? - args.length < 4 ? - (args.push(1), args) : - args : - args[0]; + (args: any[]) => { + if (typeof args[0] === "number") { + switch (args.length) { + case 1: + return (args.push(0, 0, 1), args); + case 2: + return (args.push(0, 1), args); + case 3: + return (args.push(1), args); + default: + return args; + } + } + return args[0]; + }; diff --git a/packages/color/src/rgba.ts b/packages/color/src/rgba.ts index 08c43d06f6..73cdbbebe5 100644 --- a/packages/color/src/rgba.ts +++ b/packages/color/src/rgba.ts @@ -4,8 +4,8 @@ import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ctor-args"; -export function rgba(rgba: Color): RGBA -export function rgba(r: number, g: number, b: number, a?: number): RGBA; +export function rgba(col: Color): RGBA +export function rgba(r?: number, g?: number, b?: number, a?: number): RGBA; export function rgba(...args: any[]) { return new RGBA(ensureArgs(args)); } diff --git a/packages/color/src/xyza.ts b/packages/color/src/xyza.ts index 7ff869ab61..aa727f8a7f 100644 --- a/packages/color/src/xyza.ts +++ b/packages/color/src/xyza.ts @@ -4,8 +4,8 @@ import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ctor-args"; -export function xyza(rgba: Color): XYZA -export function xyza(r: number, g: number, b: number, a?: number): XYZA; +export function xyza(col: Color): XYZA +export function xyza(x?: number, y?: number, z?: number, a?: number): XYZA; export function xyza(...args: any[]) { return new XYZA(ensureArgs(args)); } diff --git a/packages/color/src/ycbcr.ts b/packages/color/src/ycbcr.ts index f0e5c06a02..3af05b2803 100644 --- a/packages/color/src/ycbcr.ts +++ b/packages/color/src/ycbcr.ts @@ -4,8 +4,8 @@ import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ctor-args"; -export function ycbcra(rgba: Color): YCbCrA -export function ycbcra(r: number, g: number, b: number, a?: number): YCbCrA; +export function ycbcra(col: Color): YCbCrA +export function ycbcra(y: number, b: number, r: number, a?: number): YCbCrA; export function ycbcra(...args: any[]) { return new YCbCrA(ensureArgs(args)); } From 36b7d038f8852d98a75f049dc799b343989d40da Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 29 Dec 2018 15:48:30 +0000 Subject: [PATCH 110/333] refactor(color): rename, update matrix ops - rename concatMatrices() => concat() - move mulMatrix(), rename => mulM45() - rename/update invert() => subtract() - add doc strings --- packages/color/src/index.ts | 2 +- packages/color/src/internal/matrix-ops.ts | 64 +++++++++++++ packages/color/src/internal/mulv.ts | 39 -------- .../color/src/{matrix.ts => transform.ts} | 96 ++++++++++++------- 4 files changed, 124 insertions(+), 77 deletions(-) create mode 100644 packages/color/src/internal/matrix-ops.ts delete mode 100644 packages/color/src/internal/mulv.ts rename packages/color/src/{matrix.ts => transform.ts} (63%) diff --git a/packages/color/src/index.ts b/packages/color/src/index.ts index c07d0f0d51..bbbbdd2fec 100644 --- a/packages/color/src/index.ts +++ b/packages/color/src/index.ts @@ -42,5 +42,5 @@ export * from "./ycbcr"; export * from "./cosine-gradients"; export * from "./invert"; export * from "./luminance"; -export * from "./matrix"; export * from "./porter-duff"; +export * from "./transform"; diff --git a/packages/color/src/internal/matrix-ops.ts b/packages/color/src/internal/matrix-ops.ts new file mode 100644 index 0000000000..b3ccd933e5 --- /dev/null +++ b/packages/color/src/internal/matrix-ops.ts @@ -0,0 +1,64 @@ +import { dotS3, dotS4 } from "@thi.ng/vectors3/dots"; +import { Color, ReadonlyColor, ColorMatrix } from "../api"; +import { clamp01 } from "@thi.ng/math/interval"; +import { setC4 } from "@thi.ng/vectors3/setc"; +import { ensureAlpha } from "./ensure-alpha"; + +export const mulV33 = + (out: Color, mat: number[], src: ReadonlyColor, clampOut = true) => { + const x = dotS3(mat, src, 0, 0, 3); + const y = dotS3(mat, src, 1, 0, 3); + const z = dotS3(mat, src, 2, 0, 3); + const a = ensureAlpha(src[3]); + return clampOut ? + setC4( + out || src, + clamp01(x), + clamp01(y), + clamp01(z), + a + ) : + setC4(out || src, x, y, z, a); + }; + +export const mulV45 = + (out: Color, mat: ColorMatrix, src: ReadonlyColor, clampOut = true) => { + out = setC4(out || src, src[0], src[1], src[2], ensureAlpha(src[3])); + const x = dotS4(out, mat, 0, 0) + mat[4]; + const y = dotS4(out, mat, 0, 5) + mat[9]; + const z = dotS4(out, mat, 0, 10) + mat[14]; + const w = dotS4(out, mat, 0, 15) + mat[19]; + return clampOut ? + setC4( + out, + clamp01(x), + clamp01(y), + clamp01(z), + clamp01(w) + ) : + setC4(out, x, y, z, w); + }; + +export const mulM45 = + (a: ColorMatrix, b: ColorMatrix): ColorMatrix => [ + dotS4(b, a, 0, 0, 1, 5), + dotS4(b, a, 0, 1, 1, 5), + dotS4(b, a, 0, 2, 1, 5), + dotS4(b, a, 0, 3, 1, 5), + dotS4(b, a, 0, 4, 1, 5) + b[4], + dotS4(b, a, 5, 0, 1, 5), + dotS4(b, a, 5, 1, 1, 5), + dotS4(b, a, 5, 2, 1, 5), + dotS4(b, a, 5, 3, 1, 5), + dotS4(b, a, 5, 4, 1, 5) + b[9], + dotS4(b, a, 10, 0, 1, 5), + dotS4(b, a, 10, 1, 1, 5), + dotS4(b, a, 10, 2, 1, 5), + dotS4(b, a, 10, 3, 1, 5), + dotS4(b, a, 10, 4, 1, 5) + b[14], + dotS4(b, a, 15, 0, 1, 5), + dotS4(b, a, 15, 1, 1, 5), + dotS4(b, a, 15, 2, 1, 5), + dotS4(b, a, 15, 3, 1, 5), + dotS4(b, a, 15, 4, 1, 5) + b[19], + ]; diff --git a/packages/color/src/internal/mulv.ts b/packages/color/src/internal/mulv.ts deleted file mode 100644 index 8030bf9709..0000000000 --- a/packages/color/src/internal/mulv.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { dotS3, dotS4 } from "@thi.ng/vectors3/dots"; -import { Color, ReadonlyColor, ColorMatrix } from "../api"; -import { clamp01 } from "@thi.ng/math/interval"; -import { setC4 } from "@thi.ng/vectors3/setc"; -import { ensureAlpha } from "./ensure-alpha"; - -export const mulV33 = - (out: Color, mat: number[], src: ReadonlyColor, clampOut = true) => { - const x = dotS3(mat, src, 0, 0, 3); - const y = dotS3(mat, src, 1, 0, 3); - const z = dotS3(mat, src, 2, 0, 3); - const a = ensureAlpha(src[3]); - return clampOut ? - setC4( - out || src, - clamp01(x), - clamp01(y), - clamp01(z), - a - ) : - setC4(out || src, x, y, z, a); - }; - -export const mulV45 = - (out: Color, mat: ColorMatrix, src: ReadonlyColor, clampOut = true) => { - const x = dotS4(src, mat, 0, 0) + mat[4]; - const y = dotS4(src, mat, 0, 5) + mat[9]; - const z = dotS4(src, mat, 0, 10) + mat[14]; - const w = dotS4(src, mat, 0, 15) + mat[19]; - return clampOut ? - setC4( - out || src, - clamp01(x), - clamp01(y), - clamp01(z), - clamp01(w) - ) : - setC4(out || src, x, y, z, w); - }; diff --git a/packages/color/src/matrix.ts b/packages/color/src/transform.ts similarity index 63% rename from packages/color/src/matrix.ts rename to packages/color/src/transform.ts index 289e48615a..dc63c343af 100644 --- a/packages/color/src/matrix.ts +++ b/packages/color/src/transform.ts @@ -1,7 +1,6 @@ import { mix } from "@thi.ng/math/mix"; -import { dotS4 } from "@thi.ng/vectors3/dots"; -import { ColorMatrix, RGB_LUMINANCE } from "./api"; -import { mulV45 } from "./internal/mulv"; +import { ColorMatrix, RGB_LUMINANCE, ReadonlyColor, WHITE } from "./api"; +import { mulV45, mulM45 } from "./internal/matrix-ops"; // https://drafts.fxtf.org/filter-effects/#feColorMatrixElement @@ -28,33 +27,25 @@ const S8 = 0.283; */ export const transform = mulV45; -export const mulMatrix = - (a: ColorMatrix, b: ColorMatrix): ColorMatrix => [ - dotS4(a, b, 0, 0, 1, 5), - dotS4(a, b, 0, 1, 1, 5), - dotS4(a, b, 0, 2, 1, 5), - dotS4(a, b, 0, 3, 1, 5), - dotS4(a, b, 0, 4, 1, 5) + a[4], - dotS4(a, b, 5, 0, 1, 5), - dotS4(a, b, 5, 1, 1, 5), - dotS4(a, b, 5, 2, 1, 5), - dotS4(a, b, 5, 3, 1, 5), - dotS4(a, b, 5, 4, 1, 5) + a[9], - dotS4(a, b, 10, 0, 1, 5), - dotS4(a, b, 10, 1, 1, 5), - dotS4(a, b, 10, 2, 1, 5), - dotS4(a, b, 10, 3, 1, 5), - dotS4(a, b, 10, 4, 1, 5) + a[14], - dotS4(a, b, 15, 0, 1, 5), - dotS4(a, b, 15, 1, 1, 5), - dotS4(a, b, 15, 2, 1, 5), - dotS4(a, b, 15, 3, 1, 5), - dotS4(a, b, 15, 4, 1, 5) + a[19], - ]; - -export const concatMatrices = +/** + * Concatenates given color matrices by pairwise multiplying them in + * left-right order. Returns combined result matrix to be used with + * `transform()`. + * + * Note: Using `concat()` is the recommended way when applying multiple + * color transformations in sequence. Since the transforms are combined + * into a single matrix, it is faster than multiple, individual + * `transform()` calls and will also produce more correct results, since + * result color clamping is only applied once at the end (by default, + * unless disabled). + * + * @see transform + * @param mat + * @param xs + */ +export const concat = (mat: ColorMatrix, ...xs: ColorMatrix[]) => - xs.reduce(mulMatrix, mat); + xs.reduce(mulM45, mat); export const IDENTITY: ColorMatrix = [ @@ -64,14 +55,31 @@ export const IDENTITY: ColorMatrix = 0, 0, 0, 1, 0 ]; -export const INVERT: ColorMatrix = - [ - -1, 0, 0, 0, 1, - 0, -1, 0, 0, 1, - 0, 0, -1, 0, 1, - 0, 0, 0, 1, 0 - ]; +/** + * Returns a transformation matrix which subtracts user color from given + * `src` color. With the default color white, this results in the + * inverted color. Does NOT modify alpha channel. + * + * @param src + */ +export const subtract = + (src: ReadonlyColor = WHITE): ColorMatrix => + [ + -1, 0, 0, 0, src[0], + 0, -1, 0, 0, src[1], + 0, 0, -1, 0, src[2], + 0, 0, 0, 1, 0 + ]; +/** + * Returns a transformation matrix which adds the given constant offset + * `x` to RGB channels. Does NOT modify alpha channel. + * + * If `x < 0` results in darker color. + * If `x > 0` results in brighter color. + * + * @param x + */ export const brightness = (x: number): ColorMatrix => [ @@ -108,7 +116,7 @@ export const saturation = 0, 0, 0, 1, 0 ]; -export const hueRotation = +export const hueRotate = (theta: number): ColorMatrix => { const s = Math.sin(theta); const c = Math.cos(theta); @@ -156,6 +164,13 @@ export const tint = 0, 0, 0, 1, 0 ]; +/** + * Returns transformation matrix which computes luminance of user color + * (optionally with custom coefficients). Does NOT modify alpha channel. + * + * @param x + * @param coeffs + */ export const grayscale = (x = 0, [r, g, b] = RGB_LUMINANCE): ColorMatrix => [ @@ -165,6 +180,13 @@ export const grayscale = 0, 0, 0, 1, 0 ]; +/** + * Returns transformation matrix which computes luminance of user color + * (optionally with custom coefficients), uses result as alpha channel + * and clears RGB channels (all set to zero). + * + * @param coeffs + */ export const luminanceAlpha = ([r, g, b] = RGB_LUMINANCE): ColorMatrix => [ From 445b8c1f9edd1b5d6e8e120cc60a680b585cf33d Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 29 Dec 2018 15:49:12 +0000 Subject: [PATCH 111/333] feat(color): add luminance defmulti --- packages/color/src/luminance.ts | 52 ++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/packages/color/src/luminance.ts b/packages/color/src/luminance.ts index 2702cd56ff..69bab4cf93 100644 --- a/packages/color/src/luminance.ts +++ b/packages/color/src/luminance.ts @@ -1,14 +1,52 @@ +import { DEFAULT, defmulti, MultiFn1O } from "@thi.ng/defmulti"; +import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; import { dot3 } from "@thi.ng/vectors3/dot"; -import { INV8BIT, ReadonlyColor, RGB_LUMINANCE } from "./api"; +import { + ColorMode, + IColor, + INV8BIT, + ReadonlyColor, + RGB_LUMINANCE +} from "./api"; +import { convert } from "./convert"; export const luminanceRGB = (rgb: ReadonlyColor, weights = RGB_LUMINANCE) => dot3(rgb, weights); export const luminanceInt = - (rgb: number) => { - const r = (rgb >>> 16) & 0xff; - const g = (rgb >>> 8) & 0xff; - const b = rgb & 0xff; - return ((r * 76 + g * 150 + b * 29) >>> 3) * INV8BIT; - }; + (rgb: number) => ( + ((rgb >>> 16) & 0xff) * 76 + + ((rgb >>> 8) & 0xff) * 150 + + (rgb & 0xff) * 29 + ) * INV8BIT * INV8BIT; + +/** + * Multi-method to compute relative luminance from any supported input + * color format. Unless color already is an RGBA or ARGB int (plain or + * wrapped), it will first be converted to RGBA. + */ +export const luminance: MultiFn1O = + defmulti( + (col: any, mode) => + col.mode !== undefined ? + col.mode : + mode !== undefined ? + mode : + illegalArgs(`missing color mode`) + ); + +luminance.add( + ColorMode.RGBA, + (x: ReadonlyColor) => luminanceRGB(x) +); + +luminance.add( + ColorMode.INT32, + (x: any) => luminanceInt(typeof x === "number" ? x : x.deref()) +); + +luminance.add( + DEFAULT, + (x: any, mode) => luminanceRGB(convert(x, ColorMode.RGBA, mode)) +); From aa303442f7f217779ee443c9faabb0095f536065 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 29 Dec 2018 15:51:14 +0000 Subject: [PATCH 112/333] feat(color): add convert() fallback, minor other updates --- packages/color/src/api.ts | 5 +++ packages/color/src/convert.ts | 43 +++++++++++++++----------- packages/color/src/cosine-gradients.ts | 7 +++++ packages/color/src/parse-css.ts | 2 +- packages/color/src/rgba-xyza.ts | 6 ++-- packages/color/src/xyza-rgba.ts | 2 +- 6 files changed, 42 insertions(+), 23 deletions(-) diff --git a/packages/color/src/api.ts b/packages/color/src/api.ts index 227b2d663b..6149319205 100644 --- a/packages/color/src/api.ts +++ b/packages/color/src/api.ts @@ -29,6 +29,11 @@ export const enum ColorMode { YCBCRA } +/** + * Reverse lookup for `ColorMode` enums + */ +export const __ColorMode = (exports).ColorMode; + export interface IColor { readonly mode: ColorMode; } diff --git a/packages/color/src/convert.ts b/packages/color/src/convert.ts index 7825cf098e..45d7bd10b5 100644 --- a/packages/color/src/convert.ts +++ b/packages/color/src/convert.ts @@ -1,12 +1,19 @@ -import { defmulti, Implementation3, MultiFn2O } from "@thi.ng/defmulti"; +import { + DEFAULT, + defmulti, + Implementation3, + MultiFn2O +} from "@thi.ng/defmulti"; import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; import { + __ColorMode, Color, ColorConversion, ColorMode, IColor, ReadonlyColor } from "./api"; +import { hcyaRgba } from "./hcya-rgba"; import { hsiaRgba } from "./hsia-rgba"; import { hslaCss } from "./hsla-css"; import { hslaHsva } from "./hsla-hsva"; @@ -16,7 +23,7 @@ import { hsvaHsla } from "./hsva-hsla"; import { hsvaRgba } from "./hsva-rgba"; import { int32Css } from "./int-css"; import { int32Rgba } from "./int-rgba"; -import { parseCss } from "./parse-css"; +import { parseCSS } from "./parse-css"; import { rgbaCss } from "./rgba-css"; import { rgbaHcya } from "./rgba-hcya"; import { rgbaHsia } from "./rgba-hsia"; @@ -27,21 +34,27 @@ import { rgbaXyza } from "./rgba-xyza"; import { rgbaYcbcra } from "./rgba-ycbcra"; import { xyzaRgba } from "./xyza-rgba"; import { ycbcraRgba } from "./ycbcra-rgba"; -import { hcyaRgba } from "./hcya-rgba"; export const convert: MultiFn2O = defmulti( - (col, mdest, msrc) => - (col).mode !== undefined ? - `${mdest}-${(col).mode}` : + (col: any, mdest, msrc) => + col.mode !== undefined ? + `${mdest}-${col.mode}` : msrc !== undefined ? `${mdest}-${msrc}` : illegalArgs(`missing src color mode`) ); +convert.add( + DEFAULT, + (col: any, mdest, msrc) => + (col.mode !== undefined && col.mode === mdest) || (mdest === msrc) ? + col : + illegalArgs(`missing conversion for ${__ColorMode[msrc]} -> ${__ColorMode[mdest]}`) +); -export function asCss(col: IColor): string; -export function asCss(col: string | number | ReadonlyColor, mode: ColorMode): string; -export function asCss(col: any, mode?: ColorMode) { +export function asCSS(col: IColor): string; +export function asCSS(col: string | number | ReadonlyColor, mode: ColorMode): string; +export function asCSS(col: any, mode?: ColorMode) { return convert(col, ColorMode.CSS, mode); } @@ -92,20 +105,14 @@ const defConversion = ( src: ColorMode, impl: Implementation3 ) => - convert.add( - `${dest}-${src}`, - impl - ); + convert.add(`${dest}-${src}`, impl); const defConversions = ( src: ColorMode, toRGBA: ColorConversion, ...dest: ColorMode[] ) => { - defConversion( - ColorMode.RGBA, src, - (x: any) => toRGBA([], x) - ); + defConversion(ColorMode.RGBA, src, (x: any) => toRGBA([], x)); dest.forEach( (id) => defConversion( id, src, @@ -128,7 +135,7 @@ const defConversions = ( ].forEach( (id) => defConversion( id, ColorMode.CSS, - (x: string) => parseCss(x, id) + (x: string) => parseCSS(x, id) ) ); diff --git a/packages/color/src/cosine-gradients.ts b/packages/color/src/cosine-gradients.ts index 8107cbc240..2fb3f35a64 100644 --- a/packages/color/src/cosine-gradients.ts +++ b/packages/color/src/cosine-gradients.ts @@ -69,6 +69,13 @@ export const cosineCoeffs = ]; }; +/** + * Multi-color cosine gradient generator, based on + * thi.ng/transducers/interpolate. + * + * @param n + * @param stops + */ export const multiCosineGradient = (n: number, ...stops: [number, ReadonlyColor][]) => interpolate( diff --git a/packages/color/src/parse-css.ts b/packages/color/src/parse-css.ts index e92481c70a..61d0b772b3 100644 --- a/packages/color/src/parse-css.ts +++ b/packages/color/src/parse-css.ts @@ -9,7 +9,7 @@ import { IDeref } from "@thi.ng/api/api"; const RE_HEX = /^#?([0-9a-f]{3,8})$/i; const RE_CSS = /^(rgb|hsl)a?\(\s*([0-9.]+?),\s*([0-9.]+%?),\s*([0-9.]+%?),?\s*([0-9.]+)?\s*\)$/; -export const parseCss = +export const parseCSS = (col: string | IDeref, mode = ColorMode.RGBA) => { col = typeof col === "string" ? col : col.deref(); let res: Color | number; diff --git a/packages/color/src/rgba-xyza.ts b/packages/color/src/rgba-xyza.ts index 62cc5ce62c..4c3103bd3a 100644 --- a/packages/color/src/rgba-xyza.ts +++ b/packages/color/src/rgba-xyza.ts @@ -1,13 +1,13 @@ import { Color, ReadonlyColor, RGB_XYZ } from "./api"; import { clamp } from "./clamp"; -import { mulV33 } from "./internal/mulv"; +import { mulV33 } from "./internal/matrix-ops"; import { ensureAlpha } from "./internal/ensure-alpha"; /** * https://en.wikipedia.org/wiki/CIE_1931_color_space - * + * * @param out - * @param src + * @param src */ export const rgbaXyza = (out: Color, src: ReadonlyColor) => { diff --git a/packages/color/src/xyza-rgba.ts b/packages/color/src/xyza-rgba.ts index 0be8df5a9f..1c4eb31855 100644 --- a/packages/color/src/xyza-rgba.ts +++ b/packages/color/src/xyza-rgba.ts @@ -1,5 +1,5 @@ import { Color, ReadonlyColor, XYZ_RGB } from "./api"; -import { mulV33 } from "./internal/mulv"; +import { mulV33 } from "./internal/matrix-ops"; /** * https://en.wikipedia.org/wiki/CIE_1931_color_space From 9d4fffa113807bd9cf1fe2012ec1734d04e51199 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 29 Dec 2018 15:51:44 +0000 Subject: [PATCH 113/333] build(color): add package keywords --- packages/color/package.json | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/color/package.json b/packages/color/package.json index 33fb3506af..c6aa8d581e 100644 --- a/packages/color/package.json +++ b/packages/color/package.json @@ -37,8 +37,26 @@ "@thi.ng/vectors3": "^0.0.1" }, "keywords": [ - "ES6", + "alpha", + "blending", + "CSS", + "CIE1931", "color", + "conversion", + "cosine", + "ES6", + "filter", + "gradient", + "HCY", + "HSL", + "HSV", + "HSI", + "matrix", + "porter-duff", + "RGB", + "sRGB", + "XYZ", + "YCbCr", "typescript" ], "publishConfig": { From 172f50707df8148cbd6c508edfa45144b8da9c02 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 29 Dec 2018 15:56:28 +0000 Subject: [PATCH 114/333] docs(color): update readme --- packages/color/README.md | 57 ++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/packages/color/README.md b/packages/color/README.md index e214b9e9f4..06dd2be666 100644 --- a/packages/color/README.md +++ b/packages/color/README.md @@ -10,7 +10,7 @@ This project is part of the - [About](#about) - - [Color modes](#color-modes) + - [Color spaces / modes](#color-spaces--modes) - [RGBA transformations](#rgba-transformations) - [RGBA Porter-Duff compositing](#rgba-porter-duff-compositing) - [Cosine gradients](#cosine-gradients) @@ -25,7 +25,13 @@ This project is part of the ## About -### Color modes +Raw, array-based, color operations, conversions and optional type +wrappers. The functions provided by this package are largely using the +same calling convention as those in the +[@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3) +package. + +### Color spaces / modes Fast color space conversions (any direction) between: @@ -39,16 +45,17 @@ Fast color space conversions (any direction) between: - XYZA (float4, aka CIE 1931) - YCbCr (float4) -Apart from `CSS` and `Int32` colors, all others can be stored as plain, -typed or custom array-like types of (mostly) normalized values (`[0,1]` -interval). Where applicable, the hue too is stored in that range, NOT in -degrees. +Apart from `CSS` and `Int32` colors, all others can be stored as plain +arrays, typed array or custom array-like types of (mostly) normalized +values (`[0,1]` interval). Where applicable, the hue too is stored in +that range, NOT in degrees. Apart from conversions, most other operations provided by this package -are only supporting RGBA colors. These can also be converted to/from -sRGB (i.e. linear vs gamma corrected). Additionally, RGBA colors can be -pre-multiplied (and post-multiplied) with their alpha channel (see -[Porter-Duff](#rgba-porter-duff-compositing) section below). +are currently only supporting RGBA colors. These can also be converted +to / from sRGB (i.e. linear vs gamma corrected). Additionally, RGBA +colors can be pre-multiplied (and post-multiplied) with their alpha +channel (see [Porter-Duff](#rgba-porter-duff-compositing) section +below). #### Class wrappers @@ -57,8 +64,8 @@ space. These wrappers act similarly to the `Vec2/3/4` wrappers in [@thi.ng/vectors](https://github.com/thi-ng/umbrella/tree/master/packages/vectors3), support striding (for mapped memory views), named channel accessor aliases (in addition to array indexing) and are fully compatible with -all other functions. Wrapper factory functions are provided for -convenience. +all functions (and act as syntax sugar for generic conversion +functions). Wrapper factory functions are provided for convenience. ### RGBA transformations @@ -75,11 +82,11 @@ including parametric preset transforms: - sepia (w/ fade amount) - tint (green / purple) - grayscale (luminance aware) -- invert (also available as non-matrix op) +- subtraction/inversion (also available as non-matrix op) - luminance to alpha -Matrix transforms can be combined using matrix multiplication / -concatenation (`mulMatrix()` / `concatMatrices`). +Transformation matrices can be combined using matrix multiplication / +concatenation (`concat()`) for more efficient application. ### RGBA Porter-Duff compositing @@ -124,8 +131,9 @@ The following presets are bundled (in [`cosine-gradients.ts`](https://github.com ### Multi-stop gradients -The `multiCosineGradient()` function returns an iterator of RGBA colors -based on given gradient stops. This iterator computes a cosine gradient between each color stop and yields a sequence of RGBA values. +The `multiCosineGradient()` function returns an iterator of raw RGBA +colors based on given gradient stops. This iterator computes a cosine +gradient between each color stop and yields a sequence of RGBA values. ```ts const gradient = col.multiCosineGradient( @@ -181,15 +189,20 @@ const a = col.asRGBA(col.css("#3cf")); const b = col.parseCss("hsla(30,100%,50%,0.75)", col.ColorMode.RGBA); // [ 1, 0.5, 0, 0.75 ] -// route #3: convert() multi-method: HSVA -> RGBA +// route #3: convert() multi-method: CSS -> RGBA -> HSVA +// (see convert.ts) const c = col.convert("rgb(0,255,255)", col.ColorMode.HSVA, col.ColorMode.CSS); // [ 0.4999999722222268, 0.9999990000010001, 1, 1 ] -// route #4: direct conversion -col.rgbaHsla([], [1,0.5,0,1]) +// route #4: direct conversion RGBA -> HSLA -> CSS +// first arg is output color (same calling convention as @thi.ng/vectors) +// (use `null` to mutate the input color) +col.hslaCss(col.rgbaHsla([], [1, 0.5, 0.5, 1])) +// "hsl(0.00,100.00%,75.00%)" -col.luminanceRGB(a) -// 0.6434 +col.luminance(col.css("white")) +col.luminance(0xffffff, col.ColorMode.INT32) +// 1 // apply color matrix (RGBA only) col.transform([], col.saturation(1.25), a) From e7bb46b74a49d04af945c8f5f82e0079e4a6765d Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 29 Dec 2018 18:37:25 +0000 Subject: [PATCH 115/333] feat(color): add Hue enum, closestHue*() fns, namedHueRgba() --- packages/color/src/api.ts | 23 +++++++++++++++++++---- packages/color/src/closest-hue.ts | 20 ++++++++++++++++++++ packages/color/src/hue-rgba.ts | 6 +++++- 3 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 packages/color/src/closest-hue.ts diff --git a/packages/color/src/api.ts b/packages/color/src/api.ts index 6149319205..949091e6b7 100644 --- a/packages/color/src/api.ts +++ b/packages/color/src/api.ts @@ -53,8 +53,25 @@ export const YELLOW = Object.freeze([1, 1, 0, 1]); export const RGB_LUMINANCE = [0.299, 0.587, 0.114]; -export const SRGB_GAMMA = 1.0 / 2.2; -export const SRGB_INVERSE_GAMMA = 2.2; +// Hue names + +export enum Hue { + RED, + ORANGE, + YELLOW, + CHARTREUSE, + GREEN, + SPRING_GREEN, + CYAN, + AZURE, + BLUE, + VIOLET, + MAGENTA, + ROSE +} + +// internal helpers + export const SRGB_ALPHA = 0.055; export const RGB_XYZ = [ @@ -69,8 +86,6 @@ export const XYZ_RGB = [ 0.0556434, -0.2040259, 1.0572252 ]; -// internal helpers - export const FF = float(2); export const PC = percent(2); export const INV8BIT = 1 / 0xff; diff --git a/packages/color/src/closest-hue.ts b/packages/color/src/closest-hue.ts new file mode 100644 index 0000000000..6d8aeea5c3 --- /dev/null +++ b/packages/color/src/closest-hue.ts @@ -0,0 +1,20 @@ +import { Hue } from "./api"; +import { ensureHue } from "./internal/ensure-hue"; + +/** + * Returns the `Hue` constant of the closest of 12 defined hues. + * + * @param h hue + */ +export const closestHue = + (h: number): Hue => + Math.round(ensureHue(h) * 12) % 12; + +/** + * Returns the `Hue` constant of the closest primary or secondary hue. + * + * @param h + */ +export const closestPrimaryHue = + (h: number): Hue => + (Math.round(ensureHue(h) * 12) % 12) & 0xe; diff --git a/packages/color/src/hue-rgba.ts b/packages/color/src/hue-rgba.ts index 76b70b5273..5e01aea0ad 100644 --- a/packages/color/src/hue-rgba.ts +++ b/packages/color/src/hue-rgba.ts @@ -1,6 +1,6 @@ import { clamp01 } from "@thi.ng/math/interval"; import { setC4 } from "@thi.ng/vectors3/setc"; -import { Color } from "./api"; +import { Color, Hue } from "./api"; import { ensureHue } from "./internal/ensure-hue"; /** @@ -21,3 +21,7 @@ export const hueRgba = alpha ); }; + +export const namedHueRgba = + (out: Color, hue: Hue, alpha = 1) => + hueRgba(out, hue / 12, alpha); From b849bd1b1f113f61b5df06e3e02fc0d8dbb834b2 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 29 Dec 2018 18:38:59 +0000 Subject: [PATCH 116/333] feat(color): add alpha()/setAlpha(), add docs, re-exports, update readme --- packages/color/README.md | 43 ++++++++++++++------------ packages/color/src/alpha.ts | 16 ++++++++++ packages/color/src/cosine-gradients.ts | 28 ++++++++++++++--- packages/color/src/index.ts | 5 +++ packages/color/src/invert.ts | 11 +++++++ 5 files changed, 79 insertions(+), 24 deletions(-) create mode 100644 packages/color/src/alpha.ts diff --git a/packages/color/README.md b/packages/color/README.md index 06dd2be666..106fef9f38 100644 --- a/packages/color/README.md +++ b/packages/color/README.md @@ -15,6 +15,7 @@ This project is part of the - [RGBA Porter-Duff compositing](#rgba-porter-duff-compositing) - [Cosine gradients](#cosine-gradients) - [Multi-stop gradients](#multi-stop-gradients) +- [Status](#status) - [Installation](#installation) - [Dependencies](#dependencies) - [Usage examples](#usage-examples) @@ -35,7 +36,7 @@ package. Fast color space conversions (any direction) between: -- CSS (string, hex3/hex4/hex6/hex8, `rgba()`, `hsla()`, named colors) +- CSS (string, hex3/hex4/hex6/hex8, rgba(), hsla(), named colors) - HCYA (float4) - HSIA (float4) - HSLA (float4) @@ -136,30 +137,34 @@ colors based on given gradient stops. This iterator computes a cosine gradient between each color stop and yields a sequence of RGBA values. ```ts -const gradient = col.multiCosineGradient( +col.multiCosineGradient( // num colors to produce 10, // gradient stops (normalized positions, only RGBA colors supported) [0.1, col.RED], [0.5, col.GREEN], [0.9, col.BLUE] -); - -for(let c of gradient) { - console.log(col.rgbaCss(c)); -} - -// #ff0000 -// #ff0000 -// #da2500 -// #807f00 -// #25da00 -// #00ff00 -// #00da25 -// #00807f -// #0025da -// #0000ff -// #0000ff +) +// convert to CSS +.map(col.rgbaCss) + +// [ +// "#ff0000", +// "#ff0000", +// "#da2500", +// "#807f00", +// "#25da00", +// "#00ff00", +// "#00da25", +// "#00807f", +// "#0025da", +// "#0000ff", +// "#0000ff", +// ] ``` +## Status + +ALPHA - work in progress + ## Installation ```bash diff --git a/packages/color/src/alpha.ts b/packages/color/src/alpha.ts new file mode 100644 index 0000000000..b79a6d7d33 --- /dev/null +++ b/packages/color/src/alpha.ts @@ -0,0 +1,16 @@ +import { setC4 } from "@thi.ng/vectors3/setc"; +import { Color, ReadonlyColor } from "./api"; + +export const alpha = + (src: ReadonlyColor) => + src[3] !== undefined ? src[3] : 1; + +export const setAlpha = + (out: Color, src: ReadonlyColor, alpha: number) => + setC4( + out || src, + src[0], + src[1], + src[2], + alpha + ); diff --git a/packages/color/src/cosine-gradients.ts b/packages/color/src/cosine-gradients.ts index 2fb3f35a64..669c28bb8a 100644 --- a/packages/color/src/cosine-gradients.ts +++ b/packages/color/src/cosine-gradients.ts @@ -56,6 +56,13 @@ export const cosineGradient = normRange(n - 1) ); +/** + * Returns coefficients to produce a cosine gradient between the two + * given RGBA colors. + * + * @param from + * @param to + */ export const cosineCoeffs = (from: ReadonlyColor, to: ReadonlyColor) => { from = clamp([], from); @@ -70,19 +77,30 @@ export const cosineCoeffs = }; /** - * Multi-color cosine gradient generator, based on - * thi.ng/transducers/interpolate. + * Multi-color cosine gradient generator using RGBA color stops. Returns + * an array of `n+1` color samples. + * + * ``` + * multiCosineGradient( + * // num colors to produce + * 10, + * // gradient stops (normalized positions) + * [0.1, [1, 0, 0, 1]], [0.5, [0, 1, 0, 1]], [0.9, [0, 0, 1, 1]] + * ) + * ``` + * + * @see thi.ng/transducers/iter/interpolate * * @param n * @param stops */ export const multiCosineGradient = - (n: number, ...stops: [number, ReadonlyColor][]) => - interpolate( + (n: number, ...stops: [number, ReadonlyColor][]): Color[] => + [...interpolate( n, 0, 1, cosineCoeffs, cosineColor, ...stops - ); + )]; diff --git a/packages/color/src/index.ts b/packages/color/src/index.ts index bbbbdd2fec..413f74e6bb 100644 --- a/packages/color/src/index.ts +++ b/packages/color/src/index.ts @@ -39,8 +39,13 @@ export * from "./rgba"; export * from "./xyza"; export * from "./ycbcr"; +export * from "./alpha"; +export * from "./clamp"; +export * from "./closest-hue"; export * from "./cosine-gradients"; export * from "./invert"; export * from "./luminance"; +export * from "./mix"; export * from "./porter-duff"; +export * from "./premultiply"; export * from "./transform"; diff --git a/packages/color/src/invert.ts b/packages/color/src/invert.ts index 400854da52..eb4cfb44bb 100644 --- a/packages/color/src/invert.ts +++ b/packages/color/src/invert.ts @@ -3,11 +3,22 @@ import { sub3 } from "@thi.ng/vectors3/sub"; import { Color, ReadonlyColor } from "./api"; import { clamp } from "./clamp"; +/** + * Inverts the RGB channels of an RGBA color. + * + * @param out + * @param src + */ export const invertRGB = (out: Color, src: ReadonlyColor) => ( out = clamp(out || src, src), sub3(out, ONE3, out) ); +/** + * Inverts the lowest 24 bits of an ARGB int. + * + * @param src + */ export const invertInt = (src: number) => src ^ 0xffffff; From 784f5c34d110d8cc39dfa925070d779a788cc291 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 29 Dec 2018 18:43:06 +0000 Subject: [PATCH 117/333] build: update deps --- packages/color/package.json | 2 +- packages/vectors2/package.json | 2 +- packages/vectors3/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/color/package.json b/packages/color/package.json index c6aa8d581e..8ddb372089 100644 --- a/packages/color/package.json +++ b/packages/color/package.json @@ -33,7 +33,7 @@ "@thi.ng/defmulti": "^0.5.1", "@thi.ng/errors": "^0.1.12", "@thi.ng/strings": "^0.7.1", - "@thi.ng/transducers": "^2.2.7", + "@thi.ng/transducers": "^2.3.1", "@thi.ng/vectors3": "^0.0.1" }, "keywords": [ diff --git a/packages/vectors2/package.json b/packages/vectors2/package.json index 0dfe6c1b80..664abf219a 100644 --- a/packages/vectors2/package.json +++ b/packages/vectors2/package.json @@ -36,7 +36,7 @@ "@thi.ng/math": "^0.2.2", "@thi.ng/random": "^0.1.1", "@thi.ng/strings": "^0.7.1", - "@thi.ng/transducers": "^2.2.8" + "@thi.ng/transducers": "^2.3.1" }, "keywords": [ "ES6", diff --git a/packages/vectors3/package.json b/packages/vectors3/package.json index 876035c360..b424f19b87 100644 --- a/packages/vectors3/package.json +++ b/packages/vectors3/package.json @@ -34,7 +34,7 @@ "@thi.ng/errors": "^0.1.12", "@thi.ng/math": "^0.2.2", "@thi.ng/random": "^0.1.1", - "@thi.ng/transducers": "^2.2.8" + "@thi.ng/transducers": "^2.3.1" }, "keywords": [ "algebra", From dc6f4661a64afac7514a39540da28ec375afe11d Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 00:30:19 +0000 Subject: [PATCH 118/333] refactor(vectors): add defMathOp()/defMathNOp(), update basic math ops --- packages/vectors3/src/add.ts | 7 ++----- packages/vectors3/src/addn.ts | 7 ++----- packages/vectors3/src/div.ts | 7 ++----- packages/vectors3/src/divn.ts | 7 ++----- packages/vectors3/src/internal/codegen.ts | 17 ++++++++++++++++- packages/vectors3/src/internal/templates.ts | 11 ++++++++++- packages/vectors3/src/mul.ts | 7 ++----- packages/vectors3/src/muln.ts | 7 ++----- packages/vectors3/src/sub.ts | 7 ++----- packages/vectors3/src/subn.ts | 7 ++----- 10 files changed, 42 insertions(+), 42 deletions(-) diff --git a/packages/vectors3/src/add.ts b/packages/vectors3/src/add.ts index bb7d12a9fb..68bdc2d755 100644 --- a/packages/vectors3/src/add.ts +++ b/packages/vectors3/src/add.ts @@ -1,6 +1,3 @@ -import { MultiVecOpVV, VecOpVV } from "./api"; -import { defOp } from "./internal/codegen"; -import { MATH } from "./internal/templates"; +import { defMathOp } from "./internal/codegen"; -export const [add, add2, add3, add4] = - defOp(MATH("+")); +export const [add, add2, add3, add4] = defMathOp("+"); diff --git a/packages/vectors3/src/addn.ts b/packages/vectors3/src/addn.ts index c86530310a..9c4c98b0fa 100644 --- a/packages/vectors3/src/addn.ts +++ b/packages/vectors3/src/addn.ts @@ -1,6 +1,3 @@ -import { MultiVecOpVN, VecOpVN } from "./api"; -import { defOp } from "./internal/codegen"; -import { MATH_N } from "./internal/templates"; +import { defMathNOp } from "./internal/codegen"; -export const [addN, addN2, addN3, addN4] = - defOp(MATH_N("+"), "o,a,n"); +export const [addN, addN2, addN3, addN4] = defMathNOp("+"); diff --git a/packages/vectors3/src/div.ts b/packages/vectors3/src/div.ts index 1ac6b113b5..034bdfd8e3 100644 --- a/packages/vectors3/src/div.ts +++ b/packages/vectors3/src/div.ts @@ -1,6 +1,3 @@ -import { MultiVecOpVV, VecOpVV } from "./api"; -import { defOp } from "./internal/codegen"; -import { MATH } from "./internal/templates"; +import { defMathOp } from "./internal/codegen"; -export const [div, div2, div3, div4] = - defOp(MATH("/")); +export const [div, div2, div3, div4] = defMathOp("/"); diff --git a/packages/vectors3/src/divn.ts b/packages/vectors3/src/divn.ts index 1c44c438a3..4ba8f37dbb 100644 --- a/packages/vectors3/src/divn.ts +++ b/packages/vectors3/src/divn.ts @@ -1,6 +1,3 @@ -import { MultiVecOpVN, VecOpVN } from "./api"; -import { defOp } from "./internal/codegen"; -import { MATH_N } from "./internal/templates"; +import { defMathNOp } from "./internal/codegen"; -export const [divN, divN2, divN3, divN4] = - defOp(MATH_N("/"), "o,a,n"); +export const [divN, divN2, divN3, divN4] = defMathNOp("/"); diff --git a/packages/vectors3/src/internal/codegen.ts b/packages/vectors3/src/internal/codegen.ts index 676b8b1146..5782695076 100644 --- a/packages/vectors3/src/internal/codegen.ts +++ b/packages/vectors3/src/internal/codegen.ts @@ -6,11 +6,20 @@ import { transduce } from "@thi.ng/transducers/transduce"; import { map } from "@thi.ng/transducers/xform/map"; import { mapIndexed } from "@thi.ng/transducers/xform/map-indexed"; import { take } from "@thi.ng/transducers/xform/take"; -import { FN } from "./templates"; +import { + MultiVecOpVN, + MultiVecOpVV, + VecOpVN, + VecOpVV +} from "../api"; +import { FN, MATH, MATH_N } from "./templates"; import { vop } from "./vop"; export const ARGS_V = "o,a"; export const ARGS_VV = "o,a,b"; +export const ARGS_VVV = "o,a,b,c"; +export const ARGS_VN = "o,a,n"; +export const ARGS_VVN = "o,a,b,n"; export const SARGS_V = "io=0,ia=0,so=1,sa=1"; export const SARGS_VV = "io=0,ia=0,ib=0,so=1,sa=1,sb=1"; @@ -250,3 +259,9 @@ export const defOpS = ( sizes.map( (dim) => compile(dim, tpl, args, syms, ret, "", pre != null ? pre : defaultOut(ret, args), "", true) ); + +export const defMathOp = + (op: string) => defOp(MATH(op)); + +export const defMathNOp = + (op: string) => defOp(MATH_N(op), ARGS_VN); diff --git a/packages/vectors3/src/internal/templates.ts b/packages/vectors3/src/internal/templates.ts index 093c00e839..760ab87e4a 100644 --- a/packages/vectors3/src/internal/templates.ts +++ b/packages/vectors3/src/internal/templates.ts @@ -1,8 +1,17 @@ export const MATH = (op: string) => ([o, a, b]) => `${o}=${a}${op}${b};` export const MATH_N = (op: string) => ([o, a]) => `${o}=${a}${op}n;` export const FN = (op: string) => ([o, a]) => `${o}=${op}(${a});` +export const FN2 = (op: string) => ([o, a, b]) => `${o}=${op}(${a},${b});` +export const FN_N = (op: string) => ([o, a]) => `${o}=${op}(${a},n);` export const DOT = ([a, b]) => `${a}*${b}`; -export const DOT_G = ([a, b]) => `sum+=${a}*${b};`; +export const DOT_G = ([a, b]) => `s+=${a}*${b};`; export const SET = ([o, a]) => `${o}=${a};`; export const SET_N = ([a]) => `${a}=n;` + +export const HOF_VVV = ([o, a, b, c]) => `${o}=op(${a},${b},${c});`; + +export const MADD = ([o, a, b, c]) => `${o}=${a}+${b}*${c};`; +export const MADD_N = ([o, a, b]) => `${o}=${a}+${b}*n;`; +export const MIX = ([o, a, b, c]) => `${o}=${a}+(${b}-${a})*${c};`; +export const MIX_N = ([o, a, b]) => `${o}=${a}+(${b}-${a})*n;` diff --git a/packages/vectors3/src/mul.ts b/packages/vectors3/src/mul.ts index 9755527c5b..6dc31c562e 100644 --- a/packages/vectors3/src/mul.ts +++ b/packages/vectors3/src/mul.ts @@ -1,6 +1,3 @@ -import { MultiVecOpVV, VecOpVV } from "./api"; -import { defOp } from "./internal/codegen"; -import { MATH } from "./internal/templates"; +import { defMathOp } from "./internal/codegen"; -export const [mul, mul2, mul3, mul4] = - defOp(MATH("*")); +export const [mul, mul2, mul3, mul4] = defMathOp("*"); diff --git a/packages/vectors3/src/muln.ts b/packages/vectors3/src/muln.ts index efc8480649..f7019a269a 100644 --- a/packages/vectors3/src/muln.ts +++ b/packages/vectors3/src/muln.ts @@ -1,6 +1,3 @@ -import { MultiVecOpVN, VecOpVN } from "./api"; -import { defOp } from "./internal/codegen"; -import { MATH_N } from "./internal/templates"; +import { defMathNOp } from "./internal/codegen"; -export const [mulN, mulN2, mulN3, mulN4] = - defOp(MATH_N("*"), "o,a,n"); +export const [mulN, mulN2, mulN3, mulN4] = defMathNOp("*"); diff --git a/packages/vectors3/src/sub.ts b/packages/vectors3/src/sub.ts index e4696d8172..4dfbf570ec 100644 --- a/packages/vectors3/src/sub.ts +++ b/packages/vectors3/src/sub.ts @@ -1,6 +1,3 @@ -import { MultiVecOpVV, VecOpVV } from "./api"; -import { defOp } from "./internal/codegen"; -import { MATH } from "./internal/templates"; +import { defMathOp } from "./internal/codegen"; -export const [sub, sub2, sub3, sub4] = - defOp(MATH("-")); +export const [sub, sub2, sub3, sub4] = defMathOp("-"); diff --git a/packages/vectors3/src/subn.ts b/packages/vectors3/src/subn.ts index 560bbb60f4..e8f49e9235 100644 --- a/packages/vectors3/src/subn.ts +++ b/packages/vectors3/src/subn.ts @@ -1,6 +1,3 @@ -import { MultiVecOpVN, VecOpVN } from "./api"; -import { defOp } from "./internal/codegen"; -import { MATH_N } from "./internal/templates"; +import { defMathNOp } from "./internal/codegen"; -export const [subN, subN2, subN3, subN4] = - defOp(MATH_N("-"), "o,a,n"); +export const [subN, subN2, subN3, subN4] = defMathNOp("-"); From 6857f3475cf62e03480739fe0824deb7087d3ad1 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 00:31:43 +0000 Subject: [PATCH 119/333] feat(vectors): add clamp01(), clamp11() fns --- packages/vectors3/src/clamp.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/vectors3/src/clamp.ts b/packages/vectors3/src/clamp.ts index 9cd30708a3..aa37e07294 100644 --- a/packages/vectors3/src/clamp.ts +++ b/packages/vectors3/src/clamp.ts @@ -1,10 +1,13 @@ -import { clamp as _clamp } from "@thi.ng/math/interval"; +import { clamp as _clamp, clamp01 as _clamp01, clamp11 as _clamp11 } from "@thi.ng/math/interval"; import { MultiVecOpVVV, VecOpVVV } from "./api"; -import { defHofOp } from "./internal/codegen"; +import { ARGS_VVV, defHofOp } from "./internal/codegen"; +import { HOF_VVV } from "./internal/templates"; export const [clamp, clamp2, clamp3, clamp4] = - defHofOp( - _clamp, - ([o, a, b, c]) => `${o}=op(${a},${b},${c});`, - "o,a,b,c" - ); + defHofOp(_clamp, HOF_VVV, ARGS_VVV); + +export const [clamp01, clamp01_2, clamp01_3, clamp01_4] = + defHofOp(_clamp01, HOF_VVV, ARGS_VVV); + +export const [clamp11, clamp11_2, clamp11_3, clamp11_4] = + defHofOp(_clamp11, HOF_VVV, ARGS_VVV); From 809bf9b945c13338de03a7941ffbff675bab4c7b Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 00:32:51 +0000 Subject: [PATCH 120/333] refactor(vectors): rename dotValues*() => dotC*() --- .../vectors3/src/{dot-values.ts => dotc.ts} | 18 ++++++++++++------ packages/vectors3/src/index.ts | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) rename packages/vectors3/src/{dot-values.ts => dotc.ts} (62%) diff --git a/packages/vectors3/src/dot-values.ts b/packages/vectors3/src/dotc.ts similarity index 62% rename from packages/vectors3/src/dot-values.ts rename to packages/vectors3/src/dotc.ts index df82496786..5225c97099 100644 --- a/packages/vectors3/src/dot-values.ts +++ b/packages/vectors3/src/dotc.ts @@ -1,35 +1,41 @@ /** - * Returns pairwise product sum of args (in order). + * Returns pairwise product sum of given components. * * @param a * @param b * @param c * @param d */ -export const dotValues4 = +export const dotC4 = (a: number, b: number, c: number, d: number) => a * b + c * d; /** - * Returns pairwise product sum of args (in order). + * Returns pairwise product sum of given components. * * @param a * @param b * @param c * @param d + * @param e + * @param f */ -export const dotValues6 = +export const dotC6 = (a: number, b: number, c: number, d: number, e: number, f: number) => a * b + c * d + e * f; /** - * Returns pairwise product sum of args (in order). + * Returns pairwise product sum of given components. * * @param a * @param b * @param c * @param d + * @param e + * @param f + * @param g + * @param h */ -export const dotValues8 = +export const dotC8 = (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => a * b + c * d + e * f + g * h; diff --git a/packages/vectors3/src/index.ts b/packages/vectors3/src/index.ts index 356357f299..901a50a789 100644 --- a/packages/vectors3/src/index.ts +++ b/packages/vectors3/src/index.ts @@ -32,8 +32,8 @@ export * from "./div"; export * from "./divn"; export * from "./divs"; export * from "./dot"; +export * from "./dotc"; export * from "./dots"; -export * from "./dot-values"; export * from "./empty"; export * from "./eqdelta"; export * from "./exp"; From 9b789bcaa17fff920a022af56182e743ec10af98 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 00:37:40 +0000 Subject: [PATCH 121/333] refactor(vectors): simplify various ops, use setC*() --- packages/vectors3/src/cartesian.ts | 13 ++++---- packages/vectors3/src/cross.ts | 17 +++++------ packages/vectors3/src/homogeneous.ts | 17 ++++------- packages/vectors3/src/perpendicular.ts | 17 ++--------- packages/vectors3/src/polar.ts | 17 ++++------- packages/vectors3/src/rotate-around-axis.ts | 12 ++++---- packages/vectors3/src/rotate-around-point.ts | 15 ++++++---- packages/vectors3/src/swizzle.ts | 31 +++++--------------- 8 files changed, 51 insertions(+), 88 deletions(-) diff --git a/packages/vectors3/src/cartesian.ts b/packages/vectors3/src/cartesian.ts index a55cfb0809..e2bc7cbe87 100644 --- a/packages/vectors3/src/cartesian.ts +++ b/packages/vectors3/src/cartesian.ts @@ -2,6 +2,7 @@ import { cossin } from "@thi.ng/math/angle"; import { MultiVecOpVO, ReadonlyVec, ZERO4 } from "./api"; import { vop } from "./internal/vop"; import { maddN } from "./maddn"; +import { setC3 } from "./setc"; const cos = Math.cos; const sin = Math.sin; @@ -43,14 +44,14 @@ export const cartesian2 = export const cartesian3 = cartesian.add(3, (out, a, b = ZERO4) => { - !out && (out = a); const r = a[0]; const theta = a[1]; const phi = a[2]; const ct = cos(theta); - - out[0] = r * ct * cos(phi) + b[0]; - out[1] = r * ct * sin(phi) + b[1]; - out[2] = r * sin(theta) + b[2]; - return out; + return setC3( + out || a, + r * ct * cos(phi) + b[0], + r * ct * sin(phi) + b[1], + r * sin(theta) + b[2] + ); }); diff --git a/packages/vectors3/src/cross.ts b/packages/vectors3/src/cross.ts index 5944897860..1491edd0e0 100644 --- a/packages/vectors3/src/cross.ts +++ b/packages/vectors3/src/cross.ts @@ -1,16 +1,15 @@ import { ReadonlyVec, Vec } from "./api"; +import { setC3 } from "./setc"; export const cross2 = (a: ReadonlyVec, b: ReadonlyVec) => a[0] * b[1] - a[1] * b[0]; export const cross3 = - (out: Vec, a: ReadonlyVec, b: ReadonlyVec) => { - !out && (out = a); - const x = a[1] * b[2] - a[2] * b[1]; - const y = a[2] * b[0] - a[0] * b[2]; - out[2] = a[0] * b[1] - a[1] * b[0]; - out[1] = y; - out[0] = x; - return a; - }; + (out: Vec, a: ReadonlyVec, b: ReadonlyVec) => + setC3( + out || a, + a[1] * b[2] - a[2] * b[1], + a[2] * b[0] - a[0] * b[2], + a[0] * b[1] - a[1] * b[0] + ); diff --git a/packages/vectors3/src/homogeneous.ts b/packages/vectors3/src/homogeneous.ts index dd33a1658b..1d98208bdd 100644 --- a/packages/vectors3/src/homogeneous.ts +++ b/packages/vectors3/src/homogeneous.ts @@ -1,24 +1,17 @@ import { MultiVecOpV } from "./api"; import { vop } from "./internal/vop"; +import { setC2, setC3 } from "./setc"; export const fromHomogeneous: MultiVecOpV = vop(1); export const fromHomogeneous3 = fromHomogeneous.add(3, - (out, [x, y, w]) => ( - !out && (out = []), - out[0] = x / w, - out[1] = y / w, - out - ) + (out, [x, y, w]) => + setC2(out || [], x / w, y / w) ); export const fromHomogeneous4 = fromHomogeneous.add(4, - (out, [x, y, z, w]) => ( - !out && (out = []), - out[0] = x / w, - out[1] = y / w, - out[2] = z / w, out - ) + (out, [x, y, z, w]) => + setC3(out || [], x / w, y / w, z / w) ); diff --git a/packages/vectors3/src/perpendicular.ts b/packages/vectors3/src/perpendicular.ts index 180b6416f9..b478e4ac56 100644 --- a/packages/vectors3/src/perpendicular.ts +++ b/packages/vectors3/src/perpendicular.ts @@ -1,4 +1,5 @@ import { VecOpV } from "./api"; +import { setC2 } from "./setc"; /** * Produces a perpendicular vector to `v`, i.e. `[-y,x]`. @@ -7,13 +8,7 @@ import { VecOpV } from "./api"; * @param v */ export const perpendicularLeft2: VecOpV = - (out, a) => { - !out && (out = a); - const x = a[0]; - out[0] = -a[1]; - out[1] = x; - return out; - }; + (out, a) => setC2(out || a, -a[1], a[0]); /** * Produces a perpendicular vector to `v`, i.e. `[y,-x]`. @@ -22,10 +17,4 @@ export const perpendicularLeft2: VecOpV = * @param v */ export const perpendicularRight2: VecOpV = - (out, a) => { - !out && (out = a); - const x = -a[0]; - out[0] = a[1]; - out[1] = x; - return out; - }; + (out, a) => setC2(out || a, a[1], -a[0]); diff --git a/packages/vectors3/src/polar.ts b/packages/vectors3/src/polar.ts index f06b482c48..7fafdba5ce 100644 --- a/packages/vectors3/src/polar.ts +++ b/packages/vectors3/src/polar.ts @@ -1,6 +1,7 @@ import { MultiVecOpV } from "./api"; import { vop } from "./internal/vop"; import { mag } from "./mag"; +import { setC2, setC3 } from "./setc"; const sqrt = Math.sqrt; const asin = Math.asin; @@ -23,13 +24,9 @@ export const polar: MultiVecOpV = vop(1); * @param out * @param v */ -export const polar2 = polar.add(2, (out, a) => { - !out && (out = a); - const x = a[0]; - out[0] = mag(a); - out[1] = atan2(a[1], x); - return out; -}); +export const polar2 = polar.add(2, (out, a) => + setC2(out || a, mag(a), atan2(a[1], a[0])) +); /** * Converts 3D cartesian vector `v` to spherical coordinates, i.e. @@ -40,13 +37,9 @@ export const polar2 = polar.add(2, (out, a) => { * @param v */ export const polar3 = polar.add(3, (out, a) => { - !out && (out = a); const x = a[0]; const y = a[1]; const z = a[2]; const r = sqrt(x * x + y * y + z * z); - out[0] = r; - out[1] = asin(z / r); - out[2] = atan2(y, x); - return out; + return setC3(out || a, r, asin(z / r), atan2(y, x)); }); diff --git a/packages/vectors3/src/rotate-around-axis.ts b/packages/vectors3/src/rotate-around-axis.ts index 60bf727f8e..e77f28178f 100644 --- a/packages/vectors3/src/rotate-around-axis.ts +++ b/packages/vectors3/src/rotate-around-axis.ts @@ -1,4 +1,5 @@ import { ReadonlyVec, Vec } from "./api"; +import { setC3 } from "./setc"; export const rotateAroundAxis3 = (out: Vec, v: ReadonlyVec, axis: ReadonlyVec, theta: number) => { @@ -20,9 +21,10 @@ export const rotateAroundAxis3 = const uvw = ux + vy + wz; const s = Math.sin(theta); const c = Math.cos(theta); - - out[0] = ax * uvw + (x * (ay * ay + az * az) - ax * (vy + wz)) * c + (-wy + vz) * s; - out[1] = ay * uvw + (y * (ax * ax + az * az) - ay * (ux + wz)) * c + (wx - uz) * s; - out[2] = az * uvw + (z * (ax * ax + ay * ay) - az * (ux + vy)) * c + (-vx + uy) * s; - return v; + return setC3( + out || v, + ax * uvw + (x * (ay * ay + az * az) - ax * (vy + wz)) * c + (-wy + vz) * s, + ay * uvw + (y * (ax * ax + az * az) - ay * (ux + wz)) * c + (wx - uz) * s, + az * uvw + (z * (ax * ax + ay * ay) - az * (ux + vy)) * c + (-vx + uy) * s + ); }; diff --git a/packages/vectors3/src/rotate-around-point.ts b/packages/vectors3/src/rotate-around-point.ts index f460d01152..e1bcd294e9 100644 --- a/packages/vectors3/src/rotate-around-point.ts +++ b/packages/vectors3/src/rotate-around-point.ts @@ -1,12 +1,15 @@ import { VecOpVVN } from "./api"; +import { setC2 } from "./setc"; export const rotateAroundPoint2: VecOpVVN = - (out, a, b, theta) => { - const x = a[0] - b[0]; - const y = a[1] - b[1]; + (out, v, p, theta) => { + const x = v[0] - p[0]; + const y = v[1] - p[1]; const s = Math.sin(theta); const c = Math.cos(theta); - out[0] = x * c - y * s + b[0]; - out[1] = x * s + y * c + b[1]; - return out; + return setC2( + out || v, + x * c - y * s + p[0], + x * s + y * c + p[1] + ); }; diff --git a/packages/vectors3/src/swizzle.ts b/packages/vectors3/src/swizzle.ts index a71b75c463..4cd0f49e23 100644 --- a/packages/vectors3/src/swizzle.ts +++ b/packages/vectors3/src/swizzle.ts @@ -1,4 +1,5 @@ import { ReadonlyVec, Vec, VecOpV } from "./api"; +import { setC2, setC3, setC4 } from "./setc"; /** * Places a re-ordered 2D version of vector `a` into `out`. The given @@ -10,12 +11,8 @@ import { ReadonlyVec, Vec, VecOpV } from "./api"; * @param y new y coord index */ export const swizzle2 = - (out: Vec, a: ReadonlyVec, x: number, y: number) => ( - x = a[x] || 0, - out[1] = a[y] || 0, - out[0] = x, - out - ); + (out: Vec, a: ReadonlyVec, x: number, y: number) => + setC2(out || a, a[x] || 0, a[y] || 0); /** * Places a re-ordered 3D version of vector `a` into `out`. The given @@ -28,14 +25,8 @@ export const swizzle2 = * @param z new z coord index */ export const swizzle3 = - (out: Vec, a: ReadonlyVec, x: number, y: number, z: number) => ( - x = a[x] || 0, - y = a[y] || 0, - out[2] = a[z] || 0, - out[1] = y, - out[0] = x, - out - ); + (out: Vec, a: ReadonlyVec, x: number, y: number, z: number) => + setC3(out || a, a[x] || 0, a[y] || 0, a[z] || 0); /** * Places a re-ordered 4D version of vector `a` into `out`. The given @@ -49,16 +40,8 @@ export const swizzle3 = * @param w new w coord index */ export const swizzle4 = - (out: Vec, a: ReadonlyVec, x: number, y: number, z: number, w: number) => ( - x = a[x] || 0, - y = a[y] || 0, - z = a[z] || 0, - out[3] = a[w] || 0, - out[2] = z, - out[1] = y, - out[0] = x, - out - ); + (out: Vec, a: ReadonlyVec, x: number, y: number, z: number, w: number) => + setC4(out || a, a[x] || 0, a[y] || 0, a[z] || 0, a[w] || 0); export const swapXY: VecOpV = (out, v) => swizzle3(out, v, 1, 0, 2); From 6b3608da963c568ff2e5965db5d42b674f6ad5a6 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 00:40:38 +0000 Subject: [PATCH 122/333] fix(vectors): sum() impls --- packages/vectors3/src/sum.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/vectors3/src/sum.ts b/packages/vectors3/src/sum.ts index d13b73217b..ec12b5eeb3 100644 --- a/packages/vectors3/src/sum.ts +++ b/packages/vectors3/src/sum.ts @@ -13,5 +13,5 @@ export const sum: MultiVecOpRoV = vop(0); sum.default((v) => reduce(add(), v)); export const sum2 = sum.add(2, (a) => a[0] + a[1]); -export const sum3 = sum.add(2, (a) => a[0] + a[1] + a[2]); -export const sum4 = sum.add(2, (a) => a[0] + a[1] + a[2] + a[3]); +export const sum3 = sum.add(3, (a) => a[0] + a[1] + a[2]); +export const sum4 = sum.add(4, (a) => a[0] + a[1] + a[2] + a[3]); From cfe333fe6db46ca60bb1e4fb879198c2cb84fbd7 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 00:51:30 +0000 Subject: [PATCH 123/333] refactor(vectors): simplify various ops, improve tpl re-use --- packages/vectors3/src/internal/codegen.ts | 2 ++ packages/vectors3/src/madd.ts | 8 +++----- packages/vectors3/src/maddn.ts | 8 +++----- packages/vectors3/src/mix.ts | 8 +++----- packages/vectors3/src/mixn.ts | 8 +++----- packages/vectors3/src/modn.ts | 4 ++-- packages/vectors3/src/pow.ts | 3 ++- packages/vectors3/src/pown.ts | 5 +++-- packages/vectors3/src/round.ts | 3 ++- packages/vectors3/src/smoothstep.ts | 8 +++++--- packages/vectors3/src/step.ts | 8 +++++--- packages/vectors3/src/wrap.ts | 9 +++------ 12 files changed, 36 insertions(+), 38 deletions(-) diff --git a/packages/vectors3/src/internal/codegen.ts b/packages/vectors3/src/internal/codegen.ts index 5782695076..514362289c 100644 --- a/packages/vectors3/src/internal/codegen.ts +++ b/packages/vectors3/src/internal/codegen.ts @@ -25,6 +25,8 @@ export const SARGS_V = "io=0,ia=0,so=1,sa=1"; export const SARGS_VV = "io=0,ia=0,ib=0,so=1,sa=1,sb=1"; export const SARGS_VVV = "io=0,ia=0,ib=0,ic=0,so=1,sa=1,sb=1,sc=1"; +export const DEFAULT_OUT = "!o&&(o=a);"; + export type Template = (syms: string[], i?: number) => string; /** diff --git a/packages/vectors3/src/madd.ts b/packages/vectors3/src/madd.ts index 6095caa3d6..b69f4d3d46 100644 --- a/packages/vectors3/src/madd.ts +++ b/packages/vectors3/src/madd.ts @@ -1,11 +1,9 @@ import { MultiVecOpVVV, VecOpVVV } from "./api"; -import { defOp } from "./internal/codegen"; +import { ARGS_VVV, defOp } from "./internal/codegen"; +import { MADD } from "./internal/templates"; /** * Returns `out = a + b * c`. */ export const [madd, madd2, madd3, madd4] = - defOp( - ([o, a, b, c]) => `${o}=${a}+${b}*${c};`, - "o,a,b,c" - ); + defOp(MADD, ARGS_VVV); diff --git a/packages/vectors3/src/maddn.ts b/packages/vectors3/src/maddn.ts index f8d05b2b44..1e067a5835 100644 --- a/packages/vectors3/src/maddn.ts +++ b/packages/vectors3/src/maddn.ts @@ -1,11 +1,9 @@ import { MultiVecOpVVN, VecOpVVN } from "./api"; -import { defOp } from "./internal/codegen"; +import { ARGS_VVN, defOp } from "./internal/codegen"; +import { MADD_N } from "./internal/templates"; /** * Returns `out = a + b * n`. */ export const [maddN, maddN2, maddN3, maddN4] = - defOp( - ([o, a, b]) => `${o}=${a}+${b}*n;`, - "o,a,b,n" - ); + defOp(MADD_N, ARGS_VVN); diff --git a/packages/vectors3/src/mix.ts b/packages/vectors3/src/mix.ts index 09b3b8a8b2..fcbee18af0 100644 --- a/packages/vectors3/src/mix.ts +++ b/packages/vectors3/src/mix.ts @@ -1,8 +1,6 @@ import { MultiVecOpVVV, VecOpVVV } from "./api"; -import { defOp } from "./internal/codegen"; +import { ARGS_VVV, defOp } from "./internal/codegen"; +import { MIX } from "./internal/templates"; export const [mix, mix2, mix3, mix4] = - defOp( - ([o, a, b, c]) => `${o}=${a}+(${b}-${a})*${c};`, - "o,a,b,c" - ); + defOp(MIX, ARGS_VVV); diff --git a/packages/vectors3/src/mixn.ts b/packages/vectors3/src/mixn.ts index 2c1015353a..79b355f13d 100644 --- a/packages/vectors3/src/mixn.ts +++ b/packages/vectors3/src/mixn.ts @@ -1,8 +1,6 @@ import { MultiVecOpVVN, VecOpVVN } from "./api"; -import { defOp } from "./internal/codegen"; +import { ARGS_VVN, defOp } from "./internal/codegen"; +import { MIX_N } from "./internal/templates"; export const [mixN, mixN2, mixN3, mixN4] = - defOp( - ([o, a, b]) => `${o}=${a}+(${b}-${a})*n;`, - "o,a,b,n" - ); + defOp(MIX_N, ARGS_VVN); diff --git a/packages/vectors3/src/modn.ts b/packages/vectors3/src/modn.ts index d047fe8f53..4f570a719e 100644 --- a/packages/vectors3/src/modn.ts +++ b/packages/vectors3/src/modn.ts @@ -1,5 +1,5 @@ import { MultiVecOpVN, VecOpVN } from "./api"; -import { defOp } from "./internal/codegen"; +import { ARGS_VN, defOp } from "./internal/codegen"; export const [modN, modN2, modN3, modN4] = - defOp(([o, a]) => `${o}=${a}%n;`, "o,a,n"); + defOp(([o, a]) => `${o}=${a}%n;`, ARGS_VN); diff --git a/packages/vectors3/src/pow.ts b/packages/vectors3/src/pow.ts index 2c8be0fade..40cbdb9ad0 100644 --- a/packages/vectors3/src/pow.ts +++ b/packages/vectors3/src/pow.ts @@ -1,5 +1,6 @@ import { MultiVecOpVV, VecOpVV } from "./api"; import { defOp } from "./internal/codegen"; +import { FN2 } from "./internal/templates"; export const [pow, pow2, pow3, pow4] = - defOp(([o, a, b]) => `${o}=Math.pow(${a},${b});`); + defOp(FN2("Math.pow")); diff --git a/packages/vectors3/src/pown.ts b/packages/vectors3/src/pown.ts index fa29c44a2d..8097f72810 100644 --- a/packages/vectors3/src/pown.ts +++ b/packages/vectors3/src/pown.ts @@ -1,5 +1,6 @@ import { MultiVecOpVN, VecOpVN } from "./api"; -import { defOp } from "./internal/codegen"; +import { ARGS_VN, defOp } from "./internal/codegen"; +import { FN_N } from "./internal/templates"; export const [powN, powN2, powN3, powN4] = - defOp(([o, a]) => `${o}=Math.pow(${a},n);`, "o,a,n"); + defOp(FN_N("Math.pow"), ARGS_VN); diff --git a/packages/vectors3/src/round.ts b/packages/vectors3/src/round.ts index 0a6942216f..502619937a 100644 --- a/packages/vectors3/src/round.ts +++ b/packages/vectors3/src/round.ts @@ -1,11 +1,12 @@ import { roundTo as _round } from "@thi.ng/math/prec"; import { MultiVecOpVO, VecOpVO } from "./api"; import { defHofOp } from "./internal/codegen"; +import { FN_N } from "./internal/templates"; export const [round, round2, round3, round4] = defHofOp, VecOpVO>( _round, - ([o, a]) => `${o}=op(${a},n);`, + FN_N("op"), "o,a,n=1", "o,a" ); diff --git a/packages/vectors3/src/smoothstep.ts b/packages/vectors3/src/smoothstep.ts index d2ea556d7d..9c40958728 100644 --- a/packages/vectors3/src/smoothstep.ts +++ b/packages/vectors3/src/smoothstep.ts @@ -1,6 +1,7 @@ import { smoothStep as _step } from "@thi.ng/math/step"; import { MultiVecOpV, VecOpV } from "./api"; -import { defHofOp } from "./internal/codegen"; +import { DEFAULT_OUT, defHofOp } from "./internal/codegen"; +import { HOF_VVV } from "./internal/templates"; /** * Like GLSL `smoothstep()` @@ -13,9 +14,10 @@ import { defHofOp } from "./internal/codegen"; export const [smoothStep, smoothStep2, smoothStep3, smoothStep4] = defHofOp( _step, - ([o, e1, e2, a]) => `${o}=op(${e1},${e2},${a});`, + HOF_VVV, "o,e1,e2,a", undefined, "o", - 3 + 3, + DEFAULT_OUT ); diff --git a/packages/vectors3/src/step.ts b/packages/vectors3/src/step.ts index 2e22dc8151..08e84de9d2 100644 --- a/packages/vectors3/src/step.ts +++ b/packages/vectors3/src/step.ts @@ -1,6 +1,7 @@ import { step as _step } from "@thi.ng/math/step"; import { MultiVecOpV, VecOpV } from "./api"; -import { defHofOp } from "./internal/codegen"; +import { DEFAULT_OUT, defHofOp } from "./internal/codegen"; +import { FN2 } from "./internal/templates"; /** * Like GLSL `step()` @@ -12,9 +13,10 @@ import { defHofOp } from "./internal/codegen"; export const [step, step2, step3, step4] = defHofOp( _step, - ([o, e, a]) => `${o}=op(${e},${a});`, + FN2("op"), "o,e,a", undefined, "o", - 2 + 2, + DEFAULT_OUT ); diff --git a/packages/vectors3/src/wrap.ts b/packages/vectors3/src/wrap.ts index 64e5dd68a5..81e0c6feb8 100644 --- a/packages/vectors3/src/wrap.ts +++ b/packages/vectors3/src/wrap.ts @@ -1,10 +1,7 @@ import { wrap as _wrap } from "@thi.ng/math/interval"; import { MultiVecOpVVV, VecOpVVV } from "./api"; -import { defHofOp } from "./internal/codegen"; +import { ARGS_VVV, defHofOp } from "./internal/codegen"; +import { HOF_VVV } from "./internal/templates"; export const [wrap, wrap2, wrap3, wrap4] = - defHofOp( - _wrap, - ([o, a, b, c]) => `${o}=op(${a},${b},${c});`, - "o,a,b,c" - ); + defHofOp(_wrap, HOF_VVV, ARGS_VVV); From 745053c5e4029cfce0470c8f91d526c24d26d86e Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 00:56:12 +0000 Subject: [PATCH 124/333] refactor(vector): minor updates arg/result handling --- packages/vectors3/src/distsq.ts | 8 ++++---- packages/vectors3/src/dot.ts | 2 +- packages/vectors3/src/face-forward.ts | 4 +++- packages/vectors3/src/gvec.ts | 5 +++-- packages/vectors3/src/limit.ts | 6 +++--- packages/vectors3/src/normalize.ts | 6 +++--- packages/vectors3/src/ortho-normal.ts | 8 ++++---- packages/vectors3/src/refract.ts | 1 + packages/vectors3/src/rotate.ts | 4 +++- 9 files changed, 25 insertions(+), 19 deletions(-) diff --git a/packages/vectors3/src/distsq.ts b/packages/vectors3/src/distsq.ts index 5d6ced5926..d358c664b0 100644 --- a/packages/vectors3/src/distsq.ts +++ b/packages/vectors3/src/distsq.ts @@ -2,18 +2,18 @@ import { MultiVecOpRoVV } from "./api"; import { compile, compileG } from "./internal/codegen"; import { vop } from "./internal/vop"; -const tpl = ([a, b]) => `t=${a}-${b};sum+=t*t;`; -const pre = "let t,sum=0;"; +const tpl = ([a, b]) => `t=${a}-${b};s+=t*t;`; +const pre = "let t,s=0;"; const $ = (dim: number) => distSq.add( dim, - compile(dim, tpl, "a,b", undefined, "sum", "", pre) + compile(dim, tpl, "a,b", undefined, "s", "", pre) ); export const distSq: MultiVecOpRoVV = vop(); -distSq.default(compileG(tpl, "a,b", undefined, "sum", pre)); +distSq.default(compileG(tpl, "a,b", undefined, "s", pre)); export const distSq2 = $(2); export const distSq3 = $(3); diff --git a/packages/vectors3/src/dot.ts b/packages/vectors3/src/dot.ts index b6a0bfb64f..187b8913b1 100644 --- a/packages/vectors3/src/dot.ts +++ b/packages/vectors3/src/dot.ts @@ -21,7 +21,7 @@ const $ = (dim: number) => export const dot: MultiVecOpRoVV = vop(); dot.default( - compileG(DOT_G, "a,b", undefined, "sum", "let sum=0;") + compileG(DOT_G, "a,b", undefined, "s", "let s=0;") ); export const dot2 = $(2); diff --git a/packages/vectors3/src/face-forward.ts b/packages/vectors3/src/face-forward.ts index 9a7c5edf7f..e317a4283a 100644 --- a/packages/vectors3/src/face-forward.ts +++ b/packages/vectors3/src/face-forward.ts @@ -7,6 +7,8 @@ export const faceForward: VecOpVVV = (out, n, i, nref) => { !out && (out = n); return dot(nref, i) < 0 ? - out === n ? out : set(out, n) : + out !== n ? + set(out, n) : + out : mulN(out, n, -1); }; diff --git a/packages/vectors3/src/gvec.ts b/packages/vectors3/src/gvec.ts index 701355e35c..fbaaa7ff7f 100644 --- a/packages/vectors3/src/gvec.ts +++ b/packages/vectors3/src/gvec.ts @@ -13,8 +13,9 @@ const L = "length"; const O = "offset"; const S = "stride"; -const keys = memoize1((size: number) => - [...map(String, range(size)), L, O, S]); +const keys = memoize1( + (size: number) => [...map(String, range(size)), L, O, S] +); /** * Wrapper for strided, arbitrary length vectors. Wraps given buffer in diff --git a/packages/vectors3/src/limit.ts b/packages/vectors3/src/limit.ts index bce2ea6ad8..40dd78d14d 100644 --- a/packages/vectors3/src/limit.ts +++ b/packages/vectors3/src/limit.ts @@ -9,7 +9,7 @@ export const limit = const m = mag(v); return m > n ? mulN(out, v, n / m) : - out === v ? - out : - set(out, v); + out !== v ? + set(out, v) : + out; }; diff --git a/packages/vectors3/src/normalize.ts b/packages/vectors3/src/normalize.ts index c9e1499741..4f837684fd 100644 --- a/packages/vectors3/src/normalize.ts +++ b/packages/vectors3/src/normalize.ts @@ -18,7 +18,7 @@ export const normalize: VecOpVO = const m = mag(v); return m >= EPS ? mulN(out, v, n / m) : - out === v ? - out : - set(out, v); + out !== v ? + set(out, v) : + out; }; diff --git a/packages/vectors3/src/ortho-normal.ts b/packages/vectors3/src/ortho-normal.ts index ee76c27976..45403346db 100644 --- a/packages/vectors3/src/ortho-normal.ts +++ b/packages/vectors3/src/ortho-normal.ts @@ -20,7 +20,7 @@ import { Vec, ReadonlyVec } from "./api"; * @param normalize */ export const orthoNormal3 = - (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, doNormalize = true) => ( - cross3(out, sub3(out, b, a), sub3([], c, a)), - doNormalize ? normalize(out, out) : out - ); + (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, doNormalize = true) => { + out = cross3(null, sub3(out || a, b, a), sub3([], c, a)); + return doNormalize ? normalize(out, out) : out; + }; diff --git a/packages/vectors3/src/refract.ts b/packages/vectors3/src/refract.ts index 16d2ebfd0e..7d439a5850 100644 --- a/packages/vectors3/src/refract.ts +++ b/packages/vectors3/src/refract.ts @@ -6,6 +6,7 @@ import { zero } from "./setn"; export const refract: VecOpVVN = (out, a, n, eta) => { + !out && (out = a); const d = dot(a, n); const k = 1 - eta * eta * (1 - d * d); return k < 0 ? diff --git a/packages/vectors3/src/rotate.ts b/packages/vectors3/src/rotate.ts index 239e9f6e85..df891e68fb 100644 --- a/packages/vectors3/src/rotate.ts +++ b/packages/vectors3/src/rotate.ts @@ -4,11 +4,13 @@ import { set } from "./set"; const _rotate = (u: number, v: number): VecOpVN => (out, a, theta) => { + out ? + (out !== a && set(out, a)) : + (out = a); const s = Math.sin(theta); const c = Math.cos(theta); const x = a[u]; const y = a[v]; - out !== a && set(out, a); out[u] = x * c - y * s; out[v] = x * s + y * c; return out; From 06dd9634ba1d9d9abe3a776c0cc1df6c571bfb05 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 00:56:46 +0000 Subject: [PATCH 125/333] fix(vectors): result handling jitter()/project() --- packages/vectors3/src/jitter.ts | 2 +- packages/vectors3/src/project.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/vectors3/src/jitter.ts b/packages/vectors3/src/jitter.ts index d473a82525..b3bbfc4f94 100644 --- a/packages/vectors3/src/jitter.ts +++ b/packages/vectors3/src/jitter.ts @@ -6,4 +6,4 @@ import { randNorm } from "./random"; export const jitter = (out: Vec, a: ReadonlyVec, n = 1, rnd: IRandom = SYSTEM) => - add(out, randNorm(new Array(a.length), n, rnd), a); + add(out, a, randNorm(new Array(a.length), n, rnd)); diff --git a/packages/vectors3/src/project.ts b/packages/vectors3/src/project.ts index 183e654250..358c08b218 100644 --- a/packages/vectors3/src/project.ts +++ b/packages/vectors3/src/project.ts @@ -8,9 +8,9 @@ import { mulN } from "./muln"; * * https://en.wikipedia.org/wiki/Vector_projection * - * @param dir * @param v + * @param dir */ export const project = - (out: Vec, dir: ReadonlyVec, v: ReadonlyVec) => - mulN(out, dir, dot(v, dir) / magSq(dir)); + (out: Vec, v: ReadonlyVec, dir: ReadonlyVec) => + mulN(out || v, dir, dot(v, dir) / magSq(dir)); From b03b9192af6997b32ea290f2d4732348db57b2ad Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 01:02:17 +0000 Subject: [PATCH 126/333] feat(matrices): add quaternion fns --- packages/matrices/src/alignment-quat.ts | 19 +++++++++++++++++ packages/matrices/src/conjugate.ts | 14 +++++++++++++ packages/matrices/src/mixq.ts | 23 +++++++++++++++++++++ packages/matrices/src/quat-axis-angle.ts | 24 ++++++++++++++++++++++ packages/matrices/src/quat-euler.ts | 23 +++++++++++++++++++++ packages/matrices/src/quat-m44.ts | 26 ++++++++++++++++++++++++ 6 files changed, 129 insertions(+) create mode 100644 packages/matrices/src/alignment-quat.ts create mode 100644 packages/matrices/src/conjugate.ts create mode 100644 packages/matrices/src/mixq.ts create mode 100644 packages/matrices/src/quat-axis-angle.ts create mode 100644 packages/matrices/src/quat-euler.ts create mode 100644 packages/matrices/src/quat-m44.ts diff --git a/packages/matrices/src/alignment-quat.ts b/packages/matrices/src/alignment-quat.ts new file mode 100644 index 0000000000..2f2a116b28 --- /dev/null +++ b/packages/matrices/src/alignment-quat.ts @@ -0,0 +1,19 @@ +import { ReadonlyVec } from "@thi.ng/vectors3/api"; +import { normalize as _normalize } from "@thi.ng/vectors3/normalize"; +import { cross3 } from "@thi.ng/vectors3/cross"; +import { quatFromAxisAngle } from "./quat-axis-angle"; +import { dot3 } from "@thi.ng/vectors3/dot"; +import { mag } from "@thi.ng/vectors3/mag"; + +export const alignmentQuat = + (from: ReadonlyVec, to: ReadonlyVec, normalize = true) => { + if (normalize) { + from = _normalize([], from); + to = _normalize([], to); + } + const axis = cross3([], from, to); + return quatFromAxisAngle( + axis, + Math.atan2(mag(axis), dot3(from, to)) + ) + }; diff --git a/packages/matrices/src/conjugate.ts b/packages/matrices/src/conjugate.ts new file mode 100644 index 0000000000..9ddda8e39d --- /dev/null +++ b/packages/matrices/src/conjugate.ts @@ -0,0 +1,14 @@ +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { setC4 } from "@thi.ng/vectors3/setc"; + +export const conjugateQ = + (out: Vec, a: ReadonlyVec) => + setC4( + out || a, + -a[0], + -a[1], + -a[2], + a[3] + ); + + diff --git a/packages/matrices/src/mixq.ts b/packages/matrices/src/mixq.ts new file mode 100644 index 0000000000..04832bf342 --- /dev/null +++ b/packages/matrices/src/mixq.ts @@ -0,0 +1,23 @@ +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { dot4 } from "@thi.ng/vectors3/dot"; +import { maddN4 } from "@thi.ng/vectors3/maddn"; +import { mulN4 } from "@thi.ng/vectors3/muln"; +import { set4 } from "@thi.ng/vectors3/set"; + +export const mixQ = + (out: Vec, a: ReadonlyVec, b: ReadonlyVec, t: number, eps = 1e-3) => { + const d = dot4(a, b); + if (Math.abs(d) < 1.0) { + const theta = Math.acos(d); + const stheta = Math.sqrt(1 - d * d); + let u: number, v: number; + if (Math.abs(stheta) < eps) { + u = v = 0.5; + } else { + u = Math.sin(theta * (1 - t)) / stheta; + v = Math.sin(theta * t) / stheta; + } + return maddN4(null, mulN4(out, a, u), b, v); + } + return a !== out ? set4(out, a) : out; + }; diff --git a/packages/matrices/src/quat-axis-angle.ts b/packages/matrices/src/quat-axis-angle.ts new file mode 100644 index 0000000000..4dfab4d9e7 --- /dev/null +++ b/packages/matrices/src/quat-axis-angle.ts @@ -0,0 +1,24 @@ +import { EPS } from "@thi.ng/math/api"; +import { ReadonlyVec } from "@thi.ng/vectors3/api"; +import { normalize } from "@thi.ng/vectors3/normalize"; + +export const quatFromAxisAngle = + (axis: ReadonlyVec, theta: number) => { + theta /= 2; + return normalize( + [0, 0, 0, Math.cos(theta)], + axis, + Math.sin(theta) + ); + }; + +export const quatToAxisAngle = + (quat: ReadonlyVec) => { + const n = normalize([], quat); + const w = n[3]; + const m = Math.sqrt(1 - w * w); + const theta = 2 * Math.acos(w); + return m > EPS ? + [[n[0] / m, n[1] / m, n[2] / m], theta] : + [[n[0], n[1], n[2]], theta]; + }; diff --git a/packages/matrices/src/quat-euler.ts b/packages/matrices/src/quat-euler.ts new file mode 100644 index 0000000000..52fd557fa4 --- /dev/null +++ b/packages/matrices/src/quat-euler.ts @@ -0,0 +1,23 @@ +import { X3, Y3, Z3 } from "@thi.ng/vectors3/api"; +import { mulQ } from "./mul"; +import { quatFromAxisAngle } from "./quat-axis-angle"; + +const axisOrder = { + "xyz": [X3, Y3, Z3], + "yxz": [Y3, X3, Z3], + "xzy": [X3, Z3, Y3], + "zxy": [Z3, X3, Y3], + "yzx": [Y3, Z3, X3], + "zyx": [Z3, Y3, X3], +}; + +export const quatFromEuler = + (order: keyof typeof axisOrder, a: number, b: number, c: number) => { + const [aa, ab, ac] = axisOrder[order]; + return mulQ(null, + mulQ([], + quatFromAxisAngle(aa, a), + quatFromAxisAngle(ab, b)), + quatFromAxisAngle(ac, c) + ); + }; diff --git a/packages/matrices/src/quat-m44.ts b/packages/matrices/src/quat-m44.ts new file mode 100644 index 0000000000..43d720b5cb --- /dev/null +++ b/packages/matrices/src/quat-m44.ts @@ -0,0 +1,26 @@ +import { ReadonlyVec, Vec, ZERO3 } from "@thi.ng/vectors3/api"; +import { setC } from "@thi.ng/vectors3/setc"; + +export const quatToMat44 = + (out: Vec, a: ReadonlyVec, t: ReadonlyVec = ZERO3) => { + const { 0: x, 1: y, 2: z, 3: w } = a; + const x2 = x + x; + const y2 = y + y; + const z2 = z + z; + const xx = x * x2; + const xy = x * y2; + const xz = x * z2; + const yy = y * y2; + const yz = y * z2; + const zz = z * z2; + const wx = w * x2; + const wy = w * y2; + const wz = w * z2; + return setC( + out || [], + 1 - (yy + zz), xy + wz, xz - wy, 0, + xy - wz, 1 - (xx + zz), yz + wx, 0, + xz + wy, yz - wx, 1 - (xx + yy), 0, + t[0], t[1], t[2], 1 + ); + }; From b5adea6f3677b4c4960e6d038f63ad5a56d0e563 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 01:13:07 +0000 Subject: [PATCH 127/333] refactor(matrices): replace setValues*() w/ setC*(), update dotC*() use --- packages/matrices/src/determinant.ts | 6 +- packages/matrices/src/frustum.ts | 6 +- packages/matrices/src/invert.ts | 43 +++++--- packages/matrices/src/lookat.ts | 6 +- packages/matrices/src/mul.ts | 49 ++++++---- packages/matrices/src/mulv.ts | 98 +++++++++++-------- packages/matrices/src/ortho.ts | 6 +- packages/matrices/src/project.ts | 4 +- packages/matrices/src/rotation-around-axis.ts | 8 +- packages/matrices/src/rotation.ts | 39 ++++---- packages/matrices/src/scale.ts | 23 ++--- packages/matrices/src/set-values.ts | 14 --- packages/matrices/src/set.ts | 2 +- packages/matrices/src/translation.ts | 7 +- packages/matrices/src/transpose.ts | 14 +-- 15 files changed, 173 insertions(+), 152 deletions(-) delete mode 100644 packages/matrices/src/set-values.ts diff --git a/packages/matrices/src/determinant.ts b/packages/matrices/src/determinant.ts index 620dd1ea73..72d66abd1c 100644 --- a/packages/matrices/src/determinant.ts +++ b/packages/matrices/src/determinant.ts @@ -1,8 +1,8 @@ -import { dotValues4, dotValues6 } from "@thi.ng/vectors3/dot-values"; +import { dotC4, dotC6 } from "@thi.ng/vectors3/dotc"; import { ReadonlyMat } from "./api"; -const dp4 = dotValues4; -const dp6 = dotValues6; +const dp4 = dotC4; +const dp6 = dotC6; export const det22 = (m: ReadonlyMat) => diff --git a/packages/matrices/src/frustum.ts b/packages/matrices/src/frustum.ts index a38afac27a..60023cf340 100644 --- a/packages/matrices/src/frustum.ts +++ b/packages/matrices/src/frustum.ts @@ -1,6 +1,6 @@ import { DEG2RAD } from "@thi.ng/math/api"; +import { setC } from "@thi.ng/vectors3/setc"; import { Mat } from "./api"; -import { setValues44 } from "./set-values"; export const frustum = ( out: Mat, @@ -15,8 +15,8 @@ export const frustum = ( const dy = 1 / (top - bottom); const dz = 1 / (far - near); - return setValues44( - out, + return setC( + out || [], near * 2 * dx, 0, 0, 0, 0, near * 2 * dy, 0, 0, (right + left) * dx, (top + bottom) * dy, -(far + near) * dz, -1, diff --git a/packages/matrices/src/invert.ts b/packages/matrices/src/invert.ts index 606e02a673..84ba6ce3c2 100644 --- a/packages/matrices/src/invert.ts +++ b/packages/matrices/src/invert.ts @@ -1,11 +1,13 @@ -import { dotValues4, dotValues6 } from "@thi.ng/vectors3/dot-values"; -import { MatOpM, MultiMatOpM } from "./api"; -import { setValues23, setValues22, setValues44, setValues33 } from "./set-values"; -import { detCoeffs44, det44FromCoeffs } from "./determinant"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { dotC4, dotC6 } from "@thi.ng/vectors3/dotc"; import { vop } from "@thi.ng/vectors3/internal/vop"; +import { magSq4 } from "@thi.ng/vectors3/magsq"; +import { setC, setC4 } from "@thi.ng/vectors3/setc"; +import { MatOpM, MultiMatOpM } from "./api"; +import { det44FromCoeffs, detCoeffs44 } from "./determinant"; -const dp4 = dotValues4; -const dp6 = dotValues6; +const dp4 = dotC4; +const dp6 = dotC6; export const invert: MultiMatOpM = vop(1); @@ -15,8 +17,8 @@ export const invert22: MatOpM = let det = dp4(m00, m11, -m01, m10); if (det === 0) return; det = 1.0 / det; - return setValues22( - out, + return setC4( + out || m, m11 * det, -m01 * det, -m10 * det, @@ -30,8 +32,8 @@ export const invert23: MatOpM = let det = dp4(m00, m11, -m01, m10); if (det === 0) return; det = 1.0 / det; - return setValues23( - out, + return setC( + out || m, m11 * det, -m01 * det, -m10 * det, @@ -50,8 +52,8 @@ export const invert33: MatOpM = let det = dp6(m00, d01, m01, d11, m02, d21); if (det === 0) return; det = 1.0 / det; - return setValues33( - out, + return setC( + out || m, d01 * det, dp4(-m22, m01, m02, m21) * det, dp4(m12, m01, -m02, m11) * det, @@ -72,8 +74,8 @@ export const invert44: MatOpM = det = 1.0 / det; const [m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33] = m; const [d00, d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11] = coeffs; - return setValues44( - out, + return setC( + out || m, dp6(m11, d11, -m12, d10, m13, d09) * det, dp6(-m01, d11, m02, d10, -m03, d09) * det, dp6(m31, d05, - m32, d04, m33, d03) * det, @@ -92,3 +94,16 @@ export const invert44: MatOpM = dp6(m20, d03, -m21, d01, m22, d00) * det ); }); + +export const invertQ = + (out: Vec, a: ReadonlyVec) => { + let d = magSq4(a); + d = d > 0 ? -1 / d : 0; + return setC4( + out || a, + a[0] * d, + a[1] * d, + a[2] * d, + a[3] * -d + ); + }; \ No newline at end of file diff --git a/packages/matrices/src/lookat.ts b/packages/matrices/src/lookat.ts index ac1ba2a838..31c0dc0afb 100644 --- a/packages/matrices/src/lookat.ts +++ b/packages/matrices/src/lookat.ts @@ -2,9 +2,9 @@ import { ReadonlyVec } from "@thi.ng/vectors3/api"; import { cross3 } from "@thi.ng/vectors3/cross"; import { dot3 } from "@thi.ng/vectors3/dot"; import { normalize } from "@thi.ng/vectors3/normalize"; +import { setC } from "@thi.ng/vectors3/setc"; import { sub3 } from "@thi.ng/vectors3/sub"; import { Mat } from "./api"; -import { setValues44 } from "./set-values"; export const lookAt = ( out: Mat, @@ -16,8 +16,8 @@ export const lookAt = ( const x = normalize(null, cross3([], up, z)); const y = normalize(null, cross3([], z, x)); - return setValues44( - out, + return setC( + out || [], x[0], y[0], z[0], 0, x[1], y[1], z[1], 0, x[2], y[2], z[2], 0, diff --git a/packages/matrices/src/mul.ts b/packages/matrices/src/mul.ts index 86704b25de..95e94b680c 100644 --- a/packages/matrices/src/mul.ts +++ b/packages/matrices/src/mul.ts @@ -1,41 +1,39 @@ +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; import { dotS2, dotS3, dotS4 } from "@thi.ng/vectors3/dots"; import { vop } from "@thi.ng/vectors3/internal/vop"; +import { setC, setC4 } from "@thi.ng/vectors3/setc"; import { MultiMatOpMM } from "./api"; -import { - setValues22, - setValues23, - setValues33, - setValues44 -} from "./set-values"; export const mul: MultiMatOpMM = vop(1); export const mul22 = mul.add(4, (out, a, b) => - setValues22( - out, + setC4( + out || a, dotS2(a, b, 0, 0, 2), dotS2(a, b, 1, 0, 2), dotS2(a, b, 0, 2, 2), dotS2(a, b, 1, 2, 2) - )); + ) + ); export const mul23 = mul.add(6, (out, a, b) => - setValues23( - out, + setC( + out || a, dotS2(a, b, 0, 0, 2), dotS2(a, b, 1, 0, 2), dotS2(a, b, 0, 2, 2), dotS2(a, b, 1, 2, 2), dotS2(a, b, 0, 4, 2) + a[4], dotS2(a, b, 1, 4, 2) + a[5] - )); + ) + ); export const mul33 = mul.add(9, (out, a, b) => - setValues33( - out, + setC( + out || a, dotS3(a, b, 0, 0, 3), dotS3(a, b, 1, 0, 3), dotS3(a, b, 2, 0, 3), @@ -45,12 +43,13 @@ export const mul33 = dotS3(a, b, 0, 6, 3), dotS3(a, b, 1, 6, 3), dotS3(a, b, 2, 6, 3) - )); + ) + ); export const mul44 = mul.add(16, (out, a, b) => - setValues44( - out, + setC( + out || a, dotS4(a, b, 0, 0, 4), dotS4(a, b, 1, 0, 4), dotS4(a, b, 2, 0, 4), @@ -67,4 +66,18 @@ export const mul44 = dotS4(a, b, 1, 12, 4), dotS4(a, b, 2, 12, 4), dotS4(a, b, 3, 12, 4) - )); + ) + ); + +export const mulQ = + (out: Vec, a: ReadonlyVec, b: ReadonlyVec) => { + const { 0: ax, 1: ay, 2: az, 3: aw } = a; + const { 0: bx, 1: by, 2: bz, 3: bw } = b; + return setC4( + out || a, + ax * bw + aw * bx + ay * bz - az * by, + ay * bw + aw * by + az * bx - ax * bz, + az * bw + aw * bz + ax * by - ay * bx, + aw * bw - ax * bx - ay * by - az * bz + ); + }; diff --git a/packages/matrices/src/mulv.ts b/packages/matrices/src/mulv.ts index d77190e05f..4d249a7ee5 100644 --- a/packages/matrices/src/mulv.ts +++ b/packages/matrices/src/mulv.ts @@ -1,6 +1,8 @@ +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; import { dotS2, dotS3, dotS4 } from "@thi.ng/vectors3/dots"; -import { MatOpMV, MultiMatOpMV } from "./api"; import { vop } from "@thi.ng/vectors3/internal/vop"; +import { setC2, setC3, setC4 } from "@thi.ng/vectors3/setc"; +import { MatOpMV, MultiMatOpMV } from "./api"; /** * Matrix-vector multiplication. Supports in-place modification, i.e. if @@ -21,12 +23,13 @@ export const mulV: MultiMatOpMV = vop(1); * @param v */ export const mulV22: MatOpMV = - mulV.add(4, (out, m, v) => { - const x = dotS2(m, v, 0, 0, 2); - out[1] = dotS2(m, v, 1, 0, 2); - out[0] = x; - return out; - }); + mulV.add(4, (out, m, v) => + setC2( + out || v, + dotS2(m, v, 0, 0, 2), + dotS2(m, v, 1, 0, 2) + ) + ); /** * Multiplies M23 `m` with 2D vector `v`. Supports in-place @@ -37,12 +40,13 @@ export const mulV22: MatOpMV = * @param v */ export const mulV23: MatOpMV = - mulV.add(6, (out, m, v) => { - const x = dotS2(m, v, 0, 0, 2) + m[4]; - out[1] = dotS2(m, v, 1, 0, 2) + m[5]; - out[0] = x; - return out; - }); + mulV.add(6, (out, m, v) => + setC2( + out || v, + dotS2(m, v, 0, 0, 2) + m[4], + dotS2(m, v, 1, 0, 2) + m[5] + ) + ); /** * Multiplies M33 `m` with 3D vector `v`. Supports in-place @@ -53,14 +57,14 @@ export const mulV23: MatOpMV = * @param v */ export const mulV33: MatOpMV = - mulV.add(9, (out, m, v) => { - const x = dotS3(m, v, 0, 0, 3); - const y = dotS3(m, v, 1, 0, 3); - out[2] = dotS3(m, v, 2, 0, 3); - out[1] = y; - out[0] = x; - return out; - }); + mulV.add(9, (out, m, v) => + setC3( + out || v, + dotS3(m, v, 0, 0, 3), + dotS3(m, v, 1, 0, 3), + dotS3(m, v, 2, 0, 3) + ) + ); /** * Multiplies M44 `m` with 4D vector `v`. Supports in-place @@ -71,17 +75,15 @@ export const mulV33: MatOpMV = * @param v */ export const mulV44: MatOpMV = - mulV.add(16, (out, m, v) => { - !out && (out = v); - const x = dotS4(m, v, 0, 0, 4); - const y = dotS4(m, v, 1, 0, 4); - const z = dotS4(m, v, 2, 0, 4); - out[3] = dotS4(m, v, 3, 0, 4); - out[2] = z; - out[1] = y; - out[0] = x; - return out; - }); + mulV.add(16, (out, m, v) => + setC4( + out || v, + dotS4(m, v, 0, 0, 4), + dotS4(m, v, 1, 0, 4), + dotS4(m, v, 2, 0, 4), + dotS4(m, v, 3, 0, 4) + ) + ); /** * Multiplies M44 `m` with 3D vector `v` and assumes `w=1`, i.e. the @@ -93,12 +95,26 @@ export const mulV44: MatOpMV = * @param v */ export const mulV344: MatOpMV = - (out, m, v) => { - !out && (out = v); - const x = dotS3(m, v, 0, 0, 4) + m[12]; - const y = dotS3(m, v, 1, 0, 4) + m[13]; - out[2] = dotS3(m, v, 2, 0, 4) + m[14]; - out[1] = y; - out[0] = x; - return out; - }; + (out, m, v) => + setC3( + out || v, + dotS3(m, v, 0, 0, 4) + m[12], + dotS3(m, v, 1, 0, 4) + m[13], + dotS3(m, v, 2, 0, 4) + m[14] + ); + +export const mulVQ = + (out: Vec, quat: ReadonlyVec, v: ReadonlyVec) => { + const { 0: px, 1: py, 2: pz } = v; + const { 0: qx, 1: qy, 2: qz, 3: qw } = quat; + const ix = qw * px + qy * pz - qz * py; + const iy = qw * py + qz * px - qx * pz; + const iz = qw * pz + qx * py - qy * px; + const iw = -qx * px - qy * py - qz * pz; + return setC3( + out || v, + ix * qw + iw * -qx + iy * -qz - iz * -qy, + iy * qw + iw * -qy + iz * -qx - ix * -qz, + iz * qw + iw * -qz + ix * -qy - iy * -qx + ); + }; \ No newline at end of file diff --git a/packages/matrices/src/ortho.ts b/packages/matrices/src/ortho.ts index 8dff5486ef..0710e2998f 100644 --- a/packages/matrices/src/ortho.ts +++ b/packages/matrices/src/ortho.ts @@ -1,5 +1,5 @@ +import { setC } from "@thi.ng/vectors3/setc"; import { Mat } from "./api"; -import { setValues44 } from "./set-values"; export const ortho = ( out: Mat, @@ -13,8 +13,8 @@ export const ortho = ( const dx = 1 / (right - left); const dy = 1 / (top - bottom); const dz = 1 / (far - near); - return setValues44( - out, + return setC( + out || [], 2 * dx, 0, 0, 0, 0, 2 * dy, 0, 0, 0, 0, -2 * dz, 0, diff --git a/packages/matrices/src/project.ts b/packages/matrices/src/project.ts index f890be4557..c2967a4b0d 100644 --- a/packages/matrices/src/project.ts +++ b/packages/matrices/src/project.ts @@ -1,6 +1,6 @@ import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; import { divN3 } from "@thi.ng/vectors3/divn"; -import { dotValues6 } from "@thi.ng/vectors3/dot-values"; +import { dotC6 } from "@thi.ng/vectors3/dotc"; import { fromHomogeneous4 } from "@thi.ng/vectors3/homogeneous"; import { ReadonlyMat } from "./api"; import { invert23, invert44 } from "./invert"; @@ -43,6 +43,6 @@ export const unproject = return divN3( out, mulV344(out, mvp, q), - dotValues6(q[0], mvp[3], q[1], mvp[7], q[2], mvp[11]) + mvp[15] + dotC6(q[0], mvp[3], q[1], mvp[7], q[2], mvp[11]) + mvp[15] ); }; diff --git a/packages/matrices/src/rotation-around-axis.ts b/packages/matrices/src/rotation-around-axis.ts index 8da41b40e3..308937d08f 100644 --- a/packages/matrices/src/rotation-around-axis.ts +++ b/packages/matrices/src/rotation-around-axis.ts @@ -1,15 +1,15 @@ import { ReadonlyVec } from "@thi.ng/vectors3/api"; +import { setC } from "@thi.ng/vectors3/setc"; import { Mat } from "./api"; -import { mat33to44 } from "./convert"; -import { setValues33 } from "./set-values"; +import { mat33to44 } from "./m33-m44"; export const rotationAroundAxis33 = (out: Mat, [x, y, z]: ReadonlyVec, theta: number) => { const s = Math.sin(theta); const c = Math.cos(theta); const t = 1 - c; - return setValues33( - out, + return setC( + out || [], x * x * t + c, y * x * t + z * s, z * x * t - y * s, diff --git a/packages/matrices/src/rotation.ts b/packages/matrices/src/rotation.ts index 5452f556fe..f3b13e3a57 100644 --- a/packages/matrices/src/rotation.ts +++ b/packages/matrices/src/rotation.ts @@ -1,17 +1,12 @@ import { sincos } from "@thi.ng/math/angle"; +import { setC, setC4 } from "@thi.ng/vectors3/setc"; import { Mat } from "./api"; -import { - setValues22, - setValues23, - setValues33, - setValues44 -} from "./set-values"; export const rotation22 = (m: Mat, theta: number) => { const [s, c] = sincos(theta); - return setValues22( - m, + return setC4( + m || [], c, s, -s, c, ); @@ -20,8 +15,8 @@ export const rotation22 = export const rotation23 = (m: Mat, theta: number) => { const [s, c] = sincos(theta); - return setValues23( - m, + return setC( + m || [], c, s, -s, c, 0, 0 @@ -31,8 +26,8 @@ export const rotation23 = export const rotationX33 = (m: Mat, theta: number) => { const [s, c] = sincos(theta); - return setValues33( - m, + return setC( + m || [], 1, 0, 0, 0, c, s, 0, -s, c, @@ -42,8 +37,8 @@ export const rotationX33 = export const rotationY33 = (m: Mat, theta: number) => { const [s, c] = sincos(theta); - return setValues33( - m, + return setC( + m || [], c, 0, -s, 0, 1, 0, s, 0, c, @@ -53,8 +48,8 @@ export const rotationY33 = export const rotationZ33 = (m: Mat, theta: number) => { const [s, c] = sincos(theta); - return setValues33( - m, + return setC( + m || [], c, s, 0, -s, c, 0, 0, 0, 1, @@ -64,8 +59,8 @@ export const rotationZ33 = export const rotationX44 = (m: Mat, theta: number) => { const [s, c] = sincos(theta); - return setValues44( - m, + return setC( + m || [], 1, 0, 0, 0, 0, c, s, 0, 0, -s, c, 0, @@ -76,8 +71,8 @@ export const rotationX44 = export const rotationY44 = (m: Mat, theta: number) => { const [s, c] = sincos(theta); - return setValues44( - m, + return setC( + m || [], c, 0, -s, 0, 0, 1, 0, 0, s, 0, c, 0, @@ -88,8 +83,8 @@ export const rotationY44 = export const rotationZ44 = (m: Mat, theta: number) => { const [s, c] = sincos(theta); - return setValues44( - m, + return setC( + m || [], c, s, 0, 0, -s, c, 0, 0, 0, 0, 1, 0, diff --git a/packages/matrices/src/scale.ts b/packages/matrices/src/scale.ts index fc111bde77..ebde03bb10 100644 --- a/packages/matrices/src/scale.ts +++ b/packages/matrices/src/scale.ts @@ -1,18 +1,13 @@ import { isNumber } from "@thi.ng/checks/is-number"; import { ReadonlyVec } from "@thi.ng/vectors3/api"; +import { setC, setC4 } from "@thi.ng/vectors3/setc"; import { Mat } from "./api"; -import { - setValues22, - setValues23, - setValues33, - setValues44 -} from "./set-values"; export const scale22 = (m: Mat, s: number | ReadonlyVec) => ( s = isNumber(s) ? [s, s] : s, - setValues22( - m, + setC4( + m || [], s[0], 0, 0, s[1] ) @@ -21,8 +16,8 @@ export const scale22 = export const scale23 = (m: Mat, s: number | ReadonlyVec) => ( s = isNumber(s) ? [s, s] : s, - setValues23( - m, + setC( + m || [], s[0], 0, 0, s[1], 0, 0 @@ -32,8 +27,8 @@ export const scale23 = export const scale33 = (m: Mat, s: number | ReadonlyVec) => ( s = isNumber(s) ? [s, s, s] : s, - setValues33( - m, + setC( + m || [], s[0], 0, 0, 0, s[1], 0, 0, 0, s[2] @@ -43,8 +38,8 @@ export const scale33 = export const scale44 = (m: Mat, s: number | ReadonlyVec) => ( s = isNumber(s) ? [s, s, s] : s, - setValues44( - m, + setC( + m || [], s[0], 0, 0, 0, 0, s[1], 0, 0, 0, 0, s[2], 0, diff --git a/packages/matrices/src/set-values.ts b/packages/matrices/src/set-values.ts deleted file mode 100644 index c16fef6c14..0000000000 --- a/packages/matrices/src/set-values.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Mat } from "./api"; -import { set23, set22, set33, set44 } from "./set"; - -export const setValues22 = - (mat: Mat, ...xs: number[]) => set22(mat, xs); - -export const setValues23 = - (mat: Mat, ...xs: number[]) => set23(mat, xs); - -export const setValues33 = - (mat: Mat, ...xs: number[]) => set33(mat, xs); - -export const setValues44 = - (mat: Mat, ...xs: number[]) => set44(mat, xs); \ No newline at end of file diff --git a/packages/matrices/src/set.ts b/packages/matrices/src/set.ts index b6cb2d6e0b..6ebc4708bf 100644 --- a/packages/matrices/src/set.ts +++ b/packages/matrices/src/set.ts @@ -6,7 +6,7 @@ import { MatOpM } from "./api"; const $ = (dim) => _set.add(dim, compile(dim, SET, "o,a")); export const set: MatOpM = _set; -export const set22: MatOpM = set4 +export const set22: MatOpM = set4; export const set23: MatOpM = $(6); export const set33: MatOpM = $(9); export const set44: MatOpM = $(16); diff --git a/packages/matrices/src/translation.ts b/packages/matrices/src/translation.ts index 76701324d2..3c371bcb3e 100644 --- a/packages/matrices/src/translation.ts +++ b/packages/matrices/src/translation.ts @@ -1,14 +1,15 @@ import { ReadonlyVec } from "@thi.ng/vectors3/api"; import { Mat } from "./api"; -import { setValues23, setValues44 } from "./set-values"; +import { setC } from "@thi.ng/vectors3/setc"; export const translation23 = (m: Mat, v: ReadonlyVec) => - setValues23(m || [], 1, 0, 0, 1, v[0], v[1]); + setC(m || [], 1, 0, 0, 1, v[0], v[1]); export const translation44 = (m: Mat, v: ReadonlyVec) => - setValues44(m, + setC( + m || [], 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, diff --git a/packages/matrices/src/transpose.ts b/packages/matrices/src/transpose.ts index b58ef5fb60..7c2a27a608 100644 --- a/packages/matrices/src/transpose.ts +++ b/packages/matrices/src/transpose.ts @@ -1,18 +1,18 @@ +import { setC, setC4 } from "@thi.ng/vectors3/setc"; import { MatOpM } from "./api"; -import { setValues22, setValues33, setValues44 } from "./set-values"; export const transpose22: MatOpM = (out, m) => - setValues22( - out, + setC4( + out || [], m[0], m[2], m[1], m[3], ); export const transpose33: MatOpM = (out, m) => - setValues33( - out, + setC( + out || [], m[0], m[3], m[6], m[1], m[4], m[7], m[2], m[5], m[8], @@ -20,8 +20,8 @@ export const transpose33: MatOpM = export const transpose44: MatOpM = (out, m) => - setValues44( - out, + setC( + out || [], m[0], m[4], m[8], m[12], m[1], m[5], m[9], m[13], m[2], m[6], m[10], m[14], From 0b07ac86b12a8474452e2ae8f75cef142a215679 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 01:26:34 +0000 Subject: [PATCH 128/333] fix(matrices): inject default output handling code --- packages/matrices/src/internal/codegen.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/matrices/src/internal/codegen.ts b/packages/matrices/src/internal/codegen.ts index bf69e405c3..dc1b1d3368 100644 --- a/packages/matrices/src/internal/codegen.ts +++ b/packages/matrices/src/internal/codegen.ts @@ -1,4 +1,9 @@ -import { compile } from "@thi.ng/vectors3/internal/codegen"; +import { + ARGS_VN, + ARGS_VV, + compile, + DEFAULT_OUT +} from "@thi.ng/vectors3/internal/codegen"; import { MATH, MATH_N } from "@thi.ng/vectors3/internal/templates"; import { MultiMatOpMM, MultiMatOpMN } from "../api"; @@ -6,8 +11,8 @@ const DEFAULT_SIZES = [6, 9, 16]; export const defMath = (fn: MultiMatOpMM, op: string, sizes = DEFAULT_SIZES) => - sizes.map((n) => fn.add(n, compile(n, MATH(op), "o,a,b", undefined, "o"))); + sizes.map((n) => fn.add(n, compile(n, MATH(op), ARGS_VV, undefined, "o", "", DEFAULT_OUT))); export const defMathN = (fn: MultiMatOpMN, op: string, sizes = DEFAULT_SIZES) => - sizes.map((n) => fn.add(n, compile(n, MATH_N(op), "o,a,n", "o,a", "o"))); + sizes.map((n) => fn.add(n, compile(n, MATH_N(op), ARGS_VN, "o,a", "o", "", DEFAULT_OUT))); From 0ee306a2976db74e35e0622b66021f59859b3aa5 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 01:27:08 +0000 Subject: [PATCH 129/333] feat(vectors): add setC6() --- packages/vectors3/src/setc.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/vectors3/src/setc.ts b/packages/vectors3/src/setc.ts index b7b50035df..1ce4556032 100644 --- a/packages/vectors3/src/setc.ts +++ b/packages/vectors3/src/setc.ts @@ -24,6 +24,17 @@ export const setC4 = out ); +export const setC6 = + (out: Vec, a: number, b: number, c: number, d: number, e: number, f: number) => ( + out[0] = a, + out[1] = b, + out[2] = c, + out[3] = d, + out[4] = e, + out[5] = f, + out + ); + export const setC = (out: Vec, ...xs: number[]) => { for (let i = 0, n = xs.length; i < n; i++) { From 809383c98dbd1e1b1515d6cc944eeda2eaeb742c Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 01:29:08 +0000 Subject: [PATCH 130/333] refactor(matrices): extract m33to44/m44to33() into own files, update re-exports --- packages/matrices/src/index.ts | 10 ++++++++-- packages/matrices/src/{convert.ts => m33-m44.ts} | 12 ++---------- packages/matrices/src/m44-m33.ts | 10 ++++++++++ packages/matrices/src/normal-mat.ts | 4 ++-- 4 files changed, 22 insertions(+), 14 deletions(-) rename packages/matrices/src/{convert.ts => m33-m44.ts} (59%) create mode 100644 packages/matrices/src/m44-m33.ts diff --git a/packages/matrices/src/index.ts b/packages/matrices/src/index.ts index 4ff1f0a767..87ae1eabf8 100644 --- a/packages/matrices/src/index.ts +++ b/packages/matrices/src/index.ts @@ -2,8 +2,9 @@ export * from "./api"; export * from "./add"; export * from "./addn"; +export * from "./alignment-quat"; export * from "./concat"; -export * from "./convert"; +export * from "./conjugate"; export * from "./determinant"; export * from "./diag"; export * from "./div"; @@ -12,6 +13,9 @@ export * from "./frustum"; export * from "./identity"; export * from "./invert"; export * from "./lookat"; +export * from "./m33-m44"; +export * from "./m44-m33"; +export * from "./mixq"; export * from "./mul"; export * from "./muln"; export * from "./mulv"; @@ -19,13 +23,15 @@ export * from "./normal-mat"; export * from "./ortho"; export * from "./perspective"; export * from "./project"; +export * from "./quat-axis-angle"; +export * from "./quat-euler"; +export * from "./quat-m44"; export * from "./rotation-around-axis"; export * from "./rotation"; export * from "./row"; export * from "./scale"; export * from "./scale-center"; export * from "./set"; -export * from "./set-values"; export * from "./shear"; export * from "./skew"; export * from "./sub"; diff --git a/packages/matrices/src/convert.ts b/packages/matrices/src/m33-m44.ts similarity index 59% rename from packages/matrices/src/convert.ts rename to packages/matrices/src/m33-m44.ts index 0873ff5c63..0862fa66b7 100644 --- a/packages/matrices/src/convert.ts +++ b/packages/matrices/src/m33-m44.ts @@ -4,18 +4,10 @@ import { MatOpM } from "./api"; export const mat33to44: MatOpM = (m44, m33) => ( + !m44 && (m44 = []), setS3(m44, m33, 0, 0), setS3(m44, m33, 4, 3), setS3(m44, m33, 8, 6), setS3(m44, ZERO4, 12), - setS4(m44, [0, 0, 0, 1], 3, 0, 4), - m44 - ); - -export const mat44to33: MatOpM = - (m33, m44) => ( - setS3(m33, m44), - setS3(m33, m44, 3, 4), - setS3(m33, m44, 6, 8), - m33 + setS4(m44, [0, 0, 0, 1], 3, 0, 4) ); diff --git a/packages/matrices/src/m44-m33.ts b/packages/matrices/src/m44-m33.ts new file mode 100644 index 0000000000..35f63a376d --- /dev/null +++ b/packages/matrices/src/m44-m33.ts @@ -0,0 +1,10 @@ +import { setS3 } from "@thi.ng/vectors3/sets"; +import { MatOpM } from "./api"; + +export const mat44to33: MatOpM = + (m33, m44) => ( + !m33 && (m33 = []), + setS3(m33, m44), + setS3(m33, m44, 3, 4), + setS3(m33, m44, 6, 8) + ); diff --git a/packages/matrices/src/normal-mat.ts b/packages/matrices/src/normal-mat.ts index d7b8ae4a18..9d911aba28 100644 --- a/packages/matrices/src/normal-mat.ts +++ b/packages/matrices/src/normal-mat.ts @@ -1,5 +1,5 @@ import { MatOpM } from "./api"; -import { mat44to33 } from "./convert"; +import { mat44to33 } from "./m44-m33"; import { invert33 } from "./invert"; import { transpose33 } from "./transpose"; @@ -12,4 +12,4 @@ import { transpose33 } from "./transpose"; */ export const normal44: MatOpM = (out, m) => - transpose33(out, invert33(out, mat44to33(out, m))); + transpose33(null, invert33(null, mat44to33(out, m))); From d462ae0a2378e6aa28d97db5d86a4663f4678c0b Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 01:30:01 +0000 Subject: [PATCH 131/333] perf(matrices): use setC6() for M23 ops --- packages/matrices/src/invert.ts | 4 ++-- packages/matrices/src/mul.ts | 4 ++-- packages/matrices/src/rotation.ts | 4 ++-- packages/matrices/src/scale.ts | 4 ++-- packages/matrices/src/translation.ts | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/matrices/src/invert.ts b/packages/matrices/src/invert.ts index 84ba6ce3c2..aaadebf8fd 100644 --- a/packages/matrices/src/invert.ts +++ b/packages/matrices/src/invert.ts @@ -2,7 +2,7 @@ import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; import { dotC4, dotC6 } from "@thi.ng/vectors3/dotc"; import { vop } from "@thi.ng/vectors3/internal/vop"; import { magSq4 } from "@thi.ng/vectors3/magsq"; -import { setC, setC4 } from "@thi.ng/vectors3/setc"; +import { setC, setC4, setC6 } from "@thi.ng/vectors3/setc"; import { MatOpM, MultiMatOpM } from "./api"; import { det44FromCoeffs, detCoeffs44 } from "./determinant"; @@ -32,7 +32,7 @@ export const invert23: MatOpM = let det = dp4(m00, m11, -m01, m10); if (det === 0) return; det = 1.0 / det; - return setC( + return setC6( out || m, m11 * det, -m01 * det, diff --git a/packages/matrices/src/mul.ts b/packages/matrices/src/mul.ts index 95e94b680c..18d3d50a75 100644 --- a/packages/matrices/src/mul.ts +++ b/packages/matrices/src/mul.ts @@ -1,7 +1,7 @@ import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; import { dotS2, dotS3, dotS4 } from "@thi.ng/vectors3/dots"; import { vop } from "@thi.ng/vectors3/internal/vop"; -import { setC, setC4 } from "@thi.ng/vectors3/setc"; +import { setC, setC4, setC6 } from "@thi.ng/vectors3/setc"; import { MultiMatOpMM } from "./api"; export const mul: MultiMatOpMM = vop(1); @@ -19,7 +19,7 @@ export const mul22 = export const mul23 = mul.add(6, (out, a, b) => - setC( + setC6( out || a, dotS2(a, b, 0, 0, 2), dotS2(a, b, 1, 0, 2), diff --git a/packages/matrices/src/rotation.ts b/packages/matrices/src/rotation.ts index f3b13e3a57..bfc29c510e 100644 --- a/packages/matrices/src/rotation.ts +++ b/packages/matrices/src/rotation.ts @@ -1,5 +1,5 @@ import { sincos } from "@thi.ng/math/angle"; -import { setC, setC4 } from "@thi.ng/vectors3/setc"; +import { setC, setC4, setC6 } from "@thi.ng/vectors3/setc"; import { Mat } from "./api"; export const rotation22 = @@ -15,7 +15,7 @@ export const rotation22 = export const rotation23 = (m: Mat, theta: number) => { const [s, c] = sincos(theta); - return setC( + return setC6( m || [], c, s, -s, c, diff --git a/packages/matrices/src/scale.ts b/packages/matrices/src/scale.ts index ebde03bb10..4d6cd20592 100644 --- a/packages/matrices/src/scale.ts +++ b/packages/matrices/src/scale.ts @@ -1,6 +1,6 @@ import { isNumber } from "@thi.ng/checks/is-number"; import { ReadonlyVec } from "@thi.ng/vectors3/api"; -import { setC, setC4 } from "@thi.ng/vectors3/setc"; +import { setC, setC4, setC6 } from "@thi.ng/vectors3/setc"; import { Mat } from "./api"; export const scale22 = @@ -16,7 +16,7 @@ export const scale22 = export const scale23 = (m: Mat, s: number | ReadonlyVec) => ( s = isNumber(s) ? [s, s] : s, - setC( + setC6( m || [], s[0], 0, 0, s[1], diff --git a/packages/matrices/src/translation.ts b/packages/matrices/src/translation.ts index 3c371bcb3e..d57333a169 100644 --- a/packages/matrices/src/translation.ts +++ b/packages/matrices/src/translation.ts @@ -1,10 +1,10 @@ import { ReadonlyVec } from "@thi.ng/vectors3/api"; import { Mat } from "./api"; -import { setC } from "@thi.ng/vectors3/setc"; +import { setC, setC6 } from "@thi.ng/vectors3/setc"; export const translation23 = (m: Mat, v: ReadonlyVec) => - setC(m || [], 1, 0, 0, 1, v[0], v[1]); + setC6(m || [], 1, 0, 0, 1, v[0], v[1]); export const translation44 = (m: Mat, v: ReadonlyVec) => From 064d61c5c2b812e4abcfe9bf3598d0619480594d Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 14:26:28 +0000 Subject: [PATCH 132/333] docs(vectors): update readme & package keywords --- packages/vectors3/README.md | 381 ++++++++++++++++++++++----------- packages/vectors3/package.json | 40 +++- 2 files changed, 295 insertions(+), 126 deletions(-) diff --git a/packages/vectors3/README.md b/packages/vectors3/README.md index 3d140ae9cb..6800f4cf39 100644 --- a/packages/vectors3/README.md +++ b/packages/vectors3/README.md @@ -14,7 +14,27 @@ This project is part of the - [Installation](#installation) - [Dependencies](#dependencies) - [Usage examples](#usage-examples) - - [API](#api) +- [API](#api) + - [Constants](#constants) + - [Component setters & copying](#component-setters--copying) + - [Component swizzling](#component-swizzling) + - [Vector creation](#vector-creation) + - [Basic vector math](#basic-vector-math) + - [Multiply-add](#multiply-add) + - [Constraints](#constraints) + - [Cross product](#cross-product) + - [Dot product](#dot-product) + - [Interpolation](#interpolation) + - [Normalization / magnitude](#normalization--magnitude) + - [Distances](#distances) + - [Orientation](#orientation) + - [Rotations](#rotations) + - [Polar / cartesian conversion](#polar--cartesian-conversion) + - [Randomness](#randomness) + - [Unary vector math ops](#unary-vector-math-ops) + - [Vector array batch processing](#vector-array-batch-processing) + - [Comparison / equality](#comparison--equality) + - [Code generator](#code-generator) - [Authors](#authors) - [License](#license) @@ -26,10 +46,11 @@ This project is part of the [@thi.ng/vectors](https://github.com/thi-ng/umbrella/tree/master/packages/vectors) package.** -This package provides 100+ functions & supporting types to perform -vector operations on fixed and arbitrary-length vectors, both packed and -strided (i.e. where individual vector components are not successive -array elements, for example in SOA layouts). +This package provides 350+ largely code generated functions & supporting +types to perform vector operations on fixed and arbitrary-length +vectors, both packed and strided (i.e. where individual vector +components are not successive array elements, for example in SOA +layouts). Use the supporting [@thi.ng/vector-pools](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vector-pools) @@ -45,9 +66,10 @@ package to directly operate on memory mapped data. versions based on given vector arguments. - Each function is defined in its own submodule / file. In addition to each generic multi-method base function, all fixed-length optimized - versions are exported too. E.g. If [`add`](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/add.ts) performs vector addition on - arbitrary-length vectors, `add2`, `add3`, `add4` are the optimized - version for fixed-length vectors... + versions are exported too. E.g. If + [`add`](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/add.ts) + performs vector addition on arbitrary-length vectors, `add2`, `add3`, + `add4` are the optimized version for fixed-length vectors... - Extensible. Custom vector ops can be defined in a similar manner using the provided code generation helpers (see [vop.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/vop.ts) and [codegen.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/codegen.ts) @@ -83,6 +105,7 @@ yarn add @thi.ng/vectors3 - [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/api) - [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/master/packages/checks) - [@thi.ng/equiv](https://github.com/thi-ng/umbrella/tree/master/packages/equiv) +- [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/master/packages/errors) - [@thi.ng/math](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/math) - [@thi.ng/random](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/random) - [@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/master/packages/transducers) @@ -122,122 +145,232 @@ v.swizzle4([], [1, 2], 1, 1, 0, 0) // [ 2, 2, 1, 1 ] ``` -### API - -(Incomplete) list of functions: - -- abs -- acos -- add -- addN -- addS -- addWeighted -- angleBetween -- asin -- bisect -- cartesian -- ceil -- clamp -- clampN -- compare -- copy -- cos -- cosh -- cross -- distChebyshev -- distManhattan -- dist -- distSq -- div -- divN -- divS -- dotValues -- dot -- dotS -- empty -- eqDelta -- eqDeltaS -- eqDeltaArray -- exp -- faceForward -- floor -- fract -- gvec -- headingXY -- headingXZ -- headingYZ -- fromHomogeneous -- invert -- invSqrt -- jitter -- limit -- log -- madd -- maddN -- mag -- magSq -- major -- max -- min -- minor -- mixBilinear -- mixCubic -- mixQuadratic -- mix -- mixN -- mod -- modN -- mul -- mulN -- mulS -- neg -- normalize -- one -- ones -- orthoNormal -- perpendicularLeft -- perpendicularRight -- polar -- pow -- powN -- project -- random -- randNorm -- reflect -- refract -- rotateAroundAxis -- rotateAroundPoint -- rotateX -- rotateY -- rotateZ -- round -- set -- setN -- setS -- setSN -- sign -- sin -- sinh -- smoothstep -- sqrt -- step -- sub -- subN -- subS -- sum -- swizzle -- tan -- tanh -- trunc -- vec2 -- vec2n -- vec3 -- vec3n -- vec4 -- vec4n -- wrap -- zero -- zeroes +## API + +### Constants + +- `MAX2` / `MAX3` / `MAX4` - each component `+Infinity` +- `MIN2` / `MIN3` / `MIN4` - each component `-Infinity` +- `ONE2` / `ONE3` / `ONE4` - each component `1` +- `ZERO2` / `ZERO3` / `ZERO4` - each component `0` +- `X2` / `X3` / `X4` - positive X axis +- `Y2` / `Y3` / `Y4` - positive Y axis +- `Z3` / `Z4` - positive Z axis +- `W4` - positive W axis + +### Component setters & copying + +- `set` / `set2` / `set3` / `set4` +- `setC` / `setC2` / `setC3` / `setC4` / `setC6` +- `setN` / `setN2` / `setN3` / `setN4` +- `setS` / `setS2` / `setS3` / `setS4` +- `setSN2` / `setSN3` / `setSN4` +- `copy` +- `empty` +- `one` +- `zero` + +### Component swizzling + +- `swizzle2` / `swizzle3` / `swizzle4` +- `swapXY` / `swapXZ` / `swapYZ` + +### Vector creation + +Functions to create wrapped vector instances: + +- `vec2` / `vec2n` +- `vec3` / `vec3n` +- `vec4` / `vec4n` +- `gvec` + +Wrap existing vanilla vectors: + +- `asVec2` / `asVec3` / `asVec4` + +Vanilla vector (array) factories: + +- `ones` +- `zeroes` + +### Basic vector math + +#### Vector / vector + +Component wise op with 2 input vectors: + +- `add` / `add2` / `add3` / `add4` +- `div` / `div2` / `div3` / `div4` +- `mul` / `mul2` / `mul3` / `mul4` +- `sub` / `sub2` / `sub3` / `sub4` +- `mod` / `mod2` / `mod3` / `mod4` +- `pow` / `pow2` / `pow3` / `pow4` + +#### Vector / scalar + +Component wise op with one input vector and single scalar: + +- `addN` / `addN2` / `addN3` / `addN4` +- `divN` / `divN2` / `divN3` / `divN4` +- `mulN` / `mulN2` / `mulN3` / `mulN4` +- `subN` / `subN2` / `subN3` / `subN4` +- `neg` - same as `mulN(out, v, -1)` +- `modN` / `modN2` / `modN3` / `modN4` +- `powN` / `powN2` / `powN3` / `powN4` + +#### Strided vectors + +Functions for memory mapped, strided vectors (without requiring wrappers): + +- `addS2` / `addS3` / `addS4` +- `divS2` / `divS3` / `divS4` +- `mulS2` / `mulS3` / `mulS4` +- `subS2` / `subS3` / `subS4` + +### Multiply-add + +- `addWeighted2` / `addWeighted3` / `addWeighted4` / `addWeighted5` +- `madd` / `madd2` / `madd3` / `madd4` +- `maddN` / `maddN2` / `maddN3` / `maddN4` + +### Constraints + +- `clamp` +- `clamp2` / `clamp3` / `clamp4` +- `clampN` / `clampN2` / `clampN3` / `clampN4` +- `clamp01` / `clamp01_2` / `clamp01_3` / `clamp01_4` +- `clamp11` / `clamp11_2` / `clamp11_3` / `clamp11_4` +- `max` / `max2` / `max3` / `max4` +- `min` / `min2` / `min3` / `min4` + +### Cross product + +- `cross2` +- `cross3` +- `orthoNormal3` +- `signedArea2` + +### Dot product + +- `dot` +- `dot2` / `dot3` / `dot4` +- `dotC4` / `dotC6` / `dotC8` +- `dotS2` / `dotS3` / `dotS4` + +### Interpolation + +- `mix` / `mix2` / `mix3` / `mix4` +- `mixN` / `mixN2` / `mixN3` / `mixN4` +- `mixBilinear` / `mixBilinear2` / `mixBilinear3` / `mixBilinear4` +- `mixCubic` +- `mixQuadratic` +- `smoothStep` / `smoothStep2` / `smoothStep3` / `smoothStep4` +- `step` / `step2` / `step3` / `step4` + +### Normalization / magnitude + +- `limit` +- `mag` +- `magSq` / `magSq2` / `magSq3` / `magSq4` +- `normalize` + +### Distances + +- `dist` +- `distSq` / `distSq2` / `distSq3` / `distSq4` +- `distChebyshev` / `distChebyshev2` / `distChebyshev3` / `distChebyshev4` +- `distManhattan` / `distManhattan2` / `distManhattan3` / `distManhattan4` + +### Orientation + +- `angleBetween` +- `angleRatio` +- `bisect2` +- `faceForward` +- `heading` / `headingXY` / `headingXZ` / `headingYZ` +- `perpendicularLeft2` / `perpendicularRight2` +- `project` +- `reflect` +- `refract` + +### Rotations + +(Also see rotation matrices provided by +[@thi.ng/matrices](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/matrices)) + +- `rotateAroundAxis3` +- `rotateAroundPoint2` +- `rotateX` \ `rotateY` \ `rotateZ` + +### Polar / cartesian conversion + +- `cartesian` / `cartesian2` / `cartesian3` +- `polar` / `polar2` / `polar3` + +### Randomness + +All ops support custom PRNG impls based on the +[@thi.ng/random](https://github.com/thi-ng/umbrella/tree/master/packages/random) +`IRandom` interface and use `Math.random` by default: + +- `jitter` +- `randNorm` +- `random` / `random2` / `random3` / `random4` + +### Unary vector math ops + +- `abs` / `abs2` / `abs3` / `abs4` +- `acos` / `acos2` / `acos3` / `acos4` +- `asin` / `asin2` / `asin3` / `asin4` +- `ceil` / `ceil2` / `ceil3` / `ceil4` +- `cos` / `cos2` / `cos3` / `cos4` +- `cosh` / `cosh2` / `cosh3` / `cosh4` +- `exp` / `exp2` / `exp3` / `exp4` +- `floor` / `floor2` / `floor3` / `floor4` +- `fract` / `fract2` / `fract3` / `fract4` +- `fromHomogeneous` / `fromHomogeneous3` / `fromHomogeneous4` +- `invert` / `invert2` / `invert3` / `invert4` +- `invSqrt` / `invSqrt2` / `invSqrt3` / `invSqrt4` +- `log` / `log2` / `log3` / `log4` +- `major` / `major2` / `major3` / `major4` +- `minor` / `minor2` / `minor3` / `minor4` +- `round` / `round2` / `round3` / `round4` +- `sign` / `sign2` / `sign3` / `sign4` +- `sin` / `sin2` / `sin3` / `sin4` +- `sinh` / `sinh2` / `sinh3` / `sinh4` +- `sqrt` / `sqrt2` / `sqrt3` / `sqrt4` +- `sum` / `sum2` / `sum3` / `sum4` +- `tan` / `tan2` / `tan3` / `tan4` +- `tanh` / `tanh2` / `tanh3` / `tanh4` +- `trunc` / `trunc2` / `trunc3` / `trunc4` +- `wrap` / `wrap2` / `wrap3` / `wrap4` + +### Vector array batch processing + +Functions to transform flat / strided buffers w/ vector operations: + +- `mapV` / `mapVN` / `mapVV` / `mapVVN` / `mapVVV` + +### Comparison / equality + +- `comparator2` / `comparator3` / `comparator4` +- `eqDelta` / `eqDelta2` / `eqDelta3` / `eqDelta4` +- `eqDeltaS` +- `eqDeltaArray` + +### Code generator + +- `compile` +- `compileG` +- `compileGHOF` +- `compileHOF` +- `defFnOp` +- `defHofOp` +- `defMathNOp` +- `defMathOp` +- `defOp` +- `defOpS` +- `vop` ## Authors diff --git a/packages/vectors3/package.json b/packages/vectors3/package.json index b424f19b87..77b4669a3c 100644 --- a/packages/vectors3/package.json +++ b/packages/vectors3/package.json @@ -37,14 +37,50 @@ "@thi.ng/transducers": "^2.3.1" }, "keywords": [ - "algebra", + "2D", + "3D", + "4D", + "abitrary length", + "bilinear", + "cartesian", + "chebyshev", + "clamp", "code generator", + "cubic", "data structures", + "distance", + "dot product", + "equality", "ES6", + "faceforward", "geometry", + "gvec", + "heading", + "homogeneous", + "interpolation", + "manhattan", + "magnitude", + "math", + "memory mapped", + "normal", + "normalize", + "polar", + "projection", + "quadratic", + "random", + "reflect", + "refract", + "rotation", + "setter", + "smoothstep", + "step", + "strided", "typescript", "webgl", - "vector" + "vector", + "vec2", + "vec3", + "vec4" ], "publishConfig": { "access": "public" From 6c9fe88e22c9b65815079926ec75fc51a0dcd080 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 14:33:21 +0000 Subject: [PATCH 133/333] refactor(vectors): rename addWeighted*() => addW*(), update package kw --- packages/matrices/package.json | 23 +++++++++++++++++-- .../vectors3/src/{add-weighted.ts => addw.ts} | 8 +++---- packages/vectors3/src/index.ts | 2 +- packages/vectors3/src/mix-cubic.ts | 4 ++-- packages/vectors3/src/mix-quadratic.ts | 4 ++-- 5 files changed, 30 insertions(+), 11 deletions(-) rename packages/vectors3/src/{add-weighted.ts => addw.ts} (91%) diff --git a/packages/matrices/package.json b/packages/matrices/package.json index 1e0a18fcb4..695363a4ba 100644 --- a/packages/matrices/package.json +++ b/packages/matrices/package.json @@ -1,7 +1,7 @@ { "name": "@thi.ng/matrices", "version": "0.0.1", - "description": "TODO", + "description": "Matrix operations for 2D / 3D geometry processing", "main": "./index.js", "typings": "./index.d.ts", "repository": { @@ -32,8 +32,27 @@ "@thi.ng/vectors3": "^0.0.1" }, "keywords": [ + "2D", + "3D", "ES6", - "typescript" + "code generator", + "euler angles", + "frustum", + "geometry", + "linear algebra", + "lookat", + "math", + "matrix", + "ortho", + "perspective", + "projection", + "quaternion", + "shear", + "skew", + "transformation", + "typescript", + "vectors", + "webgl" ], "publishConfig": { "access": "public" diff --git a/packages/vectors3/src/add-weighted.ts b/packages/vectors3/src/addw.ts similarity index 91% rename from packages/vectors3/src/add-weighted.ts rename to packages/vectors3/src/addw.ts index 0a21d0ea0c..3634cb1515 100644 --- a/packages/vectors3/src/add-weighted.ts +++ b/packages/vectors3/src/addw.ts @@ -2,13 +2,13 @@ import { ReadonlyVec, Vec } from "./api"; import { maddN } from "./maddn"; import { mulN } from "./muln"; -export const addWeighted2 = +export const addW2 = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, wa: number, wb: number) => maddN(out, mulN(out, a, wa), b, wb); -export const addWeighted3 = +export const addW3 = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, wa: number, wb: number, wc: number) => maddN(out, maddN(out, @@ -16,7 +16,7 @@ export const addWeighted3 = b, wb), c, wc); -export const addWeighted4 = +export const addW4 = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, wa: number, wb: number, wc: number, wd: number) => maddN(out, @@ -26,7 +26,7 @@ export const addWeighted4 = c, wc), d, wd); -export const addWeighted5 = +export const addW5 = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, e: ReadonlyVec, wa: number, wb: number, wc: number, wd: number, we: number) => maddN(out, diff --git a/packages/vectors3/src/index.ts b/packages/vectors3/src/index.ts index 901a50a789..c4be876ab9 100644 --- a/packages/vectors3/src/index.ts +++ b/packages/vectors3/src/index.ts @@ -8,7 +8,7 @@ export * from "./vec4"; export * from "./abs"; export * from "./acos"; -export * from "./add-weighted"; +export * from "./addw"; export * from "./add"; export * from "./addn"; export * from "./adds"; diff --git a/packages/vectors3/src/mix-cubic.ts b/packages/vectors3/src/mix-cubic.ts index e29dcd3e16..51aa4053fc 100644 --- a/packages/vectors3/src/mix-cubic.ts +++ b/packages/vectors3/src/mix-cubic.ts @@ -1,10 +1,10 @@ import { ReadonlyVec, Vec } from "./api"; -import { addWeighted4 } from "./add-weighted"; +import { addW4 } from "./addw"; export const mixCubic = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, t: number) => { const s = 1 - t; const s2 = s * s; const t2 = t * t; - return addWeighted4(out, a, b, c, d, s2 * s, 3 * s2 * t, 3 * t2 * s, t2 * t); + return addW4(out, a, b, c, d, s2 * s, 3 * s2 * t, 3 * t2 * s, t2 * t); }; diff --git a/packages/vectors3/src/mix-quadratic.ts b/packages/vectors3/src/mix-quadratic.ts index 1cfee23f72..fbbdb2646f 100644 --- a/packages/vectors3/src/mix-quadratic.ts +++ b/packages/vectors3/src/mix-quadratic.ts @@ -1,8 +1,8 @@ -import { addWeighted3 } from "./add-weighted"; +import { addW3 } from "./addw"; import { ReadonlyVec, Vec } from "./api"; export const mixQuadratic = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, t: number) => { const s = 1 - t; - return addWeighted3(out, a, b, c, s * s, 2 * s * t, t * t); + return addW3(out, a, b, c, s * s, 2 * s * t, t * t); }; From 66036e6c221a6998467db0f8e552f0fcdfba32dc Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 16:57:10 +0000 Subject: [PATCH 134/333] fix(vectors): update gvec prop lookup & interning --- packages/vectors3/src/gvec.ts | 107 +++++++++++++++++++++++----------- 1 file changed, 73 insertions(+), 34 deletions(-) diff --git a/packages/vectors3/src/gvec.ts b/packages/vectors3/src/gvec.ts index fbaaa7ff7f..80f2f902d0 100644 --- a/packages/vectors3/src/gvec.ts +++ b/packages/vectors3/src/gvec.ts @@ -8,25 +8,47 @@ import { values } from "./internal/vec-utils"; import { zeroes } from "./setn"; import { setS } from "./sets"; -const B = "buf"; -const L = "length"; -const O = "offset"; -const S = "stride"; +const SYM_B = "buf"; +const SYM_L = "length"; +const SYM_O = "offset"; +const SYM_S = "stride"; +const SYM_C = "copy"; +const SYM_CV = "copyView"; +const SYM_EMPTY = "empty"; +const SYM_EQD = "eqDelta"; +const SYM_STR = "toString"; -const keys = memoize1( - (size: number) => [...map(String, range(size)), L, O, S] +const PROPS = new Set([ + SYM_B, + SYM_C, + SYM_CV, + SYM_EMPTY, + SYM_EQD, + SYM_L, + SYM_O, + SYM_S, + SYM_STR, + Symbol.iterator +]); + +const keys = memoize1( + (size: number) => [ + ...map(String, range(size)), + ...PROPS + ] ); /** * Wrapper for strided, arbitrary length vectors. Wraps given buffer in - * ES6 `Proxy` with custom property getters/setters and implements the following - * interfaces: + * ES6 `Proxy` with custom property getters/setters and implements the + * following interfaces: * * - `Iterable` (ES6) * - `ICopy` * - `IEmpty` * - `IEqualsDelta` * - `IVector` + * - `Object.toString()` * * Read/write access for the following properties: * @@ -40,10 +62,10 @@ const keys = memoize1( * interval, but, for performance reasons, **not** against the actual * wrapped buffer. * - * Note: ES6 Proxy use is approx. 10x slower than standard array - * accesses. If several computations are to be performed on such vectors - * it will be much more efficient to first copy them to compact arrays - * and then copy result back if needed. + * Note: ES6 proxies are ~10x slower than standard array accesses. If + * several computations are to be performed on such vectors it will be + * much more efficient to first copy them to compact arrays and then + * copy result back if needed. * * ``` * // 3D vector w/ stride length of 4 @@ -52,13 +74,26 @@ const keys = memoize1( * a[1] // 2 * a[2] // 3 * + * a.stride + * // 4 + * * [...a] * // [1, 2, 3] * + * a.toString() + * // "[1,2,3]" + * * add([], a, a) * // [2, 4, 6] * - * add() + * copy(a) + * // [1, 2, 3] + * + * a.copyView() + * // Proxy [ [ 1, 0, 2, 0, 3, 0 ], ... } + * + * eqDelta(a, [1, 2, 3]) + * // true * ``` * * @param buf @@ -69,49 +104,52 @@ const keys = memoize1( export const gvec = (buf: Vec, size: number, offset = 0, stride = 1): IVector => new Proxy(buf, { - get: (obj, id) => { + get(obj, id) { switch (id) { case Symbol.iterator: return () => values(obj, size, offset, stride); - case L: + case SYM_L: return size; - case B: + case SYM_B: return buf; - case O: + case SYM_O: return offset; - case S: + case SYM_S: return stride; - case "copy": + case SYM_C: return () => - gvec(setS([], obj, 0, offset, 1, stride), size); - case "copyView": + setS([], obj, size, 0, offset, 1, stride); + case SYM_CV: return () => gvec(obj, size, offset, stride); - case "empty": + case SYM_EMPTY: return () => zeroes(size); - case "eqDelta": + case SYM_EQD: return (o, eps = EPS) => eqDeltaS(buf, o, size, eps, offset, 0, stride, 1); + case SYM_STR: + return () => + JSON.stringify([...values(obj, size, offset, stride)]); default: - let j = parseInt(id); + const j = parseInt(id); return !isNaN(j) && j >= 0 && j < size ? obj[offset + j * stride] : undefined; } }, - set: (obj, id, value) => { + set(obj, id, value) { const j = parseInt(id); if (!isNaN(j) && j >= 0 && j < size) { obj[offset + (id | 0) * stride] = value; } else { switch (id) { - case O: + case SYM_O: offset = value; break; - case S: + case SYM_S: stride = value; break; - case L: + case SYM_L: size = value; break; default: @@ -120,10 +158,11 @@ export const gvec = } return true }, - has: (_, id) => - (id >= 0 && id < size) || - id === O || - id == S || - id == L, - ownKeys: () => keys(size), + has(_, id) { + return (id >= 0 && id < size) || + PROPS.has(id); + }, + ownKeys() { + return keys(size); + } }); From 7e19e7b4644029a0a6798545011029f8e02307f8 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 16:57:37 +0000 Subject: [PATCH 135/333] minor(vectors): minor update vop() --- packages/vectors3/src/internal/vop.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/vectors3/src/internal/vop.ts b/packages/vectors3/src/internal/vop.ts index 867672b30a..771acbf303 100644 --- a/packages/vectors3/src/internal/vop.ts +++ b/packages/vectors3/src/internal/vop.ts @@ -19,6 +19,5 @@ export const vop = (dispatch = 0) => { fn.add = (dim: number, fn) => (impls[dim] = fn); fn.default = (fn) => (fallback = fn); // fn.impls = impls; - // fn.fallback = fallback; return fn; }; From c70189aa05048e4ebc5ed8e527ec2007fd840da4 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 16:57:53 +0000 Subject: [PATCH 136/333] docs(vectors): update readme --- packages/vectors3/README.md | 77 ++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 31 deletions(-) diff --git a/packages/vectors3/README.md b/packages/vectors3/README.md index 6800f4cf39..c284986efd 100644 --- a/packages/vectors3/README.md +++ b/packages/vectors3/README.md @@ -11,6 +11,7 @@ This project is part of the - [About](#about) - [Features](#features) + - [Related packages](#related-packages) - [Installation](#installation) - [Dependencies](#dependencies) - [Usage examples](#usage-examples) @@ -52,29 +53,28 @@ vectors, both packed and strided (i.e. where individual vector components are not successive array elements, for example in SOA layouts). -Use the supporting -[@thi.ng/vector-pools](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vector-pools) -package to directly operate on memory mapped data. - ### Features - Small & fast: The vast majority of these functions are code generated - with fixed-sized versions not using any loops. + with fixed-sized versions not using any loops. Minified + gzipped, the + entire package is ~12.7KB. - Unified API: Any `ArrayLike` type can be used as vector containers (e.g. JS arrays, typed arrays, custom impls). Most functions are implemented as multi-methods, dispatching to any potentially optimized versions based on given vector arguments. -- Each function is defined in its own submodule / file. In addition to - each generic multi-method base function, all fixed-length optimized - versions are exported too. E.g. If +- Highly modular: Each function is defined in its own submodule / file. + In addition to each generic multi-method base function, all + fixed-length optimized versions are exported too. E.g. If [`add`](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/add.ts) performs vector addition on arbitrary-length vectors, `add2`, `add3`, `add4` are the optimized version for fixed-length vectors... -- Extensible. Custom vector ops can be defined in a similar manner using - the provided code generation helpers (see [vop.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/vop.ts) and +- Extensible: Custom vector ops can be defined in a similar manner using + the provided code generation helpers (see + [vop.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/vop.ts) + and [codegen.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/codegen.ts) for details). -- Immutable by default. Each operation producing a vector result takes +- Immutable by default: Each operation producing a vector result takes an output vector as first argument. If `null`, the vector given as 2nd argument will be used as output (i.e. for mutation). - Strided vector support is handled via the lightweight @@ -94,6 +94,12 @@ package to directly operate on memory mapped data. to work with custom (P)RNGs. If omitted, the built-in `Math.random()` will be used. +### Related packages + +- [@thi.ng/geom2](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/geom2) - 2D/3D geometry types & operations +- [@thi.ng/matrices](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/matrices) - 2x2, 2x3, 3x3, 4x4 matrix & quaternion ops +- [@thi.ng/vector-pools](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vector-pools) - operations on memory mapped data + ## Installation ```bash @@ -107,7 +113,7 @@ yarn add @thi.ng/vectors3 - [@thi.ng/equiv](https://github.com/thi-ng/umbrella/tree/master/packages/equiv) - [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/master/packages/errors) - [@thi.ng/math](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/math) -- [@thi.ng/random](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/random) +- [@thi.ng/random](https://github.com/thi-ng/umbrella/tree/master/packages/random) - [@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/master/packages/transducers) ## Usage examples @@ -115,33 +121,43 @@ yarn add @thi.ng/vectors3 ```ts import * as v from "@thi.ng/vectors3"; +// immutable vector addition (1st arg is result) v.add([], [1, 2, 3, 4], [10, 20, 30, 40]) // [11, 22, 33, 44] +// mutable addition (if first arg is null) +a = [1, 2, 3]; +v.add(null, a, a); +// [2, 4, 6] + // multiply-add (o = a + b * c) -v.madd([], [1,2], [10, 20], [0.5, 0.25]); +v.madd([], [1, 2], [10, 20], [0.5, 0.25]); // [6, 7] -// scalar addition -v.addN([], gvec([0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0], 3, 1, 4), 10) +// multiply-add w/ scalar (o = a + b * n) +v.maddN([], [1, 2], [10, 20], 0.5); +// [6, 12] + +// scalar addition w/ arbitrary length & strided vector +v.addN([], gvec([0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0], 3, 1, 4), 10); // [11, 12, 13] -v.dist([1,2], [100, 200]) +v.dist([1, 2], [100, 200]); // 221.37072977247917 -v.distManhattan([1,2], [100, 200]) +v.distManhattan([1, 2], [100, 200]); // 297 -v.distChebyshev([1,2], [100, 200]) +v.distChebyshev([1, 2], [100, 200]); // 198 v.mixN([], [1, 2], [10, 20], 0.5); // [5.5, 11] -v.fromHomogeneous([], [100, 200, 0.5]) +v.fromHomogeneous([], [100, 200, 0.5]); // [200, 400] -v.swizzle4([], [1, 2], 1, 1, 0, 0) +v.swizzle4([], [1, 2], 1, 1, 0, 0); // [ 2, 2, 1, 1 ] ``` @@ -229,7 +245,7 @@ Functions for memory mapped, strided vectors (without requiring wrappers): ### Multiply-add -- `addWeighted2` / `addWeighted3` / `addWeighted4` / `addWeighted5` +- `addW2` / `addW3` / `addW4` / `addW5` - `madd` / `madd2` / `madd3` / `madd4` - `maddN` / `maddN2` / `maddN3` / `maddN4` @@ -360,18 +376,17 @@ Functions to transform flat / strided buffers w/ vector operations: ### Code generator -- `compile` -- `compileG` -- `compileGHOF` -- `compileHOF` -- `defFnOp` -- `defHofOp` -- `defMathNOp` -- `defMathOp` -- `defOp` -- `defOpS` +- `compile` / `compileG` / `compileGHOF` / `compileHOF` +- `defOp` / `defOpS` / `defFnOp` / `defHofOp` +- `defMathNOp` / `defMathOp` - `vop` +For more information about the code generator see: + +- [codegen.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/codegen.ts) +- [templates.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/templates.ts) +- [vop.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/vop.ts) + ## Authors - Karsten Schmidt From ae7a039e1f6a4424a2274350770b46ce23bbf64b Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 17:34:55 +0000 Subject: [PATCH 137/333] feat(matrices): add cwise matrix multiply, rename mul* => mulM*, move mulQ --- packages/matrices/src/concat.ts | 6 +- packages/matrices/src/index.ts | 3 + packages/matrices/src/mul.ts | 88 ++--------------------------- packages/matrices/src/mulm.ts | 69 ++++++++++++++++++++++ packages/matrices/src/mulq.ts | 15 +++++ packages/matrices/src/quat-euler.ts | 2 +- packages/matrices/src/viewport.ts | 4 +- 7 files changed, 99 insertions(+), 88 deletions(-) create mode 100644 packages/matrices/src/mulm.ts create mode 100644 packages/matrices/src/mulq.ts diff --git a/packages/matrices/src/concat.ts b/packages/matrices/src/concat.ts index 6d32b0bd6d..9ba087a280 100644 --- a/packages/matrices/src/concat.ts +++ b/packages/matrices/src/concat.ts @@ -1,9 +1,9 @@ import { Mat, ReadonlyMat } from "./api"; -import { mul } from "./mul"; +import { mulM } from "./mulM"; export const concat = (out: Mat, a: ReadonlyMat, b: ReadonlyMat, ...xs: ReadonlyMat[]) => xs.reduce( - (acc: Mat, x) => mul(acc, acc, x), - mul(out, a, b) + (acc: Mat, x) => mulM(acc, acc, x), + mulM(out, a, b) ); diff --git a/packages/matrices/src/index.ts b/packages/matrices/src/index.ts index 87ae1eabf8..7524d50067 100644 --- a/packages/matrices/src/index.ts +++ b/packages/matrices/src/index.ts @@ -3,6 +3,7 @@ export * from "./api"; export * from "./add"; export * from "./addn"; export * from "./alignment-quat"; +export * from "./column"; export * from "./concat"; export * from "./conjugate"; export * from "./determinant"; @@ -17,7 +18,9 @@ export * from "./m33-m44"; export * from "./m44-m33"; export * from "./mixq"; export * from "./mul"; +export * from "./mulm"; export * from "./muln"; +export * from "./mulq"; export * from "./mulv"; export * from "./normal-mat"; export * from "./ortho"; diff --git a/packages/matrices/src/mul.ts b/packages/matrices/src/mul.ts index 18d3d50a75..fdb9ba6258 100644 --- a/packages/matrices/src/mul.ts +++ b/packages/matrices/src/mul.ts @@ -1,83 +1,7 @@ -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { dotS2, dotS3, dotS4 } from "@thi.ng/vectors3/dots"; -import { vop } from "@thi.ng/vectors3/internal/vop"; -import { setC, setC4, setC6 } from "@thi.ng/vectors3/setc"; -import { MultiMatOpMM } from "./api"; +import { mul as _mul, mul4 } from "@thi.ng/vectors3/mul"; +import { MatOpMM, MultiMatOpMM } from "./api"; +import { defMath } from "./internal/codegen"; -export const mul: MultiMatOpMM = vop(1); - -export const mul22 = - mul.add(4, (out, a, b) => - setC4( - out || a, - dotS2(a, b, 0, 0, 2), - dotS2(a, b, 1, 0, 2), - dotS2(a, b, 0, 2, 2), - dotS2(a, b, 1, 2, 2) - ) - ); - -export const mul23 = - mul.add(6, (out, a, b) => - setC6( - out || a, - dotS2(a, b, 0, 0, 2), - dotS2(a, b, 1, 0, 2), - dotS2(a, b, 0, 2, 2), - dotS2(a, b, 1, 2, 2), - dotS2(a, b, 0, 4, 2) + a[4], - dotS2(a, b, 1, 4, 2) + a[5] - ) - ); - -export const mul33 = - mul.add(9, (out, a, b) => - setC( - out || a, - dotS3(a, b, 0, 0, 3), - dotS3(a, b, 1, 0, 3), - dotS3(a, b, 2, 0, 3), - dotS3(a, b, 0, 3, 3), - dotS3(a, b, 1, 3, 3), - dotS3(a, b, 2, 3, 3), - dotS3(a, b, 0, 6, 3), - dotS3(a, b, 1, 6, 3), - dotS3(a, b, 2, 6, 3) - ) - ); - -export const mul44 = - mul.add(16, (out, a, b) => - setC( - out || a, - dotS4(a, b, 0, 0, 4), - dotS4(a, b, 1, 0, 4), - dotS4(a, b, 2, 0, 4), - dotS4(a, b, 3, 0, 4), - dotS4(a, b, 0, 4, 4), - dotS4(a, b, 1, 4, 4), - dotS4(a, b, 2, 4, 4), - dotS4(a, b, 3, 4, 4), - dotS4(a, b, 0, 8, 4), - dotS4(a, b, 1, 8, 4), - dotS4(a, b, 2, 8, 4), - dotS4(a, b, 3, 8, 4), - dotS4(a, b, 0, 12, 4), - dotS4(a, b, 1, 12, 4), - dotS4(a, b, 2, 12, 4), - dotS4(a, b, 3, 12, 4) - ) - ); - -export const mulQ = - (out: Vec, a: ReadonlyVec, b: ReadonlyVec) => { - const { 0: ax, 1: ay, 2: az, 3: aw } = a; - const { 0: bx, 1: by, 2: bz, 3: bw } = b; - return setC4( - out || a, - ax * bw + aw * bx + ay * bz - az * by, - ay * bw + aw * by + az * bx - ax * bz, - az * bw + aw * bz + ax * by - ay * bx, - aw * bw - ax * bx - ay * by - az * bz - ); - }; +export const mul: MultiMatOpMM = _mul; +export const mul22: MatOpMM = mul4; +export const [mul23, mul33, mul44] = defMath(mul, "*"); diff --git a/packages/matrices/src/mulm.ts b/packages/matrices/src/mulm.ts new file mode 100644 index 0000000000..3148c654e4 --- /dev/null +++ b/packages/matrices/src/mulm.ts @@ -0,0 +1,69 @@ +import { dotS2, dotS3, dotS4 } from "@thi.ng/vectors3/dots"; +import { vop } from "@thi.ng/vectors3/internal/vop"; +import { setC, setC4, setC6 } from "@thi.ng/vectors3/setc"; +import { MultiMatOpMM } from "./api"; + +export const mulM: MultiMatOpMM = vop(1); + +export const mulM22 = + mulM.add(4, (out, a, b) => + setC4( + out || a, + dotS2(a, b, 0, 0, 2), + dotS2(a, b, 1, 0, 2), + dotS2(a, b, 0, 2, 2), + dotS2(a, b, 1, 2, 2) + ) + ); + +export const mulM23 = + mulM.add(6, (out, a, b) => + setC6( + out || a, + dotS2(a, b, 0, 0, 2), + dotS2(a, b, 1, 0, 2), + dotS2(a, b, 0, 2, 2), + dotS2(a, b, 1, 2, 2), + dotS2(a, b, 0, 4, 2) + a[4], + dotS2(a, b, 1, 4, 2) + a[5] + ) + ); + +export const mulM33 = + mulM.add(9, (out, a, b) => + setC( + out || a, + dotS3(a, b, 0, 0, 3), + dotS3(a, b, 1, 0, 3), + dotS3(a, b, 2, 0, 3), + dotS3(a, b, 0, 3, 3), + dotS3(a, b, 1, 3, 3), + dotS3(a, b, 2, 3, 3), + dotS3(a, b, 0, 6, 3), + dotS3(a, b, 1, 6, 3), + dotS3(a, b, 2, 6, 3) + ) + ); + +export const mulM44 = + mulM.add(16, (out, a, b) => + setC( + out || a, + dotS4(a, b, 0, 0, 4), + dotS4(a, b, 1, 0, 4), + dotS4(a, b, 2, 0, 4), + dotS4(a, b, 3, 0, 4), + dotS4(a, b, 0, 4, 4), + dotS4(a, b, 1, 4, 4), + dotS4(a, b, 2, 4, 4), + dotS4(a, b, 3, 4, 4), + dotS4(a, b, 0, 8, 4), + dotS4(a, b, 1, 8, 4), + dotS4(a, b, 2, 8, 4), + dotS4(a, b, 3, 8, 4), + dotS4(a, b, 0, 12, 4), + dotS4(a, b, 1, 12, 4), + dotS4(a, b, 2, 12, 4), + dotS4(a, b, 3, 12, 4) + ) + ); diff --git a/packages/matrices/src/mulq.ts b/packages/matrices/src/mulq.ts new file mode 100644 index 0000000000..be70ef56bf --- /dev/null +++ b/packages/matrices/src/mulq.ts @@ -0,0 +1,15 @@ +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { setC4 } from "@thi.ng/vectors3/setc"; + +export const mulQ = + (out: Vec, a: ReadonlyVec, b: ReadonlyVec) => { + const { 0: ax, 1: ay, 2: az, 3: aw } = a; + const { 0: bx, 1: by, 2: bz, 3: bw } = b; + return setC4( + out || a, + ax * bw + aw * bx + ay * bz - az * by, + ay * bw + aw * by + az * bx - ax * bz, + az * bw + aw * bz + ax * by - ay * bx, + aw * bw - ax * bx - ay * by - az * bz + ); + }; diff --git a/packages/matrices/src/quat-euler.ts b/packages/matrices/src/quat-euler.ts index 52fd557fa4..36c35b9aa8 100644 --- a/packages/matrices/src/quat-euler.ts +++ b/packages/matrices/src/quat-euler.ts @@ -1,5 +1,5 @@ import { X3, Y3, Z3 } from "@thi.ng/vectors3/api"; -import { mulQ } from "./mul"; +import { mulQ } from "./mulq"; import { quatFromAxisAngle } from "./quat-axis-angle"; const axisOrder = { diff --git a/packages/matrices/src/viewport.ts b/packages/matrices/src/viewport.ts index c5fc5315a3..06c2570d85 100644 --- a/packages/matrices/src/viewport.ts +++ b/packages/matrices/src/viewport.ts @@ -1,5 +1,5 @@ import { Mat } from "./api"; -import { mul23 } from "./mul"; +import { mulM23 } from "./mulM"; import { scale23 } from "./scale"; import { translation23 } from "./translation"; @@ -19,5 +19,5 @@ export const viewport = const y = (bottom + top) / 2; const w = (right - left) / 2; const h = (top - bottom) / 2; - return mul23(out, translation23(out, [x, y]), scale23([], [w, h])); + return mulM23(null, translation23(out, [x, y]), scale23([], [w, h])); }; From 4f2f512cf8db515d2825a5f0f64ccf6deabeb0a2 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 17:48:33 +0000 Subject: [PATCH 138/333] build(matrices): update deps --- packages/matrices/package.json | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/matrices/package.json b/packages/matrices/package.json index 695363a4ba..d0302e7181 100644 --- a/packages/matrices/package.json +++ b/packages/matrices/package.json @@ -1,7 +1,7 @@ { "name": "@thi.ng/matrices", "version": "0.0.1", - "description": "Matrix operations for 2D / 3D geometry processing", + "description": "Matrix & quaternion operations for 2D/3D geometry processing", "main": "./index.js", "typings": "./index.d.ts", "repository": { @@ -29,6 +29,8 @@ }, "dependencies": { "@thi.ng/api": "^4.2.4", + "@thi.ng/checks": "^1.5.14", + "@thi.ng/math": "^0.2.2", "@thi.ng/vectors3": "^0.0.1" }, "keywords": [ @@ -36,9 +38,12 @@ "3D", "ES6", "code generator", + "conversion", + "column", "euler angles", "frustum", "geometry", + "invert", "linear algebra", "lookat", "math", @@ -47,11 +52,15 @@ "perspective", "projection", "quaternion", + "rotation", + "row", + "scale", "shear", "skew", + "translation", "transformation", "typescript", - "vectors", + "vector", "webgl" ], "publishConfig": { From 10fc9cc5c9f4d9df696985550d85722227529e10 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 17:48:56 +0000 Subject: [PATCH 139/333] docs(matrices): update readme (add full API list) --- packages/matrices/README.md | 134 +++++++++++++++++++++++++++++++++++- 1 file changed, 132 insertions(+), 2 deletions(-) diff --git a/packages/matrices/README.md b/packages/matrices/README.md index c5b0477ef9..f3af3c0f18 100644 --- a/packages/matrices/README.md +++ b/packages/matrices/README.md @@ -9,11 +9,41 @@ This project is part of the +- [About](#about) +- [Installation](#installation) +- [Dependencies](#dependencies) +- [Usage examples](#usage-examples) +- [API](#api) + - [Constants](#constants) + - [Matrix creation](#matrix-creation) + - [Matrix conversion](#matrix-conversion) + - [Setters](#setters) + - [Row & column accessors](#row--column-accessors) + - [Componentwise matrix - matrix](#componentwise-matrix---matrix) + - [Componentwise matrix - scalar](#componentwise-matrix---scalar) + - [Matrix multiplication](#matrix-multiplication) + - [Matrix - vector multiplication](#matrix---vector-multiplication) + - [Determinant & inversion](#determinant--inversion) + - [Matrix transposition](#matrix-transposition) + - [Quaternion](#quaternion) +- [Authors](#authors) +- [License](#license) + ## About -TODO... +This package provides 160+ matrix & quaternion operations for 2D/3D +geometry processing and acts as companion package for +[@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3). +Like with the vectors package, most functions are defined as +multi-method dispatching to optimized implementations based on matrix +size (which themselves are exposed for direct use too). + +Any `ArrayLike` type can be used as matrix containers (e.g. JS arrays, +typed arrays, custom impls) and hence many other functions provided by +the vectors package can also be used directly with matrices (where +sensible). ## Installation @@ -23,7 +53,10 @@ yarn add @thi.ng/matrices ## Dependencies -- TODO... +- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/master/packages/api) +- [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/master/packages/checks) +- [@thi.ng/math](https://github.com/thi-ng/umbrella/tree/master/packages/math) +- [@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3) ## Usage examples @@ -31,6 +64,103 @@ yarn add @thi.ng/matrices import * as m from "@thi.ng/matrices"; ``` +## API + +### Constants + +- `IDENT22` / `IDENT23` / `IDENT33` / `IDENT44` + +### Matrix creation + +- `rotation22` / `rotation23` +- `rotationAroundAxis33` / `rotationAroundAxis44` +- `rotationX33` / `rotationX44` +- `rotationY33` / `rotationY44` +- `rotationZ33` / `rotationZ44` +- `scale22` / `scale23` / `scale33` / `scale44` +- `scaleWithCenter23` / `scaleWithCenter44` +- `shearX22` / `shearY22` +- `shearX23` / `shearY23` +- `shearXY33` / `shearXZ33` / `shearYX33` / `shearYZ33` / `shearZX33` / `shearZY33` +- `shearXY44` / `shearXZ44` / `shearYX44` / `shearYZ44` / `shearZX44` / `shearZY44` +- `skewX22` / `skewY22` +- `skewX23` / `skewY23` +- `skewXY33` / `skewXZ33` / `skewYX33` / `skewYZ33` / `skewZX33` / `skewZY33` +- `skewXY44` / `skewXZ44` / `skewYX44` / `skewYZ44` / `skewZX44` / `skewZY44` +- `translation23` / `translation44` + +#### WebGL related + +- `frustum` / `frustumBounds` +- `lookAt` +- `ortho` +- `perspective` +- `viewport` + +### Matrix conversion + +- `mat33to44` / `mat44to33` +- `normal44` + +### Setters + +- `set` / `set22` / `set23` / `set33` / `set44` +- `identity` / `identity22` / `identity23` / `identity33` / `identity44` + +### Row & column accessors + +- `column` / `column22` / `column23` / `column33` / `column44` +- `row` / `row22` / `row23` / `row33` / `row44` + +### Componentwise matrix - matrix + +- `add` / `add22` / `add23` / `add33` / `add44` +- `div` / `div22` / `div23` / `div33` / `div44` +- `mul` / `mul22` / `mul23` / `mul33` / `mul44` +- `sub` / `sub22` / `sub23` / `sub33` / `sub44` + +### Componentwise matrix - scalar + +- `addN` / `addN22` / `addN23` / `addN33` / `addN44` +- `divN` / `divN22` / `divN23` / `divN33` / `divN44` +- `mulN` / `mulN22` / `mulN23` / `mulN33` / `mulN44` +- `subN` / `subN22` / `subN23` / `subN33` / `subN44` + +### Matrix multiplication + +- `mulM` / `mulM22` / `mulM23` / `mulM33` / `mulM44` +- `concat` + +### Matrix - vector multiplication + +- `mulV` / `mulV22` / `mulV23` / `mulV33` / `mulV344` / `mulV44` +- `project` +- `unproject` + +### Determinant & inversion + +- `det22` / `det23` / `det33` / `det44` +- `det44FromCoeffs` / `detCoeffs44` +- `diag` / `diag22` / `diag23` / `diag33` / `diag44` +- `invert` / `invert22` / `invert23` / `invert33` / `invert44` / `invertQ` +- `trace` + +### Matrix transposition + +- `transpose22` / `transpose33` / `transpose44` + +### Quaternion + +- `alignmentQuat` +- `conjugateQ` +- `mixQ` +- `mulQ` +- `mulVQ` +- `quatFromAxisAngle` +- `quatFromEuler` +- `quatToAxisAngle` +- `quatToMat44` + ## Authors - Karsten Schmidt From 0ee2be0a18a65e946e4bd8bdbafd21dbffc0d2ab Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 18:22:45 +0000 Subject: [PATCH 140/333] docs: update readmes --- packages/color/README.md | 5 +++++ packages/matrices/README.md | 8 ++++++++ packages/vectors3/README.md | 1 + 3 files changed, 14 insertions(+) diff --git a/packages/color/README.md b/packages/color/README.md index 106fef9f38..44d386ab6a 100644 --- a/packages/color/README.md +++ b/packages/color/README.md @@ -165,6 +165,11 @@ col.multiCosineGradient( ALPHA - work in progress +- [@thi.ng/geom2](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/geom2) - 2D/3D geometry types & operations +- [@thi.ng/matrices](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/matrices) - 2x2, 2x3, 3x3, 4x4 matrix & quaternion ops +- [@thi.ng/vectors](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3) - optimized 2d/3d/4d and arbitrary length vector ops +- [@thi.ng/vector-pools](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vector-pools) - operations on memory mapped data + ## Installation ```bash diff --git a/packages/matrices/README.md b/packages/matrices/README.md index f3af3c0f18..a5efc042c6 100644 --- a/packages/matrices/README.md +++ b/packages/matrices/README.md @@ -10,6 +10,7 @@ This project is part of the - [About](#about) + - [Related packages](#related-packages) - [Installation](#installation) - [Dependencies](#dependencies) - [Usage examples](#usage-examples) @@ -45,6 +46,13 @@ typed arrays, custom impls) and hence many other functions provided by the vectors package can also be used directly with matrices (where sensible). +### Related packages + +- [@thi.ng/colors](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/colors) - vector based color operations / conversions +- [@thi.ng/geom2](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/geom2) - 2D/3D geometry types & operations +- [@thi.ng/vectors](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3) - optimized 2d/3d/4d and arbitrary length vector ops +- [@thi.ng/vector-pools](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vector-pools) - operations on memory mapped data + ## Installation ```bash diff --git a/packages/vectors3/README.md b/packages/vectors3/README.md index c284986efd..8b62527454 100644 --- a/packages/vectors3/README.md +++ b/packages/vectors3/README.md @@ -96,6 +96,7 @@ layouts). ### Related packages +- [@thi.ng/colors](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/colors) - vector based color operations / conversions - [@thi.ng/geom2](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/geom2) - 2D/3D geometry types & operations - [@thi.ng/matrices](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/matrices) - 2x2, 2x3, 3x3, 4x4 matrix & quaternion ops - [@thi.ng/vector-pools](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vector-pools) - operations on memory mapped data From 83a463114d6d0a0198cc015dd0cda8f65d7704ac Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 18:28:44 +0000 Subject: [PATCH 141/333] docs: fix readme links --- packages/matrices/README.md | 2 +- packages/vectors3/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/matrices/README.md b/packages/matrices/README.md index a5efc042c6..3279dae217 100644 --- a/packages/matrices/README.md +++ b/packages/matrices/README.md @@ -48,7 +48,7 @@ sensible). ### Related packages -- [@thi.ng/colors](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/colors) - vector based color operations / conversions +- [@thi.ng/color](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/color) - vector based color operations / conversions - [@thi.ng/geom2](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/geom2) - 2D/3D geometry types & operations - [@thi.ng/vectors](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3) - optimized 2d/3d/4d and arbitrary length vector ops - [@thi.ng/vector-pools](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vector-pools) - operations on memory mapped data diff --git a/packages/vectors3/README.md b/packages/vectors3/README.md index 8b62527454..226c0885cd 100644 --- a/packages/vectors3/README.md +++ b/packages/vectors3/README.md @@ -96,7 +96,7 @@ layouts). ### Related packages -- [@thi.ng/colors](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/colors) - vector based color operations / conversions +- [@thi.ng/color](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/color) - vector based color operations / conversions - [@thi.ng/geom2](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/geom2) - 2D/3D geometry types & operations - [@thi.ng/matrices](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/matrices) - 2x2, 2x3, 3x3, 4x4 matrix & quaternion ops - [@thi.ng/vector-pools](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vector-pools) - operations on memory mapped data From cfc88744ad079f1f09733ea8edbc28adcb67bf1d Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 30 Dec 2018 18:31:45 +0000 Subject: [PATCH 142/333] docs(color): add porterduff image --- assets/porterduff.png | Bin 0 -> 69726 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 assets/porterduff.png diff --git a/assets/porterduff.png b/assets/porterduff.png new file mode 100644 index 0000000000000000000000000000000000000000..fe93829379ef95d8beb5829590acb4b1e01b90ee GIT binary patch literal 69726 zcmdq}^;?@k(*TU(6ev*KrMSBlFU3QO26xw{xNDK(?i5OKf>Yexp#_4wyStwBdEfUr z=llWRFJG=J*WSCCoteFNc1LzL;VPfyFwsfT;o#sf738JW;NTEKVPEk#2(Xq4M|}ZU zfn@a&_z@1SIu_%}1Q}MRHj`Ha!ohhlz`+Fs!@)hkngaIV;9R-j;0}!8;DpoQ;E29v zHLHrk!NKd;XlT1=1C@l$zz!TH=3r9`4iAT~upV%5q8`GqM+XZR6KW3!`!CMI9%3~A zfe?m0|7+%?q5cnui=7yaHc*B76WGaunxBJ@gNsHSotm0j)XCgZSWQ~?f4jqKVl>t+ zE?B zDy-~eV*#W555G9K=zk#p|JweSjwt6p;{QL){Le`L(+V4^IJzk3e_xw8x>7fz4jh~$ zoPzX64G;LEHq11GSAC_Cu257je1{w0M2$gq&3B^goJUFcP|^%}C?aaOo0}Vm;wU=wmE! z@#up`A6srE+{ZF}$D5pYFSA8-chjvV{43jT7VMrU7OZkAy-$PUEy8fTdDg8u6q>vmFE8_e5e25^pDPe$Q2{Qz-LVbgYo{u&cAMK zL-GH^+rJ7s@pt+r!j|`0|7DK@4gDY4q`;{nsEA#iqdZmAerUFqXqa|w<8YDZ zUEffNIP@DmFLw?rJK8%sasb2u8DhIVHAoP|1s^{5v;Xr z65#5--0ZqkDDJfNrocVO)oUb$oegR=o@Mgm1{nB14B?<;w>a;PlW^n91_c^gt#yZB z2(EZ+YIQt7m31twV7<*v_YdfjHW=e%4MshYHPY$X7QzZ<3+`F&W%xiHRD6?)ILNy?2k z838c5>n19z+(-TQ0x69H$Y!gN5xd~tezh2lGHCO1B_LB4Jr5@AtMom#+shJiM0gfC zY5c|^0M${U^1Cwu2YN5hgZM!Y8CWxo3SS6`H|DC%Gz7maG5w$raZ|ZAh?~klJI^5? z%@sJy7W1}Gf`iSYia*N6CzWzU?Wc}ClC@?$EDt~ZJ|sZNiKX+rt+4m)Ndavn6Dw;Z zO==NDvwY*1Cc2k;6f|C|NBggiX2X}|VdV2rOtR7LdWXfE)71%D+b`h~H*;o8UoV$* zMUcX;tw z%zXRxeAw6WMC#G1C;d}%)3H%MM>|A@6~JSctLd((Us@K4Eq+IRSiL-zvOPfMPaa2d z&T6+KX#+Ae$@1PY{0I>*kYGGR|0ireHQ)AvoXXwggr;#2)->`s0P zhQF;AIyMx?I#Ogf4P>n>3)0a*P>^>u5vv%j zWj}yDm~3F>1RzigR$$31H8vuvHQH$+*drU_K)ohyCEvMKn8ag zq(l%Qu*Is|qJ!n-Nz19gGo+#!eRTMk)4Z-XBPL)p$cdMVMArj*M(?Pu7)HX&S%nCi)AZKPJ^!! z7lX7b-^C(QR9Gvt;E1Blvw!vo#^29&@M5T9!sLB{TV>aMqPxM^IEG{mYEd4)q*p%y ze|f-@!#tVHZCBr94%WYHGC|v~*!|;0pBa;J)~e}%?qx;xfeMtMGCOcnDCkt)b<9U+nG?3TCHCp9j~RBN$H z)m>UyU?8i~>HnGbY2eo=B{(xVT<=uWDXElzON z=Q2$E>b-AlA$K3!Gv zQ}o1ds$<&@K$RPrJog8{P)WSegAqv|6Go8B%4PPg&s`6drM_r9^U=>xiPfhaL7n<0 z1WPuy#YMeTL$CeC)fczuzBb3`K4-`Bu^r`re?rZRcwUR=x+1c!S5C4P&Z%sx1FS6? znR3tQdpUqqW@C;_-LkX6w)M^kW!!EKKoO z#V%HfPLQm5vd21IBh&Jdu}mae4PA^rkj%iqj4esNTMhA!SZQPYU$4SJm^3NJH|`Ps zpNbo0gJGUv%Q0d9FD;sXwEkZJW1yFyoGto6R8+LKD;TC}&8R2YXz5C82RcJAhz1*A zI%jO$fpl6TIY|0i0qDdj@Q5CTohlD50VE?s1)QF2XB*faTPS{pW z>A4j@U**HSxKwR6Fj)ZDg-1*s{YFd^{GW*o3XDt-{2}5#9(!i>%#yy#3e(8CHReM> z$QX?cofNM$j(hft^J@^;e${r;MltYMD$j?<-!U?^1l=x;*= zQX!+pCn4V^g7;%IP(#x&gd^UFWh9QVr&7mVwV1F79B^N3^!RU!1YB|8jd?JMBHM-v ziS+}@nvsBl)@C#cFOM4P@{XSH3HEc zr{&>-P4R z>Vwl3ObdVe_HC^w$1j6>JxC9e)aU+Udk~vKICy+#EYn8#>smktY-d-PYWIEooFx>9 z!-Z={N=z*2G(h2gG+!&%eXoiuPWKL974H#djS#Gv#fpVy#hJYQMF~^-ba9ddz&Ben zn86d+xP|Zf@RUX2wanjyBav|-8YuGK!6&l7?S=G|>oxH7mZ%pQzg>xAl?Qe!*=&y+PAk7R#@4_|dzzD%?kLK=mML8p8i z?GP4nRNwc($aL^>%bT-k;y#q~4R#Pkiv~0hpq_@S^*+T|;e)m6VESu5tL#bZ<>&K$ zzrQ%x7Du##zADAWMv|q7F`U)=U&n z4XTulsYLZWWZ9~?wusH@ec$qgl)>E zkHhH@bF5xnC}Is@G!nBm7E89&%M*jYtM-vi#~mU4_gPNd(P*<5&b(t2{KwlQjH4% z7p+=n%>FF-=t;uUUS2E@wnG=wc2F-(j%Z(T{E}CkHFu z@Q2f7_ti04CIQpki*BrtS$*f|`K>i%EzPz;_z#=&)Ozv~jtFZ?6je(1YGu5-(klnWFz z!)TUK>h}%Rh~T$K;8L1hYB&ku-0GO$G{M4jbsL!eKM_*jNKe!|5>&9kn3T!o<(=#a z!llL*18B8&%!Sg>{AoneMS38UM=*}80^69=*HMT@%#0=eo+vf zrwmaFHdWcS_Dq``WFj5Z;X2VpsLH@~`qy!14^>7^$4&|hwN*cihk_a0ax6e=Q1~w6 zq7|t%WRP7`ik3MY$|X5iP#bAZZ*i;*Cy^y#IZJYx@N4p?@wd4;%Aat&vZU^cp3&;* zJqp>`y8C?Oz(X}#w-pQp0Rt-MJuB`t{XZTfrn}bGQ|SyRf^pz{s?o)M^sZof*VB$y zzr%4{g!&PF_74v~gV`l!jr_$ny&ki|H}o8KMXWqL>`v|lpK6&$+w8PWzah!jbI6iP zwpLp{Di1|sws>M_ZLx@8@Vh1Mv0wDtU6R{GKk33h?aEm1&>F@wF69QwW`?hTbk~QC zo}Ecit9ws8YcB~_8^X@*C8k2ZFl`3MU{a9AZGMTmtlc$S_TOGCS!#Wq0|M)WAfkk!sEW}d>A*-v{D|~ZZ&!>&E=3kgsuf#@ zKUbrLT)>J!PO?;tUuvLmn0BFW^Ie{4?Q_g2{}* zj^BdX8uy#AS_BeEGhUgYC|tjY$U7+5(#kkGW?0}x9eR=;Ex9wtKqrYDKGJV*CDR43 zh_U(zk`~ zdbh%_d{1flSmV-O3^3}POUl5UY%aTUFuZQWP$-Ms^wlin9bbH;A5 z%A3Tl=KLX2h!N=RFg6xNJP*m(y#KBX=J`oWD?u}Ye7=@Bxd0lgGpA$sch$WUZ6ESm zqB^{qUk}~7$|-#G6Z!GtL;4hd{gfeW$9o6_<8sMV-Xl|L;(Lhr+FGBXP5~?J*ciEL zFX}dl@dA7NlS5x?xc~gIB5TEzh(}p%R&A|bQTqFB

3w)z!IpMx>kwKI^wJA^_7Z zHg$aIz3)^Je((;r@V=Hgtwv#z6htOV=Fd#3^y z4tvUzJ2?yJV4}tFwX&0+hJus;r^?f=$XWjijl1XR+*OI@O$r-ciL0VdhP#p6qtQmS zO+HPBcs8euyZ3W(x)wvMLQj0Obe}_qvTg`?fUVU6;8*KS>9ZU6RWuj}KSCpK2cZHN9-GbVVt=&( zC?01`Fqej4mb2+bBv$-J#O5-zFtv<);q7mv%@;jLpr-R`!TxxTeC)HXu)pOgbk%eI zWVz+IXh)Bw?b+YMBh4tl=ypQ0%=dX{;4|N>8A4DP0s+0FCgi$<@7PmLxK2Xsp`|6o z=houE^#K<{jCErRdqLo71k`|q^`p6?i88YKrd0eY+Z2YGRjDE~wUp*dS{*>?C z+4}jhY6~&RcgR+xW96;O=+cKJmyzb^SJC4;!El-1)yW3U(G`5;n8#oqqCcX>D=#B9 zcaX^Y{rUUzn)8?E$A;DR?fU5bm>m0+MM2#KII}Xbp~C*nd(M1^$I1I$wvdK<$JZR* zC-~xk=3@o1w?aB^=QD8{otFJ^W`%6W*2X8-v z%&EtATSvUx^6bDtH}=RZvoFIg#;v@7!-C6=KUHW$puZ4NtHWYWOg3pi!(H*pmK#)b z((h#ahsds~5YBL`MZo4}?DJf#*xl;s%V|e~;k6inNex$(j!kFq*iAw=AF?j#Y#Yz{ zE$7O)9fr~LY+jDR`X`{>OxgXU(UWkiK~phF8Zv;rr+tAY_o>4MJxWWrU5LHypgY!~ z?RGNt%E*1$b(73HufGS!L+`G9a{w!U3TwjKO2tuU~LgViYUvoF)~ zW0!+I*Y#4K1!WM2_q7F}<8UinIlmoj7rOh6eS-(ZDc$Qmf1DlPK^X_5TTzR@$p|d| zI=o=VzS$zK>GMh;XdvNY?tf{?KTgw{GQHsfp zC)7Qn&+4~!K+#Yz_FCG9D<-@?rp@C^_v6xjSq`_g+}mIG>0#{g<~Xx+d4bQFvi5+A zbN+JW_Y3=G-i^IWP*HE12c>xG%(GPUJ>yC1W{imKCnX^sqPM-#hfT&G`qQuwTaTKb zphkCn$K{)}^+IzcM^D9!z{5p86&;U9AbmS{tGp86{<>h*aRm(ldm!cnlsxt$KSv9$ z+{I9d-H!W8JaGeze9^5NBcGvd_eRs`=9J0?3s zdrkcJ=PFk=WXrAq^}|P0o9o+xoVoKwN7Th?C)LhI#dan)=Tnp+hl#0A-k#aBcL?u9 zJm9b7j6;jw9+hI*IdGzeG(#XtC?GVXF?yuR$^w&*>XOEXU@&3y=@;4N%J z1dn_Hg!#3dfQK9@doImRE>As`k-;ghrp7bGc4s%`d{@@GwY)z(_B2|LWl9a{^h5#e z@@_85p+mcFF)t4*e|J5}^XHDziUUex!YA#GbXS#tDUsXqq#mBaPI3!Z^{zK92r}iu z@^`Y4&aqTtXYg{V$QZ`8lOw!G&|u(uyI;D^b+ROPH!kMh8z!Q+lK=ucn&5^ITIgZ5 z=X``6A6ayYKtTJ<$Ps?vK3~_xsluZG<9J1*8|Oi&xgpOxz(wm)`Q`iKenE?uMfQQa zDuz?~XbFvEa`f8oKq^my@#ZAWaxey4hvgO15SdkhSTn~K86(!~!58s{#8oY>iSKx{V}qE{>sMU z`t?@G?r=2?#c261h=>tGDCb`s5oUedxY(12uDCBYCC>_etIA78?MBDVdVYV44$_xr zWF6B;kJoz6yV^Uum!o`sB=ys7ay+~aOL^{~vh{nJ%hD1mB_(`M*cf7uKC^X3B`&^xdiM@W0GlJ?gCs$TEJ8r1IP>5?}Dip^6nn>;ERhf~?NlWaAY=bMw%S zkzuiTV6mS~+q3FpSm~El##R^y;(4bvlsql{iHKw^f!_D|>cM|fSjbY28+1M~0^%<^ zHr{oOnDa_+*C|GzwHX-OUz5ANu>F#(*s$f3jBfOcr|Y(OO`jQi#b!d*`^X!#o)RLK ziHl8Z>+x;9qUB`c`Jezm&fA}WivFjzNOK6YVZ-5jgek`G%j|Rb&2!zHqrCp3>7T zj#D?oRalrZpy108zgE`6*o<65UovMn0EEE{$Z$ivbpiyoaDa94cgEIeYnA^`bTi0p;0k=SEP}s zXA^*%Vw8DDCQ@iM;Qs3ZwagS`l9$MTZ-{4lT~}jbXTSK6!sl|q)KSXEa3HWDWxE+0 z^|E#@5^eHtO6W3njw!>`LI-k*Rryw@gABAi3vVzfE<3ViA- zC(z=Xwr+FBOCIZ2#Qp5ox~u6Db>7e2_-|_l%bQK+)6K>TEKoeBkXOy`&mTen{cSml z*y8G`WN**vcls@!vgf*q_;d!G%_hDwt3;_0jw@yq_8azVj~vy1V{UUggdM$ckuUmK zP*)`E9%dgy8$BXgU&5v)`!+dsgybEKO{dmN@c9-8nB`4}%Rem^$AAh{Kp7dR!0j=? zLJWW3W(K0++a>3TW3ciwr=2Ptm~jheOCqCD_jh;)F$W<9S?kM7Za-#dhG_WiY* z?0PJ7UDcyM0wu^O2v4fYP&Lib_I(cpo79xAXODPT4Ytcq{#UcN*zF|*PR!tblrN<9 z^2qpsU;@oll8DOlWW&{*yZAAZ8bMdy*1E4x9ppRsUz6T#mJbHpojW<2I)Q*pKsLC}g?5$jb|z092sXET zcYD`M7gjro+)s6#Z;9Go#?lm=VrD%z~~0F`AenG!A&ilASWMETbgXI zMzNGF$`#Mc30JIm!M1S&&^wd!HKFyuNh+ieW(PchCirNJf_-HqO{2wU42#beU%Y%H zStH-9HC?1J2-uKXt0#XhWcFPhfz)*|JDz%7CtMnIxJM&yezx$DHV&a)DN~TLV;=_6 z{3uMXz7$=x)fNz8YI1M8ySUU}8nI2f{C9Y>yDEMR{q6y_*t?C5rJ(tMZz=bwqu3mX z=%11#vK!;K`gjgH!m1fCxrFApVDk~6RxnxS5rGw%z zP_tt+bGo_Bm{9lx;rAgAnFzfxSP*70(F!Y~sp?6A-&f%e56DVf(v6g|Q{zll%PiLS z0v((HW~17#GBno+b(yR7O1s8mKd2Y(lzZk5?A;wm-#yjt=Y~-(G&vX9E0-@dI&OA$ zc1}Mefb+oY+Wz-S&~G%dG$tqu8qe?4Mij~LJwr1QST#8mz#?ZQGLeMo=IF+UGv%^NaYA3i zpLKc){`p~*^wXgo2eIzQbZnid_R_}bzAajtS zYiSdfO+X@v;T)`T{U)bjz(u3a<)_6x1|&!6q!FyW%fB= zA4;57rkBb1G7ayFK4lG0n=7o;Jyy6ZJ9!GmY^kb7;!(+mnGiO!wI4)Q(~(ue7j|_% z-saDi+iyW$8eRKSmL)Saphs!I&V05c7JrW^z99QDTf|jW0YvTy?*$}90G<~dhi02f zKYg`Y_uuy;FX>~23=-mVef0N3j5)0b5t?Z$&L5a>2Sk?Q(t8ot^B83biZ8U9E1~8V z-ai!T+<1!LzTj7;Df@aqoexyjf&cWr-L&PU&IN6!1-B>Z+ZLJ?`asa2%Nb=vl0Z!X ziE6}49K|PZ$7G?^T-lcZ;Gvt0d=tK)?s#NU?1vb#nop&6&9d&En ztL~HKnZng{?upL|QOArO%BI^Df_&l_a~9ICF*rx>h7r zbl7KCIb5~!BwBu!PH5$P{D?DjaYH4xBh$r}nRGJz3Tn2k?Q4|@dKap^I{dtbJ*DJd zdg||^81x8#1{c!C?f=#duBF z#O%UcH-#_oMc?l7g{WG=-bJD8>Vjr`TBFXf08H;xX>7|tr4Z@DsR~?XVjRfquAU5t zEXF}{vg28E&0otTUDlTaffVNf5kgZoM(l1m`N8y_zr&=ePTE=YbuFbz8P2H_A+}PO z2O%>^Ov|#QIS1Ljpc<0j)rwSkS%7K%(j0N`9#kwq4I71n!(*y$`CxhFl+en{D z=6s3xD{ZvYZF)i_L#TP4{8TAIdX@IrRgu;xT}AqAp8s z?mL(xHQH4P6{;AbPauZf+U+IU$-FWY&XanVw!qQd0kv1jPg=nCRN;(##(;?inqBm% zR9SgKgZ@z60gOjme;ioEtzOGc2c&5+6j79tA@fr+5(Qb|?HvOeaD$&d$+yzj36C&Z zTiq(4V0$SQ{p0<91cj&R3tXu+_cl${i4$9`4!-3>A@zt4!hug}>Xx%|w3X~{V&03X z?$J_01C+8BS2jiKgu0zq?jztm18*`~Ig9Z!0Fr*80r9ae7hP>l428huWj2uPwX)D! z4!g5Oo-FY)8_cW{&k7ux;!47V*swNI+fcQBf&+g}V^}W{?uxOggdiAWO8z-@Yaxf1 zc!Y?Tx?xbu!B}8KAP^1UYU4(6d=j13%Je&s0kU~5(xYYI3QdfS$#FgSj$P0>5>h)^ z8X%wz6bMcNcJSXZ?amzF3rT;zpQ^U>8xF{oOHCOK7L`teH*!^tQonT4;X?a4mP0jO zbyf0Ej%UIsys~5d)l6ZgL}@1SW1WR0w5+U@rh#F-l*KGPXkR{!ziyfoZ~^dqyRt+_ zUjF;VLMq*Xf99ma)6P$EW7}|Jn=ndCQXX2L@)8n{jL6An1N_J~#J|kFxnx@~Jx5nG zj}gL5&zVxV=FJb4Ye|!0_+1*{I~}sUdyKE81Wr4dr5EH!A8}~ot2|zc+HI3{!wRUTql!5}4lDM6 znKNmpL^#C|LlYk2l~BgM%zI{K9~&S@GREQsqKiLVQ@0=qr0rQ!@OtUKa`4SdO|G%G zupAq~oW&fKZ@2hJ;vFzEr14=)s)ftCzJ`@w{plBE1q7^xZ3EtXl^@mU`6oo@DrDb>J<673mxZyAhfxK?s7R| zYI`gQlonSakr-)Mic+Q^dG)}f&c%n7i2N>VkPfjB>M~^kW`G)G_ z@*4(YEswCL>7ZZ7rr%f7 z1VpKwROM^-OKXRp;zsKfFyZ&i9Rdo`|M6%$WQE>`0x=x|A4}^LizkCod{~7N1(E5y ze-+Lv??0{9uN?E(A*9!_QRJt#_Jb8uD3DKZw;-hRHO6<2gATZ*=}(?73j zrt!}TwsZE=%%$S`_OHv)-e+bgF{!YOx(Guqw&!*`W(2)B|Bj-o5PnKT+AQ3xMuSKe z>g)37!W9TuU2diK3bHqlHlOAE4HHl0@L4`zTO!-UoTa;M^(>oF!Zhh`Wlr-eq;BGb zhNzJN?bCxYG)fhO83c0`3Q^aN@BVlQwgL!~mZ}&)k*&GL25+fkWGGqy?=_XPo2tTv{vBRbOcgSu+ z*d-Opbf@_gaMJksbwHh^?R8QfuO%**V}et2<?Mm38CW+16L?IK;FAWf6K)w}+ zzoe|j?327nx7tI}!XK;4Haak^Mq&vN?Q8Oq|Mo_r|JDWje2rg(lV1Q3yj&iWj zroKe6=%*)sn7=XqMizJUqBRp=x(cv#CcoFgnlAy_hdIJ0e7Ep)Tjprv*n52NA$68+ z$L&jR!cxo+(zja8Qdvpf;;sh&O3Jq}ce&HjP?L%x$ zIzbh2xdJXE!;e8QghnM*=>%d7@v=ZuZ$685c~T~|!UeWf5MZwORhq5%P*Ym9swPVd zCu#EkEG)BqU{4`!QJc#U<*F;3X?*4gPd-TA*E`&T-&IrJ0=^$fWb;8=47NuXC#RJz zm!Y6z{^2KzDdA4dt|P8!qpmGgxs|kn3DLC!!hP<}eTfQ-0wn@;sy)`FJ&a9AJyd}R zUv_2LhK}b-0GY~~vB^J%Wk!q1%4`+_>Y}}?5+4!5 zCOytY6Gxn>;u+zyn3FW=U4R3x?z-(ho7gV5M8-sMsm`#)jh%gYxe-<5ETVu>nP|LOF;DZ(!(P;5ZF^=JE+aIu^T;?@ z6Fi&&m!LO~j~|O4KCGlk3>42h&4RrL+XT%qW1sSt;eer-Oh|_ooxgaIi593kpnoy+*oNAwQU|#v z|61kOR58V8r6DOo+HIuR)MarW613$&nHwa`+UqAT*XJ)*-z-(FK+Z~?t;a~_2BoDD ziLtaf%3-fnkM8B$+pb@Fg= zw{`*Ln}aLHus(BDDM*H>3X!6K?!3}QXXm9{N_*qH?judg*1{=Gj=7@xb^&LyPeK5u zxl?MM=Y}o5gl0)i3H;m4!r&>^57LEz)R-0(hAcK3GMvsG2+6o`MoplSL}Ekv%C*r{ ze>7Q>qzvS6ai&}^to@Jw!(~i#$+;|De|Q5mgRhM(+$u!-I)lQL#GZ6KdL)P+h`j_$ ztwr^30WTGu`b^7!Nh+A6)#$;MS=TI@WNvbDOXDR64~rvmf~fhG9OW^a&1q7=fZd|O z){C)2;_-~)8l6Lrue&g}1Myo}@naynjp(*Z=j^$0ejMe0%0w;#RzLBse1o5jeiQrbd0$qN>m} zbBCX(1$R8(7`)CqhI|5Qky&t`{gNI&kby9JWTjsS3uqQ@Zd2M(8$Hat&D#;wwX)vy zy&lUH1V4V?L?01oMxK*31zrqm0jlQ(sq5-N*)&wIhk;khg0c6SwoAb^vipK$gBUF_ z=fk^cCh@0$NUY8jP{Do(u=PrY_VCer^CJ&;U&7K-9Y1FcT`f6(fD|_c(3HCN(==bT zg%gOrp(b~BLB*K$#%5XICwa-433sz;6Y$LD~D3`-f;S#aT%x;Lp&L3mISMA5nMO@@J;7IA}+ z{hTCW$PlJ{Ad6n%QrQXdUix*~8&icZCxaP8=9#aTHoKQRfk#`M*e{$r?JSUPKh3MYW4;TaKgHFq2&utY{NqmryZB$BAE-W z%#B@D;MMlyj-wgT%`WYlJ=ky&nEsgi>p)JotEXFgQ7#D0TYnEtPutRWatU`EHZf;@ zh6gVhr@=1mD4cjwwodG{!mo~?S~Si-pV97LU8WSy3a-{^t_sit`!vB-HtM={Ot~X3 zTSYk5a82tpgI*;IY^X*8JdMSKs&0GIY(o^dPzQbh&!nn91H5)jJ&vWY#(e7w-+2^I zFQjVZ^?dE5hamSpP9&DbtaGEhCT_^Ub#cA-W7ek+HM$PXU0=@vZO&vx`=dNU8={0E z=-T{;dk|xoBgo^)2)eGRF|l9}{KECt-{O27FGPNJH>L+!@^TmjS7R((eFH z(LA-21gYj`Qa#!+$_3U4 z{gz?ceIlqFz;H{bG!T$vQ0M3aOW{LxH0NJ}&BJl(W9WF}vH|H&A}^^oL#2kOWu=_J zTKu~cCY9@cK#P*%+;2fzWGk(+`t5J~M>$%-IiA@dz_P%P&v1lF4x)y)xh^L_y(v4* znB&yRbzvOa?>j2|EThgjT$Finpz=smYSaMzM z5vOPIWhY5^r>=u zx`uyy#uCMNCcBQ7j*mBTVCvP)pOO5!vU(wNMSv}LvZ@%`aJ?D#_L>2X_<2@X%#4A5 zQRG(^?fR7!2-|0ars0SUVHGf!>LEoW5X|Chhm&ck?u&vElkh0+X1)A4*~BUMqgt{R zyFjWbpTXoX0j(SwV1q7nKU8Zo`?@FLcBDPqQGrpkV87Jfe!P1U-0*kx7gIs;yX8Gq zvX*{0ifhL3BM&quv_(YTz35C8NnjE&pOQNBmk6uYHQ%-_OuY}8>F8h`p&d_ELl)Jv zO>f7ShFgE^{2y|p@uU+D%_H)f0>Uj#WwzytGWo4)Hn@_YH3q@8v~~8wPn8F4*J;bR z0H<=N+HR79k_l0TQrua)WkG z3eI>@$_AC^y)ET4VUA;-(ts*rDuzoJ@Ylfum($rj^lQ$jDpqb@m9iUHBt*~#T;4{} zjlb4ErM_HY3`|PwWg06^Vwgf_Q&;FY!NoJMXc-%~B7HC|zdA>d<)EmPxYKb^Na{3m ze~fQ9eUn*fbManL%635jeSu4vE%o6cq(B(9kaTxF+?Y1{cG^!V^=o^URoR-8?#oIM zu3+ZFZ|-fEyN!I%Ywo$?>;V*lbKBcL-*YCI5-XC~b;`D)^sAGHVgxUsinG98SjVWe z9qqB5#R832Il?Uh*HdI_JNHvqXts9qc25lJt z!+2j_%V_BM(a6vAFzdkt-d6ijtgO&S=X8^Nl63HMA zaK7_AA!;Ut>bef3ndd=8xMu>QHD1t(hH(UTbLSPh6>dA3z3N$2DHfD2h?3Iod010kUfVh9`N8b{ohCo? zFE#!oc05+_vak%S zZkK{C?(VWD_}Tsr7B0SLpoJNqs4>#eUp?uq#cSQ`mp{o)6mEST_j|Ama9Rr*55@jtE-WAfseaJN^SDLnM&M2ns(f92#@A+1yCx#yqP>h0kM! zFJxua-^H3{Wvf0*W13P=1y}dYCVYo!%>m;6+Msdsp|mdFpTV!RDugwqryR&ewrs;R z-f!&cbX>$Gt15qOLb@yTUoUVfVjqcSSgJ~d@BkMY+L?#qI>HYu3j4g!4E>svQ3v%) zIQ_DWxU`VPq}qv*;bd0jAHuGuRO|*f6)qRG95(@VR(%1KD(fw{-+yh0^8Ti_CtMllR>_b6yF@`ZJ z8R_l&e2Z3fYix0gZx>Iu)Kz+&|r4EBMS{+V|Q;jFN{px>r)4-Im% ztGfw)%)FMRr351mb9r@|WEGZy+Wauj3P|~o&0DieKpWKrRzqe;a0 zjTy!`p!KTX{JNwV)7SbQv^YVfoMJ9s`7~!1TkiXq&HtL~zl=J0_FA%r*;1AI94=@E zDt|-I-J~F@V#Im=kdS&3ua>KWm&S&XIJ=87l+J7Q$GO^(M>`uP27j2&0&|R;FrwJ4_J~w-Psr_V&liuU%Z8I#n8}(`5gVa zPN?k*;HA9RwAJzNVEQcQ+=89aUufuycEVzudJzLa4lu(8jMqcS{5&&qXg+M1*yszr z9o}jeZm@Tp9|%l9wuEwCIXrw77870BHGQ)JS`Qi@;z1DQ<1*ZH}7XzfxyvqSy&|JzZeK@omZj9g8P7Exiw$dH9 zA!&7#n(BCpp_f=h1^du^St7@=kqK+lC*I8r=({^p(Y-kNeXOimcuQrcPu}5UoCU;~ z`ey&Vj0G4x_MWAjf6-3k4zBC2QUZe!v9zj7LGalq)n)rT#MkBs?izXDuO+65M{l|7R*Sd|5&VnQ4PC8iy-E+ zO{5^gt#nsHe7ecB5)H-FDBE4BNo5u$%ZNXhCeCsY_dsAov7F0g={M0mzSv#dsqG}QY z@8e<&LFc3YmKsa$H5Ozxd;OHDU(oVXPy%Q`IxI@a!e0x=e@n;5wg!=j>YY~nSg4}Q z|GvF?C?+d?Q4Qm*-ROL+6*iT4>+{Q_;1Lz2&)7YL1AJHgL}0UisrDKddCJ8ZB@TC!pVRdf&1++0+HxCP(@m=j=OdX<34QEc?boKL^)tl;z`>1oR z>G5Wz*Oa10zd!uFu7`R*GhlJPZF4*_wKj5(6-W6JH5EKPkRbYA=30f?abClck|48{ zu1E9u-On9<&~-s8kHXF(x#qnZJE3L$`ucjF92v%FUaa`T8WrD6S|X$JFwP8^vLr|q zcD42ILLDM13Mx+N^#DI1C9yc}H>bEaMkwjX|rR^}5sMcy}J2eP8b zWwMb&**Qu>8IjVZY(P?WEC#Q#z8Q!9N^KMp&;All^MfJa0%s#-t5-Ldate>G!A=aa zaW;PiM5EeQ!2ah*rOr5RP)*SJ+6Kp>Ij zaA^v9o5XUD{?W~hyO&FBsUxj(#=kq!^$F&mRGCf0H28BXEgQA@6__QNnw$(lM#Cig zX%fqbarLmwQtT?aj)r@S>2${QoYIUxTDnl~pJ=_SH z(dtHn^tF@zX4npHW$vU=%_cX=>lRG^gLoDURg%M!)&cx~*n6v}I-0iqGr(@eser))*Q{zUR~Y0rK-ED>#pni z-GJM_Y};-iwF-}-(d_puvowM?n2WY_fq47?tHf$|neto@{zM6(rhMeSBuoc`@ivxY z4k80oaB|TLTa%%4)kh%#D3vBSU7MPHUrqxeLM^nn4F*F?cMSa>n1NB>^NsWb*$DFp z&niS(^;!gIol31z>EAMY+dT}F=fnsn;s`d9=A*K9opPlb>^}aru836(McBbRazy^Y ziQHt3NUXI+(^qe27D)S>3bZ~!Sl?Rp0%~{mMbg|8rtGlWZnOopZc20u6*G`3DAq6} zt~*K3;stKc5+Q6LuhmAFT2vK_BNS+Bpr3>A^>6hQ-K$`Zr*j6Im1*UO_xd>SeD;o@&`WFSY75;4fI9Ehm)1etxM6bW$hsrumIZszh z373faMivW*8-X?wf~zU@O9^^ZHbLlk8Q8y*Ohk%3f30&&H=Sd@Z~?XKYVsG)Dlp}T zCRU>~vXlilU~)1DP#oxG7Fo$7>;W~L)Ou-4K0~gkCBCPPk_1zJgvA2Pt;Ff}i6<>c zl}P_l51%{qFFg?UYP3J*QCb&b2Xwva&MFz$Q2B-&X^S>funJS7f4OJqI&iD%0pc+A zx1Nx<$40?x%&|p91Mrk|piKVX)3hejO)+%p&HdWF2{%bnmmrr-`X@&~X>-(HK+jiU zd)0g!M*NU1R5?u!wi3VpL_V`UP))sTV2rQ_MsO`Dx>~w%$(681r>BX(p?}XR4Lw+8 zYk#TcQmiKjx0sTuHmc{U(J=nA!fM&Q_{&ySd|#~2?XvF>AkSdp({W>zd~OaXH#I1bDz{d!#{}uq-0P2}vN4PZqT9ymU0E~u}T^7Z^1<9g7i=>NI85jJI zfx_T71o%^NV`$>P1qL61{d#;Hh|2u07sKkGhh>LS>%RruCcu9G|C0#}_Xg0r$)k+3wT*<<>vF zGZne_OOJqIf95zTtaB^*>f+J@FDDyYjm>-&4N+8u+p3Qn*t*|5^=%Z34Xd529rDRS zt#v2GJwPY{1VvCszkj+00Iq?@$%~2%2m)Pu!mxHn)1dDv@6a@22kMcMOsWEx&WL!s z&+1GDVm~H`mP+C!A5t`8LV%7^{sL@ix72VBAX0#H&2U8E3WYdAYgyc1pKqO+(j1dE z^yIN}Q=O~9wWD75fIX45w%A0<+SwrWwndlx?dU}8aDvSKz~W<@mN zk}v14?8y#yvwWYvbPEcez>8vdR!xjDCKiF1;zAz_4N-dD&qgSjrxtM}+~2DtS>Vfc zIO!5);v_vb%Ex{wV$r7`(0x^kcN|5-qgQ1w+iLA05U9SN7O4?}XZ@?7%pBp=t6W(` zcyo^s2YeQMg(Mmu1p6R|@mIsHDB3Av^DEs6l>b5tZmL0&B=TwNh;Sd$ zuo@%4=9veHkC`iod~Vpb@%aTE3kxg6fyM-lPLAtvTAqJKn2mV%jUa-roY9RljU#VL9N@MbT(t93u$ zph|ZS)FAdcV*b(!#9sl(3?iD~nc2GNCJ;}T$$nXwZA(NS9YL@h3_OLeT#6JjN_?xA zSvS|;v3`9xs}e@hso&~Z8!YOdFQ4}1ebqz|m3->gUhzI4U=Ee{^J{00Fx_hV07fx? zNC{LgLltn|K@LhD1Ki;kC?aTDfz%G-^roH@^=xQP)4NO$5U3eSs1q`%9fwOM8MMVE zDs5C9bCXz;`+c;MX$WN->Fovr=FAU!mAOl~HSr(PvgNR{@8_q=2)|P_Oh)~Ng9@LA zz=9U=;rrG%G<0MBAjcuvv-1dSrsonKDS;J_?8L+Jlw&?A$4Q-py;k$@HNXx=pdvhu z7lr>9!p#)B*gz@!hXLX@4U>*5OVB&@@UB(sfF;!NFa!UCVhWvuKS2O&I&a=pY zTa^D~KTcs9()-g!>y`mVP{9#Ph^{p(hot|2_QbHYF3%R z*t{rx)fAVr>}+l9DnYE=P=;Z{l)*fn(h93S;fmwDVYB5T!gj=|mJ9B@+HMAi^(l=n z%G)_ES8u-mvcYiQJS)nUU{>;x@v>PyL_*BSZX~Lb<|F!2Oa9n8))Pr|8wwv{SsNw5 z^D(WL!zo1>|B)i4^0SON-vI-Xa|%t=gw;E=mMp6uHiA0pOe$UGA4xaU6HQXdou58& zBtC7?G)1Cous1d+>kBF*ET(fZ(;?|qB3M%yy@zoeK9#IqrT>%DC908C_KbNM23P;+FX%;TX2MKZThjBcgz>M;7xuR3<4)zjwB@S0|hyRe{SMDd~drX#d3;G3OIO~)FO4rAtlmk*Bv2?klwlhFEzx1LzMW<0H6(~lxi3=j48tD{u5Plp?>GecM8X8;eV z2sbSTVLWy~(x>7(dm=VAIUb`c9SfaZq~YTCgCQ1UkhrxobMRA_q)kN*ud!9IoG~oYAe!>v8{R-?t1(zfPU&x5B%3pXUnS^n)|Vg$$Ohlx zE{R!wZ1dHl9W#7+j~J>XhF<72>Bfd^uY;tC6$0vfi$mt>rC1M+q=g`B-{Ql334GUF z`raSK306G@Ggtw6t7H`$UQ@#m=#YRgHuF6hyBfbb#XB3tCSf~4Wg?!ftq0#OXhobJ?2p1;6 zkn))ig+Rp&>sPr6g$q}g$q9ncf~x{2zd*_jT+3s*hc?;zMjIMcG9Q_a5Vmv*9rW>s zcNF}jG|78tcS2TrD$k`g`zP?e;O&ofv%)lt^oxfsV{JV|Kk}tS6_Im35focE$;-HD ziF1`s);#CZP~h-{93mtBfU6d2pf@}Ja;2}Z&S+sUXLpO0y~)&}OIQtSe}uyi)9-G~ zwVE~qAc=Zq4?>YLXshY9>-zc4zWnH+QRj~B%wa&ASSPF7f&%JZ#Egn>BkZ#U?`LKo z3$ooY%_PU40qB9K3mv!(TmiOQUc%w3{<9;47r z=lA7A|1Y?s-`EKA(>F%6@M4rAI3E_o##{BHdh?ca{}_@aHN4qu^}RC~HN9-Z?PKW|%dk;XP?GS1B4Z|@j^&N9Bc!>gke02co8~6nd$=_T&SE2TVLKI(U=BqOky3DhK5f*F0*la}5_k%Qb zrycKq2I*$22jam;2uOd_EtnT)B{T|Bi>TPND3Y-!@MH*>L$kk=_FT(E%nZft@n`Aa zqmui(HqVefVy+BteUR&pL};o@bnpj}pee$voEfgg5YO76+2W>UfY$4Aq4xmWAMaR^ zTgY{tTfV5MfLa>Y{WH&%r7}&}4?7P5&P{>YcKttX8RsZv`sZQl4vh}m3F<6k`qxG3 z9aVY!Eo4s*v+bjyqzcf6egpOOHzH^*YAARDz3EP^KW%PMm zT$R_+f7-x7y17}je@)4_$KzIbuxcyx9H2=09eM^(^je=ThE|_X+*k!=yW&BER2kkF zcB|)6ZY{6Rr<`O*9}qhGp(|H;s6Kn5X#D~hmG-`u(0Q_&s?!67qs5gQj=9gP?wCPC zK3^zA9f-3mvScvD9D58nVSk24;!3NsvEFnOa5RG7khUOQr{A_n@*r{>8ATHAz>$34 z07>+F+f=Q;fuzi9fkR~_g^awP5B0~Y$LiazOD}%??B~2B;rNZtlHqwkEoCgxzD;jW z-J4Yt^kdBD#94SbU`yH;o8kQDWkIgIB z3{b=#;a$Bi9Joo`xp1EyKni3smR+CfLhnO3TLOMbM;w+lGe8x)`vXC==bZ$qe+X`3 zDyWn2sa>`cAn6OBmU@>i6iy~vJT3B{oTD}sqNC1`g3C9xuJzt~nLo}lq~XNfVPMbR zd=_HD471r15)*jZi+(Afe?Lk7C!+GCmxUmk(O^3RrP+}6Kf_W>mOq;WbbIeDA$bf% zCxCDM0NTc0S%7)STk7)|KSDz`(gU8sph`}U7CMvHvdny`SIHfI2b?=yQ|Xi zx#nCAJ8D->K1JAgjBuD}J1D?DndwE^M7jC1ljOd6n0v>u~-((~N{ZYaW z@2}g+xvnnG;=3k*csMm&u%}0cpdoT6;nn8%dRLi^)0U3VmVMsm+I7pGMkqbz&7S64 z6QJ;F$@4nhy)ZnhcLDzSV78n$*`whw2xE`RclL(joUx7Px}A>R+qdZj4C0WOj8n+1 z?n2?an*X*=fU*M6mJG@Z(Z!jVkPtM!53u>_i?xf?TtWWc+D5ip>(8^X#1i{`L3stk zW;|s}4D5ft?@eORM;>yf8;H~;)>dHsgS?AloV=cDf!ao0s+*wJ&Ty@tK3T84acETh zIx3JDg_`^5OZ6`_pbeANZ^bXP?AZE*nFU^RtBY5ecoeuVX~*i#@+{vwe{o;6=Tv5(Cj@4RYCVWo zH^L|yletOv@ems5c5u#b{7l@8#XUsvpE`PLb&W$5YH*{8;kB%G(`EWdEK8V0{bF5P z?4zGWgvQXAr6n8bRsagoy26qEYgcxQWocS6r`zu!(L@vX=396C7bihMh3;}mxycyC z_OG}G%qzeb_Pzp%{;R^|Nb%H#HE(ieY2!Z5QFU~FcKd99eK4c$phEiaP%wAmR=APO zaQo-`Ok7_Iv)L%y@AmR;ZN-k+E;b1i3sv_=yROsk*{&LEp0h3QQr=QNwX{G-q>(74qy`jii387_N@d)@3sCqOu*`X zWLMUAm$g_5W2++yf(9h|zYeu?rrqV%m`|P6jU1|#Xk?n}mbKQChM&itHXcm~F1Z}M z)a>p;4=Z74va`tlTGb}VPIZyU@y?{JR5_vuiss-P%FqSvWf}U%31V+j%<4?EpRF0U z$JMP&>O>c-6bMJu;urk3elGg9v$>yF99{0YSp|Y}+~0E2dR|3vmBo6QsRw5>{pmRe z&};Iq9Uc6q^0a=xYmr$47GLL&)#Sc8ymD3`+-6z|76J*8mty0r;-y_UM|hOVD%w&;hzoOI2{eWS-d_Dxsfo5nRq7nWq} z?maDLM18cEC;fx7IX$b6>wR{Q+e0`g!{4EEj+;EI*GlD7uuC6wZw`hM{Z7YYo=bVl zIAqVcx>T>tL0~0K$$)dK@OD=I7OJ%8j7QB$E>hgpIRf^m=%KRKhnf2HZO`2E69Q;3 z9bHxlTX2Zgwb?g3hbGx}-n0h?e4e%>*<9l75phfh4CJ$rz7W60gYjj{!@L>7n!n0L zcU7&1Q*4Tvf_F{dj(jX zcWW0<=>yGfr){U|b#eASj0{7Z8B|k!rYRC_=kUVNo4gNx1P_A%zf7W%^L?xj(Y;SHp$sBzpelfvss7kPxq2hyT>D}uk8V?$-s{Sb% zEcO*xuJM(OZllEFENf05UKgT(UGm>B+$w#w%DTpd9Ui8(IWWx)c(3BMl0KOvKlAE= z6>UGe)DQ%H+MF>C|M*+5lg&`Pzj5x+T*7I(@*!YxvXNEtUTQe`>o}j0|1BTKa#hqW zS)4{RlHgD-jkHo}SX16k=WZ_9;uQa@C5|}~ILsvxh<@+3I#)jSQhj{X=c~D_JD2^b z1_M%MHi?^o@CoJ1ba2*^F1nc4kvwR;$%RP(Elc ziLr;S)Ro}~l8|tgRr3>0H!=OGavOVB&-Zi~d>fSF#qk^jPMdG8axEVYu?VR4i}^>F z!s}R+p3z|8?Y!RA9PQ)HCwm0GxBrbb`ZZ@G|R8%F5U$tlKtkyQqQXb{3{W2 z$~Tl7eI$7NA@%Rt2~iWE&1QO^mIzm_Ph9eStFa<-K?vTRzYmM61GJ@^?cADNLDBrG zQ3SK4CSk8GM*bvmxGj~9#H_|H$~LU?{*=y^(?-IQ?=cfWJxF1RwIhP@qo^4r>s>Sq zG4`(mJDz-+D-m)E!n7+P!^Y)P#E*JpNGl=o#A)XGDhuiU9!rB{7``ngeeIU?m5_Xy z93xAy8cUWm>9<47)pECa4r6)WZkOF|XJ&1C!52BMzF)`SVdY5M@Nb9Dcht`v739e(jwEJdJX%PwKn{u`5_yVp`9FQxDp!n zqJ0yydnzWMmwDavX)SO^HFG%*JyCbJ{3rgSVam4c*TdI};{V`E&;a=j>G$|Ic zvL;8c%&x-h8N&BV=Cy8Qhfwd?_SN3#q==D1y48xz78YQ>e!bgRULrdow;na`JIV5* z=&46fEMLkpVN>h2m%vRlX1!F&f=MlCpi(A;1%8SSrraKPdD=6Hc|FDH^{~g;ZE0JJfRCKQ^ZucoWB=8O5i6h=XTdE>QdeP;@|w!CrSQ0XHPg+e6zk%FvbHdy1`5nsl~o;l-hb2*lO)Qf{6?Mg=?J}2|(dFhU& z!t};2Eo`5+BOphBT=Hs4yCFf4t~NFgbSaRNHT_L)p_OP#sYcW+$=wax**~WGcS8ve zT6)mV#lmw+vrpv?*bPXnJMJ`;;LUVDPuGSYdQB;+-!AnUW9$Xz204dNIuU?l=T+>x zhhCKqXo$wLOG}E-63C?4rNTHZXvNJ6Ebsz7m6vapi##5#wifQpPEkfLC7kL&IOd$E zCY#g~TAtz&ZS7>0;g{)kxTifT)Q<;f)Ph*zSb~7~blw7C`YRt5<)^a;y%A&00)|Zy zZn9eSqNl$*0QjrCr7VSXp?%?0hKliAgNKs&*Fg0rkr58aT*(y#)6kdZ+r68v0hq(M z79Nn}y3Xo+i?S?Y^t-;3ZRKD^3n|JonlaJAzAhbrB~W!O8qBMmo^`!nVV~W5PRb8B z{d%T`tcDS6%$x{QZux*=2C7N4GfSLdX}PK8cV?_)YYSJKYe+Cn>VGMb4^@i)`j+k; z;K@*_DC!4KCr#EUTcss%w&rnO9LJ7!ro1hU>8r~vPbW@Gony^1T~ud{fNAy+VZRo! zB`mQASlG_T7siV40tT*5P4) zr3cNykgfVybX-12+Da9K^+|b8Z*qY2Y{`9A1?AtZaPi2izjQ3_g>!%fhSq_Jar%mb zd>u3lnKj30p%lJi&ktn#)_zH&FFl&`C-)bJyAlHJhF8gX28e2Y5}o9zMkuTYUskm4 zt{fir^`~%E7y*>;-_=zJQ5@SP036lpxzA`(rv4D(gE==;T1ZXeVfPxSPK-~q`j^GJ zr)c&F&e)Lr`ObRE@A-KhT!sC6R+eyaj(m=asUM0@LY1-sWw%fAP$4m z3|lO=P7`0N!yjl0#nV%~np4oh3J1XADBvBKjal|H`X+<%>EcMCa}v%1Z=cU&6p+E` zZw`Sxy&q?S;r*PQ=maB~JFP@j!Er8(uu1$-d4UVm$&*$5MaGCgvxHis!xfY%kD@{9 z$LrNu{LxcR?{N)`ha#9tH86EXHPdxz{DVyrtVKtXj zl2=>W52~R<#a^WJMHrQC!+(1N#9N#ZI{R{M?xqh_X$+pMnQDPqii2QXtOShqO}|9(iMewETZ55xzTnuwkyk&WGXUKcW+{P3uAs*>18J5ko4VjhdmGEr4fG!7 z2)$lX<_g3O($TByDrr382|q6Egpe0$SyKzSqub;>yt(}xNire6rm{1_gYP9Z{2K|S z01Upq1_AI9dWRDNdN$M-T36%G#WX^UR}jrRwo1)?Px=<}^D5vfTrg5KWxJ&11yss)I}0cO zAFOII+{v#1@iBY7FX3|6%saen%;4IKLOWK%>Wgm1-We--{Ny46{@L;l0`-CSOESi0 z?^`tWVOfm+&V7BeNM2(_{dEu7uT{1DT`(S%Z4n+4U;t_BGnHdwh|j=fuul0fzxN&E zl$;A7O7)O+@BgnXoLqE9q0C4re|i6c&0hrb5<}4ol~YTo2Hd<_UlHf4l)+O-~^EA zX0LZapbfwx2??xcEoaupOFpGm2xKP1D9|c4gxzz%We52~7UJozFLZ?@SplCrr*t{& zxp9oE9-tEKNvbk?FK&?i3EBe3zR1V1ZX#@!Q)4CK@1O?hG?C0`YilG|(R6vZ$u~5# zE01;j8;G-)W5pwpF;9(ed64Qw3A)GfLvfl&%pSY>T-Si*CRV6bX>5++I^W1x%hG+S zY1nMng^y8;pO{)Cbott&C>PABw8eeZ5)e5pmtR0>nt*qC96aK~8d{tPIh8f;MMNiv z9rCbdF`ZJ1D^lh-@?t-4yrgceIU=!KV(_nYS_SNg5T$vm4+?34M5~Fr*8+$C&B8v6prz6Mr#B1 zLUzv9&-SV^NJ$U?1r!wbcKBw!-6}E{{rRdl9!CqjsSLPIsaQQv59E_LE3GKR{^U?i z8K2W#unu-N&MQqH77WNL<0sDywQt(G)bGHmA7Pi5mn9z_|(Nj>(ZkS1dF!csu+k=ap<+Kwvx2(6_*<8 zm<+2oxVHPeN)wtYJOterwx_XUfP*^Ky6yTkKzo<_KrBhl|!gQ|_EkqaORdB)4Tj25YbskZXiMsx^vvB(87``fu9thA=( z#<5@e5pP?EKQq1u-SHTj<&T16e(!m=q%5g}=7ZiVg7sxs*@1WEWZP9>uyIoQOizil zatXv6|92(%B41CJ4QuE-Kvp=wN>;5x)VgAzC}^iPJ)SatI2L7Z=JK&TmcF0n*Ffn3 zH_dy?gzO4!b(blZSRs5F$;O)p|Q5-h8G&pMHYFSLRZ|%0Z$aC zP6nO*fswZ|d#aLEA}f4c{agHCWo;Gb^?oV+TY-10PNpF*IL5bh%sKWMH&%>O?i=1-}RQR^N0WXtVhll2P;#YqWA#P#lm@ENP9ISLFG%OGmu1fFgCxU znUBkGp+{S>V8k*bqAIEy8oe-dl8eC*plxBrFHp_O!*eqGVs8CcU=S(=MPD(fvKZ0k zh_!XYRaB{DgAbteyWACaq9&zeGpO|9kkO_XhCo{J)d!wo?;SBfi#DJB!%@gI9=7ID zxcHruOp4r*7eJ>?UP)8hnK!@3D!F(Toalu|0H{qJQSJ%tfcGjbNAU6OuK^TXc9=G; zzrrkf?iX@eE$+s*6Y?{@IlWkwI;*EkBFhfN?%q)1Ob&~h+ zE11mVFj_c7wokJ8ghG)BA}McyG+XQh#8zzAxJJ?f)xjl#->zdghy@DJoHCmtYse+B=vTH$t;kE|K+S3FdH%fbr zv%rCg``pW{ZK&UYS@5+*&rfqD@llglof52O+l2h4)nF_V+2!O z5s#Oe9~HNQ^Y%jr9>&9u{~V`Bt>vwCsF6hHzty8u++=FBpH3x)u(mi=oIeyl9Pdv` zY9YZ-NcSNcV>MKwh014JVV<7*7~Ln&mST=%?OSAqMDAo?6e`hG-103U_BEX;8S6VC zMY3s{0>I9!MrM(}2i?pscDfXgHsh_(<&4zR+SdC)f)8K)ud9{N6fU5MI3~K(G0x#%N*ZOc4-(5qs z_$v*T99LR5a-K=BR>&V&xxNpWS|vgObqb`0vpjY&!6RZrG1S&0gB2eRu-~h(!+%-* ze$DBfI{f0@TeWm1BKR&Mgv;O~gQ$9Xt>t z|K+o+zTU(BeToke%|%Y>{)+)$2r}pXPCXy^DN~Ujj?ywOh3(2_!u6JS{#XH7_uGW{ zRH%mEg4y7ToxY8fKe!u_TXkAQcu?glW8+q={fl&+db^kU37h71i{N-sLWas&CJr=k z5#-kN76TDU;J89sRM_f6StSdF+PBH^puK{@1krb>LIZ)g(O^#dd7Xc}=!UYZG9!^M zhiDQ`3@;@V4#ZcBbTUY9q)nwkDlwrWq0NlBzgo?`lCAb|S!|6>c+0e{Zmp?tOheF3v{RGHoG4#Qh{uFx_C2c)mPZJZnBbYexv1 zhp&ZXSaT0+*co^vb$(s$=kuI_YIpB3?NM~HH@g!e-J+hwy8)6VYrZk#Y*GBJ_=($} zkY;+E9PK5pK-vQ`geNzEPYgeg4AU_o*S8g_)p6m{y6DH}4xmO9SdDxv(zUmst`TYB zA`Rk&l}t?IM@x>&F0;#L$8@hTQXfyhr>#@Uk^4rujArOn!r7_69vXc&3~TUk52(Q~ z`G(=487Q(LZRpWs*riTq*J7bka3yN^JGA1DHkv8u?K+4ZQttJ6(Pa>F)UL(96LAKS zC=Qjwv#mu-M9G!|;+BshARyYlBG*;Mr61jbYo=F{1!ZdNfytIb>c(k{!sWG9?uOB_ozZl|FW7c(+062}pQtm(0#gJ0~0$*p?v zGwUjPDz|%Vy6Q-8l<@=a78ziU4oV(f952R2rpjEXyF#NvL_1x*>~i}QS6;r;z21MQ zMphE&0)1hx#Fi>1eyENjNP@m(dtoq+BU6xW#*}oU_*icw&<5)X&y4{f$x^obn4jj&qK{J*w;ZoJu`MB1e+})11$G5KV>mPUHz-9J_C~ z+c?EeQvYbWVeR83ODk-gXu3XTROgS4Gj5Y>p{Xuy-q$$>UPvT46=$(QH=-7U5>kyF z7uWZ+uRgtBi0k`>SSG$}Z?!%&>9N3-YBmXX312Ue%;ITPvXB#>fsy#QSCb=4tw~k!rs{5y9PU>w(I~@Xw#^=^by?Fv zk^J|m*PEGkz7{+4O>wceya`p={*GPsZYxC-M@Hdo8B}^dm&S^tc&0>q?OLyAKx2&U z+b6v=`=noxBg=6T9pj=BzCzm&jZ1AQNI%HmH|5TUk$EBxg*Fs1p{y$(WhYgrQdlW7 z3{^j6$fe$w|EOwr({|lbv_z z^r(FBjKk>owZ4GcqTl{o~S@4r{=4#%4H(%#N zd(skj>etQ8499Uw+!nDbL`b|iQxosAf9i;r(dXe5?p(+cI;e^*4on@()Diq%y?ZRQD(;8 zHpWXK7f0Q*^p2ynYJ_>t7CM&JiozFI@W z4BYlY_;ZlY;MxM!ZJ<~j615af zwbi0aZNRoYmCFteIpPLAR!!z3Z2|Z}D?9S*H?@(|TY78Zx1I=5q@Ob@(<^AmRJALP zUTp+ev;r%On9D?stQUGtX9c ziTdmp%>01_KV0~^vzA8Kq=3$ZQ#6w(N3QSZy3G({_0SBequ(%05LeU+puY{!4%+@5Kg<-MPe4}CB z`;GKtGFm5UfCb|@1ip1^ZJk#kW!hd}j6nfORN|7Uqa%nOk)8TeSv!^X>qFSl=?aIZ zCrni>D1v}CIA<7&HT7puWV|D=zFa-cucznrZ>yF@I!36N&AT*<OZqjB(xHZDf3m_EjpMm!ohh z;(Cg=1>qbJG2Xr1g}zSP=07ve=Vdft=1pSq4ixgQp{fnYmNk4_s^b$BUJ^njf9^)3 z4NcJN2mKk4fiaqqNL#UF>Umus}Qv;Z(3}C03 zMGnJPlzyRZ6H_oA0OEzZ8b1uZ!TDZo z9`CVLZtFsh2?2+o7Q(Nf$k^S!q~{;PH^rB?&l|~zFfD=ZqsCnX`m`gn2z6waxX@B6 z$1M9Ju~bX_q=2@|=3BidKa|pDH=82Gb`Fnsq(BETMqYGS!S)Ac1eLeK~!JDpoz7?l%(G@-wDW5S9 zByl{mj7GM<2gOA5S0LR9Esqj{i*r&r`Ww`JfrNf-_kS*E?QK)}umkTILmSy_N3VVv z0v22M){DAK`zPtehPTaKT^<#EF$q&67nW*jlFYQ)5FJIWT$=c*}d;vl2l1;)DkQ@NBfz-Q)`kcSp^}MvzQ^3&Y%y^I=ibm4nqLh zGI=_Q!Z*(nKg+vR5}fu{y^!Tmyy8wz&AlHI@9~LfN%Jn(8d*f!kDtN2PuUw2EItDi z&R`6v!PLGS>io_I*3!wtepvXcc-`Sh=Q$kb*n3fFxsN#rRY;gbROZzWy$WV->7H-+ z1nWH3CeCWk!9D+6^(Zdkilm*MKx0HoksnMa`O4&lD(y7pxzh zzMOtF+*|O=XlE0^m)*#jlW*wkYACKp(SLoKgGLUXU}%i5O9hPpBu(S*3^_yDpZSl|)4(+z1uti)$$**sG zD0HU=&UG2j+lTVaW@iV2G#JS8PW@oP!o1Ae74`uNI!%wgt77>F{deX1tM0o)4w#-s zt!RAD-BKD_g)>QA^A`c@ivkI{&fce4?9^kyhSihVRt@ZkD-qoLBqr)F?xrticT2Lg zqr8IeL#gqoKa604m5jRg0#n-pGfE7}ocoq)Wf{lp?qBiq^Bc*tL`Tn9X1N84_1dkE zy0~1{9Ytd+q_)1t)5O-4el-LyIoZLI#0wuL47QwTOhpwD~YV^09w>Ua?A_+szJUlK07JqRi^4`S8ngh z+lPFvJ0CeTH=h@xBz;=^yF~7fj%ul%4PA$Bmxn5m>>{cJeB*6BH4?}vNk&6H;&G-&qmor=$MrlZKQ5Kd)2Kvp5(2Dk_;r46OQzKoNE!S-rvS} z&{C{q%-J|3~9(0M+SyrPY4IJi_Z(%Qh4yB@lDbH%|9XtnHrjf{7ut zb=VWG0Hje~P9qbow_>mm4LqgYM#e&CrVD7oai?6Z$yA%UuMQ52OY9|NC6r5~AYS6< z$+rXU%Zxu19xlCE&2QgD9!eV8t$D#fxLKkEqRym#b8$T; zG1u0!kfXV@LU`J%WoXc?3%SXsyK1H{~#R73$Jc z`40HL?hcX*uX2Q`N^ACYeqsHb|6JVx(r;jX2fC|+(G4LtU%22E8U2RaNxRdFCbe2M78$1?uQ{q zX+*^eBMe;p+RrH|S6R0YlOl~kK5u|`vzhAGWVqI)Yb`&E_4W zx{bli+2H*=e0WtY39o_P<^`9#78Oh^0++|O2E^|(Z&e$AjA@2;TAGLOjoa)_xufG; zO0L>WMeJE;P{?%OA{#)E)*W5ykQuG?eSUZZ5*{!3H5d*&EvM$lHL55;Do_brO>bLx zT3)s{%%dzoVr^`7u@z^LOmhIqnj@0^IjbIcC{R$R7Uc+WbR9;E1y{us%vq7U=3}FG zUc0;(hq#~jF7E~R%-TAuG<1Lg^%JzQzZ(-DYbCGkaNDM<*qD`>lC6a!Hv*hcseD#K zt&vcEEi$pU>N;=xx;d}=WQO0EGWC+~buwRNIy8!-e|J|Y>p&Cbi2er1{m^9H6@v06 znf6tPY}sO$+ch6`^fh4@68%yCY(leG5OV#B6GgyObJuL#7Zv`xFd6W@IVBhQT}w z_3a&y8@=^@2b%f>D7AbKOY1-XigN?}eirFY`vjm08z~t<8B&MqX?6SiC%^iOYFY#{ zb4ij|dO^O780{5eUu!>K(Uxt_M(i=w3qSXg?}c5=c9!oG;6xZX>w3f~z;55TDL%ZB zNtB{gei|-%J4q=l1E@;XZ}!2^m45A(yOp!3Tc?d9`1>P#2ye-Ly%SS=dQ=yhK^whp z6Wi;~BrDW;ebl^~(`~yue{58?O|Qfr*Uu9?>NGb1Hapf~O_S;T;Db4_traKw^!+5b znfhNA07JeBJjesESiX|H-oCQlMbDJqNipzVlT{<2j^6lkJ?&|8H`}7Fq78(C>{aRQ zR5g;bpp{|#6EWiuT^M>)gzbaiaS zgF#8*@-oJ>NI`mf0}#bRPmusnz7x*rn>^MM%lZ*^=6A~_JTg9wmWdxQ)OeIQ&PTDAotA~q-lzqc z+}y1(`db8;5j5Oe@?6sVhy)3#uQRl`%aGqQw5nAYTHq5g+bFzV`i}Rwd|U`hxegD^ z;qiRWxC*WBpcH2BLy1fm$iL7GiCNGEeYb&^X?;z>w8?oO0Q6$E$YNA!T&r4-$6sRPsXASNVO=(iiXg-G=ewj)8VTm_pwYO-CD(8Yt48Oij&?PjVX!pK-WQ2Z4(02bvfFAfdt ztfpuJy2Sr!Iu4}2EqNN4YMyiShSueuf(Xaw7>}sb_m2$TB``i!s ze?_xLwiIGx6k`C@XUiio{-H)7p$5kjbgDNV@FyTdXxpV)o)$HjT|0(#VoKD$EF7V%Neq$qw$&~dl1!4ZP{eS)j z80BF9yFicjGhQd$5RvLX`}=3T)By9l|1M~KMx$=T?n0CQ@9tw_jX(Z(p;qX#vJ-s> zY3l!+4tQI%K;mf~8KjR6V|M%kH zVPayfnUUAU{#!)Nz4Px?d{+Db9BkGIw=?v=MaoXY|GlvPuP=ND4lY2b6s_Umpt#;< zKDMC-NQ6Xi={CEj6oxal;obziBet0O%h`4w`A?q>Bqr9YG=c|> za_Z5Q^W<6^(}pto?8^eldqJjP#NapIwtVAnKwT-2U4zE!L$Mv z{2M5gvM`6Ra60V&BJV99qI#n)P(>PPMN+!EkuHfLrMr7*kPc~(?(UL?p<6<_dtd}< zknV?pGcE1d1JrS>c$020205cX2do|uai_Ifoy}pU z3h=d4{{nbloDA4U$cfwpVqUf4W&+3T4{eLS^xw8QJAeOtTowu2$!B#wE~xIj)eZ~-8!HxUp4OxOHz8h9zT5M?C&hWdI1#>@S=%s_)~KcVw7Jz1FF!;#i$z*5sE z_1$duoX4V$?G#;~6PZ&abGTFtC+fPNI<>Dtau0uGVrz>c!SePaSvmr_BBtBL+zrA) zxh(zRez10&iYJW=FT~}2!|XS4MivySMk3%D0qhSrNh(p)@9>&OL*=oAqQ0$Bqw!gz(fu34 z=S3T-V9MVMm*Hgq{tY!?Mr4b<-uJa-%-Wo)Dv$xy%0`Pnxx(ugig~>}bL{GS4ttpZpsFZ02_xIpqZj$U6G@aKr9Jp9YZ0x{Z>Sd1jzz~`kv zR0^yg%y8OvLTG~+^6*;O+Gfn_1js4hNIkc(gU#To=71k4aG%b)E?lm_EQ(MmQhU!_ zHGOiI`5axS9A%WBYq$^RjdO}$@L`rW@HpyP%E`oe0(D7~f){U5w>~FwQEuU{r@l{0 zNEB`1>VY80G3F_Mhk)VU@eOGuDF2NYEcW`M@}WpZS$Ts?&HQ!ESjp-uS{3bAc&WJwnTLQFSt&6G_n!X9}4Y6*8RYxCEjKMX?p%T>9#l8802-g`YYO4os4Tl&Y zTQMg1%8`_2yAeJV9EK#IxHk7|{9WvR{)*>Bt>)=}x1B0MMU+;#O!fA6Uo;Vwo$RNr zSHG1(F9~ui^qEy$)C#MB9jx0>J~i+97IML9K%6g%g0(zifcOV46gWMKxQXd}crN7Y zxOqvUKjq1AslsM_i89d+KIy?9_cPGV8WHGlI;t^?vY&mHv(q4aWT_-KzujK&)5<& zE;qMD-o;{zLwVbkIK7Ee1dmY`kAL~}!~3|^5*DhW?DElZV|F7JvH}yJoVo0g`RWwN0CX8@8X3FZ~0I#%0HMjsZE0lfb~nHYb|`MtOsd zM~#o}@>;&se{R)ggB73gvogHzcb9v;BRbf^8F0op2L%^lB#6vI<{ z#O^SsBrdfSYI!C$RM9YE(vfT$oUWBDcR%@Db#Pn3OOote>#mj3k)&S&_`<|!CalAR%~!k zVQDkp-|abUjH|QS8tW0g^*~M_wn{L$6UOnrx{mtkhBg+XLr+~_NXF}vwuuo8d-Kw*2hIap8y6?f3G9dB^F70`T4hya?KhqI;O9x4Zap!lSUzL%oqQrU?~FUKc_) zQ1i4e;*j7PCGy<6yWi*BP{S<`Z{2OQOjAQ+B!@24nv}FluBuErj zQfRIr(Y)XBrWd(E5IRi5R6(ReCUM;odhOz0s_1h4ct`VoM3h!w$~^oBMGa%=2uFjI zWYuM-8K{l{Aq0hh@Qs+r<3@522D}$WfVM~F1^I|*-Y(Xk=QMB06lab)rMH`iy?*pa z6|HMdjT%c^WH(FKmFkVMr^oMaB2{0y)vMY!a}vB&MafXxC#-%KK{Twa1PE1AfNC#p zFkZ@V&tmD*BE3U?Y;%o@9Tu)4TgD+Cg&1K6*wH%xe!DY89N;==`zPm;{S73Yqkc z_^H4PA~1iZ{J zF}G{wCX2#@{y8uo8^Axkl(B-&3zgb(sVwF%`NVJd|Dp0h;cIqRMS&x(?tF#$e>1KD z@mQr;r-{Hk!1wJn5o`M)$JXXCO|rmIwb^J2^KI;I*heqAeqh$eHYRoe4pVrx>x`@y zY(f~HYXn)Wusvt7!~OURJQG{BZu5jUT2w~Zx8a8M{dbLYoNFHP2pztUwcjsdI3w{t zjq;J&>AolCOZ%$kl!C&tgTE*Hsb^{v}T_ z++X4yWPSUUEU)_64negf$F3gyu{W#Uv2vNzaw#yNaR_Kg{|VHhAt50d`rVn|Q@!P( zn7acUgu_BZk2@|DU8`Gn2+Qr;k9gFpbQ-^x1OB3!3?TXZ!-_bg-348TDT)=Z{7rkXyu9Rmv4||5jk{Vi`sYHS#Y5w>U{f~%x1YX`Ol-F5_orSG~_?+ zAXb(TRQ3!>ny9=MIG#4U`a3_SlJO5?a~__Kxk~HFXUeg5CgFcd^XMOKl|4ZY2n@Q2 zNvA=XRk9>@!J7K^Tz)WMBR1Lvd0qUEEVMv2`QuC&)ZQ8DX|SDvYOJ6qe#RxXEscl`UkELgNO=gWVpS# z1OJp@&$<4B`)HEbV}fP*vA{W&(46=Uu^_FMQ4-Y$|p z0{keon6>cywr6sdow#g~T2W&(Trp3sv_hVIlyKFg_f^&LU!kmVueDB-NHhF0ERvo( zia`ft8I`VM#VqZ@*}oHs($w4tg)hc9$0)M-K%6OpX~9;g?4IyNBd8HUBcuy)Ix29; zrg)FZ=wfIAPbYzxLYJg4EYVQV zpplb@()f`#^c#E-#+32wPfeT|h$zMz-ufUKg*kzH{DvOxY!;kzJ<1p&Gb@2b(OCTP zW;~Q$SIME0J+tjp?2#hbSja5U1My%g9_QI-ge+_&@X`13%U)@Y*9Z^q5|asU&=JXi z(k`dBWUW>`x&im@eR!F5iC4%gBnT4`>*0)^^DwnuNp1ROHZ4n??E&^J;QL|M*ha_B zgB<%xRVH-|C*f6P%0n8FeM>+#d)&)RYM10NotB+Hu2FBs#C6`UV@qtyxbfz#U<5pU zc21O|OG)I~tlF%c1*~<14|@N6qw=JfBeGPJvtADY1)@T} zt|S3^3Wv~dG8RQ$gUz;+t_NgdqeN9LVcM2yVp#Zen5>JNc@KK{&!ZTD<2ZW9LNpHc z$b981{XgF{6u+8*ZJTS)p8^pxXAb)$ut>hJy_WA8%psFk24Pit6Wat%@utSLS~7N* z;3?~V5K@poso(lw=!4zywjETI=J;)5$Ex;ph%4iwkXSm^an`_-p^M7dhB2KkI|GW7AQJgi*71yk^tT6kLZ4 zF5&*vTG>oX<~tSa`X_cAXP*tUiys`;(+6W(W;um=_WnX$B!(}RJ{hKGYJ}$v-m8bD zV%|w1swW{U~sxJc-j{g#r=Q93DFVTjOFP+hsPxR_D26bbbyx^BJB( z188knaIlmYjr^|yJGzVRj<2EcZ|x2yxq@E3uGVj%x>0ugyR4WuoF1@cVUbrtF~pf# z+0>1~qscwkK$_WK?QPP%KcXLLiB2pe)QF4Q%EEs1h0c>?^H7VU*$&~4{O&s*${ZPs zuA0Ai%v@ZuTW>z45hULxX7yI_R%?&H>d);)g^^L11~8KZB+t>MSNOfa1Vk?&at8VB zTzl;3r-t>&n#SYB|FbHnh!&rN%}0z$L;h!7c&AoIg6yuo5q|K}JNG%zT?=dq(wE%w zlO`lt{U|v!Pq8=$h!?HZgZZt_MfuhJk|`^Da}NyU`bHlt~x8t!b;DZ7_6`mI6)tJ zV0lSFCdHJ-ODK_WH@xz#kP=0^?AY?o-5l?cK!}bE9NScmF{NL#!9V4oo=Uh>D2jl+-Dvz19bK+ zT}}6?&1&1*OF;E4ZxNhx-EvNjl$6q>?JyuV%D6|X-p44azxMoqs72S>qB_(z!nnrx z4dqWBrNS$*8Ewn^0m5d&F{~Yw`p?L3QcDP$Ii|)$%hU9iZ)Ww8E3vL`Bz%J+;HFz8 zI4sU<<6pfScSD}a*WgsmNOm7iQy&n|omDMm3tk`4GD0%)b>aU!L?OzE7}#S%#)Z0_ z?oiSu^M{sPIWTkQt?(%6vH4e2)#B5ysGPG_aDS3_>3eKssSN(i*hl+w%Z}Imu`FC4 z(A%D(;)MYlHr#gm0DGubY5szp)`mEeruImOb3Od}*SsD)V1U?$Q<`}0Z|Ych>-Dc$ zMjm{f$x-PoBPEw`B^f<`<59j#zS*Ir+vSuP3J2w05R2D*FiC+zox&^!$O723zrGQZ zY)T10vE6ucMzQsHlM$gR4rY`=$E9)2$U;G{XLk`xeB`>(8%-1!B)G8Pdhwb zH9~T<(7Y!k?t(5|a7>;n-NAr!I$(Q_Mst5oYPQsX-bLk&$4uP&SL6~u6BJI`M5Rle zcWCX}djk>KISOBaI6?M~s9^I=iZ?9{bY`$uA|zgNv7?=|-iQB(@BcA} zw#c8C!g9yB#*blgRzYBqj@q>Ja{yom^r8Ov2l$ws-zNCgCS#aJ5VQ{;0iTHh#Ob%MpU*O$esJ&y=yK-a+|~F$9XvhUWX9#n z32enlM4?k)Sw#akUAUFBizPn=(9>Dr<4UswE&2-UZ_<@p)V$Rh;K$TWL@Qz>64$Blfq;7?Sd;zl zk(WuMu1)}12M#%|JY^mpxjS3!Obo|pXT3O}hzgwb<6^2cP#m9Ohm+0`lNL_>5P{Pn z7^ZXR=mOu(*g|O`o?+%e7m%LVQ{AhO2h&mg8q1>HMK{Y8|7@X~3i*h1XTV$j3bQHb zqcfwt)az#Vn~tW#CEL3M+dpx(>yN~pAedWMh7%I9{fb}u(?;>5KeNlXm4K$RpH;Pv z4@b|x<#|eASwTAMO`F9&Q)ypy4TnY(MZSXc(A*peZxYLZx5$-&WWqEl@*?;$X1}&d zQ5Y8$%j`V71fR93LQfyOm1f7f)0)oJSM~NqY<;hgs5$H@a&OY_y8h+y=_KKs*kRJz zFdi#|c$MUE;qJSZ5_Xs(pVOxn666nDu_Dj6m?tm7EzBaq0_NI0u5%tOpZd8_pw3HO zoVm90t&>@88!(qip(z%t`+w-*9(IF&*Tx-G&x5vW8sIeK z%IB{A)9n2Cy>CmQ!=;xO;=}$R#O5`>S~OS+@$75Z_3^0F<^^t+FyEtQ;{;mNcV5|e%*Q+ zjcwdU?l$LKwc2i%eTG++8)%IfK$Q!GUaI-CBZrrK8B|0qa@U+8o(-b<qwgH4mKR zQWy@zNNhmdWB%zm8J_~&%gRV$&Fhz{kYq+kK&xS&}kI>vFC~mCC zSoYa|?lG|mHB4ssMkM}7zzP|5|1~q;vh-&Z|3`XHsr8tNlJK9tH@|N#7skPplc9Kc zDFfpKn+!$+u2ELV&BsGsFILyQi$2?`x%YGLgicH@Fhw360S;Bu)$ty7e)F3T6dwc9 zQA;M``QmrjYCEe0>GoV-&hcx%eY#mgYHnVGHC;QrJ84huOD#e{E{sbd;<4_%9>W#b zsnT!1-XwkDi{9XSh0V7Iuw9W?eKB#~7_S!wMeY(sJg>HyU!KBta^dX{#jna9_X0mgO$ydc{ z$C0$twI7JsWqS|hM}A+pQ=$b9*DO6S?8(7j>>+1fiC>bw4Z z^+bzDd^PnHVH1GJBah`&i8D(aaSFS9Yp7RembA=8tpZ{QfKQ83^24ppTUZK0ihK~5Ic5B~E zY7={UWRXTEgQ$CC6-sTIgW0SYh2QgvF-{!T)F%nAS$f$M^8J{E!xi=EcF%!i!pM-G8Z4 zH>=({;@4eb-b+0KcQcB9S|yjG=_qK)!|#r?Roy)A%f^N3Kz=vvYx>W_8`SIjKdXfL zx$t_Ar2YLw)(*1A_Qs4d;}5!VL5u9$9<=-iBX|Rm;8jsS?u$~Qu2GhIkG3ysBL9xR z+`7YV8Gubq8`}EYjvF#k)PJ6;vB#_bpqRu%SrxG!<(-br(ug=> zL-dB-!=vfC^3Z!te=?_5eIf48)8EJY8WPx+FXhiHutGCI6>oyMgtP^CVrYqaL;pJu zdazCnC2*Q9O4m9(?Mj#U-C7cLdx@QORirSOaEm*|>i6*5pew3;kY$jqp4tqKhuJo$0@wD~Bl#zaiHrP-SjVvz6a)sd(4 ziATV%=h$mw0AWD_a~0FRaFHGU*p#*{IGf*olf2}53uM)Sgr5=zZCcRfdN+mE#^GBhv zYB&9xnRg^Rk3Ws?nA+lsaa2zmg;kW~O11a7M_miww`4yLA3m(T_(>>7cI)W`tZ3&l zXZ3jAVJ=3UzSe;^;QP8fh6j(C97_W0JF$&@kF*%}FUb1Dj;`WlzCPmKK59(XMC51$ z`>jiCXsfb-Q|2>dbv8WiA&05mO9S1Zwq@Lf$+lNDe8W!_ru?*AK@{W++PEnsn(FnC z$~DQ}XpWY7o1lQZ0VS>2=SZtqqBET#soNtR-&Cug>=%P1g*K zpf``rM7$-vO!n2THz+Ng1b|9z4Qaszn)NCWO zWOO^W(W&>fkq4`>GX?-?2BbZH7rCWFk83|Y!&301s}zD)qGYxPyn?B+ytJ3}{N$S) zCRtYB-Uzuy0yvHHrPTTIi0V$PC{%)zBA!S$Mp7M@S#-S6Ql`>{o~{2kI6?Az}nI;5_hn`GMXNKNv^@bmS}x@8r3m(@47#73)UiO4lwkVK?mQx0~r+AU~#>QvXlfs8$M zFvh;?4?P~W$hqEZ{+BANEi_X^xHEAga09I%&5RO=UW*>A$|5`bwIvB!XNr_)2V8&( ziYJs5@7v(+oqJ1Qt+T%^^{|6mj7G`bGY*GZu=y{5_==1j&yj28Sq*g#DMk=SQ-pIA zteEYPaeK99d9#7yqeO-etV4be&&Sm#Jv+K+qk6C4f5e)h*!6-aUQ1W9>Wd`O+-=8c z8m>aGNQ*ZVeW7(M$gjc4w@-;b|LZ-^~!f>fmNq`9k#A~4$boN3;r2n9Q#fv_P zHbvvRdun-{*Kt!cm%)wijVr^ZG`R~q{ctnXAqU>Ivyr-i2Aq}4sg`%6PG4KrN8KM< zlX_fyZNr5!r)I?VP)v1^N7Ze(;}cRlV$!>FGrb8SAuqtG2lF>wuE0K99g*u^tvkd; zf6*>Kq)cA|EeB)iY)1Vsqi$f}W=%DyLiv3)*DG}2)!BaW+mGbdnv}JyNC7$jRWw^u zWulsF{u9J%^-Abv`nMk%*5Kt?LNE`4QW^%lvwt{qs(~eiD+$YM+6{+2#kT>Ua8)sn z2&BK|G67QiO_aO9Fh(k?q2J|n3Nej^*5Td7rN0s#I*@PrSMCz#yYaK9Uv=g3s&|MHyO&9L)R>kiqAIk?=Wv_C-H z?qvlkq0}wJ$Cu_IMDDgdk{m|tJQSQEAI2eY%ISFwI4#I~ea(nDWwet5RRD8F+~P1q50waKe3XrNZvN!$2$MkkxhB>GL}2;I5ox_S%}LZ;*5JrD{ru@h(; zBc{CAdl|V(p>kV)4(7s0{aU!QWhn-aYNf*POeNx8u6lv@& z*P~_9XLP_w|8XJV35UMNL=Y-C!wzZa11xLf)1IG%xx7*8AZd}qO8{x>e6 zH3@n)YG^^K8wEDSAPrZS|E$#@bl8VUc)~ zoTpoVwAaw2to<;NbiAWYG5DB>(x>1{z_=UTxNH$TJTGaBmai!@S2O1A1P|9VFu#8+e- z^1eb!Fje88j>OHTWnGRoHfYCekcEH~6;;d^U!O)92ptvmcBKy)*_T}xO@xc3+0Ddw z0%5N%=UaRDuplfD}gpWPwg9)*p$XhKxXTosR2r{|Es{4?&wiBerku?Sg*E6~HT3sN( zLdY0Fp8io~p?WlYA&5!%^qG*qF*ZG^zrH}>7^Q;47x`T!)6kbD$cSsysSSb<8*QeL z<-}@psp}nh2P{T60AU>8G9SODdI-x@oV{Z4_rd(%K*Y}E~zuKFD`#-sb+ zUy&Zn1Sf=t@Q63ed-b}K@i91Eh?nJCOHQ+}QaNpt5j~%@C1r8RYSpW{z%>IRBF|(g z-58{^@9SDejO8%TGB=GaWI5`cF;ka!M5?aV5i)LeFt_TgR8&{V7C?m7sila-bPGQ> z45tVvWOyS;AE2|+rdc~*HuA02f3_26WnV^~lgyO-)VC#zDmKnlg+}k)YQ@SPq&VIo(m*SjS%kxT6{=Wpc=W))x$)c9weICevBmFmVyg2XiT; z)zajW#k0oOq%2@NQ0))ZCpVycreaFz6fC<^-wFD_--bsIedKkBmMIqmH()nFsK||5 zB?p7Cq%sBfml=PQTP2rnwVJ9zxDs~;+>(ZNSG>`88JU|M2g;*<23mnA%`|XOiY@pT zY8(>gbkrrDS?KRhr9c{0(7KPEMJj`guBp|otk^WR&~>NxX^VZ(p0ATb+A!+W!6rW( zi%enXaVsTdgcS>Ix)?kgzL5`V0==N@e#I3gqKG@3eayp$San&trUagRTKP3xx?2fb zG-DO@hV5$e@7*O^`e}5(S?oQkWBFyQ0RJwO=nU>)EO2qRH&3H@g^9BT^nvspJ#-}= zLcp~^BpaM)E<1b|+AXqGpIlyURyBfL29!31fw0RN`YHFctE9)OgXM918Q(eQB#a4L zO%QjD*+~_h=%xdYVRIns(Q;Zlma(!a#j9bQ_hClAW7WJ**OVeXDWl|kaVHDe@cvsz zhkRy94Ttf}7wSwprSIG6R$Wfaq$7AE&i_Em(mw=zkB@8IYQyK9YU!=-oAM|X+1?3x zF;J1std-YVR!&yJ&neL${gY4vl8CJ-JT+LXl^ZVS@HMT9Nc8|42xDg?JzkHZ-;AJ- z>U+pi+lf;O(zph|%8h)hhKo%r-7B#m)SNf91I!Sc;(z-{&A#12K(%Y*jByPV!*2Th zh|5xI_0u$3DtaT5(+;tj$$lY=oyzx9YE%^6>lwyyMc0l%^~Nc#Y*}ok_?pgbotgL- zt!NZ#Y+c|BCgkO(YC@_)K3^Qovp)j8=8ij|!Y zD=ANBB+>9{R0*v_Dc;jpqzBe;q_Lo^Z4})5pg~Or< zzSybg;9k)^F?k;ynKXCntthiyVHc=ys%N~KJTY}xgObDMs@6j*&KE}De+F}NL(eKp zBbV)1&4VISWtyMsT18Yf(liP$j79 zFpNNWSBLSKb%JfjTvht?bck0KC3vLPf^lhY{ohB1;+k0W-0YC?ew$wM=uRZuXWvcg5jfds^CYg(2lqcY!wfxmFWw6-MeQ?TRMWJ@*Vs zA9!}hM({3sU6y5rx9OGTP&mi@w+gAIfJX9RTK$ojWY?a2NaK_ZUJA$=S*m8@SwGuiA>^CL~uQkF_z4L)l zZ1kxa^a5xr1{0y7p>4Nh+FfxvEpi`!w-2cMs@Y+98*>txm#cvWxyXG=>XyZQ$Be%G z%GaatvK?kV?=8fe0MaB4te3^AT;q{-3i2>9itZ#R^yl~E!_5boV3XpwDLhtZjEWE} z`vhHe&V@r6&Sq{CyN3#B0q%19XP!-)YKY3-`!>bReBlV%2w)czR(Ip`>gl1W;>ME$-kBN5(7Ew>Ume-@1R_u-moubN&PR)EGH|_HdGVh6B0ZiX&{D73GF=y9z3P>; zl}=?aYxOQTQ+77TW^}0>*3>wXj(9LnRihgbc1{0K!oaF2Npoh4>t&?T z^y9-vps@~UV_)*Z%}CW4(XK)$hK5Cd7Z9q|tl$&8v^4c@EOyjf`9M+?9$*(MwBnaq-^ zT8q(Hxd_G6C2&l~50^Rup}XIIKYw~W@d6k4`KB+n_Gw1AC99J697PWUsT-up7(J~+ z*KLQt?RFX*?EzgiL7|=!B9cdSS zrYcrJ6UP9J5+~p@j^;2Q);6AI`ntp#dOgax5D+vcaWl@R)~S-U6!71`TzG}J5nyxP z*uTRmonsSD@3<-;p;&OJ;&#!=W_+7fA?}z2IvpnFt3!v)c`ickw={}+XfvCtZa*Lz z>uJttZhV=%mJ458y#Gjxzf%ChZ=Mi0BS~Xq7L>v;jN6+blao|#SK7}fT@N8av)jw^ z*oZ)jF}PlG2`LY;b{Y;G9?#R1u>u2)l^2q;^`DQPlq`#WX22*$+h>(TeAf;K5QDI4 zovCsLE>B;BXi;i8Qt8^$N(fT9LDUHrw)x$gjfYE0#F<@7<~-z;o@hGvBn&-vu0i>Z z&RbLow10nXjcaY~dB7@LvEh_UI!M-O&^R{0kvo|=<0(FV>MSXZ5h)x?64bB%Cf@4d zp`xl@Fo|ID3J9z#vvPE1-~f=ApUo6D!z2%~PQ%h@7#1>C$0F{M*D_QuiCnN=pPy-y zJ%_ajb~LtpQG7d%Av=bjT$1(OnG9s6>XZ$kLqPV2ZCTB#Q zxL&)ySWt`cn(%@_0%+k8sMJ@v@2J=bt=DQy5XKp__Y+?6-rESt)f49T9uKexK2%Ft z_*~z_$Oyg?*HKT0&|1wH-LaexRNXOi$azZWq;}h~ zol*&}87W6;WCTSNC2*S~zZ)VJ_Dqv(tj)nvD5Dv`*nJ7x{ZO+bQjxGqk%>_HHr?IM zTujmMtaZ}&e{4VSc-KfL_9%_1!RlCa`1T)Bw}{IVbjb08YPX_~m;SC@_IBX+r5VK4a$&!wI#$R(;B($X^k`f*;L^Zxie!3 ziJ^`zYZjM6-vr5SuK)8aE4uyfbtauCXI*ZZOWS{VlF5g%as+olUo0+mmqp7BC~KD~ zw%^w5I!_MENpIeKzx%;{Ww1X%4N`LWwIfcWtDIxogXG;Uw9L?wlt8b4F@tLR_U-$C7sx%-hQ<{Im>R+!*?0|6c~dm(8i~yPhF$G( z4U1NW?cF|$DTk2f9^0E7*>x#V@kyMh0F-<)N_qM54ACFSR1A?m^_w*iObgPw$NquX zfJ}s%Pbe8QB>YQh*!Gk!lG-0fS}4@hW&W`yypnYb3*YzmG^~F{(BCDTh$J5g*xa2N z@@djY&sEw<*!7-cyIkE$@C}#FuNpIzvC#-TG12DGKSz(u#9S?xD;QFs?m=uBTWL zyYA;}+@5yZ2#+;hp0;R3?jCllpC>TuJ0A!OYr>g`m$jqtTIMq#v`K1}`AG_5&c(PW z3W+alXPJk|?ud$abM$v9jazmpt#0%As}(jS6s9XLXx-i{nw+rA7+D;Pxk1K!1T=6X zR!R^$Fa3|?`2uU_#sqQlwGN?&U#t0v-D-L-@e75`HgQ>4t6drvtO?*KemYXOo zeJ}%6imeYLw=2%a5aEZBtVAV#&tup|?q)ii)JVfuhJs2m*@A^n*O7*g8`zO44jyKe zpZVtp`y=|bD2q_Q!B*>`${AAlD{;1K$xn_CKk5BVj}AY%NPSaLk4#|j*E%uK^4C$; z(so-iEncom2!KNAFD$Oi#AA~5J|6RfY~2XgX$usj4Z-4E(V=wp2~_62I(<&tbguVC z$$}R9-&bCkz>S4g**di{I#V;6dNa24>mqD^4|Sd$NPaM`Ih;(jZ#O)?)9a9+`GYRpVq@EWAKL=7qElpD!B^u0Cg&J z@3coXf>#)S!^Yy0x33E66RRavQV}<^<5V!40(NL7l!;2$-QvYbE+-Z#2A`Oe7tC0Y z4Oy3Ae%`2k;kpO>8(Jhdh)#2_(FsH*Eaa(8s8&u{ci5L!;75Ld%D5X{zoP`wTgr# zbc*Q`R!xO;okUSGRw|$ECy^H)$6sr0uBV%FDtS}!7AiEhoZQ1MxI)f1UFSz( zh)rF4URUuTTjSmsIa*YUp2qE`zocDk9{a_qkdW&8j|{^sdgDIVWAg_*7V{@Yx@;)# zYWb-&)2Z--W#q-~Lon9dz3erw51KI_4lP9l?n&{dx8k~x4RxwM#K;x0p(C~U-i;ax z-!-To9FLZ-^)x9m6H_r;?W2j7X?IYdQr-B)RlSVb9_0MW?c4*;*JxFw7RhVX!^9QU z(J>_k!a=m^nQG{kK`xNl-AVq2MT0uUjlGbU{j3%rBMASv&tVmH*TSCD|Fq^S3wz|3 zc7|n_+}(knHGABPxc)!*=tC z%ef0k76^##?0=6VJ6%I9FLHTbJo-Yr{YF;b%MH3&lgqpX<52!6Ps$9O$HOtuxINy4 z9>&&a)%|^ZysOK|e6px)w%`Y_vv!59HF<+uWx5Wzhy~e0cAxj<*;!icCX44=Vs7&^ zm+e@eD`!?&t1@z11(}{@LOI51siX?jysuL0E7ssJ#yS zjWe+Iyv|xhAgeoYFg5$*%RKB(n&cr}$)9F&5V4VVOl_KBH$g`WrHZRpa~m}4UCRw; z@89aOca2o;n7HDMBK?+;N{TWyLogZgj_@+)hO_JN(!r0*vA?V$HMiYj%ePv}ZdFf8 zjmGv%`rouJn<_P3(*vb{!RtWeeEeOBuS4maoqRywnPZ~SjQdWfB{Wb(5Rh(^B?WAY zV;nH-_*c^vXMGIsfaXxo=eu2?km@-s7y9+Mw4OQ=qz???UfAOZsOW>53P8dP(gu&F z7rUA=PHx?npQ@phDWk02kCq}2(A-u3m%!Hc$tQUpt|js>6nr#j5xHE$SF~WWFR>2Y2a+bs z?Gv-n%L6IAaQ>UhX(>L@mcGs0qtnf27ZHxj^BOCJ#xs zgjDUhgJZ+!eLKMd1vXLfXFoH60MH4i1=k+C9frH+g0hdR;$ z9rU)znGN?E_BAFzAR%^&}WLhv+^X8%X?BNQEJ$6UrQND%AJVd zKpU^6UhJcn&poMsQf6AYOSOrBWI0HhLNcQSZNZNN5FH2W;KUGi>1eOyhIZi~H4Z`@ zb8tlOTZ-}!XF$ag@j0wJ5$eipbcRkt&rKnphTjmld|ZoSL9U8gF&xkFrhd8GUK4RZ zkOd=B?ul!5wD-@NKhJVT+$jN80Dy1I8QS$L!l~_+*O6jdokWbgpNn{}x4K`SFL>8~ zVA68jkR4QxX}ZFTQVb7n%#Q~oWN{^L%+hp3-mcie?r5*u^{|)CP2K&YTS|A<7cD2| zaJl;-B+s;|5Ul<*+m62O16~)rkKK=3^QD+91{}*xo_(-18--E?-Lk~J(N6wUybzZJ zvkpi5g~;xt{XnbFQXu;fMg6~N8S3>e{hiLqssG~(M|BR;5I1yt!-@xbwtO|H>(JQ< zJ<3^a3+`)x!b9J(@PR_0WOYa207X z>f-0J0CEa^-x*M#7PJ!k^QcaLaBOYTKQ!&hhR0peZHfG@Qea~$>ag9x|5*u0jjw}tv=$`I}pjl2bRDT=cBv0qzvZs;VilCqLYU`8{s6epqc$|D~uiI?@ zwBBU5=52C=jdb+;PH&*_!t)KZH+IXI#UReG<`qeOjP*br*uClEDdb^ot^H4nIa+ti zWAG-?%R(7(JXM3WR6`1Fqlqt6Te8G{oY>yvdks(BX6@-8+ja8#7{QhZmF{p#>YE9f zrkoa8JI;lzBitGJ%g(9tw(ry;<;Aea=Z6yqpo{_VRA{+?#gI%M4PPHZFP6b~FSuHO zW%&v5Sy7_&FEq&ER(`(0qm3#sGMs=D>1O<-;{u~a=<+tkb~T|JuJeY&KJU|>y(8ON z@%C;rhQMKMALgX6TR%2h47`Z@?I&eGBPNI+V$??Q-PcPq#+mY<&I|&JT@yW@Tekao z-)cLYET=!IUmp|I9C@c2;!mCn{9z)x9Wr{3B)zEL9%L5S*!xB4mr__8H_hgyNAU&g z-*Te#bG^W%-AqtoS`~>qg66i@?e^KeI6g-vJQC9k8Y6AL9Hj-VY~(zgV7IO%@>5VN zp*9iN_iHC*$)JFrshlSX?cl4T@ZxJr;)Xh%Rm^i-WB&*b_{|2rulJ6*)SB$z9poNQ zpq7Jd-bQ_0mGZ3gaDA3Jo{!3b&!>@EZX3RdPIM{RBD99E!BBZz80?AhvL0XYM_uu zw^ucHWT8~Gl_wq_44+T%8%QMBL9Sji3#Jpp@l1_pq`vPk(_4OrQ$WHqZM|cxxwWHP zzdDL)z`JnSFedS zoSC*6{x4YpSn`ar%uCPo4i}XZ9BfPR{@dcfz4v+l4|#9d7RM94>k=SHaCg_ig1b9| zyC=9i1b25G++}cg0t9yp?(PH#4ng<){%7xfzQVb#GcRX)x~rwCYt>rM{b1*T{-d!3 zm*fSH&sUHXE<>^#|1qo}7#l<*&qZNq?nb#3pcmzTA!WaFl%!ZS9%1g&Ds$^xK9GWx z*5$v9yPY)k4Q{pO52W&wHa^HnW}B+#6Dk$rTB@3BQrS)HfDkEx|+D&QM1xUkeOJNB!%$=sk^GluT;PCYGCM;&R3qF1hWv1k2#uz8rpv~ zlBUFZKGz4sc9)`I;|t35?o6>&reFSEA?c22KM@pdi5tydEWWRaYHKIZ**AIFa(#dC ze@D{g;)iY{M3Juh$!_bpGIRY6r8wcuA0mdjD-IXJpz86NOc1>ft=cuCf&TjI$pqY$ zC+?5mg4(0-z8gVyxzW*-hpy>8^mXE9LN`^D;+zF?+d5+c?nwW)))*m{T;;XWqu~ES zbYP)3r6JnkHW~6~wEu(R`2uPEh~)qI2kif!$UFaELJleL(m1X)pQhR6nw>J#7MCxg(NBLzP zowW-`h%1w`W`bTJ+>53kb`W7SFGNNu*PUuJ>e#*;UNLzJY@)CWhpL(k!~3>U-FkE* z5MA7oGFhIY#9z@eO>Og^=GnmadML$eYliPQ2Zf0H?t2N7!+z<({hwv5cWRU6 z{&onYP_8+S79If_OKI$4r+?Cx?Lw>W+gmRT8Zrt>iz$O!X?(BHBd43 zkZA(~iGGXI$8>yQ0(fn7E&giBn>RC2xQs8l?_Y7{4IP*d>dkSFZDa)u)#@}*&Td0& zk|D$(bcnlwi;)pj@YpyeqL|#4;V)mWxxuF9AzlmBQVQJqeH`yBEtOCx1b0N}>-*a1 p z3H=(lUQ`22N*P%X^d%(DT=s8I#jeI1r-~_=B2LKz$_%$+4*KV#TuG7GI+2FQb*Dte zmd!0(lMUA5ciFq)!VjA3CMNm`9MbgYBA{_-?sO)#x)2}oQa7k@ZYj&ji@Z}S&#rw4 zhX+=7&sdK&AvOg5&2X^sN&gCh0BkcWozM817gi@3wrGv|{EzM@-Mj z@x$Q@Ck0h?Mrdh;^(6T?x#7GPRvt&LmbQU&7_EKBNUf|x*R^!l+#vZEglsAPFch_1 z;lZL60Hbm_yF;jgmHCE33QK5q4d#=m@Gx08V(_o#pYETFT*_hvM7v*aCN$Wxo@NS- zX<#dz@DXV!WKk5Q#7fZnOYHclSKHB9De$2}h&cJAtixcP?0#vMmN`NXBj^O%6F(#(^RzCb7gAmi7sqqW2K44hkUn#gtQGOW+kZy(3wZ| z>@kv>chfq8H=|T0y7s54DE6?|(Rxbuy=`0I?IBD$d-k31OBA>07T&N=ind1J<1gDc ziE6)k<&Ls@wQ-($gNas5wAzzqLbH!p&CL@yz7EPs8&sw3{f8EC3Mo(Gcs$^~V(*L; zCxzzv1dZSl#&?^y+%w{=)(FvY`wR}OIsgdnGNttp%Gp6Fndt=uuKMGgmN}EqRA2sd z%C9|qsZt+JBi)-L9t!vk!-FJgWhE|O4zT?q%{tq0#fb|YrI7jwe&w42vtCbg78ZGd zGb$rGxrsv}T_`oU#=HMF)xLGs`hDU-HHLU&EYUcz+HEtBjzks?aRC!xEfe9BRV(ct z-zk=2c3h5kGnXG3VeyV@pu*|K9jD?+|Mq}!j&;R4IT)8n1(f+Q#`%yt&051`Wwk@s zu*2bSGB<^ORmNJ=45#HiL9fGz9g4$&vNpq$SoW2+ivYtxT&;Z-Sq5I#-a;>h1+zaw zmG+B%gYLCa_jeH(vJp&ZtJgf-xuE!++eTUqvnlNisM7Tyk>cG z_*Xwew8A{p*py^1xuB>$%i$=xJgcNc!FG??&zmjF-zMbN?e_Fi*o}`RIx5R(e(D@a znqVA&EIOJutjmNxWjSpaO=KnG2YwU#x)y8OZ-+-LpB#-{1 zUrH!kG;CbkmiL6HJje%hh0XO=4-HGW($DWX1p)9hQHpTVJu#?{(#th}w||g6`_a{oWDYi) zcm&_i{^e_8VfCxHdEqdBS+g(`iC{?6*5%+*X|hMhdLZt5w(5-JtxIglmFkkT$7oQN z8Wooix4Gyms}MUm8s=V2bQ(iELSI|BZ*SmKuR21PmRDO(o)DP+_BW3YO>&a4%0#KC zLP)yLRul0Pw)oh=MppezzX|MBx9&lB>JNJqTY1*iSGmfOUh?6j92MB1J%=FH+zf61 z;>Ai)#FJPYtt`_mCfpP81RQWRvu=;`1%@;S-(gKmCY??l!u<2%QUfi{HMc<6L{*w@ zpwSm=0#M?LJ%S_>%98SdKLEWlmIUQGNKd2`ImKh~aRoGS;$=* z=W#(+9#@rIdGL2-`)0jrVQESJY*C9L_1NVbpT2+HiZ-=WV?5Ham`NvV6?$f>*A7B# zLvN!Xf*gXi$fo7<x6(^HD@+=Xt4cZ-f~6J2HR zGd4Ugb_rOhHb@=apeitm_2G&4sUL$e8%u@19R!?`p!A(0gL+dG&J)k|qCR~34}Ue` zb%cU!3X@qL%+KK8rnuNAljpv#?&^XCx^~1xTn(GCaYK`C<;_ zMFv{ozmx=xQjrjz%}An-@6iYGPKuCFMjA83A7MbyzbBcOm$f$W4tegG2%nue)dgqrwZ@k@QY6hZv*B%2P)u2CBNg->&RPw?vUxVodG> zX+B%%8h~YPe`{1r{U-B&-6vCT>cfP?)53HMG$9p~H7z(<`^0E<$LbVK!vP)i-HnMM zYzBrf!|D`;M-Rm~Qz1mRwy}efzpO7AoltVe>L4(%8PoCu_cQsIj=)cLP`q}kl%sgM z6D3ws$f&F8d0*s}?>s|;>A34r0v<}ppP1_VV3nU#boFM63U1A0haKS*9&@O;fUtp> zVx@yK|9e<0!YHPbS{DAb-{ev+g=KP|9At9@ z!jVrJ%nCv>pmhO6X+N5Si{oR=N$yp#gQ9S~PdM?{Po%NoEs2^PiclFsig~Le11X_& zhS#i%HZ2vl>U0Dkg5kOf+*O%i34)t`sE zVqn8N{-$C-v60&PJ)cOmme9poz#0HWj_1bgBO1i`Grm7>G8}f0A()&{kfI-WaMfET zPk7arE36^Fr%tTnd={08rBqVTAW&0XtD3dm~88j|hsv-0Dn7|4ER|~OhZg0<+I4mtK{p}=Z zgpgoa1dq6jNBjHk?#^zt5e#;zlrhC|Oi4*0M=>aL*h4A$5XtxU#jGlb_j$Z5453g( zRzucA)`|4=CJblbhRS$;dEtS0LVp<@EjtN-ZSfZV^Du+`@spR0jg6Z-e1y{7J*zK> z{P10PzUf!u%R=+mRMwEs(HiLVob?4Q78MO`-#H30J7DCkVRySdQrtsIgcYZ6)%;s@LIvTd5&1UnFkrpFt<+5GE&Jnyp2KDwrC`iF#(UvhLw3nA(r0HAx zYG|og)|C7)k>@r@Ty1G}gw!q9n=F+PclFnYl*ek`{{34D`7}9*zq{hF*(KaKf&7<~ zN`f{dlhX6I-x{gw?Gp}%^P<6POkorORlq&d7#r5U^&~I*^ie7FoakoAkS7u#_q|_1 zA?rF}5^USoGyS_YYnjtnqP3J~ z!E#u3VDaweyN*eak)IC<30~hXc+iAR;spr|O_C@=!UKjc7C-51?HFiuV4K&oEfnpQj_mS?3bswIiq*>1|T*D z=&jo9l)tcDBm(Ys5T3Bgi~S;dpcDtKsX-tAYiQqd9q4QFmk{h~@ZHZ*x61(|ldTS0 z*!^aEhs8Vfn@SRP=1ktBR0xsS@2Kh8^kd2Hk1|P{i-wFT?`Q{oJn=9KJk}&ffZyGJ z3?;cn$zo^U*MBnsc^4V5j(*)ViK3EH8n8)fP8+aWN;zEL1KxG?zgeJ{cxQ}4Da8jo z%zp^Ks?=Lu_WPw=lVW0{_!mVNkk32Dvv15tlQZ0iMo@`ZU` zv#qn=@_Y*`-Yp`EYYn#&OECd5SmE?}XxDXH!;umXk&U)pww1K^-7n^UT#S<5zG~Y{ z<6n#1cX(ZRSUmoccCq(Ny*5N>sBNrAX79sw3^) zAU_jbT6msSlw~C*Hf9}^9WeqX}=dS*9ny7<*0~tID|6ydx4}zozKbCvEVekx{EAi}T z;uqa!FhfEe9P@bo8lLj`zdkM1vJLo*x zi~9wMONK-YOU(HdKcl=Iehu*2-)FmP>rbZw-!aY_j}xt3qef|xYt1y}hTxagbbi6^ znX27MxsnosX@Q(}L9cJ@509jOI<4fwS}-v+N$*MuQsVPTUo-12XLcL;E_K|WxeITU z1D@x}rgNUR0xITw4S?av2fsi5jZAU)lwNaj|C(f>34F9Rg!8}6-k#hbeA$xU^_{dH zWl4(fkOhdwD!PxP*nfMEUd_oIyr8YNBV|% zNhWG}027zQkj|-h`}vGi=NMgJAT8T2|A)xi{-1xhIL!dQIv|k&(@kN-)a6U5-ZQ-} zK&q-ha4Fz;CRaKD>9Ts5*5~ssP?nx`@cX7%GKK zsop6c!C@1bo2zw#p!_mxJl5%sZN8h+Yi|(Iqq%f;PlI&36aG)e%K$gdp(0-iwHmFd zScy5z7H+Bj6MbfX1W(YXZy%p|v`tfTsWq&?ZuFmB6W!3m`_=ir3)``D1;A~)gFAW3 z7L~`Q{&hTQeMa6{u<`lOa1z1eCj5!4gB-a{t-EY z8l~I9s?0B76s|QQ3z&YrjpC`-D)*1$ia#kkAjCQ!r~`dc@VR^0H`1VsbK)akwFGk= zO@N07&x2>**VXB+CyKuOsZezm%rEr0pk`sl_LPuj2h{2?AU0Jnsfg#)woo|s2+uZm zrKUD`Sisdg45x?&-;@0eI!C;c#Q;aK%4qaHfCvwXqu#oY!sryMe5bHm_&p!h8_fpx zEsUYkzg??G_y0|pWr>yG!cLX7PajX+H6gyUXPqJAbc8HQv5mm3u}h0&bWrr zq9bw}b=z6k;};V;fdpS8`#8qT!${jWVVTTvQS6q*iVAb7&Cszq{;~>FtOqEyDI6+^g>b9)H4j1#ZT}a znc&qwyri0J?waDp{R7u*o;tML&1n@Xy@2FoMNR9(*bY0?3%2FjSRM*T&9NVlnh0%b zPilm`nbhqoUDspPKq(g*)yrc1!|n+LOc~X9VVfc~yV8Iah~W8eOTogynaA{bmm5ltTSJ(&kh-0)r!JQmJJv ztDwpd(YVGk5&kslAA)qQ=u#9*7S6KSE!-$zhB#HcL@5@AZ|wW?XEHXwar$CbsU*KZUr%M!uJpXr9eQ$qtRJ2wsVtLE z0KVswS07haCrB=*j0~&H+bWgtfKx?I**;Aoy~&ATb$ke{&!1*4(N!~p>~=gnGQunm zgT2EXP?66l!wu9MQAz1%?6+k? zG%Ax>GWuR!eYQik>Of0NTb>MedEGvqP^++0O|ydSsDJ@cZPd;dCVoo7()*${mN9s) zg^NHH*w)a{&^YdOd<5xCjaM3pE1T&Xu29sa(u|79^toeYgg!a+XpZ*L&U)i?kUp=b zb0hr21WKZN{^0p#uv~fyKkcqa>o+}3w|X(LtQieX(r2(lrl)6iA7Rn%vQYz5Z;#AA zB4SuE#WhuvMGh<|Pf`oG#bErEX`Nc0K!C0e5Ek_MlfX~H9Sy*sAU2j6!&+Z6t^v$e z^J7)gH%EjVazS~H=+6XH`16UA4$UxiPdiEpMG|}sv|JIBl<@i3^#r`%rp4`ZNBH*; z=2V`NNnOT7YTE1J_rsKM%r~N`xmPzvVFPQa(^h?oyS82Ufs)@SPg1(cCxa?3ZK{Ei zS}x8klq4V`zOu^(*ghxGbJ%mLY-DA- z=5%i@U<5l`Z4{ULr+ApDA+%xOUYv_ea1Ip=Hya%?2+eEleXa&pkbi}J8Pj~2bi2#T z72@{LEOaI{i6HFuyiw?EVhvU+G48I>pskImr1wgQ7(ubi7}%A9vr;-QJ2-kZ&@!!J zU9c2R2QA0`q!vDL!LK%wc6wtIo*@KYV+}9zY>08zRhT zvjpB%ZP@>tjyU>Oiyk2o6%6zhRKfjG5Io1+k5`*z=tFvWSsH;q_C*hE{~uaM&Q8rR zfkC^IG2}CpN-XT_IYTOV=}tp5x3EpAo^fJ21)oZ3isa_@_dB=lX3S_@?!{AUNR1c( z!+1iP!;NvfIlQaG3yXQO4QPX}zq2v)JNI5AL$Zv0td9lrtFVA0B+R<8x4mxr*RhVb zh4C>_msopBOJGCV<@71^vRj8 z-`k1PjD%9@W-An2>SIRtCXTeGU;nM;mz9+PddDCBVyx=OQs|z_+8R!KP6%qNS(ar0jC9IsL=Ye(bf$ z|7^=2{jJAu(G!UyYZy{^Ssb<`L12D%f~bUrL8BOJtj93;E$6c%(x0W>*5;+Hv~=9E zGM4OF8EqvD1fw*lSGmoICZmMCP%WJ@LX~j;+(xwTfdQuFJzO?GILGck`zS80 zTBVaKh`(1$^4R)su9HA3O`0a|^32Jn935eu_N+9=tAFF*0Io%ImO?>l_)XDfeau?5 zFanA)Pc6k?G^5)~iw68zl{^kPSh}1AbZNL^?E{%2d9Xt@`RL=CG2Jiid63nZULAg9 z*-QLmXeWnRh09RpSdpBe^AJqj%jt@#fm5hb0+XG8C%uD6$WZ$BlS}%oyvk8!Y zC@{;a|5}*@LV6r8BE6p~hOzu=$$Deo6cvgAv{pXPv{Ev%-hm`i(k6BqERgIl{4WkW zEl=Bxqnw%0RIoa}DFZ@%xs}`)HPhUx@fCXv%6`rBTb!D-`y}Eg+|{75B-*IeK89d1 zo3ykvJm>z|1${rX-sny@)f-wNnlxc(%jJxY4!%MwKZrDj@=*IHdu9TYbZ2z&;6Wpf z9_zx(UixuJV0rF0V#DY!DQF-UMtKE>@?cpWrru>vPax{A^%SC6ai1l5RpXl=HHSHP zZ);6jh9OjB4FG}QU`BG8<+@dl$yhR|bD?aWa#_eAT5K>|*9zaU50B=o5;<$+>pMtJ zg3=T&8CDaQQXjDiU+-=%5!47;Ku3LiTE=qKW-{mX4DO-V6VVv~@CkijSFy{vl*sKo z2+AJ~N|iQ91kM*Km|r)U=?VlhCRH(#X*53{S+Ews(W|xqb;0z`z>42B4R2F@*>Z^)o zd{#3)WL7-|$21Z`esu-dFw z)m|}-mSsyt#eC}^itv!eD@E%BEXOCG!bH?08@8PQUE0VE^Jh$Xo~T@57IS}Knt4!a z8Rpn(g@&`*(Cb3KFarH|pfV*NFWU=@ERVYuDpS9%gBnQZiE{`vc~NNQRd+|7tZA&} zqRW@tn@NJ8?mS%2j%sWyQyQEj(+Apk?g?Zlq4^htTSTp*7lrOK(=aMogp6r(l*Vph z?+Z+OCzcFS^VPseU+Jv)nvv`!q4Q788*@y|n1v<=s)++CYS%|hxkyUBFY}8F0J_~O zF2?D!Yb;o`g1=|k1E___s0yyF27;#Nu=j>ZDb43Aqml@_%~Uc4?$kgTF}$gET++&8 zL$4u4;HOB2Wb)F39hrtm>92=ncjNGs_CPe6Y)ZVE29jh!T{1KQkG3TF-oUo6lym0> zk?2b)vQhL*O)+%kBG}QxY^fYka#~9fmOdA*X-qeBZmXdyv2rNl&YUM+NcT_7bscS1 z?6aVpgE25vj__O|adqAJXrnRG?P*FLrxFtqv}v^Fw90szJkznME)b`Xp+6YE5>H1>!owWK72YaMblY9QX|Z3lIB7dLQ4>Kq-S4EE4g*e$dv+ySsi zogk*gg~B~8HhLijCS?m3Oq#(BmqZ!I`6L?1}l02yHk?{m;OsdwUfLhw+K$eRW;lfyT2yw70f)PJh# zM2mWNqo&_FP-#2G2q2QrQ1G+S!iMa@eC&cEPP_~WoWh6Jv?!WGp>R=`Xe5)AD zuvLUzzHsHLki9BT)}XY}CIkSh1*x!DAYQ3pp}bPvC;FoEFND(L)I;oS4jYl1TQo6r znlj#Hba((1SczPg-qNRa9688(QkPoZRv5!dW~Dryc}mG~V;@Ch6(ix5}@nMU^SbV28$qL)!D?keX}&qly+ z%ei&*YDen@MPqREGrmEoUH6ZV-(Lc170g*RbFuC1Y|ZFb?F-V27)B{!;zQoUzponu zTNSS;!0dn|iADT{M`ZcGgrnlVza5(~=nb452kmMg(??0^sUIpJZSJsLq zwb^@{>tQ~1M2K{%>W*dfKE1#;$z7EO%fgLOb7{oPfdKKbu?h-5$5mc5an%(1iIGuV zLg+Eko>VCzemKtkE@Z=lyj(;>ye-6ExF)Qse=w}-38`!YbX(Sy)U4;E2oycHtnMh( zTB~UB$L8dvwF&jjEHgY)Rx*h0R^ZgeyKfTG$BA-*EINevBqS)(0^${Tc$VFBiLzQo zaG|T2n`>j<1kW2YmSSA!G_!@TBAJI?A*CacX zO9@yFo#r+ThaZHz4x1^{I@Djp$U)U~y@a@*>B71?G{kTUz&;jd?q#QlUarsO^%@%$ zu`(=%YY@-4$Km%0GMQBh-flAlum&o+b&9C5$yb*J&Cx)O#F*m9!NN$#bPHVeQXYeG zouvXy0oi2stJ>YAc7X16FmY>+MI$X4p36bHp;%53CoR~L*c4&IMOZFs zqlANpd}vVkFmQKww?SU((?b7OZU&Snv(Fa2ymR0r7_!5B%5Yi(shrOAK1~ADZFCiG z#|@xaA0MzcLy&?WE$JMt7heh#+1M54>E7pN+39Y#I(X&|1>$-bRV|I(SfRcRRdZlU z=E#;Tx8C6Vy{Z4ik{LZJlup^pmimjGO^5$`i?~XY^~^AK(t0?orY<)HYIY9WSjroL zN}m;34yEJCMK4(W^lPs9RXO&bGsH7q8rOHISb%n!^qkR)d{u9|P2BMW=hZi&*|ar@ zJ?30uYsDcB4@IX=u79IK#}uidtCGDH8p0KO@gxHLO@8W6Xv(2`=}ab!asw!V8O?Ia z59!mDc0ciP2LbHA^!}VAZtG1%{^;kG|K&e1IfXQLK0I-U*p$GoTD2MxpTUlEistu| z-U8(N*QQ6^Oe!8b2q&mO-Wr4ezqNP1i)r+JR&{4=33-g>2gg%`Uop{f#?oVlz18@o zGGxCZC99=1a?uZ=j*nCRlk|yIZyNgnV01y)b6ydR3X4g(saK5YaZ!p-K1lq4|41YZ+C zR@jkdXT_E&)Rq=qbdHqpea4{JlZ8PAE{T*mUPwq=8Bz-QA>d;Okm^~e#%m%q{mk5 zO<3GCUF8`+)1YYw?a5_Ot)trM0eV~hsQ=Y_i!M@~u&(1&JE$DP>X^7QPIV5H!}>L% zX3>3tWmCIbxjsBaV%wj;E=NYB?zDyX!)WF#=vis3adR{c(*mqMpar!q;_!A-x(Z1> zJ>Q?@50t3;7@JI%4lRv#fw}sZj}1ivC~Xg@Ob5e5=P8a1!|Q+iS<3B{R{GekN1&WY zN0#tjl2tW+pdhcQZtw$zOJOIpMiE&YPv@fa*eFh|wmE*cTyAy6DwO2A5w>v(QUFsV zWqv9claMxI6sUrs$4N>efI&E(P(NDf>z-Q)$9KDyUOJCVl@YH%y%Wcp_P*MB&T|3lD=+^ zL&CI@B_9|0HQT@5qbOO)RKLCea2M&}#ie$j=3b>$&=3=P?OfRgI_<+u zw6*2sbw6LJcg-FV0rm-rng=*1NHY z2BB`DdWo`2q*Y2*k={bog*H|eao&r0rJ5dzRe~`$&5|%#e=+j;K3!%1?KBvGJ4T~2 z(zRu9#?_CuZ^2P=KXx9vqEiy z&yx_`l>8?d6;ptuB$+MH5S_3C@%lzFgbbEv48Y!kv3<1*4a4$sj8*6+nT_PF6zwYu z(%~ytaaUO1#=+{@?Rbjf^ETq?Y{P+KelQ3|&SWV~;xc2V4KMR1X!=245R)Un4R1b3 z`v>z3N7Pr_g=!gZqc1SyW~f1@f|EKKN9SjQ8m?+JFo0qD#gp^O-JaGIF1&yxq^(!q zt{j!Lm_l&qic-W!Z}i7m>Vxipj#uamEEjjhek4o@_Vts z52PavN%NG43MqLWlTZHdz-5iOH!5O;sRBG}>@}fl+JbTKE zsX%AG>$`k~-K1qJEOqL&?<#7=G>(l3BwsFq=VWxp295VAmF~mgpC9dP`M1iuaV~Ho zCZSwqB>_Lp0R89WgF703f7x63DPQ#&SDDQW4alaRI~Bzu={e>ljOWx9W+p&1Mx|S*3Z&_un%mJ&yH3cy1Pv** zQKGOFKe$V}Bzl7z24mWWusV%~(tf4)*@i>1|ADKAaoc#EGciQux4{0nOtw!zU4~TY z$S39-a5ll~rR+~0#9^N61pj}hSe655syDsX3}EaO)?;bZaYbpk@Ki2mXLr&B_%Tv1 zGy1>3{T-9ZjE>#JbvYu&+&;$_;`B)UN}I@f@!*HE;E%xG*eXkB7>O3ZZxjk?K+kUf@VQcY?Cm7e{xvIV!mZ%UmG2!DeFG<0)(r($MPEb8|zSeTZJM z(!=OrkgQ)6g!GrMeJ+u{CYGRA#$Jl6-`ILA=R>~!eV|Az%o_6=lJssO3Hj%WM;ZFK zAqg3Nsxh0w6EcWDLFF~m8QF%ykmkEV3X)fQY;C_k)qK-ww)fzUPylfv`a?6wnxRMQ zeB}0|v7yBud<;d#zc5AD(=427F(FnLUr2=7Qm+(X6v0^f}js(pC z$079F=?D$hVkOkzYHHu2dsu(5uWwPiz=y`@Xg2AWmaoswRoZsN=Nj>lFgMNZtPqra zf#uPD)o}V}JKWLUys)&tJ?H5LlKu7I;|IFz({rU3U=zqIYq=0Z`zlEkG4&Hdoj6|^ zu$yX6?W3UxH&jJkh8J6Cc{$F1j_WRvD`Yf_^+Z}?%Q(BjY4i=INL#e1!<%O58(e; zS@Zx(A59|Br9)62P?i9}YZ1%Rqn}qu9i=}fq#>`^44q^j%M)sLnxI0o_fTi1C$I9I zG+*HAy5@vh>klyDB+EzwS-_teL#*X~_i*Nf&r~Rjs3C4f;5k>XQw5;zAQ*8ez}EZm z(*A+$Y6tn36R3n!(*`I<$uZEoBq4!?`~p>Om3A}-A~@N6jT<3N3tL0M;!p^KWzghq zASJYGwnX)Ifj)2HLdXhtw;JE##e4#l7M%Ug&M&kK#XUFye}7C2{epMhH0SHuOWL z1qS&6fA6H#RtPXRz3&%Old@%RXK+sEavg{j4W5&WVSoLIAE2*xNpX(tc*xXkUw_;C zev!^n1wG=0pcYOW1+mE|zTdx8VFq2wY0TBl~btwvO9BtDEwN{RDq%!#C|ZZrrPe2h^Raye;?H*#vIGC#&; zCr9C>X4feE-VqCbiZ=gvf4gh)Ac2BH)sT}E(@=a#%^R<#oRxzHy*3u7$emH4I5d#X zWa`EeTh;&fWZ-h~=}|*igF6YfbB@#uWo-0fLB(}9REQg^1AZVPT-wi z^>CWfRVuIpI+19Q*HDtZ_ICe0V@yEkiDALb?Z}5W6|92LUxYQGcNW(3&{B8rKq3`@ z^iBuLlF?MpwvTJBl841dD5Rc0AM80Js)s`d5ToH=~0N3MkA#O%~ z0p|@PSM;aL-+b(!-7l?Q8XGDNqZ$FN6&Y|NBiDZ{3Y#8(7cO;@-kvwj1h)n7I`91{ z?wHL@jzq88NTuH#qb8xIRVEf43g6!kt15Mr*baC*JF&@3=!;TBaxS`4nn@IW1>rvS zO}V3G6ebx7rwsuRB9e;+=_#d%jzhFQF4ni-A6A<}0(@=`u8$`R-sE{~5Va>LVIUEA zDsaXG!HJCcXnz%DJ)|!2klB!4DbM*Mqp>`Sr2U!;=0{F)CZPa&;)agBcISCcZ~N)M0V7kaAT`O;%+QWA8yJJAx2?xt5xQP3XU|B=naG#L z2i&fPt+bnFFC$!>(>~8|sPVDQCvRV#GJ)T}fA3wNIz8?op2L`7Qvt+b)3`$lTAkZg zJ9eIUpLZUP$$UH&EjjC)u3KS^$d$x}<+a!Y#Y`|IrY3XvJeVP&|BT3{xVIVx3%yiS zN2JCYzC+9El?37)Pc?K;Baa7t*GX-PRQCd@P2k}8AnJI;CZ&)+9qvZ@uOH>bA7Ts| z<-xv`GhN>pVzNqHg}qU>35E0$nK}BcX{~x+IuaCGJ=Xg|;I;ogjtpjOa5!QnhWs`d zu*#2`899d$CHl0*5y*uoBlYJh{%H^1}rNdOi#nqbgWQavAd8>bS&sKY@@c0km1;0K1%qUH`zBm@Gc7(d4#eLz3Lo&qVp0eM zT+`P#gj}t;UyJF+SbZ?*r8M$1I@PUts)2+XA#Zc?Uvq_g9v0`zJRT0?{SniprL3mK zTNPJsRXW6omW{3>zKUJ@)+QxwK5j0f2IzzappU5D+?~#g{JY4Mfj>q~$jD>qlNakbGg|-^ZFK5Uh-CWAY(F}1DeA&c|~H6hh(^(C-b^33_W(H zg)3!Gi|(4)cq+J|&{_u=t`;iPMfmw1Ca;Kp*^OVVl5t5d$uD1&z^%B4(AEx;q~nz} zTKLtic6Syt3Zf^%bOKbO>8Vz9xEkS1Ak#6ah+JfWdh6Al8EPlXsRcU=Cnu+7>-QfK zL@U_6N6a?3wW|9c)K31ycV6!D(7?ag>LAtzE*sIfEoWzBZQyhc-)+hVmIABHLpIBg zTNO3a9A<3b>oz57eA8oaL{sbPfMtD_*Ja1?m4S)E)nMfVicO%@!{DfV0|NR7-R~l(eRT z9sCagn5?deMWTF(^pC`f0COsvD7GEzV6WRLo`AbQ4R2_Zadtcd0M}2J)cQDp5D~tQ zexn@a&C9|3D514qF(Mln|Kc2dVc^G8=#<~5K1j*@AWwf*pA$>sAhwgFsu&EmBI}98 z4$8ipyKo4dIq6!HX^TNc{453{26GZ|w?6S6DT`a{pLvTT2X0SHgkOT;Xq`Bp$NK=u zbJo#onh_p3Ec=a15YQegTRv(2V0EnXS{>=maGYca_0fYAaARGp>oDzS@OnG<=6C(A zBJa(by(3MW1rK0r_B3Av?FN{D7}wRpn`M4+k&Bh}>frqovG0XTl{}UufbH>cM}@Bm zUy$l{SllV7u--XzF6f4uO=_%EyoO6A!>Ar}BtRoJF7D0U?mVDdpxeU;6^kR>uh5c? zi>V7vf`iR_^Jpsjh3tgv^6z()7!hB_1en9AY@V51fk$Q2eOFi4PM%|FQr3a>K^a=F z7*l?Bxcxis^2?9$U;gLX6ZVV2h4>)s28!B2JSX1yUZF1?VM_Dsj?X;ViZEgMe1+IA zc>i6AQpS#?7WgNUeUF|OLxoBFvbuLj&4524751Bb)vHU0e$`r&U9bLC?-{|X1~t|d zcYVkHubM-};YsFY@m@e_hQ_)LIWDRJ7Xm3#6kQJURv(x-Wh&#+t}k>q4v%}oK9ZT2 z-Qn+cCx3jbSU-+~YI;AXU>ME8W@sjUi)5ZySS*fCkgQa@QP^p9IWH~#>l*wzB*GSE zW4k6jIuiNjf0Q}>?$le{R5)=R9dx6+>$}mnB#GfDU0rN?c+B}!)rmj< z;-d(NY+esilv#N`Zl9jY^8K@PEq@L;&iE|DH%a*Gqn5%5Mj##IxOyUpc&;xvwmy2? zIgH(wx=6C6IsynaC5PRzik24d42i33^b*)Sk-2d9<>lo$I5^5}+}&~8%gW%%MnsjB zX*aZH|HjH&yo5khVV=uJlP=$tdCiS_7G~LqUVEIK#A7QyvySv|l-6(LgXr&LQv&Bw zGK$O~$#l(44A)z%-SE+jyoT>OI-<%jqlYdhCK-<2+=Q>PFj;ooo&Im$P(8*D!{Lr6 zVnd5n+IUTy9UWm6U!k{X9jESoc-*^vjyWlOf!TWIuHIf?{)-Ya?f40XV;wcC)0G2h zw`1tybVs_z2=$V4bC)nevIrPQOMiG}JQ+x$Qyi$SpsglP*f7HUbEO`)3$j9#;C~}x z*-FZJ+r$xrWI@3Ai(r1ybZN(q7YoYn&rg9RX*?i+Y8pw4&ca-^fLK;Rdnu#gS#hlW zT_L?-eIIv;Fn}fO%Hwh)bC{Btt}pC;#ISS+mmHi{gw@23NZ+kaO_ROHY*P?=+7Z;! z=CC;Rnm{-;ZKGUohS&<)HOhu0D_{uXQem~oU6SfEQMPyIG~jEMcHfzP#H4MqcOI$@ zWQc`zITJ%Ot)W!4minu^wCMlJ+AEY;@#|j-!~}!>-{U;k87h*+&n$8zTK2Af$g2X$ zAZ^A}@rFDbQ@0Jy0_G{e|M?CK4V3IINqV6M+nJ%%=O^2W+Axc|kTr&^(}I&AX>SDC z3@*9e(^8Q8ZPzeIJrI8<$n^LRCx9jf89l-oauISU882|TRZ`{{%H$YgOx$Imfyzbd zx_HqL1p!_bV>RqsNT;kC{koV7>lmPer}>rL>kZh(&0YGj{Ysl~0MsLDWE@ed>Zc$i^+B%OiKl z&6F^J5b?|s9qcBUPc*^wW#1S&WU(5vwz$nxi?G&#OY|y5IzGdY*7(FT)_vLx^NEc; z(&!gE1)mI7D?p!mw~n`ZofGKTBU7WmLi`m|Br7Z-m04SW#zrsU+!9*8dtfHyn5LgW z2;#EEcR*d!Ey%u1gR3w}{epd>I121F2?6|Uj4{xMqLhreQ@6mGUK^u=6Z(1*kaV=t zFMtkjgC$N(k0g+u9U0_`@8dveN=5;g z?`UU4i8y*;D1>Cz75}?*vi~);l&3Lo2{YTQQ%+HJ5>-z0G-Z&GWBA zqkC)mN&k~upYQl2b?;Z?Q^QxHj(=}^?_KrvYXzIsxdX5NuYKs7v6t=6Ov8ERA2*ij z=wB~nRM7f%0lvj#9^*-ea^*^s37_``k%An Date: Sun, 30 Dec 2018 18:35:40 +0000 Subject: [PATCH 143/333] docs: rename pd image (because of GH CDN issues), update readme --- assets/{porterduff.png => porter-duff.png} | Bin packages/color/README.md | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename assets/{porterduff.png => porter-duff.png} (100%) diff --git a/assets/porterduff.png b/assets/porter-duff.png similarity index 100% rename from assets/porterduff.png rename to assets/porter-duff.png diff --git a/packages/color/README.md b/packages/color/README.md index 44d386ab6a..8332e3f226 100644 --- a/packages/color/README.md +++ b/packages/color/README.md @@ -96,7 +96,7 @@ The package provides all 12 basic compositing / blending operators, both for colors with pre-multiplied alpha and without. -![porter-duff compositing modes](https://raw.githubusercontent.com/thi-ng/umbrella/feature/vec-refactor/assets/porterduff.png) +![porter-duff compositing modes](https://raw.githubusercontent.com/thi-ng/umbrella/feature/vec-refactor/assets/porter-duff.png) ([Image source](http://www.svgopen.org/2005/papers/abstractsvgopen/#PorterDuffMap)) From 4f0249188b0c685594a39c154cef2f1a6d77c7c0 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 31 Dec 2018 03:16:23 +0000 Subject: [PATCH 144/333] fix(matrices): scaleWithCenter* (add missing concat() arg) --- packages/matrices/src/scale-center.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/matrices/src/scale-center.ts b/packages/matrices/src/scale-center.ts index e4fe20e4c8..c34c8e3f88 100644 --- a/packages/matrices/src/scale-center.ts +++ b/packages/matrices/src/scale-center.ts @@ -1,5 +1,5 @@ import { ReadonlyVec } from "@thi.ng/vectors3/api"; -import { mulN2, mulN3 } from "@thi.ng/vectors3/muln"; +import { neg } from "@thi.ng/vectors3/neg"; import { Mat } from "./api"; import { concat } from "./concat"; import { scale23, scale44 } from "./scale"; @@ -7,14 +7,16 @@ import { translation23, translation44 } from "./translation"; export const scaleWithCenter23 = (m: Mat, p: ReadonlyVec, s: number | ReadonlyVec) => concat( - translation23(m, p), + m, + translation23([], p), scale23([], s), - translation23([], mulN2([], p, -1)) + translation23([], neg([], p)) ); export const scaleWithCenter44 = (m: Mat, p: ReadonlyVec, s: number | ReadonlyVec) => concat( - translation44(m, p), + m, + translation44([], p), scale44([], s), - translation44([], mulN3([], p, -1)) + translation44([], neg([], p)) ); From 4c6fe066175b542c21dde95f56f7fa5212e1ac06 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 31 Dec 2018 04:55:30 +0000 Subject: [PATCH 145/333] fix(matrices): re-add persp divide in mulV344() --- packages/matrices/src/mulv.ts | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/packages/matrices/src/mulv.ts b/packages/matrices/src/mulv.ts index 4d249a7ee5..3172990963 100644 --- a/packages/matrices/src/mulv.ts +++ b/packages/matrices/src/mulv.ts @@ -87,22 +87,32 @@ export const mulV44: MatOpMV = /** * Multiplies M44 `m` with 3D vector `v` and assumes `w=1`, i.e. the - * vector is interpreted as `[x,y,z,1]` and the last row of `m` is - * `[0,0,0,1]`. Supports in-place modification, i.e. if `out === v`. + * vector is interpreted as `[x,y,z,1]`. After transformation applies + * perspective divide of the resulting XYZ components. * * @param out * @param m * @param v */ export const mulV344: MatOpMV = - (out, m, v) => - setC3( + (out, m, v) => { + const w = dotS3(m, v, 3, 0, 4) || 1; + return setC3( out || v, - dotS3(m, v, 0, 0, 4) + m[12], - dotS3(m, v, 1, 0, 4) + m[13], - dotS3(m, v, 2, 0, 4) + m[14] + (dotS3(m, v, 0, 0, 4) + m[12]) / w, + (dotS3(m, v, 1, 0, 4) + m[13]) / w, + (dotS3(m, v, 2, 0, 4) + m[14]) / w ); + }; +/** + * Multiplies quaternion `q` with 3D vector `v`. Returns transformed + * vector or modifies in-place if `out` is null or `v`. + * + * @param out + * @param quat + * @param v + */ export const mulVQ = (out: Vec, quat: ReadonlyVec, v: ReadonlyVec) => { const { 0: px, 1: py, 2: pz } = v; @@ -117,4 +127,4 @@ export const mulVQ = iy * qw + iw * -qy + iz * -qx - ix * -qz, iz * qw + iw * -qz + ix * -qy - iy * -qx ); - }; \ No newline at end of file + }; From 52fb939966b81b110e3ac2e62f3f4c3f97ba9c78 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 31 Dec 2018 05:02:20 +0000 Subject: [PATCH 146/333] feat(matrices): add quatToMat33, update readme --- packages/matrices/README.md | 4 +++- packages/matrices/src/index.ts | 1 + packages/matrices/src/quat-m33.ts | 25 +++++++++++++++++++++++++ packages/matrices/src/quat-m44.ts | 8 ++++---- 4 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 packages/matrices/src/quat-m33.ts diff --git a/packages/matrices/README.md b/packages/matrices/README.md index 3279dae217..960d9de3d7 100644 --- a/packages/matrices/README.md +++ b/packages/matrices/README.md @@ -150,7 +150,7 @@ import * as m from "@thi.ng/matrices"; - `det22` / `det23` / `det33` / `det44` - `det44FromCoeffs` / `detCoeffs44` - `diag` / `diag22` / `diag23` / `diag33` / `diag44` -- `invert` / `invert22` / `invert23` / `invert33` / `invert44` / `invertQ` +- `invert` / `invert22` / `invert23` / `invert33` / `invert44` - `trace` ### Matrix transposition @@ -161,12 +161,14 @@ import * as m from "@thi.ng/matrices"; - `alignmentQuat` - `conjugateQ` +- `invertQ` - `mixQ` - `mulQ` - `mulVQ` - `quatFromAxisAngle` - `quatFromEuler` - `quatToAxisAngle` +- `quatToMat33` - `quatToMat44` ## Authors diff --git a/packages/matrices/src/index.ts b/packages/matrices/src/index.ts index 7524d50067..6f7c72b0f9 100644 --- a/packages/matrices/src/index.ts +++ b/packages/matrices/src/index.ts @@ -28,6 +28,7 @@ export * from "./perspective"; export * from "./project"; export * from "./quat-axis-angle"; export * from "./quat-euler"; +export * from "./quat-m33"; export * from "./quat-m44"; export * from "./rotation-around-axis"; export * from "./rotation"; diff --git a/packages/matrices/src/quat-m33.ts b/packages/matrices/src/quat-m33.ts new file mode 100644 index 0000000000..8857a1e6c5 --- /dev/null +++ b/packages/matrices/src/quat-m33.ts @@ -0,0 +1,25 @@ +import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { setC } from "@thi.ng/vectors3/setc"; + +export const quatToMat33 = + (out: Vec, q: ReadonlyVec) => { + const [x, y, z, w] = q; + const x2 = x + x; + const y2 = y + y; + const z2 = z + z; + const xx = x * x2; + const xy = x * y2; + const xz = x * z2; + const yy = y * y2; + const yz = y * z2; + const zz = z * z2; + const wx = w * x2; + const wy = w * y2; + const wz = w * z2; + return setC( + out || [], + 1 - yy - zz, xy + wz, xz - wy, + xy - wz, 1 - xx - zz, yz + wx, + xz + wy, yz - wx, 1 - xx - yy + ); + }; diff --git a/packages/matrices/src/quat-m44.ts b/packages/matrices/src/quat-m44.ts index 43d720b5cb..53f5dff4d5 100644 --- a/packages/matrices/src/quat-m44.ts +++ b/packages/matrices/src/quat-m44.ts @@ -3,7 +3,7 @@ import { setC } from "@thi.ng/vectors3/setc"; export const quatToMat44 = (out: Vec, a: ReadonlyVec, t: ReadonlyVec = ZERO3) => { - const { 0: x, 1: y, 2: z, 3: w } = a; + const [x, y, z, w] = a; const x2 = x + x; const y2 = y + y; const z2 = z + z; @@ -18,9 +18,9 @@ export const quatToMat44 = const wz = w * z2; return setC( out || [], - 1 - (yy + zz), xy + wz, xz - wy, 0, - xy - wz, 1 - (xx + zz), yz + wx, 0, - xz + wy, yz - wx, 1 - (xx + yy), 0, + 1 - yy - zz, xy + wz, xz - wy, 0, + xy - wz, 1 - xx - zz, yz + wx, 0, + xz + wy, yz - wx, 1 - xx - yy, 0, t[0], t[1], t[2], 1 ); }; From c7052171ea745161e242bf88f422ff26033d1802 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 31 Dec 2018 17:29:49 +0000 Subject: [PATCH 147/333] fix(vectors): cartesian2/3 --- packages/vectors3/src/cartesian.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/vectors3/src/cartesian.ts b/packages/vectors3/src/cartesian.ts index e2bc7cbe87..77a98c95da 100644 --- a/packages/vectors3/src/cartesian.ts +++ b/packages/vectors3/src/cartesian.ts @@ -1,7 +1,12 @@ import { cossin } from "@thi.ng/math/angle"; -import { MultiVecOpVO, ReadonlyVec, ZERO4 } from "./api"; +import { + MultiVecOpVO, + ReadonlyVec, + ZERO2, + ZERO3 +} from "./api"; import { vop } from "./internal/vop"; -import { maddN } from "./maddn"; +import { maddN2 } from "./maddn"; import { setC3 } from "./setc"; const cos = Math.cos; @@ -29,7 +34,7 @@ export const cartesian: MultiVecOpVO = vop(1); */ export const cartesian2 = cartesian.add(2, - (out, a, b = ZERO4) => maddN(out || a, b, cossin(a[1]), a[0]) + (out, a, b = ZERO2) => maddN2(out || a, b, cossin(a[1]), a[0]) ); /** @@ -43,7 +48,7 @@ export const cartesian2 = */ export const cartesian3 = cartesian.add(3, - (out, a, b = ZERO4) => { + (out, a, b = ZERO3) => { const r = a[0]; const theta = a[1]; const phi = a[2]; From b912516852aa306836d6720d60eade7393529a34 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 31 Dec 2018 17:30:19 +0000 Subject: [PATCH 148/333] feat(geom): add ray skeleton impl --- packages/geom2/src/api.ts | 32 +++++++++++++++++++++++++++++++- packages/geom2/src/index.ts | 1 + packages/geom2/src/ray.ts | 16 ++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 packages/geom2/src/ray.ts diff --git a/packages/geom2/src/api.ts b/packages/geom2/src/api.ts index cc30721665..6bf8b1eed5 100644 --- a/packages/geom2/src/api.ts +++ b/packages/geom2/src/api.ts @@ -43,6 +43,7 @@ export const enum Type { QUADRATIC2 = "quadratic", RECT2 = "rect", TRIANGLE2 = "triangle", + RAY = "ray" } export const enum ClipMode { @@ -281,7 +282,7 @@ export const pointAt = defmulti(dispatch); export const pointInside = defmulti(dispatch); -export const resample = defmulti(dispatch); +export const resample: MultiFn1O, IShape> = defmulti(dispatch); /** * Returns new shape of same type with a shallow copy of the original @@ -747,6 +748,35 @@ export class Quadratic2 extends PointContainer implements } } +export class Ray implements IShape { + + pos: Vec; + dir: Vec; + + constructor(pos: Vec, dir: Vec) { + this.pos = pos; + this.dir = dir; + } + + get type() { + return Type.RAY; + } + + copy() { + return new Ray(copy(this.pos), copy(this.dir)); + } + + equiv(o: any) { + return o instanceof Ray && + equiv(this.pos, o.pos) && + equiv(this.dir, o.dir); + } + + toHiccup() { + return ""; + } +} + export class Rect2 implements AABBLike, IShape { diff --git a/packages/geom2/src/index.ts b/packages/geom2/src/index.ts index d25bb8920e..25f474a0f6 100644 --- a/packages/geom2/src/index.ts +++ b/packages/geom2/src/index.ts @@ -10,6 +10,7 @@ export * from "./path"; export * from "./polygon"; export * from "./polyline"; export * from "./quad"; +export * from "./ray"; export * from "./rect"; export * from "./triangle"; diff --git a/packages/geom2/src/ray.ts b/packages/geom2/src/ray.ts new file mode 100644 index 0000000000..3f5f9eb4f0 --- /dev/null +++ b/packages/geom2/src/ray.ts @@ -0,0 +1,16 @@ +import { implementations } from "@thi.ng/defmulti"; +import { Vec } from "@thi.ng/vectors3/api"; +import { maddN } from "@thi.ng/vectors3/maddn"; +import { pointAt, Ray, Type } from "./api"; + +export const ray = + (pos: Vec, dir: Vec) => new Ray(pos, dir); + +implementations( + Type.RAY, + {}, + + pointAt, + (ray: Ray, t: number) => + maddN([], ray.pos, ray.dir, t) +); From 76c343c35ca8bf2608a7f93358239ef49bd0f434 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 31 Dec 2018 17:31:37 +0000 Subject: [PATCH 149/333] feat(geom): add pointAt/tangentAt impls for circle/line --- packages/geom2/src/circle.ts | 13 ++++++++++++- packages/geom2/src/line.ts | 5 +++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/geom2/src/circle.ts b/packages/geom2/src/circle.ts index 4639a7efdb..63e30ccff7 100644 --- a/packages/geom2/src/circle.ts +++ b/packages/geom2/src/circle.ts @@ -1,7 +1,13 @@ import { isNumber } from "@thi.ng/checks/is-number"; import { implementations } from "@thi.ng/defmulti"; import { sign } from "@thi.ng/math/abs"; -import { EPS, PI, TAU } from "@thi.ng/math/api"; +import { cossin } from "@thi.ng/math/angle"; +import { + EPS, + HALF_PI, + PI, + TAU +} from "@thi.ng/math/api"; import { add2 } from "@thi.ng/vectors3/add"; import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; import { cartesian2 } from "@thi.ng/vectors3/cartesian"; @@ -29,6 +35,7 @@ import { pointInside, Rect2, SamplingOpts, + tangentAt, translate, Type, vertices @@ -102,6 +109,10 @@ implementations( (circle: Circle2, p: ReadonlyVec) => distSq2(circle.pos, p) <= circle.r * circle.r, + tangentAt, + (_: Circle2, t: number) => + cossin(TAU * t + HALF_PI), + translate, (circle: Circle2, delta: ReadonlyVec) => new Circle2( diff --git a/packages/geom2/src/line.ts b/packages/geom2/src/line.ts index 588db06647..f8a82aecfb 100644 --- a/packages/geom2/src/line.ts +++ b/packages/geom2/src/line.ts @@ -17,6 +17,7 @@ import { Line2, offset, perimeter, + pointAt, Polygon2, Polyline2, Rect2, @@ -88,6 +89,10 @@ implementations( (line: Line2) => dist(...line.points), + pointAt, + (line: Line2, t: number) => + mixN([], line.a, line.b, t), + tangentAt, (line: Line2, _, n = 1) => direction(line.a, line.b, n), From 7cf5f7c49acb47456572de489a584122f3718325 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 31 Dec 2018 17:31:59 +0000 Subject: [PATCH 150/333] refactor(geom): update subdivKernel* fns --- packages/geom2/src/internal/subdiv-curve.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/geom2/src/internal/subdiv-curve.ts b/packages/geom2/src/internal/subdiv-curve.ts index 808dc1a64c..9515455c68 100644 --- a/packages/geom2/src/internal/subdiv-curve.ts +++ b/packages/geom2/src/internal/subdiv-curve.ts @@ -5,29 +5,29 @@ import { transduce } from "@thi.ng/transducers/transduce"; import { indexed } from "@thi.ng/transducers/xform/indexed"; import { mapcat } from "@thi.ng/transducers/xform/mapcat"; import { partition } from "@thi.ng/transducers/xform/partition"; -import { addWeighted2, addWeighted3, addWeighted5 } from "@thi.ng/vectors3/add-weighted"; +import { addW2, addW3, addW5 } from "@thi.ng/vectors3/addw"; import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; import { SubdivKernel } from "../api"; export const subdivKernel2 = ([ua, ub]: number[], [va, vb]: number[]) => ([a, b]: ReadonlyVec[]) => [ - addWeighted2([], a, b, ua, ub), - addWeighted2([], a, b, va, vb), + addW2([], a, b, ua, ub), + addW2([], a, b, va, vb), ]; export const subdivKernel3 = ([ua, ub, uc]: number[], [va, vb, vc]: number[]) => ([a, b, c]: ReadonlyVec[]) => [ - addWeighted3([], a, b, c, ua, ub, uc), - addWeighted3([], a, b, c, va, vb, vc), + addW3([], a, b, c, ua, ub, uc), + addW3([], a, b, c, va, vb, vc), ]; export const subdivKernel5 = ([ua, ub, uc, ud, ue]: number[], [va, vb, vc, vd, ve]: number[]) => ([a, b, c, d, e]: ReadonlyVec[]) => [ - addWeighted5([], a, b, c, d, e, ua, ub, uc, ud, ue), - addWeighted5([], a, b, c, d, e, va, vb, vc, vd, ve), + addW5([], a, b, c, d, e, ua, ub, uc, ud, ue), + addW5([], a, b, c, d, e, va, vb, vc, vd, ve), ]; /** From c0008a7a2faf09af2cf83b2b3163b454ee73684a Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 31 Dec 2018 17:32:14 +0000 Subject: [PATCH 151/333] minor(geom): update formatting --- .../geom2/src/internal/greiner-hormann.ts | 2 - packages/geom2/src/internal/liang-barsky.ts | 86 ++++++++++--------- .../geom2/src/internal/line-intersection.ts | 3 +- packages/geom2/src/internal/offset.ts | 69 ++++++++------- 4 files changed, 84 insertions(+), 76 deletions(-) diff --git a/packages/geom2/src/internal/greiner-hormann.ts b/packages/geom2/src/internal/greiner-hormann.ts index f1ee65af3c..b35e1d9600 100644 --- a/packages/geom2/src/internal/greiner-hormann.ts +++ b/packages/geom2/src/internal/greiner-hormann.ts @@ -201,8 +201,6 @@ export class ClipPolygon implements return inside; } - - protected insertIntersections(clip: ClipPolygon) { let s = this.first; let c = clip.first; diff --git a/packages/geom2/src/internal/liang-barsky.ts b/packages/geom2/src/internal/liang-barsky.ts index e08962d10a..29bb3bee91 100644 --- a/packages/geom2/src/internal/liang-barsky.ts +++ b/packages/geom2/src/internal/liang-barsky.ts @@ -4,49 +4,55 @@ import { Vec } from "@thi.ng/vectors3/api"; // https://en.wikipedia.org/wiki/Liang%E2%80%93Barsky_algorithm // https://github.com/thi-ng/c-thing/blob/master/src/geom/clip/liangbarsky.c -export const liangBarsky2 = - (la: Vec, lb: Vec, tl: Vec, br: Vec, ca: Vec = [], cb: Vec = []): [Vec, Vec, number, number] => { - const lax = la[0]; - const lay = la[1]; - const dx = lb[0] - lax; - const dy = lb[1] - lay; - let a = 0; - let b = 1; +export const liangBarsky2 = ( + la: Vec, + lb: Vec, + tl: Vec, + br: Vec, + ca: Vec = [], + cb: Vec = [] +): [Vec, Vec, number, number] => { + const lax = la[0]; + const lay = la[1]; + const dx = lb[0] - lax; + const dy = lb[1] - lay; + let a = 0; + let b = 1; - const clip = (p: number, q: number) => { - if (q < 0 && Math.abs(p) < EPS) { - return 0; + const clip = (p: number, q: number) => { + if (q < 0 && Math.abs(p) < EPS) { + return 0; + } + const r = q / p; + if (p < 0) { + if (r > b) { + return false; + } else if (r > a) { + a = r; } - const r = q / p; - if (p < 0) { - if (r > b) { - return false; - } else if (r > a) { - a = r; - } - } else if (p > 0) { - if (r < a) { - return false; - } else if (r < b) { - b = r; - } + } else if (p > 0) { + if (r < a) { + return false; + } else if (r < b) { + b = r; } - return true; - }; - - if (!( - clip(-dx, -(tl[0] - lax)) && - clip(dx, br[0] - lax) && - clip(-dy, -(tl[1] - lay)) && - clip(dy, br[1] - lay) - )) { - return; } + return true; + }; - ca[0] = a * dx + lax; - ca[1] = a * dy + lay; - cb[0] = b * dx + lax; - cb[1] = b * dy + lay; + if (!( + clip(-dx, -(tl[0] - lax)) && + clip(dx, br[0] - lax) && + clip(-dy, -(tl[1] - lay)) && + clip(dy, br[1] - lay) + )) { + return; + } - return [ca, cb, a, b]; - }; + ca[0] = a * dx + lax; + ca[1] = a * dy + lay; + cb[0] = b * dx + lax; + cb[1] = b * dy + lay; + + return [ca, cb, a, b]; +}; diff --git a/packages/geom2/src/internal/line-intersection.ts b/packages/geom2/src/internal/line-intersection.ts index 0817c142ff..7e53562390 100644 --- a/packages/geom2/src/internal/line-intersection.ts +++ b/packages/geom2/src/internal/line-intersection.ts @@ -10,7 +10,8 @@ export const intersectLines2 = ( b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, - eps = EPS): LineIntersection => { + eps = EPS +): LineIntersection => { const bax = b[0] - a[0]; const bay = b[1] - a[1]; diff --git a/packages/geom2/src/internal/offset.ts b/packages/geom2/src/internal/offset.ts index 1d6e45fbd0..f2344a0760 100644 --- a/packages/geom2/src/internal/offset.ts +++ b/packages/geom2/src/internal/offset.ts @@ -8,20 +8,21 @@ import { edges as _edges } from "./edges"; import { booleanOp } from "./greiner-hormann"; import { polygonArea } from "./polygon"; -export const offset = (points: Vec[], dist: number, res = 8, closed = true) => { - if (!closed && dist < 0) return; - polygonArea(points) > 0 && (points = [...points].reverse()); - const contours = offsetEdges(_edges(points, closed), Math.abs(dist), res); - if (contours.length > 0) { - const a1 = Math.abs(polygonArea(contours[0])); - const a2 = Math.abs(polygonArea(contours[1])); - return contours[ - dist > 0 ? - a1 > a2 ? 0 : 1 : - a1 > a2 ? 1 : 0 - ]; - } -}; +export const offset = + (points: Vec[], dist: number, res = 8, closed = true) => { + if (!closed && dist < 0) return; + polygonArea(points) > 0 && (points = [...points].reverse()); + const contours = offsetEdges(_edges(points, closed), Math.abs(dist), res); + if (contours.length > 0) { + const a1 = Math.abs(polygonArea(contours[0])); + const a2 = Math.abs(polygonArea(contours[1])); + return contours[ + dist > 0 ? + a1 > a2 ? 0 : 1 : + a1 > a2 ? 1 : 0 + ]; + } + }; /** * @@ -29,23 +30,25 @@ export const offset = (points: Vec[], dist: number, res = 8, closed = true) => { * @param dist * @param res */ -export const offsetEdges = (edges: Iterable, dist: number, res: number) => { - let result: Vec[][]; - for (let e of edges) { - const seg = offsetLine(e, dist, res); - result = result ? - booleanOp(result, seg, ClipMode.UNION, false) : - [seg]; - } - return result; -}; +export const offsetEdges = + (edges: Iterable, dist: number, res: number) => { + let result: Vec[][]; + for (let e of edges) { + const seg = offsetLine(e, dist, res); + result = result ? + booleanOp(result, seg, ClipMode.UNION, false) : + [seg]; + } + return result; + }; -export const offsetLine = ([ea, eb]: VecPair, dist: number, res: number) => { - const verts: Vec[] = []; - const r = [dist, dist]; - const n = normalL2(ea, eb, dist); - const e1 = [add2([], ea, n), add2([], eb, n)]; - const e2 = [sub2([], eb, n), sub2([], ea, n)]; - arcVertices(ea, e2[1], e1[0], r, verts, true, res); - return arcVertices(eb, e1[1], e2[0], r, verts, true, res); -}; +export const offsetLine = + ([ea, eb]: VecPair, dist: number, res: number) => { + const verts: Vec[] = []; + const r = [dist, dist]; + const n = normalL2(ea, eb, dist); + const e1 = [add2([], ea, n), add2([], eb, n)]; + const e2 = [sub2([], eb, n), sub2([], ea, n)]; + arcVertices(ea, e2[1], e1[0], r, verts, true, res); + return arcVertices(eb, e1[1], e2[0], r, verts, true, res); + }; From b10c8d67e9ad66850814252af3918212dc1af0fc Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 1 Jan 2019 18:06:39 +0000 Subject: [PATCH 152/333] refactor(geom): prep/update intersectShape() w/ new dispatch fn --- packages/geom2/src/api.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/geom2/src/api.ts b/packages/geom2/src/api.ts index 6bf8b1eed5..e2e828da05 100644 --- a/packages/geom2/src/api.ts +++ b/packages/geom2/src/api.ts @@ -210,6 +210,7 @@ export type Tessellator = (points: Vec[]) => Vec[][]; export type VecPair = [Vec, Vec]; const dispatch = (x: IShape) => x.type; +const dispatch2 = (a: IShape, b: IShape) => a.type + "-" + b.type; export const arcLength: MultiFn1 = defmulti(dispatch); @@ -263,7 +264,7 @@ height.add(DEFAULT, (x) => bounds(x).size[1]); export const intersection = defmulti(dispatch); // TODO define isec result -export const intersectShape = defmulti(dispatch); +export const intersectShape = defmulti(dispatch2); export const intersectLine = defmulti(dispatch); From d47798edee3b628d7e27ed0098766aa11f15abaa Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 1 Jan 2019 18:19:44 +0000 Subject: [PATCH 153/333] refactor(examples): update gesture analysis demo --- examples/gesture-analysis/src/index.ts | 144 ++++++++++++------------- 1 file changed, 69 insertions(+), 75 deletions(-) diff --git a/examples/gesture-analysis/src/index.ts b/examples/gesture-analysis/src/index.ts index 124f311b04..7bd82574db 100644 --- a/examples/gesture-analysis/src/index.ts +++ b/examples/gesture-analysis/src/index.ts @@ -1,3 +1,5 @@ +import { resample, vertices } from "@thi.ng/geom2/api"; +import { polyline as _polyline } from "@thi.ng/geom2/polyline"; import { circle } from "@thi.ng/hiccup-svg/circle"; import { group } from "@thi.ng/hiccup-svg/group"; import { polyline } from "@thi.ng/hiccup-svg/polyline"; @@ -16,8 +18,10 @@ import { filter } from "@thi.ng/transducers/xform/filter"; import { map } from "@thi.ng/transducers/xform/map"; import { multiplexObj } from "@thi.ng/transducers/xform/multiplex-obj"; import { partition } from "@thi.ng/transducers/xform/partition"; -import { Vec2 } from "@thi.ng/vectors/vec2"; - +import { angleBetween } from "@thi.ng/vectors3/angle-between"; +import { Vec } from "@thi.ng/vectors3/api"; +import { mixN2 } from "@thi.ng/vectors3/mixn"; +import { sub2 } from "@thi.ng/vectors3/sub"; import { CTA } from "./config"; /** @@ -27,23 +31,24 @@ import { CTA } from "./config"; * @param raw * @param processed */ -const app = ({ raw, processed }) => - ["div", - svg( - { - width: window.innerWidth, - height: window.innerHeight, - stroke: "none", - fill: "none", - }, - path(raw || [], processed.path, processed.corners || []) - ), - ["div.fixed.top-0.left-0.ma3", - ["div", `raw: ${(raw && raw.length) || 0}`], - ["div", `resampled: ${(processed && processed.path.length) || 0}`], - ["div", `corners: ${(processed && processed.corners.length) || 0}`], - ] - ]; +const app = + ({ raw, processed }) => + ["div", + svg( + { + width: window.innerWidth, + height: window.innerHeight, + stroke: "none", + fill: "none", + }, + path(raw || [], processed.path, processed.corners || []) + ), + ["div.fixed.top-0.left-0.ma3", + ["div", `raw: ${(raw && raw.length) || 0}`], + ["div", `resampled: ${(processed && processed.path.length) || 0}`], + ["div", `corners: ${(processed && processed.corners.length) || 0}`], + ] + ]; /** * Gesture visualization component. Creates an SVG group of shape @@ -53,16 +58,17 @@ const app = ({ raw, processed }) => * @param sampled resampled path * @param corners array of corner points */ -const path = (raw: Vec2[], sampled: Vec2[], corners: Vec2[]) => - group({}, - polyline(raw, { stroke: "#444" }), - map((p) => circle(p, 2, { fill: "#444" }), raw), - polyline(sampled, { stroke: "#fff" }), - map((p) => circle(p, 2, { fill: "#fff" }), sampled), - map((p) => circle(p, 6, { fill: "#cf0" }), corners), - circle(sampled[0], 6, { fill: "#f0c" }), - circle(peek(sampled), 6, { fill: "#0cf" }), - ); +const path = + (raw: Vec[], sampled: Vec[], corners: Vec[]) => + group({ __diff: false }, + polyline(raw, { stroke: "#444" }), + map((p) => circle(p, 2, { fill: "#444" }), raw), + polyline(sampled, { stroke: "#fff" }), + map((p) => circle(p, 2, { fill: "#fff" }), sampled), + map((p) => circle(p, 6, { fill: "#cf0" }), corners), + circle(sampled[0], 6, { fill: "#f0c" }), + circle(peek(sampled), 6, { fill: "#0cf" }), + ); /** * Re-samples given polyline at given uniform distance. Returns array of @@ -71,21 +77,9 @@ const path = (raw: Vec2[], sampled: Vec2[], corners: Vec2[]) => * @param step sample distance * @param pts */ -const sampleUniform = (step: number, pts: Vec2[]) => { - if (!pts.length) return []; - let prev = pts[0]; - const res: Vec2[] = [prev]; - for (let i = 1, n = pts.length; i < n; prev = peek(res), i++) { - const p = pts[i]; - let d = p.dist(prev); - while (d >= step) { - res.push(prev = prev.copy().mixN(p, step / d)); - d -= step; - } - } - res.push(peek(pts)); - return res; -}; +const sampleUniform = + (step: number, pts: Vec[]) => + vertices(resample(_polyline(pts), { dist: step })); /** * Applies low-pass filter to given polyline. I.e. Each point in the @@ -94,13 +88,14 @@ const sampleUniform = (step: number, pts: Vec2[]) => { * * @param path */ -const smoothPath = (smooth: number, path: Vec2[]) => { - const res: Vec2[] = [path[0]]; - for (let i = 1, n = path.length; i < n; i++) { - res.push(path[i].copy().mixN(res[i - 1], smooth)); - } - return res; -}; +const smoothPath = + (smooth: number, path: Vec[]) => { + const res: Vec[] = [path[0]]; + for (let i = 1, n = path.length; i < n; i++) { + res.push(mixN2([], path[i], res[i - 1], smooth)); + } + return res; + }; /** * Corner detector HOF. Returns new function which takes 3 successive @@ -108,34 +103,33 @@ const smoothPath = (smooth: number, path: Vec2[]) => { * * @param thresh normalized angle threshold */ -const isCorner = (thresh: number) => { - thresh = Math.PI * (1 - thresh); - return ([a, b, c]: Vec2[]) => - b.copy().sub(a).angleBetween(b.copy().sub(c), true) < thresh; -}; +const isCorner = + (thresh: number) => { + thresh = Math.PI * (1 - thresh); + return ([a, b, c]: Vec[]) => + angleBetween(sub2([], b, a), sub2([], b, c), true) < thresh; + }; /** * Gesture event processor. Collects gesture event positions into an * array of Vec2. */ -const collectPath = () => { - let pts: Vec2[] = []; - return (g: GestureEvent) => { - const pos = new Vec2(g[1].pos); - switch (g[0]) { - case GestureType.START: - pts = [pos]; - break; - case GestureType.DRAG: - pts.push(pos); - break; - // uncomment to destroy path on mouseup / touchend - // case GestureType.END: - // pts = []; +const collectPath = + () => { + let pts: Vec[] = []; + return (g: GestureEvent) => { + const pos = g[1].pos; + switch (g[0]) { + case GestureType.START: + pts = [pos]; + break; + case GestureType.DRAG: + pts.push(pos); + break; + } + return pts; } - return pts; - } -}; + }; // gesture input stream(s) const gesture = merge({ @@ -166,8 +160,8 @@ sync({ raw: gesture, processed: gesture.transform( comp( - map((pts: Vec2[]) => smoothPath(3 / 4, pts)), - map((pts: Vec2[]) => sampleUniform(20, pts)), + map((pts: Vec[]) => smoothPath(3 / 4, pts)), + map((pts: Vec[]) => sampleUniform(20, pts)), multiplexObj({ path: map(identity), corners: map( From 2fb2aa3296778299a642e9e4eac07d592333e9db Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 1 Jan 2019 21:51:14 +0000 Subject: [PATCH 154/333] build: update deps --- packages/color/package.json | 2 +- packages/geom2/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/color/package.json b/packages/color/package.json index 8ddb372089..8a50e5f5f3 100644 --- a/packages/color/package.json +++ b/packages/color/package.json @@ -30,7 +30,7 @@ "dependencies": { "@thi.ng/api": "^4.2.4", "@thi.ng/compose": "^0.3.0", - "@thi.ng/defmulti": "^0.5.1", + "@thi.ng/defmulti": "^0.6.0", "@thi.ng/errors": "^0.1.12", "@thi.ng/strings": "^0.7.1", "@thi.ng/transducers": "^2.3.1", diff --git a/packages/geom2/package.json b/packages/geom2/package.json index 9116446eba..2a85ec1885 100644 --- a/packages/geom2/package.json +++ b/packages/geom2/package.json @@ -30,7 +30,7 @@ "dependencies": { "@thi.ng/api": "^4.2.4", "@thi.ng/checks": "^1.5.14", - "@thi.ng/defmulti": "^0.5.1", + "@thi.ng/defmulti": "^0.6.0", "@thi.ng/hiccup": "^2.7.2", "@thi.ng/hiccup-svg": "^2.0.10", "@thi.ng/malloc": "^0.2.1", From 2e6d1965f40e9e352117f224dbd8dd33ef0b0d28 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 2 Jan 2019 01:29:12 +0000 Subject: [PATCH 155/333] fix(vectors): disable default prefix for random*() fns --- packages/vectors3/src/random.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/vectors3/src/random.ts b/packages/vectors3/src/random.ts index 306f8f9b36..45a6a0d566 100644 --- a/packages/vectors3/src/random.ts +++ b/packages/vectors3/src/random.ts @@ -20,7 +20,8 @@ export const [random, random2, random3, random4] = "a,n=-1,m=1,rnd=op", "a", "a", - 0 + 0, + "" ); /** From 161199f40e29d846064b69fe8f04b790021d186e Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 2 Jan 2019 03:06:35 +0000 Subject: [PATCH 156/333] feat(geom): add/rename type ids, add sphere, isec fns --- packages/geom2/src/api.ts | 70 +++++++++++++++++++++++++++-------- packages/geom2/src/circle.ts | 2 +- packages/geom2/src/ellipse.ts | 2 +- packages/geom2/src/index.ts | 1 + packages/geom2/src/rect.ts | 28 +++++++++++++- packages/geom2/src/sphere.ts | 59 +++++++++++++++++++++++++++++ 6 files changed, 143 insertions(+), 19 deletions(-) create mode 100644 packages/geom2/src/sphere.ts diff --git a/packages/geom2/src/api.ts b/packages/geom2/src/api.ts index e2e828da05..bad2a46a54 100644 --- a/packages/geom2/src/api.ts +++ b/packages/geom2/src/api.ts @@ -29,19 +29,25 @@ import { subdivKernel3 } from "./internal/subdiv-curve"; import { warpPoints } from "./internal/warp"; export const enum Type { + AABB = "aabb", ARC2 = "arc", - CIRCLE2 = "circle", + CIRCLE = "circle", CUBIC2 = "cubic", - ELLIPSE2 = "ellipse", + ELLIPSE = "ellipse", GROUP = "g", LINE2 = "line", + LINE3 = "line3", PATH2 = "path", POINTS2 = "points", + POINTS3 = "points3", POLYGON2 = "polygon", + POLYGON3 = "poly3", POLYLINE2 = "polyline", - QUAD2 = "quad", + QUAD2 = "quad2", + QUAD3 = "quad3", QUADRATIC2 = "quadratic", - RECT2 = "rect", + RECT = "rect", + SPHERE = "sphere", TRIANGLE2 = "triangle", RAY = "ray" } @@ -469,7 +475,7 @@ export class Circle2 implements } get type() { - return Type.CIRCLE2; + return Type.CIRCLE; } copy() { @@ -531,7 +537,7 @@ export class Ellipse2 implements } get type() { - return Type.ELLIPSE2; + return Type.ELLIPSE; } copy() { @@ -596,6 +602,14 @@ export class Line2 extends PointContainer implements super(Type.LINE2, points, attribs); } + get a() { + return this.points[0]; + } + + get b() { + return this.points[1]; + } + copy() { return new Line2(this._copy(), { ...this.attribs }); } @@ -607,17 +621,9 @@ export class Line2 extends PointContainer implements ["V", b[1]] : a[1] === b[1] ? ["H", b[0]] : - ["L", this.points[1]] + ["L", b] ]; } - - get a() { - return this.points[0]; - } - - get b() { - return this.points[1]; - } } export class Path2 implements IShape { @@ -799,7 +805,7 @@ export class Rect2 implements } get type() { - return Type.RECT2; + return Type.RECT; } copy() { @@ -817,6 +823,38 @@ export class Rect2 implements } } +export class Sphere implements + IShape { + + pos: Vec; + r: number; + attribs: Attribs; + + constructor(pos: Vec, r: number, attribs?: Attribs) { + this.pos = pos; + this.r = r; + this.attribs = attribs; + } + + get type() { + return Type.SPHERE; + } + + copy() { + return new Sphere(copy(this.pos), this.r, { ...this.attribs }); + } + + equiv(o: any) { + return o instanceof Sphere && + equiv(this.pos, o.pos) && + this.r === o.r; + } + + toHiccup() { + return ""; + } +} + export class Triangle2 extends PointContainer { constructor(points: Vec[], attribs?: Attribs) { diff --git a/packages/geom2/src/circle.ts b/packages/geom2/src/circle.ts index 63e30ccff7..a58e1bd4bf 100644 --- a/packages/geom2/src/circle.ts +++ b/packages/geom2/src/circle.ts @@ -60,7 +60,7 @@ export const circleFrom3Points = }; implementations( - Type.CIRCLE2, + Type.CIRCLE, null, diff --git a/packages/geom2/src/ellipse.ts b/packages/geom2/src/ellipse.ts index 8241f8e9a6..67b5117f22 100644 --- a/packages/geom2/src/ellipse.ts +++ b/packages/geom2/src/ellipse.ts @@ -34,7 +34,7 @@ export function ellipse(pos: Vec, r = [1, 1], attribs?: Attribs): Ellipse2 { } implementations( - Type.ELLIPSE2, + Type.ELLIPSE, null, diff --git a/packages/geom2/src/index.ts b/packages/geom2/src/index.ts index 25f474a0f6..700c65e00f 100644 --- a/packages/geom2/src/index.ts +++ b/packages/geom2/src/index.ts @@ -12,6 +12,7 @@ export * from "./polyline"; export * from "./quad"; export * from "./ray"; export * from "./rect"; +export * from "./sphere"; export * from "./triangle"; export * from "./svg"; diff --git a/packages/geom2/src/rect.ts b/packages/geom2/src/rect.ts index f44b9b0b14..71e99817fe 100644 --- a/packages/geom2/src/rect.ts +++ b/packages/geom2/src/rect.ts @@ -13,9 +13,11 @@ import { Attribs, bounds, centroid, + Circle2, clipConvex, ClipMode, edges, + intersectShape, IShape, mapPoint, perimeter, @@ -51,7 +53,7 @@ export const rectFromMinMax = (min: Vec, max: Vec, attribs?: Attribs) => Rect2.fromMinMax(min, max, attribs); implementations( - Type.RECT2, + Type.RECT, { [Type.POLYGON2]: [ @@ -144,3 +146,27 @@ implementations( verts; }, ); + +intersectShape.addAll({ + + [`${Type.RECT}-${Type.RECT}`]: + ({ pos: { 0: ax, 1: ay }, size: { 0: aw, 1: ah } }: Rect2, + { pos: { 0: bx, 1: by }, size: { 0: bw, 1: bh } }: Rect2) => + !((ax > bx + bw) || + (bx > ax + aw) || + (ay > by + bh) || + (by > ay + ah)), + + [`${Type.RECT}-${Type.CIRCLE}`]: + ({ pos: rp, size }: Rect2, { pos: cp, r }: Circle2) => + rcAxis(cp[0], rp[0], size[0]) + + rcAxis(cp[1], rp[1], size[1]) <= r * r, + +}); + +const rcAxis = (a: number, b: number, c: number) => + a < b ? + Math.pow(a - b, 2) : + a > b + c ? + Math.pow(a - b - c, 2) : + 0; diff --git a/packages/geom2/src/sphere.ts b/packages/geom2/src/sphere.ts new file mode 100644 index 0000000000..527a42c2f6 --- /dev/null +++ b/packages/geom2/src/sphere.ts @@ -0,0 +1,59 @@ +import { Vec } from "@thi.ng/vectors3/api"; +import { dot3 } from "@thi.ng/vectors3/dot"; +import { maddN3 } from "@thi.ng/vectors3/maddn"; +import { magSq3 } from "@thi.ng/vectors3/magsq"; +import { sub3 } from "@thi.ng/vectors3/sub"; +import { + intersectShape, + Ray, + Sphere, + Type, +} from "./api"; +import { distSq3 } from "@thi.ng/vectors3/distsq"; + +export const sphere = + (pos: Vec, r = 1) => new Sphere(pos, r); + +intersectShape.addAll({ + + [`${Type.SPHERE}-${Type.SPHERE}`]: + (a: Sphere, b: Sphere) => + distSq3(a.pos, b.pos) <= Math.pow(a.r + b.r, 2), + + [`${Type.SPHERE}-${Type.RAY}`]: + ({ pos: spos, r: r }: Sphere, { pos: rpos, dir }: Ray) => { + const delta = sub3([], spos, rpos); + const w = dot3(delta, dir); + let d = r * r + w * w - magSq3(delta); + if (d >= 0) { + d = Math.sqrt(d); + const a = w + d; + const b = w - d; + d = a >= 0 ? + b >= 0 ? + a > b ? + b : + a : + a : + b >= 0 ? + b : + undefined; + // reuse delta as out + return d !== undefined ? + maddN3(delta, rpos, dir, d) : + d; + } + }, +}); + +// export const isecRaySphere = (ray: Ray, sphere: Sphere) => { +// const w = sub3([], ray.pos, sphere.pos); +// const rd = ray.dir; +// const b = 2 * dot3(w, rd); +// const a = magSq3(rd); +// const c = magSq3(w) - sphere.r * sphere.r; +// let d = b * b - 4 * a * c; +// return d >= 0 && ((d = (-b - Math.sqrt(d)) / (2 * a)) >= 0) ? +// maddN3([], ray.pos, rd, d) : +// undefined; +// }; From 731ede0243e16e925a82f6ee241d92485ab0b5b1 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 2 Jan 2019 14:51:05 +0000 Subject: [PATCH 157/333] build: update deps (defmulti / transducers) --- packages/color/package.json | 4 ++-- packages/geom2/package.json | 2 +- packages/vectors2/package.json | 2 +- packages/vectors3/package.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/color/package.json b/packages/color/package.json index 8a50e5f5f3..720575028c 100644 --- a/packages/color/package.json +++ b/packages/color/package.json @@ -30,10 +30,10 @@ "dependencies": { "@thi.ng/api": "^4.2.4", "@thi.ng/compose": "^0.3.0", - "@thi.ng/defmulti": "^0.6.0", + "@thi.ng/defmulti": "^0.7.0", "@thi.ng/errors": "^0.1.12", "@thi.ng/strings": "^0.7.1", - "@thi.ng/transducers": "^2.3.1", + "@thi.ng/transducers": "^2.3.2", "@thi.ng/vectors3": "^0.0.1" }, "keywords": [ diff --git a/packages/geom2/package.json b/packages/geom2/package.json index 2a85ec1885..437793d235 100644 --- a/packages/geom2/package.json +++ b/packages/geom2/package.json @@ -30,7 +30,7 @@ "dependencies": { "@thi.ng/api": "^4.2.4", "@thi.ng/checks": "^1.5.14", - "@thi.ng/defmulti": "^0.6.0", + "@thi.ng/defmulti": "^0.7.0", "@thi.ng/hiccup": "^2.7.2", "@thi.ng/hiccup-svg": "^2.0.10", "@thi.ng/malloc": "^0.2.1", diff --git a/packages/vectors2/package.json b/packages/vectors2/package.json index 664abf219a..8aa0adc52f 100644 --- a/packages/vectors2/package.json +++ b/packages/vectors2/package.json @@ -36,7 +36,7 @@ "@thi.ng/math": "^0.2.2", "@thi.ng/random": "^0.1.1", "@thi.ng/strings": "^0.7.1", - "@thi.ng/transducers": "^2.3.1" + "@thi.ng/transducers": "^2.3.2" }, "keywords": [ "ES6", diff --git a/packages/vectors3/package.json b/packages/vectors3/package.json index 77b4669a3c..d286972a19 100644 --- a/packages/vectors3/package.json +++ b/packages/vectors3/package.json @@ -34,7 +34,7 @@ "@thi.ng/errors": "^0.1.12", "@thi.ng/math": "^0.2.2", "@thi.ng/random": "^0.1.1", - "@thi.ng/transducers": "^2.3.1" + "@thi.ng/transducers": "^2.3.2" }, "keywords": [ "2D", From e03390b1ae3fcebb8ff42cf10abf3bbe44400f24 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 3 Jan 2019 00:13:45 +0000 Subject: [PATCH 158/333] feat(fsm): import fsm package --- packages/fsm/.npmignore | 11 ++ packages/fsm/LICENSE | 201 ++++++++++++++++++++++++++++++++ packages/fsm/README.md | 59 ++++++++++ packages/fsm/package.json | 42 +++++++ packages/fsm/src/alts.ts | 35 ++++++ packages/fsm/src/api.ts | 28 +++++ packages/fsm/src/fsm.ts | 29 +++++ packages/fsm/src/index.ts | 7 ++ packages/fsm/src/range.ts | 46 ++++++++ packages/fsm/src/seq.ts | 35 ++++++ packages/fsm/src/str.ts | 26 +++++ packages/fsm/src/until.ts | 24 ++++ packages/fsm/test/index.ts | 6 + packages/fsm/test/tsconfig.json | 10 ++ packages/fsm/tsconfig.json | 9 ++ 15 files changed, 568 insertions(+) create mode 100644 packages/fsm/.npmignore create mode 100644 packages/fsm/LICENSE create mode 100644 packages/fsm/README.md create mode 100644 packages/fsm/package.json create mode 100644 packages/fsm/src/alts.ts create mode 100644 packages/fsm/src/api.ts create mode 100644 packages/fsm/src/fsm.ts create mode 100644 packages/fsm/src/index.ts create mode 100644 packages/fsm/src/range.ts create mode 100644 packages/fsm/src/seq.ts create mode 100644 packages/fsm/src/str.ts create mode 100644 packages/fsm/src/until.ts create mode 100644 packages/fsm/test/index.ts create mode 100644 packages/fsm/test/tsconfig.json create mode 100644 packages/fsm/tsconfig.json diff --git a/packages/fsm/.npmignore b/packages/fsm/.npmignore new file mode 100644 index 0000000000..ec83d74c9d --- /dev/null +++ b/packages/fsm/.npmignore @@ -0,0 +1,11 @@ +build +coverage +dev +doc +export +src* +test +.nyc_output +tsconfig.json +*.tgz +*.html diff --git a/packages/fsm/LICENSE b/packages/fsm/LICENSE new file mode 100644 index 0000000000..8dada3edaf --- /dev/null +++ b/packages/fsm/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/fsm/README.md b/packages/fsm/README.md new file mode 100644 index 0000000000..ba67ade7f1 --- /dev/null +++ b/packages/fsm/README.md @@ -0,0 +1,59 @@ +# @thi.ng/fsm + +[![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/fsm.svg)](https://www.npmjs.com/package/@thi.ng/fsm) +![npm downloads](https://img.shields.io/npm/dm/@thi.ng/fsm.svg) +[![Twitter Follow](https://img.shields.io/twitter/follow/thing_umbrella.svg?style=flat-square&label=twitter)](https://twitter.com/thing_umbrella) + +This project is part of the +[@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo. + + + +- [About](#about) +- [Status](#status) +- [Installation](#installation) +- [Dependencies](#dependencies) +- [Usage examples](#usage-examples) +- [Authors](#authors) +- [License](#license) + + + +## About + +Primitives for building transducer based Finite-State machines and +parsers (not necessarily text based). + +See the [minimal markdown parser +example](https://github.com/thi-ng/umbrella/tree/feature/fsm/examples/markdown) +for a concrete use case. + +## Status + +ALPHA. + +## Installation + +```bash +yarn add @thi.ng/fsm +``` + +## Dependencies + +- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/master/packages/api) +- [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/master/packages/errors) +- [@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/master/packages/transducers) + +## Usage examples + +```ts +import * as fsm from "@thi.ng/fsm"; +``` + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/packages/fsm/package.json b/packages/fsm/package.json new file mode 100644 index 0000000000..b38fc5ad46 --- /dev/null +++ b/packages/fsm/package.json @@ -0,0 +1,42 @@ +{ + "name": "@thi.ng/fsm", + "version": "0.0.1", + "description": "TODO", + "main": "./index.js", + "typings": "./index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/thi-ng/umbrella.git" + }, + "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/fsm", + "author": "Karsten Schmidt ", + "license": "Apache-2.0", + "scripts": { + "build": "yarn run clean && tsc --declaration", + "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "cover": "yarn test && nyc report --reporter=lcov", + "doc": "node_modules/.bin/typedoc --mode modules --out doc src", + "pub": "yarn run build && yarn publish --access public", + "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + }, + "devDependencies": { + "@types/mocha": "^5.2.5", + "@types/node": "^10.12.15", + "mocha": "^5.2.0", + "nyc": "^13.1.0", + "typedoc": "^0.13.0", + "typescript": "^3.2.2" + }, + "dependencies": { + "@thi.ng/api": "^4.2.4", + "@thi.ng/errors": "^0.1.12", + "@thi.ng/transducers": "^2.3.2" + }, + "keywords": [ + "ES6", + "typescript" + ], + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/packages/fsm/src/alts.ts b/packages/fsm/src/alts.ts new file mode 100644 index 0000000000..40bbc8f56b --- /dev/null +++ b/packages/fsm/src/alts.ts @@ -0,0 +1,35 @@ +import { Match, RES_FAIL, RES_PARTIAL, Matcher, ResultBody } from "./api"; + +export const alts = ( + opts: Matcher[], + fallback?: (ctx: C, buf: T[]) => ResultBody, + callback?: (ctx: C, next: ResultBody, buf: T[]) => ResultBody +): Matcher => + () => { + const alts = opts.map((o) => o()); + const buf: T[] = []; + return (ctx, x) => { + for (let i = alts.length; --i >= 0;) { + const next = alts[i](ctx, x); + if (next.type === Match.FULL) { + return callback ? + { + type: Match.FULL, + body: callback(ctx, next.body, buf) + } : + next; + } else if (next.type === Match.FAIL) { + alts.splice(i, 1); + } + } + fallback && buf.push(x); + return alts.length ? + RES_PARTIAL : + fallback ? + { + type: Match.FULL, + body: fallback(ctx, buf) + } : + RES_FAIL; + }; + }; diff --git a/packages/fsm/src/api.ts b/packages/fsm/src/api.ts new file mode 100644 index 0000000000..084ee24e4b --- /dev/null +++ b/packages/fsm/src/api.ts @@ -0,0 +1,28 @@ +export const enum Match { + PARTIAL = 0, + FULL = 1, + FAIL = -1 +} + +export interface MatchResult { + type: Match; + body?: ResultBody; +} + +export type Matcher = + () => (ctx: C, x: T) => MatchResult; + +export type ResultBody = + [number | string, T[]?]; + +export type AltCallback = + (ctx: C, next: ResultBody, x: T[]) => ResultBody; + +export type RangeCallback = + (ctx: C, x: T) => ResultBody; + +export type SeqCallback = + (ctx: C, buf: T[]) => ResultBody; + +export const RES_PARTIAL = Object.freeze({ type: Match.PARTIAL }); +export const RES_FAIL = Object.freeze({ type: Match.FAIL }); diff --git a/packages/fsm/src/fsm.ts b/packages/fsm/src/fsm.ts new file mode 100644 index 0000000000..aa50a0956d --- /dev/null +++ b/packages/fsm/src/fsm.ts @@ -0,0 +1,29 @@ +import { IObjectOf } from "@thi.ng/api"; +import { illegalState } from "@thi.ng/errors/illegal-state"; +import { reduced } from "@thi.ng/transducers/reduced"; +import { mapcat } from "@thi.ng/transducers/xform/mapcat"; +import { Match, Matcher } from "./api"; + +export const fsm = ( + states: IObjectOf>, + ctx: C, + init: string | number = "start" +) => { + let currID = init; + let curr = states[init](); + return mapcat((x) => { + const { type, body } = curr(ctx, x); + if (type === Match.FULL) { + const next = states[body[0]]; + if (next) { + currID = body[0]; + curr = next(); + } else { + illegalState(`unknown tx: ${currID} -> ${body && body[0]}`); + } + return body[1]; + } else if (type === Match.FAIL) { + return reduced([]); + } + }); +}; diff --git a/packages/fsm/src/index.ts b/packages/fsm/src/index.ts new file mode 100644 index 0000000000..ce52057625 --- /dev/null +++ b/packages/fsm/src/index.ts @@ -0,0 +1,7 @@ +export * from "./api"; +export * from "./alts"; +export * from "./fsm"; +export * from "./range"; +export * from "./seq"; +export * from "./str"; +export * from "./until"; diff --git a/packages/fsm/src/range.ts b/packages/fsm/src/range.ts new file mode 100644 index 0000000000..c296dc6ff6 --- /dev/null +++ b/packages/fsm/src/range.ts @@ -0,0 +1,46 @@ +import { alts } from "./alts"; +import { + AltCallback, + Match, + Matcher, + RangeCallback, + RES_FAIL +} from "./api"; +import { str } from "./str"; + +export const range = ( + min: T, + max: T, + callback?: RangeCallback +): Matcher => + () => + (ctx, x) => + x >= min && x <= max ? + { + type: Match.FULL, + body: callback && callback(ctx, x) + } : + RES_FAIL; + +export const digit = + (callback?: RangeCallback): Matcher => + range("0", "9", callback); + +export const alpha = + (callback?: AltCallback): Matcher => + alts( + [range("a", "z"), range("A", "Z")], + null, + callback + ); + +export const alphaNum = + (callback?: AltCallback): Matcher => + alts([alpha(), digit()], null, callback); + +const WS: Matcher[] = + [str("\r"), str("\n"), str("\t"), str(" ")]; + +export const whitespace = + (callback?: AltCallback): Matcher => + alts(WS, null, callback); diff --git a/packages/fsm/src/seq.ts b/packages/fsm/src/seq.ts new file mode 100644 index 0000000000..11081edb91 --- /dev/null +++ b/packages/fsm/src/seq.ts @@ -0,0 +1,35 @@ +import { + Match, + Matcher, + RES_FAIL, + RES_PARTIAL, + SeqCallback +} from "./api"; + +export const seq = ( + opts: Matcher[], + callback?: SeqCallback +): Matcher => + () => { + let i = 0; + let o = opts[i](); + const n = opts.length - 1; + const buf: T[] = []; + return (state, x) => { + if (i > n) return RES_FAIL; + callback && buf.push(x); + const { type } = o(state, x); + if (type === Match.FULL) { + if (i === n) { + return { + type: Match.FULL, + body: callback && callback(state, buf) + }; + } + o = opts[++i](); + } + return type === Match.FAIL ? + RES_FAIL : + RES_PARTIAL; + } + }; diff --git a/packages/fsm/src/str.ts b/packages/fsm/src/str.ts new file mode 100644 index 0000000000..1f3d3f4d4a --- /dev/null +++ b/packages/fsm/src/str.ts @@ -0,0 +1,26 @@ +import { + Match, + Matcher, + RangeCallback, + RES_FAIL, + RES_PARTIAL +} from "./api"; + +export const str = ( + str: string, + callback?: RangeCallback +): Matcher => + () => { + let buf = ""; + return (state, x) => + buf.length >= str.length ? + RES_FAIL : + (buf += x) === str ? + { + type: Match.FULL, + body: callback && callback(state, buf) + } : + str.indexOf(buf) === 0 ? + RES_PARTIAL : + RES_FAIL; + }; diff --git a/packages/fsm/src/until.ts b/packages/fsm/src/until.ts new file mode 100644 index 0000000000..0025ded874 --- /dev/null +++ b/packages/fsm/src/until.ts @@ -0,0 +1,24 @@ +import { + Match, + Matcher, + RangeCallback, + RES_PARTIAL +} from "./api"; + +export const until = ( + str: string, + callback?: RangeCallback +): Matcher => + () => { + let buf = ""; + return (ctx, x) => { + buf += x; + return buf.length >= str.length && + buf.substr(buf.length - str.length) === str ? + { + type: Match.FULL, + body: callback && callback(ctx, buf.substr(0, buf.length - str.length)) + } : + RES_PARTIAL; + }; + }; diff --git a/packages/fsm/test/index.ts b/packages/fsm/test/index.ts new file mode 100644 index 0000000000..b089705eea --- /dev/null +++ b/packages/fsm/test/index.ts @@ -0,0 +1,6 @@ +// import * as assert from "assert"; +// import * as f from "../src/index"; + +describe("fsm", () => { + it("tests pending"); +}); diff --git a/packages/fsm/test/tsconfig.json b/packages/fsm/test/tsconfig.json new file mode 100644 index 0000000000..bcf29ace54 --- /dev/null +++ b/packages/fsm/test/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "../build" + }, + "include": [ + "./**/*.ts", + "../src/**/*.ts" + ] +} diff --git a/packages/fsm/tsconfig.json b/packages/fsm/tsconfig.json new file mode 100644 index 0000000000..bd6481a5a6 --- /dev/null +++ b/packages/fsm/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "." + }, + "include": [ + "./src/**/*.ts" + ] +} From 9875cda8deba157ced86693b573b6fd7055aad64 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 3 Jan 2019 00:14:24 +0000 Subject: [PATCH 159/333] feat(examples): add markdown parser example --- examples/markdown/.gitignore | 5 + examples/markdown/README.md | 80 +++++++++++++ examples/markdown/index.html | 19 ++++ examples/markdown/package.json | 29 +++++ examples/markdown/src/index.ts | 51 +++++++++ examples/markdown/src/parser.ts | 195 ++++++++++++++++++++++++++++++++ examples/markdown/tsconfig.json | 11 ++ 7 files changed, 390 insertions(+) create mode 100644 examples/markdown/.gitignore create mode 100644 examples/markdown/README.md create mode 100644 examples/markdown/index.html create mode 100644 examples/markdown/package.json create mode 100644 examples/markdown/src/index.ts create mode 100644 examples/markdown/src/parser.ts create mode 100644 examples/markdown/tsconfig.json diff --git a/examples/markdown/.gitignore b/examples/markdown/.gitignore new file mode 100644 index 0000000000..0c5abcab62 --- /dev/null +++ b/examples/markdown/.gitignore @@ -0,0 +1,5 @@ +.cache +out +node_modules +yarn.lock +*.js diff --git a/examples/markdown/README.md b/examples/markdown/README.md new file mode 100644 index 0000000000..51b4c26f70 --- /dev/null +++ b/examples/markdown/README.md @@ -0,0 +1,80 @@ +# minimal markdown parser + +This project is part of the +[@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo. + +## About + +This example is a test environment for a new & minimal +[Markdown](https://en.wikipedia.org/wiki/Markdown) parser & converter to +[hiccup](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup) +format, using basic state handling and parsing primitives provided by +the (still unreleased) +[@thi.ng/fsm](https://github.com/thi-ng/umbrella/tree/feature/fsm/packages/fsm) +package, which itself is a potential replacement / major version update +for +[@transducers-fsm](https://github.com/thi-ng/umbrella/tree/master/packages/transducers-fsm). + +### Features + +The parser itself is currently not aimed to support **all** of Markdown's quirky +syntax features, but already supports so far: + +- headlines (level 1-6) +- paragraphs +- inline links +- images +- flat unordered lists +- inline formats (**bold**, _emphasis_, `code`) in paragraphs & lists +- GFM code blocks with language hint + +Other features + +- **Functional:** parser entirely built using [transducers](https://github.com/thi-ng/umbrella/tree/master/packages/transducers) & function composition. Use the parser in a transducer pipeline to easily apply post-processing of the emitted results +- **Declarative:** parsing rules defined declaratively with only minimal state/context handling needed +- **No regex:** consumes input character-wise and produces an iterator of hiccup-style tree nodes, ready to be used with [@thi.ng/hdom](https://github.com/thi-ng/umbrella/tree/master/packages/hdom), [@thi.ng/hiccup](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup) or [@thi.ng/hiccup-markdown](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup-markdown) (for back conversion to MD) +- **Fast (enough):** parses this markdown file in 2-3ms on MBP2016 / Chrome 71 +- **Small:** minified+gzipped ~3KB + +See [example source +code](https://github.com/thi-ng/umbrella/tree/feature/fsm/examples/markdown/src/) +for reference... + +### Limitations + +These MD features (and probably more) are not supported: + +- inline HTML +- image links +- footnotes +- link references +- inline formats within link labels +- ordered / numbered / todo lists +- block quotes +- tables + +Some of these are considered, though currently not high priority... + +## Building locally + +```bash +git clone https://github.com/thi-ng/umbrella.git +cd umbrella + +# first build all packages in mono repo (takes about 1-2mins) +yarn install +yarn build + +# then launch example +cd examples/markdown +yarn start +``` + +## Authors + +- Karsten Schmidt + +## License + +© 2018 - 2019 Karsten Schmidt // Apache Software License 2.0 + diff --git a/examples/markdown/index.html b/examples/markdown/index.html new file mode 100644 index 0000000000..88bb840a90 --- /dev/null +++ b/examples/markdown/index.html @@ -0,0 +1,19 @@ + + + + + + + + markdown + + + + + +

+ + + + \ No newline at end of file diff --git a/examples/markdown/package.json b/examples/markdown/package.json new file mode 100644 index 0000000000..b7e873bc4c --- /dev/null +++ b/examples/markdown/package.json @@ -0,0 +1,29 @@ +{ + "name": "markdown", + "version": "0.0.1", + "repository": "https://github.com/thi-ng/umbrella", + "author": "Karsten Schmidt ", + "license": "Apache-2.0", + "scripts": { + "clean": "rm -rf .cache build out", + "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --detailed-report", + "start": "parcel index.html -p 8080 --open" + }, + "devDependencies": { + "parcel-bundler": "^1.10.3", + "terser": "^3.11.0", + "typescript": "^3.2.2" + }, + "dependencies": { + "@thi.ng/api": "latest", + "@thi.ng/fsm": "latest", + "@thi.ng/rstream": "latest", + "@thi.ng/transducers-hdom": "latest" + }, + "browserslist": [ + "last 3 Chrome versions" + ], + "browser": { + "process": false + } +} \ No newline at end of file diff --git a/examples/markdown/src/index.ts b/examples/markdown/src/index.ts new file mode 100644 index 0000000000..259c245fd8 --- /dev/null +++ b/examples/markdown/src/index.ts @@ -0,0 +1,51 @@ +import { timedResult } from "@thi.ng/bench"; +import { stream, Stream } from "@thi.ng/rstream/stream"; +import { updateDOM } from "@thi.ng/transducers-hdom"; +import { iterator } from "@thi.ng/transducers/iterator"; +import { map } from "@thi.ng/transducers/xform/map"; +import { parseMD } from "./parser"; + +// ignore error, resolved by parcel +import readme from "../README.md"; + +// UI root component +const app = + (input: Stream) => + ({ src, parsed: [hiccup, time] }) => + ["div.flex.vh-100.sans-serif.flex-column.flex-row-l", + ["div.w-100.h-50.w-50-l.h-100-l", + ["textarea.w-100.vh-50.vh-100-l.bg-lightest-blue.pa1.f7.code", + { + value: src, + oninput: (e) => input.next(e.target.value) + } + ]], + ["div.w-100.h-50.w-50-l.vh-100-l.overflow-y-scroll.pa3.lh-copy", + ["div.pa2.bg-yellow.purple.f7", `Parsed in ${time}ms`], + ...hiccup] + ]; + +// markdown input stream +const src = stream(); + +// stream transformer & UI update +src.transform( + map((src) => ({ src, parsed: timedResult(() => [...iterator(parseMD(), src)]) })), + map(app(src)), + updateDOM() +); + +// seed temp input +src.next(`# Loading readme...`); + +// load markdown & seed input +fetch(readme) + .then((res) => res.text()) + .then((txt) => src.next(txt)) + .catch((e) => src.next(`# Error loading file: ${e}`)); + +// HMR handling +if (process.env.NODE_ENV !== "production") { + const hot = (module).hot; + hot && hot.dispose(() => src.done()); +} diff --git a/examples/markdown/src/parser.ts b/examples/markdown/src/parser.ts new file mode 100644 index 0000000000..f3652448c3 --- /dev/null +++ b/examples/markdown/src/parser.ts @@ -0,0 +1,195 @@ +import { + alts, + fsm, + ResultBody, + seq, + str, + until, + whitespace +} from "@thi.ng/fsm"; + +// parse state IDs +const CODE = "code"; +const CODEBLOCK = "codeblock"; +const EMPHASIS = "em"; +const END_LI = "end_li"; +const END_PARA = "end_para"; +const HD = "hd"; +const IMG = "img"; +const LINK = "link"; +const LI = "li"; +const PARA = "para"; +const START = "start"; +const START_CODEBLOCK = "start_codeblock"; +const STRONG = "strong"; + +// parse context +interface FSMCtx { + stack: any[]; + list?: any[]; + children?: any[]; + body?: string; + title?: string; + href?: string; + lang?: string; + hd?: number; +} + +// state / context handling helpers + +const transition = + (ctx: FSMCtx, id: string): ResultBody => + (ctx.children = [], ctx.body = "", [id]); + +const push = + (curr: string, next: string) => + (ctx: FSMCtx): ResultBody => { + ctx.stack.push({ id: curr, children: [...ctx.children, ctx.body] }); + return transition(ctx, next); + }; + +const pop = + (result) => + (ctx, body): ResultBody => { + const { id, children } = ctx.stack.pop(); + children.push(result(ctx, body)); + ctx.children = children; + return [id]; + }; + +const collect = + (id: string) => + (ctx, buf): ResultBody => + (ctx.body += buf.join(""), [id]); + +const hd = + (level: number) => + (ctx: FSMCtx): ResultBody => (ctx.hd = level, [HD]); + +const inline = + (id: string) => [ + str("![", push(id, IMG)), + str("[", push(id, LINK)), + str("**", push(id, STRONG)), + str("_", push(id, EMPHASIS)), + str("`", push(id, CODE)) + ]; + +const link = + (result: (ctx: FSMCtx) => any) => + seq( + [ + until("]", (ctx, body) => (ctx.title = body, null)), + str("("), + until(")", (ctx, body) => (ctx.href = body, null)), + ], + pop(result) + ); + +const newPara = + (next: string) => + (ctx: FSMCtx): ResultBody => { + ctx.stack.push({ id: PARA, children: [] }); + return transition(ctx, next); + }; + +const newList = + (tag: string) => + (ctx: FSMCtx): ResultBody => { + ctx.list = [tag]; + return transition(ctx, LI); + }; + +/** + * Main parser / transducer. Defines state map with various matchers and + * transition handlers. The returned parser itself is only used in + * `index.ts`. + */ +export const parseMD = () => + fsm( + { + [START]: + alts( + [ + whitespace(() => [START]), + str("# ", hd(1)), + str("## ", hd(2)), + str("### ", hd(3)), + str("#### ", hd(4)), + str("##### ", hd(5)), + str("###### ", hd(6)), + str("- ", newList("ul")), + str("```", () => [START_CODEBLOCK]), + str("![", newPara(IMG)), + str("[", newPara(LINK)), + str("**", newPara(STRONG)), + str("_", newPara(EMPHASIS)), + ], + (ctx, buf) => (ctx.body = buf.join(""), ctx.children = [], [PARA]), + ), + + [PARA]: + alts( + [ + ...inline(PARA), + str("\n", (s) => (s.body += " ", [END_PARA])), + ], + collect(PARA), + ), + + [END_PARA]: + alts( + [ + ...inline(PARA), + str("\n", (s) => [START, [["p", ...s.children, s.body]]]), + ], + collect(PARA) + ), + + [HD]: + until("\n\n", (s, buf) => [START, [[`h${s.hd}`, buf]]]), + + [START_CODEBLOCK]: + until("\n", (s, lang) => (s.lang = lang, [CODEBLOCK])), + + [CODEBLOCK]: + until( + "\n```\n", + (ctx, body) => [START, [["pre.bg-washed-yellow.pa3.f7", { lang: ctx.lang }, ["code", body]]]] + ), + + [LI]: + alts( + [ + ...inline(LI), + str("\n", (ctx) => (ctx.list.push(["li", ...ctx.children, ctx.body]), [END_LI])), + ], + collect(LI) + ), + + [END_LI]: + alts([ + str("\n", (ctx) => [START, [ctx.list]]), + str("- ", (ctx) => transition(ctx, LI)) + ]), + + [LINK]: + link((ctx) => ["a", { href: ctx.href }, ctx.title]), + + [IMG]: + link((ctx) => ["img", { src: ctx.href, alt: ctx.title }]), + + [STRONG]: + until("**", pop((_, body) => ["strong", body])), + + [EMPHASIS]: + until("_", pop((_, body) => ["em", body])), + + [CODE]: + until("`", pop((_, body) => ["code.bg-washed-green.pa1.f7", body])), + }, + { + stack: [] + }, + START + ); diff --git a/examples/markdown/tsconfig.json b/examples/markdown/tsconfig.json new file mode 100644 index 0000000000..bbf112cc18 --- /dev/null +++ b/examples/markdown/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": ".", + "target": "es6", + "sourceMap": true + }, + "include": [ + "./src/**/*.ts" + ] +} From b04e07470a24450ce2b4c97f527edf77a2897344 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 3 Jan 2019 03:29:24 +0000 Subject: [PATCH 160/333] feat(examples): update MD parser, add parse rules & custom tag support --- examples/markdown/README.md | 3 ++- examples/markdown/src/index.ts | 13 +++++++-- examples/markdown/src/parser.ts | 48 ++++++++++++++++++++++++--------- 3 files changed, 48 insertions(+), 16 deletions(-) diff --git a/examples/markdown/README.md b/examples/markdown/README.md index 51b4c26f70..fe88ef96b2 100644 --- a/examples/markdown/README.md +++ b/examples/markdown/README.md @@ -25,7 +25,7 @@ syntax features, but already supports so far: - inline links - images - flat unordered lists -- inline formats (**bold**, _emphasis_, `code`) in paragraphs & lists +- inline formats (**bold**, _emphasis_, `code`, ~~strikethrough~~) in paragraphs & lists - GFM code blocks with language hint Other features @@ -33,6 +33,7 @@ Other features - **Functional:** parser entirely built using [transducers](https://github.com/thi-ng/umbrella/tree/master/packages/transducers) & function composition. Use the parser in a transducer pipeline to easily apply post-processing of the emitted results - **Declarative:** parsing rules defined declaratively with only minimal state/context handling needed - **No regex:** consumes input character-wise and produces an iterator of hiccup-style tree nodes, ready to be used with [@thi.ng/hdom](https://github.com/thi-ng/umbrella/tree/master/packages/hdom), [@thi.ng/hiccup](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup) or [@thi.ng/hiccup-markdown](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup-markdown) (for back conversion to MD) +- **Customizable:** supports custom tag factory functions to override default behavior / representation of each parsed result element - **Fast (enough):** parses this markdown file in 2-3ms on MBP2016 / Chrome 71 - **Small:** minified+gzipped ~3KB diff --git a/examples/markdown/src/index.ts b/examples/markdown/src/index.ts index 259c245fd8..fe4576b490 100644 --- a/examples/markdown/src/index.ts +++ b/examples/markdown/src/index.ts @@ -8,13 +8,22 @@ import { parseMD } from "./parser"; // ignore error, resolved by parcel import readme from "../README.md"; +// custom tag factories (passed to parser) +// uses Tachyons CSS classes for styling +const CUSTOM_TAGS = { + pre: (ctx, body) => ["pre.bg-washed-yellow.pa3.f7", { lang: ctx.lang }, ["code", body]], + a: (ctx) => ["a.link.dark-blue.hover-white.hover-bg-dark-blue.b", { href: ctx.href }, ctx.title], + strike: (_, body) => ["del.bg-washed-red", body], + code: (_, body) => ["code.bg-light-gray.pa1.f7", body], +}; + // UI root component const app = (input: Stream) => ({ src, parsed: [hiccup, time] }) => ["div.flex.vh-100.sans-serif.flex-column.flex-row-l", ["div.w-100.h-50.w-50-l.h-100-l", - ["textarea.w-100.vh-50.vh-100-l.bg-lightest-blue.pa1.f7.code", + ["textarea.w-100.vh-50.vh-100-l.bg-washed-blue.pa3.f7.code", { value: src, oninput: (e) => input.next(e.target.value) @@ -30,7 +39,7 @@ const src = stream(); // stream transformer & UI update src.transform( - map((src) => ({ src, parsed: timedResult(() => [...iterator(parseMD(), src)]) })), + map((src) => ({ src, parsed: timedResult(() => [...iterator(parseMD(CUSTOM_TAGS), src)]) })), map(app(src)), updateDOM() ); diff --git a/examples/markdown/src/parser.ts b/examples/markdown/src/parser.ts index f3652448c3..c630199f86 100644 --- a/examples/markdown/src/parser.ts +++ b/examples/markdown/src/parser.ts @@ -1,3 +1,4 @@ +import { IObjectOf } from "@thi.ng/api"; import { alts, fsm, @@ -21,6 +22,7 @@ const LI = "li"; const PARA = "para"; const START = "start"; const START_CODEBLOCK = "start_codeblock"; +const STRIKE = "strike"; const STRONG = "strong"; // parse context @@ -70,6 +72,7 @@ const inline = (id: string) => [ str("![", push(id, IMG)), str("[", push(id, LINK)), + str("~~", push(id, STRIKE)), str("**", push(id, STRONG)), str("_", push(id, EMPHASIS)), str("`", push(id, CODE)) @@ -100,13 +103,27 @@ const newList = return transition(ctx, LI); }; +const DEFAULT_TAGS = { + p: (ctx) => ["p", ...ctx.children, ctx.body], + hd: (ctx, buf) => [`h${ctx.hd}`, buf], + pre: (ctx, body) => ["pre", { lang: ctx.lang }, body], + li: (ctx) => ["li", ...ctx.children, ctx.body], + a: (ctx) => ["a", { href: ctx.href }, ctx.title], + img: (ctx) => ["img", { src: ctx.href, alt: ctx.title }], + strong: (_, body) => ["strong", body], + strike: (_, body) => ["del", body], + em: (_, body) => ["em", body], + code: (_, body) => ["code", body], +}; + /** * Main parser / transducer. Defines state map with various matchers and * transition handlers. The returned parser itself is only used in * `index.ts`. */ -export const parseMD = () => - fsm( +export const parseMD = (tags?: IObjectOf<(ctx: FSMCtx, body?: any) => any>) => { + tags = { ...DEFAULT_TAGS, ...tags }; + return fsm( { [START]: alts( @@ -123,6 +140,7 @@ export const parseMD = () => str("![", newPara(IMG)), str("[", newPara(LINK)), str("**", newPara(STRONG)), + str("~~", newPara(STRIKE)), str("_", newPara(EMPHASIS)), ], (ctx, buf) => (ctx.body = buf.join(""), ctx.children = [], [PARA]), @@ -132,7 +150,7 @@ export const parseMD = () => alts( [ ...inline(PARA), - str("\n", (s) => (s.body += " ", [END_PARA])), + str("\n", (ctx) => (ctx.body += " ", [END_PARA])), ], collect(PARA), ), @@ -141,28 +159,28 @@ export const parseMD = () => alts( [ ...inline(PARA), - str("\n", (s) => [START, [["p", ...s.children, s.body]]]), + str("\n", (ctx) => [START, [tags.p(ctx)]]), ], collect(PARA) ), [HD]: - until("\n\n", (s, buf) => [START, [[`h${s.hd}`, buf]]]), + until("\n\n", (ctx, buf) => [START, [tags.hd(ctx, buf)]]), [START_CODEBLOCK]: - until("\n", (s, lang) => (s.lang = lang, [CODEBLOCK])), + until("\n", (ctx, lang) => (ctx.lang = lang, [CODEBLOCK])), [CODEBLOCK]: until( "\n```\n", - (ctx, body) => [START, [["pre.bg-washed-yellow.pa3.f7", { lang: ctx.lang }, ["code", body]]]] + (ctx, body) => [START, [tags.pre(ctx, body)]] ), [LI]: alts( [ ...inline(LI), - str("\n", (ctx) => (ctx.list.push(["li", ...ctx.children, ctx.body]), [END_LI])), + str("\n", (ctx) => (ctx.list.push(tags.li(ctx)), [END_LI])), ], collect(LI) ), @@ -174,22 +192,26 @@ export const parseMD = () => ]), [LINK]: - link((ctx) => ["a", { href: ctx.href }, ctx.title]), + link(tags.a), [IMG]: - link((ctx) => ["img", { src: ctx.href, alt: ctx.title }]), + link(tags.img), [STRONG]: - until("**", pop((_, body) => ["strong", body])), + until("**", pop(tags.strong)), + + [STRIKE]: + until("~~", pop(tags.strike)), [EMPHASIS]: - until("_", pop((_, body) => ["em", body])), + until("_", pop(tags.em)), [CODE]: - until("`", pop((_, body) => ["code.bg-washed-green.pa1.f7", body])), + until("`", pop(tags.code)), }, { stack: [] }, START ); +}; From 36cadc9650197df848039c63e81e28e4dbd954d8 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 3 Jan 2019 13:12:28 +0000 Subject: [PATCH 161/333] feat(examples): update tags, add hrule, blockquote, update CSS / readme --- examples/markdown/README.md | 80 +++++++++++++++++-- examples/markdown/index.html | 22 ++++++ examples/markdown/src/index.ts | 15 ++-- examples/markdown/src/parser.ts | 133 +++++++++++++++++++++----------- 4 files changed, 190 insertions(+), 60 deletions(-) diff --git a/examples/markdown/README.md b/examples/markdown/README.md index fe88ef96b2..ad3765c32d 100644 --- a/examples/markdown/README.md +++ b/examples/markdown/README.md @@ -1,4 +1,4 @@ -# minimal markdown parser +# Minimal Markdown parser This project is part of the [@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo. @@ -13,20 +13,28 @@ the (still unreleased) [@thi.ng/fsm](https://github.com/thi-ng/umbrella/tree/feature/fsm/packages/fsm) package, which itself is a potential replacement / major version update for -[@transducers-fsm](https://github.com/thi-ng/umbrella/tree/master/packages/transducers-fsm). +[@thi.ng/transducers-fsm](https://github.com/thi-ng/umbrella/tree/master/packages/transducers-fsm). + +> "Weeks of coding can **save hours** of planning." +> -- Anonymous ### Features -The parser itself is currently not aimed to support **all** of Markdown's quirky -syntax features, but already supports so far: +The parser itself is not aimed at supporting **all** of Markdown's +quirky syntax features, but will restrict itself to a sane subset of +features and already sports: - headlines (level 1-6) - paragraphs +- blockquotes - inline links - images - flat unordered lists - inline formats (**bold**, _emphasis_, `code`, ~~strikethrough~~) in paragraphs & lists - GFM code blocks with language hint +- horizontal rules + +--- Other features @@ -43,19 +51,75 @@ for reference... ### Limitations -These MD features (and probably more) are not supported: +These MD features (and probably many more) are not supported: - inline HTML +- inline formats within link labels - image links - footnotes - link references -- inline formats within link labels -- ordered / numbered / todo lists -- block quotes +- nested / ordered / numbered / todo lists - tables Some of these are considered, though currently not high priority... +## Serializing to HTML + +```ts +import { iterator } from "@thi.ng/transducers"; +import { serialize } from "@thi.ng/hiccup"; + +import { parseMD } from "./parser"; + +const src = ` +# Hello world + +[This](http://example.com) is a _test_. + +`; + +serialize(iterator(parseMD(), src)); + +//

Hello world

+// This is a test.

+``` + +## Customizing tags + +The following interface defines factory functions for all supported +elements. User implementations / overrides can be given to the +`parseMD()` transducer to customize output. + +```ts +interface TagFactories { + blockquote(...children: any[]): any[]; + code(body: string): any[]; + codeblock(lang: string, body: string): any[]; + em(body: string): any[]; + img(src: string, alt: string): any[]; + link(href: string, body: string): any[]; + list(type: string): any[]; + li(...children: any[]): any[]; + paragraph(...children: any[]): any[]; + strong(body: string): any[]; + strike(body: string): any[]; + title(level: number, body: string): any[]; +} +``` + +Example w/ custom link elements + +```ts +const tags = { + link: (href, body) => ["a.link.blue", { href }, body] +}; + +serialize(iterator(parseMD(tags), src)); + +//

Hello world

+//

This is a test.

+``` + ## Building locally ```bash diff --git a/examples/markdown/index.html b/examples/markdown/index.html index 88bb840a90..84364d1aa0 100644 --- a/examples/markdown/index.html +++ b/examples/markdown/index.html @@ -8,6 +8,28 @@ markdown diff --git a/examples/markdown/src/index.ts b/examples/markdown/src/index.ts index fe4576b490..ba0f11ff25 100644 --- a/examples/markdown/src/index.ts +++ b/examples/markdown/src/index.ts @@ -3,18 +3,19 @@ import { stream, Stream } from "@thi.ng/rstream/stream"; import { updateDOM } from "@thi.ng/transducers-hdom"; import { iterator } from "@thi.ng/transducers/iterator"; import { map } from "@thi.ng/transducers/xform/map"; -import { parseMD } from "./parser"; +import { parseMD, TagFactories } from "./parser"; // ignore error, resolved by parcel import readme from "../README.md"; // custom tag factories (passed to parser) // uses Tachyons CSS classes for styling -const CUSTOM_TAGS = { - pre: (ctx, body) => ["pre.bg-washed-yellow.pa3.f7", { lang: ctx.lang }, ["code", body]], - a: (ctx) => ["a.link.dark-blue.hover-white.hover-bg-dark-blue.b", { href: ctx.href }, ctx.title], - strike: (_, body) => ["del.bg-washed-red", body], - code: (_, body) => ["code.bg-light-gray.pa1.f7", body], +const CUSTOM_TAGS: Partial = { + blockquote: (...xs) => ["blockquote.i.f4.gray", ...xs], + code: (body) => ["code.bg-light-gray.pa1.f7", body], + codeblock: (lang, body) => ["pre.bg-washed-yellow.pa3.f7", { lang }, ["code", body]], + link: (href, body) => ["a.link.dark-blue.hover-white.hover-bg-dark-blue.b", { href }, body], + strike: (body) => ["del.bg-washed-red", body], }; // UI root component @@ -23,7 +24,7 @@ const app = ({ src, parsed: [hiccup, time] }) => ["div.flex.vh-100.sans-serif.flex-column.flex-row-l", ["div.w-100.h-50.w-50-l.h-100-l", - ["textarea.w-100.vh-50.vh-100-l.bg-washed-blue.pa3.f7.code", + ["textarea.w-100.vh-50.vh-100-l.bg-washed-blue.navy.pa3.f7.code.lh-copy", { value: src, oninput: (e) => input.next(e.target.value) diff --git a/examples/markdown/src/parser.ts b/examples/markdown/src/parser.ts index c630199f86..0967697b4c 100644 --- a/examples/markdown/src/parser.ts +++ b/examples/markdown/src/parser.ts @@ -1,4 +1,3 @@ -import { IObjectOf } from "@thi.ng/api"; import { alts, fsm, @@ -10,20 +9,38 @@ import { } from "@thi.ng/fsm"; // parse state IDs +const BLOCKQUOTE = "blockquote"; const CODE = "code"; const CODEBLOCK = "codeblock"; const EMPHASIS = "em"; -const END_LI = "end_li"; -const END_PARA = "end_para"; -const HD = "hd"; +const END_BLOCKQUOTE = "end-blockquote"; +const END_LI = "end-li"; +const END_PARA = "end-para"; const IMG = "img"; const LINK = "link"; const LI = "li"; const PARA = "para"; const START = "start"; -const START_CODEBLOCK = "start_codeblock"; +const START_CODEBLOCK = "start-codeblock"; const STRIKE = "strike"; const STRONG = "strong"; +const TITLE = "title"; + +// hiccup element factories +export interface TagFactories { + blockquote(...children: any[]): any[]; + code(body: string): any[]; + codeblock(lang: string, body: string): any[]; + em(body: string): any[]; + img(src: string, alt: string): any[]; + link(href: string, body: string): any[]; + list(type: string): any[]; + li(...children: any[]): any[]; + paragraph(...children: any[]): any[]; + strong(body: string): any[]; + strike(body: string): any[]; + title(level, body): any[]; +} // parse context interface FSMCtx { @@ -64,9 +81,13 @@ const collect = (ctx, buf): ResultBody => (ctx.body += buf.join(""), [id]); -const hd = +const resultBody = + (fn: (body: string) => any[]) => + (_, body: string) => fn(body.trim()); + +const title = (level: number) => - (ctx: FSMCtx): ResultBody => (ctx.hd = level, [HD]); + (ctx: FSMCtx): ResultBody => (ctx.hd = level, [TITLE]); const inline = (id: string) => [ @@ -79,14 +100,14 @@ const inline = ]; const link = - (result: (ctx: FSMCtx) => any) => + (result: (href, body) => any[]) => seq( [ until("]", (ctx, body) => (ctx.title = body, null)), str("("), until(")", (ctx, body) => (ctx.href = body, null)), ], - pop(result) + pop((ctx) => result(ctx.href, ctx.title)) ); const newPara = @@ -96,24 +117,36 @@ const newPara = return transition(ctx, next); }; +const paragraph = + (id: string, next: string) => + alts( + [ + ...inline(id), + str("\n", (ctx: FSMCtx) => (ctx.body += " ", [next])), + ], + collect(id), + ); + const newList = - (tag: string) => + (factory: (type: string) => any[], type: string) => (ctx: FSMCtx): ResultBody => { - ctx.list = [tag]; + ctx.list = factory(type); return transition(ctx, LI); }; -const DEFAULT_TAGS = { - p: (ctx) => ["p", ...ctx.children, ctx.body], - hd: (ctx, buf) => [`h${ctx.hd}`, buf], - pre: (ctx, body) => ["pre", { lang: ctx.lang }, body], - li: (ctx) => ["li", ...ctx.children, ctx.body], - a: (ctx) => ["a", { href: ctx.href }, ctx.title], - img: (ctx) => ["img", { src: ctx.href, alt: ctx.title }], - strong: (_, body) => ["strong", body], - strike: (_, body) => ["del", body], - em: (_, body) => ["em", body], - code: (_, body) => ["code", body], +const DEFAULT_TAGS: TagFactories = { + blockquote: (...xs) => ["blockquote", ...xs], + code: (body) => ["code", body], + codeblock: (lang, body) => ["pre", { lang }, body], + em: (body) => ["em", body], + img: (src, alt) => ["img", { src, alt }], + li: (...xs: any[]) => ["li", ...xs], + link: (href, body) => ["a", { href }, body], + list: (type) => [type], + paragraph: (...xs) => ["p", ...xs], + strong: (body) => ["strong", body], + strike: (body) => ["del", body], + title: (level, body) => [`h${level}`, body], }; /** @@ -121,7 +154,7 @@ const DEFAULT_TAGS = { * transition handlers. The returned parser itself is only used in * `index.ts`. */ -export const parseMD = (tags?: IObjectOf<(ctx: FSMCtx, body?: any) => any>) => { +export const parseMD = (tags?: Partial) => { tags = { ...DEFAULT_TAGS, ...tags }; return fsm( { @@ -129,14 +162,17 @@ export const parseMD = (tags?: IObjectOf<(ctx: FSMCtx, body?: any) => any>) => { alts( [ whitespace(() => [START]), - str("# ", hd(1)), - str("## ", hd(2)), - str("### ", hd(3)), - str("#### ", hd(4)), - str("##### ", hd(5)), - str("###### ", hd(6)), - str("- ", newList("ul")), + str("# ", title(1)), + str("## ", title(2)), + str("### ", title(3)), + str("#### ", title(4)), + str("##### ", title(5)), + str("###### ", title(6)), + str("####### ", title(7)), + str("> ", (ctx) => (ctx.children = [], ctx.body = "", [BLOCKQUOTE])), + str("- ", newList(tags.list, "ul")), str("```", () => [START_CODEBLOCK]), + str("---\n", () => [START, [["hr"]]]), str("![", newPara(IMG)), str("[", newPara(LINK)), str("**", newPara(STRONG)), @@ -147,25 +183,32 @@ export const parseMD = (tags?: IObjectOf<(ctx: FSMCtx, body?: any) => any>) => { ), [PARA]: + paragraph(PARA, END_PARA), + + [END_PARA]: alts( [ ...inline(PARA), - str("\n", (ctx) => (ctx.body += " ", [END_PARA])), + str("\n", (ctx) => [START, [tags.paragraph(...ctx.children, ctx.body)]]), ], - collect(PARA), + collect(PARA) ), - [END_PARA]: + [BLOCKQUOTE]: + paragraph(BLOCKQUOTE, END_BLOCKQUOTE), + + [END_BLOCKQUOTE]: alts( [ - ...inline(PARA), - str("\n", (ctx) => [START, [tags.p(ctx)]]), + ...inline(BLOCKQUOTE), + str("> ", (ctx) => (ctx.children.push(ctx.body, ["br"]), ctx.body = "", [BLOCKQUOTE])), + str("\n", (ctx) => [START, [tags.blockquote(...ctx.children, ctx.body)]]), ], - collect(PARA) + collect(BLOCKQUOTE) ), - [HD]: - until("\n\n", (ctx, buf) => [START, [tags.hd(ctx, buf)]]), + [TITLE]: + until("\n\n", (ctx, body) => [START, [tags.title(ctx.hd, body)]]), [START_CODEBLOCK]: until("\n", (ctx, lang) => (ctx.lang = lang, [CODEBLOCK])), @@ -173,14 +216,14 @@ export const parseMD = (tags?: IObjectOf<(ctx: FSMCtx, body?: any) => any>) => { [CODEBLOCK]: until( "\n```\n", - (ctx, body) => [START, [tags.pre(ctx, body)]] + (ctx, body) => [START, [tags.codeblock(ctx.lang, body)]] ), [LI]: alts( [ ...inline(LI), - str("\n", (ctx) => (ctx.list.push(tags.li(ctx)), [END_LI])), + str("\n", (ctx) => (ctx.list.push(tags.li(...ctx.children, ctx.body)), [END_LI])), ], collect(LI) ), @@ -192,22 +235,22 @@ export const parseMD = (tags?: IObjectOf<(ctx: FSMCtx, body?: any) => any>) => { ]), [LINK]: - link(tags.a), + link(tags.link), [IMG]: link(tags.img), [STRONG]: - until("**", pop(tags.strong)), + until("**", pop(resultBody(tags.strong))), [STRIKE]: - until("~~", pop(tags.strike)), + until("~~", pop(resultBody(tags.strike))), [EMPHASIS]: - until("_", pop(tags.em)), + until("_", pop(resultBody(tags.em))), [CODE]: - until("`", pop(tags.code)), + until("`", pop(resultBody(tags.code))), }, { stack: [] From 55671fc7e76a0051f5bc1e2b55fad64c2fa95aa9 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 3 Jan 2019 16:00:26 +0000 Subject: [PATCH 162/333] feat(fsm): add repeat(), success(), refactor all matchers --- packages/fsm/src/alts.ts | 19 ++++++++++--------- packages/fsm/src/api.ts | 1 + packages/fsm/src/index.ts | 1 + packages/fsm/src/range.ts | 7 ++----- packages/fsm/src/repeat.ts | 37 +++++++++++++++++++++++++++++++++++++ packages/fsm/src/seq.ts | 6 ++---- packages/fsm/src/str.ts | 7 ++----- packages/fsm/src/success.ts | 5 +++++ packages/fsm/src/until.ts | 16 ++++------------ 9 files changed, 64 insertions(+), 35 deletions(-) create mode 100644 packages/fsm/src/repeat.ts create mode 100644 packages/fsm/src/success.ts diff --git a/packages/fsm/src/alts.ts b/packages/fsm/src/alts.ts index 40bbc8f56b..55434e03a6 100644 --- a/packages/fsm/src/alts.ts +++ b/packages/fsm/src/alts.ts @@ -1,4 +1,11 @@ -import { Match, RES_FAIL, RES_PARTIAL, Matcher, ResultBody } from "./api"; +import { + Match, + Matcher, + RES_FAIL, + RES_PARTIAL, + ResultBody +} from "./api"; +import { success } from "./success"; export const alts = ( opts: Matcher[], @@ -13,10 +20,7 @@ export const alts = ( const next = alts[i](ctx, x); if (next.type === Match.FULL) { return callback ? - { - type: Match.FULL, - body: callback(ctx, next.body, buf) - } : + success(callback(ctx, next.body, buf)) : next; } else if (next.type === Match.FAIL) { alts.splice(i, 1); @@ -26,10 +30,7 @@ export const alts = ( return alts.length ? RES_PARTIAL : fallback ? - { - type: Match.FULL, - body: fallback(ctx, buf) - } : + success(fallback(ctx, buf)) : RES_FAIL; }; }; diff --git a/packages/fsm/src/api.ts b/packages/fsm/src/api.ts index 084ee24e4b..4221a13384 100644 --- a/packages/fsm/src/api.ts +++ b/packages/fsm/src/api.ts @@ -1,6 +1,7 @@ export const enum Match { PARTIAL = 0, FULL = 1, + FULL_NC = 2, FAIL = -1 } diff --git a/packages/fsm/src/index.ts b/packages/fsm/src/index.ts index ce52057625..988a94c258 100644 --- a/packages/fsm/src/index.ts +++ b/packages/fsm/src/index.ts @@ -2,6 +2,7 @@ export * from "./api"; export * from "./alts"; export * from "./fsm"; export * from "./range"; +export * from "./repeat"; export * from "./seq"; export * from "./str"; export * from "./until"; diff --git a/packages/fsm/src/range.ts b/packages/fsm/src/range.ts index c296dc6ff6..91df2288a5 100644 --- a/packages/fsm/src/range.ts +++ b/packages/fsm/src/range.ts @@ -1,11 +1,11 @@ import { alts } from "./alts"; import { AltCallback, - Match, Matcher, RangeCallback, RES_FAIL } from "./api"; +import { success } from "./success"; import { str } from "./str"; export const range = ( @@ -16,10 +16,7 @@ export const range = ( () => (ctx, x) => x >= min && x <= max ? - { - type: Match.FULL, - body: callback && callback(ctx, x) - } : + success(callback && callback(ctx, x)) : RES_FAIL; export const digit = diff --git a/packages/fsm/src/repeat.ts b/packages/fsm/src/repeat.ts new file mode 100644 index 0000000000..66785f8a04 --- /dev/null +++ b/packages/fsm/src/repeat.ts @@ -0,0 +1,37 @@ +import { + Match, + Matcher, + SeqCallback, + RES_PARTIAL, +} from "./api"; +import { success } from "./success"; + +export const repeat = ( + match: Matcher, + min: number, + max: number, + callback?: SeqCallback +): Matcher => + () => { + let m = match(); + let i = 0; + const buf: T[] = []; + return (ctx, x) => { + buf.push(x); + const r = m(ctx, x); + if (r.type === Match.FULL) { + i++; + if (i === max) { + return success(callback && callback(ctx, buf)); + } + m = match(); + return RES_PARTIAL; + } else if (r.type === Match.FAIL) { + if (i >= min) { + buf.pop(); + return success(callback && callback(ctx, buf)); + } + } + return r; + }; + }; diff --git a/packages/fsm/src/seq.ts b/packages/fsm/src/seq.ts index 11081edb91..b54ac58acf 100644 --- a/packages/fsm/src/seq.ts +++ b/packages/fsm/src/seq.ts @@ -5,6 +5,7 @@ import { RES_PARTIAL, SeqCallback } from "./api"; +import { success } from "./success"; export const seq = ( opts: Matcher[], @@ -21,10 +22,7 @@ export const seq = ( const { type } = o(state, x); if (type === Match.FULL) { if (i === n) { - return { - type: Match.FULL, - body: callback && callback(state, buf) - }; + return success(callback && callback(state, buf)); } o = opts[++i](); } diff --git a/packages/fsm/src/str.ts b/packages/fsm/src/str.ts index 1f3d3f4d4a..954f0de195 100644 --- a/packages/fsm/src/str.ts +++ b/packages/fsm/src/str.ts @@ -1,10 +1,10 @@ import { - Match, Matcher, RangeCallback, RES_FAIL, RES_PARTIAL } from "./api"; +import { success } from "./success"; export const str = ( str: string, @@ -16,10 +16,7 @@ export const str = ( buf.length >= str.length ? RES_FAIL : (buf += x) === str ? - { - type: Match.FULL, - body: callback && callback(state, buf) - } : + success(callback && callback(state, buf)) : str.indexOf(buf) === 0 ? RES_PARTIAL : RES_FAIL; diff --git a/packages/fsm/src/success.ts b/packages/fsm/src/success.ts new file mode 100644 index 0000000000..6e456d0b6d --- /dev/null +++ b/packages/fsm/src/success.ts @@ -0,0 +1,5 @@ +import { Match, MatchResult, ResultBody } from "./api"; + +export const success = + (body: ResultBody, type = Match.FULL): MatchResult => + ({ type, body }); diff --git a/packages/fsm/src/until.ts b/packages/fsm/src/until.ts index 0025ded874..a9baa9b07a 100644 --- a/packages/fsm/src/until.ts +++ b/packages/fsm/src/until.ts @@ -1,9 +1,5 @@ -import { - Match, - Matcher, - RangeCallback, - RES_PARTIAL -} from "./api"; +import { Matcher, RangeCallback, RES_PARTIAL } from "./api"; +import { success } from "./success"; export const until = ( str: string, @@ -13,12 +9,8 @@ export const until = ( let buf = ""; return (ctx, x) => { buf += x; - return buf.length >= str.length && - buf.substr(buf.length - str.length) === str ? - { - type: Match.FULL, - body: callback && callback(ctx, buf.substr(0, buf.length - str.length)) - } : + return buf.endsWith(str) ? + success(callback && callback(ctx, buf.substr(0, buf.length - str.length))) : RES_PARTIAL; }; }; From f9cece70e2d077a910fa71b330fe430a9471f732 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 3 Jan 2019 16:09:56 +0000 Subject: [PATCH 163/333] refactor(examples): update MD title parser --- examples/markdown/src/parser.ts | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/examples/markdown/src/parser.ts b/examples/markdown/src/parser.ts index 0967697b4c..0d7ff8f8b0 100644 --- a/examples/markdown/src/parser.ts +++ b/examples/markdown/src/parser.ts @@ -1,6 +1,7 @@ import { alts, fsm, + repeat, ResultBody, seq, str, @@ -86,8 +87,8 @@ const resultBody = (_, body: string) => fn(body.trim()); const title = - (level: number) => - (ctx: FSMCtx): ResultBody => (ctx.hd = level, [TITLE]); + (ctx: FSMCtx, body: string[]): ResultBody => + (ctx.hd = body.length, [TITLE]); const inline = (id: string) => [ @@ -146,7 +147,7 @@ const DEFAULT_TAGS: TagFactories = { paragraph: (...xs) => ["p", ...xs], strong: (body) => ["strong", body], strike: (body) => ["del", body], - title: (level, body) => [`h${level}`, body], + title: (level, body) => [level < 7 ? `h${level}` : "p", body], }; /** @@ -162,14 +163,8 @@ export const parseMD = (tags?: Partial) => { alts( [ whitespace(() => [START]), - str("# ", title(1)), - str("## ", title(2)), - str("### ", title(3)), - str("#### ", title(4)), - str("##### ", title(5)), - str("###### ", title(6)), - str("####### ", title(7)), - str("> ", (ctx) => (ctx.children = [], ctx.body = "", [BLOCKQUOTE])), + repeat(str("#"), 1, 10, title), + str("> ", (ctx) => transition(ctx, BLOCKQUOTE)), str("- ", newList(tags.list, "ul")), str("```", () => [START_CODEBLOCK]), str("---\n", () => [START, [["hr"]]]), From 4a9bb3d6392cea9b121b306f3e156a67a16b3db1 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 3 Jan 2019 17:44:13 +0000 Subject: [PATCH 164/333] feat(fsm): add support for lookahead-1, add docs --- packages/fsm/src/alts.ts | 19 ++++++++- packages/fsm/src/api.ts | 14 +++++++ packages/fsm/src/fsm.ts | 81 ++++++++++++++++++++++++++++---------- packages/fsm/src/repeat.ts | 2 +- packages/fsm/src/seq.ts | 22 +++++++---- packages/fsm/src/str.ts | 12 +++--- 6 files changed, 111 insertions(+), 39 deletions(-) diff --git a/packages/fsm/src/alts.ts b/packages/fsm/src/alts.ts index 55434e03a6..69c8f19e92 100644 --- a/packages/fsm/src/alts.ts +++ b/packages/fsm/src/alts.ts @@ -7,6 +7,21 @@ import { } from "./api"; import { success } from "./success"; +/** + * Returns a composed matcher which applies inputs to all given child + * matchers (`opts`) until either all have failed or one of them returns + * a full match. If successful, calls `callback` with the context, the + * child matcher's result and an array of all processed inputs thus far. + * The result of `alts` is the result of this callback (else undefined). + * Matchers are always processed in reverse order. + * + * If none of the matchers succeeded the optional `fallback` callback + * will be executed and given a chance to produce a state transition. + * + * @param opts + * @param fallback + * @param callback + */ export const alts = ( opts: Matcher[], fallback?: (ctx: C, buf: T[]) => ResultBody, @@ -18,9 +33,9 @@ export const alts = ( return (ctx, x) => { for (let i = alts.length; --i >= 0;) { const next = alts[i](ctx, x); - if (next.type === Match.FULL) { + if (next.type >= Match.FULL) { return callback ? - success(callback(ctx, next.body, buf)) : + success(callback(ctx, next.body, buf), next.type) : next; } else if (next.type === Match.FAIL) { alts.splice(i, 1); diff --git a/packages/fsm/src/api.ts b/packages/fsm/src/api.ts index 4221a13384..734e939629 100644 --- a/packages/fsm/src/api.ts +++ b/packages/fsm/src/api.ts @@ -1,7 +1,21 @@ export const enum Match { + /** + * Partial match + */ PARTIAL = 0, + /** + * Full match + */ FULL = 1, + /** + * Full match (No Consume), i.e. didn't consume last input. The + * result will be treated like `FULL`, but the last input will be + * processed further. + */ FULL_NC = 2, + /** + * Failed match. + */ FAIL = -1 } diff --git a/packages/fsm/src/fsm.ts b/packages/fsm/src/fsm.ts index aa50a0956d..6c8a4b469a 100644 --- a/packages/fsm/src/fsm.ts +++ b/packages/fsm/src/fsm.ts @@ -1,29 +1,68 @@ import { IObjectOf } from "@thi.ng/api"; +import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; import { illegalState } from "@thi.ng/errors/illegal-state"; -import { reduced } from "@thi.ng/transducers/reduced"; -import { mapcat } from "@thi.ng/transducers/xform/mapcat"; +import { Reducer, Transducer } from "@thi.ng/transducers/api"; +import { reduced, unreduced, isReduced, ensureReduced } from "@thi.ng/transducers/reduced"; import { Match, Matcher } from "./api"; +/** + * Finite-state machine transducer w/ support for single lookahead + * value. Takes an object of `states` and their matchers, an arbitrary + * context object and an `initial` state ID. + * + * The returned transducer consumes inputs of type `T` and produces + * results of type `R`. The results are produced by callbacks of the + * given state matchers. Each can produce any number of values. If a + * callback returns a result wrapped w/ `reduced()`, the FSM causes + * early termination of the overall transducer pipeline. + * + * @param states + * @param ctx + * @param initialState + */ export const fsm = ( states: IObjectOf>, ctx: C, - init: string | number = "start" -) => { - let currID = init; - let curr = states[init](); - return mapcat((x) => { - const { type, body } = curr(ctx, x); - if (type === Match.FULL) { - const next = states[body[0]]; - if (next) { - currID = body[0]; - curr = next(); - } else { - illegalState(`unknown tx: ${currID} -> ${body && body[0]}`); + initialState: string | number = "start" +): Transducer => + ([init, complete, reduce]: Reducer) => { + let currID = initialState; + let curr = states[initialState] ? + states[initialState]() : + illegalArgs(`invalid initial state: ${initialState}`); + return [ + init, + complete, + (acc, x) => { + while (true) { + const { type, body } = curr(ctx, x); + if (type >= Match.FULL) { + const next = body && states[body[0]]; + if (next) { + currID = body[0]; + curr = next(); + } else { + illegalState(`unknown tx: ${currID} -> ${body && body[0]}`); + } + const res = body[1]; + if (res) { + for (let y of unreduced(res)) { + acc = reduce(acc, y); + if (isReduced(acc)) { + break; + } + } + isReduced(res) && (acc = ensureReduced(acc)); + } + if (type === Match.FULL_NC && !isReduced(acc)) { + continue; + } + } else if (type === Match.FAIL) { + return reduced(acc); + } + break; + } + return acc; } - return body[1]; - } else if (type === Match.FAIL) { - return reduced([]); - } - }); -}; + ]; + }; diff --git a/packages/fsm/src/repeat.ts b/packages/fsm/src/repeat.ts index 66785f8a04..0d9b369b89 100644 --- a/packages/fsm/src/repeat.ts +++ b/packages/fsm/src/repeat.ts @@ -29,7 +29,7 @@ export const repeat = ( } else if (r.type === Match.FAIL) { if (i >= min) { buf.pop(); - return success(callback && callback(ctx, buf)); + return success(callback && callback(ctx, buf), Match.FULL_NC); } } return r; diff --git a/packages/fsm/src/seq.ts b/packages/fsm/src/seq.ts index b54ac58acf..44f54bede1 100644 --- a/packages/fsm/src/seq.ts +++ b/packages/fsm/src/seq.ts @@ -19,15 +19,21 @@ export const seq = ( return (state, x) => { if (i > n) return RES_FAIL; callback && buf.push(x); - const { type } = o(state, x); - if (type === Match.FULL) { - if (i === n) { - return success(callback && callback(state, buf)); + while (i <= n) { + const { type } = o(state, x); + if (type >= Match.FULL) { + if (i === n) { + return success(callback && callback(state, buf)); + } + o = opts[++i](); + if (type === Match.FULL_NC) { + continue; + } } - o = opts[++i](); + return type === Match.FAIL ? + RES_FAIL : + RES_PARTIAL; } - return type === Match.FAIL ? - RES_FAIL : - RES_PARTIAL; + return RES_FAIL; } }; diff --git a/packages/fsm/src/str.ts b/packages/fsm/src/str.ts index 954f0de195..7c82f80f47 100644 --- a/packages/fsm/src/str.ts +++ b/packages/fsm/src/str.ts @@ -13,11 +13,9 @@ export const str = ( () => { let buf = ""; return (state, x) => - buf.length >= str.length ? - RES_FAIL : - (buf += x) === str ? - success(callback && callback(state, buf)) : - str.indexOf(buf) === 0 ? - RES_PARTIAL : - RES_FAIL; + (buf += x) === str ? + success(callback && callback(state, buf)) : + str.indexOf(buf) === 0 ? + RES_PARTIAL : + RES_FAIL; }; From 995a104b9a3972f9502d33a7f87358939ad2b62f Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 3 Jan 2019 17:45:06 +0000 Subject: [PATCH 165/333] refactor(examples): update title & blockquote parsers/style --- examples/markdown/src/index.ts | 2 +- examples/markdown/src/parser.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/markdown/src/index.ts b/examples/markdown/src/index.ts index ba0f11ff25..e96a73b2d3 100644 --- a/examples/markdown/src/index.ts +++ b/examples/markdown/src/index.ts @@ -11,7 +11,7 @@ import readme from "../README.md"; // custom tag factories (passed to parser) // uses Tachyons CSS classes for styling const CUSTOM_TAGS: Partial = { - blockquote: (...xs) => ["blockquote.i.f4.gray", ...xs], + blockquote: (...xs) => ["blockquote.pl3.bl.bw2.i.f4.gray", ...xs], code: (body) => ["code.bg-light-gray.pa1.f7", body], codeblock: (lang, body) => ["pre.bg-washed-yellow.pa3.f7", { lang }, ["code", body]], link: (href, body) => ["a.link.dark-blue.hover-white.hover-bg-dark-blue.b", { href }, body], diff --git a/examples/markdown/src/parser.ts b/examples/markdown/src/parser.ts index 0d7ff8f8b0..85f70399ab 100644 --- a/examples/markdown/src/parser.ts +++ b/examples/markdown/src/parser.ts @@ -163,8 +163,8 @@ export const parseMD = (tags?: Partial) => { alts( [ whitespace(() => [START]), - repeat(str("#"), 1, 10, title), - str("> ", (ctx) => transition(ctx, BLOCKQUOTE)), + repeat(str("#"), 1, Infinity, title), + str(">", (ctx) => transition(ctx, BLOCKQUOTE)), str("- ", newList(tags.list, "ul")), str("```", () => [START_CODEBLOCK]), str("---\n", () => [START, [["hr"]]]), @@ -196,7 +196,7 @@ export const parseMD = (tags?: Partial) => { alts( [ ...inline(BLOCKQUOTE), - str("> ", (ctx) => (ctx.children.push(ctx.body, ["br"]), ctx.body = "", [BLOCKQUOTE])), + str(">", (ctx) => (ctx.children.push(ctx.body, ["br"]), ctx.body = "", [BLOCKQUOTE])), str("\n", (ctx) => [START, [tags.blockquote(...ctx.children, ctx.body)]]), ], collect(BLOCKQUOTE) From 992f31acaad108711be54925cb4bc967dcaf82a5 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 4 Jan 2019 00:16:31 +0000 Subject: [PATCH 166/333] feat(fsm): add always(), lit(), not(), cleanup imports --- packages/fsm/src/always.ts | 8 ++++++++ packages/fsm/src/api.ts | 2 +- packages/fsm/src/fsm.ts | 7 ++++++- packages/fsm/src/index.ts | 4 ++++ packages/fsm/src/lit.ts | 26 ++++++++++++++++++++++++++ packages/fsm/src/not.ts | 17 +++++++++++++++++ packages/fsm/src/range.ts | 8 ++++---- packages/fsm/src/repeat.ts | 2 +- packages/fsm/src/str.ts | 4 ++-- packages/fsm/src/until.ts | 4 ++-- 10 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 packages/fsm/src/always.ts create mode 100644 packages/fsm/src/lit.ts create mode 100644 packages/fsm/src/not.ts diff --git a/packages/fsm/src/always.ts b/packages/fsm/src/always.ts new file mode 100644 index 0000000000..9d35b5e2b0 --- /dev/null +++ b/packages/fsm/src/always.ts @@ -0,0 +1,8 @@ +import { LitCallback, Matcher } from "./api"; +import { success } from "./success"; + +export const always = + (callback?: LitCallback): Matcher => + () => + (ctx, x) => + success(callback && callback(ctx, x)); diff --git a/packages/fsm/src/api.ts b/packages/fsm/src/api.ts index 734e939629..00262438ae 100644 --- a/packages/fsm/src/api.ts +++ b/packages/fsm/src/api.ts @@ -33,7 +33,7 @@ export type ResultBody = export type AltCallback = (ctx: C, next: ResultBody, x: T[]) => ResultBody; -export type RangeCallback = +export type LitCallback = (ctx: C, x: T) => ResultBody; export type SeqCallback = diff --git a/packages/fsm/src/fsm.ts b/packages/fsm/src/fsm.ts index 6c8a4b469a..72a026b6bf 100644 --- a/packages/fsm/src/fsm.ts +++ b/packages/fsm/src/fsm.ts @@ -2,7 +2,12 @@ import { IObjectOf } from "@thi.ng/api"; import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; import { illegalState } from "@thi.ng/errors/illegal-state"; import { Reducer, Transducer } from "@thi.ng/transducers/api"; -import { reduced, unreduced, isReduced, ensureReduced } from "@thi.ng/transducers/reduced"; +import { + ensureReduced, + isReduced, + reduced, + unreduced +} from "@thi.ng/transducers/reduced"; import { Match, Matcher } from "./api"; /** diff --git a/packages/fsm/src/index.ts b/packages/fsm/src/index.ts index 988a94c258..5f54365399 100644 --- a/packages/fsm/src/index.ts +++ b/packages/fsm/src/index.ts @@ -1,6 +1,10 @@ export * from "./api"; + export * from "./alts"; +export * from "./always"; export * from "./fsm"; +export * from "./lit"; +export * from "./not"; export * from "./range"; export * from "./repeat"; export * from "./seq"; diff --git a/packages/fsm/src/lit.ts b/packages/fsm/src/lit.ts new file mode 100644 index 0000000000..f93f127503 --- /dev/null +++ b/packages/fsm/src/lit.ts @@ -0,0 +1,26 @@ +import { Predicate2 } from "@thi.ng/api"; +import { equiv as _equiv } from "@thi.ng/equiv"; +import { + Matcher, + RES_FAIL, + RES_PARTIAL, + SeqCallback +} from "./api"; +import { success } from "./success"; + +export const lit = ( + match: T[], + callback?: SeqCallback, + equiv: Predicate2 = _equiv +): Matcher => + () => { + const buf: T[] = []; + const n = match.length; + let i = 0; + return (state, x) => + equiv((buf.push(x), x), match[i++]) ? + i === n ? + success(callback && callback(state, buf)) : + RES_PARTIAL : + RES_FAIL; + }; diff --git a/packages/fsm/src/not.ts b/packages/fsm/src/not.ts new file mode 100644 index 0000000000..d37e40ed09 --- /dev/null +++ b/packages/fsm/src/not.ts @@ -0,0 +1,17 @@ +import { Match, RES_FAIL, RES_PARTIAL, Matcher } from "./api"; +import { success } from "./success"; + +export const not = + (match: Matcher, callback?): Matcher => + () => { + let m = match(); + return (ctx, x) => { + const { type } = m(ctx, x); + return type === Match.FAIL ? + success(callback && callback(ctx)) : + type !== Match.PARTIAL ? + // TODO Match.FULL_NC handling? + RES_FAIL : + RES_PARTIAL; + } + }; diff --git a/packages/fsm/src/range.ts b/packages/fsm/src/range.ts index 91df2288a5..0a09ab5973 100644 --- a/packages/fsm/src/range.ts +++ b/packages/fsm/src/range.ts @@ -1,17 +1,17 @@ import { alts } from "./alts"; import { AltCallback, + LitCallback, Matcher, - RangeCallback, RES_FAIL } from "./api"; -import { success } from "./success"; import { str } from "./str"; +import { success } from "./success"; export const range = ( min: T, max: T, - callback?: RangeCallback + callback?: LitCallback ): Matcher => () => (ctx, x) => @@ -20,7 +20,7 @@ export const range = ( RES_FAIL; export const digit = - (callback?: RangeCallback): Matcher => + (callback?: LitCallback): Matcher => range("0", "9", callback); export const alpha = diff --git a/packages/fsm/src/repeat.ts b/packages/fsm/src/repeat.ts index 0d9b369b89..d213997b40 100644 --- a/packages/fsm/src/repeat.ts +++ b/packages/fsm/src/repeat.ts @@ -1,8 +1,8 @@ import { Match, Matcher, - SeqCallback, RES_PARTIAL, + SeqCallback } from "./api"; import { success } from "./success"; diff --git a/packages/fsm/src/str.ts b/packages/fsm/src/str.ts index 7c82f80f47..f9a877fd31 100644 --- a/packages/fsm/src/str.ts +++ b/packages/fsm/src/str.ts @@ -1,6 +1,6 @@ import { + LitCallback, Matcher, - RangeCallback, RES_FAIL, RES_PARTIAL } from "./api"; @@ -8,7 +8,7 @@ import { success } from "./success"; export const str = ( str: string, - callback?: RangeCallback + callback?: LitCallback ): Matcher => () => { let buf = ""; diff --git a/packages/fsm/src/until.ts b/packages/fsm/src/until.ts index a9baa9b07a..5c72cac697 100644 --- a/packages/fsm/src/until.ts +++ b/packages/fsm/src/until.ts @@ -1,9 +1,9 @@ -import { Matcher, RangeCallback, RES_PARTIAL } from "./api"; +import { LitCallback, Matcher, RES_PARTIAL } from "./api"; import { success } from "./success"; export const until = ( str: string, - callback?: RangeCallback + callback?: LitCallback ): Matcher => () => { let buf = ""; From 980d4888b1e9830f5b89eac0bd81cb8e3f06f784 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 4 Jan 2019 00:42:42 +0000 Subject: [PATCH 167/333] feat(examples): update MD parser, styles, readme --- examples/markdown/README.md | 14 ++++--- examples/markdown/index.html | 4 +- examples/markdown/src/index.ts | 4 +- examples/markdown/src/parser.ts | 72 +++++++++++++++++++++++---------- 4 files changed, 63 insertions(+), 31 deletions(-) diff --git a/examples/markdown/README.md b/examples/markdown/README.md index ad3765c32d..24e7082569 100644 --- a/examples/markdown/README.md +++ b/examples/markdown/README.md @@ -24,13 +24,14 @@ The parser itself is not aimed at supporting **all** of Markdown's quirky syntax features, but will restrict itself to a sane subset of features and already sports: -- headlines (level 1-6) +- ATX headlines (level 1-6, then downgrade to paragraph) - paragraphs - blockquotes - inline links - images - flat unordered lists -- inline formats (**bold**, _emphasis_, `code`, ~~strikethrough~~) in paragraphs & lists +- inline formats (**bold**, _emphasis_, `code`, ~~strikethrough~~) in + paragraphs, titles, lists, blockquotes - GFM code blocks with language hint - horizontal rules @@ -42,8 +43,8 @@ Other features - **Declarative:** parsing rules defined declaratively with only minimal state/context handling needed - **No regex:** consumes input character-wise and produces an iterator of hiccup-style tree nodes, ready to be used with [@thi.ng/hdom](https://github.com/thi-ng/umbrella/tree/master/packages/hdom), [@thi.ng/hiccup](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup) or [@thi.ng/hiccup-markdown](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup-markdown) (for back conversion to MD) - **Customizable:** supports custom tag factory functions to override default behavior / representation of each parsed result element -- **Fast (enough):** parses this markdown file in 2-3ms on MBP2016 / Chrome 71 -- **Small:** minified+gzipped ~3KB +- **Fast (enough):** parses this markdown file in ~3ms on MBP2016 / Chrome 71 +- **Small:** minified + gzipped ~3.3KB See [example source code](https://github.com/thi-ng/umbrella/tree/feature/fsm/examples/markdown/src/) @@ -54,6 +55,7 @@ for reference... These MD features (and probably many more) are not supported: - inline HTML +- nested inline formats (e.g. **bold** inside `code`) - inline formats within link labels - image links - footnotes @@ -103,11 +105,11 @@ interface TagFactories { paragraph(...children: any[]): any[]; strong(body: string): any[]; strike(body: string): any[]; - title(level: number, body: string): any[]; + title(level, ...children: any[]): any[]; } ``` -Example w/ custom link elements +Example with custom link elements: ```ts const tags = { diff --git a/examples/markdown/index.html b/examples/markdown/index.html index 84364d1aa0..3beebc571f 100644 --- a/examples/markdown/index.html +++ b/examples/markdown/index.html @@ -12,7 +12,7 @@ position: relative; } - pre[lang]:before { + pre[lang]::before { display: block; position: absolute; background-color: #fbf1a9; @@ -26,7 +26,7 @@ font-size: 80%; } - pre[lang]:before { + pre[lang]::before { content: attr(lang); text-transform: uppercase; } diff --git a/examples/markdown/src/index.ts b/examples/markdown/src/index.ts index e96a73b2d3..ac2fa99557 100644 --- a/examples/markdown/src/index.ts +++ b/examples/markdown/src/index.ts @@ -12,8 +12,8 @@ import readme from "../README.md"; // uses Tachyons CSS classes for styling const CUSTOM_TAGS: Partial = { blockquote: (...xs) => ["blockquote.pl3.bl.bw2.i.f4.gray", ...xs], - code: (body) => ["code.bg-light-gray.pa1.f7", body], - codeblock: (lang, body) => ["pre.bg-washed-yellow.pa3.f7", { lang }, ["code", body]], + code: (body) => ["code.bg-light-gray.ph1", body], + codeblock: (lang, body) => ["pre.bg-washed-yellow.pa3.f7.overflow-x-scroll", { lang: lang || "code" }, ["code", body]], link: (href, body) => ["a.link.dark-blue.hover-white.hover-bg-dark-blue.b", { href }, body], strike: (body) => ["del.bg-washed-red", body], }; diff --git a/examples/markdown/src/parser.ts b/examples/markdown/src/parser.ts index 85f70399ab..cfc89752a4 100644 --- a/examples/markdown/src/parser.ts +++ b/examples/markdown/src/parser.ts @@ -1,13 +1,12 @@ -import { - alts, - fsm, - repeat, - ResultBody, - seq, - str, - until, - whitespace -} from "@thi.ng/fsm"; +import { alts } from "@thi.ng/fsm/alts"; +import { ResultBody } from "@thi.ng/fsm/api"; +import { fsm } from "@thi.ng/fsm/fsm"; +import { not } from "@thi.ng/fsm/not"; +import { whitespace } from "@thi.ng/fsm/range"; +import { repeat } from "@thi.ng/fsm/repeat"; +import { seq } from "@thi.ng/fsm/seq"; +import { str } from "@thi.ng/fsm/str"; +import { until } from "@thi.ng/fsm/until"; // parse state IDs const BLOCKQUOTE = "blockquote"; @@ -17,6 +16,7 @@ const EMPHASIS = "em"; const END_BLOCKQUOTE = "end-blockquote"; const END_LI = "end-li"; const END_PARA = "end-para"; +const END_TITLE = "end-title"; const IMG = "img"; const LINK = "link"; const LI = "li"; @@ -40,7 +40,7 @@ export interface TagFactories { paragraph(...children: any[]): any[]; strong(body: string): any[]; strike(body: string): any[]; - title(level, body): any[]; + title(level, ...children: any[]): any[]; } // parse context @@ -74,6 +74,7 @@ const pop = const { id, children } = ctx.stack.pop(); children.push(result(ctx, body)); ctx.children = children; + ctx.body = ""; return [id]; }; @@ -82,13 +83,17 @@ const collect = (ctx, buf): ResultBody => (ctx.body += buf.join(""), [id]); +const collectList = + (ctx: FSMCtx, tag: (...xs: any[]) => any[]) => + ctx.list.push(tag(...ctx.children, ctx.body)); + const resultBody = (fn: (body: string) => any[]) => - (_, body: string) => fn(body.trim()); + (ctx, body: string) => fn(ctx.body + body.trim()); const title = (ctx: FSMCtx, body: string[]): ResultBody => - (ctx.hd = body.length, [TITLE]); + (ctx.hd = body.length, transition(ctx, TITLE)); const inline = (id: string) => [ @@ -118,6 +123,13 @@ const newPara = return transition(ctx, next); }; +const newParaCode = + (ctx: FSMCtx, x: string[]): ResultBody => { + ctx.body = x[1]; + ctx.stack.push({ id: PARA, children: [] }); + return [CODE]; + }; + const paragraph = (id: string, next: string) => alts( @@ -147,7 +159,7 @@ const DEFAULT_TAGS: TagFactories = { paragraph: (...xs) => ["p", ...xs], strong: (body) => ["strong", body], strike: (body) => ["del", body], - title: (level, body) => [level < 7 ? `h${level}` : "p", body], + title: (level, ...xs) => [level < 7 ? `h${level}` : "p", ...xs], }; /** @@ -166,7 +178,13 @@ export const parseMD = (tags?: Partial) => { repeat(str("#"), 1, Infinity, title), str(">", (ctx) => transition(ctx, BLOCKQUOTE)), str("- ", newList(tags.list, "ul")), - str("```", () => [START_CODEBLOCK]), + alts( + [ + seq([str("`"), not(str("`"))], newParaCode), + str("```", () => [START_CODEBLOCK]) + ], + null, (_, next) => next + ), str("---\n", () => [START, [["hr"]]]), str("![", newPara(IMG)), str("[", newPara(LINK)), @@ -203,7 +221,16 @@ export const parseMD = (tags?: Partial) => { ), [TITLE]: - until("\n\n", (ctx, body) => [START, [tags.title(ctx.hd, body)]]), + paragraph(TITLE, END_TITLE), + + [END_TITLE]: + alts( + [ + ...inline(TITLE), + str("\n", (ctx) => [START, [tags.title(ctx.hd, ...ctx.children, ctx.body)]]), + ], + collect(TITLE) + ), [START_CODEBLOCK]: until("\n", (ctx, lang) => (ctx.lang = lang, [CODEBLOCK])), @@ -218,16 +245,19 @@ export const parseMD = (tags?: Partial) => { alts( [ ...inline(LI), - str("\n", (ctx) => (ctx.list.push(tags.li(...ctx.children, ctx.body)), [END_LI])), + str("\n", () => [END_LI]), ], collect(LI) ), [END_LI]: - alts([ - str("\n", (ctx) => [START, [ctx.list]]), - str("- ", (ctx) => transition(ctx, LI)) - ]), + alts( + [ + str("\n", (ctx) => (collectList(ctx, tags.li), [START, [ctx.list]])), + str("- ", (ctx) => (collectList(ctx, tags.li), transition(ctx, LI))) + ], + (ctx, body) => (ctx.body += " " + body.join(""), [LI]) + ), [LINK]: link(tags.link), From a93360752c2d0a2db7f38ef06e4107792d948e0f Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 4 Jan 2019 04:16:49 +0000 Subject: [PATCH 168/333] feat(fsm): update not() --- packages/fsm/src/not.ts | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/packages/fsm/src/not.ts b/packages/fsm/src/not.ts index d37e40ed09..5f2b33391b 100644 --- a/packages/fsm/src/not.ts +++ b/packages/fsm/src/not.ts @@ -1,17 +1,21 @@ -import { Match, RES_FAIL, RES_PARTIAL, Matcher } from "./api"; +import { Match, RES_FAIL, RES_PARTIAL, Matcher, SeqCallback } from "./api"; import { success } from "./success"; -export const not = - (match: Matcher, callback?): Matcher => - () => { - let m = match(); - return (ctx, x) => { - const { type } = m(ctx, x); - return type === Match.FAIL ? - success(callback && callback(ctx)) : - type !== Match.PARTIAL ? - // TODO Match.FULL_NC handling? - RES_FAIL : - RES_PARTIAL; - } - }; +export const not = ( + match: Matcher, + callback?: SeqCallback +): Matcher => + () => { + let m = match(); + const buf: T[] = []; + return (ctx, x) => { + buf.push(x); + const { type } = m(ctx, x); + return type === Match.FAIL ? + success(callback && callback(ctx, buf)) : + type !== Match.PARTIAL ? + // TODO Match.FULL_NC handling? + RES_FAIL : + RES_PARTIAL; + } + }; From 9585b86e17899995dd4fb521184aa6ac21b6391b Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 4 Jan 2019 04:17:23 +0000 Subject: [PATCH 169/333] feat(examples): add initial MD table support --- examples/markdown/src/index.ts | 5 ++- examples/markdown/src/parser.ts | 67 +++++++++++++++++++++++++++++---- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/examples/markdown/src/index.ts b/examples/markdown/src/index.ts index ac2fa99557..6e853470c7 100644 --- a/examples/markdown/src/index.ts +++ b/examples/markdown/src/index.ts @@ -16,6 +16,9 @@ const CUSTOM_TAGS: Partial = { codeblock: (lang, body) => ["pre.bg-washed-yellow.pa3.f7.overflow-x-scroll", { lang: lang || "code" }, ["code", body]], link: (href, body) => ["a.link.dark-blue.hover-white.hover-bg-dark-blue.b", { href }, body], strike: (body) => ["del.bg-washed-red", body], + table: (x, _, ...xs) => ["table.w-100.collapse.ba.b--black-10", ["tbody", x, ...xs]], + tr: (_, ...xs) => ["tr.striped--near-white", ...xs], + td: (i, ...xs) => [i < 1 ? "th.pa2.ttu.tl" : "td.pa2", ...xs], }; // UI root component @@ -31,7 +34,7 @@ const app = } ]], ["div.w-100.h-50.w-50-l.vh-100-l.overflow-y-scroll.pa3.lh-copy", - ["div.pa2.bg-yellow.purple.f7", `Parsed in ${time}ms`], + ["div.pa2.bg-yellow.purple.f7", `Parsed ${src.length} chars in ${time}ms`], ...hiccup] ]; diff --git a/examples/markdown/src/parser.ts b/examples/markdown/src/parser.ts index cfc89752a4..e1f76ae678 100644 --- a/examples/markdown/src/parser.ts +++ b/examples/markdown/src/parser.ts @@ -9,6 +9,7 @@ import { str } from "@thi.ng/fsm/str"; import { until } from "@thi.ng/fsm/until"; // parse state IDs +// TODO use const enum once moved to own package const BLOCKQUOTE = "blockquote"; const CODE = "code"; const CODEBLOCK = "codeblock"; @@ -17,12 +18,14 @@ const END_BLOCKQUOTE = "end-blockquote"; const END_LI = "end-li"; const END_PARA = "end-para"; const END_TITLE = "end-title"; +const END_TABLE = "end-table"; const IMG = "img"; const LINK = "link"; const LI = "li"; const PARA = "para"; const START = "start"; const START_CODEBLOCK = "start-codeblock"; +const TABLE = "table"; const STRIKE = "strike"; const STRONG = "strong"; const TITLE = "title"; @@ -41,12 +44,15 @@ export interface TagFactories { strong(body: string): any[]; strike(body: string): any[]; title(level, ...children: any[]): any[]; + table(...rows: any[]): any[]; + tr(i: number, ...cells: any[]): any[]; + td(i: number, ...children: any[]): any[]; } // parse context interface FSMCtx { stack: any[]; - list?: any[]; + container?: any[]; children?: any[]; body?: string; title?: string; @@ -80,12 +86,28 @@ const pop = const collect = (id: string) => - (ctx, buf): ResultBody => + (ctx: FSMCtx, buf: string[]): ResultBody => (ctx.body += buf.join(""), [id]); const collectList = (ctx: FSMCtx, tag: (...xs: any[]) => any[]) => - ctx.list.push(tag(...ctx.children, ctx.body)); + ctx.container.push(tag(...ctx.children, ctx.body)); + +const collectTD = + (tag: (i: number, ...xs: any[]) => any[]) => + (ctx: FSMCtx) => ( + ctx.container.push(tag(ctx.stack[ctx.stack.length - 1].container.length, ...ctx.children, ctx.body)), + transition(ctx, TABLE) + ); + +const collectTR = + (tag: (i: number, ...xs: any[]) => any[]) => + (ctx: FSMCtx) => { + const rows = ctx.stack[ctx.stack.length - 1].container; + rows.push(tag(rows.length, ...ctx.container)); + ctx.container = []; + return transition(ctx, END_TABLE); + }; const resultBody = (fn: (body: string) => any[]) => @@ -142,10 +164,17 @@ const paragraph = const newList = (factory: (type: string) => any[], type: string) => - (ctx: FSMCtx): ResultBody => { - ctx.list = factory(type); - return transition(ctx, LI); - }; + (ctx: FSMCtx): ResultBody => ( + ctx.container = factory(type), + transition(ctx, LI) + ); + +const newTable = + (ctx: FSMCtx) => ( + ctx.stack.push({ id: TABLE, container: [] }), + ctx.container = [], + transition(ctx, TABLE) + ); const DEFAULT_TAGS: TagFactories = { blockquote: (...xs) => ["blockquote", ...xs], @@ -160,6 +189,9 @@ const DEFAULT_TAGS: TagFactories = { strong: (body) => ["strong", body], strike: (body) => ["del", body], title: (level, ...xs) => [level < 7 ? `h${level}` : "p", ...xs], + table: () => ["table"], + tr: (...xs) => ["tr", ...xs], + td: (...xs) => ["td", ...xs], }; /** @@ -191,6 +223,7 @@ export const parseMD = (tags?: Partial) => { str("**", newPara(STRONG)), str("~~", newPara(STRIKE)), str("_", newPara(EMPHASIS)), + str("|", newTable), ], (ctx, buf) => (ctx.body = buf.join(""), ctx.children = [], [PARA]), ), @@ -253,7 +286,7 @@ export const parseMD = (tags?: Partial) => { [END_LI]: alts( [ - str("\n", (ctx) => (collectList(ctx, tags.li), [START, [ctx.list]])), + str("\n", (ctx) => (collectList(ctx, tags.li), [START, [ctx.container]])), str("- ", (ctx) => (collectList(ctx, tags.li), transition(ctx, LI))) ], (ctx, body) => (ctx.body += " " + body.join(""), [LI]) @@ -276,6 +309,24 @@ export const parseMD = (tags?: Partial) => { [CODE]: until("`", pop(resultBody(tags.code))), + + [TABLE]: + alts( + [ + ...inline(TABLE), + str("|", collectTD(tags.td)), + str("\n", collectTR(tags.tr)) + ], + collect(TABLE) + ), + + [END_TABLE]: + alts( + [ + str("\n", (ctx) => [START, [tags.table(...ctx.stack.pop().container)]]), + str("|", () => [TABLE]) + ], + ) }, { stack: [] From b60bf31a3337763d080dcaed6bc2ef1880cb08ea Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 4 Jan 2019 15:37:01 +0000 Subject: [PATCH 170/333] refactor(examples): cleanup parser & rules, tag handling, update readme --- examples/markdown/README.md | 80 +++++---- examples/markdown/package.json | 1 + examples/markdown/src/index.ts | 8 +- examples/markdown/src/parser.ts | 295 +++++++++++++++++++------------- 4 files changed, 225 insertions(+), 159 deletions(-) diff --git a/examples/markdown/README.md b/examples/markdown/README.md index 24e7082569..f97cfdfd11 100644 --- a/examples/markdown/README.md +++ b/examples/markdown/README.md @@ -24,47 +24,59 @@ The parser itself is not aimed at supporting **all** of Markdown's quirky syntax features, but will restrict itself to a sane subset of features and already sports: -- ATX headlines (level 1-6, then downgrade to paragraph) -- paragraphs -- blockquotes -- inline links -- images -- flat unordered lists -- inline formats (**bold**, _emphasis_, `code`, ~~strikethrough~~) in - paragraphs, titles, lists, blockquotes -- GFM code blocks with language hint -- horizontal rules - ---- - -Other features - -- **Functional:** parser entirely built using [transducers](https://github.com/thi-ng/umbrella/tree/master/packages/transducers) & function composition. Use the parser in a transducer pipeline to easily apply post-processing of the emitted results -- **Declarative:** parsing rules defined declaratively with only minimal state/context handling needed -- **No regex:** consumes input character-wise and produces an iterator of hiccup-style tree nodes, ready to be used with [@thi.ng/hdom](https://github.com/thi-ng/umbrella/tree/master/packages/hdom), [@thi.ng/hiccup](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup) or [@thi.ng/hiccup-markdown](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup-markdown) (for back conversion to MD) -- **Customizable:** supports custom tag factory functions to override default behavior / representation of each parsed result element -- **Fast (enough):** parses this markdown file in ~3ms on MBP2016 / Chrome 71 -- **Small:** minified + gzipped ~3.3KB - -See [example source -code](https://github.com/thi-ng/umbrella/tree/feature/fsm/examples/markdown/src/) -for reference... +| Feature | Comments | +|-------------|-----------------------------------------------------------------------------------------------------| +| Heading | ATX only (`#` line prefix), levels 1-6, then downgrade to paragraph | +| Paragraph | no support for `\` line breaks | +| Blockquote | Respects newlines | +| Format | **bold**, _emphasis_, `code`, ~~strikethrough~~ in paragraphs, headings, lists, blockquotes, tables | +| Link | no support for inline formats in label | +| Image | no image links | +| List | only unordered (`- ` line prefix), no nesting, supports line breaks | +| Table | no support for column alignment | +| Code block | GFM only (triple backtick prefix), w/ optional language hint | +| Horiz. Rule | only dash supported (e.g. `---`), min 3 chars required | + +Note: Currently, the last heading, paragraph, blockquote, list or table requires an additional newline. ### Limitations -These MD features (and probably many more) are not supported: +These MD features (and probably many more) are **not** supported: - inline HTML -- nested inline formats (e.g. **bold** inside `code`) +- nested inline formats (e.g. **bold** inside _italic_) - inline formats within link labels - image links - footnotes - link references - nested / ordered / numbered / todo lists -- tables Some of these are considered, though currently not high priority... +### Other features + +- **Functional:** parser entirely built using + [transducers](https://github.com/thi-ng/umbrella/tree/master/packages/transducers) + & function composition. Use the parser in a transducer pipeline to + easily apply post-processing of the emitted results +- **Declarative:** parsing rules defined declaratively with only minimal + state/context handling needed +- **No regex:** consumes input character-wise and produces an iterator + of hiccup-style tree nodes, ready to be used with + [@thi.ng/hdom](https://github.com/thi-ng/umbrella/tree/master/packages/hdom), + [@thi.ng/hiccup](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup) + or + [@thi.ng/hiccup-markdown](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup-markdown) + (for back conversion to MD) +- **Customizable:** supports custom tag factory functions to override + default behavior / representation of each parsed result element +- **Fast (enough):** parses this markdown file (5.8KB) in ~5ms on MBP2016 / Chrome 71 +- **Small:** minified + gzipped ~2.6KB + +See [example source +code](https://github.com/thi-ng/umbrella/tree/feature/fsm/examples/markdown/src/) +for reference... + ## Serializing to HTML ```ts @@ -100,12 +112,16 @@ interface TagFactories { em(body: string): any[]; img(src: string, alt: string): any[]; link(href: string, body: string): any[]; - list(type: string): any[]; - li(...children: any[]): any[]; - paragraph(...children: any[]): any[]; + list(type: string, items: any[]): any[]; + li(children: any[]): any[]; + paragraph(children: any[]): any[]; strong(body: string): any[]; strike(body: string): any[]; - title(level, ...children: any[]): any[]; + title(level, children: any[]): any[]; + table(rows: any[]): any[]; + tr(i: number, cells: any[]): any[]; + td(i: number, children: any[]): any[]; + hr(): any[]; } ``` diff --git a/examples/markdown/package.json b/examples/markdown/package.json index b7e873bc4c..426edcd267 100644 --- a/examples/markdown/package.json +++ b/examples/markdown/package.json @@ -7,6 +7,7 @@ "scripts": { "clean": "rm -rf .cache build out", "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --detailed-report", + "build-parser": "yarn clean && parcel build src/parser.ts -d out --global md --public-url ./ --no-source-maps --no-cache --detailed-report --experimental-scope-hoisting", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/markdown/src/index.ts b/examples/markdown/src/index.ts index 6e853470c7..790591a484 100644 --- a/examples/markdown/src/index.ts +++ b/examples/markdown/src/index.ts @@ -11,14 +11,14 @@ import readme from "../README.md"; // custom tag factories (passed to parser) // uses Tachyons CSS classes for styling const CUSTOM_TAGS: Partial = { - blockquote: (...xs) => ["blockquote.pl3.bl.bw2.i.f4.gray", ...xs], + blockquote: (xs) => ["blockquote.pl3.bl.bw2.i.f4.gray", ...xs], code: (body) => ["code.bg-light-gray.ph1", body], codeblock: (lang, body) => ["pre.bg-washed-yellow.pa3.f7.overflow-x-scroll", { lang: lang || "code" }, ["code", body]], link: (href, body) => ["a.link.dark-blue.hover-white.hover-bg-dark-blue.b", { href }, body], strike: (body) => ["del.bg-washed-red", body], - table: (x, _, ...xs) => ["table.w-100.collapse.ba.b--black-10", ["tbody", x, ...xs]], - tr: (_, ...xs) => ["tr.striped--near-white", ...xs], - td: (i, ...xs) => [i < 1 ? "th.pa2.ttu.tl" : "td.pa2", ...xs], + table: ([x, _, ...xs]) => ["table.w-100.collapse.ba.b--black-10", ["tbody", x, ...xs]], + tr: (_, xs) => ["tr.striped--near-white", ...xs], + td: (i, xs) => [i < 1 ? "th.pa2.ttu.tl" : "td.pa2", ...xs], }; // UI root component diff --git a/examples/markdown/src/parser.ts b/examples/markdown/src/parser.ts index e1f76ae678..3b18eb63a1 100644 --- a/examples/markdown/src/parser.ts +++ b/examples/markdown/src/parser.ts @@ -7,6 +7,7 @@ import { repeat } from "@thi.ng/fsm/repeat"; import { seq } from "@thi.ng/fsm/seq"; import { str } from "@thi.ng/fsm/str"; import { until } from "@thi.ng/fsm/until"; +import { peek } from "@thi.ng/transducers/func/peek"; // parse state IDs // TODO use const enum once moved to own package @@ -30,6 +31,18 @@ const STRIKE = "strike"; const STRONG = "strong"; const TITLE = "title"; +// parse context +interface FSMCtx { + stack: any[]; + container?: any[]; + children?: any[]; + body?: string; + title?: string; + href?: string; + lang?: string; + hd?: number; +} + // hiccup element factories export interface TagFactories { blockquote(...children: any[]): any[]; @@ -38,41 +51,52 @@ export interface TagFactories { em(body: string): any[]; img(src: string, alt: string): any[]; link(href: string, body: string): any[]; - list(type: string): any[]; - li(...children: any[]): any[]; - paragraph(...children: any[]): any[]; + list(type: string, items: any[]): any[]; + li(children: any[]): any[]; + paragraph(children: any[]): any[]; strong(body: string): any[]; strike(body: string): any[]; - title(level, ...children: any[]): any[]; - table(...rows: any[]): any[]; - tr(i: number, ...cells: any[]): any[]; - td(i: number, ...children: any[]): any[]; + title(level, children: any[]): any[]; + table(rows: any[]): any[]; + tr(i: number, cells: any[]): any[]; + td(i: number, children: any[]): any[]; + hr(): any[]; } -// parse context -interface FSMCtx { - stack: any[]; - container?: any[]; - children?: any[]; - body?: string; - title?: string; - href?: string; - lang?: string; - hd?: number; -} +const DEFAULT_TAGS: TagFactories = { + blockquote: (...xs) => ["blockquote", ...xs], + code: (body) => ["code", body], + codeblock: (lang, body) => ["pre", { lang }, body], + em: (body) => ["em", body], + img: (src, alt) => ["img", { src, alt }], + li: (xs: any[]) => ["li", ...xs], + link: (href, body) => ["a", { href }, body], + list: (type, xs) => [type, ...xs], + paragraph: (xs) => ["p", ...xs], + strong: (body) => ["strong", body], + strike: (body) => ["del", body], + title: (level, xs) => [level < 7 ? `h${level}` : "p", ...xs], + table: (rows) => ["table", ...rows], + tr: (_, xs) => ["tr", ...xs], + td: (_, xs) => ["td", ...xs], + hr: () => ["hr"], +}; // state / context handling helpers const transition = - (ctx: FSMCtx, id: string): ResultBody => - (ctx.children = [], ctx.body = "", [id]); + (ctx: FSMCtx, id: string): ResultBody => ( + ctx.children = [], + ctx.body = "", + [id] + ); const push = - (curr: string, next: string) => - (ctx: FSMCtx): ResultBody => { - ctx.stack.push({ id: curr, children: [...ctx.children, ctx.body] }); - return transition(ctx, next); - }; + (id: string, next: string) => + (ctx: FSMCtx): ResultBody => ( + ctx.stack.push({ id, children: ctx.children.concat(ctx.body) }), + transition(ctx, next) + ); const pop = (result) => @@ -84,40 +108,83 @@ const pop = return [id]; }; +const collectChildren = + (ctx: FSMCtx) => (ctx.children.push(ctx.body), ctx.children); + const collect = (id: string) => - (ctx: FSMCtx, buf: string[]): ResultBody => - (ctx.body += buf.join(""), [id]); + (ctx: FSMCtx, buf: string[]): ResultBody => ( + ctx.body += buf.join(""), + [id] + ); + +const collectHeading = + (tag: (i: number, xs: any[]) => any[]) => + (ctx) => [START, [tag(ctx.hd, collectChildren(ctx))]]; + +const collectAndRestart = + (tag: (xs: any[]) => any[]) => + (ctx) => [START, [tag(collectChildren(ctx))]]; -const collectList = - (ctx: FSMCtx, tag: (...xs: any[]) => any[]) => - ctx.container.push(tag(...ctx.children, ctx.body)); +const collectBlockQuote = + (ctx) => ( + ctx.children.push(ctx.body, ["br"]), + ctx.body = "", + [BLOCKQUOTE] + ); + +const collectCodeBlock = + (tag: (lang: string, body: string) => any[]) => + (ctx, body) => [START, [tag(ctx.lang, body)]]; + +const collectLi = + (ctx: FSMCtx, tag: (xs: any[]) => any[]) => + ctx.container.push(tag(collectChildren(ctx))); + +const collectList = ( + type: string, + list: (type: string, xs: any[]) => any[], + item: (xs: any[]) => any[] +) => + (ctx) => ( + collectLi(ctx, item), + [START, [list(type, ctx.container)]] + ); const collectTD = - (tag: (i: number, ...xs: any[]) => any[]) => + (tag: (i: number, xs: any[]) => any[]) => (ctx: FSMCtx) => ( - ctx.container.push(tag(ctx.stack[ctx.stack.length - 1].container.length, ...ctx.children, ctx.body)), + ctx.children.push(ctx.body), + ctx.container.push( + tag(peek(ctx.stack).container.length, ctx.children) + ), transition(ctx, TABLE) ); const collectTR = - (tag: (i: number, ...xs: any[]) => any[]) => + (tag: (i: number, xs: any[]) => any[]) => (ctx: FSMCtx) => { - const rows = ctx.stack[ctx.stack.length - 1].container; - rows.push(tag(rows.length, ...ctx.container)); + const rows = peek(ctx.stack).container; + rows.push(tag(rows.length, ctx.container)); ctx.container = []; return transition(ctx, END_TABLE); }; -const resultBody = +const collectTable = + (tag: (xs: any[]) => any) => + (ctx) => [START, [tag(ctx.stack.pop().container)]]; + +const collectInline = (fn: (body: string) => any[]) => - (ctx, body: string) => fn(ctx.body + body.trim()); + pop((ctx, body: string) => fn(ctx.body + body.trim())); const title = - (ctx: FSMCtx, body: string[]): ResultBody => - (ctx.hd = body.length, transition(ctx, TITLE)); + (ctx: FSMCtx, body: string[]): ResultBody => ( + ctx.hd = body.length, + transition(ctx, TITLE) + ); -const inline = +const matchInline = (id: string) => [ str("![", push(id, IMG)), str("[", push(id, LINK)), @@ -127,7 +194,7 @@ const inline = str("`", push(id, CODE)) ]; -const link = +const matchLink = (result: (href, body) => any[]) => seq( [ @@ -138,37 +205,43 @@ const link = pop((ctx) => result(ctx.href, ctx.title)) ); -const newPara = - (next: string) => - (ctx: FSMCtx): ResultBody => { - ctx.stack.push({ id: PARA, children: [] }); - return transition(ctx, next); - }; - -const newParaCode = - (ctx: FSMCtx, x: string[]): ResultBody => { - ctx.body = x[1]; - ctx.stack.push({ id: PARA, children: [] }); - return [CODE]; - }; - -const paragraph = +const matchPara = (id: string, next: string) => - alts( + alts( [ - ...inline(id), + ...matchInline(id), str("\n", (ctx: FSMCtx) => (ctx.body += " ", [next])), ], collect(id), ); -const newList = - (factory: (type: string) => any[], type: string) => +const newPara = + (ctx: FSMCtx, buf: string[]): ResultBody => ( + ctx.body = buf.join(""), + ctx.children = [], + [PARA] + ); + +const newParaInline = + (next: string) => (ctx: FSMCtx): ResultBody => ( - ctx.container = factory(type), - transition(ctx, LI) + ctx.stack.push({ id: PARA, children: [] }), + transition(ctx, next) ); +const newParaCode = + (ctx: FSMCtx, x: string[]): ResultBody => ( + ctx.body = x[1], + ctx.stack.push({ id: PARA, children: [] }), + [CODE] + ); + +const newList = + (ctx: FSMCtx): ResultBody => ( + ctx.container = [], + transition(ctx, LI) + ); + const newTable = (ctx: FSMCtx) => ( ctx.stack.push({ id: TABLE, container: [] }), @@ -176,28 +249,10 @@ const newTable = transition(ctx, TABLE) ); -const DEFAULT_TAGS: TagFactories = { - blockquote: (...xs) => ["blockquote", ...xs], - code: (body) => ["code", body], - codeblock: (lang, body) => ["pre", { lang }, body], - em: (body) => ["em", body], - img: (src, alt) => ["img", { src, alt }], - li: (...xs: any[]) => ["li", ...xs], - link: (href, body) => ["a", { href }, body], - list: (type) => [type], - paragraph: (...xs) => ["p", ...xs], - strong: (body) => ["strong", body], - strike: (body) => ["del", body], - title: (level, ...xs) => [level < 7 ? `h${level}` : "p", ...xs], - table: () => ["table"], - tr: (...xs) => ["tr", ...xs], - td: (...xs) => ["td", ...xs], -}; - /** - * Main parser / transducer. Defines state map with various matchers and - * transition handlers. The returned parser itself is only used in - * `index.ts`. + * Main parser / transducer. Defines state map with the various Markdown + * syntax matchers and state transition handlers. The returned parser + * itself is only used in `index.ts`. */ export const parseMD = (tags?: Partial) => { tags = { ...DEFAULT_TAGS, ...tags }; @@ -209,7 +264,7 @@ export const parseMD = (tags?: Partial) => { whitespace(() => [START]), repeat(str("#"), 1, Infinity, title), str(">", (ctx) => transition(ctx, BLOCKQUOTE)), - str("- ", newList(tags.list, "ul")), + str("- ", newList), alts( [ seq([str("`"), not(str("`"))], newParaCode), @@ -217,50 +272,53 @@ export const parseMD = (tags?: Partial) => { ], null, (_, next) => next ), - str("---\n", () => [START, [["hr"]]]), - str("![", newPara(IMG)), - str("[", newPara(LINK)), - str("**", newPara(STRONG)), - str("~~", newPara(STRIKE)), - str("_", newPara(EMPHASIS)), + seq( + [repeat(str("-"), 3, Infinity), str("\n")], + () => [START, [tags.hr()]] + ), + str("![", newParaInline(IMG)), + str("[", newParaInline(LINK)), + str("**", newParaInline(STRONG)), + str("~~", newParaInline(STRIKE)), + str("_", newParaInline(EMPHASIS)), str("|", newTable), ], - (ctx, buf) => (ctx.body = buf.join(""), ctx.children = [], [PARA]), + newPara, ), [PARA]: - paragraph(PARA, END_PARA), + matchPara(PARA, END_PARA), [END_PARA]: alts( [ - ...inline(PARA), - str("\n", (ctx) => [START, [tags.paragraph(...ctx.children, ctx.body)]]), + ...matchInline(PARA), + str("\n", collectAndRestart(tags.paragraph)), ], collect(PARA) ), [BLOCKQUOTE]: - paragraph(BLOCKQUOTE, END_BLOCKQUOTE), + matchPara(BLOCKQUOTE, END_BLOCKQUOTE), [END_BLOCKQUOTE]: alts( [ - ...inline(BLOCKQUOTE), - str(">", (ctx) => (ctx.children.push(ctx.body, ["br"]), ctx.body = "", [BLOCKQUOTE])), - str("\n", (ctx) => [START, [tags.blockquote(...ctx.children, ctx.body)]]), + ...matchInline(BLOCKQUOTE), + str(">", collectBlockQuote), + str("\n", collectAndRestart(tags.blockquote)), ], collect(BLOCKQUOTE) ), [TITLE]: - paragraph(TITLE, END_TITLE), + matchPara(TITLE, END_TITLE), [END_TITLE]: alts( [ - ...inline(TITLE), - str("\n", (ctx) => [START, [tags.title(ctx.hd, ...ctx.children, ctx.body)]]), + ...matchInline(TITLE), + str("\n", collectHeading(tags.title)), ], collect(TITLE) ), @@ -269,51 +327,42 @@ export const parseMD = (tags?: Partial) => { until("\n", (ctx, lang) => (ctx.lang = lang, [CODEBLOCK])), [CODEBLOCK]: - until( - "\n```\n", - (ctx, body) => [START, [tags.codeblock(ctx.lang, body)]] - ), + until("\n```\n", collectCodeBlock(tags.codeblock)), [LI]: - alts( - [ - ...inline(LI), - str("\n", () => [END_LI]), - ], - collect(LI) - ), + matchPara(LI, END_LI), [END_LI]: alts( [ - str("\n", (ctx) => (collectList(ctx, tags.li), [START, [ctx.container]])), - str("- ", (ctx) => (collectList(ctx, tags.li), transition(ctx, LI))) + str("\n", collectList("ul", tags.list, tags.li)), + str("- ", (ctx) => (collectLi(ctx, tags.li), transition(ctx, LI))) ], - (ctx, body) => (ctx.body += " " + body.join(""), [LI]) + collect(LI) ), [LINK]: - link(tags.link), + matchLink(tags.link), [IMG]: - link(tags.img), + matchLink(tags.img), [STRONG]: - until("**", pop(resultBody(tags.strong))), + until("**", collectInline(tags.strong)), [STRIKE]: - until("~~", pop(resultBody(tags.strike))), + until("~~", collectInline(tags.strike)), [EMPHASIS]: - until("_", pop(resultBody(tags.em))), + until("_", collectInline(tags.em)), [CODE]: - until("`", pop(resultBody(tags.code))), + until("`", collectInline(tags.code)), [TABLE]: alts( [ - ...inline(TABLE), + ...matchInline(TABLE), str("|", collectTD(tags.td)), str("\n", collectTR(tags.tr)) ], @@ -323,7 +372,7 @@ export const parseMD = (tags?: Partial) => { [END_TABLE]: alts( [ - str("\n", (ctx) => [START, [tags.table(...ctx.stack.pop().container)]]), + str("\n", collectTable(tags.table)), str("|", () => [TABLE]) ], ) From 120a7afd93f60d9a693684051ecc1056bc97e6db Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 4 Jan 2019 15:50:47 +0000 Subject: [PATCH 171/333] refactor(examples): remove 2nd table row in collectTable() --- examples/markdown/src/index.ts | 2 +- examples/markdown/src/parser.ts | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/markdown/src/index.ts b/examples/markdown/src/index.ts index 790591a484..2d99046ef6 100644 --- a/examples/markdown/src/index.ts +++ b/examples/markdown/src/index.ts @@ -16,7 +16,7 @@ const CUSTOM_TAGS: Partial = { codeblock: (lang, body) => ["pre.bg-washed-yellow.pa3.f7.overflow-x-scroll", { lang: lang || "code" }, ["code", body]], link: (href, body) => ["a.link.dark-blue.hover-white.hover-bg-dark-blue.b", { href }, body], strike: (body) => ["del.bg-washed-red", body], - table: ([x, _, ...xs]) => ["table.w-100.collapse.ba.b--black-10", ["tbody", x, ...xs]], + table: (xs) => ["table.w-100.collapse.ba.b--black-10", ["tbody", ...xs]], tr: (_, xs) => ["tr.striped--near-white", ...xs], td: (i, xs) => [i < 1 ? "th.pa2.ttu.tl" : "td.pa2", ...xs], }; diff --git a/examples/markdown/src/parser.ts b/examples/markdown/src/parser.ts index 3b18eb63a1..7624587597 100644 --- a/examples/markdown/src/parser.ts +++ b/examples/markdown/src/parser.ts @@ -172,7 +172,11 @@ const collectTR = const collectTable = (tag: (xs: any[]) => any) => - (ctx) => [START, [tag(ctx.stack.pop().container)]]; + (ctx) => { + const rows = ctx.stack.pop().container; + rows.splice(1, 1); + return [START, [tag(rows)]]; + }; const collectInline = (fn: (body: string) => any[]) => From 297356dd880e6dc1c40f49c321034c161fecb19e Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 4 Jan 2019 15:54:48 +0000 Subject: [PATCH 172/333] docs(examples): update readme --- examples/markdown/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/markdown/README.md b/examples/markdown/README.md index f97cfdfd11..ac7be3d695 100644 --- a/examples/markdown/README.md +++ b/examples/markdown/README.md @@ -143,6 +143,7 @@ serialize(iterator(parseMD(tags), src)); ```bash git clone https://github.com/thi-ng/umbrella.git cd umbrella +git checkout feature/fsm # first build all packages in mono repo (takes about 1-2mins) yarn install From 81e3fc799327551f05d370c02d3617bca3772631 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 4 Jan 2019 16:51:59 +0000 Subject: [PATCH 173/333] feat(fsm): add never(), optimize alts(), add docs for all matchers --- packages/fsm/src/alts.ts | 28 ++++++++++++------- packages/fsm/src/always.ts | 10 +++++-- packages/fsm/src/api.ts | 5 +++- packages/fsm/src/index.ts | 1 + packages/fsm/src/lit.ts | 4 +-- packages/fsm/src/never.ts | 12 ++++++++ packages/fsm/src/not.ts | 21 ++++++++++++-- packages/fsm/src/range.ts | 32 ++++++++++++++++++++-- packages/fsm/src/repeat.ts | 16 +++++++++-- packages/fsm/src/{success.ts => result.ts} | 2 +- packages/fsm/src/seq.ts | 22 ++++++++++----- packages/fsm/src/str.ts | 11 ++++++-- packages/fsm/src/until.ts | 13 +++++++-- 13 files changed, 142 insertions(+), 35 deletions(-) create mode 100644 packages/fsm/src/never.ts rename packages/fsm/src/{success.ts => result.ts} (86%) diff --git a/packages/fsm/src/alts.ts b/packages/fsm/src/alts.ts index 69c8f19e92..13fcdddb41 100644 --- a/packages/fsm/src/alts.ts +++ b/packages/fsm/src/alts.ts @@ -1,11 +1,13 @@ import { Match, Matcher, + MatcherInst, + MatchResult, RES_FAIL, RES_PARTIAL, ResultBody } from "./api"; -import { success } from "./success"; +import { result } from "./result"; /** * Returns a composed matcher which applies inputs to all given child @@ -13,10 +15,13 @@ import { success } from "./success"; * a full match. If successful, calls `callback` with the context, the * child matcher's result and an array of all processed inputs thus far. * The result of `alts` is the result of this callback (else undefined). - * Matchers are always processed in reverse order. * - * If none of the matchers succeeded the optional `fallback` callback - * will be executed and given a chance to produce a state transition. + * Note: Matchers are always processed in reverse order, therefore + * attention must be paid to the given ordering of supplied matchers. + * + * If none of the matchers succeed the optional `fallback` callback will + * be executed and given a chance to produce a state transition. It too + * will be given an array of all processed inputs thus far. * * @param opts * @param fallback @@ -30,22 +35,25 @@ export const alts = ( () => { const alts = opts.map((o) => o()); const buf: T[] = []; + let active = alts.length; return (ctx, x) => { - for (let i = alts.length; --i >= 0;) { - const next = alts[i](ctx, x); + for (let i = alts.length, a: MatcherInst, next: MatchResult; --i >= 0;) { + if (!(a = alts[i])) continue; + next = a(ctx, x); if (next.type >= Match.FULL) { return callback ? - success(callback(ctx, next.body, buf), next.type) : + result(callback(ctx, next.body, buf), next.type) : next; } else if (next.type === Match.FAIL) { - alts.splice(i, 1); + alts[i] = null; + active--; } } fallback && buf.push(x); - return alts.length ? + return active ? RES_PARTIAL : fallback ? - success(fallback(ctx, buf)) : + result(fallback(ctx, buf)) : RES_FAIL; }; }; diff --git a/packages/fsm/src/always.ts b/packages/fsm/src/always.ts index 9d35b5e2b0..dd674cd853 100644 --- a/packages/fsm/src/always.ts +++ b/packages/fsm/src/always.ts @@ -1,8 +1,14 @@ import { LitCallback, Matcher } from "./api"; -import { success } from "./success"; +import { result } from "./result"; +/** + * Returns a matcher which always succeeds (produces a `Match.FULL` result) for + * any given input. Use `never()` for the opposite effect. + * + * @param callback + */ export const always = (callback?: LitCallback): Matcher => () => (ctx, x) => - success(callback && callback(ctx, x)); + result(callback && callback(ctx, x)); diff --git a/packages/fsm/src/api.ts b/packages/fsm/src/api.ts index 00262438ae..67383fa3af 100644 --- a/packages/fsm/src/api.ts +++ b/packages/fsm/src/api.ts @@ -25,7 +25,10 @@ export interface MatchResult { } export type Matcher = - () => (ctx: C, x: T) => MatchResult; + () => MatcherInst; + +export type MatcherInst = + (ctx: C, x: T) => MatchResult; export type ResultBody = [number | string, T[]?]; diff --git a/packages/fsm/src/index.ts b/packages/fsm/src/index.ts index 5f54365399..498b4322bd 100644 --- a/packages/fsm/src/index.ts +++ b/packages/fsm/src/index.ts @@ -4,6 +4,7 @@ export * from "./alts"; export * from "./always"; export * from "./fsm"; export * from "./lit"; +export * from "./never"; export * from "./not"; export * from "./range"; export * from "./repeat"; diff --git a/packages/fsm/src/lit.ts b/packages/fsm/src/lit.ts index f93f127503..8145f56235 100644 --- a/packages/fsm/src/lit.ts +++ b/packages/fsm/src/lit.ts @@ -6,7 +6,7 @@ import { RES_PARTIAL, SeqCallback } from "./api"; -import { success } from "./success"; +import { result } from "./result"; export const lit = ( match: T[], @@ -20,7 +20,7 @@ export const lit = ( return (state, x) => equiv((buf.push(x), x), match[i++]) ? i === n ? - success(callback && callback(state, buf)) : + result(callback && callback(state, buf)) : RES_PARTIAL : RES_FAIL; }; diff --git a/packages/fsm/src/never.ts b/packages/fsm/src/never.ts new file mode 100644 index 0000000000..df9707421f --- /dev/null +++ b/packages/fsm/src/never.ts @@ -0,0 +1,12 @@ +import { LitCallback, Match, Matcher } from "./api"; +import { result } from "./result"; + +/** + * Returns a matcher which always fails (produces a `Match.FAIL` result) + * for any given input. Use `always()` for the opposite effect. + */ +export const never = + (callback?: LitCallback): Matcher => + () => + (ctx, x) => + result(callback && callback(ctx, x), Match.FAIL); diff --git a/packages/fsm/src/not.ts b/packages/fsm/src/not.ts index 5f2b33391b..4de741ef4f 100644 --- a/packages/fsm/src/not.ts +++ b/packages/fsm/src/not.ts @@ -1,6 +1,21 @@ -import { Match, RES_FAIL, RES_PARTIAL, Matcher, SeqCallback } from "./api"; -import { success } from "./success"; +import { + Match, + Matcher, + RES_FAIL, + RES_PARTIAL, + SeqCallback +} from "./api"; +import { result } from "./result"; +/** + * Takes an existing matcher `match` and returns new matcher which + * inverts the result of `match`. I.e. If `match` returns `Match.FULL`, + * the new matcher returns `Match.FAIL` and vice versa. `Match.PARTIAL` + * results remain as is. + * + * @param match + * @param callback + */ export const not = ( match: Matcher, callback?: SeqCallback @@ -12,7 +27,7 @@ export const not = ( buf.push(x); const { type } = m(ctx, x); return type === Match.FAIL ? - success(callback && callback(ctx, buf)) : + result(callback && callback(ctx, buf)) : type !== Match.PARTIAL ? // TODO Match.FULL_NC handling? RES_FAIL : diff --git a/packages/fsm/src/range.ts b/packages/fsm/src/range.ts index 0a09ab5973..800dd34345 100644 --- a/packages/fsm/src/range.ts +++ b/packages/fsm/src/range.ts @@ -5,9 +5,17 @@ import { Matcher, RES_FAIL } from "./api"; +import { result } from "./result"; import { str } from "./str"; -import { success } from "./success"; +/** + * Returns a single input matcher which returns `Match.FULL` if the + * input is within the closed interval given by [`min`,`max`]. + * + * @param min + * @param max + * @param callback + */ export const range = ( min: T, max: T, @@ -16,13 +24,23 @@ export const range = ( () => (ctx, x) => x >= min && x <= max ? - success(callback && callback(ctx, x)) : + result(callback && callback(ctx, x)) : RES_FAIL; +/** + * Matcher for single digit characters (0-9). + * + * @param callback + */ export const digit = (callback?: LitCallback): Matcher => range("0", "9", callback); +/** + * Matcher for single A-Z or a-z characters. + * + * @param callback + */ export const alpha = (callback?: AltCallback): Matcher => alts( @@ -31,6 +49,11 @@ export const alpha = callback ); +/** + * Combination of `digit()` and `alpha()`. + * + * @param callback + */ export const alphaNum = (callback?: AltCallback): Matcher => alts([alpha(), digit()], null, callback); @@ -38,6 +61,11 @@ export const alphaNum = const WS: Matcher[] = [str("\r"), str("\n"), str("\t"), str(" ")]; +/** + * Matcher for single whitespace characters. + * + * @param callback + */ export const whitespace = (callback?: AltCallback): Matcher => alts(WS, null, callback); diff --git a/packages/fsm/src/repeat.ts b/packages/fsm/src/repeat.ts index d213997b40..bfe6d62c88 100644 --- a/packages/fsm/src/repeat.ts +++ b/packages/fsm/src/repeat.ts @@ -4,8 +4,18 @@ import { RES_PARTIAL, SeqCallback } from "./api"; -import { success } from "./success"; +import { result } from "./result"; +/** + * Takes a matcher and `min` / `max` repeats. Returns new matcher which + * only returns `Match.FULL` if `match` succeeded at least `min` times + * or once `max` repetitions have been found. + * + * @param match + * @param min + * @param max + * @param callback + */ export const repeat = ( match: Matcher, min: number, @@ -22,14 +32,14 @@ export const repeat = ( if (r.type === Match.FULL) { i++; if (i === max) { - return success(callback && callback(ctx, buf)); + return result(callback && callback(ctx, buf)); } m = match(); return RES_PARTIAL; } else if (r.type === Match.FAIL) { if (i >= min) { buf.pop(); - return success(callback && callback(ctx, buf), Match.FULL_NC); + return result(callback && callback(ctx, buf), Match.FULL_NC); } } return r; diff --git a/packages/fsm/src/success.ts b/packages/fsm/src/result.ts similarity index 86% rename from packages/fsm/src/success.ts rename to packages/fsm/src/result.ts index 6e456d0b6d..d61db87611 100644 --- a/packages/fsm/src/success.ts +++ b/packages/fsm/src/result.ts @@ -1,5 +1,5 @@ import { Match, MatchResult, ResultBody } from "./api"; -export const success = +export const result = (body: ResultBody, type = Match.FULL): MatchResult => ({ type, body }); diff --git a/packages/fsm/src/seq.ts b/packages/fsm/src/seq.ts index 44f54bede1..dc2ee4cc9c 100644 --- a/packages/fsm/src/seq.ts +++ b/packages/fsm/src/seq.ts @@ -5,27 +5,35 @@ import { RES_PARTIAL, SeqCallback } from "./api"; -import { success } from "./success"; +import { result } from "./result"; +/** + * Takes an array of matchers and returns new matcher which applies them + * in sequence. If any of the given matchers fails, returns + * `Match.FAIL`. + * + * @param matches + * @param callback + */ export const seq = ( - opts: Matcher[], + matches: Matcher[], callback?: SeqCallback ): Matcher => () => { let i = 0; - let o = opts[i](); - const n = opts.length - 1; + let m = matches[i](); + const n = matches.length - 1; const buf: T[] = []; return (state, x) => { if (i > n) return RES_FAIL; callback && buf.push(x); while (i <= n) { - const { type } = o(state, x); + const { type } = m(state, x); if (type >= Match.FULL) { if (i === n) { - return success(callback && callback(state, buf)); + return result(callback && callback(state, buf)); } - o = opts[++i](); + m = matches[++i](); if (type === Match.FULL_NC) { continue; } diff --git a/packages/fsm/src/str.ts b/packages/fsm/src/str.ts index f9a877fd31..017994ac92 100644 --- a/packages/fsm/src/str.ts +++ b/packages/fsm/src/str.ts @@ -4,8 +4,15 @@ import { RES_FAIL, RES_PARTIAL } from "./api"; -import { success } from "./success"; +import { result } from "./result"; +/** + * String-only version of `seq()`. Returns `Match.FULL` once the entire + * given string could be matched. + * + * @param str + * @param callback + */ export const str = ( str: string, callback?: LitCallback @@ -14,7 +21,7 @@ export const str = ( let buf = ""; return (state, x) => (buf += x) === str ? - success(callback && callback(state, buf)) : + result(callback && callback(state, buf)) : str.indexOf(buf) === 0 ? RES_PARTIAL : RES_FAIL; diff --git a/packages/fsm/src/until.ts b/packages/fsm/src/until.ts index 5c72cac697..5f1588c632 100644 --- a/packages/fsm/src/until.ts +++ b/packages/fsm/src/until.ts @@ -1,6 +1,15 @@ import { LitCallback, Matcher, RES_PARTIAL } from "./api"; -import { success } from "./success"; +import { result } from "./result"; +/** + * String only. Returns a matcher which consumes input until the given + * string could be matched. If successful, calls `callback` with string + * recorded so far (excluding the matched terminator string) and returns + * `Match.FULL` result. Else `Match.PARTIAL`. + * + * @param str + * @param callback + */ export const until = ( str: string, callback?: LitCallback @@ -10,7 +19,7 @@ export const until = ( return (ctx, x) => { buf += x; return buf.endsWith(str) ? - success(callback && callback(ctx, buf.substr(0, buf.length - str.length))) : + result(callback && callback(ctx, buf.substr(0, buf.length - str.length))) : RES_PARTIAL; }; }; From 0a505c1a69275bb9199cfd8e731f21e38228bb27 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 4 Jan 2019 17:16:37 +0000 Subject: [PATCH 174/333] docs(fsm): update readme & package --- packages/fsm/README.md | 43 +++++++++++++++++++++++++++++++++++---- packages/fsm/package.json | 13 +++++++++++- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/packages/fsm/README.md b/packages/fsm/README.md index ba67ade7f1..db34868138 100644 --- a/packages/fsm/README.md +++ b/packages/fsm/README.md @@ -14,6 +14,9 @@ This project is part of the - [Installation](#installation) - [Dependencies](#dependencies) - [Usage examples](#usage-examples) +- [API](#api) + - [Matchers](#matchers) + - [FSM transducer](#fsm-transducer) - [Authors](#authors) - [License](#license) @@ -21,16 +24,20 @@ This project is part of the ## About -Primitives for building transducer based Finite-State machines and -parsers (not necessarily text based). +Functional & composable primitives for building declarative, +[transducer](https://github.com/thi-ng/umbrella/tree/master/packages/transducers) +based Finite-State machines and parsers for arbitrary input data streams +(not necessarily string based). See the [minimal markdown parser -example](https://github.com/thi-ng/umbrella/tree/feature/fsm/examples/markdown) +example](https://github.com/thi-ng/umbrella/tree/master/examples/markdown) for a concrete use case. ## Status -ALPHA. +**ALPHA**. This package will be merged with and update the existing +[@thi.ng/transducers-fsm](https://github.com/thi-ng/umbrella/tree/master/packages/transducers-fsm) +package. ## Installation @@ -41,6 +48,7 @@ yarn add @thi.ng/fsm ## Dependencies - [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/master/packages/api) +- [@thi.ng/equiv](https://github.com/thi-ng/umbrella/tree/master/packages/equiv) - [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/master/packages/errors) - [@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/master/packages/transducers) @@ -50,6 +58,33 @@ yarn add @thi.ng/fsm import * as fsm from "@thi.ng/fsm"; ``` +## API + +There're two key concepts provided by this package: + +### Matchers + +Matchers are composable functions which receive a single input value and +attempt to match it to their configured criteria / patterns. Matchers +also support optional user callbacks, which are executed when a match +was made and are responsible for state transitions, state update and +production of any result values. + +### FSM transducer + +The `fsm()` function returns a Finite-state machine transducer w/ +support for single lookahead value. It takes an object of `states` and +their matchers, an arbitrary context object which will be uses as state +container for the various matchers and an `initial` state ID. + +The returned transducer consumes inputs of type `T` and produces results +of type `R`. The results are produced by callbacks of the given state +matchers. For each input consumed, the callbacks can produce any number +of result values. If a callback returns a result wrapped w/ `reduced()`, +the FSM causes early termination of the overall transducer pipeline. + +See docs strings in `/src` folder for now. + ## Authors - Karsten Schmidt diff --git a/packages/fsm/package.json b/packages/fsm/package.json index b38fc5ad46..171fafc1cf 100644 --- a/packages/fsm/package.json +++ b/packages/fsm/package.json @@ -1,7 +1,7 @@ { "name": "@thi.ng/fsm", "version": "0.0.1", - "description": "TODO", + "description": "Composable primitives for building declarative, transducer based Finite-State machines & parsers for arbitrary data streams", "main": "./index.js", "typings": "./index.d.ts", "repository": { @@ -29,11 +29,22 @@ }, "dependencies": { "@thi.ng/api": "^4.2.4", + "@thi.ng/equiv": "^0.1.15", "@thi.ng/errors": "^0.1.12", "@thi.ng/transducers": "^2.3.2" }, "keywords": [ "ES6", + "composition", + "declarative", + "finite state machine", + "FSM", + "functional", + "parser", + "pattern match", + "regex", + "string", + "transducers", "typescript" ], "publishConfig": { From 17c14b49407a998f2f081c0ba18ecd6e78611e63 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 4 Jan 2019 17:18:24 +0000 Subject: [PATCH 175/333] docs(examples): update readmes --- examples/README.md | 1 + examples/markdown/README.md | 25 ++++++++++++++----------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/examples/README.md b/examples/README.md index 2472d69dad..4b6a41c28e 100644 --- a/examples/README.md +++ b/examples/README.md @@ -32,6 +32,7 @@ If you want to [contribute](../CONTRIBUTING.md) an example, please get in touch | 24 | [json-components](./json-components) | JSON->component transformation, live editor | hdom, transducers | intermediate | | 25 | [login-form](./login-form) | Basic SPA without router | atom, hdom | intermediate | | 26 | [mandelbrot](./mandelbrot) | Worker-based mandelbrot fractal renderer | rstream, rstream-gestures, transducers-hdom | advanced | +| 26 | [markdown](./markdown) | Markdown parser & editor w/ live preview | fsm, rstream, transducers-hdom | advanced | | 27 | [pointfree-svg](./pointfree-svg) | Generate SVG using pointfree DSL | hiccup, hiccup-svg, pointfree-lang | intermediate | | 28 | [router-basics](./router-basics) | Complete mini SPA | atom, hdom, interceptors, router | advanced | | 29 | [rstream-dataflow](./rstream-dataflow) | Dataflow graph | atom, hdom, rstream, rstream-gestures, rstream-graph, transducers | intermediate | diff --git a/examples/markdown/README.md b/examples/markdown/README.md index ac7be3d695..e8376e70e4 100644 --- a/examples/markdown/README.md +++ b/examples/markdown/README.md @@ -9,8 +9,8 @@ This example is a test environment for a new & minimal [Markdown](https://en.wikipedia.org/wiki/Markdown) parser & converter to [hiccup](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup) format, using basic state handling and parsing primitives provided by -the (still unreleased) -[@thi.ng/fsm](https://github.com/thi-ng/umbrella/tree/feature/fsm/packages/fsm) +the +[@thi.ng/fsm](https://github.com/thi-ng/umbrella/tree/master/packages/fsm) package, which itself is a potential replacement / major version update for [@thi.ng/transducers-fsm](https://github.com/thi-ng/umbrella/tree/master/packages/transducers-fsm). @@ -74,7 +74,7 @@ Some of these are considered, though currently not high priority... - **Small:** minified + gzipped ~2.6KB See [example source -code](https://github.com/thi-ng/umbrella/tree/feature/fsm/examples/markdown/src/) +code](https://github.com/thi-ng/umbrella/tree/master/examples/markdown/src/) for reference... ## Serializing to HTML @@ -92,6 +92,16 @@ const src = ` `; +// convert to hiccup tree +[...iterator(parseMD(), src)] +// [ [ 'h1', ' Hello world ' ], +// [ 'p', +// [ 'a', { href: 'http://example.com' }, 'This' ], +// ' is a ', +// [ 'em', 'test' ], +// '. ' ] ] + +// or serialize to HTML serialize(iterator(parseMD(), src)); //

Hello world

@@ -142,15 +152,8 @@ serialize(iterator(parseMD(tags), src)); ```bash git clone https://github.com/thi-ng/umbrella.git -cd umbrella -git checkout feature/fsm - -# first build all packages in mono repo (takes about 1-2mins) +cd umbrella/examples/markdown yarn install -yarn build - -# then launch example -cd examples/markdown yarn start ``` From 492992d7f7a15b532ced687948f6ccbd8035bb82 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 4 Jan 2019 17:30:14 +0000 Subject: [PATCH 176/333] docs: update package list in main readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0f88dbcd57..7ce484c56c 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,7 @@ packages) in the [examples](./examples) directory. | Project | Version | Changelog | Description | |-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------|----------------------------------| | [`@thi.ng/csp`](./packages/csp) | [![version](https://img.shields.io/npm/v/@thi.ng/csp.svg)](https://www.npmjs.com/package/@thi.ng/csp) | [changelog](./packages/csp/CHANGELOG.md) | Channel based async ops | +| [`@thi.ng/fsm`](./packages/fsm) | [![version](https://img.shields.io/npm/v/@thi.ng/fsm.svg)](https://www.npmjs.com/package/@thi.ng/fsm) | [changelog](./packages/fsm/CHANGELOG.md) | FSM / parser primitives | | [`@thi.ng/iterators`](./packages/iterators) | [![version](https://img.shields.io/npm/v/@thi.ng/iterators.svg)](https://www.npmjs.com/package/@thi.ng/iterators) | [changelog](./packages/iterators/CHANGELOG.md) | ES6 generators / iterators | | [`@thi.ng/sax`](./packages/sax) | [![version](https://img.shields.io/npm/v/@thi.ng/sax.svg)](https://www.npmjs.com/package/@thi.ng/sax) | [changelog](./packages/sax/CHANGELOG.md) | SAX-like XML parser / transducer | | [`@thi.ng/transducers`](./packages/transducers) | [![version](https://img.shields.io/npm/v/@thi.ng/transducers.svg)](https://www.npmjs.com/package/@thi.ng/transducers) | [changelog](./packages/transducers/CHANGELOG.md) | Composable data transformations | From 6030753ab98acdac5d1a19bd8a4ce5f2cf863406 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 4 Jan 2019 17:30:28 +0000 Subject: [PATCH 177/333] Publish - @thi.ng/fsm@0.1.0 --- packages/fsm/CHANGELOG.md | 16 ++++++++++++++++ packages/fsm/package.json | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 packages/fsm/CHANGELOG.md diff --git a/packages/fsm/CHANGELOG.md b/packages/fsm/CHANGELOG.md new file mode 100644 index 0000000000..423ac08263 --- /dev/null +++ b/packages/fsm/CHANGELOG.md @@ -0,0 +1,16 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# 0.1.0 (2019-01-04) + + +### Features + +* **fsm:** add always(), lit(), not(), cleanup imports ([992f31a](https://github.com/thi-ng/umbrella/commit/992f31a)) +* **fsm:** add never(), optimize alts(), add docs for all matchers ([81e3fc7](https://github.com/thi-ng/umbrella/commit/81e3fc7)) +* **fsm:** add repeat(), success(), refactor all matchers ([55671fc](https://github.com/thi-ng/umbrella/commit/55671fc)) +* **fsm:** add support for lookahead-1, add docs ([4a9bb3d](https://github.com/thi-ng/umbrella/commit/4a9bb3d)) +* **fsm:** import fsm package ([e03390b](https://github.com/thi-ng/umbrella/commit/e03390b)) +* **fsm:** update not() ([a933607](https://github.com/thi-ng/umbrella/commit/a933607)) diff --git a/packages/fsm/package.json b/packages/fsm/package.json index 171fafc1cf..1889a22628 100644 --- a/packages/fsm/package.json +++ b/packages/fsm/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/fsm", - "version": "0.0.1", + "version": "0.1.0", "description": "Composable primitives for building declarative, transducer based Finite-State machines & parsers for arbitrary data streams", "main": "./index.js", "typings": "./index.d.ts", @@ -50,4 +50,4 @@ "publishConfig": { "access": "public" } -} \ No newline at end of file +} From 5f09d3ecbaec11ec29634b0c9b8b953716a8100a Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 4 Jan 2019 20:07:30 +0000 Subject: [PATCH 178/333] fix(examples): add missing return types --- examples/markdown/src/parser.ts | 39 ++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/examples/markdown/src/parser.ts b/examples/markdown/src/parser.ts index 7624587597..fe0d883164 100644 --- a/examples/markdown/src/parser.ts +++ b/examples/markdown/src/parser.ts @@ -31,6 +31,8 @@ const STRIKE = "strike"; const STRONG = "strong"; const TITLE = "title"; +type ParseResult = ResultBody; + // parse context interface FSMCtx { stack: any[]; @@ -85,7 +87,7 @@ const DEFAULT_TAGS: TagFactories = { // state / context handling helpers const transition = - (ctx: FSMCtx, id: string): ResultBody => ( + (ctx: FSMCtx, id: string): ParseResult => ( ctx.children = [], ctx.body = "", [id] @@ -93,14 +95,14 @@ const transition = const push = (id: string, next: string) => - (ctx: FSMCtx): ResultBody => ( + (ctx: FSMCtx): ParseResult => ( ctx.stack.push({ id, children: ctx.children.concat(ctx.body) }), transition(ctx, next) ); const pop = (result) => - (ctx, body): ResultBody => { + (ctx, body): ParseResult => { const { id, children } = ctx.stack.pop(); children.push(result(ctx, body)); ctx.children = children; @@ -113,21 +115,23 @@ const collectChildren = const collect = (id: string) => - (ctx: FSMCtx, buf: string[]): ResultBody => ( + (ctx: FSMCtx, buf: string[]): ParseResult => ( ctx.body += buf.join(""), [id] ); const collectHeading = (tag: (i: number, xs: any[]) => any[]) => - (ctx) => [START, [tag(ctx.hd, collectChildren(ctx))]]; + (ctx): ParseResult => + [START, [tag(ctx.hd, collectChildren(ctx))]]; const collectAndRestart = (tag: (xs: any[]) => any[]) => - (ctx) => [START, [tag(collectChildren(ctx))]]; + (ctx): ParseResult => + [START, [tag(collectChildren(ctx))]]; const collectBlockQuote = - (ctx) => ( + (ctx): ParseResult => ( ctx.children.push(ctx.body, ["br"]), ctx.body = "", [BLOCKQUOTE] @@ -135,7 +139,8 @@ const collectBlockQuote = const collectCodeBlock = (tag: (lang: string, body: string) => any[]) => - (ctx, body) => [START, [tag(ctx.lang, body)]]; + (ctx, body): ParseResult => + [START, [tag(ctx.lang, body)]]; const collectLi = (ctx: FSMCtx, tag: (xs: any[]) => any[]) => @@ -146,7 +151,7 @@ const collectList = ( list: (type: string, xs: any[]) => any[], item: (xs: any[]) => any[] ) => - (ctx) => ( + (ctx): ParseResult => ( collectLi(ctx, item), [START, [list(type, ctx.container)]] ); @@ -172,7 +177,7 @@ const collectTR = const collectTable = (tag: (xs: any[]) => any) => - (ctx) => { + (ctx): ParseResult => { const rows = ctx.stack.pop().container; rows.splice(1, 1); return [START, [tag(rows)]]; @@ -183,7 +188,7 @@ const collectInline = pop((ctx, body: string) => fn(ctx.body + body.trim())); const title = - (ctx: FSMCtx, body: string[]): ResultBody => ( + (ctx: FSMCtx, body: string[]): ParseResult => ( ctx.hd = body.length, transition(ctx, TITLE) ); @@ -220,7 +225,7 @@ const matchPara = ); const newPara = - (ctx: FSMCtx, buf: string[]): ResultBody => ( + (ctx: FSMCtx, buf: string[]): ParseResult => ( ctx.body = buf.join(""), ctx.children = [], [PARA] @@ -228,20 +233,20 @@ const newPara = const newParaInline = (next: string) => - (ctx: FSMCtx): ResultBody => ( + (ctx: FSMCtx): ParseResult => ( ctx.stack.push({ id: PARA, children: [] }), transition(ctx, next) ); const newParaCode = - (ctx: FSMCtx, x: string[]): ResultBody => ( + (ctx: FSMCtx, x: string[]): ParseResult => ( ctx.body = x[1], ctx.stack.push({ id: PARA, children: [] }), [CODE] ); const newList = - (ctx: FSMCtx): ResultBody => ( + (ctx: FSMCtx): ParseResult => ( ctx.container = [], transition(ctx, LI) ); @@ -381,9 +386,7 @@ export const parseMD = (tags?: Partial) => { ], ) }, - { - stack: [] - }, + { stack: [] }, START ); }; From 35db07fee79b3ac83e9083a8b0f6d811cb5a5fba Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 4 Jan 2019 22:11:21 +0000 Subject: [PATCH 179/333] feat(hiccup-markdown): add & refactor markdown parser (from example), update docs --- packages/hiccup-markdown/README.md | 196 +++++++++-- packages/hiccup-markdown/package.json | 9 +- packages/hiccup-markdown/src/api.ts | 18 + packages/hiccup-markdown/src/index.ts | 154 +-------- packages/hiccup-markdown/src/parse.ts | 400 ++++++++++++++++++++++ packages/hiccup-markdown/src/serialize.ts | 152 ++++++++ packages/hiccup-markdown/tsconfig.json | 5 +- 7 files changed, 752 insertions(+), 182 deletions(-) create mode 100644 packages/hiccup-markdown/src/api.ts create mode 100644 packages/hiccup-markdown/src/parse.ts create mode 100644 packages/hiccup-markdown/src/serialize.ts diff --git a/packages/hiccup-markdown/README.md b/packages/hiccup-markdown/README.md index c06acd7117..54231c5e5a 100644 --- a/packages/hiccup-markdown/README.md +++ b/packages/hiccup-markdown/README.md @@ -10,10 +10,18 @@ This project is part of the - [About](#about) - - [Behaviors](#behaviors) - [Installation](#installation) - [Dependencies](#dependencies) -- [Usage examples](#usage-examples) +- [Parser](#parser) + - [Features](#features) + - [Limitations](#limitations) + - [Other parser features](#other-parser-features) + - [Serializing to HTML](#serializing-to-html) + - [Customizing tags](#customizing-tags) +- [Serializer](#serializer) + - [Features](#features-1) + - [Behaviors](#behaviors) + - [Usage examples](#usage-examples) - [Authors](#authors) - [License](#license) @@ -21,12 +29,161 @@ This project is part of the ## About -This package provides an extensible serializer of HTML-ish -[@thi.ng/hiccup](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup) -trees to Markdown format. Currently supports most standard (applicable) -Markdown features: +This package provides both a customizable +[Markdown](https://en.wikipedia.org/wiki/Markdown)-to-[Hiccup](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup) +parser and an extensible Hiccup-to-Markdown serializer. + +## Installation + +```bash +yarn add @thi.ng/hiccup-markdown +``` + +## Dependencies + +- [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/master/packages/checks) +- [@thi.ng/defmulti](https://github.com/thi-ng/umbrella/tree/master/packages/defmulti) +- [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/master/packages/errors) +- [@thi.ng/fsm](https://github.com/thi-ng/umbrella/tree/master/packages/fsm) +- [@thi.ng/hiccup](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup) +- [@thi.ng/strings](https://github.com/thi-ng/umbrella/tree/master/packages/strings) + +## Parser + +### Features + +The parser itself is not aimed at supporting **all** of Markdown's +quirky syntax features, but restricts itself to a sane subset of +features: + +| Feature | Comments | +|-------------|-----------------------------------------------------------------------------------------------------| +| Heading | ATX only (`#` line prefix), levels 1-6, then downgrade to paragraph | +| Paragraph | no support for `\` line breaks | +| Blockquote | Respects newlines | +| Format | **bold**, _emphasis_, `code`, ~~strikethrough~~ in paragraphs, headings, lists, blockquotes, tables | +| Link | no support for inline formats in label | +| Image | no image links | +| List | only unordered (`- ` line prefix), no nesting, supports line breaks | +| Table | no support for column alignment | +| Code block | GFM only (triple backtick prefix), w/ optional language hint | +| Horiz. Rule | only dash supported (e.g. `---`), min 3 chars required | + +Note: Currently, the last heading, paragraph, blockquote, list or table requires an additional newline. + +### Limitations + +These MD features (and probably many more) are **not** supported: + +- inline HTML +- nested inline formats (e.g. **bold** inside _italic_) +- inline formats within link labels +- image links +- footnotes +- link references +- nested / ordered / numbered / todo lists + +Some of these are considered, though currently not high priority... Pull +requests are welcome, though! + +### Other parser features + +- **Functional:** parser entirely built using + [transducers](https://github.com/thi-ng/umbrella/tree/master/packages/transducers) + & function composition. Use the parser in a transducer pipeline to + easily apply post-processing of the emitted results +- **Declarative:** parsing rules defined declaratively with only minimal + state/context handling needed +- **No regex:** consumes input character-wise and produces an iterator + of hiccup-style tree nodes, ready to be used with + [@thi.ng/hdom](https://github.com/thi-ng/umbrella/tree/master/packages/hdom), + [@thi.ng/hiccup](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup) + or the serializer of this package for back conversion to MD +- **Customizable:** supports custom tag factory functions to override + default behavior / representation of each parsed result element +- **Fast (enough):** parses this markdown file (5.8KB) in ~5ms on MBP2016 / Chrome 71 +- **Small:** minified + gzipped ~2.6KB (parser sub-module incl. deps) + +### Serializing to HTML + +```ts +import { iterator } from "@thi.ng/transducers"; +import { serialize } from "@thi.ng/hiccup"; + +import { parse } from "@thi.ng/hiccup-markdown/parse"; + +const src = ` +# Hello world + +[This](http://example.com) is a _test_. + +`; + +// convert to hiccup tree +[...iterator(parse(), src)] +// [ [ 'h1', ' Hello world ' ], +// [ 'p', +// [ 'a', { href: 'http://example.com' }, 'This' ], +// ' is a ', +// [ 'em', 'test' ], +// '. ' ] ] + +// or serialize to HTML +serialize(iterator(parse(), src)); + +//

Hello world

+// This is a test.

+``` + +### Customizing tags -- Headings (level 1-6) +The following interface defines factory functions for all supported +elements. User implementations / overrides can be given to the +`parse()` transducer to customize output. + +```ts +interface TagFactories { + blockquote(...children: any[]): any[]; + code(body: string): any[]; + codeblock(lang: string, body: string): any[]; + em(body: string): any[]; + heading(level, children: any[]): any[]; + hr(): any[]; + img(src: string, alt: string): any[]; + li(children: any[]): any[]; + link(href: string, body: string): any[]; + list(type: string, items: any[]): any[]; + paragraph(children: any[]): any[]; + strike(body: string): any[]; + strong(body: string): any[]; + table(rows: any[]): any[]; + td(i: number, children: any[]): any[]; + tr(i: number, cells: any[]): any[]; +} +``` + +Example with custom link elements: + +```ts +const tags = { + link: (href, body) => ["a.link.blue", { href }, body] +}; + +serialize(iterator(parse(tags), src)); + +//

Hello world

+//

This is a test.

+``` + +## Serializer + +For the reverse operation, the `serialize()` function can be used to +convert an hiccup component tree into Markdown. Currently supports most +standard (applicable) Markdown features: + +### Features + +- ATX-style headings (level 1-6) - Paragraphs - Forced line breaks - Inline styles: strong, italic, code @@ -47,9 +204,10 @@ Not (yet) supported: ### Behaviors -- Unless needed for serialization, all other element attribs are ignored -- Code blocks are always output in GFM w/ optional language hint (via - `lang` attrib) +- Unless needed for serialization, all other hiccup element attribs are + ignored +- Code blocks are always output in GFM flavor w/ optional language hint + (via `lang` attrib) - Images use the optional `alt` attrib as label - Forced line breaks are realized via `["br"]` elements in the hiccup tree @@ -61,24 +219,10 @@ implementation to the exported `serializeElement` [multi-method](https://github.com/thi-ng/umbrella/tree/master/packages/defmulti). See source code for reference. -## Installation - -```bash -yarn add @thi.ng/hiccup-markdown -``` - -## Dependencies - -- [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/master/packages/checks) -- [@thi.ng/defmulti](https://github.com/thi-ng/umbrella/tree/master/packages/defmulti) -- [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/master/packages/errors) -- [@thi.ng/hiccup](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup) -- [@thi.ng/strings](https://github.com/thi-ng/umbrella/tree/master/packages/strings) - -## Usage examples +### Usage examples ```ts -import { serialize } from "@thi.ng/hiccup-markdown"; +import { serialize } from "@thi.ng/hiccup-markdown/serialize"; // list component // the 1st arg is the optional user context object diff --git a/packages/hiccup-markdown/package.json b/packages/hiccup-markdown/package.json index fac4c405c5..8b17228da4 100644 --- a/packages/hiccup-markdown/package.json +++ b/packages/hiccup-markdown/package.json @@ -31,19 +31,24 @@ "@thi.ng/checks": "^1.5.14", "@thi.ng/defmulti": "^0.7.0", "@thi.ng/errors": "^0.1.12", + "@thi.ng/fsm": "^0.1.0", "@thi.ng/hiccup": "^2.7.2", - "@thi.ng/strings": "^0.7.1" + "@thi.ng/strings": "^0.7.1", + "@thi.ng/transducers": "^2.3.2" }, "keywords": [ "ES6", + "ast", "converter", "DOM", "hiccup", "markdown", + "parser", "serialize", + "transducers", "typescript" ], "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/hiccup-markdown/src/api.ts b/packages/hiccup-markdown/src/api.ts new file mode 100644 index 0000000000..5a016f90c9 --- /dev/null +++ b/packages/hiccup-markdown/src/api.ts @@ -0,0 +1,18 @@ +export interface TagFactories { + blockquote(...children: any[]): any[]; + code(body: string): any[]; + codeblock(lang: string, body: string): any[]; + em(body: string): any[]; + heading(level, children: any[]): any[]; + hr(): any[]; + img(src: string, alt: string): any[]; + li(children: any[]): any[]; + link(href: string, body: string): any[]; + list(type: string, items: any[]): any[]; + paragraph(children: any[]): any[]; + strike(body: string): any[]; + strong(body: string): any[]; + table(rows: any[]): any[]; + td(i: number, children: any[]): any[]; + tr(i: number, cells: any[]): any[]; +} diff --git a/packages/hiccup-markdown/src/index.ts b/packages/hiccup-markdown/src/index.ts index 397bf0ebb3..96dd664954 100644 --- a/packages/hiccup-markdown/src/index.ts +++ b/packages/hiccup-markdown/src/index.ts @@ -1,152 +1,2 @@ -import { implementsFunction } from "@thi.ng/checks/implements-function"; -import { isFunction } from "@thi.ng/checks/is-function"; -import { isNotStringAndIterable } from "@thi.ng/checks/is-not-string-iterable"; -import { isString } from "@thi.ng/checks/is-string"; -import { DEFAULT, defmulti, MultiFn3 } from "@thi.ng/defmulti"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { normalize } from "@thi.ng/hiccup/serialize"; -import { repeat } from "@thi.ng/strings/repeat"; -import { wrap } from "@thi.ng/strings/wrap"; - -export const serialize = (tree: any, ctx) => - _serialize(tree, ctx, { indent: 0, sep: "" }); - -const _serialize = (tree: any, ctx, state) => { - if (tree == null) return ""; - if (Array.isArray(tree)) { - if (!tree.length) { - return ""; - } - let tag = tree[0]; - if (isFunction(tag)) { - return _serialize(tag.apply(null, [ctx, ...tree.slice(1)]), ctx, state); - } - if (implementsFunction(tag, "render")) { - return _serialize(tag.render.apply(null, [ctx, ...tree.slice(1)]), ctx, state); - } - if (isString(tag)) { - tree = normalize(tree); - const attribs = tree[1]; - if (attribs.__skip || attribs.__serialize === false) { - return ""; - } - tag = tree[0]; - return serializeElement(tree, ctx, state); - } - if (isNotStringAndIterable(tree)) { - return serializeIter(tree, ctx, state); - } - illegalArgs(`invalid tree node: ${tree}`); - } - if (isFunction(tree)) { - return _serialize(tree(ctx), ctx, state); - } - if (implementsFunction(tree, "toHiccup")) { - return _serialize(tree.toHiccup(ctx), ctx, state); - } - if (implementsFunction(tree, "deref")) { - return _serialize(tree.deref(), ctx, state); - } - if (isNotStringAndIterable(tree)) { - return serializeIter(tree, ctx, state); - } - return tree.toString(); -}; - -const serializeIter = ( - iter: Iterable, - ctx: any, - state: any -) => { - if (!iter) return ""; - const res = []; - for (let i of iter) { - res.push(_serialize(i, ctx, state)); - } - return res.join(state.sep); -}; - -const header = - (level) => - (el, ctx, state) => - repeat("#", level) + " " + body(el, ctx, state) + "\n\n"; - -const body = (el, ctx, state) => - serializeIter(el[2], ctx, state); - -export const serializeElement: MultiFn3 = defmulti((el) => el[0]); -serializeElement.add(DEFAULT, body); -serializeElement.add("h1", header(1)); -serializeElement.add("h2", header(2)); -serializeElement.add("h3", header(3)); -serializeElement.add("h4", header(4)); -serializeElement.add("h5", header(5)); -serializeElement.add("h6", header(6)); - -serializeElement.add("p", (el, ctx, state) => - `\n${body(el, ctx, state)}\n` -); - -serializeElement.add("img", (el) => - `![${el[1].alt || ""}](${el[1].src})` -); - -serializeElement.add("a", (el, ctx, state) => - `[${body(el, ctx, state)}](${el[1].href})` -); - -serializeElement.add("em", (el, ctx, state) => - `_${body(el, ctx, state)}_` -); - -serializeElement.add("strong", (el, ctx, state) => - `**${body(el, ctx, state)}**` -); - -serializeElement.add("pre", (el, ctx, state) => - `\n\`\`\`${el[1].lang || ""}\n${body(el, ctx, { ...state, pre: true, sep: "\n" })}\n\`\`\`\n` -); - -serializeElement.add("code", (el, ctx, state) => - state.pre ? - el[2][0] : - `\`${body(el, ctx, state)}\`` -); - -serializeElement.add("ul", (el, ctx, state) => { - const cstate = { - ...state, - indent: state.indent + 4, - sep: "\n" - }; - return wrap(state.indent === 0 ? "\n" : "")( - body(el, ctx, cstate) - ); -}); - -serializeElement.add("ol", (el, ctx, state) => { - const cstate = { - ...state, - indent: state.indent + 4, - id: 0, - sep: "\n" - }; - return wrap(state.indent === 0 ? "\n" : "")( - body(el, ctx, cstate) - ); -}); - -serializeElement.add("li", (el, ctx, state) => - repeat(" ", state.indent - 4) + - (state.id != null ? (++state.id) + "." : "-") + - " " + - body(el, ctx, { ...state, sep: "" }) -); - -serializeElement.add("blockquote", (el, ctx, state) => - `\n> ${body(el, ctx, state)}\n` -); - -serializeElement.add("br", () => "\\\n"); - -serializeElement.add("hr", () => "\n---\n"); +export * from "./parse"; +export * from "./serialize"; diff --git a/packages/hiccup-markdown/src/parse.ts b/packages/hiccup-markdown/src/parse.ts new file mode 100644 index 0000000000..47516b611f --- /dev/null +++ b/packages/hiccup-markdown/src/parse.ts @@ -0,0 +1,400 @@ +import { alts } from "@thi.ng/fsm/alts"; +import { ResultBody } from "@thi.ng/fsm/api"; +import { fsm } from "@thi.ng/fsm/fsm"; +import { not } from "@thi.ng/fsm/not"; +import { whitespace } from "@thi.ng/fsm/range"; +import { repeat } from "@thi.ng/fsm/repeat"; +import { seq } from "@thi.ng/fsm/seq"; +import { str } from "@thi.ng/fsm/str"; +import { until } from "@thi.ng/fsm/until"; +import { peek } from "@thi.ng/transducers/func/peek"; +import { TagFactories } from "./api"; + +type ParseResult = ResultBody; + +/** + * Parser state IDs + */ +const enum State { + BLOCKQUOTE, + CODE, + CODEBLOCK, + EMPHASIS, + END_BLOCKQUOTE, + END_LI, + END_PARA, + END_HEADING, + END_TABLE, + HEADING, + IMG, + LINK, + LI, + PARA, + START, + START_CODEBLOCK, + STRIKE, + STRONG, + TABLE, +} + +/** + * Parser context / state + */ +interface FSMCtx { + stack: any[]; + container?: any[]; + children?: any[]; + body?: string; + title?: string; + href?: string; + lang?: string; + hd?: number; +} + +/** + * Default hiccup element factories + */ +const DEFAULT_TAGS: TagFactories = { + blockquote: (...xs) => ["blockquote", ...xs], + code: (body) => ["code", body], + codeblock: (lang, body) => ["pre", { lang }, body], + em: (body) => ["em", body], + heading: (level, xs) => [level < 7 ? `h${level}` : "p", ...xs], + hr: () => ["hr"], + img: (src, alt) => ["img", { src, alt }], + li: (xs: any[]) => ["li", ...xs], + link: (href, body) => ["a", { href }, body], + list: (type, xs) => [type, ...xs], + paragraph: (xs) => ["p", ...xs], + strong: (body) => ["strong", body], + strike: (body) => ["del", body], + table: (rows) => ["table", ["tbody", ...rows]], + td: (_, xs) => ["td", ...xs], + tr: (_, xs) => ["tr", ...xs], +}; + +const BQUOTE = ">"; +const CODE = "`"; +const CODEBLOCK = "```"; +const CODEBLOCK_END = "\n```\n"; +const EM = "_"; +const HD = "#"; +const HR = "-"; +const IMG = "!["; +const LI = "- "; +const LINK_LABEL = "["; +const LINK_LABEL_END = "]"; +const LINK_HREF = "("; +const LINK_HREF_END = ")"; +const NL = "\n"; +const STRIKE = "~~"; +const STRONG = "**"; +const TD = "|"; + +// state / context handling helpers + +const transition = + (ctx: FSMCtx, id: State): ParseResult => ( + ctx.children = [], + ctx.body = "", + [id] + ); + +const push = + (id: State, next: State) => + (ctx: FSMCtx): ParseResult => ( + ctx.stack.push({ id, children: ctx.children.concat(ctx.body) }), + transition(ctx, next) + ); + +const pop = + (result) => + (ctx, body): ParseResult => { + const { id, children } = ctx.stack.pop(); + children.push(result(ctx, body)); + ctx.children = children; + ctx.body = ""; + return [id]; + }; + +const collectChildren = + (ctx: FSMCtx) => + (ctx.children.push(ctx.body), ctx.children); + +const collect = + (id: State) => + (ctx: FSMCtx, buf: string[]): ParseResult => ( + ctx.body += buf.join(""), + [id] + ); + +const collectHeading = + (tag: (i: number, xs: any[]) => any[]) => + (ctx): ParseResult => + [State.START, [tag(ctx.hd, collectChildren(ctx))]]; + +const collectAndRestart = + (tag: (xs: any[]) => any[]) => + (ctx): ParseResult => + [State.START, [tag(collectChildren(ctx))]]; + +const collectBlockQuote = + (ctx): ParseResult => ( + ctx.children.push(ctx.body, ["br"]), + ctx.body = "", + [State.BLOCKQUOTE] + ); + +const collectCodeBlock = + (tag: (lang: string, body: string) => any[]) => + (ctx, body): ParseResult => + [State.START, [tag(ctx.lang, body)]]; + +const collectLi = + (ctx: FSMCtx, tag: (xs: any[]) => any[]) => + ctx.container.push(tag(collectChildren(ctx))); + +const collectList = ( + type: string, + list: (type: string, xs: any[]) => any[], + item: (xs: any[]) => any[] +) => + (ctx): ParseResult => ( + collectLi(ctx, item), + [State.START, [list(type, ctx.container)]] + ); + +const collectTD = + (tag: (i: number, xs: any[]) => any[]) => + (ctx: FSMCtx) => ( + ctx.children.push(ctx.body), + ctx.container.push( + tag(peek(ctx.stack).container.length, ctx.children) + ), + transition(ctx, State.TABLE) + ); + +const collectTR = + (tag: (i: number, xs: any[]) => any[]) => + (ctx: FSMCtx) => { + const rows = peek(ctx.stack).container; + rows.push(tag(rows.length, ctx.container)); + ctx.container = []; + return transition(ctx, State.END_TABLE); + }; + +const collectTable = + (tag: (xs: any[]) => any) => + (ctx): ParseResult => { + const rows = ctx.stack.pop().container; + rows.splice(1, 1); + return [State.START, [tag(rows)]]; + }; + +const collectInline = + (fn: (body: string) => any[]) => + pop((ctx, body: string) => fn(ctx.body + body.trim())); + +const heading = + (ctx: FSMCtx, body: string[]): ParseResult => ( + ctx.hd = body.length, + transition(ctx, State.HEADING) + ); + +const matchInline = + (id: State) => [ + str("![", push(id, State.IMG)), + str(LINK_LABEL, push(id, State.LINK)), + str(STRIKE, push(id, State.STRIKE)), + str(STRONG, push(id, State.STRONG)), + str(EM, push(id, State.EMPHASIS)), + str(CODE, push(id, State.CODE)) + ]; + +const matchLink = + (result: (href, body) => any[]) => + seq( + [ + until(LINK_LABEL_END, (ctx, body) => (ctx.title = body, null)), + str(LINK_HREF), + until(LINK_HREF_END, (ctx, body) => (ctx.href = body, null)), + ], + pop((ctx) => result(ctx.href, ctx.title)) + ); + +const matchPara = + (id: State, next: State) => + alts( + [ + ...matchInline(id), + str(NL, (ctx: FSMCtx) => (ctx.body += " ", [next])), + ], + collect(id), + ); + +const newPara = + (ctx: FSMCtx, buf: string[]): ParseResult => ( + ctx.body = buf.join(""), + ctx.children = [], + [State.PARA] + ); + +const newParaInline = + (next: State) => + (ctx: FSMCtx): ParseResult => ( + ctx.stack.push({ id: State.PARA, children: [] }), + transition(ctx, next) + ); + +const newParaCode = + (ctx: FSMCtx, x: string[]): ParseResult => ( + ctx.body = x[1], + ctx.stack.push({ id: State.PARA, children: [] }), + [State.CODE] + ); + +const newList = + (ctx: FSMCtx): ParseResult => ( + ctx.container = [], + transition(ctx, State.LI) + ); + +const newTable = + (ctx: FSMCtx) => ( + ctx.stack.push({ id: State.TABLE, container: [] }), + ctx.container = [], + transition(ctx, State.TABLE) + ); + +/** + * Main parser / transducer. Defines state map with the various Markdown + * syntax matchers and state transition handlers. The returned parser + * itself is only used in `index.ts`. + */ +export const parse = (tags?: Partial) => { + tags = { ...DEFAULT_TAGS, ...tags }; + return fsm( + { + [State.START]: + alts( + [ + whitespace(() => [State.START]), + repeat(str(HD), 1, Infinity, heading), + str(BQUOTE, (ctx) => transition(ctx, State.BLOCKQUOTE)), + str(LI, newList), + alts( + [ + seq([str(CODE), not(str(CODE))], newParaCode), + str(CODEBLOCK, () => [State.START_CODEBLOCK]) + ], + null, (_, next) => next + ), + seq( + [repeat(str(HR), 3, Infinity), str(NL)], + () => [State.START, [tags.hr()]] + ), + str(IMG, newParaInline(State.IMG)), + str(LINK_LABEL, newParaInline(State.LINK)), + str(STRONG, newParaInline(State.STRONG)), + str(STRIKE, newParaInline(State.STRIKE)), + str(EM, newParaInline(State.EMPHASIS)), + str(TD, newTable), + ], + newPara, + ), + + [State.PARA]: + matchPara(State.PARA, State.END_PARA), + + [State.END_PARA]: + alts( + [ + ...matchInline(State.PARA), + str(NL, collectAndRestart(tags.paragraph)), + ], + collect(State.PARA) + ), + + [State.BLOCKQUOTE]: + matchPara(State.BLOCKQUOTE, State.END_BLOCKQUOTE), + + [State.END_BLOCKQUOTE]: + alts( + [ + ...matchInline(State.BLOCKQUOTE), + str(BQUOTE, collectBlockQuote), + str(NL, collectAndRestart(tags.blockquote)), + ], + collect(State.BLOCKQUOTE) + ), + + [State.HEADING]: + matchPara(State.HEADING, State.END_HEADING), + + [State.END_HEADING]: + alts( + [ + ...matchInline(State.HEADING), + str(NL, collectHeading(tags.heading)), + ], + collect(State.HEADING) + ), + + [State.START_CODEBLOCK]: + until(NL, (ctx, lang) => (ctx.lang = lang, [State.CODEBLOCK])), + + [State.CODEBLOCK]: + until(CODEBLOCK_END, collectCodeBlock(tags.codeblock)), + + [State.LI]: + matchPara(State.LI, State.END_LI), + + [State.END_LI]: + alts( + [ + str(NL, collectList("ul", tags.list, tags.li)), + str(LI, (ctx) => (collectLi(ctx, tags.li), transition(ctx, State.LI))) + ], + collect(State.LI) + ), + + [State.LINK]: + matchLink(tags.link), + + [State.IMG]: + matchLink(tags.img), + + [State.STRONG]: + until(STRONG, collectInline(tags.strong)), + + [State.STRIKE]: + until(STRIKE, collectInline(tags.strike)), + + [State.EMPHASIS]: + until(EM, collectInline(tags.em)), + + [State.CODE]: + until(CODE, collectInline(tags.code)), + + [State.TABLE]: + alts( + [ + ...matchInline(State.TABLE), + str(TD, collectTD(tags.td)), + str(NL, collectTR(tags.tr)) + ], + collect(State.TABLE) + ), + + [State.END_TABLE]: + alts( + [ + str(NL, collectTable(tags.table)), + str(TD, () => [State.TABLE]) + ], + ) + }, + { stack: [] }, + State.START + ); +}; diff --git a/packages/hiccup-markdown/src/serialize.ts b/packages/hiccup-markdown/src/serialize.ts new file mode 100644 index 0000000000..397bf0ebb3 --- /dev/null +++ b/packages/hiccup-markdown/src/serialize.ts @@ -0,0 +1,152 @@ +import { implementsFunction } from "@thi.ng/checks/implements-function"; +import { isFunction } from "@thi.ng/checks/is-function"; +import { isNotStringAndIterable } from "@thi.ng/checks/is-not-string-iterable"; +import { isString } from "@thi.ng/checks/is-string"; +import { DEFAULT, defmulti, MultiFn3 } from "@thi.ng/defmulti"; +import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { normalize } from "@thi.ng/hiccup/serialize"; +import { repeat } from "@thi.ng/strings/repeat"; +import { wrap } from "@thi.ng/strings/wrap"; + +export const serialize = (tree: any, ctx) => + _serialize(tree, ctx, { indent: 0, sep: "" }); + +const _serialize = (tree: any, ctx, state) => { + if (tree == null) return ""; + if (Array.isArray(tree)) { + if (!tree.length) { + return ""; + } + let tag = tree[0]; + if (isFunction(tag)) { + return _serialize(tag.apply(null, [ctx, ...tree.slice(1)]), ctx, state); + } + if (implementsFunction(tag, "render")) { + return _serialize(tag.render.apply(null, [ctx, ...tree.slice(1)]), ctx, state); + } + if (isString(tag)) { + tree = normalize(tree); + const attribs = tree[1]; + if (attribs.__skip || attribs.__serialize === false) { + return ""; + } + tag = tree[0]; + return serializeElement(tree, ctx, state); + } + if (isNotStringAndIterable(tree)) { + return serializeIter(tree, ctx, state); + } + illegalArgs(`invalid tree node: ${tree}`); + } + if (isFunction(tree)) { + return _serialize(tree(ctx), ctx, state); + } + if (implementsFunction(tree, "toHiccup")) { + return _serialize(tree.toHiccup(ctx), ctx, state); + } + if (implementsFunction(tree, "deref")) { + return _serialize(tree.deref(), ctx, state); + } + if (isNotStringAndIterable(tree)) { + return serializeIter(tree, ctx, state); + } + return tree.toString(); +}; + +const serializeIter = ( + iter: Iterable, + ctx: any, + state: any +) => { + if (!iter) return ""; + const res = []; + for (let i of iter) { + res.push(_serialize(i, ctx, state)); + } + return res.join(state.sep); +}; + +const header = + (level) => + (el, ctx, state) => + repeat("#", level) + " " + body(el, ctx, state) + "\n\n"; + +const body = (el, ctx, state) => + serializeIter(el[2], ctx, state); + +export const serializeElement: MultiFn3 = defmulti((el) => el[0]); +serializeElement.add(DEFAULT, body); +serializeElement.add("h1", header(1)); +serializeElement.add("h2", header(2)); +serializeElement.add("h3", header(3)); +serializeElement.add("h4", header(4)); +serializeElement.add("h5", header(5)); +serializeElement.add("h6", header(6)); + +serializeElement.add("p", (el, ctx, state) => + `\n${body(el, ctx, state)}\n` +); + +serializeElement.add("img", (el) => + `![${el[1].alt || ""}](${el[1].src})` +); + +serializeElement.add("a", (el, ctx, state) => + `[${body(el, ctx, state)}](${el[1].href})` +); + +serializeElement.add("em", (el, ctx, state) => + `_${body(el, ctx, state)}_` +); + +serializeElement.add("strong", (el, ctx, state) => + `**${body(el, ctx, state)}**` +); + +serializeElement.add("pre", (el, ctx, state) => + `\n\`\`\`${el[1].lang || ""}\n${body(el, ctx, { ...state, pre: true, sep: "\n" })}\n\`\`\`\n` +); + +serializeElement.add("code", (el, ctx, state) => + state.pre ? + el[2][0] : + `\`${body(el, ctx, state)}\`` +); + +serializeElement.add("ul", (el, ctx, state) => { + const cstate = { + ...state, + indent: state.indent + 4, + sep: "\n" + }; + return wrap(state.indent === 0 ? "\n" : "")( + body(el, ctx, cstate) + ); +}); + +serializeElement.add("ol", (el, ctx, state) => { + const cstate = { + ...state, + indent: state.indent + 4, + id: 0, + sep: "\n" + }; + return wrap(state.indent === 0 ? "\n" : "")( + body(el, ctx, cstate) + ); +}); + +serializeElement.add("li", (el, ctx, state) => + repeat(" ", state.indent - 4) + + (state.id != null ? (++state.id) + "." : "-") + + " " + + body(el, ctx, { ...state, sep: "" }) +); + +serializeElement.add("blockquote", (el, ctx, state) => + `\n> ${body(el, ctx, state)}\n` +); + +serializeElement.add("br", () => "\\\n"); + +serializeElement.add("hr", () => "\n---\n"); diff --git a/packages/hiccup-markdown/tsconfig.json b/packages/hiccup-markdown/tsconfig.json index bd6481a5a6..bed3f606cb 100644 --- a/packages/hiccup-markdown/tsconfig.json +++ b/packages/hiccup-markdown/tsconfig.json @@ -1,9 +1,10 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "preserveConstEnums": false }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file From 343280d8305a77bc007399b38d8d8c869f8b7f11 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 4 Jan 2019 22:22:01 +0000 Subject: [PATCH 180/333] refactor(examples): update MD demo, use parser from hiccup-markdown package --- examples/markdown/README.md | 38 ++-- examples/markdown/package.json | 2 +- examples/markdown/src/index.ts | 5 +- examples/markdown/src/parser.ts | 392 -------------------------------- 4 files changed, 23 insertions(+), 414 deletions(-) delete mode 100644 examples/markdown/src/parser.ts diff --git a/examples/markdown/README.md b/examples/markdown/README.md index e8376e70e4..afacc8854f 100644 --- a/examples/markdown/README.md +++ b/examples/markdown/README.md @@ -5,18 +5,15 @@ This project is part of the ## About -This example is a test environment for a new & minimal +This example is a test environment for the new & minimal [Markdown](https://en.wikipedia.org/wiki/Markdown) parser & converter to [hiccup](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup) -format, using basic state handling and parsing primitives provided by -the -[@thi.ng/fsm](https://github.com/thi-ng/umbrella/tree/master/packages/fsm) -package, which itself is a potential replacement / major version update -for -[@thi.ng/transducers-fsm](https://github.com/thi-ng/umbrella/tree/master/packages/transducers-fsm). +format from the +[@thi.ng/hiccup-markdown](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup-markdown) +package. -> "Weeks of coding can **save hours** of planning." -> -- Anonymous +The rest of this file is an excerpt of the relevant parts of that +package's `README.md`... ### Features @@ -53,6 +50,9 @@ These MD features (and probably many more) are **not** supported: Some of these are considered, though currently not high priority... +> "Weeks of coding can **save hours** of planning." +> -- Anonymous + ### Other features - **Functional:** parser entirely built using @@ -77,13 +77,13 @@ See [example source code](https://github.com/thi-ng/umbrella/tree/master/examples/markdown/src/) for reference... -## Serializing to HTML +## Parsing & serializing to HTML ```ts import { iterator } from "@thi.ng/transducers"; import { serialize } from "@thi.ng/hiccup"; -import { parseMD } from "./parser"; +import { parse } from "@thi.ng/hiccup-markdown/parse"; const src = ` # Hello world @@ -93,7 +93,7 @@ const src = ` `; // convert to hiccup tree -[...iterator(parseMD(), src)] +[...iterator(parse(), src)] // [ [ 'h1', ' Hello world ' ], // [ 'p', // [ 'a', { href: 'http://example.com' }, 'This' ], @@ -102,7 +102,7 @@ const src = ` // '. ' ] ] // or serialize to HTML -serialize(iterator(parseMD(), src)); +serialize(iterator(parse(), src)); //

Hello world

// This is a test.

@@ -120,18 +120,18 @@ interface TagFactories { code(body: string): any[]; codeblock(lang: string, body: string): any[]; em(body: string): any[]; + heading(level, children: any[]): any[]; + hr(): any[]; img(src: string, alt: string): any[]; + li(children: any[]): any[]; link(href: string, body: string): any[]; list(type: string, items: any[]): any[]; - li(children: any[]): any[]; paragraph(children: any[]): any[]; - strong(body: string): any[]; strike(body: string): any[]; - title(level, children: any[]): any[]; + strong(body: string): any[]; table(rows: any[]): any[]; - tr(i: number, cells: any[]): any[]; td(i: number, children: any[]): any[]; - hr(): any[]; + tr(i: number, cells: any[]): any[]; } ``` @@ -142,7 +142,7 @@ const tags = { link: (href, body) => ["a.link.blue", { href }, body] }; -serialize(iterator(parseMD(tags), src)); +serialize(iterator(parse(tags), src)); //

Hello world

//

This is a test.

diff --git a/examples/markdown/package.json b/examples/markdown/package.json index 426edcd267..99de136d8d 100644 --- a/examples/markdown/package.json +++ b/examples/markdown/package.json @@ -17,7 +17,7 @@ }, "dependencies": { "@thi.ng/api": "latest", - "@thi.ng/fsm": "latest", + "@thi.ng/hiccup-markdown": "latest", "@thi.ng/rstream": "latest", "@thi.ng/transducers-hdom": "latest" }, diff --git a/examples/markdown/src/index.ts b/examples/markdown/src/index.ts index 2d99046ef6..18616d7f31 100644 --- a/examples/markdown/src/index.ts +++ b/examples/markdown/src/index.ts @@ -1,9 +1,10 @@ import { timedResult } from "@thi.ng/bench"; +import { TagFactories } from "@thi.ng/hiccup-markdown/api"; +import { parse } from "@thi.ng/hiccup-markdown/parse"; import { stream, Stream } from "@thi.ng/rstream/stream"; import { updateDOM } from "@thi.ng/transducers-hdom"; import { iterator } from "@thi.ng/transducers/iterator"; import { map } from "@thi.ng/transducers/xform/map"; -import { parseMD, TagFactories } from "./parser"; // ignore error, resolved by parcel import readme from "../README.md"; @@ -43,7 +44,7 @@ const src = stream(); // stream transformer & UI update src.transform( - map((src) => ({ src, parsed: timedResult(() => [...iterator(parseMD(CUSTOM_TAGS), src)]) })), + map((src) => ({ src, parsed: timedResult(() => [...iterator(parse(CUSTOM_TAGS), src)]) })), map(app(src)), updateDOM() ); diff --git a/examples/markdown/src/parser.ts b/examples/markdown/src/parser.ts deleted file mode 100644 index fe0d883164..0000000000 --- a/examples/markdown/src/parser.ts +++ /dev/null @@ -1,392 +0,0 @@ -import { alts } from "@thi.ng/fsm/alts"; -import { ResultBody } from "@thi.ng/fsm/api"; -import { fsm } from "@thi.ng/fsm/fsm"; -import { not } from "@thi.ng/fsm/not"; -import { whitespace } from "@thi.ng/fsm/range"; -import { repeat } from "@thi.ng/fsm/repeat"; -import { seq } from "@thi.ng/fsm/seq"; -import { str } from "@thi.ng/fsm/str"; -import { until } from "@thi.ng/fsm/until"; -import { peek } from "@thi.ng/transducers/func/peek"; - -// parse state IDs -// TODO use const enum once moved to own package -const BLOCKQUOTE = "blockquote"; -const CODE = "code"; -const CODEBLOCK = "codeblock"; -const EMPHASIS = "em"; -const END_BLOCKQUOTE = "end-blockquote"; -const END_LI = "end-li"; -const END_PARA = "end-para"; -const END_TITLE = "end-title"; -const END_TABLE = "end-table"; -const IMG = "img"; -const LINK = "link"; -const LI = "li"; -const PARA = "para"; -const START = "start"; -const START_CODEBLOCK = "start-codeblock"; -const TABLE = "table"; -const STRIKE = "strike"; -const STRONG = "strong"; -const TITLE = "title"; - -type ParseResult = ResultBody; - -// parse context -interface FSMCtx { - stack: any[]; - container?: any[]; - children?: any[]; - body?: string; - title?: string; - href?: string; - lang?: string; - hd?: number; -} - -// hiccup element factories -export interface TagFactories { - blockquote(...children: any[]): any[]; - code(body: string): any[]; - codeblock(lang: string, body: string): any[]; - em(body: string): any[]; - img(src: string, alt: string): any[]; - link(href: string, body: string): any[]; - list(type: string, items: any[]): any[]; - li(children: any[]): any[]; - paragraph(children: any[]): any[]; - strong(body: string): any[]; - strike(body: string): any[]; - title(level, children: any[]): any[]; - table(rows: any[]): any[]; - tr(i: number, cells: any[]): any[]; - td(i: number, children: any[]): any[]; - hr(): any[]; -} - -const DEFAULT_TAGS: TagFactories = { - blockquote: (...xs) => ["blockquote", ...xs], - code: (body) => ["code", body], - codeblock: (lang, body) => ["pre", { lang }, body], - em: (body) => ["em", body], - img: (src, alt) => ["img", { src, alt }], - li: (xs: any[]) => ["li", ...xs], - link: (href, body) => ["a", { href }, body], - list: (type, xs) => [type, ...xs], - paragraph: (xs) => ["p", ...xs], - strong: (body) => ["strong", body], - strike: (body) => ["del", body], - title: (level, xs) => [level < 7 ? `h${level}` : "p", ...xs], - table: (rows) => ["table", ...rows], - tr: (_, xs) => ["tr", ...xs], - td: (_, xs) => ["td", ...xs], - hr: () => ["hr"], -}; - -// state / context handling helpers - -const transition = - (ctx: FSMCtx, id: string): ParseResult => ( - ctx.children = [], - ctx.body = "", - [id] - ); - -const push = - (id: string, next: string) => - (ctx: FSMCtx): ParseResult => ( - ctx.stack.push({ id, children: ctx.children.concat(ctx.body) }), - transition(ctx, next) - ); - -const pop = - (result) => - (ctx, body): ParseResult => { - const { id, children } = ctx.stack.pop(); - children.push(result(ctx, body)); - ctx.children = children; - ctx.body = ""; - return [id]; - }; - -const collectChildren = - (ctx: FSMCtx) => (ctx.children.push(ctx.body), ctx.children); - -const collect = - (id: string) => - (ctx: FSMCtx, buf: string[]): ParseResult => ( - ctx.body += buf.join(""), - [id] - ); - -const collectHeading = - (tag: (i: number, xs: any[]) => any[]) => - (ctx): ParseResult => - [START, [tag(ctx.hd, collectChildren(ctx))]]; - -const collectAndRestart = - (tag: (xs: any[]) => any[]) => - (ctx): ParseResult => - [START, [tag(collectChildren(ctx))]]; - -const collectBlockQuote = - (ctx): ParseResult => ( - ctx.children.push(ctx.body, ["br"]), - ctx.body = "", - [BLOCKQUOTE] - ); - -const collectCodeBlock = - (tag: (lang: string, body: string) => any[]) => - (ctx, body): ParseResult => - [START, [tag(ctx.lang, body)]]; - -const collectLi = - (ctx: FSMCtx, tag: (xs: any[]) => any[]) => - ctx.container.push(tag(collectChildren(ctx))); - -const collectList = ( - type: string, - list: (type: string, xs: any[]) => any[], - item: (xs: any[]) => any[] -) => - (ctx): ParseResult => ( - collectLi(ctx, item), - [START, [list(type, ctx.container)]] - ); - -const collectTD = - (tag: (i: number, xs: any[]) => any[]) => - (ctx: FSMCtx) => ( - ctx.children.push(ctx.body), - ctx.container.push( - tag(peek(ctx.stack).container.length, ctx.children) - ), - transition(ctx, TABLE) - ); - -const collectTR = - (tag: (i: number, xs: any[]) => any[]) => - (ctx: FSMCtx) => { - const rows = peek(ctx.stack).container; - rows.push(tag(rows.length, ctx.container)); - ctx.container = []; - return transition(ctx, END_TABLE); - }; - -const collectTable = - (tag: (xs: any[]) => any) => - (ctx): ParseResult => { - const rows = ctx.stack.pop().container; - rows.splice(1, 1); - return [START, [tag(rows)]]; - }; - -const collectInline = - (fn: (body: string) => any[]) => - pop((ctx, body: string) => fn(ctx.body + body.trim())); - -const title = - (ctx: FSMCtx, body: string[]): ParseResult => ( - ctx.hd = body.length, - transition(ctx, TITLE) - ); - -const matchInline = - (id: string) => [ - str("![", push(id, IMG)), - str("[", push(id, LINK)), - str("~~", push(id, STRIKE)), - str("**", push(id, STRONG)), - str("_", push(id, EMPHASIS)), - str("`", push(id, CODE)) - ]; - -const matchLink = - (result: (href, body) => any[]) => - seq( - [ - until("]", (ctx, body) => (ctx.title = body, null)), - str("("), - until(")", (ctx, body) => (ctx.href = body, null)), - ], - pop((ctx) => result(ctx.href, ctx.title)) - ); - -const matchPara = - (id: string, next: string) => - alts( - [ - ...matchInline(id), - str("\n", (ctx: FSMCtx) => (ctx.body += " ", [next])), - ], - collect(id), - ); - -const newPara = - (ctx: FSMCtx, buf: string[]): ParseResult => ( - ctx.body = buf.join(""), - ctx.children = [], - [PARA] - ); - -const newParaInline = - (next: string) => - (ctx: FSMCtx): ParseResult => ( - ctx.stack.push({ id: PARA, children: [] }), - transition(ctx, next) - ); - -const newParaCode = - (ctx: FSMCtx, x: string[]): ParseResult => ( - ctx.body = x[1], - ctx.stack.push({ id: PARA, children: [] }), - [CODE] - ); - -const newList = - (ctx: FSMCtx): ParseResult => ( - ctx.container = [], - transition(ctx, LI) - ); - -const newTable = - (ctx: FSMCtx) => ( - ctx.stack.push({ id: TABLE, container: [] }), - ctx.container = [], - transition(ctx, TABLE) - ); - -/** - * Main parser / transducer. Defines state map with the various Markdown - * syntax matchers and state transition handlers. The returned parser - * itself is only used in `index.ts`. - */ -export const parseMD = (tags?: Partial) => { - tags = { ...DEFAULT_TAGS, ...tags }; - return fsm( - { - [START]: - alts( - [ - whitespace(() => [START]), - repeat(str("#"), 1, Infinity, title), - str(">", (ctx) => transition(ctx, BLOCKQUOTE)), - str("- ", newList), - alts( - [ - seq([str("`"), not(str("`"))], newParaCode), - str("```", () => [START_CODEBLOCK]) - ], - null, (_, next) => next - ), - seq( - [repeat(str("-"), 3, Infinity), str("\n")], - () => [START, [tags.hr()]] - ), - str("![", newParaInline(IMG)), - str("[", newParaInline(LINK)), - str("**", newParaInline(STRONG)), - str("~~", newParaInline(STRIKE)), - str("_", newParaInline(EMPHASIS)), - str("|", newTable), - ], - newPara, - ), - - [PARA]: - matchPara(PARA, END_PARA), - - [END_PARA]: - alts( - [ - ...matchInline(PARA), - str("\n", collectAndRestart(tags.paragraph)), - ], - collect(PARA) - ), - - [BLOCKQUOTE]: - matchPara(BLOCKQUOTE, END_BLOCKQUOTE), - - [END_BLOCKQUOTE]: - alts( - [ - ...matchInline(BLOCKQUOTE), - str(">", collectBlockQuote), - str("\n", collectAndRestart(tags.blockquote)), - ], - collect(BLOCKQUOTE) - ), - - [TITLE]: - matchPara(TITLE, END_TITLE), - - [END_TITLE]: - alts( - [ - ...matchInline(TITLE), - str("\n", collectHeading(tags.title)), - ], - collect(TITLE) - ), - - [START_CODEBLOCK]: - until("\n", (ctx, lang) => (ctx.lang = lang, [CODEBLOCK])), - - [CODEBLOCK]: - until("\n```\n", collectCodeBlock(tags.codeblock)), - - [LI]: - matchPara(LI, END_LI), - - [END_LI]: - alts( - [ - str("\n", collectList("ul", tags.list, tags.li)), - str("- ", (ctx) => (collectLi(ctx, tags.li), transition(ctx, LI))) - ], - collect(LI) - ), - - [LINK]: - matchLink(tags.link), - - [IMG]: - matchLink(tags.img), - - [STRONG]: - until("**", collectInline(tags.strong)), - - [STRIKE]: - until("~~", collectInline(tags.strike)), - - [EMPHASIS]: - until("_", collectInline(tags.em)), - - [CODE]: - until("`", collectInline(tags.code)), - - [TABLE]: - alts( - [ - ...matchInline(TABLE), - str("|", collectTD(tags.td)), - str("\n", collectTR(tags.tr)) - ], - collect(TABLE) - ), - - [END_TABLE]: - alts( - [ - str("\n", collectTable(tags.table)), - str("|", () => [TABLE]) - ], - ) - }, - { stack: [] }, - START - ); -}; From 634e2504b72eebed2dc61c093a08fae34efa0094 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 4 Jan 2019 22:43:57 +0000 Subject: [PATCH 181/333] Publish - @thi.ng/hiccup-markdown@0.2.0 --- packages/hiccup-markdown/CHANGELOG.md | 11 +++++++++++ packages/hiccup-markdown/package.json | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/hiccup-markdown/CHANGELOG.md b/packages/hiccup-markdown/CHANGELOG.md index 1b0f8c8844..7c428c670c 100644 --- a/packages/hiccup-markdown/CHANGELOG.md +++ b/packages/hiccup-markdown/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.2.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-markdown@0.1.2...@thi.ng/hiccup-markdown@0.2.0) (2019-01-04) + + +### Features + +* **hiccup-markdown:** add & refactor markdown parser (from example), update docs ([35db07f](https://github.com/thi-ng/umbrella/commit/35db07f)) + + + + + ## [0.1.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-markdown@0.1.1...@thi.ng/hiccup-markdown@0.1.2) (2019-01-02) **Note:** Version bump only for package @thi.ng/hiccup-markdown diff --git a/packages/hiccup-markdown/package.json b/packages/hiccup-markdown/package.json index 8b17228da4..b0450088a2 100644 --- a/packages/hiccup-markdown/package.json +++ b/packages/hiccup-markdown/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hiccup-markdown", - "version": "0.1.2", + "version": "0.2.0", "description": "Markdown serialization of hiccup DOM trees", "main": "./index.js", "typings": "./index.d.ts", @@ -51,4 +51,4 @@ "publishConfig": { "access": "public" } -} \ No newline at end of file +} From 3038a844e79134714437cd713f51c72a5b4cfc64 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 4 Jan 2019 22:57:47 +0000 Subject: [PATCH 182/333] docs(hiccup-markdown): update readme --- packages/hiccup-markdown/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/hiccup-markdown/README.md b/packages/hiccup-markdown/README.md index 54231c5e5a..bb1677163b 100644 --- a/packages/hiccup-markdown/README.md +++ b/packages/hiccup-markdown/README.md @@ -50,6 +50,9 @@ yarn add @thi.ng/hiccup-markdown ## Parser +**Try out the [Markdown editor demo](https://demo.thi.ng/umbrella/markdown/)** +([Source code](https://github.com/thi-ng/umbrella/tree/master/examples/markdown)) + ### Features The parser itself is not aimed at supporting **all** of Markdown's From b70a3e1a200fe28c57ed483f6bfca493270093c4 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 03:30:52 +0000 Subject: [PATCH 183/333] refactor(checks): update all as arrow fns --- packages/checks/src/exists-not-null.ts | 5 ++--- packages/checks/src/exists.ts | 5 ++--- packages/checks/src/has-crypto.ts | 5 ++--- packages/checks/src/has-max-length.ts | 6 ++--- packages/checks/src/has-min-length.ts | 6 ++--- packages/checks/src/has-performance.ts | 5 ++--- packages/checks/src/has-wasm.ts | 6 ++--- packages/checks/src/has-webgl.ts | 17 +++++++------- packages/checks/src/has-websocket.ts | 5 ++--- packages/checks/src/implements-function.ts | 6 ++--- packages/checks/src/is-arraylike.ts | 6 ++--- packages/checks/src/is-blob.ts | 5 ++--- packages/checks/src/is-boolean.ts | 5 ++--- packages/checks/src/is-chrome.ts | 5 ++--- packages/checks/src/is-date.ts | 5 ++--- packages/checks/src/is-even.ts | 5 ++--- packages/checks/src/is-false.ts | 5 ++--- packages/checks/src/is-file.ts | 5 ++--- packages/checks/src/is-firefox.ts | 5 ++--- packages/checks/src/is-function.ts | 5 ++--- packages/checks/src/is-ie.ts | 6 ++--- packages/checks/src/is-in-range.ts | 6 ++--- packages/checks/src/is-int32.ts | 6 ++--- packages/checks/src/is-iterable.ts | 6 ++--- packages/checks/src/is-map.ts | 5 ++--- packages/checks/src/is-mobile.ts | 6 ++--- packages/checks/src/is-nan.ts | 5 ++--- packages/checks/src/is-negative.ts | 6 ++--- packages/checks/src/is-node.ts | 17 +++++++------- packages/checks/src/is-not-string-iterable.ts | 6 ++--- packages/checks/src/is-null.ts | 5 ++--- packages/checks/src/is-number.ts | 5 ++--- packages/checks/src/is-object.ts | 6 ++--- packages/checks/src/is-odd.ts | 5 ++--- packages/checks/src/is-plain-object.ts | 11 +++++----- packages/checks/src/is-positive.ts | 5 ++--- packages/checks/src/is-promise.ts | 5 ++--- packages/checks/src/is-promiselike.ts | 6 ++--- packages/checks/src/is-regexp.ts | 5 ++--- packages/checks/src/is-safari.ts | 8 ++++--- packages/checks/src/is-set.ts | 5 ++--- packages/checks/src/is-string.ts | 5 ++--- packages/checks/src/is-symbol.ts | 5 ++--- packages/checks/src/is-transferable.ts | 6 ++--- packages/checks/src/is-true.ts | 5 ++--- packages/checks/src/is-typedarray.ts | 22 +++++++++---------- packages/checks/src/is-uint32.ts | 6 ++--- packages/checks/src/is-undefined.ts | 5 ++--- packages/checks/src/is-uuid.ts | 7 +++--- packages/checks/src/is-uuid4.ts | 7 +++--- packages/checks/src/is-zero.ts | 5 ++--- 51 files changed, 152 insertions(+), 173 deletions(-) diff --git a/packages/checks/src/exists-not-null.ts b/packages/checks/src/exists-not-null.ts index dfc00f83f9..b11de3a1e6 100644 --- a/packages/checks/src/exists-not-null.ts +++ b/packages/checks/src/exists-not-null.ts @@ -1,3 +1,2 @@ -export function existsAndNotNull(x: any) { - return x != null; -} +export const existsAndNotNull = + (x: any) => x != null; diff --git a/packages/checks/src/exists.ts b/packages/checks/src/exists.ts index a0c963d50c..7c548aaada 100644 --- a/packages/checks/src/exists.ts +++ b/packages/checks/src/exists.ts @@ -1,3 +1,2 @@ -export function exists(x: any) { - return x !== undefined; -} +export const exists = + (x: any) => x !== undefined; diff --git a/packages/checks/src/has-crypto.ts b/packages/checks/src/has-crypto.ts index 96609bc53d..11e01ce282 100644 --- a/packages/checks/src/has-crypto.ts +++ b/packages/checks/src/has-crypto.ts @@ -1,3 +1,2 @@ -export function hasCrypto() { - return typeof window !== "undefined" && window["crypto"] !== undefined; -} +export const hasCrypto = + () => typeof window !== "undefined" && window["crypto"] !== undefined; diff --git a/packages/checks/src/has-max-length.ts b/packages/checks/src/has-max-length.ts index 5cd5e31072..3421673854 100644 --- a/packages/checks/src/has-max-length.ts +++ b/packages/checks/src/has-max-length.ts @@ -1,3 +1,3 @@ -export function hasMaxLength(len: number, x: ArrayLike) { - return x != null && x.length <= len; -} +export const hasMaxLength = + (len: number, x: ArrayLike) => + x != null && x.length <= len; diff --git a/packages/checks/src/has-min-length.ts b/packages/checks/src/has-min-length.ts index 905a553295..ae970513bc 100644 --- a/packages/checks/src/has-min-length.ts +++ b/packages/checks/src/has-min-length.ts @@ -1,3 +1,3 @@ -export function hasMinLength(len: number, x: ArrayLike) { - return x != null && x.length >= len; -} +export const hasMinLength = + (len: number, x: ArrayLike) => + x != null && x.length >= len; diff --git a/packages/checks/src/has-performance.ts b/packages/checks/src/has-performance.ts index 7d8b8042c5..75216308be 100644 --- a/packages/checks/src/has-performance.ts +++ b/packages/checks/src/has-performance.ts @@ -1,5 +1,4 @@ import { isFunction } from "./is-function"; -export function hasPerformance() { - return typeof performance !== 'undefined' && isFunction(performance.now); -} +export const hasPerformance = + () => typeof performance !== 'undefined' && isFunction(performance.now); diff --git a/packages/checks/src/has-wasm.ts b/packages/checks/src/has-wasm.ts index 4e2837f890..63d6d157d7 100644 --- a/packages/checks/src/has-wasm.ts +++ b/packages/checks/src/has-wasm.ts @@ -1,4 +1,4 @@ -export function hasWASM() { - return (typeof window !== "undefined" && typeof window["WebAssembly"] !== "undefined") || +export const hasWASM = + () => + (typeof window !== "undefined" && typeof window["WebAssembly"] !== "undefined") || (typeof global !== "undefined" && typeof global["WebAssembly"] !== "undefined"); -} diff --git a/packages/checks/src/has-webgl.ts b/packages/checks/src/has-webgl.ts index 043f42bb0f..f98ed9a797 100644 --- a/packages/checks/src/has-webgl.ts +++ b/packages/checks/src/has-webgl.ts @@ -1,8 +1,9 @@ -export function hasWebGL() { - try { - document.createElement("canvas").getContext("webgl"); - return true; - } catch (e) { - return false; - } -} +export const hasWebGL = + () => { + try { + document.createElement("canvas").getContext("webgl"); + return true; + } catch (e) { + return false; + } + }; diff --git a/packages/checks/src/has-websocket.ts b/packages/checks/src/has-websocket.ts index 1949f25ed3..83399832c5 100644 --- a/packages/checks/src/has-websocket.ts +++ b/packages/checks/src/has-websocket.ts @@ -1,3 +1,2 @@ -export function hasWebSocket() { - return typeof WebSocket !== "undefined"; -} +export const hasWebSocket = + () => typeof WebSocket !== "undefined"; diff --git a/packages/checks/src/implements-function.ts b/packages/checks/src/implements-function.ts index ab0e0e6368..ffc6bac186 100644 --- a/packages/checks/src/implements-function.ts +++ b/packages/checks/src/implements-function.ts @@ -1,3 +1,3 @@ -export function implementsFunction(x: any, fn: string | symbol) { - return x != null && typeof x[fn] === "function"; -} +export const implementsFunction = + (x: any, fn: string | symbol) => + x != null && typeof x[fn] === "function"; diff --git a/packages/checks/src/is-arraylike.ts b/packages/checks/src/is-arraylike.ts index 7824d8f9dc..137f6b5abb 100644 --- a/packages/checks/src/is-arraylike.ts +++ b/packages/checks/src/is-arraylike.ts @@ -1,3 +1,3 @@ -export function isArrayLike(x: any): x is ArrayLike { - return (x != null && typeof x !== "function" && x.length !== undefined); -} +export const isArrayLike = + (x: any): x is ArrayLike => + (x != null && typeof x !== "function" && x.length !== undefined); diff --git a/packages/checks/src/is-blob.ts b/packages/checks/src/is-blob.ts index b8902c8a0a..dfc81a6475 100644 --- a/packages/checks/src/is-blob.ts +++ b/packages/checks/src/is-blob.ts @@ -1,3 +1,2 @@ -export function isBlob(x: any): x is Blob { - return x instanceof Blob; -} +export const isBlob = + (x: any): x is Blob => x instanceof Blob; diff --git a/packages/checks/src/is-boolean.ts b/packages/checks/src/is-boolean.ts index a3657e6a63..501a6368af 100644 --- a/packages/checks/src/is-boolean.ts +++ b/packages/checks/src/is-boolean.ts @@ -1,3 +1,2 @@ -export function isBoolean(x: any): x is boolean { - return typeof x === "boolean"; -} +export const isBoolean = + (x: any): x is boolean => typeof x === "boolean"; diff --git a/packages/checks/src/is-chrome.ts b/packages/checks/src/is-chrome.ts index 9734e4c0f1..391d54deb8 100644 --- a/packages/checks/src/is-chrome.ts +++ b/packages/checks/src/is-chrome.ts @@ -1,3 +1,2 @@ -export function isChrome() { - return typeof window !== "undefined" && !!window["chrome"]; -} +export const isChrome = + () => typeof window !== "undefined" && !!window["chrome"]; diff --git a/packages/checks/src/is-date.ts b/packages/checks/src/is-date.ts index 36e8a3bfee..a1ac5e524f 100644 --- a/packages/checks/src/is-date.ts +++ b/packages/checks/src/is-date.ts @@ -1,3 +1,2 @@ -export function isDate(x: any): x is Date { - return x instanceof Date; -} +export const isDate = + (x: any): x is Date => x instanceof Date; diff --git a/packages/checks/src/is-even.ts b/packages/checks/src/is-even.ts index 464503c36e..444de8bfcf 100644 --- a/packages/checks/src/is-even.ts +++ b/packages/checks/src/is-even.ts @@ -1,3 +1,2 @@ -export function isEven(x: number) { - return (x % 2) === 0; -} +export const isEven = + (x: number) => (x % 2) === 0; diff --git a/packages/checks/src/is-false.ts b/packages/checks/src/is-false.ts index 8dadd935c6..d022dc6a08 100644 --- a/packages/checks/src/is-false.ts +++ b/packages/checks/src/is-false.ts @@ -1,3 +1,2 @@ -export function isFalse(x: any): x is false { - return x === false; -} +export const isFalse = + (x: any): x is false => x === false; diff --git a/packages/checks/src/is-file.ts b/packages/checks/src/is-file.ts index 450a1771a4..0829b72054 100644 --- a/packages/checks/src/is-file.ts +++ b/packages/checks/src/is-file.ts @@ -1,3 +1,2 @@ -export function isFile(x: any): x is File { - return x instanceof File; -} +export const isFile = + (x: any): x is File => x instanceof File; diff --git a/packages/checks/src/is-firefox.ts b/packages/checks/src/is-firefox.ts index a903aded26..ac3be232de 100644 --- a/packages/checks/src/is-firefox.ts +++ b/packages/checks/src/is-firefox.ts @@ -1,3 +1,2 @@ -export function isFirefox() { - return typeof window !== "undefined" && !!window["InstallTrigger"]; -} +export const isFirefox = + () => typeof window !== "undefined" && !!window["InstallTrigger"]; diff --git a/packages/checks/src/is-function.ts b/packages/checks/src/is-function.ts index d474efcb26..b4f74a0716 100644 --- a/packages/checks/src/is-function.ts +++ b/packages/checks/src/is-function.ts @@ -1,3 +1,2 @@ -export function isFunction(x: any): x is Function { - return typeof x === "function"; -} +export const isFunction = + (x: any): x is Function => typeof x === "function"; diff --git a/packages/checks/src/is-ie.ts b/packages/checks/src/is-ie.ts index 0fc94de9d1..635d0dd6aa 100644 --- a/packages/checks/src/is-ie.ts +++ b/packages/checks/src/is-ie.ts @@ -1,5 +1,5 @@ -export function isIE() { - return typeof document !== "undefined" && +export const isIE = + () => + typeof document !== "undefined" && (typeof document["documentMode"] !== "undefined" || navigator.userAgent.indexOf("MSIE") > 0); -} diff --git a/packages/checks/src/is-in-range.ts b/packages/checks/src/is-in-range.ts index 80b89b5930..d1e5eca52f 100644 --- a/packages/checks/src/is-in-range.ts +++ b/packages/checks/src/is-in-range.ts @@ -1,3 +1,3 @@ -export function isInRange(min: number, max: number, x: number) { - return x >= min && x <= max; -} \ No newline at end of file +export const isInRange = + (min: number, max: number, x: number) => + x >= min && x <= max; diff --git a/packages/checks/src/is-int32.ts b/packages/checks/src/is-int32.ts index 60f520c9e3..9855cae552 100644 --- a/packages/checks/src/is-int32.ts +++ b/packages/checks/src/is-int32.ts @@ -1,3 +1,3 @@ -export function isInt32(x: any): x is number { - return typeof x === "number" && (x | 0) === x; -} +export const isInt32 = + (x: any): x is number => + typeof x === "number" && (x | 0) === x; diff --git a/packages/checks/src/is-iterable.ts b/packages/checks/src/is-iterable.ts index f15ab3f953..7bcda95b93 100644 --- a/packages/checks/src/is-iterable.ts +++ b/packages/checks/src/is-iterable.ts @@ -1,3 +1,3 @@ -export function isIterable(x: any): x is Iterable { - return x != null && typeof x[Symbol.iterator] === "function"; -} +export const isIterable = + (x: any): x is Iterable => + x != null && typeof x[Symbol.iterator] === "function"; diff --git a/packages/checks/src/is-map.ts b/packages/checks/src/is-map.ts index d895c5decc..eaa247dc65 100644 --- a/packages/checks/src/is-map.ts +++ b/packages/checks/src/is-map.ts @@ -1,3 +1,2 @@ -export function isMap(x: any): x is Map { - return x instanceof Map; -} +export const isMap = + (x: any): x is Map => x instanceof Map; diff --git a/packages/checks/src/is-mobile.ts b/packages/checks/src/is-mobile.ts index 96a7aef994..63eea28859 100644 --- a/packages/checks/src/is-mobile.ts +++ b/packages/checks/src/is-mobile.ts @@ -1,5 +1,5 @@ -export function isMobile() { - return typeof navigator !== "undefined" && +export const isMobile = + () => + typeof navigator !== "undefined" && /mobile|tablet|ip(ad|hone|od)|android|silk/i.test(navigator.userAgent) && !/crios/i.test(navigator.userAgent); -} diff --git a/packages/checks/src/is-nan.ts b/packages/checks/src/is-nan.ts index bf8ee8bb89..9a70106397 100644 --- a/packages/checks/src/is-nan.ts +++ b/packages/checks/src/is-nan.ts @@ -1,3 +1,2 @@ -export function isNaN(x: any) { - return x !== x; -} +export const isNaN = + (x: any) => x !== x; diff --git a/packages/checks/src/is-negative.ts b/packages/checks/src/is-negative.ts index d577df9f01..b31142b248 100644 --- a/packages/checks/src/is-negative.ts +++ b/packages/checks/src/is-negative.ts @@ -1,3 +1,3 @@ -export function isNegative(x: any): x is number { - return typeof x === "number" && x < 0; -} +export const isNegative = + (x: any): x is number => + typeof x === "number" && x < 0; diff --git a/packages/checks/src/is-node.ts b/packages/checks/src/is-node.ts index d99a8b015c..239f69c3fc 100644 --- a/packages/checks/src/is-node.ts +++ b/packages/checks/src/is-node.ts @@ -1,12 +1,13 @@ declare var process: any; -export function isNode() { - if (typeof process === "object") { - if (typeof process.versions === "object") { - if (typeof process.versions.node !== "undefined") { - return true; +export const isNode = + () => { + if (typeof process === "object") { + if (typeof process.versions === "object") { + if (typeof process.versions.node !== "undefined") { + return true; + } } } - } - return false; -} + return false; + }; diff --git a/packages/checks/src/is-not-string-iterable.ts b/packages/checks/src/is-not-string-iterable.ts index cef0d8f2df..d5c7886a5d 100644 --- a/packages/checks/src/is-not-string-iterable.ts +++ b/packages/checks/src/is-not-string-iterable.ts @@ -1,5 +1,5 @@ -export function isNotStringAndIterable(x: any): x is Iterable { - return x != null && +export const isNotStringAndIterable = + (x: any): x is Iterable => + x != null && typeof x !== "string" && typeof x[Symbol.iterator] === "function"; -} diff --git a/packages/checks/src/is-null.ts b/packages/checks/src/is-null.ts index 9e8acdc7bb..f09baa8188 100644 --- a/packages/checks/src/is-null.ts +++ b/packages/checks/src/is-null.ts @@ -1,3 +1,2 @@ -export function isNull(x: any): x is null { - return x === null; -} +export const isNull = + (x: any): x is null => x === null; diff --git a/packages/checks/src/is-number.ts b/packages/checks/src/is-number.ts index 9a56ac8cb2..9554093c76 100644 --- a/packages/checks/src/is-number.ts +++ b/packages/checks/src/is-number.ts @@ -1,3 +1,2 @@ -export function isNumber(x: any): x is number { - return typeof x === "number"; -} +export const isNumber = + (x: any): x is number => typeof x === "number"; diff --git a/packages/checks/src/is-object.ts b/packages/checks/src/is-object.ts index dca362c824..27d361aa2a 100644 --- a/packages/checks/src/is-object.ts +++ b/packages/checks/src/is-object.ts @@ -1,3 +1,3 @@ -export function isObject(x: any): x is Object { - return x !== null && typeof x === "object"; -} +export const isObject = + (x: any): x is Object => + x !== null && typeof x === "object"; diff --git a/packages/checks/src/is-odd.ts b/packages/checks/src/is-odd.ts index 46eb851ada..e394871b63 100644 --- a/packages/checks/src/is-odd.ts +++ b/packages/checks/src/is-odd.ts @@ -1,3 +1,2 @@ -export function isOdd(x: number) { - return (x % 2) !== 0; -} +export const isOdd = + (x: number) => (x % 2) !== 0; diff --git a/packages/checks/src/is-plain-object.ts b/packages/checks/src/is-plain-object.ts index ce694b554c..c37f935e46 100644 --- a/packages/checks/src/is-plain-object.ts +++ b/packages/checks/src/is-plain-object.ts @@ -6,8 +6,9 @@ const OBJP = Object.getPrototypeOf({}); * * @param x */ -export function isPlainObject(x: any): x is object { - let proto; - return Object.prototype.toString.call(x) === "[object Object]" && - (proto = Object.getPrototypeOf(x), proto === null || proto === OBJP); -} +export const isPlainObject = + (x: any): x is object => { + let proto; + return Object.prototype.toString.call(x) === "[object Object]" && + (proto = Object.getPrototypeOf(x), proto === null || proto === OBJP); + }; diff --git a/packages/checks/src/is-positive.ts b/packages/checks/src/is-positive.ts index d993b81cdc..85ed4d9502 100644 --- a/packages/checks/src/is-positive.ts +++ b/packages/checks/src/is-positive.ts @@ -1,3 +1,2 @@ -export function isPosititve(x: any): x is number { - return typeof x === "number" && x > 0; -} +export const isPosititve = + (x: any): x is number => typeof x === "number" && x > 0; diff --git a/packages/checks/src/is-promise.ts b/packages/checks/src/is-promise.ts index d950e5f9e7..8be66e5903 100644 --- a/packages/checks/src/is-promise.ts +++ b/packages/checks/src/is-promise.ts @@ -1,3 +1,2 @@ -export function isPromise(x: any): x is Promise { - return x instanceof Promise; -} +export const isPromise = + (x: any): x is Promise => x instanceof Promise; diff --git a/packages/checks/src/is-promiselike.ts b/packages/checks/src/is-promiselike.ts index a02355a677..3a2b4a66e4 100644 --- a/packages/checks/src/is-promiselike.ts +++ b/packages/checks/src/is-promiselike.ts @@ -1,6 +1,6 @@ import { implementsFunction } from "./implements-function"; -export function isPromiseLike(x: any): x is Promise { - return x instanceof Promise || +export const isPromiseLike = + (x: any): x is Promise => + x instanceof Promise || (implementsFunction(x, "then") && implementsFunction(x, "catch")); -} diff --git a/packages/checks/src/is-regexp.ts b/packages/checks/src/is-regexp.ts index 9c265f7875..715be99056 100644 --- a/packages/checks/src/is-regexp.ts +++ b/packages/checks/src/is-regexp.ts @@ -1,3 +1,2 @@ -export function isRegExp(x: any): x is RegExp { - return x instanceof RegExp; -} +export const isRegExp = + (x: any): x is RegExp => x instanceof RegExp; diff --git a/packages/checks/src/is-safari.ts b/packages/checks/src/is-safari.ts index 19d3011218..5976f70158 100644 --- a/packages/checks/src/is-safari.ts +++ b/packages/checks/src/is-safari.ts @@ -1,5 +1,7 @@ import { isChrome } from "./is-chrome"; -export function isSafari() { - return typeof navigator !== "undefined" && /Safari/.test(navigator.userAgent) && !isChrome(); -} +export const isSafari = + () => + typeof navigator !== "undefined" && + /Safari/.test(navigator.userAgent) && + !isChrome(); diff --git a/packages/checks/src/is-set.ts b/packages/checks/src/is-set.ts index a7e5d3e65b..468813acb9 100644 --- a/packages/checks/src/is-set.ts +++ b/packages/checks/src/is-set.ts @@ -1,3 +1,2 @@ -export function isSet(x: any): x is Set { - return x instanceof Set; -} +export const isSet = + (x: any): x is Set => x instanceof Set; diff --git a/packages/checks/src/is-string.ts b/packages/checks/src/is-string.ts index 4f4937b2df..1bddcaebc7 100644 --- a/packages/checks/src/is-string.ts +++ b/packages/checks/src/is-string.ts @@ -1,3 +1,2 @@ -export function isString(x: any): x is string { - return typeof x === "string"; -} +export const isString = + (x: any): x is string => typeof x === "string"; diff --git a/packages/checks/src/is-symbol.ts b/packages/checks/src/is-symbol.ts index fe417d1823..92fe97c84d 100644 --- a/packages/checks/src/is-symbol.ts +++ b/packages/checks/src/is-symbol.ts @@ -1,3 +1,2 @@ -export function isSymbol(x: any): x is Symbol { - return typeof x === "symbol"; -} +export const isSymbol = + (x: any): x is Symbol => typeof x === "symbol"; diff --git a/packages/checks/src/is-transferable.ts b/packages/checks/src/is-transferable.ts index af2f3cab43..d5e12fb210 100644 --- a/packages/checks/src/is-transferable.ts +++ b/packages/checks/src/is-transferable.ts @@ -1,7 +1,7 @@ declare var SharedArrayBuffer: any; -export function isTransferable(x: any) { - return x instanceof ArrayBuffer || +export const isTransferable = + (x: any) => + x instanceof ArrayBuffer || (typeof SharedArrayBuffer !== "undefined" && x instanceof SharedArrayBuffer) || (typeof MessagePort !== "undefined" && x instanceof MessagePort); -} diff --git a/packages/checks/src/is-true.ts b/packages/checks/src/is-true.ts index d51b37136b..f88d7fda45 100644 --- a/packages/checks/src/is-true.ts +++ b/packages/checks/src/is-true.ts @@ -1,3 +1,2 @@ -export function isTrue(x: any): x is boolean { - return x === true; -} +export const isTrue = + (x: any): x is boolean => x === true; diff --git a/packages/checks/src/is-typedarray.ts b/packages/checks/src/is-typedarray.ts index 1fd85470bc..1eeaa6b26e 100644 --- a/packages/checks/src/is-typedarray.ts +++ b/packages/checks/src/is-typedarray.ts @@ -1,11 +1,11 @@ -export function isTypedArray(x: any): x is ArrayLike { - return x && (x.constructor === Float32Array || - x.constructor === Uint32Array || - x.constructor === Uint8Array || - x.constructor === Uint8ClampedArray || - x.constructor === Int8Array || - x.constructor === Uint16Array || - x.constructor === Int16Array || - x.constructor === Int32Array || - x.constructor === Float64Array); -} +export const isTypedArray = + (x: any): x is ArrayLike => + x && (x.constructor === Float32Array || + x.constructor === Uint32Array || + x.constructor === Uint8Array || + x.constructor === Uint8ClampedArray || + x.constructor === Int8Array || + x.constructor === Uint16Array || + x.constructor === Int16Array || + x.constructor === Int32Array || + x.constructor === Float64Array); diff --git a/packages/checks/src/is-uint32.ts b/packages/checks/src/is-uint32.ts index 66dc4c1d1e..7a6bdb1b41 100644 --- a/packages/checks/src/is-uint32.ts +++ b/packages/checks/src/is-uint32.ts @@ -1,3 +1,3 @@ -export function isUint32(x: any): x is number { - return typeof x === "number" && (x >>> 0) === x; -} +export const isUint32 = + (x: any): x is number => + typeof x === "number" && (x >>> 0) === x; diff --git a/packages/checks/src/is-undefined.ts b/packages/checks/src/is-undefined.ts index acc51707eb..ee36222a69 100644 --- a/packages/checks/src/is-undefined.ts +++ b/packages/checks/src/is-undefined.ts @@ -1,3 +1,2 @@ -export function isUndefined(x: any): x is undefined { - return x === undefined; -} +export const isUndefined = + (x: any): x is undefined => x === undefined; diff --git a/packages/checks/src/is-uuid.ts b/packages/checks/src/is-uuid.ts index 53c250a6c4..fe7b2c60b4 100644 --- a/packages/checks/src/is-uuid.ts +++ b/packages/checks/src/is-uuid.ts @@ -1,3 +1,4 @@ -export function isUUID(x: string) { - return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(x); -} +const RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; + +export const isUUID = + (x: string) => RE.test(x); diff --git a/packages/checks/src/is-uuid4.ts b/packages/checks/src/is-uuid4.ts index bcf27d480d..6045145718 100644 --- a/packages/checks/src/is-uuid4.ts +++ b/packages/checks/src/is-uuid4.ts @@ -1,3 +1,4 @@ -export function isUUIDv4(x: string) { - return /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(x); -} +const RE = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + +export const isUUIDv4 = + (x: string) => RE.test(x); diff --git a/packages/checks/src/is-zero.ts b/packages/checks/src/is-zero.ts index 79ceb96f8c..6a67a7ba98 100644 --- a/packages/checks/src/is-zero.ts +++ b/packages/checks/src/is-zero.ts @@ -1,3 +1,2 @@ -export function isZero(x: any): x is 0 { - return x === 0; -} +export const isZero = + (x: any): x is 0 => x === 0; From fc22a27e2c50f34caf3e6aa9ecce1b5fb0c1728d Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 03:52:57 +0000 Subject: [PATCH 184/333] refactor(paths): update all as arrow fns --- packages/paths/src/index.ts | 287 +++++++++++++++++++----------------- 1 file changed, 152 insertions(+), 135 deletions(-) diff --git a/packages/paths/src/index.ts b/packages/paths/src/index.ts index fe34929594..7ee36b787a 100644 --- a/packages/paths/src/index.ts +++ b/packages/paths/src/index.ts @@ -1,4 +1,3 @@ -import { isArray } from "@thi.ng/checks/is-array"; import { isString } from "@thi.ng/checks/is-string"; import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; @@ -6,9 +5,12 @@ export type Path = PropertyKey | PropertyKey[]; export type UpdateFn = (curr: T, ...args: any[]) => T; -const _copy = (s) => Array.isArray(s) ? s.slice() : { ...s }; +const isa = Array.isArray; +const iss = isString; -const compS = (k, f) => (s, v) => { s = _copy(s); s[k] = f ? f(s[k], v) : v; return s; } +const _copy = (s) => isa(s) ? s.slice() : { ...s }; + +const compS = (k, f) => (s, v) => (s = _copy(s), s[k] = (f ? f(s[k], v) : v), s); const compG = (k, f) => (s) => s ? f(s[k]) : undefined; @@ -28,9 +30,17 @@ const compG = (k, f) => (s) => s ? f(s[k]) : undefined; * * @param path */ -export function toPath(path: Path) { - return isArray(path) ? path : isString(path) ? path.length > 0 ? path.split(".") : [] : path != null ? [path] : []; -} +export const toPath = + (path: Path) => + isa(path) ? + path : + iss(path) ? + path.length > 0 ? + path.split(".") : + [] : + path != null ? + [path] : + []; /** * Takes an arbitrary object and lookup path. Descends into object along @@ -41,23 +51,24 @@ export function toPath(path: Path) { * @param obj * @param path */ -export const exists = (obj: any, path: Path) => { - if (obj == null) { - return false; - } - path = toPath(path); - for (let n = path.length - 1, i = 0; i <= n; i++) { - const k = path[i]; - if (!obj.hasOwnProperty(k)) { +export const exists = + (obj: any, path: Path) => { + if (obj == null) { return false; } - obj = obj[k]; - if (obj == null && i < n) { - return false; + path = toPath(path); + for (let n = path.length - 1, i = 0; i <= n; i++) { + const k = path[i]; + if (!obj.hasOwnProperty(k)) { + return false; + } + obj = obj[k]; + if (obj == null && i < n) { + return false; + } } - } - return true; -}; + return true; + }; /** * Composes a getter function for given nested lookup path. Optimized @@ -89,29 +100,30 @@ export const exists = (obj: any, path: Path) => { * * @param path */ -export function getter(path: Path) { - const ks = toPath(path); - let [a, b, c, d] = ks; - switch (ks.length) { - case 0: - return (s) => s; - case 1: - return (s) => s ? s[a] : undefined; - case 2: - return (s) => s ? (s = s[a]) ? s[b] : undefined : undefined; - case 3: - return (s) => s ? (s = s[a]) ? (s = s[b]) ? s[c] : undefined : undefined : undefined; - case 4: - return (s) => s ? (s = s[a]) ? (s = s[b]) ? (s = s[c]) ? s[d] : undefined : undefined : undefined : undefined; - default: - const kl = ks[ks.length - 1]; - let f = (s) => s ? s[kl] : undefined; - for (let i = ks.length - 2; i >= 0; i--) { - f = compG(ks[i], f); - } - return f; - } -} +export const getter = + (path: Path) => { + const ks = toPath(path); + let [a, b, c, d] = ks; + switch (ks.length) { + case 0: + return (s) => s; + case 1: + return (s) => s ? s[a] : undefined; + case 2: + return (s) => s ? (s = s[a]) ? s[b] : undefined : undefined; + case 3: + return (s) => s ? (s = s[a]) ? (s = s[b]) ? s[c] : undefined : undefined : undefined; + case 4: + return (s) => s ? (s = s[a]) ? (s = s[b]) ? (s = s[c]) ? s[d] : undefined : undefined : undefined : undefined; + default: + const kl = ks[ks.length - 1]; + let f = (s) => s ? s[kl] : undefined; + for (let i = ks.length - 1; --i >= 0;) { + f = compG(ks[i], f); + } + return f; + } + }; /** * Composes a setter function for given nested update path. Optimized @@ -166,28 +178,29 @@ export function getter(path: Path) { * * @param path */ -export function setter(path: Path): (s: any, v: any) => any { - const ks = toPath(path); - let [a, b, c, d] = ks; - switch (ks.length) { - case 0: - return (_, v) => v; - case 1: - return (s, v) => (s = _copy(s), s[a] = v, s); - case 2: - return (s, v) => { let x; s = _copy(s); s[a] = x = _copy(s[a]); x[b] = v; return s; }; - case 3: - return (s, v) => { let x, y; s = _copy(s); s[a] = x = _copy(s[a]); x[b] = y = _copy(x[b]); y[c] = v; return s; }; - case 4: - return (s, v) => { let x, y, z; s = _copy(s); s[a] = x = _copy(s[a]); x[b] = y = _copy(x[b]); y[c] = z = _copy(y[c]); z[d] = v; return s; }; - default: - let f; - for (let i = ks.length - 1; i >= 0; i--) { - f = compS(ks[i], f); - } - return f; - } -} +export const setter = + (path: Path): (s: any, v: any) => any => { + const ks = toPath(path); + let [a, b, c, d] = ks; + switch (ks.length) { + case 0: + return (_, v) => v; + case 1: + return (s, v) => (s = _copy(s), s[a] = v, s); + case 2: + return (s, v) => { let x; s = _copy(s); s[a] = x = _copy(s[a]); x[b] = v; return s; }; + case 3: + return (s, v) => { let x, y; s = _copy(s); s[a] = x = _copy(s[a]); x[b] = y = _copy(x[b]); y[c] = v; return s; }; + case 4: + return (s, v) => { let x, y, z; s = _copy(s); s[a] = x = _copy(s[a]); x[b] = y = _copy(x[b]); y[c] = z = _copy(y[c]); z[d] = v; return s; }; + default: + let f; + for (let i = ks.length; --i >= 0;) { + f = compS(ks[i], f); + } + return f; + } + }; /** * Immediate use getter, i.e. same as: `getter(path)(state)`. @@ -200,9 +213,9 @@ export function setter(path: Path): (s: any, v: any) => any { * @param state * @param path */ -export function getIn(state: any, path: Path) { - return getter(path)(state); -} +export const getIn = + (state: any, path: Path) => + getter(path)(state); /** * Immediate use setter, i.e. same as: `setter(path)(state, val)`. @@ -215,9 +228,9 @@ export function getIn(state: any, path: Path) { * @param state * @param path */ -export function setIn(state: any, path: Path, val: any) { - return setter(path)(state, val); -} +export const setIn = + (state: any, path: Path, val: any) => + setter(path)(state, val); /** * Like `setIn()`, but takes any number of path-value pairs and applies @@ -233,16 +246,15 @@ export function setIn(state: any, path: Path, val: any) { * @param state * @param pairs */ -export function setInMany(state: any, ...pairs: any[]) { - const n = pairs.length; - if ((n & 1)) { - illegalArgs(`require an even number of args (got ${pairs.length})`); - } - for (let i = 0; i < n; i += 2) { - state = setIn(state, pairs[i], pairs[i + 1]); - } - return state; -} +export const setInMany = + (state: any, ...pairs: any[]) => { + const n = pairs.length; + (n & 1) && illegalArgs(`require even number of args (got ${pairs.length})`); + for (let i = 0; i < n; i += 2) { + state = setIn(state, pairs[i], pairs[i + 1]); + } + return state; + }; /** * Similar to `setter()`, returns a function to update values at given @@ -262,12 +274,13 @@ export function setInMany(state: any, ...pairs: any[]) { * @param path * @param fn */ -export function updater(path: Path, fn: UpdateFn) { - const g = getter(path); - const s = setter(path); - return (state: any, ...args: any[]) => - s(state, fn.apply(null, (args.unshift(g(state)), args))); -}; +export const updater = + (path: Path, fn: UpdateFn) => { + const g = getter(path); + const s = setter(path); + return (state: any, ...args: any[]) => + s(state, fn.apply(null, (args.unshift(g(state)), args))); + }; /** * Similar to `setIn()`, but applies given function to current path @@ -284,9 +297,12 @@ export function updater(path: Path, fn: UpdateFn) { * @param state * @param path */ -export function updateIn(state: any, path: Path, fn: UpdateFn, ...args: any[]) { - return setter(path)(state, fn.apply(null, (args.unshift(getter(path)(state)), args))); -} +export const updateIn = + (state: any, path: Path, fn: UpdateFn, ...args: any[]) => + setter(path)( + state, + fn.apply(null, (args.unshift(getter(path)(state)), args)) + ); /** * Uses `updateIn()` and returns updated state with key for given path @@ -302,13 +318,14 @@ export function updateIn(state: any, path: Path, fn: UpdateFn, ...args: any * @param state * @param path */ -export function deleteIn(state: any, path: Path) { - const ks = [...toPath(path)]; - if (ks.length > 0) { - const k = ks.pop(); - return updateIn(state, ks, (x) => { x = { ...x }; delete x[k]; return x; }); - } -} +export const deleteIn = + (state: any, path: Path) => { + const ks = [...toPath(path)]; + if (ks.length > 0) { + const k = ks.pop(); + return updateIn(state, ks, (x) => (x = { ...x }, delete x[k], x)); + } + }; /** * Higher-order function, similar to `setter()`. Returns function which @@ -321,32 +338,33 @@ export function deleteIn(state: any, path: Path) { * * @param path */ -export function mutator(path: Path) { - const ks = toPath(path); - let [a, b, c, d] = ks; - switch (ks.length) { - case 0: - return (_, x) => x; - case 1: - return (s, x) => s ? (s[a] = x, s) : undefined; - case 2: - return (s, x) => { let t; return s ? (t = s[a]) ? (t[b] = x, s) : undefined : undefined }; - case 3: - return (s, x) => { let t; return s ? (t = s[a]) ? (t = t[b]) ? (t[c] = x, s) : undefined : undefined : undefined }; - case 4: - return (s, x) => { let t; return s ? (t = s[a]) ? (t = t[b]) ? (t = t[c]) ? (t[d] = x, s) : undefined : undefined : undefined : undefined }; - default: - return (s, x) => { - let t = s; - const n = ks.length - 1; - for (let k = 0; k < n; k++) { - if (!(t = t[ks[k]])) return; +export const mutator = + (path: Path) => { + const ks = toPath(path); + let [a, b, c, d] = ks; + switch (ks.length) { + case 0: + return (_, x) => x; + case 1: + return (s, x) => s ? (s[a] = x, s) : undefined; + case 2: + return (s, x) => { let t; return s ? (t = s[a]) ? (t[b] = x, s) : undefined : undefined }; + case 3: + return (s, x) => { let t; return s ? (t = s[a]) ? (t = t[b]) ? (t[c] = x, s) : undefined : undefined : undefined }; + case 4: + return (s, x) => { let t; return s ? (t = s[a]) ? (t = t[b]) ? (t = t[c]) ? (t[d] = x, s) : undefined : undefined : undefined : undefined }; + default: + return (s, x) => { + let t = s; + const n = ks.length - 1; + for (let k = 0; k < n; k++) { + if (!(t = t[ks[k]])) return; + } + t[ks[n]] = x; + return s; } - t[ks[n]] = x; - return s; - } - } -} + } + }; /** * Immediate use mutator, i.e. same as: `mutator(path)(state, val)`. @@ -364,9 +382,9 @@ export function mutator(path: Path) { * @param path * @param val */ -export function mutIn(state: any, path: Path, val: any) { - return mutator(path)(state, val); -} +export const mutIn = + (state: any, path: Path, val: any) => + mutator(path)(state, val); /** * Like `mutIn()`, but takes any number of path-value pairs and applies @@ -381,13 +399,12 @@ export function mutIn(state: any, path: Path, val: any) { * @param state * @param pairs */ -export function mutInMany(state: any, ...pairs: any[]) { - const n = pairs.length; - if ((n & 1)) { - illegalArgs(`require an even number of args (got ${pairs.length})`); - } - for (let i = 0; i < n && state; i += 2) { - state = mutIn(state, pairs[i], pairs[i + 1]); - } - return state; -} +export const mutInMany = + (state: any, ...pairs: any[]) => { + const n = pairs.length; + (n & 1) && illegalArgs(`require even number of args (got ${pairs.length})`); + for (let i = 0; i < n && state; i += 2) { + state = mutIn(state, pairs[i], pairs[i + 1]); + } + return state; + }; From aaf2723ffb1e50887b1fec0a827c61298098b553 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 06:12:07 +0000 Subject: [PATCH 185/333] refactor(associative): use arrow fns, update formatting --- packages/associative/src/common-keys.ts | 34 +++++++++++---------- packages/associative/src/difference.ts | 21 ++++++------- packages/associative/src/indexed.ts | 23 +++++++------- packages/associative/src/intersection.ts | 29 +++++++++--------- packages/associative/src/invert.ts | 30 ++++++++++--------- packages/associative/src/join.ts | 17 ++++++++--- packages/associative/src/merge-apply.ts | 38 +++++++++++++----------- packages/associative/src/merge-deep.ts | 15 ++++++---- packages/associative/src/merge-with.ts | 18 ++++++++--- packages/associative/src/merge.ts | 21 ++++++------- packages/associative/src/rename-keys.ts | 30 ++++++++++--------- packages/associative/src/select-keys.ts | 34 +++++++++++---------- packages/associative/src/union.ts | 27 +++++++++-------- 13 files changed, 188 insertions(+), 149 deletions(-) diff --git a/packages/associative/src/common-keys.ts b/packages/associative/src/common-keys.ts index 513736f4d1..bb647f358d 100644 --- a/packages/associative/src/common-keys.ts +++ b/packages/associative/src/common-keys.ts @@ -6,15 +6,16 @@ import { IObjectOf } from "@thi.ng/api/api"; * @param a * @param b */ -export function commonKeysMap(a: Map, b: Map) { - const res: K[] = []; - for (let k of a.keys()) { - if (b.has(k)) { - res.push(k); +export const commonKeysMap = + (a: Map, b: Map) => { + const res: K[] = []; + for (let k of a.keys()) { + if (b.has(k)) { + res.push(k); + } } - } - return res; -} + return res; + }; /** * Returns array of keys present in both args, i.e. the set intersection @@ -28,12 +29,13 @@ export function commonKeysMap(a: Map, b: Map) { * @param a * @param b */ -export function commonKeysObj(a: IObjectOf, b: IObjectOf) { - const res: string[] = []; - for (let k in a) { - if (b.hasOwnProperty(k)) { - res.push(k); +export const commonKeysObj = + (a: IObjectOf, b: IObjectOf) => { + const res: string[] = []; + for (let k in a) { + if (b.hasOwnProperty(k)) { + res.push(k); + } } - } - return res; -} + return res; + }; diff --git a/packages/associative/src/difference.ts b/packages/associative/src/difference.ts index b3af70cb30..af90913daa 100644 --- a/packages/associative/src/difference.ts +++ b/packages/associative/src/difference.ts @@ -1,12 +1,13 @@ import { copy, empty } from "./utils"; -export function difference(a: Set, b: Set): Set { - if (a === b) { - return empty(a, Set); - } - const res = copy(a, Set); - for (let i of b) { - res.delete(i); - } - return res; -} +export const difference = + (a: Set, b: Set): Set => { + if (a === b) { + return empty(a, Set); + } + const res = copy(a, Set); + for (let i of b) { + res.delete(i); + } + return res; + }; diff --git a/packages/associative/src/indexed.ts b/packages/associative/src/indexed.ts index f54b920e45..7b91ba8885 100644 --- a/packages/associative/src/indexed.ts +++ b/packages/associative/src/indexed.ts @@ -20,14 +20,15 @@ import { empty } from "./utils"; * @param records objects to index * @param ks keys used for indexing */ -export function indexed(records: Iterable, ks: PropertyKey[]) { - const res = new EquivMap>(); - let x, ik, rv; - for (x of records) { - ik = selectKeysObj(x, ks); - rv = res.get(ik); - !rv && res.set(ik, rv = empty(records, Set)); - rv.add(x); - } - return res; -} +export const indexed = + (records: Iterable, ks: PropertyKey[]) => { + const res = new EquivMap>(); + let x, ik, rv; + for (x of records) { + ik = selectKeysObj(x, ks); + rv = res.get(ik); + !rv && res.set(ik, rv = empty(records, Set)); + rv.add(x); + } + return res; + }; diff --git a/packages/associative/src/intersection.ts b/packages/associative/src/intersection.ts index 31ec753705..d3b2daafa3 100644 --- a/packages/associative/src/intersection.ts +++ b/packages/associative/src/intersection.ts @@ -1,17 +1,18 @@ import { empty } from "./utils"; -export function intersection(a: Set, b: Set): Set { - if (a === b) { - return a; - } - if (b.size < a.size) { - return intersection(b, a); - } - const res = empty(a, Set); - for (let i of b) { - if (a.has(i)) { - res.add(i); +export const intersection = + (a: Set, b: Set): Set => { + if (a === b) { + return a; } - } - return res; -} + if (b.size < a.size) { + return intersection(b, a); + } + const res = empty(a, Set); + for (let i of b) { + if (a.has(i)) { + res.add(i); + } + } + return res; + }; diff --git a/packages/associative/src/invert.ts b/packages/associative/src/invert.ts index 35ca6ca375..2429da833e 100644 --- a/packages/associative/src/invert.ts +++ b/packages/associative/src/invert.ts @@ -13,13 +13,14 @@ import { empty } from "./utils"; * * @param src */ -export function invertMap(src: Map) { - const dest: Map = empty(src, Map); - for (let p of src) { - dest.set(p[1], p[0]); - } - return dest; -} +export const invertMap = + (src: Map) => { + const dest: Map = empty(src, Map); + for (let p of src) { + dest.set(p[1], p[0]); + } + return dest; + }; /** * Returns a new object in which the original values are used as keys @@ -32,10 +33,11 @@ export function invertMap(src: Map) { * * @param src */ -export function invertObj(src: IObjectOf) { - const dest: IObjectOf = {}; - for (let k in src) { - dest[src[k]] = k; - } - return dest; -} +export const invertObj = + (src: IObjectOf) => { + const dest: IObjectOf = {}; + for (let k in src) { + dest[src[k]] = k; + } + return dest; + }; diff --git a/packages/associative/src/join.ts b/packages/associative/src/join.ts index 4f81f7ef0b..e3c2421759 100644 --- a/packages/associative/src/join.ts +++ b/packages/associative/src/join.ts @@ -34,7 +34,11 @@ import { empty, first, objValues } from "./utils"; * @param xrel * @param yrel */ -export function join(xrel: Set>, yrel: Set>): Set> { +export const join = ( + xrel: Set>, + yrel: Set> +): Set> => { + if (xrel.size && yrel.size) { const ks = commonKeysObj(first(xrel) || {}, first(yrel) || {}); let a: Set, b: Set; @@ -58,7 +62,7 @@ export function join(xrel: Set>, yrel: Set>): Set< return res; } return empty(xrel, Set); -} +}; /** * Similar to `join()`, computes the join between two sets of relations, @@ -88,7 +92,12 @@ export function join(xrel: Set>, yrel: Set>): Set< * @param yrel * @param kmap keys to compute join for */ -export function joinWith(xrel: Set, yrel: Set, kmap: IObjectOf): Set { +export const joinWith = ( + xrel: Set, + yrel: Set, + kmap: IObjectOf +): Set => { + if (xrel.size && yrel.size) { let r: Set, s: Set; let k: IObjectOf; @@ -115,4 +124,4 @@ export function joinWith(xrel: Set, yrel: Set, kmap: IObjectOf(src: Map, xs: Map V)>) { - const res: any = copy(src, Map); - for (let p of xs) { - let [k, v] = p; - isFunction(v) && (v = v(res[k])); - res.set(k, v); - } - return res; -} +export const mergeApplyMap = + (src: Map, xs: Map V)>) => { + const res: any = copy(src, Map); + for (let p of xs) { + let [k, v] = p; + isFunction(v) && (v = v(res[k])); + res.set(k, v); + } + return res; + }; /** * Similar to `mergeObj()`, but only supports 2 args and any function @@ -33,12 +34,13 @@ export function mergeApplyMap(src: Map, xs: Map V) * @param src * @param xs */ -export function mergeApplyObj(src: IObjectOf, xs: IObjectOf V)>) { - const res: any = { ...src }; - for (let k in xs) { - let v = xs[k]; - isFunction(v) && (v = v(res[k])); - res[k] = v; - } - return res; -} +export const mergeApplyObj = + (src: IObjectOf, xs: IObjectOf V)>) => { + const res: any = { ...src }; + for (let k in xs) { + let v = xs[k]; + isFunction(v) && (v = v(res[k])); + res[k] = v; + } + return res; + }; diff --git a/packages/associative/src/merge-deep.ts b/packages/associative/src/merge-deep.ts index b05eef217d..11e41b6b97 100644 --- a/packages/associative/src/merge-deep.ts +++ b/packages/associative/src/merge-deep.ts @@ -3,8 +3,13 @@ import { isPlainObject } from "@thi.ng/checks/is-plain-object"; import { mergeObjWith } from "./merge-with"; -export function mergeDeepObj(dest: IObjectOf, ...xs: IObjectOf[]) { - return mergeObjWith( - (a, b) => isPlainObject(a) && isPlainObject(b) ? mergeDeepObj(a, b) : b, - dest, ...xs); -} +export const mergeDeepObj = + (dest: IObjectOf, ...xs: IObjectOf[]) => + mergeObjWith( + (a, b) => + isPlainObject(a) && isPlainObject(b) ? + mergeDeepObj(a, b) : + b, + dest, + ...xs + ); diff --git a/packages/associative/src/merge-with.ts b/packages/associative/src/merge-with.ts index 364cc28240..64f79b80ed 100644 --- a/packages/associative/src/merge-with.ts +++ b/packages/associative/src/merge-with.ts @@ -2,7 +2,12 @@ import { IObjectOf } from "@thi.ng/api/api"; import { copy } from "./utils"; -export function mergeMapWith(f: (a: V, b: V) => V, dest: Map, ...xs: Map[]) { +export const mergeMapWith = ( + f: (a: V, b: V) => V, + dest: Map, + ...xs: Map[] +) => { + const res: Map = copy(dest, Map); for (let x of xs) { for (let [k, v] of x) { @@ -14,9 +19,14 @@ export function mergeMapWith(f: (a: V, b: V) => V, dest: Map, ...xs: } } return res; -} +}; + +export const mergeObjWith = ( + f: (a: T, b: T) => T, + dest: IObjectOf, + ...xs: IObjectOf[] +) => { -export function mergeObjWith(f: (a: T, b: T) => T, dest: IObjectOf, ...xs: IObjectOf[]) { const res: IObjectOf = { ...dest }; for (let x of xs) { for (let k in x) { @@ -29,4 +39,4 @@ export function mergeObjWith(f: (a: T, b: T) => T, dest: IObjectOf, ...xs: } } return res; -} +}; diff --git a/packages/associative/src/merge.ts b/packages/associative/src/merge.ts index 2da2a81a37..da901fa7f0 100644 --- a/packages/associative/src/merge.ts +++ b/packages/associative/src/merge.ts @@ -7,14 +7,15 @@ import { IObjectOf } from "@thi.ng/api/api"; * @param dest * @param xs */ -export function mergeMap(dest: Map, ...xs: Map[]) { - for (let x of xs) { - for (let pair of x) { - dest.set(pair[0], pair[1]); +export const mergeMap = + (dest: Map, ...xs: Map[]) => { + for (let x of xs) { + for (let pair of x) { + dest.set(pair[0], pair[1]); + } } - } - return dest; -} + return dest; + }; /** * Merges all given objects in left-to-right order into `dest`. @@ -23,6 +24,6 @@ export function mergeMap(dest: Map, ...xs: Map[]) { * @param dest * @param xs */ -export function mergeObj(dest: IObjectOf, ...xs: IObjectOf[]): IObjectOf { - return Object.assign(dest, ...xs); -} +export const mergeObj = + (dest: IObjectOf, ...xs: IObjectOf[]): IObjectOf => + Object.assign(dest, ...xs); diff --git a/packages/associative/src/rename-keys.ts b/packages/associative/src/rename-keys.ts index 860186ce1a..af06d7e462 100644 --- a/packages/associative/src/rename-keys.ts +++ b/packages/associative/src/rename-keys.ts @@ -9,13 +9,14 @@ import { empty } from "./utils"; * @param src * @param km */ -export function renameKeysMap(src: Map, km: Map) { - const dest: Map = empty(src, Map); - for (let [k, v] of src) { - dest.set(km.has(k) ? km.get(k) : k, v); - } - return dest; -} +export const renameKeysMap = + (src: Map, km: Map) => { + const dest: Map = empty(src, Map); + for (let [k, v] of src) { + dest.set(km.has(k) ? km.get(k) : k, v); + } + return dest; + }; /** * Renames keys in `src` using mapping provided by key map `km`. Does @@ -30,10 +31,11 @@ export function renameKeysMap(src: Map, km: Map) { * @param src * @param km */ -export function renameKeysObj(src: IObjectOf, km: IObjectOf) { - const dest = {}; - for (let k in src) { - dest[km.hasOwnProperty(k) ? km[k] : k] = src[k]; - } - return dest; -} +export const renameKeysObj = + (src: IObjectOf, km: IObjectOf) => { + const dest = {}; + for (let k in src) { + dest[km.hasOwnProperty(k) ? km[k] : k] = src[k]; + } + return dest; + }; diff --git a/packages/associative/src/select-keys.ts b/packages/associative/src/select-keys.ts index 28c60f18ac..9307b4e6e8 100644 --- a/packages/associative/src/select-keys.ts +++ b/packages/associative/src/select-keys.ts @@ -9,15 +9,16 @@ import { empty } from "./utils"; * @param src * @param ks selected keys */ -export function selectKeysMap(src: Map, ks: Iterable): any { - const dest = empty(src, Map); - for (let k of ks) { - if (src.has(k)) { - dest.set(k, src.get(k)); +export const selectKeysMap = + (src: Map, ks: Iterable): any => { + const dest = empty(src, Map); + for (let k of ks) { + if (src.has(k)) { + dest.set(k, src.get(k)); + } } - } - return dest; -} + return dest; + }; /** * Returns a new object only containing given keys (and only if they @@ -26,12 +27,13 @@ export function selectKeysMap(src: Map, ks: Iterable): any { * @param src * @param ks */ -export function selectKeysObj(src: IObjectOf, ks: Iterable): any { - const dest: IObjectOf = {}; - for (let k of ks) { - if (src.hasOwnProperty(k)) { - dest[k] = src[k]; +export const selectKeysObj = + (src: IObjectOf, ks: Iterable): any => { + const dest: IObjectOf = {}; + for (let k of ks) { + if (src.hasOwnProperty(k)) { + dest[k] = src[k]; + } } - } - return dest; -} + return dest; + }; diff --git a/packages/associative/src/union.ts b/packages/associative/src/union.ts index ce185e89eb..f223644601 100644 --- a/packages/associative/src/union.ts +++ b/packages/associative/src/union.ts @@ -1,15 +1,16 @@ import { copy } from "./utils"; -export function union(a: Set, b: Set): Set { - if (a === b) { - return a; - } - if (b.size > a.size) { - return union(b, a); - } - const res = copy(a, Set); - for (let i of b) { - res.add(i); - } - return res; -} \ No newline at end of file +export const union = + (a: Set, b: Set): Set => { + if (a === b) { + return a; + } + if (b.size > a.size) { + return union(b, a); + } + const res = copy(a, Set); + for (let i of b) { + res.add(i); + } + return res; + }; From 025412a04674545f4575f1a599fa4859dec31b20 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 06:12:45 +0000 Subject: [PATCH 186/333] refactor(compare): use arrow fns --- packages/compare/src/index.ts | 37 ++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/packages/compare/src/index.ts b/packages/compare/src/index.ts index 3cb0aa864d..32aeca5556 100644 --- a/packages/compare/src/index.ts +++ b/packages/compare/src/index.ts @@ -1,18 +1,19 @@ -export function compare(a: any, b: any): number { - if (a === b) { - return 0; - } - if (a == null) { - return b == null ? 0 : -1; - } - if (b == null) { - return a == null ? 0 : 1; - } - if (typeof a.compare === "function") { - return a.compare(b); - } - if (typeof b.compare === "function") { - return -b.compare(a); - } - return a < b ? -1 : a > b ? 1 : 0; -} +export const compare = + (a: any, b: any): number => { + if (a === b) { + return 0; + } + if (a == null) { + return b == null ? 0 : -1; + } + if (b == null) { + return a == null ? 0 : 1; + } + if (typeof a.compare === "function") { + return a.compare(b); + } + if (typeof b.compare === "function") { + return -b.compare(a); + } + return a < b ? -1 : a > b ? 1 : 0; + }; From 35377bd580f439cdf032a7c3547ee29f2fb93477 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 06:13:22 +0000 Subject: [PATCH 187/333] refactor(compose): use arrow fns --- packages/compose/src/thread-first.ts | 20 ++++++++++---------- packages/compose/src/thread-last.ts | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/compose/src/thread-first.ts b/packages/compose/src/thread-first.ts index fbb77209e7..9b268b93c5 100644 --- a/packages/compose/src/thread-first.ts +++ b/packages/compose/src/thread-first.ts @@ -26,13 +26,13 @@ import { FnAny } from "@thi.ng/api/api"; * @param init * @param fns */ -export function threadFirst(init: any, ...fns: (FnAny | [FnAny, ...any[]])[]) { - return fns.reduce( - (acc, expr) => - typeof expr === "function" ? - expr(acc) : - expr[0](acc, ...expr.slice(1)) - , - init - ); -} +export const threadFirst = + (init: any, ...fns: (FnAny | [FnAny, ...any[]])[]) => + fns.reduce( + (acc, expr) => + typeof expr === "function" ? + expr(acc) : + expr[0](acc, ...expr.slice(1)) + , + init + ); diff --git a/packages/compose/src/thread-last.ts b/packages/compose/src/thread-last.ts index 3502d21b69..e06ff76ac6 100644 --- a/packages/compose/src/thread-last.ts +++ b/packages/compose/src/thread-last.ts @@ -26,13 +26,13 @@ import { FnAny } from "@thi.ng/api/api"; * @param init * @param fns */ -export function threadLast(init: any, ...fns: (FnAny | [FnAny, ...any[]])[]) { - return fns.reduce( - (acc, expr) => - typeof expr === "function" ? - expr(acc) : - expr[0](...expr.slice(1), acc) - , - init - ); -} +export const threadLast = + (init: any, ...fns: (FnAny | [FnAny, ...any[]])[]) => + fns.reduce( + (acc, expr) => + typeof expr === "function" ? + expr(acc) : + expr[0](...expr.slice(1), acc) + , + init + ); From d9f4bd3fc7b02713c61c49e172533b09b8e4af3c Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 06:13:58 +0000 Subject: [PATCH 188/333] refactor(errors): use arrow fns --- packages/errors/src/illegal-arguments.ts | 7 ++++--- packages/errors/src/illegal-arity.ts | 7 ++++--- packages/errors/src/illegal-state.ts | 7 ++++--- packages/errors/src/unsupported.ts | 7 ++++--- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/packages/errors/src/illegal-arguments.ts b/packages/errors/src/illegal-arguments.ts index 2f4ff7f5bb..5ecdd637ee 100644 --- a/packages/errors/src/illegal-arguments.ts +++ b/packages/errors/src/illegal-arguments.ts @@ -4,6 +4,7 @@ export class IllegalArgumentError extends Error { } } -export function illegalArgs(msg?: any): never { - throw new IllegalArgumentError(msg); -} +export const illegalArgs = + (msg?: any): never => { + throw new IllegalArgumentError(msg); + }; diff --git a/packages/errors/src/illegal-arity.ts b/packages/errors/src/illegal-arity.ts index 4f0d5e1301..e2c4af81a4 100644 --- a/packages/errors/src/illegal-arity.ts +++ b/packages/errors/src/illegal-arity.ts @@ -4,6 +4,7 @@ export class IllegalArityError extends Error { } } -export function illegalArity(n): never { - throw new IllegalArityError(n); -} +export const illegalArity = + (n): never => { + throw new IllegalArityError(n); + }; diff --git a/packages/errors/src/illegal-state.ts b/packages/errors/src/illegal-state.ts index 3553868bfc..7552f97b36 100644 --- a/packages/errors/src/illegal-state.ts +++ b/packages/errors/src/illegal-state.ts @@ -4,6 +4,7 @@ export class IllegalStateError extends Error { } } -export function illegalState(msg?: any): never { - throw new IllegalStateError(msg); -} +export const illegalState = + (msg?: any): never => { + throw new IllegalStateError(msg); + }; diff --git a/packages/errors/src/unsupported.ts b/packages/errors/src/unsupported.ts index e0534a6d92..71687717e0 100644 --- a/packages/errors/src/unsupported.ts +++ b/packages/errors/src/unsupported.ts @@ -4,6 +4,7 @@ export class UnsupportedOperationError extends Error { } } -export function unsupported(msg?: any): never { - throw new UnsupportedOperationError(msg); -} +export const unsupported = + (msg?: any): never => { + throw new UnsupportedOperationError(msg); + }; From 3b74de9277ce41260da61b4ce1ce071963b725d1 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 06:14:37 +0000 Subject: [PATCH 189/333] refactor(hiccup-css): use arrow fns --- packages/hiccup-css/src/comment.ts | 27 ++-- packages/hiccup-css/src/conditional.ts | 63 ++++----- packages/hiccup-css/src/css.ts | 48 +++---- packages/hiccup-css/src/impl.ts | 178 +++++++++++++------------ packages/hiccup-css/src/import.ts | 20 +-- packages/hiccup-css/src/inject.ts | 33 ++--- packages/hiccup-css/src/media.ts | 6 +- packages/hiccup-css/src/supports.ts | 6 +- 8 files changed, 195 insertions(+), 186 deletions(-) diff --git a/packages/hiccup-css/src/comment.ts b/packages/hiccup-css/src/comment.ts index e11364c2dd..55c2cd07bd 100644 --- a/packages/hiccup-css/src/comment.ts +++ b/packages/hiccup-css/src/comment.ts @@ -1,16 +1,17 @@ import { RuleFn } from "./api"; import { indent } from "./impl"; -export function comment(body: string, force = false): RuleFn { - return (acc, opts) => { - const space = indent(opts); - const inner = indent(opts, opts.depth + 1); - if (opts.format.comments || force) { - Array.prototype.push.apply( - acc, - [space + "/*", body.split("\n").map((l) => inner + l).join("\n"), space + "*/"] - ); - } - return acc; - }; -} +export const comment = + (body: string, force = false): RuleFn => + (acc, opts) => { + const space = indent(opts); + const inner = indent(opts, opts.depth + 1); + if (opts.format.comments || force) { + acc.push( + space + "/*", + body.split("\n").map((l) => inner + l).join("\n"), + space + "*/" + ); + } + return acc; + }; diff --git a/packages/hiccup-css/src/conditional.ts b/packages/hiccup-css/src/conditional.ts index 9ed2642a90..80fe10e627 100644 --- a/packages/hiccup-css/src/conditional.ts +++ b/packages/hiccup-css/src/conditional.ts @@ -3,37 +3,38 @@ import { isString } from "@thi.ng/checks/is-string"; import { Conditional, CSSOpts, RuleFn } from "./api"; import { expand, indent } from "./impl"; -export function conditional(type: string, cond: Conditional, rules: any[]): RuleFn { - return (acc: string[], opts: CSSOpts) => { - const space = indent(opts); - acc.push(`${space}${type} ${formatCond(cond)}${opts.format.declStart}`); - opts.depth++; - expand(acc, [], rules, opts); - opts.depth--; - acc.push(space + opts.format.declEnd); - return acc; - }; -} +export const conditional = + (type: string, cond: Conditional, rules: any[]): RuleFn => + (acc: string[], opts: CSSOpts) => { + const space = indent(opts); + acc.push(`${space}${type} ${formatCond(cond)}${opts.format.declStart}`); + opts.depth++; + expand(acc, [], rules, opts); + opts.depth--; + acc.push(space + opts.format.declEnd); + return acc; + }; -function formatCond(cond: any) { - if (isString(cond)) { - return cond; - } - const acc = []; - for (let c in cond) { - if (cond.hasOwnProperty(c)) { - let v = cond[c]; - if (v === true) { - v = c; - } else if (v === false) { - v = "not " + c; - } else if (v === "only") { - v += " " + c; - } else { - v = `(${c}:${v})`; +const formatCond = + (cond: any) => { + if (isString(cond)) { + return cond; + } + const acc = []; + for (let c in cond) { + if (cond.hasOwnProperty(c)) { + let v = cond[c]; + if (v === true) { + v = c; + } else if (v === false) { + v = "not " + c; + } else if (v === "only") { + v += " " + c; + } else { + v = `(${c}:${v})`; + } + acc.push(v); } - acc.push(v); } - } - return acc.join(" and "); -} + return acc.join(" and "); + }; diff --git a/packages/hiccup-css/src/css.ts b/packages/hiccup-css/src/css.ts index ae61dc10d3..821331f81a 100644 --- a/packages/hiccup-css/src/css.ts +++ b/packages/hiccup-css/src/css.ts @@ -3,31 +3,31 @@ import { isFunction } from "@thi.ng/checks/is-function"; import { isIterable } from "@thi.ng/checks/is-iterable"; import { isPlainObject } from "@thi.ng/checks/is-plain-object"; import { isString } from "@thi.ng/checks/is-string"; - import { COMPACT, CSSOpts, DEFAULT_VENDORS } from "./api"; import { expand, formatDecls } from "./impl"; -export function css(rules: any, opts?: Partial) { - opts = { - format: COMPACT, - vendors: DEFAULT_VENDORS, - fns: {}, - depth: 0, - ...opts +export const css = + (rules: any, opts?: Partial) => { + opts = { + format: COMPACT, + vendors: DEFAULT_VENDORS, + fns: {}, + depth: 0, + ...opts + }; + if (isPlainObject(rules)) { + return formatDecls(rules, opts); + } + if (isArray(opts.autoprefix)) { + opts.autoprefix = new Set(opts.autoprefix); + } + if (isIterable(rules) && !isString(rules)) { + rules = [...rules]; + } + if (isArray(rules)) { + return expand([], [], rules, opts).join(opts.format.rules); + } + if (isFunction(rules)) { + return rules([], opts).join(opts.format.rules); + } }; - if (isPlainObject(rules)) { - return formatDecls(rules, opts); - } - if (isArray(opts.autoprefix)) { - opts.autoprefix = new Set(opts.autoprefix); - } - if (isIterable(rules) && !isString(rules)) { - rules = [...rules]; - } - if (isArray(rules)) { - return expand([], [], rules, opts).join(opts.format.rules); - } - if (isFunction(rules)) { - return rules([], opts).join(opts.format.rules); - } -} diff --git a/packages/hiccup-css/src/impl.ts b/packages/hiccup-css/src/impl.ts index 02766d4398..fc874a4f2f 100644 --- a/packages/hiccup-css/src/impl.ts +++ b/packages/hiccup-css/src/impl.ts @@ -12,109 +12,115 @@ import { str } from "@thi.ng/transducers/rfn/str"; import { transduce } from "@thi.ng/transducers/transduce"; import { flatten } from "@thi.ng/transducers/xform/flatten"; import { map } from "@thi.ng/transducers/xform/map"; - import { CSSOpts } from "./api"; const EMPTY = new Set(); const NO_SPACES = ":["; -const xfSel = comp( - flatten(), - map((x: string) => NO_SPACES.indexOf(x.charAt(0)) >= 0 ? x : " " + x) -); +const xfSel = + comp( + flatten(), + map((x: string) => NO_SPACES.indexOf(x.charAt(0)) >= 0 ? x : " " + x) + ); -const withScope = (xf: Transducer, scope: string) => - comp(xf, map((x) => isString(x) && x.indexOf(" .") == 0 ? x + scope : x)); +const withScope = + (xf: Transducer, scope: string) => + comp(xf, map((x) => isString(x) && x.indexOf(" .") == 0 ? x + scope : x)); -export function expand(acc: string[], parent: any[], rules: any[], opts: CSSOpts) { - const n = rules.length; - const sel: string[] = []; - let curr: any, isFn; +export const expand = + (acc: string[], parent: any[], rules: any[], opts: CSSOpts) => { + const n = rules.length; + const sel: string[] = []; + let curr: any, isFn; - function process(i, r) { - if (isArray(r)) { - expand(acc, makeSelector(parent, sel), r, opts); - } else if (isIterable(r) && !isString(r)) { - expand(acc, makeSelector(parent, sel), [...r], opts); - } else if ((isFn = isFunction(r)) || opts.fns[r]) { - if (!parent.length) { - if (opts.fns[r]) { - opts.fns[r].apply(null, rules.slice(i + 1))(acc, opts); - return true; + const process = (i, r) => { + if (isArray(r)) { + expand(acc, makeSelector(parent, sel), r, opts); + } else if (isIterable(r) && !isString(r)) { + expand(acc, makeSelector(parent, sel), [...r], opts); + } else if ((isFn = isFunction(r)) || opts.fns[r]) { + if (!parent.length) { + if (opts.fns[r]) { + opts.fns[r].apply(null, rules.slice(i + 1))(acc, opts); + return true; + } + r(acc, opts); + } else if (isFn) { + process(i, r()); + } else { + illegalArgs(`quoted fn ('${r}') only allowed at head position`); } - r(acc, opts); - } else if (isFn) { - process(i, r()); - } else { - illegalArgs(`quoted fn ('${r}') only allowed at head position`); + } else if (isPlainObject(r)) { + curr = Object.assign(curr || {}, r); + } else if (r != null) { + sel.push(r); } - } else if (isPlainObject(r)) { - curr = Object.assign(curr || {}, r); - } else if (r != null) { - sel.push(r); - } - } + }; - for (let i = 0; i < n; i++) { - if (process(i, rules[i])) { - return acc; + for (let i = 0; i < n; i++) { + if (process(i, rules[i])) { + return acc; + } } - } - if (curr) { - acc.push(formatRule(parent, sel, curr, opts)); - } - return acc; -} + curr && acc.push(formatRule(parent, sel, curr, opts)); + return acc; + }; -function makeSelector(parent: any[], curr: any[]) { - return parent.length ? - [...permutations(parent, curr)] : - curr; -} +const makeSelector = + (parent: any[], curr: any[]) => + parent.length ? + [...permutations(parent, curr)] : + curr; -function formatRule(parent: any[], sel: any[], curr: any, opts: CSSOpts) { - const f = opts.format; - const space = indent(opts); - const xf = opts.scope ? withScope(xfSel, opts.scope) : xfSel; - return [ - space, - transduce( - map((sel: any[]) => transduce(xf, str(), isArray(sel) ? sel : [sel]).trim()), - str(f.ruleSep), - makeSelector(parent, sel)), - f.declStart, - formatDecls(curr, opts), - space, - f.declEnd - ].join(""); -} +const formatRule = + (parent: any[], sel: any[], curr: any, opts: CSSOpts) => { + const f = opts.format; + const space = indent(opts); + const xf = opts.scope ? withScope(xfSel, opts.scope) : xfSel; + return [ + space, + transduce( + map((sel: any[]) => transduce(xf, str(), isArray(sel) ? sel : [sel]).trim()), + str(f.ruleSep), + makeSelector(parent, sel)), + f.declStart, + formatDecls(curr, opts), + space, + f.declEnd + ].join(""); + }; -export function formatDecls(rules: any, opts: CSSOpts) { - const f = opts.format; - const prefixes = >(opts.autoprefix || EMPTY); - const space = indent(opts, opts.depth + 1); - const acc = []; - for (let r in rules) { - if (rules.hasOwnProperty(r)) { - let val = rules[r]; - if (isFunction(val)) { - val = val(rules); - } - if (isArray(val)) { - val = val.map((v) => isArray(v) ? v.join(" ") : v).join(f.ruleSep); - } - if (prefixes.has(r)) { - for (let v of opts.vendors) { - acc.push(`${space}${v}${r}:${f.valSep}${val};`); +export const formatDecls = + (rules: any, opts: CSSOpts) => { + const f = opts.format; + const prefixes = >(opts.autoprefix || EMPTY); + const space = indent(opts, opts.depth + 1); + const acc = []; + for (let r in rules) { + if (rules.hasOwnProperty(r)) { + let val = rules[r]; + if (isFunction(val)) { + val = val(rules); + } + if (isArray(val)) { + val = val.map((v) => isArray(v) ? v.join(" ") : v).join(f.ruleSep); + } + if (prefixes.has(r)) { + for (let v of opts.vendors) { + acc.push(`${space}${v}${r}:${f.valSep}${val};`); + } } + acc.push(`${space}${r}:${f.valSep}${val};`); } - acc.push(`${space}${r}:${f.valSep}${val};`); } - } - return acc.join(f.decls) + f.decls; -} + return acc.join(f.decls) + f.decls; + }; -export function indent(opts: CSSOpts, d = opts.depth) { - return d > 1 ? [...repeat(opts.format.indent, d)].join("") : d > 0 ? opts.format.indent : ""; -} \ No newline at end of file +export const indent = + (opts: CSSOpts, d = opts.depth) => + d > 1 ? + [...repeat(opts.format.indent, d)].join("") : + d > 0 ? + opts.format.indent : + ""; diff --git a/packages/hiccup-css/src/import.ts b/packages/hiccup-css/src/import.ts index 62de0a2c1e..72c56d7ae0 100644 --- a/packages/hiccup-css/src/import.ts +++ b/packages/hiccup-css/src/import.ts @@ -1,12 +1,12 @@ import { RuleFn } from "./api"; -export function at_import(url: string, ...queries: string[]): RuleFn { - return (acc, opts) => ( - acc.push( - queries.length ? - `@import url(${url}) ${queries.join(opts.format.ruleSep)};` : - `@import url(${url});` - ), - acc - ); -} +export const at_import = + (url: string, ...queries: string[]): RuleFn => + (acc, opts) => ( + acc.push( + queries.length ? + `@import url(${url}) ${queries.join(opts.format.ruleSep)};` : + `@import url(${url});` + ), + acc + ); diff --git a/packages/hiccup-css/src/inject.ts b/packages/hiccup-css/src/inject.ts index b2cbdc4940..3603e0c70c 100644 --- a/packages/hiccup-css/src/inject.ts +++ b/packages/hiccup-css/src/inject.ts @@ -9,19 +9,20 @@ * @param css * @param first */ -export const injectStyleSheet = (css: string, first = false) => { - const head = document.getElementsByTagName("head")[0]; - const sheet = document.createElement("style"); - sheet.setAttribute("type", "text/css"); - if ((sheet).styleSheet !== undefined) { - (sheet).styleSheet.cssText = css; - } else { - sheet.textContent = css; - } - if (first) { - head.insertBefore(sheet, head.firstChild); - } else { - head.appendChild(sheet); - } - return sheet; -}; +export const injectStyleSheet = + (css: string, first = false) => { + const head = document.getElementsByTagName("head")[0]; + const sheet = document.createElement("style"); + sheet.setAttribute("type", "text/css"); + if ((sheet).styleSheet !== undefined) { + (sheet).styleSheet.cssText = css; + } else { + sheet.textContent = css; + } + if (first) { + head.insertBefore(sheet, head.firstChild); + } else { + head.appendChild(sheet); + } + return sheet; + }; diff --git a/packages/hiccup-css/src/media.ts b/packages/hiccup-css/src/media.ts index 9bd6b129bf..1ceb027a31 100644 --- a/packages/hiccup-css/src/media.ts +++ b/packages/hiccup-css/src/media.ts @@ -1,6 +1,6 @@ import { Conditional, RuleFn } from "./api"; import { conditional } from "./conditional"; -export function at_media(cond: Conditional, rules: any[]): RuleFn { - return conditional("@media", cond, rules); -} +export const at_media = + (cond: Conditional, rules: any[]): RuleFn => + conditional("@media", cond, rules); diff --git a/packages/hiccup-css/src/supports.ts b/packages/hiccup-css/src/supports.ts index 8d8aaa4bed..8f12929cf4 100644 --- a/packages/hiccup-css/src/supports.ts +++ b/packages/hiccup-css/src/supports.ts @@ -1,6 +1,6 @@ import { Conditional, RuleFn } from "./api"; import { conditional } from "./conditional"; -export function at_supports(cond: Conditional, rules: any[]): RuleFn { - return conditional("@supports", cond, rules); -} +export const at_supports = + (cond: Conditional, rules: any[]): RuleFn => + conditional("@supports", cond, rules); From ad5574b92637fe12a71dc572b2e79c8d8460969e Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 06:15:11 +0000 Subject: [PATCH 190/333] refactor(iterators): use arrow fns --- packages/iterators/src/cached.ts | 43 ++++++------- packages/iterators/src/constantly.ts | 6 +- packages/iterators/src/consume.ts | 9 +-- packages/iterators/src/dense.ts | 6 +- packages/iterators/src/ensure.ts | 16 +++-- packages/iterators/src/every.ts | 23 +++---- packages/iterators/src/flatten.ts | 20 +++--- packages/iterators/src/fnil.ts | 75 +++++++++++----------- packages/iterators/src/fork.ts | 77 ++++++++++++----------- packages/iterators/src/group-by.ts | 29 ++++----- packages/iterators/src/identity.ts | 4 +- packages/iterators/src/indexed.ts | 6 +- packages/iterators/src/iterator.ts | 13 ++-- packages/iterators/src/juxt.ts | 18 +++--- packages/iterators/src/last.ts | 19 +++--- packages/iterators/src/map-indexed.ts | 9 ++- packages/iterators/src/object-iterator.ts | 22 +++---- packages/iterators/src/reduce.ts | 14 +++-- packages/iterators/src/run.ts | 15 ++--- packages/iterators/src/some.ts | 17 ++--- packages/iterators/src/walk.ts | 8 ++- packages/iterators/src/zip.ts | 29 ++++----- 22 files changed, 247 insertions(+), 231 deletions(-) diff --git a/packages/iterators/src/cached.ts b/packages/iterators/src/cached.ts index c979d7e73e..6a8057d7aa 100644 --- a/packages/iterators/src/cached.ts +++ b/packages/iterators/src/cached.ts @@ -1,27 +1,28 @@ import { iterator } from "./iterator"; -export function cached(input: Iterable) { - let cache: T[] = []; - let iter = iterator(input); - let done = false; - return function () { - let i = 0; - return { - [Symbol.iterator](): IterableIterator { return this; }, - next(): IteratorResult { - if (i < cache.length) { - return { done: false, value: cache[i++] }; - } else if (!done) { - let v = iter.next(); - if (!v.done) { - i++; - cache.push(v.value); - return { done: false, value: v.value }; +export const cached = + (input: Iterable) => { + let cache: T[] = []; + let iter = iterator(input); + let done = false; + return function () { + let i = 0; + return { + [Symbol.iterator](): IterableIterator { return this; }, + next(): IteratorResult { + if (i < cache.length) { + return { done: false, value: cache[i++] }; + } else if (!done) { + let v = iter.next(); + if (!v.done) { + i++; + cache.push(v.value); + return { done: false, value: v.value }; + } + done = true; } - done = true; + return { done, value: undefined }; } - return { done, value: undefined }; - } + }; }; }; -} diff --git a/packages/iterators/src/constantly.ts b/packages/iterators/src/constantly.ts index dfd4499078..101e2ed56f 100644 --- a/packages/iterators/src/constantly.ts +++ b/packages/iterators/src/constantly.ts @@ -1,3 +1,3 @@ -export function constantly(x: T): (...args: any[]) => T { - return () => x; -} +export const constantly = + (x: T): (...args: any[]) => T => + () => x; diff --git a/packages/iterators/src/consume.ts b/packages/iterators/src/consume.ts index 37bc6f85dc..3f8f59af16 100644 --- a/packages/iterators/src/consume.ts +++ b/packages/iterators/src/consume.ts @@ -1,4 +1,5 @@ -export function consume(iter: Iterator, n = Infinity) { - while (n-- > 0 && !iter.next().done) { } - return iter; -} +export const consume = + (iter: Iterator, n = Infinity) => { + while (n-- > 0 && !iter.next().done) { } + return iter; + }; diff --git a/packages/iterators/src/dense.ts b/packages/iterators/src/dense.ts index d62cd06de3..d56d80a956 100644 --- a/packages/iterators/src/dense.ts +++ b/packages/iterators/src/dense.ts @@ -1,5 +1,5 @@ import { filter } from "./filter"; -export function dense(input: Iterable) { - return filter(x => x != null, input); -} +export const dense = + (input: Iterable) => + filter(x => x != null, input); diff --git a/packages/iterators/src/ensure.ts b/packages/iterators/src/ensure.ts index d56748c40e..e4a2171a25 100644 --- a/packages/iterators/src/ensure.ts +++ b/packages/iterators/src/ensure.ts @@ -2,13 +2,11 @@ import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; import { iterator } from "./iterator"; -export function ensureIterable(x: any): IterableIterator { - if (!(x != null && x[Symbol.iterator])) { - illegalArgs(`value is not iterable: ${x}`); - } - return x; -} +export const ensureIterable = + (x: any): IterableIterator => + (!(x != null && x[Symbol.iterator])) ? + illegalArgs(`value is not iterable: ${x}`) : + x; -export function ensureIterator(x: any) { - return ensureIterable(iterator(x)); -} +export const ensureIterator = + (x: any) => ensureIterable(iterator(x)); diff --git a/packages/iterators/src/every.ts b/packages/iterators/src/every.ts index 4149542b83..241e5a3907 100644 --- a/packages/iterators/src/every.ts +++ b/packages/iterators/src/every.ts @@ -2,15 +2,16 @@ import { Predicate } from "@thi.ng/api/api"; import { iterator } from "./iterator"; -export function every(pred: Predicate, input: Iterable) { - let iter = iterator(input); - let v: IteratorResult; - let empty = true; - while (((v = iter.next()), !v.done)) { - if (pred(v.value) !== true) { - return false; +export const every = + (pred: Predicate, input: Iterable) => { + let iter = iterator(input); + let v: IteratorResult; + let empty = true; + while (((v = iter.next()), !v.done)) { + if (pred(v.value) !== true) { + return false; + } + empty = false; } - empty = false; - } - return !empty; -} + return !empty; + }; diff --git a/packages/iterators/src/flatten.ts b/packages/iterators/src/flatten.ts index 6ab857b428..8f11f1ff2a 100644 --- a/packages/iterators/src/flatten.ts +++ b/packages/iterators/src/flatten.ts @@ -2,13 +2,13 @@ import { flattenWith } from "./flatten-with"; import { maybeIterator } from "./iterator"; import { maybeObjectIterator } from "./object-iterator"; -export function flatten(input: Iterable, includeObjects = true) { - return flattenWith( - (x) => - (typeof x !== "string" && - (maybeIterator(x) || - (includeObjects && maybeObjectIterator(x)))) || - undefined, - input - ); -} +export const flatten = + (input: Iterable, includeObjects = true) => + flattenWith( + (x) => + (typeof x !== "string" && + (maybeIterator(x) || + (includeObjects && maybeObjectIterator(x)))) || + undefined, + input + ); diff --git a/packages/iterators/src/fnil.ts b/packages/iterators/src/fnil.ts index a0643a91ae..2564d156f5 100644 --- a/packages/iterators/src/fnil.ts +++ b/packages/iterators/src/fnil.ts @@ -1,39 +1,40 @@ import { illegalArity } from "@thi.ng/errors"; -export function fnil(fn: (...args: any[]) => any, ...ctors: (() => any)[]) { - let [cta, ctb, ctc] = ctors; - switch (ctors.length) { - case 1: - return (...args: any[]) => { - if (args[0] == null) { - args[0] = cta(); - } - return fn.apply(null, args); - }; - case 2: - return (...args: any[]) => { - if (args[0] == null) { - args[0] = cta(); - } - if (args[1] == null) { - args[1] = ctb(); - } - return fn.apply(null, args); - }; - case 3: - return (...args: any[]) => { - if (args[0] == null) { - args[0] = cta(); - } - if (args[1] == null) { - args[1] = ctb(); - } - if (args[2] == null) { - args[2] = ctc(); - } - return fn.apply(null, args); - }; - default: - illegalArity(ctors.length); - } -} +export const fnil = + (fn: (...args: any[]) => any, ...ctors: (() => any)[]) => { + let [cta, ctb, ctc] = ctors; + switch (ctors.length) { + case 1: + return (...args: any[]) => { + if (args[0] == null) { + args[0] = cta(); + } + return fn.apply(null, args); + }; + case 2: + return (...args: any[]) => { + if (args[0] == null) { + args[0] = cta(); + } + if (args[1] == null) { + args[1] = ctb(); + } + return fn.apply(null, args); + }; + case 3: + return (...args: any[]) => { + if (args[0] == null) { + args[0] = cta(); + } + if (args[1] == null) { + args[1] = ctb(); + } + if (args[2] == null) { + args[2] = ctc(); + } + return fn.apply(null, args); + }; + default: + illegalArity(ctors.length); + } + }; diff --git a/packages/iterators/src/fork.ts b/packages/iterators/src/fork.ts index 422a79b3c0..4c083db35f 100644 --- a/packages/iterators/src/fork.ts +++ b/packages/iterators/src/fork.ts @@ -2,50 +2,51 @@ import { DCons } from "@thi.ng/dcons"; import { iterator } from "./iterator"; -export function fork(src: Iterable, cacheLimit = 16) { - const iter = iterator(src); - const cache = new DCons(); - const forks = []; - let done = false; - let total = 0; +export const fork = + (src: Iterable, cacheLimit = 16) => { + const iter = iterator(src); + const cache = new DCons(); + const forks = []; + let done = false; + let total = 0; - function consume() { - if (!done) { - if (cache.length === cacheLimit) { - cache.drop(); - for (let i = forks.length - 1; i >= 0; i--) { - forks[i] = Math.max(forks[i] - 1, 0); + const consume = () => { + if (!done) { + if (cache.length === cacheLimit) { + cache.drop(); + for (let i = forks.length - 1; i >= 0; i--) { + forks[i] = Math.max(forks[i] - 1, 0); + } } + const v = iter.next(); + if (!v.done) { + cache.push(v.value); + total++; + } + done = v.done; + return v.value; } - const v = iter.next(); - if (!v.done) { - cache.push(v.value); - total++; - } - done = v.done; - return v.value; - } - } + }; - return function () { - const id = forks.length; - forks.push(0); - return >{ - [Symbol.iterator](): Iterator { return this; }, - next() { - if (forks[id] < cache.length) { - if (forks[id] < total) { - return { done: false, value: cache.nth(forks[id]++) }; + return function () { + const id = forks.length; + forks.push(0); + return >{ + [Symbol.iterator](): Iterator { return this; }, + next() { + if (forks[id] < cache.length) { + if (forks[id] < total) { + return { done: false, value: cache.nth(forks[id]++) }; + } } - } - else { - const value = consume(); - if (!done) { - forks[id]++; + else { + const value = consume(); + if (!done) { + forks[id]++; + } + return { done, value }; } - return { done, value }; } - } + }; }; }; -} diff --git a/packages/iterators/src/group-by.ts b/packages/iterators/src/group-by.ts index 39b6cfc289..a90924c011 100644 --- a/packages/iterators/src/group-by.ts +++ b/packages/iterators/src/group-by.ts @@ -1,17 +1,18 @@ import { iterator } from "./iterator"; -export function groupBy(key: (v) => any, input: Iterable): { [id: string]: T[] } { - let groups = {}; - let iter = iterator(input); - let v: IteratorResult; - while (((v = iter.next()), !v.done)) { - let id = JSON.stringify(key(v.value)); - let g = groups[id]; - if (g) { - g.push(v.value); - } else { - groups[id] = [v.value]; +export const groupBy = + (key: (v) => any, input: Iterable): { [id: string]: T[] } => { + let groups = {}; + let iter = iterator(input); + let v: IteratorResult; + while (((v = iter.next()), !v.done)) { + let id = JSON.stringify(key(v.value)); + let g = groups[id]; + if (g) { + g.push(v.value); + } else { + groups[id] = [v.value]; + } } - } - return groups; -} + return groups; + }; diff --git a/packages/iterators/src/identity.ts b/packages/iterators/src/identity.ts index 79137c560f..74efbc8cf1 100644 --- a/packages/iterators/src/identity.ts +++ b/packages/iterators/src/identity.ts @@ -1,3 +1 @@ -export function identity(x: T) { - return x; -} +export const identity = (x: T) => x; diff --git a/packages/iterators/src/indexed.ts b/packages/iterators/src/indexed.ts index 0ee1b9c449..946741e60e 100644 --- a/packages/iterators/src/indexed.ts +++ b/packages/iterators/src/indexed.ts @@ -1,5 +1,5 @@ import { mapIndexed } from "./map-indexed"; -export function indexed(input: Iterable): IterableIterator<[number, T]> { - return mapIndexed((i, x) => [i, x], input); -} +export const indexed = + (input: Iterable): IterableIterator<[number, T]> => + mapIndexed((i, x) => [i, x], input); diff --git a/packages/iterators/src/iterator.ts b/packages/iterators/src/iterator.ts index 70d1f7b660..6655106305 100644 --- a/packages/iterators/src/iterator.ts +++ b/packages/iterators/src/iterator.ts @@ -1,7 +1,8 @@ -export function iterator(x: Iterable) { - return x[Symbol.iterator](); -} +export const iterator = + (x: Iterable) => + x[Symbol.iterator](); -export function maybeIterator(x: any) { - return (x != null && x[Symbol.iterator] && x[Symbol.iterator]()) || undefined; -} +export const maybeIterator = + (x: any) => + (x != null && x[Symbol.iterator] && x[Symbol.iterator]()) || + undefined; diff --git a/packages/iterators/src/juxt.ts b/packages/iterators/src/juxt.ts index 3d29dcd95d..97a2c31897 100644 --- a/packages/iterators/src/juxt.ts +++ b/packages/iterators/src/juxt.ts @@ -1,9 +1,9 @@ -export function juxt(...fns: ((x: T) => any)[]) { - return function (x: T) { - let res = []; - for (let i = 0; i < fns.length; i++) { - res[i] = fns[i](x); - } - return res; - }; -} +export const juxt = + (...fns: ((x: T) => any)[]) => + (x: T) => { + let res = []; + for (let i = 0; i < fns.length; i++) { + res[i] = fns[i](x); + } + return res; + }; diff --git a/packages/iterators/src/last.ts b/packages/iterators/src/last.ts index ca6c42f49c..a90c788fba 100644 --- a/packages/iterators/src/last.ts +++ b/packages/iterators/src/last.ts @@ -1,11 +1,12 @@ import { iterator } from "./iterator"; -export function last(input: Iterable) { - let iter = iterator(input); - let v: IteratorResult; - let prev: T; - while (((v = iter.next()), !v.done)) { - prev = v.value; - } - return prev; -} +export const last = + (input: Iterable) => { + let iter = iterator(input); + let v: IteratorResult; + let prev: T; + while (((v = iter.next()), !v.done)) { + prev = v.value; + } + return prev; + }; diff --git a/packages/iterators/src/map-indexed.ts b/packages/iterators/src/map-indexed.ts index 38701ee3ab..f335b97a53 100644 --- a/packages/iterators/src/map-indexed.ts +++ b/packages/iterators/src/map-indexed.ts @@ -1,6 +1,9 @@ import { map } from "./map"; import { range } from "./range"; -export function mapIndexed(fn: (i: number, ...args: any[]) => T[], ...inputs: Iterable[]): IterableIterator { - return map.apply(null, ([fn, range()] as any[]).concat(inputs)); -} +export const mapIndexed = ( + fn: (i: number, ...args: any[]) => T[], + ...inputs: Iterable[] +): IterableIterator => + + map.apply(null, ([fn, range()] as any[]).concat(inputs)); diff --git a/packages/iterators/src/object-iterator.ts b/packages/iterators/src/object-iterator.ts index 631986dabf..c74e07976e 100644 --- a/packages/iterators/src/object-iterator.ts +++ b/packages/iterators/src/object-iterator.ts @@ -1,14 +1,14 @@ import { map } from "./map"; -export function objectIterator(x: any) { - return map((k) => [k, x[k]], Object.keys(x)); -} +export const objectIterator = + (x: any) => + map((k) => [k, x[k]], Object.keys(x)); -export function maybeObjectIterator(x: any) { - return ( - x != null && - typeof x === "object" && - Object.prototype.toString.call(x) !== "[object Generator]" && - objectIterator(x) - ) || undefined; -} +export const maybeObjectIterator = + (x: any) => + ( + x != null && + typeof x === "object" && + Object.prototype.toString.call(x) !== "[object Generator]" && + objectIterator(x) + ) || undefined; diff --git a/packages/iterators/src/reduce.ts b/packages/iterators/src/reduce.ts index 5d6613956d..bc8a5b51be 100644 --- a/packages/iterators/src/reduce.ts +++ b/packages/iterators/src/reduce.ts @@ -8,7 +8,12 @@ export class ReducedValue { } } -export function reduce(rfn: (acc: B, x: A) => B | ReducedValue, acc: B, input: Iterable) { +export const reduce = ( + rfn: (acc: B, x: A) => B | ReducedValue, + acc: B, + input: Iterable +) => { + let iter = iterator(input); let v: IteratorResult; let _acc: B | ReducedValue = acc; @@ -19,8 +24,7 @@ export function reduce(rfn: (acc: B, x: A) => B | ReducedValue, acc: B, } } return _acc; -} +}; -export function reduced(x: T) { - return new ReducedValue(x); -} +export const reduced = + (x: T) => new ReducedValue(x); diff --git a/packages/iterators/src/run.ts b/packages/iterators/src/run.ts index d0104bb041..9b79273ea4 100644 --- a/packages/iterators/src/run.ts +++ b/packages/iterators/src/run.ts @@ -1,9 +1,10 @@ import { iterator } from "./iterator"; -export function run(fn: (x: T) => any, input: Iterable) { - let iter = iterator(input); - let v: IteratorResult; - while (((v = iter.next()), !v.done)) { - fn(v.value); - } -} +export const run = + (fn: (x: T) => any, input: Iterable) => { + let iter = iterator(input); + let v: IteratorResult; + while (((v = iter.next()), !v.done)) { + fn(v.value); + } + }; diff --git a/packages/iterators/src/some.ts b/packages/iterators/src/some.ts index b4b2ccbbef..a526f90ceb 100644 --- a/packages/iterators/src/some.ts +++ b/packages/iterators/src/some.ts @@ -2,12 +2,13 @@ import { Predicate } from "@thi.ng/api/api"; import { iterator } from "./iterator"; -export function some(pred: Predicate, input: Iterable) { - let iter = iterator(input); - let v: IteratorResult; - while (((v = iter.next()), !v.done)) { - if (pred(v.value) === true) { - return v.value; +export const some = + (pred: Predicate, input: Iterable) => { + let iter = iterator(input); + let v: IteratorResult; + while (((v = iter.next()), !v.done)) { + if (pred(v.value) === true) { + return v.value; + } } - } -} + }; diff --git a/packages/iterators/src/walk.ts b/packages/iterators/src/walk.ts index c5acc57cc5..af21b87c15 100644 --- a/packages/iterators/src/walk.ts +++ b/packages/iterators/src/walk.ts @@ -2,9 +2,11 @@ import { iterator, maybeIterator } from "./iterator"; import { maybeObjectIterator } from "./object-iterator"; import { Fn } from "@thi.ng/api/api"; -export function walkable(x) { - return typeof x !== "string" ? maybeIterator(x) || maybeObjectIterator(x) : undefined; -} +export const walkable = + (x) => + typeof x !== "string" ? + maybeIterator(x) || maybeObjectIterator(x) : + undefined; export function walk(fn: Fn, input: any, postOrder?: boolean); export function walk(fn: Fn, children: Fn, input: any, postOrder?: boolean); diff --git a/packages/iterators/src/zip.ts b/packages/iterators/src/zip.ts index e313460e66..89a1dc9c5c 100644 --- a/packages/iterators/src/zip.ts +++ b/packages/iterators/src/zip.ts @@ -1,17 +1,18 @@ import { iterator } from "./iterator"; -export function zip(keys: Iterable, vals: Iterable, target?: any) { - let kiter = iterator(keys); - let viter = iterator(vals); - let k: IteratorResult; - let v: IteratorResult; - target = target || {}; - while (true) { - k = kiter.next(); - v = viter.next(); - if (k.done || v.done) { - return target; +export const zip = + (keys: Iterable, vals: Iterable, target?: any) => { + let kiter = iterator(keys); + let viter = iterator(vals); + let k: IteratorResult; + let v: IteratorResult; + target = target || {}; + while (true) { + k = kiter.next(); + v = viter.next(); + if (k.done || v.done) { + return target; + } + target[k.value] = v.value; } - target[k.value] = v.value; - } -} + }; From 560207a063cff71fa94e679220b12e807584dde7 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 06:15:35 +0000 Subject: [PATCH 191/333] refactor(math): use arrow fns --- packages/math/src/abs.ts | 10 ++- packages/math/src/angle.ts | 37 +++++--- packages/math/src/eqdelta.ts | 9 +- packages/math/src/fit.ts | 30 ++++--- packages/math/src/interval.ts | 164 +++++++++++++++++++--------------- packages/math/src/mix.ts | 115 +++++++++++++----------- packages/math/src/prec.ts | 33 ++++--- packages/math/src/solve.ts | 94 +++++++++---------- packages/math/src/step.ts | 28 +++--- 9 files changed, 292 insertions(+), 228 deletions(-) diff --git a/packages/math/src/abs.ts b/packages/math/src/abs.ts index c173dcb4b4..90ba7bc709 100644 --- a/packages/math/src/abs.ts +++ b/packages/math/src/abs.ts @@ -1,7 +1,9 @@ import { EPS } from "./api"; -export const absDiff = (x: number, y: number) => - Math.abs(x - y); +export const absDiff = + (x: number, y: number) => + Math.abs(x - y); -export const sign = (x: number, eps = EPS) => - x > eps ? 1 : x < -eps ? -1 : 0; +export const sign = + (x: number, eps = EPS) => + x > eps ? 1 : x < -eps ? -1 : 0; diff --git a/packages/math/src/angle.ts b/packages/math/src/angle.ts index a2f4200922..ac65c2c16d 100644 --- a/packages/math/src/angle.ts +++ b/packages/math/src/angle.ts @@ -6,33 +6,42 @@ import { TAU } from "./api"; -export const sincos = (theta: number) => - [Math.sin(theta), Math.cos(theta)]; +export const sincos = + (theta: number) => + [Math.sin(theta), Math.cos(theta)]; -export const absTheta = (theta: number) => - (theta %= TAU, theta < 0 ? TAU + theta : theta); +export const absTheta = + (theta: number) => + (theta %= TAU, theta < 0 ? TAU + theta : theta); -export const angleDist = (a: number, b: number) => - (a = absTheta((b % TAU) - (a % TAU)), a > PI ? TAU - a : a); +export const angleDist = + (a: number, b: number) => ( + a = absTheta((b % TAU) - (a % TAU)), + a > PI ? + TAU - a : + a + ); -export const atan2Abs = (y: number, x: number) => - absTheta(Math.atan2(y, x)); +export const atan2Abs = + (y: number, x: number) => + absTheta(Math.atan2(y, x)); -export const quadrant = (theta: number) => - (absTheta(theta) / HALF_PI) | 0; +export const quadrant = + (theta: number) => + (absTheta(theta) / HALF_PI) | 0; /** * Converts angle to degrees. * * @param x angle in radians */ -export const deg = (x: number) => - x * RAD2DEG; +export const deg = + (x: number) => x * RAD2DEG; /** * Converts angle to radians. * * @param x angle in degrees */ -export const rad = (x: number) => - x * DEG2RAD; +export const rad = + (x: number) => x * DEG2RAD; diff --git a/packages/math/src/eqdelta.ts b/packages/math/src/eqdelta.ts index 50eb9c196e..54c38e437b 100644 --- a/packages/math/src/eqdelta.ts +++ b/packages/math/src/eqdelta.ts @@ -7,7 +7,8 @@ import { EPS } from "./api"; * @param b right value * @param eps epsilon / tolerance */ -export const eqDelta = (a: number, b: number, eps = EPS) => { - const d = a - b; - return (d < 0 ? -d : d) <= eps; -}; +export const eqDelta = + (a: number, b: number, eps = EPS) => { + const d = a - b; + return (d < 0 ? -d : d) <= eps; + }; diff --git a/packages/math/src/fit.ts b/packages/math/src/fit.ts index 6ec0810343..390d5e6b3e 100644 --- a/packages/math/src/fit.ts +++ b/packages/math/src/fit.ts @@ -8,20 +8,26 @@ import { clamp01, clamp11 } from "./interval"; * @param a * @param b */ -export const norm = (x: number, a: number, b: number) => - b !== a ? (x - a) / (b - a) : 0; +export const norm = + (x: number, a: number, b: number) => + b !== a ? (x - a) / (b - a) : 0; -export const fit = (x: number, a: number, b: number, c: number, d: number) => - c + (d - c) * norm(x, a, b); +export const fit = + (x: number, a: number, b: number, c: number, d: number) => + c + (d - c) * norm(x, a, b); -export const fitClamped = (x: number, a: number, b: number, c: number, d: number) => - c + (d - c) * clamp01(norm(x, a, b)); +export const fitClamped = + (x: number, a: number, b: number, c: number, d: number) => + c + (d - c) * clamp01(norm(x, a, b)); -export const fit01 = (x: number, a: number, b: number) => - a + (b - a) * clamp01(x); +export const fit01 = + (x: number, a: number, b: number) => + a + (b - a) * clamp01(x); -export const fit10 = (x: number, a: number, b: number) => - b + (a - b) * clamp01(x); +export const fit10 = + (x: number, a: number, b: number) => + b + (a - b) * clamp01(x); -export const fit11 = (x: number, a: number, b: number) => - a + (b - a) * (0.5 + 0.5 * clamp11(x)); +export const fit11 = + (x: number, a: number, b: number) => + a + (b - a) * (0.5 + 0.5 * clamp11(x)); diff --git a/packages/math/src/interval.ts b/packages/math/src/interval.ts index cd4a6ebb8e..0ceb5cd698 100644 --- a/packages/math/src/interval.ts +++ b/packages/math/src/interval.ts @@ -5,57 +5,69 @@ * @param min lower bound * @param max upper bound */ -export const clamp = (x: number, min: number, max: number) => - x < min ? min : x > max ? max : x; - -export const clamp01 = (x: number) => - x < 0 ? 0 : x > 1 ? 1 : x; - -export const clamp11 = (x: number) => - x < -1 ? -1 : x > 1 ? 1 : x; - -export const wrap = (x: number, min: number, max: number) => - x < min ? x - min + max : x >= max ? x - max + min : x; - -export const wrap01 = (x: number) => - x < 0 ? x + 1 : x >= 1 ? x - 1 : x; - -export const wrap11 = (x: number) => - x < -1 ? x + 2 : x >= 1 ? x - 2 : x; - -export const min2id = (a: number, b: number) => - a <= b ? 0 : 1; - -export const min3id = (a: number, b: number, c: number) => - (a <= b) ? - (a <= c ? 0 : 2) : - (b <= c ? 1 : 2); - -export const min4id = (a: number, b: number, c: number, d: number) => - a <= b ? - (a <= c ? - (a <= d ? 0 : 3) : - (c <= d ? 2 : 3)) : - (b <= c ? - (b <= d ? 1 : 3) : - (c <= d ? 2 : 3)); - -export const max2id = (a: number, b: number) => - a >= b ? 0 : 1; - -export const max3id = (a: number, b: number, c: number) => - (a >= b) ? - (a >= c ? 0 : 2) : - (b >= c ? 1 : 2); - -export const max4id = (a: number, b: number, c: number, d: number) => - a >= b ? - (a >= c ? - (a >= d ? 0 : 3) : - (c >= d ? 2 : 3)) : - (b >= c ? - (b >= d ? 1 : 3) : - (c >= d ? 2 : 3)); +export const clamp = + (x: number, min: number, max: number) => + x < min ? min : x > max ? max : x; + +export const clamp01 = + (x: number) => + x < 0 ? 0 : x > 1 ? 1 : x; + +export const clamp11 = + (x: number) => + x < -1 ? -1 : x > 1 ? 1 : x; + +export const wrap = + (x: number, min: number, max: number) => + x < min ? x - min + max : x >= max ? x - max + min : x; + +export const wrap01 = + (x: number) => + x < 0 ? x + 1 : x >= 1 ? x - 1 : x; + +export const wrap11 = + (x: number) => + x < -1 ? x + 2 : x >= 1 ? x - 2 : x; + +export const min2id = + (a: number, b: number) => + a <= b ? 0 : 1; + +export const min3id = + (a: number, b: number, c: number) => + (a <= b) ? + (a <= c ? 0 : 2) : + (b <= c ? 1 : 2); + +export const min4id = + (a: number, b: number, c: number, d: number) => + a <= b ? + (a <= c ? + (a <= d ? 0 : 3) : + (c <= d ? 2 : 3)) : + (b <= c ? + (b <= d ? 1 : 3) : + (c <= d ? 2 : 3)); + +export const max2id = + (a: number, b: number) => + a >= b ? 0 : 1; + +export const max3id = + (a: number, b: number, c: number) => + (a >= b) ? + (a >= c ? 0 : 2) : + (b >= c ? 1 : 2); + +export const max4id = + (a: number, b: number, c: number, d: number) => + a >= b ? + (a >= c ? + (a >= d ? 0 : 3) : + (c >= d ? 2 : 3)) : + (b >= c ? + (b >= d ? 1 : 3) : + (c >= d ? 2 : 3)); /** * See `smax()`. @@ -64,8 +76,9 @@ export const max4id = (a: number, b: number, c: number, d: number) => * @param b * @param k smooth exponent (MUST be > 0) */ -export const smin = (a: number, b: number, k: number) => - smax(a, b, -k); +export const smin = + (a: number, b: number, k: number) => + smax(a, b, -k); /** * Smooth maximum. Note: Result values will be slightly larger than max @@ -78,11 +91,12 @@ export const smin = (a: number, b: number, k: number) => * @param b * @param k smooth exponent (MUST be > 0) */ -export const smax = (a: number, b: number, k: number) => { - const ea = Math.exp(a * k); - const eb = Math.exp(b * k); - return (a * ea + b * eb) / (ea + eb); -}; +export const smax = + (a: number, b: number, k: number) => { + const ea = Math.exp(a * k); + const eb = Math.exp(b * k); + return (a * ea + b * eb) / (ea + eb); + }; /** * Same as `smin(smax(x, min, k), max, k)`. @@ -92,14 +106,17 @@ export const smax = (a: number, b: number, k: number) => { * @param max * @param k */ -export const sclamp = (x: number, min: number, max: number, k: number) => - smin(smax(x, min, k), max, k); +export const sclamp = + (x: number, min: number, max: number, k: number) => + smin(smax(x, min, k), max, k); -export const absMin = (a: number, b: number) => - Math.abs(a) < Math.abs(b) ? a : b; +export const absMin = + (a: number, b: number) => + Math.abs(a) < Math.abs(b) ? a : b; -export const absMax = (a: number, b: number) => - Math.abs(a) > Math.abs(b) ? a : b; +export const absMax = + (a: number, b: number) => + Math.abs(a) > Math.abs(b) ? a : b; /** * http://www.musicdsp.org/showone.php?id=203 @@ -107,10 +124,11 @@ export const absMax = (a: number, b: number) => * @param e * @param x */ -export const foldback = (e: number, x: number) => - (x < -e || x > e) ? - Math.abs(Math.abs((x - e) % (4 * e)) - 2 * e) - e : - x; +export const foldback = + (e: number, x: number) => + (x < -e || x > e) ? + Math.abs(Math.abs((x - e) % (4 * e)) - 2 * e) - e : + x; /** * Returns true iff `x` is in closed interval `[min .. max]` @@ -119,8 +137,9 @@ export const foldback = (e: number, x: number) => * @param min * @param max */ -export const inRange = (x: number, min: number, max: number) => - x >= min && x <= max; +export const inRange = + (x: number, min: number, max: number) => + x >= min && x <= max; /** * Returns true iff `x` is in open interval `(min .. max)` @@ -129,5 +148,6 @@ export const inRange = (x: number, min: number, max: number) => * @param min * @param max */ -export const inOpenRange = (x: number, min: number, max: number) => - x > min && x < max; +export const inOpenRange = + (x: number, min: number, max: number) => + x > min && x < max; diff --git a/packages/math/src/mix.ts b/packages/math/src/mix.ts index 4ee6ecd528..2909f375c0 100644 --- a/packages/math/src/mix.ts +++ b/packages/math/src/mix.ts @@ -1,7 +1,8 @@ import { PI, HALF_PI } from "./api"; -export const mix = (a: number, b: number, t: number) => - a + (b - a) * t; +export const mix = + (a: number, b: number, t: number) => + a + (b - a) * t; /** * ``` @@ -19,44 +20,52 @@ export const mix = (a: number, b: number, t: number) => * @param u 1st interpolation factor * @param v 2nd interpolation factor */ -export const mixBilinear = (a: number, b: number, c: number, d: number, u: number, v: number) => - mix(mix(a, b, u), mix(c, d, u), v); +export const mixBilinear = + (a: number, b: number, c: number, d: number, u: number, v: number) => + mix(mix(a, b, u), mix(c, d, u), v); -export const mixQuadratic = (a: number, b: number, c: number, t: number) => { - const s = 1 - t; - return a * s * s + b * 2 * s * t + c * t * t; -}; +export const mixQuadratic = + (a: number, b: number, c: number, t: number) => { + const s = 1 - t; + return a * s * s + b * 2 * s * t + c * t * t; + }; -export const mixCubic = (a: number, b: number, c: number, d: number, t: number) => { - const t2 = t * t; - const s = 1 - t; - const s2 = s * s; - return a * s2 * s + b * 3 * s2 * t + c * 3 * t2 * s + d * t2 * t; -}; +export const mixCubic = + (a: number, b: number, c: number, d: number, t: number) => { + const t2 = t * t; + const s = 1 - t; + const s2 = s * s; + return a * s2 * s + b * 3 * s2 * t + c * 3 * t2 * s + d * t2 * t; + }; -export const tween = (f: (t: number) => number, from: number, to: number) => - (t: number) => mix(from, to, f(t)); +export const tween = + (f: (t: number) => number, from: number, to: number) => + (t: number) => mix(from, to, f(t)); /** * Circular interpolation: `sqrt(1 - (1 - t)^2)` * * @param t interpolation factor (0.0 .. 1.0) */ -export const circular = (t: number) => { - t = 1 - t; - return Math.sqrt(1 - t * t); -}; +export const circular = + (t: number) => { + t = 1 - t; + return Math.sqrt(1 - t * t); + }; -export const cosine = (t: number): number => - 1 - (Math.cos(t * PI) * 0.5 + 0.5); +export const cosine = + (t: number): number => + 1 - (Math.cos(t * PI) * 0.5 + 0.5); -export const decimated = (n: number, t: number) => - Math.floor(t * n) / n; +export const decimated = + (n: number, t: number) => + Math.floor(t * n) / n; -export const bounce = (k: number, amp: number, t: number) => { - const tk = t * k; - return 1 - amp * Math.sin(tk) / tk * Math.cos(t * HALF_PI); -}; +export const bounce = + (k: number, amp: number, t: number) => { + const tk = t * k; + return 1 - amp * Math.sin(tk) / tk * Math.cos(t * HALF_PI); + }; /** * HOF exponential easing. @@ -68,35 +77,41 @@ export const bounce = (k: number, amp: number, t: number) => { * @param ease easing behavior [0.0 .. ∞] * @param t */ -export const ease = (ease: number, t: number) => - Math.pow(t, ease); +export const ease = + (ease: number, t: number) => + Math.pow(t, ease); /** * HOF impulse generator. Peaks at `t=1/k` * * @param k impulse width (higher values => shorter impulse) */ -export const impulse = (k: number, t: number) => { - const h = k * t; - return h * Math.exp(1 - h); -}; +export const impulse = + (k: number, t: number) => { + const h = k * t; + return h * Math.exp(1 - h); + }; -export const gain = (k: number, t: number) => - t < 0.5 ? - 0.5 * Math.pow(2 * t, k) : - 1 - 0.5 * Math.pow(2 - 2 * t, k); +export const gain = + (k: number, t: number) => + t < 0.5 ? + 0.5 * Math.pow(2 * t, k) : + 1 - 0.5 * Math.pow(2 - 2 * t, k); -export const parabola = (k: number, t: number) => - Math.pow(4.0 * t * (1.0 - t), k); +export const parabola = + (k: number, t: number) => + Math.pow(4.0 * t * (1.0 - t), k); -export const cubicPulse = (w: number, c: number, t: number) => { - t = Math.abs(t - c); - return t > w ? - 0 : - (t /= w, 1 - t * t * (3 - 2 * t)); -}; +export const cubicPulse = + (w: number, c: number, t: number) => { + t = Math.abs(t - c); + return t > w ? + 0 : + (t /= w, 1 - t * t * (3 - 2 * t)); + }; -export const sinc = (k: number, t: number) => { - t = PI * (k * t - 1.0); - return Math.sin(t) / t; -}; +export const sinc = + (k: number, t: number) => { + t = PI * (k * t - 1.0); + return Math.sin(t) / t; + }; diff --git a/packages/math/src/prec.ts b/packages/math/src/prec.ts index a8ffd2f347..2f3fb56536 100644 --- a/packages/math/src/prec.ts +++ b/packages/math/src/prec.ts @@ -6,17 +6,21 @@ import { EPS } from "./api"; * @param a * @param b */ -export const fmod = (a: number, b: number) => - a - b * Math.floor(a / b); +export const fmod = + (a: number, b: number) => + a - b * Math.floor(a / b); -export const fract = (x: number) => - x - Math.floor(x); +export const fract = + (x: number) => + x - Math.floor(x); -export const trunc = (x: number) => - x < 0 ? Math.ceil(x) : Math.floor(x); +export const trunc = + (x: number) => + x < 0 ? Math.ceil(x) : Math.floor(x); -export const roundTo = (x: number, prec = 1) => - Math.round(x / prec) * prec; +export const roundTo = + (x: number, prec = 1) => + Math.round(x / prec) * prec; /** * Only rounds `x` to nearest int if `fract(x)` < `eps` or > `1-eps`. @@ -24,9 +28,10 @@ export const roundTo = (x: number, prec = 1) => * @param x * @param eps */ -export const roundEps = (x: number, eps = EPS) => { - const f = fract(x); - return f <= eps || f >= 1 - eps ? - Math.round(x) : - x; -}; +export const roundEps = + (x: number, eps = EPS) => { + const f = fract(x); + return f <= eps || f >= 1 - eps ? + Math.round(x) : + x; + }; diff --git a/packages/math/src/solve.ts b/packages/math/src/solve.ts index fab6df7f0f..0c91b2e781 100644 --- a/packages/math/src/solve.ts +++ b/packages/math/src/solve.ts @@ -16,9 +16,9 @@ import { EPS } from "./api"; * @param fn * @param eps */ -export const derivative = (f: (x: number) => number, eps = EPS) => { - return (x: number) => (f(x + eps) - f(x)) / eps; -} +export const derivative = + (f: (x: number) => number, eps = EPS) => + (x: number) => (f(x + eps) - f(x)) / eps; /** * Computes solution for linear equation: `ax + b = 0`. @@ -28,8 +28,8 @@ export const derivative = (f: (x: number) => number, eps = EPS) => { * @param a slope * @param b constant offset */ -export const solveLinear = (a: number, b: number) => - -b / a; +export const solveLinear = + (a: number, b: number) => -b / a; /** * Computes solutions for quadratic equation: `ax^2 + bx + c = 0`. @@ -45,15 +45,16 @@ export const solveLinear = (a: number, b: number) => * @param c constant offset * @param eps tolerance to determine multiple roots */ -export const solveQuadratic = (a: number, b: number, c: number, eps = 1e-9) => { - const d = 2 * a; - let r = b * b - 4 * a * c; - return r < 0 ? - [] : - r < eps ? - [-b / d] : - (r = Math.sqrt(r), [(-b - r) / d, (-b + r) / d]); -}; +export const solveQuadratic = + (a: number, b: number, c: number, eps = 1e-9) => { + const d = 2 * a; + let r = b * b - 4 * a * c; + return r < 0 ? + [] : + r < eps ? + [-b / d] : + (r = Math.sqrt(r), [(-b - r) / d, (-b + r) / d]); + }; /** * Computes solutions for quadratic equation: `ax^3 + bx^2 + c*x + d = 0`. @@ -69,38 +70,39 @@ export const solveQuadratic = (a: number, b: number, c: number, eps = 1e-9) => { * @param d constant offset * @param eps tolerance to determine multiple roots */ -export const solveCubic = (a: number, b: number, c: number, d: number, eps = 1e-9) => { - const aa = a * a; - const bb = b * b; - const ba3 = b / (3 * a); - const p = (3 * a * c - bb) / (3 * aa); - const q = (2 * bb * b - 9 * a * b * c + 27 * aa * d) / (27 * aa * a); +export const solveCubic = + (a: number, b: number, c: number, d: number, eps = 1e-9) => { + const aa = a * a; + const bb = b * b; + const ba3 = b / (3 * a); + const p = (3 * a * c - bb) / (3 * aa); + const q = (2 * bb * b - 9 * a * b * c + 27 * aa * d) / (27 * aa * a); - if (Math.abs(p) < eps) { - return [Math.cbrt(-q) - ba3]; - } else if (Math.abs(q) < eps) { - return p < 0 ? - [ - -Math.sqrt(-p) - ba3, - -ba3, Math.sqrt(-p) - ba3 - ] : - [-ba3]; - } else { - const denom = q * q / 4 + p * p * p / 27; - if (Math.abs(denom) < eps) { - return [-1.5 * q / p - ba3, 3 * q / p - ba3]; - } else if (denom > 0) { - const u = Math.cbrt(-q / 2 - Math.sqrt(denom)); - return [u - p / (3 * u) - ba3]; + if (Math.abs(p) < eps) { + return [Math.cbrt(-q) - ba3]; + } else if (Math.abs(q) < eps) { + return p < 0 ? + [ + -Math.sqrt(-p) - ba3, + -ba3, Math.sqrt(-p) - ba3 + ] : + [-ba3]; } else { - const u = 2 * Math.sqrt(-p / 3), - t = Math.acos(3 * q / p / u) / 3, - k = 2 * Math.PI / 3; - return [ - u * Math.cos(t) - ba3, - u * Math.cos(t - k) - ba3, - u * Math.cos(t - 2 * k) - ba3 - ]; + const denom = q * q / 4 + p * p * p / 27; + if (Math.abs(denom) < eps) { + return [-1.5 * q / p - ba3, 3 * q / p - ba3]; + } else if (denom > 0) { + const u = Math.cbrt(-q / 2 - Math.sqrt(denom)); + return [u - p / (3 * u) - ba3]; + } else { + const u = 2 * Math.sqrt(-p / 3), + t = Math.acos(3 * q / p / u) / 3, + k = 2 * Math.PI / 3; + return [ + u * Math.cos(t) - ba3, + u * Math.cos(t - k) - ba3, + u * Math.cos(t - 2 * k) - ba3 + ]; + } } - } -} + }; diff --git a/packages/math/src/step.ts b/packages/math/src/step.ts index 292c302df2..51e2f44c27 100644 --- a/packages/math/src/step.ts +++ b/packages/math/src/step.ts @@ -7,8 +7,9 @@ import { clamp01 } from "./interval"; * @param x test value * @returns 0, if `x < e`, else 1 */ -export const step = (edge: number, x: number) => - x < edge ? 0 : 1; +export const step = + (edge: number, x: number) => + x < edge ? 0 : 1; /** * GLSL-style smoothStep threshold function. @@ -18,10 +19,11 @@ export const step = (edge: number, x: number) => * @param x test value * @returns 0, if `x < edge1`, 1 if `x > edge2`, else sigmoid interpolation */ -export const smoothStep = (edge: number, edge2: number, x: number) => { - x = clamp01((x - edge) / (edge2 - edge)); - return (3 - 2 * x) * x * x; -}; +export const smoothStep = + (edge: number, edge2: number, x: number) => { + x = clamp01((x - edge) / (edge2 - edge)); + return (3 - 2 * x) * x * x; + }; /** * Similar to `smoothStep()` but using different polynomial. @@ -30,10 +32,11 @@ export const smoothStep = (edge: number, edge2: number, x: number) => { * @param edge2 * @param x */ -export const smootherStep = (edge: number, edge2: number, x: number) => { - x = clamp01((x - edge) / (edge2 - edge)); - return x * x * x * (x * (x * 6 - 15) + 10); -}; +export const smootherStep = + (edge: number, edge2: number, x: number) => { + x = clamp01((x - edge) / (edge2 - edge)); + return x * x * x * (x * (x * 6 - 15) + 10); + }; /** * Exponential ramp with variable shape, e.g. @@ -47,5 +50,6 @@ export const smootherStep = (edge: number, edge2: number, x: number) => { * @param n * @param x */ -export const expStep = (k: number, n: number, x: number) => - 1 - Math.exp(-k * Math.pow(x, n)); +export const expStep = + (k: number, n: number, x: number) => + 1 - Math.exp(-k * Math.pow(x, n)); From e0f7cb8524a528dba29859bb848154f9bd058d96 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 06:16:29 +0000 Subject: [PATCH 192/333] minor(resolve-map): update formatting --- packages/resolve-map/src/index.ts | 140 ++++++++++++++++++------------ 1 file changed, 86 insertions(+), 54 deletions(-) diff --git a/packages/resolve-map/src/index.ts b/packages/resolve-map/src/index.ts index ec3ab991c0..e2e14335b9 100644 --- a/packages/resolve-map/src/index.ts +++ b/packages/resolve-map/src/index.ts @@ -91,16 +91,23 @@ export type LookupPath = PropertyKey[]; * * @param root */ -export const resolve = (root: any) => { - if (isPlainObject(root)) { - return resolveMap(root); - } else if (isArray(root)) { - return resolveArray(root); - } - return root; -}; +export const resolve = + (root: any) => { + if (isPlainObject(root)) { + return resolveMap(root); + } else if (isArray(root)) { + return resolveArray(root); + } + return root; + }; -const resolveMap = (obj: any, root?: any, path: LookupPath = [], resolved: any = {}, stack: string[] = []) => { +const resolveMap = ( + obj: any, + root?: any, + path: LookupPath = [], + resolved: any = {}, + stack: string[] = [] +) => { root = root || obj; for (let k in obj) { _resolve(root, [...path, k], resolved, stack); @@ -108,7 +115,13 @@ const resolveMap = (obj: any, root?: any, path: LookupPath = [], resolved: any = return obj; }; -const resolveArray = (arr: any[], root?: any, path: LookupPath = [], resolved: any = {}, stack: string[] = []) => { +const resolveArray = ( + arr: any[], + root?: any, + path: LookupPath = [], + resolved: any = {}, + stack: string[] = [] +) => { root = root || arr; for (let k = 0, n = arr.length; k < n; k++) { _resolve(root, [...path, k], resolved, stack); @@ -127,7 +140,12 @@ const resolveArray = (arr: any[], root?: any, path: LookupPath = [], resolved: a * @param resolved * @param stack */ -const _resolve = (root: any, path: LookupPath, resolved: any, stack: string[]) => { +const _resolve = ( + root: any, + path: LookupPath, + resolved: any, + stack: string[] +) => { const pathID = path.join("/"); if (stack.indexOf(pathID) >= 0) { illegalArgs(`cyclic references not allowed: ${pathID}`); @@ -175,7 +193,12 @@ const _resolve = (root: any, path: LookupPath, resolved: any, stack: string[]) = * @param path * @param resolved */ -const resolvePath = (root: any, path: LookupPath, resolved: any, stack: string[] = []) => { +const resolvePath = ( + root: any, + path: LookupPath, + resolved: any, + stack: string[] = [] +) => { // temporarily remove current path to avoid cycle detection let pathID = stack.pop() let v; @@ -204,7 +227,12 @@ const resolvePath = (root: any, path: LookupPath, resolved: any, stack: string[] * @param pathID current base path for marking * @param resolved */ -const resolveFunction = (fn: (x: any, r?: ResolveFn) => any, resolve: ResolveFn, pathID: string, resolved: any) => { +const resolveFunction = ( + fn: (x: any, r?: ResolveFn) => any, + resolve: ResolveFn, + pathID: string, + resolved: any +) => { const match = RE_ARGS.exec(fn.toString()); let res; if (match) { @@ -222,33 +250,36 @@ const resolveFunction = (fn: (x: any, r?: ResolveFn) => any, resolve: ResolveFn, return res; }; -const markResolved = (v: any, path: string, resolved: any) => { - resolved[path] = true; - if (isPlainObject(v)) { - markObjResolved(v, path, resolved); - } - else if (isArray(v)) { - markArrayResolved(v, path, resolved); - } -}; +const markResolved = + (v: any, path: string, resolved: any) => { + resolved[path] = true; + if (isPlainObject(v)) { + markObjResolved(v, path, resolved); + } + else if (isArray(v)) { + markArrayResolved(v, path, resolved); + } + }; -const markObjResolved = (obj: any, path: string, resolved: any) => { - let v, p; - for (let k in obj) { - v = obj[k]; - p = path + "/" + k; - markResolved(v, p, resolved); - } -}; +const markObjResolved = + (obj: any, path: string, resolved: any) => { + let v, p; + for (let k in obj) { + v = obj[k]; + p = path + "/" + k; + markResolved(v, p, resolved); + } + }; -const markArrayResolved = (arr: any[], path: string, resolved: any) => { - let v, p; - for (let i = 0, n = arr.length; i < n; i++) { - v = arr[i]; - p = path + "/" + i; - markResolved(v, p, resolved); - } -}; +const markArrayResolved = + (arr: any[], path: string, resolved: any) => { + let v, p; + for (let i = 0, n = arr.length; i < n; i++) { + v = arr[i]; + p = path + "/" + i; + markResolved(v, p, resolved); + } + }; /** * Takes the path for the current key and a lookup path string. Converts @@ -258,20 +289,21 @@ const markArrayResolved = (arr: any[], path: string, resolved: any) => { * @param path * @param idx */ -export const absPath = (curr: LookupPath, path: string, idx = 1): PropertyKey[] => { - if (path.charAt(idx) === "/") { - return path.substr(idx + 1).split("/"); - } - curr = curr.slice(0, curr.length - 1); - const sub = path.substr(idx).split("/"); - for (let i = 0, n = sub.length; i < n; i++) { - if (sub[i] === "..") { - !curr.length && illegalArgs(`invalid lookup path: ${path}`); - curr.pop(); - } else { - return curr.concat(sub.slice(i)); +export const absPath = + (curr: LookupPath, path: string, idx = 1): PropertyKey[] => { + if (path.charAt(idx) === "/") { + return path.substr(idx + 1).split("/"); } - } - !curr.length && illegalArgs(`invalid lookup path: ${path}`); - return curr; -}; + curr = curr.slice(0, curr.length - 1); + const sub = path.substr(idx).split("/"); + for (let i = 0, n = sub.length; i < n; i++) { + if (sub[i] === "..") { + !curr.length && illegalArgs(`invalid lookup path: ${path}`); + curr.pop(); + } else { + return curr.concat(sub.slice(i)); + } + } + !curr.length && illegalArgs(`invalid lookup path: ${path}`); + return curr; + }; From 6c3ea083f0b8d644519c88fa77cb06b2c71a6c8e Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 06:17:28 +0000 Subject: [PATCH 193/333] refactor(rstream): use arrow fns, update formatting --- packages/rstream/src/from/atom.ts | 10 +++- packages/rstream/src/from/event.ts | 9 ++- packages/rstream/src/from/interval.ts | 26 ++++---- packages/rstream/src/from/iterable.ts | 60 +++++++++---------- packages/rstream/src/from/promise.ts | 55 ++++++++--------- packages/rstream/src/from/promises.ts | 6 +- packages/rstream/src/from/raf.ts | 28 +++++---- packages/rstream/src/from/view.ts | 38 +++++++----- packages/rstream/src/from/worker.ts | 35 +++++------ packages/rstream/src/pubsub.ts | 6 +- packages/rstream/src/stream-merge.ts | 6 +- packages/rstream/src/stream-sync.ts | 6 +- packages/rstream/src/subs/bisect.ts | 8 ++- packages/rstream/src/subs/post-worker.ts | 9 ++- packages/rstream/src/subs/resolve.ts | 6 +- .../rstream/src/subs/sidechain-partition.ts | 9 ++- packages/rstream/src/subs/sidechain-toggle.ts | 10 +++- packages/rstream/src/subs/timeout.ts | 10 +++- packages/rstream/src/subs/trace.ts | 26 ++++---- packages/rstream/src/subs/transduce.ts | 10 +++- packages/rstream/src/subs/tunnel.ts | 5 +- packages/rstream/src/subscription.ts | 10 +++- packages/rstream/src/utils/idgen.ts | 3 + packages/rstream/src/utils/worker.ts | 18 +++--- 24 files changed, 231 insertions(+), 178 deletions(-) create mode 100644 packages/rstream/src/utils/idgen.ts diff --git a/packages/rstream/src/from/atom.ts b/packages/rstream/src/from/atom.ts index 901291e51f..7b4421bf11 100644 --- a/packages/rstream/src/from/atom.ts +++ b/packages/rstream/src/from/atom.ts @@ -33,8 +33,13 @@ import { Stream } from "../stream"; * @param emitFirst * @param changed */ -export function fromAtom(atom: ReadonlyAtom, emitFirst = true, changed?: Predicate2): Stream { - return new Stream((stream) => { +export const fromAtom = ( + atom: ReadonlyAtom, + emitFirst = true, + changed?: Predicate2 +): Stream => + + new Stream((stream) => { changed = changed || ((a, b) => a !== b); atom.addWatch(stream.id, (_, prev, curr) => { if (changed(prev, curr)) { @@ -44,4 +49,3 @@ export function fromAtom(atom: ReadonlyAtom, emitFirst = true, changed?: P emitFirst && stream.next(atom.deref()); return () => atom.removeWatch(stream.id); }); -} diff --git a/packages/rstream/src/from/event.ts b/packages/rstream/src/from/event.ts index 49d677b387..2da946a196 100644 --- a/packages/rstream/src/from/event.ts +++ b/packages/rstream/src/from/event.ts @@ -10,10 +10,13 @@ import { Subscription } from "../subscription"; * @param name event name * @param opts listener opts */ -export function fromEvent(src: EventTarget, name: string, opts: boolean | AddEventListenerOptions = false) { - return new Stream((stream) => { +export const fromEvent = ( + src: EventTarget, + name: string, + opts: boolean | AddEventListenerOptions = false +) => + new Stream((stream) => { let listener = (e) => stream.next(e); src.addEventListener(name, listener, opts); return () => src.removeEventListener(name, listener, opts); }, `event-${name}-${Subscription.NEXT_ID++}`); -} diff --git a/packages/rstream/src/from/interval.ts b/packages/rstream/src/from/interval.ts index b92c6b2f56..a55cfc25ce 100644 --- a/packages/rstream/src/from/interval.ts +++ b/packages/rstream/src/from/interval.ts @@ -10,17 +10,17 @@ import { Subscription } from "../subscription"; * @param delay * @param count */ -export function fromInterval(delay: number, count = Infinity) { - return new Stream((stream) => { - let i = 0; - stream.next(i++); - let id = setInterval(() => { +export const fromInterval = + (delay: number, count = Infinity) => + new Stream((stream) => { + let i = 0; stream.next(i++); - if (--count <= 0) { - clearInterval(id); - stream.done(); - } - }, delay); - return () => clearInterval(id); - }, `interval-${Subscription.NEXT_ID++}`); -} + let id = setInterval(() => { + stream.next(i++); + if (--count <= 0) { + clearInterval(id); + stream.done(); + } + }, delay); + return () => clearInterval(id); + }, `interval-${Subscription.NEXT_ID++}`); diff --git a/packages/rstream/src/from/iterable.ts b/packages/rstream/src/from/iterable.ts index 57d74d73ce..ea4fa13eb1 100644 --- a/packages/rstream/src/from/iterable.ts +++ b/packages/rstream/src/from/iterable.ts @@ -13,24 +13,24 @@ import { Subscription } from "../subscription"; * @param delay * @param close */ -export function fromIterable(src: Iterable, delay = 0, close = true) { - return new Stream( - (stream) => { - const iter = src[Symbol.iterator](); - const id = setInterval(() => { - let val: IteratorResult; - if ((val = iter.next()).done) { - clearInterval(id); - close && stream.done(); - } else { - stream.next(val.value); - } - }, delay); - return () => clearInterval(id); - }, - `iterable-${Subscription.NEXT_ID++}` - ); -} +export const fromIterable = + (src: Iterable, delay = 0, close = true) => + new Stream( + (stream) => { + const iter = src[Symbol.iterator](); + const id = setInterval(() => { + let val: IteratorResult; + if ((val = iter.next()).done) { + clearInterval(id); + close && stream.done(); + } else { + stream.next(val.value); + } + }, delay); + return () => clearInterval(id); + }, + `iterable-${Subscription.NEXT_ID++}` + ); /** * Creates a new `Stream` of given iterable which synchronously calls @@ -42,15 +42,15 @@ export function fromIterable(src: Iterable, delay = 0, close = true) { * @param src * @param close */ -export function fromIterableSync(src: Iterable, close = true) { - return new Stream( - (stream) => { - for (let s of src) { - stream.next(s); - } - close && stream.done(); - return null; - }, - `iterable-${Subscription.NEXT_ID++}` - ); -} +export const fromIterableSync = + (src: Iterable, close = true) => + new Stream( + (stream) => { + for (let s of src) { + stream.next(s); + } + close && stream.done(); + return null; + }, + `iterable-${Subscription.NEXT_ID++}` + ); diff --git a/packages/rstream/src/from/promise.ts b/packages/rstream/src/from/promise.ts index 416a2962db..0cf5af1cd8 100644 --- a/packages/rstream/src/from/promise.ts +++ b/packages/rstream/src/from/promise.ts @@ -9,31 +9,32 @@ import { Subscription } from "../subscription"; * * @param src */ -export function fromPromise(src: Promise) { - let canceled = false; - let isError = false; - let err: any = {}; - src.catch( - (e) => { - err = e; - isError = true; - } - ); - return new Stream((stream) => { - src.then( - (x) => { - if (!canceled && stream.getState() < State.DONE) { - if (isError) { - stream.error(err); - err = null; - } else { - stream.next(x); - stream.done(); - } - } - }, - (e) => stream.error(e) +export const fromPromise = + (src: Promise) => { + let canceled = false; + let isError = false; + let err: any = {}; + src.catch( + (e) => { + err = e; + isError = true; + } ); - return () => { canceled = true; }; - }, `promise-${Subscription.NEXT_ID++}`); -} + return new Stream((stream) => { + src.then( + (x) => { + if (!canceled && stream.getState() < State.DONE) { + if (isError) { + stream.error(err); + err = null; + } else { + stream.next(x); + stream.done(); + } + } + }, + (e) => stream.error(e) + ); + return () => { canceled = true; }; + }, `promise-${Subscription.NEXT_ID++}`); + }; diff --git a/packages/rstream/src/from/promises.ts b/packages/rstream/src/from/promises.ts index bd533037f2..e270152323 100644 --- a/packages/rstream/src/from/promises.ts +++ b/packages/rstream/src/from/promises.ts @@ -33,6 +33,6 @@ import { fromPromise } from "./promise"; * * @param promises */ -export function fromPromises(promises: Iterable>): Subscription { - return fromPromise(Promise.all(promises)).transform(mapcat((x: T[]) => x)); -} +export const fromPromises = + (promises: Iterable>): Subscription => + fromPromise(Promise.all(promises)).transform(mapcat((x: T[]) => x)); diff --git a/packages/rstream/src/from/raf.ts b/packages/rstream/src/from/raf.ts index f9de131334..442eba579b 100644 --- a/packages/rstream/src/from/raf.ts +++ b/packages/rstream/src/from/raf.ts @@ -13,17 +13,19 @@ import { fromInterval } from "./interval"; * Subscribers to this stream will be processed during that same loop * iteration. */ -export function fromRAF() { - return isNode() ? +export const fromRAF = () => + isNode() ? fromInterval(16) : - new Stream((stream) => { - let i = 0; - let isActive = true; - let loop = () => { - isActive && stream.next(i++); - isActive && (id = requestAnimationFrame(loop)); - }; - let id = requestAnimationFrame(loop); - return () => (isActive = false, cancelAnimationFrame(id)); - }, `raf-${Subscription.NEXT_ID++}`); -} + new Stream( + (stream) => { + let i = 0; + let isActive = true; + let loop = () => { + isActive && stream.next(i++); + isActive && (id = requestAnimationFrame(loop)); + }; + let id = requestAnimationFrame(loop); + return () => (isActive = false, cancelAnimationFrame(id)); + }, + `raf-${Subscription.NEXT_ID++}` + ); diff --git a/packages/rstream/src/from/view.ts b/packages/rstream/src/from/view.ts index 35a9af2e13..738e3efaf5 100644 --- a/packages/rstream/src/from/view.ts +++ b/packages/rstream/src/from/view.ts @@ -43,18 +43,26 @@ import { Stream } from "../stream"; * @param equiv * @param id */ -export function fromView(atom: ReadonlyAtom, path: Path, tx?: ViewTransform, equiv?: Predicate2, id?: string): Stream { - return new Stream((stream) => { - let isActive = true; - const view = new View( - atom, - path, - tx ? - (x) => isActive && (x = tx(x), stream.next(x), x) : - (x) => isActive && (stream.next(x), x), - false, - equiv - ); - return () => (isActive = false, view.release()); - }, id); -} +export const fromView = ( + atom: ReadonlyAtom, + path: Path, + tx?: ViewTransform, + equiv?: Predicate2, + id?: string +): Stream => + new Stream( + (stream) => { + let isActive = true; + const view = new View( + atom, + path, + tx ? + (x) => isActive && (x = tx(x), stream.next(x), x) : + (x) => isActive && (stream.next(x), x), + false, + equiv + ); + return () => (isActive = false, view.release()); + }, + id + ); diff --git a/packages/rstream/src/from/worker.ts b/packages/rstream/src/from/worker.ts index e045c5f3ce..452d570d59 100644 --- a/packages/rstream/src/from/worker.ts +++ b/packages/rstream/src/from/worker.ts @@ -21,20 +21,21 @@ import { makeWorker } from "../utils/worker"; * @param worker * @param terminate */ -export function fromWorker(worker: Worker | Blob | string, terminate = true) { - const _worker = makeWorker(worker); - return new Stream((stream) => { - const ml = (e: MessageEvent) => { stream.next(e.data); }; - const el = (e: MessageEvent) => { stream.error(e.data); }; - _worker.addEventListener("message", ml); - _worker.addEventListener("error", el); - return () => { - _worker.removeEventListener("message", ml); - _worker.removeEventListener("error", el); - if (terminate) { - DEBUG && console.log("terminating worker", _worker); - _worker.terminate(); - } - }; - }); -} +export const fromWorker = + (worker: Worker | Blob | string, terminate = true) => { + const _worker = makeWorker(worker); + return new Stream((stream) => { + const ml = (e: MessageEvent) => { stream.next(e.data); }; + const el = (e: MessageEvent) => { stream.error(e.data); }; + _worker.addEventListener("message", ml); + _worker.addEventListener("error", el); + return () => { + _worker.removeEventListener("message", ml); + _worker.removeEventListener("error", el); + if (terminate) { + DEBUG && console.log("terminating worker", _worker); + _worker.terminate(); + } + }; + }); + }; diff --git a/packages/rstream/src/pubsub.ts b/packages/rstream/src/pubsub.ts index 8d97720d60..04815beaa2 100644 --- a/packages/rstream/src/pubsub.ts +++ b/packages/rstream/src/pubsub.ts @@ -136,6 +136,6 @@ export class PubSub extends Subscription { * * @param opts */ -export function pubsub(opts: PubSubOpts) { - return new PubSub(opts); -} \ No newline at end of file +export const pubsub = + (opts: PubSubOpts) => + new PubSub(opts); diff --git a/packages/rstream/src/stream-merge.ts b/packages/rstream/src/stream-merge.ts index ff274bd5ed..a5696007f5 100644 --- a/packages/rstream/src/stream-merge.ts +++ b/packages/rstream/src/stream-merge.ts @@ -67,9 +67,9 @@ export interface StreamMergeOpts extends IID { * // ["b", 30] * ``` */ -export function merge(opts?: Partial>) { - return new StreamMerge(opts); -} +export const merge = + (opts?: Partial>) => + new StreamMerge(opts); export class StreamMerge extends Subscription { diff --git a/packages/rstream/src/stream-sync.ts b/packages/rstream/src/stream-sync.ts index 467758f7e9..be3a4be463 100644 --- a/packages/rstream/src/stream-sync.ts +++ b/packages/rstream/src/stream-sync.ts @@ -91,9 +91,9 @@ export interface StreamSyncOpts extends IID { * the @thi.ng/transducers package. See this function's docs for further * details. */ -export function sync(opts: Partial>) { - return new StreamSync(opts); -} +export const sync = + (opts: Partial>) => + new StreamSync(opts); export class StreamSync extends Subscription { diff --git a/packages/rstream/src/subs/bisect.ts b/packages/rstream/src/subs/bisect.ts index 2a05864e2c..5d8d7b03eb 100644 --- a/packages/rstream/src/subs/bisect.ts +++ b/packages/rstream/src/subs/bisect.ts @@ -44,9 +44,13 @@ import { PubSub } from "../pubsub"; * @param a subscription for truthy branch * @param b subscription for falsy branch */ -export function bisect(pred: Predicate, a?: ISubscriber, b?: ISubscriber): PubSub { +export const bisect = ( + pred: Predicate, + a?: ISubscriber, + b?: ISubscriber +): PubSub => { const sub = new PubSub({ topic: pred }); sub.subscribeTopic(true, a); sub.subscribeTopic(false, b); return sub; -} +}; diff --git a/packages/rstream/src/subs/post-worker.ts b/packages/rstream/src/subs/post-worker.ts index c6520fdcff..581263b593 100644 --- a/packages/rstream/src/subs/post-worker.ts +++ b/packages/rstream/src/subs/post-worker.ts @@ -34,7 +34,12 @@ import { makeWorker } from "../utils/worker"; * @param transfer * @param terminate worker termination delay (ms) */ -export function postWorker(worker: Worker | Blob | string, transfer = false, terminate = 0): ISubscriber { +export const postWorker = ( + worker: Worker | Blob | string, + transfer = false, + terminate = 0 +): ISubscriber => { + const _worker = makeWorker(worker); return { next(x) { @@ -60,4 +65,4 @@ export function postWorker(worker: Worker | Blob | string, transfer = false, } } }; -} \ No newline at end of file +}; diff --git a/packages/rstream/src/subs/resolve.ts b/packages/rstream/src/subs/resolve.ts index 821067eb9b..e544fd5882 100644 --- a/packages/rstream/src/subs/resolve.ts +++ b/packages/rstream/src/subs/resolve.ts @@ -30,9 +30,9 @@ export interface ResolverOpts extends IID { * * @param opts */ -export function resolve(opts?: Partial) { - return new Resolver(opts); -} +export const resolve = + (opts?: Partial) => + new Resolver(opts); export class Resolver extends Subscription, T> { diff --git a/packages/rstream/src/subs/sidechain-partition.ts b/packages/rstream/src/subs/sidechain-partition.ts index b0d7307876..a3dab3abaf 100644 --- a/packages/rstream/src/subs/sidechain-partition.ts +++ b/packages/rstream/src/subs/sidechain-partition.ts @@ -27,9 +27,12 @@ import { Subscription } from "../subscription"; * @param pred * @param id */ -export function sidechainPartition(side: ISubscribable, pred?: Predicate, id?: string): Subscription { - return new SidechainPartition(side, pred, id); -} +export const sidechainPartition = ( + side: ISubscribable, + pred?: Predicate, + id?: string +): Subscription => + new SidechainPartition(side, pred, id); export class SidechainPartition extends Subscription { diff --git a/packages/rstream/src/subs/sidechain-toggle.ts b/packages/rstream/src/subs/sidechain-toggle.ts index 30595d9864..3cb230fb00 100644 --- a/packages/rstream/src/subs/sidechain-toggle.ts +++ b/packages/rstream/src/subs/sidechain-toggle.ts @@ -29,9 +29,13 @@ import { Subscription } from "../subscription"; * @param initial initial switch state * @param id */ -export function sidechainToggle(side: ISubscribable, initial = true, pred?: Predicate, id?: string): Subscription { - return new SidechainToggle(side, initial, pred, id); -} +export const sidechainToggle = ( + side: ISubscribable, + initial = true, + pred?: Predicate, + id?: string +): Subscription => + new SidechainToggle(side, initial, pred, id); export class SidechainToggle extends Subscription { diff --git a/packages/rstream/src/subs/timeout.ts b/packages/rstream/src/subs/timeout.ts index 67e074cb2f..8ad52d2855 100644 --- a/packages/rstream/src/subs/timeout.ts +++ b/packages/rstream/src/subs/timeout.ts @@ -14,9 +14,13 @@ import { Subscription } from "../subscription"; * @param resetTimeout timeout reset flag * @param id subscription id */ -export function timeout(timeoutMs: number, error?: any, resetTimeout = false, id?: string): Subscription { - return new Timeout(timeoutMs, error, resetTimeout, id); -} +export const timeout = ( + timeoutMs: number, + error?: any, + resetTimeout = false, + id?: string +): Subscription => + new Timeout(timeoutMs, error, resetTimeout, id); class Timeout extends Subscription { protected timeoutMs: number; diff --git a/packages/rstream/src/subs/trace.ts b/packages/rstream/src/subs/trace.ts index e9a403d8f4..ad5874e06f 100644 --- a/packages/rstream/src/subs/trace.ts +++ b/packages/rstream/src/subs/trace.ts @@ -6,16 +6,16 @@ import { ISubscriber } from "../api"; * * @param prefix */ -export function trace(prefix?: any): ISubscriber { - return { - next(x) { - prefix ? console.log(prefix, x) : console.log(x); - }, - done() { - prefix ? console.log(prefix, "done") : console.log("done"); - }, - error(e) { - prefix ? console.log(prefix, "error", e) : console.log("error", e); - } - } -} +export const trace = + (prefix?: any): ISubscriber => + ({ + next(x) { + prefix ? console.log(prefix, x) : console.log(x); + }, + done() { + prefix ? console.log(prefix, "done") : console.log("done"); + }, + error(e) { + prefix ? console.log(prefix, "error", e) : console.log("error", e); + } + }); diff --git a/packages/rstream/src/subs/transduce.ts b/packages/rstream/src/subs/transduce.ts index 123d904653..22d7b8231b 100644 --- a/packages/rstream/src/subs/transduce.ts +++ b/packages/rstream/src/subs/transduce.ts @@ -24,7 +24,13 @@ import { Subscription } from "../subscription"; * @param rfn * @param init */ -export function transduce(src: Subscription, xform: Transducer, rfn: Reducer, init?: C): Promise { +export const transduce = ( + src: Subscription, + xform: Transducer, + rfn: Reducer, + init?: C +): Promise => { + let acc = init !== undefined ? init : rfn[0](); let sub: Subscription; @@ -55,4 +61,4 @@ export function transduce(src: Subscription, xform: Transducer< throw rejected; } ); -} +}; diff --git a/packages/rstream/src/subs/tunnel.ts b/packages/rstream/src/subs/tunnel.ts index 8e135884a7..5dee60cdb2 100644 --- a/packages/rstream/src/subs/tunnel.ts +++ b/packages/rstream/src/subs/tunnel.ts @@ -54,8 +54,9 @@ export interface TunnelOpts { * * @param opts */ -export const tunnel = (opts: TunnelOpts) => - new Tunnel(opts); +export const tunnel = + (opts: TunnelOpts) => + new Tunnel(opts); export class Tunnel extends Subscription { diff --git a/packages/rstream/src/subscription.ts b/packages/rstream/src/subscription.ts index f6ac3a69ab..c61cadcf8f 100644 --- a/packages/rstream/src/subscription.ts +++ b/packages/rstream/src/subscription.ts @@ -51,9 +51,13 @@ import { * @param parent * @param id */ -export function subscription(sub?: ISubscriber, xform?: Transducer, parent?: ISubscribable, id?: string) { - return new Subscription(sub, xform, parent, id); -} +export const subscription = ( + sub?: ISubscriber, + xform?: Transducer, + parent?: ISubscribable, + id?: string +) => + new Subscription(sub, xform, parent, id); export class Subscription implements IDeref, diff --git a/packages/rstream/src/utils/idgen.ts b/packages/rstream/src/utils/idgen.ts new file mode 100644 index 0000000000..6a23983489 --- /dev/null +++ b/packages/rstream/src/utils/idgen.ts @@ -0,0 +1,3 @@ +let NEXT_ID = 0; + +export const nextID = () => NEXT_ID++; diff --git a/packages/rstream/src/utils/worker.ts b/packages/rstream/src/utils/worker.ts index 16221ab2c3..20588eba9a 100644 --- a/packages/rstream/src/utils/worker.ts +++ b/packages/rstream/src/utils/worker.ts @@ -2,12 +2,12 @@ export function inlineWorker(src: string) { return makeWorker(new Blob([src], { type: "text/javascript" })); } -export function makeWorker(worker: Worker | string | Blob) { - return worker instanceof Worker ? - worker : - new Worker( - worker instanceof Blob ? - URL.createObjectURL(worker) : - worker - ); -} +export const makeWorker = + (worker: Worker | string | Blob) => + worker instanceof Worker ? + worker : + new Worker( + worker instanceof Blob ? + URL.createObjectURL(worker) : + worker + ); From ff9f8e0cc88b7304e64b344768c72562c4d7c807 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 06:18:52 +0000 Subject: [PATCH 194/333] minor(rstream-graph): update formatting --- packages/rstream-graph/src/api.ts | 23 ++-- packages/rstream-graph/src/graph.ts | 141 ++++++++++++-------- packages/rstream-graph/src/nodes/extract.ts | 5 +- packages/rstream-graph/src/nodes/math.ts | 54 +++++--- 4 files changed, 133 insertions(+), 90 deletions(-) diff --git a/packages/rstream-graph/src/api.ts b/packages/rstream-graph/src/api.ts index bda295f8ba..17e8b6d9ec 100644 --- a/packages/rstream-graph/src/api.ts +++ b/packages/rstream-graph/src/api.ts @@ -1,5 +1,6 @@ -import { IObjectOf } from "@thi.ng/api/api"; +import { Fn, IObjectOf } from "@thi.ng/api/api"; import { Path } from "@thi.ng/paths"; +import { ResolveFn } from "@thi.ng/resolve-map"; import { ISubscribable } from "@thi.ng/rstream/api"; import { Transducer } from "@thi.ng/transducers/api"; @@ -7,8 +8,10 @@ import { Transducer } from "@thi.ng/transducers/api"; * A function which constructs and returns an `ISubscribable` using * given object of inputs and node ID. See `node()` and `node1()`. */ -export type NodeFactory = (src: NodeInputs, id: string) => ISubscribable; +export type NodeFactory = + (src: NodeInputs, id: string) => ISubscribable; +export type NodeResolver = Fn; export type NodeInputs = IObjectOf>; export type NodeOutputs = IObjectOf>; export type Graph = IObjectOf; @@ -25,10 +28,12 @@ export interface Node { * and the operation to be applied to produce one or more result * streams. */ -export type GraphSpec = IObjectOf< - NodeSpec | - Node | - ((resolve: (path: string) => any) => Node)>; +export type GraphSpec = + IObjectOf< + NodeSpec | + Node | + NodeResolver + >; /** * Specification for a single "node" in the dataflow graph. Nodes here @@ -108,6 +113,8 @@ export interface NodeInputSpec { xform?: Transducer; } -export type NodeOutputSpec = Path | NodeOutputFn; +export type NodeOutputSpec = + Path | NodeOutputFn; -export type NodeOutputFn = (node: ISubscribable, id: PropertyKey) => ISubscribable; +export type NodeOutputFn = + (node: ISubscribable, id: PropertyKey) => ISubscribable; diff --git a/packages/rstream-graph/src/graph.ts b/packages/rstream-graph/src/graph.ts index aee4550821..a07afb0056 100644 --- a/packages/rstream-graph/src/graph.ts +++ b/packages/rstream-graph/src/graph.ts @@ -5,14 +5,13 @@ import { isPlainObject } from "@thi.ng/checks/is-plain-object"; import { isString } from "@thi.ng/checks/is-string"; import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; import { getIn } from "@thi.ng/paths"; -import { absPath, resolve } from "@thi.ng/resolve-map"; +import { absPath, resolve, ResolveFn } from "@thi.ng/resolve-map"; import { ISubscribable } from "@thi.ng/rstream/api"; import { fromIterableSync } from "@thi.ng/rstream/from/iterable"; import { fromView } from "@thi.ng/rstream/from/view"; import { StreamSync, sync } from "@thi.ng/rstream/stream-sync"; import { Transducer } from "@thi.ng/transducers/api"; import { map } from "@thi.ng/transducers/xform/map"; - import { Graph, GraphSpec, @@ -37,21 +36,22 @@ import { * @param state * @param spec */ -export const initGraph = (state: IAtom, spec: GraphSpec): Graph => { - const res: Graph = {} - for (let id in spec) { - const n = spec[id]; - if (isNodeSpec(n)) { - res[id] = nodeFromSpec(state, spec[id], id); - } else { - res[id] = n; +export const initGraph = + (state: IAtom, spec: GraphSpec): Graph => { + const res: Graph = {} + for (let id in spec) { + const n = spec[id]; + res[id] = isNodeSpec(n) ? + nodeFromSpec(state, spec[id], id) : + n; } - } - return resolve(res); -}; + return resolve(res); + }; -const isNodeSpec = (x: any): x is NodeSpec => - isPlainObject(x) && isFunction((x).fn); +const isNodeSpec = + (x: any): x is NodeSpec => + isPlainObject(x) && + isFunction((x).fn); /** * Transforms a single `NodeSpec` into a lookup function for `resolve` @@ -96,15 +96,20 @@ const isNodeSpec = (x: any): x is NodeSpec => * @param spec * @param id */ -const nodeFromSpec = (state: IAtom, spec: NodeSpec, id: string) => - (resolve) => { - const ins = prepareNodeInputs(spec.ins, state, resolve); - const node = spec.fn(ins, id); - const outs = prepareNodeOutputs(spec.outs, node, state, id); - return { ins, node, outs }; - }; +const nodeFromSpec = + (state: IAtom, spec: NodeSpec, id: string) => + (resolve: ResolveFn): Node => { + const ins = prepareNodeInputs(spec.ins, state, resolve); + const node = spec.fn(ins, id); + const outs = prepareNodeOutputs(spec.outs, node, state, id); + return { ins, node, outs }; + }; -const prepareNodeInputs = (ins: IObjectOf, state: IAtom, resolve: (x: string) => any) => { +const prepareNodeInputs = ( + ins: IObjectOf, + state: IAtom, + resolve: ResolveFn +) => { const res: NodeInputs = {}; if (!ins) return res; for (let id in ins) { @@ -128,9 +133,14 @@ const prepareNodeInputs = (ins: IObjectOf, state: IAtom, res res[id] = s; } return res; -} +}; -const prepareNodeOutputs = (outs: IObjectOf, node: ISubscribable, state: IAtom, nodeID: string) => { +const prepareNodeOutputs = ( + outs: IObjectOf, + node: ISubscribable, + state: IAtom, + nodeID: string +) => { const res: NodeOutputs = {}; if (!outs) return res; for (let id in outs) { @@ -164,10 +174,14 @@ const prepareNodeOutputs = (outs: IObjectOf, node: ISubscribable * @param id * @param spec */ -export const addNode = (graph: Graph, state: IAtom, id: string, spec: NodeSpec): Node => { - if (graph[id]) { +export const addNode = ( + graph: Graph, + state: IAtom, + id: string, + spec: NodeSpec +): Node => { + graph[id] && illegalArgs(`graph already contains a node with ID: ${id}`); - } return graph[id] = nodeFromSpec(state, spec, id)( (path) => getIn(graph, absPath([id], path)) ); @@ -181,18 +195,19 @@ export const addNode = (graph: Graph, state: IAtom, id: string, spec: NodeS * @param graph * @param id */ -export const removeNode = (graph: Graph, id: string) => { - const node = graph[id]; - if (node) { - node.node.unsubscribe(); - for (let id in node.outs) { - node.outs[id].unsubscribe(); +export const removeNode = + (graph: Graph, id: string) => { + const node = graph[id]; + if (node) { + node.node.unsubscribe(); + for (let id in node.outs) { + node.outs[id].unsubscribe(); + } + delete graph[id]; + return true; } - delete graph[id]; - return true; - } - return false; -}; + return false; + }; /** * Calls `.unsubscribe()` on all nodes in the graph, causing all related @@ -200,11 +215,12 @@ export const removeNode = (graph: Graph, id: string) => { * * @param graph */ -export const stop = (graph: Graph) => { - for (let id in graph) { - graph[id].node.unsubscribe(); - } -}; +export const stop = + (graph: Graph) => { + for (let id in graph) { + graph[id].node.unsubscribe(); + } + }; /** * Higher order node / stream creator. Takes a transducer and (optional) @@ -216,11 +232,14 @@ export const stop = (graph: Graph) => { * @param xform * @param inputIDs */ -export const node = (xform: Transducer, any>, inputIDs?: string[]): NodeFactory => - (src: IObjectOf>, id: string): StreamSync => { - ensureInputs(src, inputIDs, id); - return sync({ src, xform, id }); - }; +export const node = ( + xform: Transducer, any>, + inputIDs?: string[] +): NodeFactory => + (src: IObjectOf>, id: string): StreamSync => ( + ensureInputs(src, inputIDs, id), + sync({ src, xform, id }) + ); /** * Similar to `node()`, but optimized for nodes using only a single @@ -229,13 +248,16 @@ export const node = (xform: Transducer, any>, inputIDs?: string[] * @param xform * @param inputID */ -export const node1 = (xform?: Transducer, inputID = "src"): NodeFactory => - (src: IObjectOf>, id: string): ISubscribable => { - ensureInputs(src, [inputID], id); - return xform ? +export const node1 = ( + xform?: Transducer, + inputID = "src" +): NodeFactory => + (src: IObjectOf>, id: string): ISubscribable => ( + ensureInputs(src, [inputID], id), + xform ? src[inputID].subscribe(xform, id) : - src[inputID].subscribe(null, id); - }; + src[inputID].subscribe(null, id) + ); /** * Helper function to verify given object of inputs has required input IDs. @@ -245,14 +267,17 @@ export const node1 = (xform?: Transducer, inputID = "src"): NodeFactor * @param inputIDs * @param nodeID */ -export const ensureInputs = (src: IObjectOf>, inputIDs: string[], nodeID: string) => { +export const ensureInputs = ( + src: IObjectOf>, + inputIDs: string[], + nodeID: string +) => { if (inputIDs !== undefined) { const missing: string[] = []; for (let i of inputIDs) { !src[i] && missing.push(i); } - if (missing.length) { + missing.length && illegalArgs(`node "${nodeID}": missing input(s): ${missing.join(", ")}`); - } } }; diff --git a/packages/rstream-graph/src/nodes/extract.ts b/packages/rstream-graph/src/nodes/extract.ts index 1df94cfa92..98b092ec57 100644 --- a/packages/rstream-graph/src/nodes/extract.ts +++ b/packages/rstream-graph/src/nodes/extract.ts @@ -12,5 +12,6 @@ import { node1 } from "../graph"; * @param path value lookup path * @param inputID default: `src` */ -export const extract = (path: Path, inputID?: string): NodeFactory => - node1(map((x) => getIn(x, path)), inputID); +export const extract = + (path: Path, inputID?: string): NodeFactory => + node1(map((x) => getIn(x, path)), inputID); diff --git a/packages/rstream-graph/src/nodes/math.ts b/packages/rstream-graph/src/nodes/math.ts index ff7a1255fa..6878a3c3ec 100644 --- a/packages/rstream-graph/src/nodes/math.ts +++ b/packages/rstream-graph/src/nodes/math.ts @@ -9,32 +9,36 @@ import { node } from "../graph"; * * Inputs: any */ -export const add: NodeFactory = node( - map((ports: IObjectOf) => { - let acc = 0; - let v; - for (let p in ports) { - if ((v = ports[p]) == null) return; - acc += v; - } - return acc; - })); +export const add: NodeFactory = + node( + map((ports: IObjectOf) => { + let acc = 0; + let v; + for (let p in ports) { + if ((v = ports[p]) == null) return; + acc += v; + } + return acc; + }) + ); /** * Multiplication node. * * Inputs: any */ -export const mul: NodeFactory = node( - map((ports: IObjectOf) => { - let acc = 1; - let v; - for (let p in ports) { - if ((v = ports[p]) == null) return; - acc *= v; - } - return acc; - })); +export const mul: NodeFactory = + node( + map((ports: IObjectOf) => { + let acc = 1; + let v; + for (let p in ports) { + if ((v = ports[p]) == null) return; + acc *= v; + } + return acc; + }) + ); /** * Subtraction node. @@ -42,7 +46,10 @@ export const mul: NodeFactory = node( * Inputs: `a`, `b` */ export const sub: NodeFactory = - node(map((ports: IObjectOf) => ports.a - ports.b), ["a", "b"]); + node( + map((ports: IObjectOf) => ports.a - ports.b), + ["a", "b"] + ); /** * Division node. @@ -50,4 +57,7 @@ export const sub: NodeFactory = * Inputs: `a`, `b` */ export const div: NodeFactory = - node(map((ports: IObjectOf) => ports.a / ports.b), ["a", "b"]); + node( + map((ports: IObjectOf) => ports.a / ports.b), + ["a", "b"] + ); From 14c00b29659ad321fc65b1c679c1ff91e8e42ea1 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 06:19:35 +0000 Subject: [PATCH 195/333] refactor(rstream-log): use arrow fns --- packages/rstream-log/src/output/file.ts | 31 ++++++++--------- packages/rstream-log/src/xform/filter.ts | 32 +++++++++--------- packages/rstream-log/src/xform/format.ts | 43 +++++++++++++----------- 3 files changed, 55 insertions(+), 51 deletions(-) diff --git a/packages/rstream-log/src/output/file.ts b/packages/rstream-log/src/output/file.ts index 51dbc51ede..ef410ea80f 100644 --- a/packages/rstream-log/src/output/file.ts +++ b/packages/rstream-log/src/output/file.ts @@ -2,18 +2,19 @@ import { isNode } from "@thi.ng/checks/is-node"; import { unsupported } from "@thi.ng/errors/unsupported"; import { ISubscriber } from "@thi.ng/rstream/api"; -export function writeFile(path: string): ISubscriber { - if (isNode()) { - const fs = require("fs"); - return { - next(msg) { - fs.appendFile(path, msg + "\n", (e) => { - if (e) { - process.stderr.write(e.message); - } - }); - } - }; - } - unsupported("only available in NodeJS"); -} +export const writeFile = + (path: string): ISubscriber => { + if (isNode()) { + const fs = require("fs"); + return { + next(msg) { + fs.appendFile(path, msg + "\n", (e) => { + if (e) { + process.stderr.write(e.message); + } + }); + } + }; + } + unsupported("only available in NodeJS"); + }; diff --git a/packages/rstream-log/src/xform/filter.ts b/packages/rstream-log/src/xform/filter.ts index a4efe2bde3..4fdfb48096 100644 --- a/packages/rstream-log/src/xform/filter.ts +++ b/packages/rstream-log/src/xform/filter.ts @@ -4,22 +4,22 @@ import { filter } from "@thi.ng/transducers/xform/filter"; import { Level, LogEntry } from "../api"; -export function onlyLevel(level: Level): Transducer { - return filter((l) => l[0] === level); -} +export const onlyLevel = + (level: Level): Transducer => + filter((l) => l[0] === level); -export function minLevel(level: Level): Transducer { - return filter((l) => l[0] >= level); -} +export const minLevel = + (level: Level): Transducer => + filter((l) => l[0] >= level); -export function maxLevel(level: Level): Transducer { - return filter((l) => l[0] <= level); -} +export const maxLevel = + (level: Level): Transducer => + filter((l) => l[0] <= level); -export function matchID(id: string | RegExp): Transducer { - return filter( - isString(id) ? - (l) => l[1] === id : - (l) => id.test(l[1]) - ); -} +export const matchID = + (id: string | RegExp): Transducer => + filter( + isString(id) ? + (l) => l[1] === id : + (l) => id.test(l[1]) + ); diff --git a/packages/rstream-log/src/xform/format.ts b/packages/rstream-log/src/xform/format.ts index e9de60c238..93690007d6 100644 --- a/packages/rstream-log/src/xform/format.ts +++ b/packages/rstream-log/src/xform/format.ts @@ -1,6 +1,5 @@ import { Transducer } from "@thi.ng/transducers/api"; import { map } from "@thi.ng/transducers/xform/map"; - import { __Level, BodyFormat, @@ -9,30 +8,34 @@ import { LogEntryObj } from "../api"; -export function formatString(dtFmt?: DateFormat, bodyFmt?: BodyFormat): Transducer { +export const formatString = ( + dtFmt?: DateFormat, + bodyFmt?: BodyFormat +): Transducer => { dtFmt = dtFmt || ((dt) => new Date(dt).toISOString()); bodyFmt = bodyFmt || ((x) => x.toString()); return map( ([level, id, time, ...body]) => `[${__Level[level]}] [${id}] ${dtFmt(time)} ${bodyFmt(body)}` ); -} +}; -export function formatObject(): Transducer { - return map( - ([level, id, time, ...body]) => ({ level, id, time, body }) - ); -} +export const formatObject = + (): Transducer => + map( + ([level, id, time, ...body]) => ({ level, id, time, body }) + ); -export function formatJSON(dtfmt?: (dt: number) => string): Transducer { - dtfmt = dtfmt || ((dt) => new Date(dt).toISOString()); - return map( - ([level, id, time, ...body]) => - JSON.stringify({ - level: __Level[level], - id, - time: dtfmt(time), - body - }) - ); -} +export const formatJSON = + (dtfmt?: DateFormat): Transducer => { + dtfmt = dtfmt || ((dt) => new Date(dt).toISOString()); + return map( + ([level, id, time, ...body]) => + JSON.stringify({ + level: __Level[level], + id, + time: dtfmt(time), + body + }) + ); + }; From 393d23eded277bac8846295268cf8afb92d581f4 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 06:20:27 +0000 Subject: [PATCH 196/333] minor(rstream-query): update formatting --- packages/rstream-query/src/api.ts | 2 +- packages/rstream-query/src/convert.ts | 53 +++++----- packages/rstream-query/src/pattern.ts | 54 ++++++----- packages/rstream-query/src/qvar.ts | 68 ++++++------- packages/rstream-query/src/store.ts | 133 ++++++++++++++------------ 5 files changed, 163 insertions(+), 147 deletions(-) diff --git a/packages/rstream-query/src/api.ts b/packages/rstream-query/src/api.ts index 25c264b154..a23af9c641 100644 --- a/packages/rstream-query/src/api.ts +++ b/packages/rstream-query/src/api.ts @@ -47,4 +47,4 @@ export interface PathQuerySpec { export interface JoinOpts { limit: number; select: string[]; -} \ No newline at end of file +} diff --git a/packages/rstream-query/src/convert.ts b/packages/rstream-query/src/convert.ts index 0f1e2be710..ca03bee3bc 100644 --- a/packages/rstream-query/src/convert.ts +++ b/packages/rstream-query/src/convert.ts @@ -6,26 +6,28 @@ import { mapcat } from "@thi.ng/transducers/xform/mapcat"; let NEXT_ID = 0; -const mapBNode = (s: any, p: any, o: any) => { - const id = `__b${NEXT_ID++}__`; - return concat([[s, p, id]], asTriples(o, id)); -}; - -const mapSubject = (subject: any) => - ([p, o]) => { - if (isArray(o)) { - return mapcat( - (o) => - isPlainObject(o) ? - mapBNode(subject, p, o) : - [[subject, p, o]], - o); - } else if (isPlainObject(o)) { - return mapBNode(subject, p, o); - } - return [[subject, p, o]]; +const mapBNode = + (s: any, p: any, o: any) => { + const id = `__b${NEXT_ID++}__`; + return concat([[s, p, id]], asTriples(o, id)); }; +const mapSubject = + (subject: any) => + ([p, o]) => { + if (isArray(o)) { + return mapcat( + (o) => + isPlainObject(o) ? + mapBNode(subject, p, o) : + [[subject, p, o]], + o); + } else if (isPlainObject(o)) { + return mapBNode(subject, p, o); + } + return [[subject, p, o]]; + }; + /** * Converts given object into an iterable of triples, with the following * conversion rules: @@ -75,10 +77,11 @@ const mapSubject = (subject: any) => * @param obj * @param subject internal use only, do not specify! */ -export const asTriples = (obj: any, subject?: any) => - mapcat( - subject === undefined ? - ([s, v]: any) => mapcat(mapSubject(s), pairs(v)) : - mapSubject(subject), - pairs(obj) - ); +export const asTriples = + (obj: any, subject?: any) => + mapcat( + subject === undefined ? + ([s, v]: any) => mapcat(mapSubject(s), pairs(v)) : + mapSubject(subject), + pairs(obj) + ); diff --git a/packages/rstream-query/src/pattern.ts b/packages/rstream-query/src/pattern.ts index e314c470e5..97ae8667bc 100644 --- a/packages/rstream-query/src/pattern.ts +++ b/packages/rstream-query/src/pattern.ts @@ -3,21 +3,23 @@ import { repeatedly } from "@thi.ng/transducers/iter/repeatedly"; import { PathPattern, Pattern } from "./api"; import { autoQVar, isQVar, qvarName } from "./qvar"; -export const patternVarCount = (p: Pattern) => { - let n = 0; - if (isQVar(p[0])) n++; - if (isQVar(p[1])) n++; - if (isQVar(p[2])) n++; - return n; -}; +export const patternVarCount = + (p: Pattern) => { + let n = 0; + if (isQVar(p[0])) n++; + if (isQVar(p[1])) n++; + if (isQVar(p[2])) n++; + return n; + }; -export const patternVars = ([s, p, o]: Pattern) => { - const vars = []; - isQVar(s) && vars.push(qvarName(s)); - isQVar(p) && vars.push(qvarName(p)); - isQVar(o) && vars.push(qvarName(o)); - return vars; -}; +export const patternVars = + ([s, p, o]: Pattern) => { + const vars = []; + isQVar(s) && vars.push(qvarName(s)); + isQVar(p) && vars.push(qvarName(p)); + isQVar(o) && vars.push(qvarName(o)); + return vars; + }; /** * Takes a path triple pattern and max depth. The pattern's predicate @@ -39,15 +41,17 @@ export const patternVars = ([s, p, o]: Pattern) => { * @param pattern * @param maxLen */ -export const resolvePathPattern = ([s, p, o]: PathPattern, maxLen = p.length): [Pattern[], string[]] => { - const res = []; - const avars = [...repeatedly(autoQVar, maxLen - 1)]; - for (let i = 0; i < maxLen; i++) { - res.push([s, p[i % p.length], s = avars[i]]); - } - res[res.length - 1][2] = o; - return [res, avars]; -}; +export const resolvePathPattern = + ([s, p, o]: PathPattern, maxLen = p.length): [Pattern[], string[]] => { + const res = []; + const avars = [...repeatedly(autoQVar, maxLen - 1)]; + for (let i = 0; i < maxLen; i++) { + res.push([s, p[i % p.length], s = avars[i]]); + } + res[res.length - 1][2] = o; + return [res, avars]; + }; -export const sortPatterns = (patterns: Pattern[]) => - patterns.sort((a, b) => patternVarCount(a) - patternVarCount(b)); +export const sortPatterns = + (patterns: Pattern[]) => + patterns.sort((a, b) => patternVarCount(a) - patternVarCount(b)); diff --git a/packages/rstream-query/src/qvar.ts b/packages/rstream-query/src/qvar.ts index 611ff2749b..5e0373fdf4 100644 --- a/packages/rstream-query/src/qvar.ts +++ b/packages/rstream-query/src/qvar.ts @@ -1,21 +1,20 @@ import { isString } from "@thi.ng/checks/is-string"; - import { Triple } from "./api"; const AUTO_QVAR_PREFIX = "?__q"; let AUTO_QVAR_ID = 0; -export const isQVar = (x: any) => - isString(x) && x.charAt(0) === "?"; +export const isQVar = + (x: any) => isString(x) && x.charAt(0) === "?"; -export const isAutoQVar = (x: any) => - isString(x) && x.indexOf(AUTO_QVAR_PREFIX) == 0; +export const isAutoQVar = + (x: any) => isString(x) && x.indexOf(AUTO_QVAR_PREFIX) == 0; -export const autoQVar = () => - AUTO_QVAR_PREFIX + (AUTO_QVAR_ID++).toString(36); +export const autoQVar = + () => AUTO_QVAR_PREFIX + (AUTO_QVAR_ID++).toString(36); -export const qvarName = (x: string) => - x.substr(1); +export const qvarName = + (x: string) => x.substr(1); /** * Returns an optimized query variable solution extractor function based @@ -31,28 +30,29 @@ export const qvarName = (x: string) => * @param p * @param o */ -export const qvarResolver = (vs: boolean, vp: boolean, vo: boolean, s, p, o) => { - const type = ((vs) << 2) | ((vp) << 1) | (vo); - let ss: any = vs && qvarName(s); - let pp: any = vp && qvarName(p); - let oo: any = vo && qvarName(o); - switch (type) { - case 0: - default: - return; - case 1: - return (f: Triple) => ({ [oo]: f[2] }); - case 2: - return (f: Triple) => ({ [pp]: f[1] }); - case 3: - return (f: Triple) => ({ [pp]: f[1], [oo]: f[2] }); - case 4: - return (f: Triple) => ({ [ss]: f[0] }); - case 5: - return (f: Triple) => ({ [ss]: f[0], [oo]: f[2] }); - case 6: - return (f: Triple) => ({ [ss]: f[0], [pp]: f[1] }); - case 7: - return (f: Triple) => ({ [ss]: f[0], [pp]: f[1], [oo]: f[2] }); - } -}; +export const qvarResolver = + (vs: boolean, vp: boolean, vo: boolean, s, p, o) => { + const type = ((vs) << 2) | ((vp) << 1) | (vo); + let ss: any = vs && qvarName(s); + let pp: any = vp && qvarName(p); + let oo: any = vo && qvarName(o); + switch (type) { + case 0: + default: + return; + case 1: + return (f: Triple) => ({ [oo]: f[2] }); + case 2: + return (f: Triple) => ({ [pp]: f[1] }); + case 3: + return (f: Triple) => ({ [pp]: f[1], [oo]: f[2] }); + case 4: + return (f: Triple) => ({ [ss]: f[0] }); + case 5: + return (f: Triple) => ({ [ss]: f[0], [oo]: f[2] }); + case 6: + return (f: Triple) => ({ [ss]: f[0], [pp]: f[1] }); + case 7: + return (f: Triple) => ({ [ss]: f[0], [pp]: f[1], [oo]: f[2] }); + } + }; diff --git a/packages/rstream-query/src/store.ts b/packages/rstream-query/src/store.ts index b4b7b9f070..1640fe16ef 100644 --- a/packages/rstream-query/src/store.ts +++ b/packages/rstream-query/src/store.ts @@ -416,74 +416,83 @@ const intersect2: Transducer, TripleIds> = const intersect3: Transducer, TripleIds> = comp(map(({ s, p, o }) => intersection(intersection(s, p), o)), dedupe(equiv)); -const indexSel = (key: any): Transducer => - (rfn: Reducer) => { - const r = rfn[2]; - return compR(rfn, - (acc, e) => { - DEBUG && console.log("index sel", e.key, key); - if (equiv(e.key, key)) { - return r(acc, e.index); +const indexSel = + (key: any): Transducer => + (rfn: Reducer) => { + const r = rfn[2]; + return compR(rfn, + (acc, e) => { + DEBUG && console.log("index sel", e.key, key); + if (equiv(e.key, key)) { + return r(acc, e.index); + } + return acc; } - return acc; + ); + }; + +const resultTriples = + (graph: TripleStore) => + map>( + (ids) => { + const res = new Set(); + for (let id of ids) res.add(graph.triples[id]); + return res; + }); + +const joinSolutions = + (n: number) => + map, Solutions>((src) => { + let res: Solutions = src[0]; + for (let i = 1; i < n && res.size; i++) { + res = join(res, src[i]); } - ); - }; + return res; + }); -const resultTriples = (graph: TripleStore) => - map>( - (ids) => { - const res = new Set(); - for (let id of ids) res.add(graph.triples[id]); +const filterSolutions = + (qvars: Iterable) => { + const filterVars = keySelector([...qvars]); + return map((sol: Solutions) => { + const res: Solutions = new Set(); + for (let s of sol) { + res.add(filterVars(s)); + } return res; }); + }; -const joinSolutions = (n: number) => - map, Solutions>((src) => { - let res: Solutions = src[0]; - for (let i = 1; i < n && res.size; i++) { - res = join(res, src[i]); - } - return res; - }); - -const filterSolutions = (qvars: Iterable) => { - const filterVars = keySelector([...qvars]); - return map((sol: Solutions) => { - const res: Solutions = new Set(); - for (let s of sol) { - res.add(filterVars(s)); - } - return res; - }); -}; +const limitSolutions = + (n: number) => + map((sol: Solutions) => { + if (sol.size <= n) { + return sol; + } + const res: Solutions = new Set(); + let m = n; + for (let s of sol) { + res.add(s); + if (--m <= 0) break; + } + return res; + }); -const limitSolutions = (n: number) => - map((sol: Solutions) => { - if (sol.size <= n) { - return sol; - } - const res: Solutions = new Set(); - let m = n; - for (let s of sol) { - res.add(s); - if (--m <= 0) break; - } - return res; - }); - -const bindVars = (bindings: IObjectOf) => - map((sol: Solutions) => { - const res: Solutions = new Set(); - for (let s of sol) { - s = { ...s }; - res.add(s); - for (let b in bindings) { - s[b] = bindings[b](s); +const bindVars = + (bindings: IObjectOf) => + map((sol: Solutions) => { + const res: Solutions = new Set(); + for (let s of sol) { + s = { ...s }; + res.add(s); + for (let b in bindings) { + s[b] = bindings[b](s); + } } - } - return res; - }); + return res; + }); + +const isWhereQuery = + (q: SubQuerySpec): q is WhereQuerySpec => !!(q).where; -const isWhereQuery = (q: SubQuerySpec): q is WhereQuerySpec => !!(q).where; -const isPathQuery = (q: SubQuerySpec): q is PathQuerySpec => !!(q).path; +const isPathQuery = + (q: SubQuerySpec): q is PathQuerySpec => !!(q).path; From 8904cb4c5e20b9b6e6eabd715ef7bdfc6272282f Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 06:21:02 +0000 Subject: [PATCH 197/333] refactor(rstream-gestures): use arrow fns --- packages/rstream-gestures/src/index.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/rstream-gestures/src/index.ts b/packages/rstream-gestures/src/index.ts index ab75860468..861c1c1b63 100644 --- a/packages/rstream-gestures/src/index.ts +++ b/packages/rstream-gestures/src/index.ts @@ -105,9 +105,14 @@ export interface GestureStreamOpts extends IID { * @param el * @param opts */ -export function gestureStream(el: HTMLElement, opts?: Partial): StreamMerge { +export const gestureStream = ( + el: HTMLElement, + opts?: Partial +): StreamMerge => { + let isDown = false, clickPos: number[]; + opts = Object.assign({ id: "gestures", zoom: 1, @@ -120,8 +125,10 @@ export function gestureStream(el: HTMLElement, opts?: Partial local: true, scale: false, }, opts); + let zoom = Math.min(Math.max(opts.zoom, opts.minZoom), opts.maxZoom); const dpr = window.devicePixelRatio || 1; + return merge({ id: opts.id, src: [ @@ -183,4 +190,4 @@ export function gestureStream(el: HTMLElement, opts?: Partial return [type, body]; }) }); -} +}; From 762db4e334c524ae95e4cb3453f4e401d3335b54 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 06:21:35 +0000 Subject: [PATCH 198/333] refactor(rstream-csp): use arrow fns --- packages/rstream-csp/src/from/channel.ts | 47 +++++++++++++----------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/packages/rstream-csp/src/from/channel.ts b/packages/rstream-csp/src/from/channel.ts index 5638f9fc05..6d5ca7f14d 100644 --- a/packages/rstream-csp/src/from/channel.ts +++ b/packages/rstream-csp/src/from/channel.ts @@ -7,25 +7,28 @@ import { Stream } from "@thi.ng/rstream/stream"; * @param src * @param closeWhenCancelled */ -export function fromChannel(src: Channel, closeWhenCancelled = true) { - return new Stream((stream) => { - let isActive = true; - (async () => { - let x; - while ((x = null, x = await src.read()) !== undefined) { - if (x === undefined || !isActive) { - break; - } - stream.next(x); - } - stream.done(); - })(); - return () => { - if (closeWhenCancelled) { - src.close(true); - DEBUG && console.log("closed channel", src.id); - } - isActive = false; - }; - }, `obs-${src.id}`); -} +export const fromChannel = + (src: Channel, closeWhenCancelled = true) => + new Stream( + (stream) => { + let isActive = true; + (async () => { + let x; + while ((x = null, x = await src.read()) !== undefined) { + if (x === undefined || !isActive) { + break; + } + stream.next(x); + } + stream.done(); + })(); + return () => { + if (closeWhenCancelled) { + src.close(true); + DEBUG && console.log("closed channel", src.id); + } + isActive = false; + }; + }, + `obs-${src.id}` + ); From 6eba241520311f06725084398a6e4ce37768aa42 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 06:22:15 +0000 Subject: [PATCH 199/333] refactor(rle-pack): use arrow fns --- packages/rle-pack/src/index.ts | 63 +++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/packages/rle-pack/src/index.ts b/packages/rle-pack/src/index.ts index e6e5901bdd..deeae4cb88 100644 --- a/packages/rle-pack/src/index.ts +++ b/packages/rle-pack/src/index.ts @@ -12,7 +12,12 @@ export type RLESizes = [number, number, number, number]; * @param wordSize in bits, range 1 - 32 * @param rleSizes run-length group sizes (in bits, max. 16) */ -export function encode(src: Iterable, num: number, wordSize = 8, rleSizes: RLESizes = [3, 4, 8, 16]) { +export const encode = ( + src: Iterable, + num: number, + wordSize = 8, + rleSizes: RLESizes = [3, 4, 8, 16] +) => { (wordSize < 1 || wordSize > 32) && illegalArgs("word size (1-32 bits only)"); const out = new BitOutputStream(Math.ceil(num * wordSize / 8) + 4 + 2 + 1) .write(num, 32) @@ -80,34 +85,36 @@ export function encode(src: Iterable, num: number, wordSize = 8, rleSize writeRLE(); } return out.bytes(); -} +}; -export function decode(src: Uint8Array) { - const input = new BitInputStream(src); - const num = input.read(32); - const wordSize = input.read(5) + 1; - const rleSizes = [0, 0, 0, 0].map(() => input.read(4) + 1); - const out = arrayForWordSize(wordSize, num); - let x, j; - for (let i = 0; i < num;) { - x = input.readBit(); - j = i + 1 + input.read(rleSizes[input.read(2)]); - if (x) { - out.fill(input.read(wordSize), i, j); - i = j; - } else { - for (; i < j; i++) { - out[i] = input.read(wordSize); +export const decode = + (src: Uint8Array) => { + const input = new BitInputStream(src); + const num = input.read(32); + const wordSize = input.read(5) + 1; + const rleSizes = [0, 0, 0, 0].map(() => input.read(4) + 1); + const out = arrayForWordSize(wordSize, num); + let x, j; + for (let i = 0; i < num;) { + x = input.readBit(); + j = i + 1 + input.read(rleSizes[input.read(2)]); + if (x) { + out.fill(input.read(wordSize), i, j); + i = j; + } else { + for (; i < j; i++) { + out[i] = input.read(wordSize); + } } } - } - return out; -} + return out; + }; -const arrayForWordSize = (ws: number, n: number) => { - return new (ws < 9 ? - Uint8Array : - ws < 17 ? - Uint16Array : - Uint32Array)(n); -} \ No newline at end of file +const arrayForWordSize = + (ws: number, n: number) => { + return new (ws < 9 ? + Uint8Array : + ws < 17 ? + Uint16Array : + Uint32Array)(n); + }; \ No newline at end of file From e9f0542aadf3e038e66ae4622cfe561e01335001 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 06:23:06 +0000 Subject: [PATCH 200/333] refactor(transducers): use arrow fns --- .../transducers/src/func/binary-search.ts | 11 ++- packages/transducers/src/func/compr.ts | 6 +- packages/transducers/src/func/constantly.ts | 5 +- .../transducers/src/func/deep-transform.ts | 29 +++---- packages/transducers/src/func/delay.ts | 6 +- packages/transducers/src/func/ensure-array.ts | 12 +-- .../transducers/src/func/ensure-iterable.ts | 13 +-- packages/transducers/src/func/fuzzy-match.ts | 8 +- packages/transducers/src/func/identity.ts | 2 +- packages/transducers/src/func/key-selector.ts | 6 +- packages/transducers/src/func/lookup.ts | 20 ++--- packages/transducers/src/func/peek.ts | 5 +- packages/transducers/src/func/random-id.ts | 5 +- packages/transducers/src/func/renamer.ts | 81 ++++++++++--------- packages/transducers/src/func/shuffle.ts | 23 +++--- packages/transducers/src/func/swizzler.ts | 63 ++++++++------- .../transducers/src/func/weighted-random.ts | 7 +- packages/transducers/src/iter/choices.ts | 8 +- packages/transducers/src/iter/permutations.ts | 23 +++--- packages/transducers/src/iter/wrap-both.ts | 5 +- packages/transducers/src/iter/wrap-left.ts | 5 +- packages/transducers/src/iter/wrap-right.ts | 5 +- packages/transducers/src/iterator.ts | 6 +- packages/transducers/src/reduce.ts | 23 +++--- packages/transducers/src/reduced.ts | 20 ++--- packages/transducers/src/rfn/group-binary.ts | 17 ++-- packages/transducers/src/rfn/push-copy.ts | 6 +- packages/transducers/src/step.ts | 33 ++++---- packages/transducers/src/xform/cat.ts | 34 ++++---- packages/transducers/src/xform/delayed.ts | 6 +- packages/transducers/src/xform/noop.ts | 6 +- packages/transducers/src/xform/side-effect.ts | 6 +- packages/transducers/src/xform/trace.ts | 6 +- 33 files changed, 267 insertions(+), 244 deletions(-) diff --git a/packages/transducers/src/func/binary-search.ts b/packages/transducers/src/func/binary-search.ts index 577514154d..01093cdccf 100644 --- a/packages/transducers/src/func/binary-search.ts +++ b/packages/transducers/src/func/binary-search.ts @@ -1,4 +1,4 @@ -import { Comparator } from "@thi.ng/api/api"; +import { Comparator, Fn } from "@thi.ng/api/api"; /** * Returns the supposed index of `x` in pre-sorted array-like collection @@ -12,7 +12,12 @@ import { Comparator } from "@thi.ng/api/api"; * @param x * @returns index of `x`, else `-index` if item could not be found */ -export function binarySearch(arr: ArrayLike, key: (x: A) => B, cmp: Comparator, x: A) { +export const binarySearch = ( + arr: ArrayLike, + key: Fn, + cmp: Comparator, + x: A +) => { const kx = key(x); let low = 0; let high = arr.length - 1; @@ -28,4 +33,4 @@ export function binarySearch(arr: ArrayLike, key: (x: A) => B, cmp: Com } } return -low; -} +}; diff --git a/packages/transducers/src/func/compr.ts b/packages/transducers/src/func/compr.ts index aa77db09e4..6fb54a53b6 100644 --- a/packages/transducers/src/func/compr.ts +++ b/packages/transducers/src/func/compr.ts @@ -22,6 +22,6 @@ import { Reduced } from "../reduced"; * @param rfn * @param fn */ -export function compR(rfn: Reducer, fn: (acc: A, x: C) => A | Reduced) { - return >[rfn[0], rfn[1], fn]; -} +export const compR = + (rfn: Reducer, fn: (acc: A, x: C) => A | Reduced): Reducer => + [rfn[0], rfn[1], fn]; diff --git a/packages/transducers/src/func/constantly.ts b/packages/transducers/src/func/constantly.ts index dfd4499078..514541cc8d 100644 --- a/packages/transducers/src/func/constantly.ts +++ b/packages/transducers/src/func/constantly.ts @@ -1,3 +1,2 @@ -export function constantly(x: T): (...args: any[]) => T { - return () => x; -} +export const constantly = + (x: T): (...args: any[]) => T => () => x; diff --git a/packages/transducers/src/func/deep-transform.ts b/packages/transducers/src/func/deep-transform.ts index 12771c0450..4b78417788 100644 --- a/packages/transducers/src/func/deep-transform.ts +++ b/packages/transducers/src/func/deep-transform.ts @@ -63,19 +63,20 @@ import { TransformSpec } from "../api"; * * @param spec transformation spec */ -export function deepTransform(spec: TransformSpec): (x: any) => any { - if (isFunction(spec)) { - return spec; - } - const mapfns = Object.keys(spec[1] || {}).reduce( - (acc, k) => (acc[k] = deepTransform((spec)[1][k]), acc), - {} - ); - return (x) => { - const res = { ...x }; - for (let k in mapfns) { - res[k] = mapfns[k](res[k]); +export const deepTransform = + (spec: TransformSpec): (x: any) => any => { + if (isFunction(spec)) { + return spec; } - return spec[0](res); + const mapfns = Object.keys(spec[1] || {}).reduce( + (acc, k) => (acc[k] = deepTransform((spec)[1][k]), acc), + {} + ); + return (x) => { + const res = { ...x }; + for (let k in mapfns) { + res[k] = mapfns[k](res[k]); + } + return spec[0](res); + }; }; -} diff --git a/packages/transducers/src/func/delay.ts b/packages/transducers/src/func/delay.ts index 274d61cb04..c276804747 100644 --- a/packages/transducers/src/func/delay.ts +++ b/packages/transducers/src/func/delay.ts @@ -1,3 +1,3 @@ -export function delay(x: T, t: number) { - return new Promise((resolve) => setTimeout(() => resolve(x), t)); -} +export const delay = + (x: T, t: number) => + new Promise((resolve) => setTimeout(() => resolve(x), t)); diff --git a/packages/transducers/src/func/ensure-array.ts b/packages/transducers/src/func/ensure-array.ts index 5928b40a58..94bdbaac25 100644 --- a/packages/transducers/src/func/ensure-array.ts +++ b/packages/transducers/src/func/ensure-array.ts @@ -10,10 +10,10 @@ import { ensureIterable } from "./ensure-iterable"; * * @param x */ -export function ensureArray(x: any): any[] { - return isArray(x) ? x : [...ensureIterable(x)]; -} +export const ensureArray = + (x: any): any[] => + isArray(x) ? x : [...ensureIterable(x)]; -export function ensureArrayLike(x: any): ArrayLike { - return isArrayLike(x) ? x : [...ensureIterable(x)]; -} +export const ensureArrayLike = + (x: any): ArrayLike => + isArrayLike(x) ? x : [...ensureIterable(x)]; diff --git a/packages/transducers/src/func/ensure-iterable.ts b/packages/transducers/src/func/ensure-iterable.ts index f481c96398..9a92cc19cc 100644 --- a/packages/transducers/src/func/ensure-iterable.ts +++ b/packages/transducers/src/func/ensure-iterable.ts @@ -1,8 +1,9 @@ import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -export function ensureIterable(x: any): IterableIterator { - if (!(x != null && x[Symbol.iterator])) { - illegalArgs(`value is not iterable: ${x}`); - } - return x; -} +export const ensureIterable = + (x: any): IterableIterator => { + if (!(x != null && x[Symbol.iterator])) { + illegalArgs(`value is not iterable: ${x}`); + } + return x; + }; diff --git a/packages/transducers/src/func/fuzzy-match.ts b/packages/transducers/src/func/fuzzy-match.ts index aa9f557cca..bc4a123062 100644 --- a/packages/transducers/src/func/fuzzy-match.ts +++ b/packages/transducers/src/func/fuzzy-match.ts @@ -15,7 +15,11 @@ import { equiv } from "@thi.ng/equiv"; * @param query * @param eq */ -export function fuzzyMatch(domain: ArrayLike, query: ArrayLike, eq: Predicate2 = equiv) { +export const fuzzyMatch = ( + domain: ArrayLike, + query: ArrayLike, + eq: Predicate2 = equiv +) => { const nd = domain.length; const nq = query.length; if (nq > nd) { @@ -35,4 +39,4 @@ export function fuzzyMatch(domain: ArrayLike, query: ArrayLike, eq: Pre return false; } return true; -} +}; diff --git a/packages/transducers/src/func/identity.ts b/packages/transducers/src/func/identity.ts index 2eae1585ce..74efbc8cf1 100644 --- a/packages/transducers/src/func/identity.ts +++ b/packages/transducers/src/func/identity.ts @@ -1 +1 @@ -export function identity(x: T) { return x; } +export const identity = (x: T) => x; diff --git a/packages/transducers/src/func/key-selector.ts b/packages/transducers/src/func/key-selector.ts index e7720fa7ff..f9f99792d5 100644 --- a/packages/transducers/src/func/key-selector.ts +++ b/packages/transducers/src/func/key-selector.ts @@ -1,5 +1,5 @@ import { renamer } from "./renamer"; -export function keySelector(keys: PropertyKey[]) { - return renamer(keys.reduce((acc, x) => (acc[x] = x, acc), {})); -} +export const keySelector = + (keys: PropertyKey[]) => + renamer(keys.reduce((acc, x) => (acc[x] = x, acc), {})); diff --git a/packages/transducers/src/func/lookup.ts b/packages/transducers/src/func/lookup.ts index 9adbd24da2..dd6dec1eda 100644 --- a/packages/transducers/src/func/lookup.ts +++ b/packages/transducers/src/func/lookup.ts @@ -9,9 +9,8 @@ * * @param src source data */ -export function lookup1d(src: T[]) { - return (i: number) => src[i]; -} +export const lookup1d = + (src: T[]) => (i: number) => src[i]; /** * Returns function accepting a single `[x, y]` index tuple, @@ -28,9 +27,9 @@ export function lookup1d(src: T[]) { * @param src source data * @param width number of items along X (columns) */ -export function lookup2d(src: T[], width: number) { - return (i: number[]) => src[i[0] + i[1] * width]; -} +export const lookup2d = + (src: T[], width: number) => + (i: number[]) => src[i[0] + i[1] * width]; /** * Same as `lookup2d()`, but for 3D data. The index ordering of the @@ -41,7 +40,8 @@ export function lookup2d(src: T[], width: number) { * @param width number of items along X (columns) * @param height number of items along Y (rows) */ -export function lookup3d(src: T[], width: number, height: number) { - const stridez = width * height; - return (i: number[]) => src[i[0] + i[1] * width + i[2] * stridez]; -} +export const lookup3d = + (src: T[], width: number, height: number) => { + const stridez = width * height; + return (i: number[]) => src[i[0] + i[1] * width + i[2] * stridez]; + }; diff --git a/packages/transducers/src/func/peek.ts b/packages/transducers/src/func/peek.ts index bfae789cbb..f0c29728fe 100644 --- a/packages/transducers/src/func/peek.ts +++ b/packages/transducers/src/func/peek.ts @@ -3,6 +3,5 @@ * * @param x */ -export function peek(x: ArrayLike) { - return x[x.length - 1]; -} +export const peek = + (x: ArrayLike) => x[x.length - 1]; diff --git a/packages/transducers/src/func/random-id.ts b/packages/transducers/src/func/random-id.ts index 3aff55d031..f4901cbb38 100644 --- a/packages/transducers/src/func/random-id.ts +++ b/packages/transducers/src/func/random-id.ts @@ -18,5 +18,6 @@ import { take } from "../xform/take"; * @param prefix * @param syms */ -export const randomID = (len = 4, prefix = "", syms = "abcdefghijklmnopqrstuvwxyz") => - [prefix, ...take(len, choices(syms))].join(""); +export const randomID = + (len = 4, prefix = "", syms = "abcdefghijklmnopqrstuvwxyz") => + [prefix, ...take(len, choices(syms))].join(""); diff --git a/packages/transducers/src/func/renamer.ts b/packages/transducers/src/func/renamer.ts index ed30ac4126..51f352aca4 100644 --- a/packages/transducers/src/func/renamer.ts +++ b/packages/transducers/src/func/renamer.ts @@ -1,42 +1,43 @@ import { IObjectOf } from "@thi.ng/api/api"; -export function renamer(kmap: IObjectOf) { - const ks = Object.keys(kmap); - const [a2, b2, c2] = ks; - const [a1, b1, c1] = ks.map((k) => kmap[k]); - switch (ks.length) { - case 3: - return (x) => { - const res: any = {}; - let v; - v = x[c1], v !== undefined && (res[c2] = v); - v = x[b1], v !== undefined && (res[b2] = v); - v = x[a1], v !== undefined && (res[a2] = v); - return res; - }; - case 2: - return (x) => { - const res: any = {}; - let v; - v = x[b1], v !== undefined && (res[b2] = v); - v = x[a1], v !== undefined && (res[a2] = v); - return res; - }; - case 1: - return (x) => { - const res: any = {}; - let v = x[a1]; - v !== undefined && (res[a2] = v); - return res; - }; - default: - return (x) => { - let k, v; - const res: any = {}; - for (let i = ks.length - 1; i >= 0; i--) { - k = ks[i], v = x[kmap[k]], v !== undefined && (res[k] = v); - } - return res; - }; - } -} +export const renamer = + (kmap: IObjectOf) => { + const ks = Object.keys(kmap); + const [a2, b2, c2] = ks; + const [a1, b1, c1] = ks.map((k) => kmap[k]); + switch (ks.length) { + case 3: + return (x) => { + const res: any = {}; + let v; + v = x[c1], v !== undefined && (res[c2] = v); + v = x[b1], v !== undefined && (res[b2] = v); + v = x[a1], v !== undefined && (res[a2] = v); + return res; + }; + case 2: + return (x) => { + const res: any = {}; + let v; + v = x[b1], v !== undefined && (res[b2] = v); + v = x[a1], v !== undefined && (res[a2] = v); + return res; + }; + case 1: + return (x) => { + const res: any = {}; + let v = x[a1]; + v !== undefined && (res[a2] = v); + return res; + }; + default: + return (x) => { + let k, v; + const res: any = {}; + for (let i = ks.length - 1; i >= 0; i--) { + k = ks[i], v = x[kmap[k]], v !== undefined && (res[k] = v); + } + return res; + }; + } + }; diff --git a/packages/transducers/src/func/shuffle.ts b/packages/transducers/src/func/shuffle.ts index 0d99287d35..9a3b355215 100644 --- a/packages/transducers/src/func/shuffle.ts +++ b/packages/transducers/src/func/shuffle.ts @@ -1,11 +1,12 @@ -export function shuffleN(buf: any[], n: number) { - const l = buf.length; - n = n < l ? n : l; - while (--n >= 0) { - const a = (Math.random() * l) | 0; - const b = (Math.random() * l) | 0; - const t = buf[a]; - buf[a] = buf[b]; - buf[b] = t; - } -} +export const shuffleN = + (buf: any[], n: number) => { + const l = buf.length; + n = n < l ? n : l; + while (--n >= 0) { + const a = (Math.random() * l) | 0; + const b = (Math.random() * l) | 0; + const t = buf[a]; + buf[a] = buf[b]; + buf[b] = t; + } + }; diff --git a/packages/transducers/src/func/swizzler.ts b/packages/transducers/src/func/swizzler.ts index 95ca29ebc2..5c368006eb 100644 --- a/packages/transducers/src/func/swizzler.ts +++ b/packages/transducers/src/func/swizzler.ts @@ -20,34 +20,35 @@ * * @param order indices */ -export function swizzler(order: string | PropertyKey[]): (x: T) => any[] { - const [a, b, c, d, e, f, g, h] = order; - switch (order.length) { - case 0: - return () => []; - case 1: - return (x) => [x[a]]; - case 2: - return (x) => [x[a], x[b]]; - case 3: - return (x) => [x[a], x[b], x[c]]; - case 4: - return (x) => [x[a], x[b], x[c], x[d]]; - case 5: - return (x) => [x[a], x[b], x[c], x[d], x[e]]; - case 6: - return (x) => [x[a], x[b], x[c], x[d], x[e], x[f]]; - case 7: - return (x) => [x[a], x[b], x[c], x[d], x[e], x[f], x[g]]; - case 8: - return (x) => [x[a], x[b], x[c], x[d], x[e], x[f], x[g], x[h]]; - default: - return (x) => { - const res = []; - for (let i = order.length - 1; i >= 0; i--) { - res[i] = x[order[i]]; - } - return res; - }; - } -} \ No newline at end of file +export const swizzler = + (order: string | PropertyKey[]): (x: T) => any[] => { + const [a, b, c, d, e, f, g, h] = order; + switch (order.length) { + case 0: + return () => []; + case 1: + return (x) => [x[a]]; + case 2: + return (x) => [x[a], x[b]]; + case 3: + return (x) => [x[a], x[b], x[c]]; + case 4: + return (x) => [x[a], x[b], x[c], x[d]]; + case 5: + return (x) => [x[a], x[b], x[c], x[d], x[e]]; + case 6: + return (x) => [x[a], x[b], x[c], x[d], x[e], x[f]]; + case 7: + return (x) => [x[a], x[b], x[c], x[d], x[e], x[f], x[g]]; + case 8: + return (x) => [x[a], x[b], x[c], x[d], x[e], x[f], x[g], x[h]]; + default: + return (x) => { + const res = []; + for (let i = order.length - 1; i >= 0; i--) { + res[i] = x[order[i]]; + } + return res; + }; + } + }; diff --git a/packages/transducers/src/func/weighted-random.ts b/packages/transducers/src/func/weighted-random.ts index 9f2dfab42a..22cc7dcc26 100644 --- a/packages/transducers/src/func/weighted-random.ts +++ b/packages/transducers/src/func/weighted-random.ts @@ -10,7 +10,10 @@ import { tuples } from "../iter/tuples"; * @param choices * @param weights */ -export function weightedRandom(choices: ArrayLike & Iterable, weights?: ArrayLike & Iterable) { +export const weightedRandom = ( + choices: ArrayLike & Iterable, + weights?: ArrayLike & Iterable +) => { const n = choices.length; const opts = [...tuples(choices, weights || repeat(1))].sort((a, b) => b[1] - a[1]); let total = 0, i, r, sum; @@ -27,4 +30,4 @@ export function weightedRandom(choices: ArrayLike & Iterable, weights?: } } }; -} \ No newline at end of file +}; diff --git a/packages/transducers/src/iter/choices.ts b/packages/transducers/src/iter/choices.ts index 9c3b9e316d..8abd5b830a 100644 --- a/packages/transducers/src/iter/choices.ts +++ b/packages/transducers/src/iter/choices.ts @@ -16,10 +16,12 @@ import { repeatedly } from "./repeatedly"; * @param choices * @param weights */ -export function choices(choices: ArrayLike & Iterable, weights?: ArrayLike & Iterable) { - return repeatedly( +export const choices = ( + choices: ArrayLike & Iterable, + weights?: ArrayLike & Iterable +) => + repeatedly( weights ? weightedRandom(choices, weights) : () => choices[(Math.random() * choices.length) | 0] ); -} diff --git a/packages/transducers/src/iter/permutations.ts b/packages/transducers/src/iter/permutations.ts index c0375cae68..71377ebace 100644 --- a/packages/transducers/src/iter/permutations.ts +++ b/packages/transducers/src/iter/permutations.ts @@ -73,14 +73,15 @@ export function* permutations(...src: any[]) { * @param m * @param offsets */ -export function permutationsN(n: number, m = n, offsets?: number[]): IterableIterator { - if (offsets && offsets.length < n) { - illegalArgs(`insufficient offsets, got ${offsets.length}, needed ${n}`); - } - const seqs = []; - while (--n >= 0) { - const o = offsets ? offsets[n] : 0; - seqs[n] = range(o, o + m); - } - return permutations.apply(null, seqs); -} +export const permutationsN = + (n: number, m = n, offsets?: number[]): IterableIterator => { + if (offsets && offsets.length < n) { + illegalArgs(`insufficient offsets, got ${offsets.length}, needed ${n}`); + } + const seqs = []; + while (--n >= 0) { + const o = offsets ? offsets[n] : 0; + seqs[n] = range(o, o + m); + } + return permutations.apply(null, seqs); + }; diff --git a/packages/transducers/src/iter/wrap-both.ts b/packages/transducers/src/iter/wrap-both.ts index 791922d08b..84b9068c05 100644 --- a/packages/transducers/src/iter/wrap-both.ts +++ b/packages/transducers/src/iter/wrap-both.ts @@ -7,6 +7,5 @@ import { wrap } from "./wrap"; * @param src * @param n */ -export function wrapBoth(src: Iterable, n = 1) { - return wrap(src, n); -} +export const wrapBoth = + (src: Iterable, n = 1) => wrap(src, n); diff --git a/packages/transducers/src/iter/wrap-left.ts b/packages/transducers/src/iter/wrap-left.ts index 17c3f027b9..fbb738b427 100644 --- a/packages/transducers/src/iter/wrap-left.ts +++ b/packages/transducers/src/iter/wrap-left.ts @@ -7,6 +7,5 @@ import { wrap } from "./wrap"; * @param src * @param n */ -export function wrapLeft(src: Iterable, n = 1) { - return wrap(src, n, true, false); -} +export const wrapLeft = + (src: Iterable, n = 1) => wrap(src, n, true, false); diff --git a/packages/transducers/src/iter/wrap-right.ts b/packages/transducers/src/iter/wrap-right.ts index d7a0ba8cdb..6e63a5f8fc 100644 --- a/packages/transducers/src/iter/wrap-right.ts +++ b/packages/transducers/src/iter/wrap-right.ts @@ -7,6 +7,5 @@ import { wrap } from "./wrap"; * @param src * @param n */ -export function wrapRight(src: Iterable, n = 1) { - return wrap(src, n, false, true); -} +export const wrapRight = + (src: Iterable, n = 1) => wrap(src, n, false, true); diff --git a/packages/transducers/src/iterator.ts b/packages/transducers/src/iterator.ts index ef8c6f6775..fc161055ad 100644 --- a/packages/transducers/src/iterator.ts +++ b/packages/transducers/src/iterator.ts @@ -64,7 +64,11 @@ export function* iterator1(xform: Transducer, xs: Iterable): Iter * @param args * @param impl */ -export const $iter = (xform: (...xs: any[]) => Transducer, args: any[], impl = iterator1) => { +export const $iter = ( + xform: (...xs: any[]) => Transducer, + args: any[], + impl = iterator1 +) => { const n = args.length - 1; return isIterable(args[n]) ? args.length > 1 ? diff --git a/packages/transducers/src/reduce.ts b/packages/transducers/src/reduce.ts index fc17cfb426..c2d01b0da6 100644 --- a/packages/transducers/src/reduce.ts +++ b/packages/transducers/src/reduce.ts @@ -58,15 +58,16 @@ export function reduce(...args: any[]): A { * @param init init step of reducer * @param rfn reduction step of reducer */ -export function reducer(init: () => A, rfn: (acc: A, x: B) => A | Reduced) { - return >[init, (acc) => acc, rfn]; -} +export const reducer = + (init: () => A, rfn: (acc: A, x: B) => A | Reduced) => + >[init, (acc) => acc, rfn]; -export const $$reduce = (rfn: (...args: any[]) => Reducer, args: any[]) => { - const n = args.length - 1; - return isIterable(args[n]) ? - args.length > 1 ? - reduce(rfn.apply(null, args.slice(0, n)), args[n]) : - reduce(rfn(), args[0]) : - undefined; -}; +export const $$reduce = + (rfn: (...args: any[]) => Reducer, args: any[]) => { + const n = args.length - 1; + return isIterable(args[n]) ? + args.length > 1 ? + reduce(rfn.apply(null, args.slice(0, n)), args[n]) : + reduce(rfn(), args[0]) : + undefined; + }; diff --git a/packages/transducers/src/reduced.ts b/packages/transducers/src/reduced.ts index 5e48322ba3..7e9f40afb9 100644 --- a/packages/transducers/src/reduced.ts +++ b/packages/transducers/src/reduced.ts @@ -14,18 +14,14 @@ export class Reduced implements } } -export function reduced(x: any): any { - return new Reduced(x); -} +export const reduced = + (x: any): any => new Reduced(x); -export function isReduced(x: any): x is Reduced { - return x instanceof Reduced; -} +export const isReduced = + (x: any): x is Reduced => x instanceof Reduced; -export function ensureReduced(x: any) { - return x instanceof Reduced ? x : new Reduced(x); -} +export const ensureReduced = + (x: any) => x instanceof Reduced ? x : new Reduced(x); -export function unreduced(x: any) { - return x instanceof Reduced ? x.deref() : x; -} +export const unreduced = + (x: any) => x instanceof Reduced ? x.deref() : x; diff --git a/packages/transducers/src/rfn/group-binary.ts b/packages/transducers/src/rfn/group-binary.ts index 4d033577b6..e1bcc28a32 100644 --- a/packages/transducers/src/rfn/group-binary.ts +++ b/packages/transducers/src/rfn/group-binary.ts @@ -4,9 +4,13 @@ import { Reducer } from "../api"; import { groupByObj } from "./group-by-obj"; import { push } from "./push"; -function branchPred(key: (x: T) => number, b: number, l: PropertyKey, r: PropertyKey) { - return (x: T) => key(x) & b ? r : l; -} +const branchPred = ( + key: (x: T) => number, + b: number, + l: PropertyKey, + r: PropertyKey +) => + (x: T) => key(x) & b ? r : l; /** * Creates a bottom-up, unbalanced binary tree of desired depth and @@ -79,13 +83,14 @@ function branchPred(key: (x: T) => number, b: number, l: PropertyKey, r: Prop * @param left key for storing left branches (e.g. `0` for arrays) * @param right key for storing right branches (e.g. `1` for arrays) */ -export function groupBinary( +export const groupBinary = ( bits: number, key: (x: T) => number, branch?: () => IObjectOf, leaf?: Reducer, left: PropertyKey = "l", - right: PropertyKey = "r"): Reducer { + right: PropertyKey = "r" +): Reducer => { const init = branch || (() => ({})); let rfn: Reducer = groupByObj({ @@ -96,4 +101,4 @@ export function groupBinary( rfn = groupByObj({ key: branchPred(key, i, left, right), group: [init, rfn[1], rfn[2]] }); } return [init, rfn[1], rfn[2]]; -} +}; diff --git a/packages/transducers/src/rfn/push-copy.ts b/packages/transducers/src/rfn/push-copy.ts index d3aece8533..ecf15165cb 100644 --- a/packages/transducers/src/rfn/push-copy.ts +++ b/packages/transducers/src/rfn/push-copy.ts @@ -1,6 +1,6 @@ import { Reducer } from "../api"; import { reducer } from "../reduce"; -export function pushCopy(): Reducer { - return reducer(() => [], (acc, x) => ((acc = acc.slice()).push(x), acc)); -} +export const pushCopy = + (): Reducer => + reducer(() => [], (acc, x) => ((acc = acc.slice()).push(x), acc)); diff --git a/packages/transducers/src/step.ts b/packages/transducers/src/step.ts index c431a73007..eda33f1227 100644 --- a/packages/transducers/src/step.ts +++ b/packages/transducers/src/step.ts @@ -36,21 +36,22 @@ import { push } from "./rfn/push"; * * @param tx */ -export function step(tx: Transducer): (x: A) => B | B[] { - const [_, complete, reduce] = tx(push()); _; - let done = false; - return (x: A) => { - if (!done) { - let acc = reduce([], x); - done = isReduced(acc); - if (done) { - acc = complete(acc.deref()); +export const step = + (tx: Transducer): (x: A) => B | B[] => { + const [_, complete, reduce] = tx(push()); _; + let done = false; + return (x: A) => { + if (!done) { + let acc = reduce([], x); + done = isReduced(acc); + if (done) { + acc = complete(acc.deref()); + } + return acc.length === 1 ? + acc[0] : + acc.length > 0 ? + acc : + undefined; } - return acc.length === 1 ? - acc[0] : - acc.length > 0 ? - acc : - undefined; - } + }; }; -} diff --git a/packages/transducers/src/xform/cat.ts b/packages/transducers/src/xform/cat.ts index 60c2303619..225bfa82c6 100644 --- a/packages/transducers/src/xform/cat.ts +++ b/packages/transducers/src/xform/cat.ts @@ -16,22 +16,22 @@ import { isReduced, unreduced, ensureReduced } from "../reduced"; * * @see thi.ng/transducers/xform/mapcat */ -export function cat(): Transducer, T> { - return (rfn: Reducer) => { - const r = rfn[2]; - return compR(rfn, - (acc, x: Iterable) => { - if (x) { - for (let y of unreduced(x)) { - acc = r(acc, y); - if (isReduced(acc)) { - break; +export const cat = + (): Transducer, T> => + (rfn: Reducer) => { + const r = rfn[2]; + return compR(rfn, + (acc, x: Iterable) => { + if (x) { + for (let y of unreduced(x)) { + acc = r(acc, y); + if (isReduced(acc)) { + break; + } } } - } - return isReduced(x) ? - ensureReduced(acc) : - acc; - }); - }; -} + return isReduced(x) ? + ensureReduced(acc) : + acc; + }); + }; diff --git a/packages/transducers/src/xform/delayed.ts b/packages/transducers/src/xform/delayed.ts index b9c3c44967..5cadd02718 100644 --- a/packages/transducers/src/xform/delayed.ts +++ b/packages/transducers/src/xform/delayed.ts @@ -11,6 +11,6 @@ import { map } from "./map"; * * @param t */ -export function delayed(t: number): Transducer> { - return map((x) => delay(x, t)); -} +export const delayed = + (t: number): Transducer> => + map((x) => delay(x, t)); diff --git a/packages/transducers/src/xform/noop.ts b/packages/transducers/src/xform/noop.ts index a825f0a88c..188a85c7f8 100644 --- a/packages/transducers/src/xform/noop.ts +++ b/packages/transducers/src/xform/noop.ts @@ -5,6 +5,6 @@ import { Transducer } from "../api"; * `map(identity)`, but faster. Useful for testing and / or to keep * existing values in a `multiplex()` tuple lane. */ -export function noop(): Transducer { - return (rfn) => rfn; -} +export const noop = + (): Transducer => + (rfn) => rfn; diff --git a/packages/transducers/src/xform/side-effect.ts b/packages/transducers/src/xform/side-effect.ts index 8434117d0a..eafefbcbf5 100644 --- a/packages/transducers/src/xform/side-effect.ts +++ b/packages/transducers/src/xform/side-effect.ts @@ -8,6 +8,6 @@ import { map } from "./map"; * * @param fn side effect */ -export function sideEffect(fn: (x: T) => void): Transducer { - return map((x) => (fn(x), x)); -} +export const sideEffect = + (fn: (x: T) => void): Transducer => + map((x) => (fn(x), x)); diff --git a/packages/transducers/src/xform/trace.ts b/packages/transducers/src/xform/trace.ts index 7f6abe084f..fa118f750a 100644 --- a/packages/transducers/src/xform/trace.ts +++ b/packages/transducers/src/xform/trace.ts @@ -1,6 +1,6 @@ import { Transducer } from "../api"; import { sideEffect } from "./side-effect"; -export function trace(prefix = ""): Transducer { - return sideEffect((x) => console.log(prefix, x)); -} +export const trace = + (prefix = ""): Transducer => + sideEffect((x) => console.log(prefix, x)); From 5d5302866bdcf62fc5b85fd7c5f33cd8bd34e29c Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 06:23:37 +0000 Subject: [PATCH 201/333] refactor(csp): use arrow fns --- packages/csp/src/utils/shuffle.ts | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/csp/src/utils/shuffle.ts b/packages/csp/src/utils/shuffle.ts index 5c23da9c24..14ff0f63fd 100644 --- a/packages/csp/src/utils/shuffle.ts +++ b/packages/csp/src/utils/shuffle.ts @@ -1,13 +1,14 @@ -export function shuffle(items: T[]) { - let n = items.length; - if (n > 1) { - while (n > 0) { - const i = (Math.random() * n) | 0; - n--; - const t = items[i]; - items[i] = items[n]; - items[n] = t; +export const shuffle = + (items: T[]) => { + let n = items.length; + if (n > 1) { + while (n > 0) { + const i = (Math.random() * n) | 0; + n--; + const t = items[i]; + items[i] = items[n]; + items[n] = t; + } } - } - return items; -} + return items; + }; From 48670f58be5b7f3f0572dd4062a23005d707a0c7 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 06:23:48 +0000 Subject: [PATCH 202/333] refactor(memoize): use arrow fns --- packages/memoize/src/defonce.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/memoize/src/defonce.ts b/packages/memoize/src/defonce.ts index 3546379952..9af67bbe56 100644 --- a/packages/memoize/src/defonce.ts +++ b/packages/memoize/src/defonce.ts @@ -16,8 +16,8 @@ const cache: any = {}; * @param id * @param factory */ -export function defonce(id: string, factory: Fn0): T { - return cache.hasOwnProperty(id) ? - cache[id] : - (cache[id] = factory()); -} +export const defonce = + (id: string, factory: Fn0): T => + cache.hasOwnProperty(id) ? + cache[id] : + (cache[id] = factory()); From e103d740f061e6b85f9f3126401dff349e0b2b19 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 06:24:13 +0000 Subject: [PATCH 203/333] refactor(transducers-fsm): use arrow fns --- packages/transducers-fsm/src/index.ts | 42 +++++++++++++-------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/packages/transducers-fsm/src/index.ts b/packages/transducers-fsm/src/index.ts index 08cef2db2d..b11e2b44c9 100644 --- a/packages/transducers-fsm/src/index.ts +++ b/packages/transducers-fsm/src/index.ts @@ -92,26 +92,26 @@ export interface FSMOpts { * * @param opts */ -export function fsm(opts: FSMOpts): Transducer { - return comp((rfn: Reducer) => { - const states = opts.states; - const state = opts.init(); - const r = rfn[2]; - return compR(rfn, - (acc, x) => { - const res = states[state.state](state, x); - if (res != null) { - for (let i = 0, n = (res).length; i < n; i++) { - acc = r(acc, res[i]); - if (isReduced(acc)) { - break; +export const fsm = + (opts: FSMOpts): Transducer => + comp((rfn: Reducer) => { + const states = opts.states; + const state = opts.init(); + const r = rfn[2]; + return compR(rfn, + (acc, x) => { + const res = states[state.state](state, x); + if (res != null) { + for (let i = 0, n = (res).length; i < n; i++) { + acc = r(acc, res[i]); + if (isReduced(acc)) { + break; + } } } - } - if (state.state === opts.terminate) { - return ensureReduced(acc); - } - return acc; - }); - }); -} + if (state.state === opts.terminate) { + return ensureReduced(acc); + } + return acc; + }); + }); From ce4b52830cb3a897f0f43da7e9fca5a5c4072b41 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 06:24:28 +0000 Subject: [PATCH 204/333] refactor(transducers-hdom): use arrow fns --- packages/transducers-hdom/src/index.ts | 49 ++++++++++++++------------ 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/packages/transducers-hdom/src/index.ts b/packages/transducers-hdom/src/index.ts index a7fcbb037d..58a1c03194 100644 --- a/packages/transducers-hdom/src/index.ts +++ b/packages/transducers-hdom/src/index.ts @@ -3,7 +3,6 @@ import { DEFAULT_IMPL } from "@thi.ng/hdom/default"; import { resolveRoot } from "@thi.ng/hdom/utils"; import { derefContext } from "@thi.ng/hiccup/deref"; import { Transducer } from "@thi.ng/transducers/api"; -import { reducer } from "@thi.ng/transducers/reduce"; import { scan } from "@thi.ng/transducers/xform/scan"; /** @@ -40,27 +39,31 @@ import { scan } from "@thi.ng/transducers/xform/scan"; * * @param opts hdom options */ -export const updateDOM = - (opts: Partial = {}, impl: HDOMImplementation = DEFAULT_IMPL): Transducer => { - const _opts = { root: "app", ...opts }; - const root = resolveRoot(_opts.root, impl); - return scan( - reducer( - () => [], - (prev, curr) => { - _opts.ctx = derefContext(opts.ctx, _opts.autoDerefKeys); - curr = impl.normalizeTree(_opts, curr); - if (curr != null) { - if (_opts.hydrate) { - impl.hydrateTree(_opts, root, curr); - _opts.hydrate = false; - } else { - impl.diffTree(_opts, root, prev, curr, 0); - } - return curr; +export const updateDOM = ( + opts: Partial = {}, + impl: HDOMImplementation = DEFAULT_IMPL +): Transducer => { + + const _opts = { root: "app", ...opts }; + const root = resolveRoot(_opts.root, impl); + return scan( + [ + () => [], + (acc) => acc, + (prev, curr) => { + _opts.ctx = derefContext(opts.ctx, _opts.autoDerefKeys); + curr = impl.normalizeTree(_opts, curr); + if (curr != null) { + if (_opts.hydrate) { + impl.hydrateTree(_opts, root, curr); + _opts.hydrate = false; + } else { + impl.diffTree(_opts, root, prev, curr, 0); } - return prev; + return curr; } - ) - ); - }; + return prev; + } + ] + ); +}; From a313d8309849b1af33add8552d0dc9745b9752f4 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 14:44:53 +0000 Subject: [PATCH 205/333] build: add/update dev deps, update build scripts in all packages --- lerna.json | 2 +- package.json | 11 +- packages/api/package.json | 8 +- packages/associative/package.json | 12 +- packages/atom/package.json | 8 +- packages/bench/package.json | 12 +- packages/binary/package.json | 12 +- packages/bitstream/package.json | 8 +- packages/cache/package.json | 12 +- packages/checks/package.json | 8 +- packages/compare/package.json | 12 +- packages/compose/package.json | 12 +- packages/csp/package.json | 8 +- packages/dcons/package.json | 8 +- packages/defmulti/package.json | 12 +- packages/dgraph/package.json | 12 +- packages/diff/package.json | 12 +- packages/dlogic/package.json | 12 +- packages/dot/package.json | 12 +- packages/dsp/package.json | 12 +- packages/equiv/package.json | 12 +- packages/errors/package.json | 12 +- packages/fsm/package.json | 12 +- packages/geom-accel/package.json | 12 +- packages/geom/package.json | 12 +- packages/hdom-canvas/package.json | 12 +- packages/hdom-components/package.json | 12 +- packages/hdom-mock/package.json | 12 +- packages/hdom/package.json | 8 +- packages/heaps/package.json | 12 +- packages/hiccup-carbon-icons/package.json | 12 +- packages/hiccup-css/package.json | 8 +- packages/hiccup-markdown/package.json | 12 +- packages/hiccup-svg/package.json | 12 +- packages/hiccup/package.json | 8 +- packages/iges/package.json | 12 +- packages/interceptors/package.json | 12 +- packages/intervals/package.json | 12 +- packages/iterators/package.json | 8 +- packages/malloc/package.json | 12 +- packages/math/package.json | 12 +- packages/memoize/package.json | 12 +- packages/morton/package.json | 12 +- packages/paths/package.json | 12 +- packages/pointfree-lang/package.json | 8 +- packages/pointfree/package.json | 12 +- packages/random/package.json | 12 +- packages/range-coder/package.json | 8 +- packages/resolve-map/package.json | 12 +- packages/rle-pack/package.json | 8 +- packages/router/package.json | 12 +- packages/rstream-csp/package.json | 8 +- packages/rstream-dot/package.json | 12 +- packages/rstream-gestures/package.json | 12 +- packages/rstream-graph/package.json | 12 +- packages/rstream-log/package.json | 8 +- packages/rstream-query/package.json | 12 +- packages/rstream/package.json | 8 +- packages/sax/package.json | 12 +- packages/strings/package.json | 12 +- packages/transducers-fsm/package.json | 12 +- packages/transducers-hdom/package.json | 12 +- packages/transducers-stats/package.json | 12 +- packages/transducers/package.json | 8 +- packages/unionstruct/package.json | 8 +- packages/vectors/package.json | 12 +- yarn.lock | 591 ++++++++++++---------- 67 files changed, 684 insertions(+), 616 deletions(-) diff --git a/lerna.json b/lerna.json index 1d7b66a51d..fb17f8b5e5 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "lerna": "3.3.0", + "lerna": "3.8.5", "packages": [ "packages/*" ], diff --git a/package.json b/package.json index 2f033a9c96..139fc9b44a 100644 --- a/package.json +++ b/package.json @@ -5,12 +5,13 @@ ], "devDependencies": { "benchmark": "^2.1.4", - "lerna": "^3.6.0", + "lerna": "^3.8.5", "mocha": "^5.2.0", "nyc": "^13.1.0", - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", - "tslint": "^5.11.0", + "parcel-bundler": "^1.11.0", + "rimraf": "^2.6.3", + "terser": "^3.14.1", + "tslint": "^5.12.0", "typescript": "^3.2.2" }, "scripts": { @@ -23,4 +24,4 @@ "pub": "lerna publish --registry https://registry.npmjs.org/ && yarn doc && scripts/upload-docs", "test": "yarn build && lerna run test" } -} +} \ No newline at end of file diff --git a/packages/api/package.json b/packages/api/package.json index aa2c8f97a0..e4585050a9 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -13,18 +13,18 @@ "license": "Apache-2.0", "scripts": { "build": "yarn clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc decorators mixins", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc decorators mixins", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -43,4 +43,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/associative/package.json b/packages/associative/package.json index 4239bf72aa..72fa50cebc 100644 --- a/packages/associative/package.json +++ b/packages/associative/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -54,4 +54,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/atom/package.json b/packages/atom/package.json index 8a45e08b01..e55b7e9662 100644 --- a/packages/atom/package.json +++ b/packages/atom/package.json @@ -13,18 +13,18 @@ "license": "Apache-2.0", "scripts": { "build": "yarn clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -46,4 +46,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/bench/package.json b/packages/bench/package.json index a5d1656f79..937ddf6514 100644 --- a/packages/bench/package.json +++ b/packages/bench/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "keywords": [ @@ -36,4 +36,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/binary/package.json b/packages/binary/package.json index 36f80224af..a0b58f809a 100644 --- a/packages/binary/package.json +++ b/packages/binary/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "keywords": [ @@ -43,4 +43,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/bitstream/package.json b/packages/bitstream/package.json index 79c73888fe..2477e45577 100644 --- a/packages/bitstream/package.json +++ b/packages/bitstream/package.json @@ -13,11 +13,11 @@ "license": "Apache-2.0", "scripts": { "build": "yarn clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "dependencies": { "@thi.ng/errors": "^0.1.12" @@ -27,7 +27,7 @@ "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "keywords": [ @@ -42,4 +42,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/cache/package.json b/packages/cache/package.json index 6ce4a1db97..9195bf1efe 100644 --- a/packages/cache/package.json +++ b/packages/cache/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -46,4 +46,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/checks/package.json b/packages/checks/package.json index a9d6dd6968..48aecd8bbb 100644 --- a/packages/checks/package.json +++ b/packages/checks/package.json @@ -13,18 +13,18 @@ "license": "Apache-2.0", "scripts": { "build": "yarn clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "keywords": [ @@ -40,4 +40,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/compare/package.json b/packages/compare/package.json index 07068a6585..a923750465 100644 --- a/packages/compare/package.json +++ b/packages/compare/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "keywords": [ @@ -35,4 +35,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/compose/package.json b/packages/compose/package.json index d69c5224a6..42320ef003 100644 --- a/packages/compose/package.json +++ b/packages/compose/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -40,4 +40,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/csp/package.json b/packages/csp/package.json index ab83c33fad..cac40b2aac 100644 --- a/packages/csp/package.json +++ b/packages/csp/package.json @@ -13,11 +13,11 @@ "license": "Apache-2.0", "scripts": { "build": "yarn clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc utils", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc utils", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/index.js", + "test": "rimraf build && tsc -p test && nyc mocha build/test/index.js", "testasync": "tsc -p test && node build/test/async.js", "testfile": "tsc -p test && node build/test/file.js", "testgraph": "tsc -p test && node build/test/graph.js", @@ -28,7 +28,7 @@ "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -54,4 +54,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/dcons/package.json b/packages/dcons/package.json index 08bde1a5eb..3f0c731a4a 100644 --- a/packages/dcons/package.json +++ b/packages/dcons/package.json @@ -13,18 +13,18 @@ "license": "Apache-2.0", "scripts": { "build": "yarn clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -49,4 +49,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/defmulti/package.json b/packages/defmulti/package.json index 67882086ac..af2fe4b369 100644 --- a/packages/defmulti/package.json +++ b/packages/defmulti/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -38,4 +38,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/dgraph/package.json b/packages/dgraph/package.json index 134a9a97fb..b7b121df78 100644 --- a/packages/dgraph/package.json +++ b/packages/dgraph/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -45,4 +45,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/diff/package.json b/packages/diff/package.json index b4628ad9cd..05f660152c 100644 --- a/packages/diff/package.json +++ b/packages/diff/package.json @@ -12,17 +12,17 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -40,4 +40,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/dlogic/package.json b/packages/dlogic/package.json index b6fc9279bd..626923e384 100644 --- a/packages/dlogic/package.json +++ b/packages/dlogic/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "keywords": [ @@ -40,4 +40,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/dot/package.json b/packages/dot/package.json index 5068c62524..384f93f9ca 100644 --- a/packages/dot/package.json +++ b/packages/dot/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -38,4 +38,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/dsp/package.json b/packages/dsp/package.json index 1c53004bf7..6bd4ff6ad9 100644 --- a/packages/dsp/package.json +++ b/packages/dsp/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -45,4 +45,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/equiv/package.json b/packages/equiv/package.json index 75288a604a..eab69efb7d 100644 --- a/packages/equiv/package.json +++ b/packages/equiv/package.json @@ -12,12 +12,12 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -25,7 +25,7 @@ "benchmark": "^2.1.4", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "keywords": [ @@ -37,4 +37,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/errors/package.json b/packages/errors/package.json index f4a0d0ab91..d0bd9f2fdb 100644 --- a/packages/errors/package.json +++ b/packages/errors/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "keywords": [ @@ -35,4 +35,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/fsm/package.json b/packages/fsm/package.json index 1889a22628..da80319859 100644 --- a/packages/fsm/package.json +++ b/packages/fsm/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -50,4 +50,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/geom-accel/package.json b/packages/geom-accel/package.json index e4f3f3aeb4..4c933a24b2 100644 --- a/packages/geom-accel/package.json +++ b/packages/geom-accel/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -46,4 +46,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/geom/package.json b/packages/geom/package.json index 91fc8bfb92..547bdedf79 100644 --- a/packages/geom/package.json +++ b/packages/geom/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc internal", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc internal", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -46,4 +46,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/hdom-canvas/package.json b/packages/hdom-canvas/package.json index 5fd0782d65..acc3c113d7 100644 --- a/packages/hdom-canvas/package.json +++ b/packages/hdom-canvas/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -47,4 +47,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/hdom-components/package.json b/packages/hdom-components/package.json index 448c4b3ab6..f625863697 100644 --- a/packages/hdom-components/package.json +++ b/packages/hdom-components/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -42,4 +42,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/hdom-mock/package.json b/packages/hdom-mock/package.json index 595762896a..4cae0a8bb4 100644 --- a/packages/hdom-mock/package.json +++ b/packages/hdom-mock/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -38,4 +38,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/hdom/package.json b/packages/hdom/package.json index 42ecb96614..7d0d2fc27d 100644 --- a/packages/hdom/package.json +++ b/packages/hdom/package.json @@ -13,11 +13,11 @@ "license": "Apache-2.0", "scripts": { "build": "yarn clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@thi.ng/atom": "^1.5.8", @@ -25,7 +25,7 @@ "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -50,4 +50,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/heaps/package.json b/packages/heaps/package.json index e01313a5a0..1f16da8306 100644 --- a/packages/heaps/package.json +++ b/packages/heaps/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -43,4 +43,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/hiccup-carbon-icons/package.json b/packages/hiccup-carbon-icons/package.json index 526910afb1..59b90d3fdc 100644 --- a/packages/hiccup-carbon-icons/package.json +++ b/packages/hiccup-carbon-icons/package.json @@ -12,12 +12,12 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@thi.ng/hiccup": "^2.7.2", @@ -25,7 +25,7 @@ "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "keywords": [ @@ -35,4 +35,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/hiccup-css/package.json b/packages/hiccup-css/package.json index 4beedffabe..ac4af4e875 100644 --- a/packages/hiccup-css/package.json +++ b/packages/hiccup-css/package.json @@ -13,18 +13,18 @@ "license": "Apache-2.0", "scripts": { "build": "yarn clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -50,4 +50,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/hiccup-markdown/package.json b/packages/hiccup-markdown/package.json index b0450088a2..13c044dd82 100644 --- a/packages/hiccup-markdown/package.json +++ b/packages/hiccup-markdown/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -51,4 +51,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/hiccup-svg/package.json b/packages/hiccup-svg/package.json index db8c978d28..6e35918f13 100644 --- a/packages/hiccup-svg/package.json +++ b/packages/hiccup-svg/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -43,4 +43,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/hiccup/package.json b/packages/hiccup/package.json index 9f8bfdc599..8c5b64ba68 100644 --- a/packages/hiccup/package.json +++ b/packages/hiccup/package.json @@ -13,11 +13,11 @@ "license": "Apache-2.0", "scripts": { "build": "yarn clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@thi.ng/atom": "^1.5.8", @@ -25,7 +25,7 @@ "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -49,4 +49,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/iges/package.json b/packages/iges/package.json index 527316b229..aa21eedbc4 100644 --- a/packages/iges/package.json +++ b/packages/iges/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -45,4 +45,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/interceptors/package.json b/packages/interceptors/package.json index afeb94fa89..1447b62f63 100644 --- a/packages/interceptors/package.json +++ b/packages/interceptors/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -41,4 +41,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/intervals/package.json b/packages/intervals/package.json index 23d375080a..0172b565e3 100644 --- a/packages/intervals/package.json +++ b/packages/intervals/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -46,4 +46,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/iterators/package.json b/packages/iterators/package.json index 4e03af5d71..f07d61f1b5 100644 --- a/packages/iterators/package.json +++ b/packages/iterators/package.json @@ -13,18 +13,18 @@ "license": "Apache-2.0", "scripts": { "build": "yarn clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -46,4 +46,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/malloc/package.json b/packages/malloc/package.json index f0c8bc4f21..3ea6a55f0d 100644 --- a/packages/malloc/package.json +++ b/packages/malloc/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -40,4 +40,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/math/package.json b/packages/math/package.json index e49132b2bf..ce3f6a78f6 100644 --- a/packages/math/package.json +++ b/packages/math/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "keywords": [ @@ -39,4 +39,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/memoize/package.json b/packages/memoize/package.json index d79213265a..16051bbd60 100644 --- a/packages/memoize/package.json +++ b/packages/memoize/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -40,4 +40,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/morton/package.json b/packages/morton/package.json index 61ce6211aa..2985274ac8 100644 --- a/packages/morton/package.json +++ b/packages/morton/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -44,4 +44,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/paths/package.json b/packages/paths/package.json index 8be8fa10e8..e613e1afd4 100644 --- a/packages/paths/package.json +++ b/packages/paths/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -47,4 +47,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/pointfree-lang/package.json b/packages/pointfree-lang/package.json index f6349f4718..978992ce77 100644 --- a/packages/pointfree-lang/package.json +++ b/packages/pointfree-lang/package.json @@ -13,20 +13,20 @@ "license": "Apache-2.0", "scripts": { "build": "yarn clean && tsc --declaration && yarn peg", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "peg": "pegjs -o parser.js src/grammar.pegjs", "pegtest": "pegjs -o build/src/parser.js src/grammar.pegjs", "pub": "yarn build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && yarn pegtest && nyc mocha build/test/*.js" + "test": "rimraf build && tsc -p test && yarn pegtest && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "pegjs": "^0.10.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -50,4 +50,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/pointfree/package.json b/packages/pointfree/package.json index 235e21c7ad..b386e0f8f1 100644 --- a/packages/pointfree/package.json +++ b/packages/pointfree/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -51,4 +51,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/random/package.json b/packages/random/package.json index 57c04c321c..7761a15324 100644 --- a/packages/random/package.json +++ b/packages/random/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -40,4 +40,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/range-coder/package.json b/packages/range-coder/package.json index 59216429c8..fe7fe12408 100644 --- a/packages/range-coder/package.json +++ b/packages/range-coder/package.json @@ -13,11 +13,11 @@ "license": "Apache-2.0", "scripts": { "build": "yarn clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@thi.ng/transducers": "^2.3.2", @@ -25,7 +25,7 @@ "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -42,4 +42,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/resolve-map/package.json b/packages/resolve-map/package.json index 76d4ad8207..72e8f8ef47 100644 --- a/packages/resolve-map/package.json +++ b/packages/resolve-map/package.json @@ -12,17 +12,17 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -42,4 +42,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/rle-pack/package.json b/packages/rle-pack/package.json index c9c4695a08..a6ad426339 100644 --- a/packages/rle-pack/package.json +++ b/packages/rle-pack/package.json @@ -13,11 +13,11 @@ "license": "Apache-2.0", "scripts": { "build": "yarn clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -25,7 +25,7 @@ "benchmark": "^2.1.4", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -43,4 +43,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/router/package.json b/packages/router/package.json index 52ca63dd08..39713d7e6f 100644 --- a/packages/router/package.json +++ b/packages/router/package.json @@ -12,18 +12,18 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -45,4 +45,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/rstream-csp/package.json b/packages/rstream-csp/package.json index 597657234c..e2dc43550f 100644 --- a/packages/rstream-csp/package.json +++ b/packages/rstream-csp/package.json @@ -13,18 +13,18 @@ "license": "Apache-2.0", "scripts": { "build": "yarn clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc from", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc from", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -42,4 +42,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/rstream-dot/package.json b/packages/rstream-dot/package.json index 98fec00007..746796a435 100644 --- a/packages/rstream-dot/package.json +++ b/packages/rstream-dot/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -45,4 +45,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/rstream-gestures/package.json b/packages/rstream-gestures/package.json index f33218615d..07c67dd4b4 100644 --- a/packages/rstream-gestures/package.json +++ b/packages/rstream-gestures/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -47,4 +47,4 @@ "access": "public" }, "gitHead": "673bf50ff571fc65bd984d1f83929bcc69a8b394" -} +} \ No newline at end of file diff --git a/packages/rstream-graph/package.json b/packages/rstream-graph/package.json index 194bffeb64..b769a30180 100644 --- a/packages/rstream-graph/package.json +++ b/packages/rstream-graph/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc nodes", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc nodes", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -48,4 +48,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/rstream-log/package.json b/packages/rstream-log/package.json index 08b7de3944..ea40694367 100644 --- a/packages/rstream-log/package.json +++ b/packages/rstream-log/package.json @@ -13,18 +13,18 @@ "license": "Apache-2.0", "scripts": { "build": "yarn clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc output xform", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc output xform", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -48,4 +48,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/rstream-query/package.json b/packages/rstream-query/package.json index 82f7f3153f..b1c1a98590 100644 --- a/packages/rstream-query/package.json +++ b/packages/rstream-query/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -54,4 +54,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/rstream/package.json b/packages/rstream/package.json index c0e39addc3..a0db67dd8c 100644 --- a/packages/rstream/package.json +++ b/packages/rstream/package.json @@ -13,18 +13,18 @@ "license": "Apache-2.0", "scripts": { "build": "yarn clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc from subs utils", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc from subs utils", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -51,4 +51,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/sax/package.json b/packages/sax/package.json index 0b7cf05ac2..69fce5f6a6 100644 --- a/packages/sax/package.json +++ b/packages/sax/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -44,4 +44,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/strings/package.json b/packages/strings/package.json index 49aa43eedb..8d0f4ca941 100644 --- a/packages/strings/package.json +++ b/packages/strings/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -44,4 +44,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/transducers-fsm/package.json b/packages/transducers-fsm/package.json index 0f5c1a3b47..95855071d9 100644 --- a/packages/transducers-fsm/package.json +++ b/packages/transducers-fsm/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -41,4 +41,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/transducers-hdom/package.json b/packages/transducers-hdom/package.json index 5ed805ae74..bedf9e3ec6 100644 --- a/packages/transducers-hdom/package.json +++ b/packages/transducers-hdom/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -45,4 +45,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/transducers-stats/package.json b/packages/transducers-stats/package.json index 537de88475..fa1b6b3414 100644 --- a/packages/transducers-stats/package.json +++ b/packages/transducers-stats/package.json @@ -12,19 +12,19 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -39,4 +39,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/transducers/package.json b/packages/transducers/package.json index 610db1a276..aadb83465a 100644 --- a/packages/transducers/package.json +++ b/packages/transducers/package.json @@ -13,18 +13,18 @@ "license": "Apache-2.0", "scripts": { "build": "yarn clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc func iter rfn xform", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc func iter rfn xform", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -50,4 +50,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/unionstruct/package.json b/packages/unionstruct/package.json index dab98fb9bf..1ee2cb8f8f 100644 --- a/packages/unionstruct/package.json +++ b/packages/unionstruct/package.json @@ -13,18 +13,18 @@ "license": "Apache-2.0", "scripts": { "build": "yarn clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "keywords": [ @@ -41,4 +41,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/vectors/package.json b/packages/vectors/package.json index a62ea777f4..f198471cff 100644 --- a/packages/vectors/package.json +++ b/packages/vectors/package.json @@ -12,12 +12,12 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && tsc --declaration", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public", + "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -25,7 +25,7 @@ "benchmark": "^2.1.4", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -47,4 +47,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 57aa3a86df..50f6c88cf5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -629,15 +629,20 @@ lodash "^4.17.10" to-fast-properties "^2.0.0" -"@lerna/add@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/add/-/add-3.6.0.tgz#eea53efff0b3237774ddac6eaa84957140e89238" - integrity sha512-aFVekkHMno3hj1Vg3EiIpAwrZ4g34i8z4KrCx7ATY6BRuxVT4Nt/Nk3l2k6gEOq3tWUDtUctLHxIAo14FI8sng== - dependencies: - "@lerna/bootstrap" "^3.6.0" - "@lerna/command" "^3.6.0" - "@lerna/filter-options" "^3.6.0" - "@lerna/npm-conf" "^3.4.1" +"@iarna/toml@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.1.tgz#82d0993d8882bb05e0645fbb4731d9e939e895b3" + integrity sha512-I2EjI9TbEFJNLziNPFfpo64PNanOaK17iL2kTW/jGlGOa4bvHw4VEied83kOEB7NJjXf1KfvmsQ2aEjy3xjiGg== + +"@lerna/add@^3.8.5": + version "3.8.5" + resolved "https://registry.yarnpkg.com/@lerna/add/-/add-3.8.5.tgz#f7dec6b9ce20bc42d64bbb29381b62a918c8c7aa" + integrity sha512-jySRqLaROejfBriA4cFdc1AlSoeQ/0f6uocdIgkFFHwWyU65j48fdLlERRDE6t2iTwh4u+UVnK5eIglGBJUqEA== + dependencies: + "@lerna/bootstrap" "^3.8.5" + "@lerna/command" "^3.8.5" + "@lerna/filter-options" "^3.8.1" + "@lerna/npm-conf" "^3.7.0" "@lerna/validation-error" "^3.6.0" dedent "^0.7.0" libnpm "^2.0.1" @@ -653,23 +658,23 @@ "@lerna/validation-error" "^3.6.0" libnpm "^2.0.1" -"@lerna/bootstrap@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/bootstrap/-/bootstrap-3.6.0.tgz#a47cd484ad60638d518a606d627b9997d5f7c960" - integrity sha512-z6rZQw/aLEN+ragWRYqIIVwA9rDv3QtmRc5VyIRrlV/JiuGpq67FcSR6BrCMc/A7UJ9Kx95+bESm/HUwheKoiQ== +"@lerna/bootstrap@^3.8.5": + version "3.8.5" + resolved "https://registry.yarnpkg.com/@lerna/bootstrap/-/bootstrap-3.8.5.tgz#0063763aa2ad8f8dec96dd92f42a01e053fa7290" + integrity sha512-AF46juyExojRndbFU5K9xX+IkvqDlaGsGzYxVaDn2o4xQwC/TnvtCuIooEKgDcVkhyTHhBi+PNr5RWcRm/IhxA== dependencies: "@lerna/batch-packages" "^3.6.0" - "@lerna/command" "^3.6.0" - "@lerna/filter-options" "^3.6.0" + "@lerna/command" "^3.8.5" + "@lerna/filter-options" "^3.8.1" "@lerna/has-npm-version" "^3.3.0" - "@lerna/npm-conf" "^3.4.1" - "@lerna/npm-install" "^3.6.0" + "@lerna/npm-install" "^3.8.2" "@lerna/package-graph" "^3.6.0" + "@lerna/pulse-till-done" "^3.7.1" "@lerna/rimraf-dir" "^3.6.0" - "@lerna/run-lifecycle" "^3.6.0" + "@lerna/run-lifecycle" "^3.8.2" "@lerna/run-parallel-batches" "^3.0.0" - "@lerna/symlink-binary" "^3.6.0" - "@lerna/symlink-dependencies" "^3.6.0" + "@lerna/symlink-binary" "^3.7.2" + "@lerna/symlink-dependencies" "^3.8.1" "@lerna/validation-error" "^3.6.0" dedent "^0.7.0" get-port "^3.2.0" @@ -682,23 +687,23 @@ read-package-tree "^5.1.6" semver "^5.5.0" -"@lerna/changed@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/changed/-/changed-3.6.0.tgz#a6c97b9c4829d294a1d8e8a7140667bc89c996e2" - integrity sha512-L1SXTtQrsv+4F5Knw5sW/nGnMJq+bbOzhZX2srJ10WsuHuzk3cJWAi7dVEsS3RPKUw9DWOuHKy86o3v6byEiqA== +"@lerna/changed@^3.8.5": + version "3.8.5" + resolved "https://registry.yarnpkg.com/@lerna/changed/-/changed-3.8.5.tgz#fe2712c66caf768a31568b4b6b864c664d084298" + integrity sha512-VIRldHvs0niGVnrZjGw2oi7MWY50vh5AkZ2E6XQFP5guHjPWF18SdRa0p0oLf4Ci+I3KskFNjzJS0dMSnmP+BA== dependencies: - "@lerna/collect-updates" "^3.6.0" - "@lerna/command" "^3.6.0" + "@lerna/collect-updates" "^3.8.1" + "@lerna/command" "^3.8.5" "@lerna/listable" "^3.6.0" "@lerna/output" "^3.6.0" - "@lerna/version" "^3.6.0" + "@lerna/version" "^3.8.5" -"@lerna/check-working-tree@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/check-working-tree/-/check-working-tree-3.6.0.tgz#638ee7f5976fe607d544629b1ef4ae67887984b5" - integrity sha512-Ioy1t2aVasAwhY1Oi5kfpwbW9RDupxxVVu2t2c1EeBYYCu3jIt1A5ad34gidgsKyiG3HeBEVziI4Uaihnb96ZQ== +"@lerna/check-working-tree@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@lerna/check-working-tree/-/check-working-tree-3.8.1.tgz#bda0719f3a3ceaed976b08f57b054af6a0acf295" + integrity sha512-UJqyvFr3+MTDo31fVjJlV/eshmQg8u0vpQcY95Vs00B99QxzLoICSGpNdldhSBnOIpOlq6tm5H/2hflc5hANew== dependencies: - "@lerna/describe-ref" "^3.6.0" + "@lerna/describe-ref" "^3.8.1" "@lerna/validation-error" "^3.6.0" "@lerna/child-process@^3.3.0": @@ -710,14 +715,15 @@ execa "^1.0.0" strong-log-transformer "^2.0.0" -"@lerna/clean@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/clean/-/clean-3.6.0.tgz#9a9d73324389cba694b19a913229c19d58e62485" - integrity sha512-4LodI/jh8IEYtqnrY/OFSpWn5YfDWoDv+5QjiJpd91EjW9vjmkvyhzQ5fG9KtltwgYVn/NJ5zlI1WfmMEXvFFQ== +"@lerna/clean@^3.8.5": + version "3.8.5" + resolved "https://registry.yarnpkg.com/@lerna/clean/-/clean-3.8.5.tgz#42ec3b70a032b38bbdcac6ea804baf2df22432cf" + integrity sha512-fYym9Lj0szbW5Z+QQuXFgsdtoe3VQxfwgFOWDDpnDr4DpjKrKulwYkR15Cx+Lc6gpjYGlM8bmi/KOFtaLfKwcQ== dependencies: - "@lerna/command" "^3.6.0" - "@lerna/filter-options" "^3.6.0" + "@lerna/command" "^3.8.5" + "@lerna/filter-options" "^3.8.1" "@lerna/prompt" "^3.6.0" + "@lerna/pulse-till-done" "^3.7.1" "@lerna/rimraf-dir" "^3.6.0" p-map "^1.2.0" p-map-series "^1.0.0" @@ -733,25 +739,25 @@ libnpm "^2.0.1" yargs "^12.0.1" -"@lerna/collect-updates@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/collect-updates/-/collect-updates-3.6.0.tgz#8520d64852c5059b453db53afee22539853f2bde" - integrity sha512-knliEz3phY51SGnwDhhYqx6SJN6y9qh/gZrZgQ7ogqz1UgA/MyJb27gszjsyyG6jUQshimBpjsG7OMwjt8+n9A== +"@lerna/collect-updates@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@lerna/collect-updates/-/collect-updates-3.8.1.tgz#e227efe9955b56b258baf7e8f853f779d40556a7" + integrity sha512-1ULd1FBX8j8XGe166CUx+PkNeBJrbauI6Ux9+NiVrpeyE5rF6hzrowRyaptE9n5jzAl0WtTTIP1MsdrVG7BvAA== dependencies: "@lerna/child-process" "^3.3.0" - "@lerna/describe-ref" "^3.6.0" + "@lerna/describe-ref" "^3.8.1" libnpm "^2.0.1" minimatch "^3.0.4" slash "^1.0.0" -"@lerna/command@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/command/-/command-3.6.0.tgz#b3289d1f72d2bebb7375d424b1778121a3d4e82c" - integrity sha512-BGpXaY2WrxPcIiZX0aATO2HQBatvYT7Qy46lqMnV9RrTePYJ1PPbX1nMzLXSxgrnnlTcTwJNEkw/TL9Xzrph7Q== +"@lerna/command@^3.8.5": + version "3.8.5" + resolved "https://registry.yarnpkg.com/@lerna/command/-/command-3.8.5.tgz#b551f3a83c87258c8e9eb681dec95542df849119" + integrity sha512-NkLuA46RlL+LZ6lyXcuhJKbiS0LgnvRj0uwkxre2yHFDRnUdoCLXEXcslHO+fcM0ROOPYOa8rWEb2uGplfM1ug== dependencies: "@lerna/child-process" "^3.3.0" "@lerna/package-graph" "^3.6.0" - "@lerna/project" "^3.6.0" + "@lerna/project" "^3.8.5" "@lerna/validation-error" "^3.6.0" "@lerna/write-log-file" "^3.6.0" dedent "^0.7.0" @@ -783,14 +789,14 @@ fs-extra "^7.0.0" libnpm "^2.0.1" -"@lerna/create@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/create/-/create-3.6.0.tgz#4540c9ee69f63d11b3138eb5eac1942348643af1" - integrity sha512-21OunW25Y3Q/oynqWVk0znQFBvZ5tHyLPhzkJeomGmOj0il1RdOUiChu9G9AYsCaLDwBFR0ZFqvTgJ5iw/eaIg== +"@lerna/create@^3.8.5": + version "3.8.5" + resolved "https://registry.yarnpkg.com/@lerna/create/-/create-3.8.5.tgz#c4d41e879110f3cbc842d93d90f2f827413e8e8e" + integrity sha512-Kgkp4jttk1ElBT2A0WiCBC5E/KWU5dnt4iCmXRqcEe5ZaV+Jd669llkp26mDY2/wx9Tjdh+CaZO54PTrVZnAZQ== dependencies: "@lerna/child-process" "^3.3.0" - "@lerna/command" "^3.6.0" - "@lerna/npm-conf" "^3.4.1" + "@lerna/command" "^3.8.5" + "@lerna/npm-conf" "^3.7.0" "@lerna/validation-error" "^3.6.0" camelcase "^4.1.0" dedent "^0.7.0" @@ -806,42 +812,42 @@ validate-npm-package-name "^3.0.0" whatwg-url "^7.0.0" -"@lerna/describe-ref@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/describe-ref/-/describe-ref-3.6.0.tgz#29eda334c81cd4c0a2942f309936bcb69a4543a0" - integrity sha512-hVZJ2hYVbrrNiEG+dEg/Op4pYAbROkDZdiIUabAJffr0T/frcN+5es2HfmOC//4+78Cs1M9iTyQRoyC1RXS2BQ== +"@lerna/describe-ref@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@lerna/describe-ref/-/describe-ref-3.8.1.tgz#b99ef6f8aa58fa9389af1e03beaa716cc6cb506d" + integrity sha512-EPXFiZbWG0KiaDM+BT3RZahy5gwrTVyKDv8HmPkGhu2h4pr34tzsSMmYmJ8I0dLeu4IpP/G/OIBa6DkYWisiZw== dependencies: "@lerna/child-process" "^3.3.0" libnpm "^2.0.1" -"@lerna/diff@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/diff/-/diff-3.6.0.tgz#ea8a77e712daf951c05316c81fe4065bf6b5e22c" - integrity sha512-p5+VyYKuAnw6NFVrT4s9eBubFZEYlJmiR1mdVlwNtohqS86gERjrPtI0unUK/pxFKb1U2ZNo4fhSlPd+pLwfHg== +"@lerna/diff@^3.8.5": + version "3.8.5" + resolved "https://registry.yarnpkg.com/@lerna/diff/-/diff-3.8.5.tgz#4f68fc9833bf722d2d7bea2be33e5e09d3651d92" + integrity sha512-20aT02ryjHwWwrLMdBZat6Wz3SzMUy3eoJ0IcNnmdz1ju9TKms3ImeeuAwFIJ1q71jQFSYT9HGDR0d3Yq5WVhw== dependencies: "@lerna/child-process" "^3.3.0" - "@lerna/command" "^3.6.0" + "@lerna/command" "^3.8.5" "@lerna/validation-error" "^3.6.0" libnpm "^2.0.1" -"@lerna/exec@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/exec/-/exec-3.6.0.tgz#757e96e890e436a31efc59dc72c5a7c2944d1a44" - integrity sha512-lwLYASpS8FoQpVYLBpoZlS7bpzkO9pD3D9XeDDKZBodDhdZeCEx2Md2CxZU1RKYDSVIXA8oObvlUh1FEhRQv2w== +"@lerna/exec@^3.8.5": + version "3.8.5" + resolved "https://registry.yarnpkg.com/@lerna/exec/-/exec-3.8.5.tgz#ab95de1bec09789e4ff3b2f7683c7f565eaeed38" + integrity sha512-lcblv2lQpKTk2sRAzV+VrHcZhHoFO9GVyZDAY6uEeQHlY2NoydeSwXT7g+jUbmhAqypptjyIeM8V3wnCu9nnrw== dependencies: "@lerna/batch-packages" "^3.6.0" "@lerna/child-process" "^3.3.0" - "@lerna/command" "^3.6.0" - "@lerna/filter-options" "^3.6.0" + "@lerna/command" "^3.8.5" + "@lerna/filter-options" "^3.8.1" "@lerna/run-parallel-batches" "^3.0.0" "@lerna/validation-error" "^3.6.0" -"@lerna/filter-options@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/filter-options/-/filter-options-3.6.0.tgz#8100a3f2e18a9772a61138711e1fe1f14969f814" - integrity sha512-6iUMZuvvXPL5EAF7Zo9azaZ6FxOq6tGbiSX8fUXgCdN+jlRjorvkzR+E0HS4bEGTWmV446lnLwdQLZuySfLcbQ== +"@lerna/filter-options@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@lerna/filter-options/-/filter-options-3.8.1.tgz#8c9708d60681383051d90a06eaa292dddd1d16b4" + integrity sha512-ty4Pl+vZjPSc7jc4nhK/4YYGKpLOhcGHLw6Zu71D4V3DJW/ZDHm/veRIApmhddL7+6y9G+ZGnGYYh/8RFyT6hA== dependencies: - "@lerna/collect-updates" "^3.6.0" + "@lerna/collect-updates" "^3.8.1" "@lerna/filter-packages" "^3.6.0" dedent "^0.7.0" @@ -861,6 +867,15 @@ dependencies: libnpm "^2.0.1" +"@lerna/get-packed@^3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@lerna/get-packed/-/get-packed-3.7.0.tgz#549c7738f7be5e3b1433e82ed9cda9123bcd1ed5" + integrity sha512-yuFtjsUZIHjeIvIYQ/QuytC+FQcHwo3peB+yGBST2uWCLUCR5rx6knoQcPzbxdFDCuUb5IFccFGd3B1fHFg3RQ== + dependencies: + fs-extra "^7.0.0" + ssri "^6.0.1" + tar "^4.4.8" + "@lerna/global-options@^3.1.3": version "3.1.3" resolved "https://registry.yarnpkg.com/@lerna/global-options/-/global-options-3.1.3.tgz#cf85e24655a91d04d4efc9a80c1f83fc768d08ae" @@ -874,48 +889,49 @@ "@lerna/child-process" "^3.3.0" semver "^5.5.0" -"@lerna/import@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/import/-/import-3.6.0.tgz#84ef5eea61ab9a284054be32367906d092aadab5" - integrity sha512-8jxNRbAaa4mvMJr0u+sy75gMFPyWfxLHEp+pDs73x1oqMZhpS8O5901QMnpZyRyOvJRhoBJd5hBX2dpsLxC6Xw== +"@lerna/import@^3.8.5": + version "3.8.5" + resolved "https://registry.yarnpkg.com/@lerna/import/-/import-3.8.5.tgz#143e96b29c64ae060882e49ecf6b583ae87e10f9" + integrity sha512-6mT4rYafszXdUOCKDfOGi/oOD+mKeoH1nn8z97PPm9V8b79c/TOROJ0vrjtRa9bS/5BpXMRKTRwq2BV+z5UiIA== dependencies: "@lerna/child-process" "^3.3.0" - "@lerna/command" "^3.6.0" + "@lerna/command" "^3.8.5" "@lerna/prompt" "^3.6.0" + "@lerna/pulse-till-done" "^3.7.1" "@lerna/validation-error" "^3.6.0" dedent "^0.7.0" fs-extra "^7.0.0" p-map-series "^1.0.0" -"@lerna/init@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/init/-/init-3.6.0.tgz#6e23c3db632b713e23250d33519ed844a79a145e" - integrity sha512-MTLy3rmMdvpXRmDdoYiVPx7I8sXH4dquq/0MxntL5VxSVh/ZS1HsbrjyRqpdkUKWD9QguxR/w0pzOjVvCeM8CQ== +"@lerna/init@^3.8.5": + version "3.8.5" + resolved "https://registry.yarnpkg.com/@lerna/init/-/init-3.8.5.tgz#c5e11ba0bf4df258538c1718e74897a4d6d23c4a" + integrity sha512-yVQmEqPY0WkXXv9HgKSiEC845PK/zQ6ejQKQbh83fV59VTkLLaLXJoCcj7OsiMiNlKdN92LxiNHE/T25Zrwokg== dependencies: "@lerna/child-process" "^3.3.0" - "@lerna/command" "^3.6.0" + "@lerna/command" "^3.8.5" fs-extra "^7.0.0" p-map "^1.2.0" write-json-file "^2.3.0" -"@lerna/link@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/link/-/link-3.6.0.tgz#490f14216b489fd66d9d3d3d0765f75dbbf52178" - integrity sha512-Xk8TTAE4EWGyhxLuPxWdyS7i7vfsM5igb6tEyhZm94XUdlA4PmMOYe25BfO7SM/9LYroFknZeDyWAebye3r+PA== +"@lerna/link@^3.8.5": + version "3.8.5" + resolved "https://registry.yarnpkg.com/@lerna/link/-/link-3.8.5.tgz#6a7060e0e7f3d99f3f3b9ccdeab5b46f6f8c836a" + integrity sha512-Xd4A5rLP5780KJ6eVqbRhkHFGCw+lfBgHr8imXwaaou7IuZv7Sh69C8YcceyQHQLwJsjNT7LaX1VXbPe4Hs1rw== dependencies: - "@lerna/command" "^3.6.0" + "@lerna/command" "^3.8.5" "@lerna/package-graph" "^3.6.0" - "@lerna/symlink-dependencies" "^3.6.0" + "@lerna/symlink-dependencies" "^3.8.1" p-map "^1.2.0" slash "^1.0.0" -"@lerna/list@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/list/-/list-3.6.0.tgz#18ae4b1e375ef1329261c9d21be27098ca0edf63" - integrity sha512-hlQOJkg8K3XXUVXotofP71XsgkhXkkmU/EkqlNg15D78MjzhT+p1wCbG5m89K3tzvjcWVeZwU6L0elaOIXVyCw== +"@lerna/list@^3.8.5": + version "3.8.5" + resolved "https://registry.yarnpkg.com/@lerna/list/-/list-3.8.5.tgz#3b2a80ed8f3fc7ea8ab97ea45cbedcb0d3258f5e" + integrity sha512-YfPllSZkw29ZDHOGBut8ju5WOLvYopqlb2KOWgmhJOMO+7P9f5Hm1A+/cjVvPQlEmV8RDgc7t4lOuC9sAfXBSA== dependencies: - "@lerna/command" "^3.6.0" - "@lerna/filter-options" "^3.6.0" + "@lerna/command" "^3.8.5" + "@lerna/filter-options" "^3.8.1" "@lerna/listable" "^3.6.0" "@lerna/output" "^3.6.0" @@ -938,26 +954,26 @@ has-unicode "^2.0.1" libnpm "^2.0.1" -"@lerna/npm-conf@^3.4.1": - version "3.4.1" - resolved "https://registry.yarnpkg.com/@lerna/npm-conf/-/npm-conf-3.4.1.tgz#859e931b0bc9a5eed86309cc09508810c1e7d121" - integrity sha512-i9G6DnbCqiAqxKx2rSXej/n14qxlV/XOebL6QZonxJKzNTB+Q2wglnhTXmfZXTPJfoqimLaY4NfAEtbOXRWOXQ== +"@lerna/npm-conf@^3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@lerna/npm-conf/-/npm-conf-3.7.0.tgz#f101d4fdf07cefcf1161bcfaf3c0f105b420a450" + integrity sha512-+WSMDfPKcKzMfqq283ydz9RRpOU6p9wfx0wy4hVSUY/6YUpsyuk8SShjcRtY8zTM5AOrxvFBuuV90H4YpZ5+Ng== dependencies: config-chain "^1.1.11" pify "^3.0.0" -"@lerna/npm-dist-tag@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/npm-dist-tag/-/npm-dist-tag-3.6.0.tgz#8f8c8567810bd9ee1c1277a71b57cec1acc101f4" - integrity sha512-qX6IfQPX9Tum1LRjvjgj/yr2FYbc9dfHyeh7RI9zJ8pGncWbksBmnMcvoxF0Eu4+d7MjjIGfEnIp9LIl4MHSIA== +"@lerna/npm-dist-tag@^3.8.5": + version "3.8.5" + resolved "https://registry.yarnpkg.com/@lerna/npm-dist-tag/-/npm-dist-tag-3.8.5.tgz#5ce22a72576badc8cb6baf85550043d63e66ea44" + integrity sha512-VO57yKTB4NC2LZuTd4w0LmlRpoFm/gejQ1gqqLGzSJuSZaBXmieElFovzl21S07cqiy7FNVdz75x7/a6WCZ6XA== dependencies: + figgy-pudding "^3.5.1" libnpm "^2.0.1" - npm-registry-fetch "^3.8.0" -"@lerna/npm-install@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/npm-install/-/npm-install-3.6.0.tgz#314fc0d0c35429e2b5db1e7de87b3ddb1ab77606" - integrity sha512-RKV31VdrBZKjmKfq25JG4mIHJ8NAOsLKq/aYSaBs8zP+uwXH7RU39saVfv9ReKiAzhKE2ghOG2JeMdIHtYnPNA== +"@lerna/npm-install@^3.8.2": + version "3.8.2" + resolved "https://registry.yarnpkg.com/@lerna/npm-install/-/npm-install-3.8.2.tgz#24c7271a62bd3ec03275cf0a1c5fbafef4955f42" + integrity sha512-A22IrhPy70Gm30rBYSPp/PDWjByvj6QdxqQh41HlNGOCzM5WCCSDXpfeoxzS0ow0d3WGJMraE2k1GFpOP6Hyxg== dependencies: "@lerna/child-process" "^3.3.0" "@lerna/get-npm-exec-opts" "^3.6.0" @@ -966,18 +982,15 @@ signal-exit "^3.0.2" write-pkg "^3.1.0" -"@lerna/npm-publish@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/npm-publish/-/npm-publish-3.6.0.tgz#8981a9744779c55955a8c4249fe6b44a0485f9d3" - integrity sha512-k4yF8ursajoGRlJeRh7xdeGN0HV/ALt5qImUnpTliux0213jqxA0YigiD8WSaXpvSqxSFyvh38DbJhhy9q+NuQ== +"@lerna/npm-publish@^3.8.5": + version "3.8.5" + resolved "https://registry.yarnpkg.com/@lerna/npm-publish/-/npm-publish-3.8.5.tgz#c6718be54dff1e7b701aed7763b213d2002b988d" + integrity sha512-cXmgiOhOKP9Ew+SncmE5ZQpEWA3mTcG5ItG5EUWAd/h9WwYOTCr7SD67lOlrkge/xw8dUQd0iDNz2QxDrpQaUg== dependencies: - "@lerna/child-process" "^3.3.0" - "@lerna/get-npm-exec-opts" "^3.6.0" - "@lerna/has-npm-version" "^3.3.0" - "@lerna/log-packed" "^3.6.0" + "@lerna/run-lifecycle" "^3.8.2" + figgy-pudding "^3.5.1" fs-extra "^7.0.0" libnpm "^2.0.1" - p-map "^1.2.0" "@lerna/npm-run-script@^3.6.0": version "3.6.0" @@ -995,6 +1008,20 @@ dependencies: libnpm "^2.0.1" +"@lerna/pack-directory@^3.8.2": + version "3.8.2" + resolved "https://registry.yarnpkg.com/@lerna/pack-directory/-/pack-directory-3.8.2.tgz#5ffddce7781998195cffcbe51128c5a69dd3ca7a" + integrity sha512-sYXioixVw3L5r9O4bt+hnfPQ8jLn/PVOJVivQdpSlup+ZUiI5mmtjzAO3NOK/k8DZf8YrUx0Lm1+vzgnqu1tKw== + dependencies: + "@lerna/get-packed" "^3.7.0" + "@lerna/package" "^3.7.2" + "@lerna/run-lifecycle" "^3.8.2" + figgy-pudding "^3.5.1" + libnpm "^2.0.1" + npm-packlist "^1.1.12" + tar "^4.4.8" + temp-write "^3.4.0" + "@lerna/package-graph@^3.6.0": version "3.6.0" resolved "https://registry.yarnpkg.com/@lerna/package-graph/-/package-graph-3.6.0.tgz#d13e6e80d30e2e29226d335412997b9ddf646305" @@ -1004,20 +1031,21 @@ libnpm "^2.0.1" semver "^5.5.0" -"@lerna/package@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/package/-/package-3.6.0.tgz#1095b91d277820b7ae8a2cfeeb73d57c6cd9b17e" - integrity sha512-XbXcjwPKA1V640mqjEicpBriO6QcNtocdfLAtEUP4uCKkRx5r9h7DdznQMCoSJYJF6Gh/PpLokPUItfMhJP3Hg== +"@lerna/package@^3.7.2": + version "3.7.2" + resolved "https://registry.yarnpkg.com/@lerna/package/-/package-3.7.2.tgz#03c69fd7fb965c372c8c969165a2f7d6dfe2dfcb" + integrity sha512-8A5hN2CekM1a0Ix4VUO/g+REo+MsnXb8lnQ0bGjr1YGWzSL5NxYJ0Z9+0pwTfDpvRDYlFYO0rMVwBUW44b4dUw== dependencies: libnpm "^2.0.1" + load-json-file "^4.0.0" write-pkg "^3.1.0" -"@lerna/project@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/project/-/project-3.6.0.tgz#b5dd2b94fae6f58478be1c53962c2570498867ab" - integrity sha512-pEOZF1igGFqs+qWog6cJWqVyBUX21xSqrlcgeN0yzqzI36VMHozmf/u7dgclIb5MylWk5Yp87KCKswBF4hrcuQ== +"@lerna/project@^3.8.5": + version "3.8.5" + resolved "https://registry.yarnpkg.com/@lerna/project/-/project-3.8.5.tgz#7177d74ad4a9fa6b709ae4f29d64951165332565" + integrity sha512-D0no5qrfKGxFkUOypUFCsT1iZww0ioW2zbwyUqvWal5ut/lH9+T7RLFxSKVfo+tuJTT0zqCITHBtsA3G/wwNDg== dependencies: - "@lerna/package" "^3.6.0" + "@lerna/package" "^3.7.2" "@lerna/validation-error" "^3.6.0" cosmiconfig "^5.0.2" dedent "^0.7.0" @@ -1038,36 +1066,45 @@ inquirer "^6.2.0" libnpm "^2.0.1" -"@lerna/publish@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/publish/-/publish-3.6.0.tgz#7985b8c549c83114180e99a9e291e8b82db57aac" - integrity sha512-F2bT96ZS7NJfid6T4a6TSanpVUQ4VOuhjPBPX2hagt5gnocm7lluvAFR7dl/cbEgmKIg2zJQnfAPTYjrtxXMVg== +"@lerna/publish@^3.8.5": + version "3.8.5" + resolved "https://registry.yarnpkg.com/@lerna/publish/-/publish-3.8.5.tgz#27437c44e76c5f2f71af339275c5582f80bd769c" + integrity sha512-F+68eSYlI16INIpWLXjprArsh1tFvSeEqaJEMCCu5NUAWHlCvds/+L5RJZDXatWFppRsNR6dlYKdM9FbAZHuLw== dependencies: "@lerna/batch-packages" "^3.6.0" - "@lerna/check-working-tree" "^3.6.0" + "@lerna/check-working-tree" "^3.8.1" "@lerna/child-process" "^3.3.0" - "@lerna/collect-updates" "^3.6.0" - "@lerna/command" "^3.6.0" - "@lerna/describe-ref" "^3.6.0" - "@lerna/get-npm-exec-opts" "^3.6.0" - "@lerna/npm-conf" "^3.4.1" - "@lerna/npm-dist-tag" "^3.6.0" - "@lerna/npm-publish" "^3.6.0" + "@lerna/collect-updates" "^3.8.1" + "@lerna/command" "^3.8.5" + "@lerna/describe-ref" "^3.8.1" + "@lerna/log-packed" "^3.6.0" + "@lerna/npm-conf" "^3.7.0" + "@lerna/npm-dist-tag" "^3.8.5" + "@lerna/npm-publish" "^3.8.5" "@lerna/output" "^3.6.0" + "@lerna/pack-directory" "^3.8.2" "@lerna/prompt" "^3.6.0" - "@lerna/run-lifecycle" "^3.6.0" + "@lerna/pulse-till-done" "^3.7.1" + "@lerna/run-lifecycle" "^3.8.2" "@lerna/run-parallel-batches" "^3.0.0" "@lerna/validation-error" "^3.6.0" - "@lerna/version" "^3.6.0" + "@lerna/version" "^3.8.5" + figgy-pudding "^3.5.1" fs-extra "^7.0.0" libnpm "^2.0.1" - npm-registry-fetch "^3.8.0" p-finally "^1.0.0" p-map "^1.2.0" p-pipe "^1.2.0" p-reduce "^1.0.0" semver "^5.5.0" +"@lerna/pulse-till-done@^3.7.1": + version "3.7.1" + resolved "https://registry.yarnpkg.com/@lerna/pulse-till-done/-/pulse-till-done-3.7.1.tgz#a9e55380fa18f6896a3e5b23621a4227adfb8f85" + integrity sha512-MzpesZeW3Mc+CiAq4zUt9qTXI9uEBBKrubYHE36voQTSkHvu/Rox6YOvfUr+U7P6k8frFPeCgGpfMDTLhiqe6w== + dependencies: + libnpm "^2.0.1" + "@lerna/resolve-symlink@^3.6.0": version "3.6.0" resolved "https://registry.yarnpkg.com/@lerna/resolve-symlink/-/resolve-symlink-3.6.0.tgz#985344796b704ff32afa923901e795e80741b86e" @@ -1087,12 +1124,13 @@ path-exists "^3.0.0" rimraf "^2.6.2" -"@lerna/run-lifecycle@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/run-lifecycle/-/run-lifecycle-3.6.0.tgz#2381fd827b4a4135613e7d73d25ae76b7af5e6ef" - integrity sha512-/1+vAZnckgKwHVgWG0plVO24erNWUduz9htMOO9wuOfglTnHlMRqDc3s9B/OIKxGDkyzEvxqzfzq3c6JqEolRQ== +"@lerna/run-lifecycle@^3.8.2": + version "3.8.2" + resolved "https://registry.yarnpkg.com/@lerna/run-lifecycle/-/run-lifecycle-3.8.2.tgz#fe97f771506e2351aa170ec75ef8e6d7e9b94509" + integrity sha512-V80nIoHpp0IL9WEaK8wz47SeqLSlI8DyNqVqUoG1DCeCGr6rdvRGD0FgHSKgRnZxk/SgP1Az/YBBtc5qnA+CzA== dependencies: - "@lerna/npm-conf" "^3.4.1" + "@lerna/npm-conf" "^3.7.0" + figgy-pudding "^3.5.1" libnpm "^2.0.1" "@lerna/run-parallel-batches@^3.0.0": @@ -1103,14 +1141,14 @@ p-map "^1.2.0" p-map-series "^1.0.0" -"@lerna/run@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/run/-/run-3.6.0.tgz#f545fcde889d7a1433b3f2cc444eeec39713ea62" - integrity sha512-OYa5pQTOiES/h9rg8vwnt0nYU/wLKUQmFYhMUxdX3lXYpoIcQ28PR7qPG1CVhex4KAU2OW42a7vnm5MAOoScDg== +"@lerna/run@^3.8.5": + version "3.8.5" + resolved "https://registry.yarnpkg.com/@lerna/run/-/run-3.8.5.tgz#5c22b4d15a29a3f98f5bd367fed754e2cf495e89" + integrity sha512-EthL+RhaS2RSXH+l1xtlekx/ZAo2ci/oK9hEESP6YS/VON4wqbMDzPlU6nBcYz/omqO2fFKfDW3pSdzDLMMUgA== dependencies: "@lerna/batch-packages" "^3.6.0" - "@lerna/command" "^3.6.0" - "@lerna/filter-options" "^3.6.0" + "@lerna/command" "^3.8.5" + "@lerna/filter-options" "^3.8.1" "@lerna/npm-run-script" "^3.6.0" "@lerna/output" "^3.6.0" "@lerna/run-parallel-batches" "^3.0.0" @@ -1118,25 +1156,24 @@ "@lerna/validation-error" "^3.6.0" p-map "^1.2.0" -"@lerna/symlink-binary@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/symlink-binary/-/symlink-binary-3.6.0.tgz#935a5b98908578da7f9eed20818899f728b9f3d9" - integrity sha512-h69AQBBWgZOEzQ1RJEYQ7Ou6llrJNhNNkpqT6k8qSWZ93iXyFmLE4hWoxMXXHFmxmQ0CqjEYKmeLV1Dr5DKT4g== +"@lerna/symlink-binary@^3.7.2": + version "3.7.2" + resolved "https://registry.yarnpkg.com/@lerna/symlink-binary/-/symlink-binary-3.7.2.tgz#fedce89711ecfeb3d85fd7035199fab0436a793a" + integrity sha512-xS7DdBXNQgfgrhBe2Jz27+S65yxBfnl+Xi+grvlqoEGVk7b8kt2VcBtui/XgL6AAaTg6f9szj4LUnwC/oX6S1Q== dependencies: "@lerna/create-symlink" "^3.6.0" - "@lerna/package" "^3.6.0" + "@lerna/package" "^3.7.2" fs-extra "^7.0.0" p-map "^1.2.0" - read-pkg "^3.0.0" -"@lerna/symlink-dependencies@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/symlink-dependencies/-/symlink-dependencies-3.6.0.tgz#76e9d54f6fd3af3e24221cce3ee546e5657ea2d8" - integrity sha512-mLpbWLidAU5Xi7bc9Fj8Yt/9XvDczzWocnS/yEe0E6RqWXh2KK+4VR9H24rLywBAWTv2s4GEXrb/ofbPb8gwBQ== +"@lerna/symlink-dependencies@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@lerna/symlink-dependencies/-/symlink-dependencies-3.8.1.tgz#890979f232beb9c4618a3b49d4ad11f567617642" + integrity sha512-MlXRTpB3Go/ubexxySngzg8PnItpPIxa0ydHMxvvw7s06g7ZsOOMOAx+F7AUPPr7bssdZ+gg5bfSq+J1HoINrg== dependencies: "@lerna/create-symlink" "^3.6.0" "@lerna/resolve-symlink" "^3.6.0" - "@lerna/symlink-binary" "^3.6.0" + "@lerna/symlink-binary" "^3.7.2" fs-extra "^7.0.0" p-finally "^1.0.0" p-map "^1.2.0" @@ -1154,20 +1191,20 @@ dependencies: libnpm "^2.0.1" -"@lerna/version@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@lerna/version/-/version-3.6.0.tgz#7360d8a93b1cc5fe6a7588d7266812b916a281f7" - integrity sha512-V1f3fNM5ELGHmF824Wc8ah505SMpfiBqOHAIiW+u9soH/3W/t256c1P9UeaDh5blWAk3HeZMzbpRZ9Nlpf6aQA== +"@lerna/version@^3.8.5": + version "3.8.5" + resolved "https://registry.yarnpkg.com/@lerna/version/-/version-3.8.5.tgz#dd4b95d1ed40211063bb546bba1581db4bab9b1a" + integrity sha512-CfWoef3M2CCA3dMqPYJCrshuSAs+xCAEfVpLmaHQyutKXXGG1LZD38iq2Xs3dxNF07Md5H9+Mt6pfEwsXqjhJA== dependencies: "@lerna/batch-packages" "^3.6.0" - "@lerna/check-working-tree" "^3.6.0" + "@lerna/check-working-tree" "^3.8.1" "@lerna/child-process" "^3.3.0" - "@lerna/collect-updates" "^3.6.0" - "@lerna/command" "^3.6.0" + "@lerna/collect-updates" "^3.8.1" + "@lerna/command" "^3.8.5" "@lerna/conventional-commits" "^3.6.0" "@lerna/output" "^3.6.0" "@lerna/prompt" "^3.6.0" - "@lerna/run-lifecycle" "^3.6.0" + "@lerna/run-lifecycle" "^3.8.2" "@lerna/validation-error" "^3.6.0" chalk "^2.3.1" dedent "^0.7.0" @@ -1202,6 +1239,47 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.2.tgz#54c5a964462be3d4d78af631363c18d6fa91ac26" integrity sha512-yprFYuno9FtNsSHVlSWd+nRlmGoAbqbeCwOryP6sC/zoCjhpArcRMYp19EvpSUSizJAlsXEwJv+wcWS9XaXdMw== +"@parcel/fs@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@parcel/fs/-/fs-1.11.0.tgz#fb8a2be038c454ad46a50dc0554c1805f13535cd" + integrity sha512-86RyEqULbbVoeo8OLcv+LQ1Vq2PKBAvWTU9fCgALxuCTbbs5Ppcvll4Vr+Ko1AnmMzja/k++SzNAwJfeQXVlpA== + dependencies: + "@parcel/utils" "^1.11.0" + mkdirp "^0.5.1" + rimraf "^2.6.2" + +"@parcel/logger@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@parcel/logger/-/logger-1.11.0.tgz#91f39da14ba08dd85db247145698c62102960abb" + integrity sha512-lIRfDg+junbFUUeU0QtHX00gKCgEsYHZydFKwrJ8dc0D+WE2SYT1FcVCgpPAfKYgtg0QQMns8E9vzT9UjH92PQ== + dependencies: + "@parcel/workers" "^1.11.0" + chalk "^2.1.0" + grapheme-breaker "^0.3.2" + ora "^2.1.0" + strip-ansi "^4.0.0" + +"@parcel/utils@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@parcel/utils/-/utils-1.11.0.tgz#539e08fff8af3b26eca11302be80b522674b51ea" + integrity sha512-cA3p4jTlaMeOtAKR/6AadanOPvKeg8VwgnHhOyfi0yClD0TZS/hi9xu12w4EzA/8NtHu0g6o4RDfcNjqN8l1AQ== + +"@parcel/watcher@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-1.11.0.tgz#a05ee752d47bf3627b77a64a6089404683edc255" + integrity sha512-1ySF0sH06jyhpaErW1UWC7BNgkAl6PJyBjuu2cLTW1o71J2iQqgGt95cbuqmfmjI3l0xYN+nauDFqHERaj7Z8A== + dependencies: + "@parcel/utils" "^1.11.0" + chokidar "^2.0.3" + +"@parcel/workers@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@parcel/workers/-/workers-1.11.0.tgz#7b8dcf992806f4ad2b6cecf629839c41c2336c59" + integrity sha512-USSjRAAQYsZFlv43FUPdD+jEGML5/8oLF0rUzPQTtK4q9kvaXr49F5ZplyLz5lox78cLZ0TxN2bIDQ1xhOkulQ== + dependencies: + "@parcel/utils" "^1.11.0" + physical-cpu-count "^2.0.0" + "@types/events@*": version "1.2.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" @@ -2709,13 +2787,13 @@ dateformat@^3.0.0: resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== -deasync@^0.1.13: - version "0.1.13" - resolved "https://registry.yarnpkg.com/deasync/-/deasync-0.1.13.tgz#815c2b69bbd1117cae570152cd895661c09f20ea" - integrity sha512-/6ngYM7AapueqLtvOzjv9+11N2fHDSrkxeMF1YPE20WIfaaawiBg+HZH1E5lHrcJxlKR42t6XPOEmMmqcAsU1g== +deasync@^0.1.14: + version "0.1.14" + resolved "https://registry.yarnpkg.com/deasync/-/deasync-0.1.14.tgz#232ea2252b443948cad033d792eb3b24b0a3d828" + integrity sha512-wN8sIuEqIwyQh72AG7oY6YQODCxIp1eXzEZlZznBuwDF8Q03Tdy9QNp1BNZXeadXoklNrw+Ip1fch+KXo/+ASw== dependencies: bindings "~1.2.1" - nan "^2.0.7" + node-addon-api "^1.6.0" debug-log@^1.0.1: version "1.0.1" @@ -3509,13 +3587,6 @@ fstream@^1.0.0, fstream@^1.0.2: mkdirp ">=0.5 0" rimraf "2" -fswatcher-child@^1.0.5: - version "1.1.1" - resolved "https://registry.yarnpkg.com/fswatcher-child/-/fswatcher-child-1.1.1.tgz#264dd95f9c4b5f8615327d7d7567884591846b9b" - integrity sha512-FVDjVhR71TkJ+ud6vnRwCHvCgK9drGRdimWcTLqw8iN88uL5tTX+/xrwigJdcuQGrWYo3TRw9gRzk9xqR0UPPQ== - dependencies: - chokidar "^2.0.3" - function-bind@^1.1.0, function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -3826,10 +3897,10 @@ hex-color-regex@^1.1.0: resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== -highlight.js@^9.0.0: - version "9.13.1" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.13.1.tgz#054586d53a6863311168488a0f58d6c505ce641e" - integrity sha512-Sc28JNQNDzaH6PORtRLMvif9RSn1mYuOoX3omVjnb0+HbpPygU2ALBI0R/wsiqCb4/fcp07Gdo8g+fhtFrQl6A== +highlight.js@9.12.0: + version "9.12.0" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e" + integrity sha1-5tnb5Xy+/mB1HwKvM2GVhwyQwB4= hmac-drbg@^1.0.0: version "1.0.1" @@ -4588,26 +4659,26 @@ lcid@^2.0.0: dependencies: invert-kv "^2.0.0" -lerna@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/lerna/-/lerna-3.6.0.tgz#b6616873fa038ee1dae514e04322c191ff71a369" - integrity sha512-iQFAgrgtv18SI5LtQBBca0WVeYvk2r8eYgiEQtcZBT63T5R9RVv+snsviIiOp0z6gD43tcyiWXiLvBdp1IY/Rg== +lerna@^3.8.5: + version "3.8.5" + resolved "https://registry.yarnpkg.com/lerna/-/lerna-3.8.5.tgz#30001989ccd44dca631c1a77eb4ec1238c4a6dfc" + integrity sha512-cPXU+4CHa0Hg9TBLQsLF7U9LssheakzD/zPQm7hXFjbqKrTx+p1QAgI/ehaY5CMqT4dPZUjOuR2zWI2hpBJaXQ== dependencies: - "@lerna/add" "^3.6.0" - "@lerna/bootstrap" "^3.6.0" - "@lerna/changed" "^3.6.0" - "@lerna/clean" "^3.6.0" + "@lerna/add" "^3.8.5" + "@lerna/bootstrap" "^3.8.5" + "@lerna/changed" "^3.8.5" + "@lerna/clean" "^3.8.5" "@lerna/cli" "^3.6.0" - "@lerna/create" "^3.6.0" - "@lerna/diff" "^3.6.0" - "@lerna/exec" "^3.6.0" - "@lerna/import" "^3.6.0" - "@lerna/init" "^3.6.0" - "@lerna/link" "^3.6.0" - "@lerna/list" "^3.6.0" - "@lerna/publish" "^3.6.0" - "@lerna/run" "^3.6.0" - "@lerna/version" "^3.6.0" + "@lerna/create" "^3.8.5" + "@lerna/diff" "^3.8.5" + "@lerna/exec" "^3.8.5" + "@lerna/import" "^3.8.5" + "@lerna/init" "^3.8.5" + "@lerna/link" "^3.8.5" + "@lerna/list" "^3.8.5" + "@lerna/publish" "^3.8.5" + "@lerna/run" "^3.8.5" + "@lerna/version" "^3.8.5" import-local "^1.0.0" libnpm "^2.0.1" @@ -5224,7 +5295,7 @@ mute-stream@0.0.7, mute-stream@~0.0.4: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= -nan@^2.0.7, nan@^2.9.2: +nan@^2.9.2: version "2.11.1" resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" integrity sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA== @@ -5260,6 +5331,11 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +node-addon-api@^1.6.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-1.6.2.tgz#d8aad9781a5cfc4132cc2fecdbdd982534265217" + integrity sha512-479Bjw9nTE5DdBSZZWprFryHGjUaQC31y1wHo19We/k0BZlrmhqQitWoUL0cD8+scljCbIUL+E58oRDEakdGGA== + node-fetch-npm@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/node-fetch-npm/-/node-fetch-npm-2.0.2.tgz#7258c9046182dca345b4208eda918daf33697ff7" @@ -5839,10 +5915,10 @@ parallel-transform@^1.1.0: inherits "^2.0.3" readable-stream "^2.1.5" -parcel-bundler@^1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/parcel-bundler/-/parcel-bundler-1.10.3.tgz#8502b40d3f23139093b25e82658f6060f025c024" - integrity sha512-Lj31fr5o2AZFbazghL/MrubzvJEXLwx24rd3MiR3lncmqCXbd5q0hgl1kpV6X+vRaN9/cSDR8G0lotmgl5OyZg== +parcel-bundler@^1.11.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/parcel-bundler/-/parcel-bundler-1.11.0.tgz#7e821a5246d7503aebf3c1bc279b59cbb8a3d4e3" + integrity sha512-H0w/Obx76vWiG+UtofznfcHZJBmd6JA5iCn7zrGBINyVAh+Nt/JLD6QDROghHLXfJkO4XyczsB+fO+nPbXlFfA== dependencies: "@babel/code-frame" "^7.0.0" "@babel/core" "^7.0.0" @@ -5856,6 +5932,12 @@ parcel-bundler@^1.10.3: "@babel/template" "^7.0.0" "@babel/traverse" "^7.0.0" "@babel/types" "^7.0.0" + "@iarna/toml" "^2.2.0" + "@parcel/fs" "^1.11.0" + "@parcel/logger" "^1.11.0" + "@parcel/utils" "^1.11.0" + "@parcel/watcher" "^1.11.0" + "@parcel/workers" "^1.11.0" ansi-to-html "^0.6.4" babylon-walk "^1.0.2" browserslist "^4.1.0" @@ -5865,14 +5947,12 @@ parcel-bundler@^1.10.3: commander "^2.11.0" cross-spawn "^6.0.4" cssnano "^4.0.0" - deasync "^0.1.13" + deasync "^0.1.14" dotenv "^5.0.0" dotenv-expand "^4.2.0" fast-glob "^2.2.2" filesize "^3.6.0" - fswatcher-child "^1.0.5" get-port "^3.2.0" - grapheme-breaker "^0.3.2" htmlnano "^0.1.9" is-glob "^4.0.0" is-url "^1.2.2" @@ -5883,10 +5963,8 @@ parcel-bundler@^1.10.3: node-forge "^0.7.1" node-libs-browser "^2.0.0" opn "^5.1.0" - ora "^2.1.0" - physical-cpu-count "^2.0.0" - postcss "^6.0.19" - postcss-value-parser "^3.3.0" + postcss "^7.0.5" + postcss-value-parser "^3.3.1" posthtml "^0.11.2" posthtml-parser "^0.4.0" posthtml-render "^1.1.3" @@ -5895,10 +5973,7 @@ parcel-bundler@^1.10.3: serialize-to-js "^1.1.1" serve-static "^1.12.4" source-map "0.6.1" - strip-ansi "^4.0.0" terser "^3.7.3" - toml "^2.3.3" - tomlify-j0.4 "^3.0.0" v8-compile-cache "^2.0.0" ws "^5.1.1" @@ -6545,7 +6620,7 @@ postcss-unique-selectors@^4.0.1: postcss "^7.0.0" uniqs "^2.0.0" -postcss-value-parser@^3.0.0, postcss-value-parser@^3.0.1, postcss-value-parser@^3.0.2, postcss-value-parser@^3.1.1, postcss-value-parser@^3.1.2, postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0: +postcss-value-parser@^3.0.0, postcss-value-parser@^3.0.1, postcss-value-parser@^3.0.2, postcss-value-parser@^3.1.1, postcss-value-parser@^3.1.2, postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== @@ -6569,15 +6644,6 @@ postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0 source-map "^0.5.6" supports-color "^3.2.3" -postcss@^6.0.19: - version "6.0.23" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" - integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== - dependencies: - chalk "^2.4.1" - source-map "^0.6.1" - supports-color "^5.4.0" - postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.2: version "7.0.5" resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.5.tgz#70e6443e36a6d520b0fd4e7593fcca3635ee9f55" @@ -6587,6 +6653,15 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.2: source-map "^0.6.1" supports-color "^5.5.0" +postcss@^7.0.5: + version "7.0.7" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.7.tgz#2754d073f77acb4ef08f1235c36c5721a7201614" + integrity sha512-HThWSJEPkupqew2fnuQMEI2YcTj/8gMV3n80cMdJsKxfIh5tHf7nM5JigNX6LxVMqo6zkgQNAI88hyFvBk41Pg== + dependencies: + chalk "^2.4.1" + source-map "^0.6.1" + supports-color "^5.5.0" + posthtml-parser@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/posthtml-parser/-/posthtml-parser-0.3.3.tgz#3fe986fca9f00c0f109d731ba590b192f26e776d" @@ -7162,6 +7237,13 @@ rimraf@2, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: dependencies: glob "^7.0.5" +rimraf@^2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" @@ -7812,7 +7894,7 @@ tar@^4: safe-buffer "^5.1.2" yallist "^3.0.2" -tar@^4.4.6: +tar@^4.4.6, tar@^4.4.8: version "4.4.8" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== @@ -7842,10 +7924,10 @@ temp-write@^3.4.0: temp-dir "^1.0.0" uuid "^3.0.1" -terser@^3.11.0: - version "3.11.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-3.11.0.tgz#60782893e1f4d6788acc696351f40636d0e37af0" - integrity sha512-5iLMdhEPIq3zFWskpmbzmKwMQixKmTYwY3Ox9pjtSklBLnHiuQ0GKJLhL1HSYtyffHM3/lDIFBnb82m9D7ewwQ== +terser@^3.14.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-3.14.1.tgz#cc4764014af570bc79c79742358bd46926018a32" + integrity sha512-NSo3E99QDbYSMeJaEk9YW2lTg3qS9V0aKGlb+PlOrei1X02r1wSBHCNX/O+yeTRFSWPKPIGj6MqvvdqV4rnVGw== dependencies: commander "~2.17.1" source-map "~0.6.1" @@ -7952,16 +8034,6 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" -toml@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/toml/-/toml-2.3.3.tgz#8d683d729577cb286231dfc7a8affe58d31728fb" - integrity sha512-O7L5hhSQHxuufWUdcTRPfuTh3phKfAZ/dqfxZFoxPCj2RYmpaSGLEIs016FCXItQwNr08yefUB5TSjzRYnajTA== - -tomlify-j0.4@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/tomlify-j0.4/-/tomlify-j0.4-3.0.0.tgz#99414d45268c3a3b8bf38be82145b7bba34b7473" - integrity sha512-2Ulkc8T7mXJ2l0W476YC/A209PR38Nw8PuaCNtk9uI3t1zzFdGQeWYGQvmj2PZkVvRC/Yoi4xQKMRnWc/N29tQ== - tough-cookie@~2.4.3: version "2.4.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" @@ -8002,10 +8074,10 @@ tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== -tslint@^5.11.0: - version "5.11.0" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.11.0.tgz#98f30c02eae3cde7006201e4c33cb08b48581eed" - integrity sha1-mPMMAurjzecAYgHkwzywi0hYHu0= +tslint@^5.12.0: + version "5.12.0" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.12.0.tgz#47f2dba291ed3d580752d109866fb640768fca36" + integrity sha512-CKEcH1MHUBhoV43SA/Jmy1l24HJJgI0eyLbBNSRyFlsQvb9v6Zdq+Nz2vEOH00nC5SUx4SneJ59PZUS/ARcokQ== dependencies: babel-code-frame "^6.22.0" builtin-modules "^1.1.1" @@ -8061,10 +8133,10 @@ typedoc-default-themes@^0.5.0: resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.5.0.tgz#6dc2433e78ed8bea8e887a3acde2f31785bd6227" integrity sha1-bcJDPnjti+qOiHo6zeLzF4W9Yic= -typedoc@^0.13.0: - version "0.13.0" - resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.13.0.tgz#9efdf352bd54873955cd161bd4b75f24a8c59dde" - integrity sha512-jQWtvPcV+0fiLZAXFEe70v5gqjDO6pJYJz4mlTtmGJeW2KRoIU/BEfktma6Uj8Xii7UakuZjbxFewl3UYOkU/w== +typedoc@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.14.0.tgz#f7de2f3f1109b92eeafd6cbff269e28a86c8079e" + integrity sha512-9DOYWO6O02YGZfbNOrELtmpQF4Eba/6AfNQNt46iRuIokoEq1Axdz9Ae/XjgdoXsM2ShGlDZsAO36BwRVz/Nmw== dependencies: "@types/fs-extra" "^5.0.3" "@types/handlebars" "^4.0.38" @@ -8075,21 +8147,16 @@ typedoc@^0.13.0: "@types/shelljs" "^0.8.0" fs-extra "^7.0.0" handlebars "^4.0.6" - highlight.js "^9.0.0" + highlight.js "9.12.0" lodash "^4.17.10" marked "^0.4.0" minimatch "^3.0.0" progress "^2.0.0" shelljs "^0.8.2" typedoc-default-themes "^0.5.0" - typescript "3.1.x" - -typescript@3.1.x: - version "3.1.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.3.tgz#01b70247a6d3c2467f70c45795ef5ea18ce191d5" - integrity sha512-+81MUSyX+BaSo+u2RbozuQk/UWx6hfG0a5gHu4ANEM4sU96XbuIyAB+rWBW1u70c6a5QuZfuYICn3s2UjuHUpA== + typescript "3.2.x" -typescript@^3.2.2: +typescript@3.2.x, typescript@^3.2.2: version "3.2.2" resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.2.tgz#fe8101c46aa123f8353523ebdcf5730c2ae493e5" integrity sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg== From e201ca8dbcbe73d79c0ae70fc748baacb4872572 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 15:24:34 +0000 Subject: [PATCH 206/333] refactor(rstream): replace Subscription.NEXT_ID w/ nextID() util --- packages/rstream/src/from/atom.ts | 25 +++++++------ packages/rstream/src/from/event.ts | 15 +++++--- packages/rstream/src/from/interval.ts | 27 ++++++++------ packages/rstream/src/from/iterable.ts | 6 +-- packages/rstream/src/from/promise.ts | 37 ++++++++++--------- packages/rstream/src/from/raf.ts | 5 +-- packages/rstream/src/from/view.ts | 4 +- packages/rstream/src/from/worker.ts | 35 ++++++++++-------- packages/rstream/src/pubsub.ts | 4 +- packages/rstream/src/stream-merge.ts | 4 +- packages/rstream/src/stream-sync.ts | 4 +- packages/rstream/src/stream.ts | 4 +- packages/rstream/src/subs/resolve.ts | 4 +- .../rstream/src/subs/sidechain-partition.ts | 4 +- packages/rstream/src/subs/sidechain-toggle.ts | 4 +- packages/rstream/src/subs/timeout.ts | 5 ++- packages/rstream/src/subs/tunnel.ts | 3 +- packages/rstream/src/subscription.ts | 8 ++-- 18 files changed, 107 insertions(+), 91 deletions(-) diff --git a/packages/rstream/src/from/atom.ts b/packages/rstream/src/from/atom.ts index 7b4421bf11..4918b1aea7 100644 --- a/packages/rstream/src/from/atom.ts +++ b/packages/rstream/src/from/atom.ts @@ -1,7 +1,7 @@ import { Predicate2 } from "@thi.ng/api/api"; import { ReadonlyAtom } from "@thi.ng/atom/api"; - import { Stream } from "../stream"; +import { nextID } from "../utils/idgen"; /** * Yields stream of value changes in given atom / cursor. Attaches watch @@ -39,13 +39,16 @@ export const fromAtom = ( changed?: Predicate2 ): Stream => - new Stream((stream) => { - changed = changed || ((a, b) => a !== b); - atom.addWatch(stream.id, (_, prev, curr) => { - if (changed(prev, curr)) { - stream.next(curr); - } - }); - emitFirst && stream.next(atom.deref()); - return () => atom.removeWatch(stream.id); - }); + new Stream( + (stream) => { + changed = changed || ((a, b) => a !== b); + atom.addWatch(stream.id, (_, prev, curr) => { + if (changed(prev, curr)) { + stream.next(curr); + } + }); + emitFirst && stream.next(atom.deref()); + return () => atom.removeWatch(stream.id); + }, + `atom-${nextID()}` + ); diff --git a/packages/rstream/src/from/event.ts b/packages/rstream/src/from/event.ts index 2da946a196..944649dab1 100644 --- a/packages/rstream/src/from/event.ts +++ b/packages/rstream/src/from/event.ts @@ -1,5 +1,5 @@ import { Stream } from "../stream"; -import { Subscription } from "../subscription"; +import { nextID } from "../utils/idgen"; /** * Creates a new stream of DOM events attached to given element / event @@ -15,8 +15,11 @@ export const fromEvent = ( name: string, opts: boolean | AddEventListenerOptions = false ) => - new Stream((stream) => { - let listener = (e) => stream.next(e); - src.addEventListener(name, listener, opts); - return () => src.removeEventListener(name, listener, opts); - }, `event-${name}-${Subscription.NEXT_ID++}`); + new Stream( + (stream) => { + let listener = (e) => stream.next(e); + src.addEventListener(name, listener, opts); + return () => src.removeEventListener(name, listener, opts); + }, + `event-${name}-${nextID()}` + ); diff --git a/packages/rstream/src/from/interval.ts b/packages/rstream/src/from/interval.ts index a55cfc25ce..6336c1108f 100644 --- a/packages/rstream/src/from/interval.ts +++ b/packages/rstream/src/from/interval.ts @@ -1,5 +1,5 @@ import { Stream } from "../stream"; -import { Subscription } from "../subscription"; +import { nextID } from "../utils/idgen"; /** * Returns a new `Stream` which emits a monotonically increasing counter @@ -12,15 +12,18 @@ import { Subscription } from "../subscription"; */ export const fromInterval = (delay: number, count = Infinity) => - new Stream((stream) => { - let i = 0; - stream.next(i++); - let id = setInterval(() => { + new Stream( + (stream) => { + let i = 0; stream.next(i++); - if (--count <= 0) { - clearInterval(id); - stream.done(); - } - }, delay); - return () => clearInterval(id); - }, `interval-${Subscription.NEXT_ID++}`); + let id = setInterval(() => { + stream.next(i++); + if (--count <= 0) { + clearInterval(id); + stream.done(); + } + }, delay); + return () => clearInterval(id); + }, + `interval-${nextID()}` + ); diff --git a/packages/rstream/src/from/iterable.ts b/packages/rstream/src/from/iterable.ts index ea4fa13eb1..401ae421d6 100644 --- a/packages/rstream/src/from/iterable.ts +++ b/packages/rstream/src/from/iterable.ts @@ -1,5 +1,5 @@ import { Stream } from "../stream"; -import { Subscription } from "../subscription"; +import { nextID } from "../utils/idgen"; /** * Creates a new `Stream` of given iterable which asynchronously calls @@ -29,7 +29,7 @@ export const fromIterable = }, delay); return () => clearInterval(id); }, - `iterable-${Subscription.NEXT_ID++}` + `iterable-${nextID()}` ); /** @@ -52,5 +52,5 @@ export const fromIterableSync = close && stream.done(); return null; }, - `iterable-${Subscription.NEXT_ID++}` + `iterable-${nextID()}` ); diff --git a/packages/rstream/src/from/promise.ts b/packages/rstream/src/from/promise.ts index 0cf5af1cd8..5f7052d738 100644 --- a/packages/rstream/src/from/promise.ts +++ b/packages/rstream/src/from/promise.ts @@ -1,6 +1,6 @@ import { State } from "../api"; import { Stream } from "../stream"; -import { Subscription } from "../subscription"; +import { nextID } from "../utils/idgen"; /** * Yields a single-value stream of the resolved promise and then @@ -20,21 +20,24 @@ export const fromPromise = isError = true; } ); - return new Stream((stream) => { - src.then( - (x) => { - if (!canceled && stream.getState() < State.DONE) { - if (isError) { - stream.error(err); - err = null; - } else { - stream.next(x); - stream.done(); + return new Stream( + (stream) => { + src.then( + (x) => { + if (!canceled && stream.getState() < State.DONE) { + if (isError) { + stream.error(err); + err = null; + } else { + stream.next(x); + stream.done(); + } } - } - }, - (e) => stream.error(e) - ); - return () => { canceled = true; }; - }, `promise-${Subscription.NEXT_ID++}`); + }, + (e) => stream.error(e) + ); + return () => { canceled = true; }; + }, + `promise-${nextID()}` + ); }; diff --git a/packages/rstream/src/from/raf.ts b/packages/rstream/src/from/raf.ts index 442eba579b..5709308fef 100644 --- a/packages/rstream/src/from/raf.ts +++ b/packages/rstream/src/from/raf.ts @@ -1,7 +1,6 @@ import { isNode } from "@thi.ng/checks/is-node"; - import { Stream } from "../stream"; -import { Subscription } from "../subscription"; +import { nextID } from "../utils/idgen"; import { fromInterval } from "./interval"; /** @@ -27,5 +26,5 @@ export const fromRAF = () => let id = requestAnimationFrame(loop); return () => (isActive = false, cancelAnimationFrame(id)); }, - `raf-${Subscription.NEXT_ID++}` + `raf-${nextID()}` ); diff --git a/packages/rstream/src/from/view.ts b/packages/rstream/src/from/view.ts index 738e3efaf5..5727abf681 100644 --- a/packages/rstream/src/from/view.ts +++ b/packages/rstream/src/from/view.ts @@ -2,8 +2,8 @@ import { Predicate2 } from "@thi.ng/api/api"; import { ReadonlyAtom, ViewTransform } from "@thi.ng/atom/api"; import { View } from "@thi.ng/atom/view"; import { Path } from "@thi.ng/paths"; - import { Stream } from "../stream"; +import { nextID } from "../utils/idgen"; /** * Similar to `fromAtom()`, but creates an eager derived view for a @@ -64,5 +64,5 @@ export const fromView = ( ); return () => (isActive = false, view.release()); }, - id + id || `view-${nextID()}` ); diff --git a/packages/rstream/src/from/worker.ts b/packages/rstream/src/from/worker.ts index 452d570d59..83a7993908 100644 --- a/packages/rstream/src/from/worker.ts +++ b/packages/rstream/src/from/worker.ts @@ -1,5 +1,6 @@ import { DEBUG } from "../api"; import { Stream } from "../stream"; +import { nextID } from "../utils/idgen"; import { makeWorker } from "../utils/worker"; /** @@ -20,22 +21,26 @@ import { makeWorker } from "../utils/worker"; * * @param worker * @param terminate + * @param id */ export const fromWorker = - (worker: Worker | Blob | string, terminate = true) => { + (worker: Worker | Blob | string, terminate = true, id?: string) => { const _worker = makeWorker(worker); - return new Stream((stream) => { - const ml = (e: MessageEvent) => { stream.next(e.data); }; - const el = (e: MessageEvent) => { stream.error(e.data); }; - _worker.addEventListener("message", ml); - _worker.addEventListener("error", el); - return () => { - _worker.removeEventListener("message", ml); - _worker.removeEventListener("error", el); - if (terminate) { - DEBUG && console.log("terminating worker", _worker); - _worker.terminate(); - } - }; - }); + return new Stream( + (stream) => { + const ml = (e: MessageEvent) => { stream.next(e.data); }; + const el = (e: MessageEvent) => { stream.error(e.data); }; + _worker.addEventListener("message", ml); + _worker.addEventListener("error", el); + return () => { + _worker.removeEventListener("message", ml); + _worker.removeEventListener("error", el); + if (terminate) { + DEBUG && console.log("terminating worker", _worker); + _worker.terminate(); + } + }; + }, + id || `worker-${nextID()}` + ); }; diff --git a/packages/rstream/src/pubsub.ts b/packages/rstream/src/pubsub.ts index 04815beaa2..2a6253fd39 100644 --- a/packages/rstream/src/pubsub.ts +++ b/packages/rstream/src/pubsub.ts @@ -2,9 +2,9 @@ import { Predicate2 } from "@thi.ng/api/api"; import { EquivMap } from "@thi.ng/associative/equiv-map"; import { unsupported } from "@thi.ng/errors/unsupported"; import { Transducer } from "@thi.ng/transducers/api"; - import { DEBUG, ISubscriber } from "./api"; import { Subscription } from "./subscription"; +import { nextID } from "./utils/idgen"; export interface PubSubOpts { /** @@ -56,7 +56,7 @@ export class PubSub extends Subscription { constructor(opts?: PubSubOpts) { opts = opts || >{}; - super(null, opts.xform, null, opts.id || `pubsub-${Subscription.NEXT_ID++}`); + super(null, opts.xform, null, opts.id || `pubsub-${nextID()}`); this.topicfn = opts.topic; this.topics = new EquivMap>(null, { equiv: opts.equiv }); } diff --git a/packages/rstream/src/stream-merge.ts b/packages/rstream/src/stream-merge.ts index a5696007f5..d85de9b07b 100644 --- a/packages/rstream/src/stream-merge.ts +++ b/packages/rstream/src/stream-merge.ts @@ -1,8 +1,8 @@ import { IID } from "@thi.ng/api/api"; import { Transducer } from "@thi.ng/transducers/api"; - import { ISubscribable, State } from "./api"; import { Subscription } from "./subscription"; +import { nextID } from "./utils/idgen"; export interface StreamMergeOpts extends IID { /** @@ -78,7 +78,7 @@ export class StreamMerge extends Subscription { constructor(opts?: Partial>) { opts = opts || {}; - super(null, opts.xform, null, opts.id || `streammerge-${Subscription.NEXT_ID++}`); + super(null, opts.xform, null, opts.id || `streammerge-${nextID()}`); this.sources = new Map(); this.autoClose = opts.close !== false; if (opts.src) { diff --git a/packages/rstream/src/stream-sync.ts b/packages/rstream/src/stream-sync.ts index be3a4be463..9e84af3855 100644 --- a/packages/rstream/src/stream-sync.ts +++ b/packages/rstream/src/stream-sync.ts @@ -5,9 +5,9 @@ import { comp } from "@thi.ng/transducers/func/comp"; import { labeled } from "@thi.ng/transducers/xform/labeled"; import { mapVals } from "@thi.ng/transducers/xform/map-vals"; import { partitionSync } from "@thi.ng/transducers/xform/partition-sync"; - import { ISubscribable, State } from "./api"; import { Subscription } from "./subscription"; +import { nextID } from "./utils/idgen"; export interface StreamSyncOpts extends IID { /** @@ -134,7 +134,7 @@ export class StreamSync extends Subscription { if (opts.xform) { xform = comp(xform, opts.xform); } - super(null, xform, null, opts.id || `streamsync-${Subscription.NEXT_ID++}`); + super(null, xform, null, opts.id || `streamsync-${nextID()}`); this.sources = new Map(); this.realSourceIDs = new Map(); this.invRealSourceIDs = new Map(); diff --git a/packages/rstream/src/stream.ts b/packages/rstream/src/stream.ts index b3f70a97e8..e18066a007 100644 --- a/packages/rstream/src/stream.ts +++ b/packages/rstream/src/stream.ts @@ -1,7 +1,6 @@ import { isString } from "@thi.ng/checks/is-string"; import { illegalArity } from "@thi.ng/errors/illegal-arity"; import { Transducer } from "@thi.ng/transducers/api"; - import { DEBUG, IStream, @@ -10,6 +9,7 @@ import { StreamSource } from "./api"; import { Subscription } from "./subscription"; +import { nextID } from "./utils/idgen"; /** * Creates a new `Stream` instance, optionally with given `StreamSource` @@ -97,7 +97,7 @@ export class Stream extends Subscription default: illegalArity(args.length); } - super(null, null, null, id || `stream-${Subscription.NEXT_ID++}`); + super(null, null, null, id || `stream-${nextID()}`); this.src = src; } diff --git a/packages/rstream/src/subs/resolve.ts b/packages/rstream/src/subs/resolve.ts index e544fd5882..8973c7d873 100644 --- a/packages/rstream/src/subs/resolve.ts +++ b/packages/rstream/src/subs/resolve.ts @@ -1,7 +1,7 @@ import { IID } from "@thi.ng/api/api"; - import { __State, DEBUG, State } from "../api"; import { Subscription } from "../subscription"; +import { nextID } from "../utils/idgen"; export interface ResolverOpts extends IID { /** @@ -40,7 +40,7 @@ export class Resolver extends Subscription, T> { protected fail: (e: any) => void; constructor(opts: Partial = {}) { - super(null, null, null, opts.id || `resolve-${Subscription.NEXT_ID++}`); + super(null, null, null, opts.id || `resolve-${nextID()}`); this.fail = opts.fail; } diff --git a/packages/rstream/src/subs/sidechain-partition.ts b/packages/rstream/src/subs/sidechain-partition.ts index a3dab3abaf..f39c331e4a 100644 --- a/packages/rstream/src/subs/sidechain-partition.ts +++ b/packages/rstream/src/subs/sidechain-partition.ts @@ -1,7 +1,7 @@ import { Predicate } from "@thi.ng/api/api"; - import { ISubscribable, State } from "../api"; import { Subscription } from "../subscription"; +import { nextID } from "../utils/idgen"; /** * Buffers values from `src` until side chain fires, then emits buffer @@ -40,7 +40,7 @@ export class SidechainPartition extends Subscription { buf: A[]; constructor(side: ISubscribable, pred?: Predicate, id?: string) { - super(null, null, null, id || `sidepart-${Subscription.NEXT_ID++}`); + super(null, null, null, id || `sidepart-${nextID()}`); this.buf = []; const $this = this; pred = pred || (() => true); diff --git a/packages/rstream/src/subs/sidechain-toggle.ts b/packages/rstream/src/subs/sidechain-toggle.ts index 3cb230fb00..5c0aac4e00 100644 --- a/packages/rstream/src/subs/sidechain-toggle.ts +++ b/packages/rstream/src/subs/sidechain-toggle.ts @@ -1,7 +1,7 @@ import { Predicate } from "@thi.ng/api/api"; - import { ISubscribable } from "../api"; import { Subscription } from "../subscription"; +import { nextID } from "../utils/idgen"; /** * Filters values from input based on values received from side chain. @@ -43,7 +43,7 @@ export class SidechainToggle extends Subscription { isActive: boolean; constructor(side: ISubscribable, initial = true, pred?: Predicate, id?: string) { - super(null, null, null, id || `sidetoggle-${Subscription.NEXT_ID++}`); + super(null, null, null, id || `sidetoggle-${nextID()}`); this.isActive = initial; const $this = this; pred = pred || (() => true); diff --git a/packages/rstream/src/subs/timeout.ts b/packages/rstream/src/subs/timeout.ts index 8ad52d2855..f656e82fbd 100644 --- a/packages/rstream/src/subs/timeout.ts +++ b/packages/rstream/src/subs/timeout.ts @@ -1,5 +1,6 @@ -import { State } from "../api" +import { State } from "../api"; import { Subscription } from "../subscription"; +import { nextID } from "../utils/idgen"; /** * A subscription that emits an arbitrary error object after a given @@ -29,7 +30,7 @@ class Timeout extends Subscription { protected resetTimeout: boolean; constructor(timeoutMs: number, error?: any, resetTimeout = false, id?: string) { - super(null, null, null, id || `timeout-${Subscription.NEXT_ID++}`); + super(null, null, null, id || `timeout-${nextID()}`); this.timeoutMs = timeoutMs; this.errorObj = error; this.resetTimeout = resetTimeout; diff --git a/packages/rstream/src/subs/tunnel.ts b/packages/rstream/src/subs/tunnel.ts index 5dee60cdb2..d5b0b2bac9 100644 --- a/packages/rstream/src/subs/tunnel.ts +++ b/packages/rstream/src/subs/tunnel.ts @@ -1,5 +1,6 @@ import { DEBUG, State } from "../api"; import { Subscription } from "../subscription"; +import { nextID } from "../utils/idgen"; import { makeWorker } from "../utils/worker"; export interface TunnelOpts { @@ -69,7 +70,7 @@ export class Tunnel extends Subscription { index: number; constructor(opts: TunnelOpts) { - super(null, null, null, opts.id || `tunnel-${Subscription.NEXT_ID++}`); + super(null, null, null, opts.id || `tunnel-${nextID()}`); this.src = opts.src; this.workers = new Array(opts.maxWorkers || 1); this.transferables = opts.transferables; diff --git a/packages/rstream/src/subscription.ts b/packages/rstream/src/subscription.ts index c61cadcf8f..64a7dc9ec6 100644 --- a/packages/rstream/src/subscription.ts +++ b/packages/rstream/src/subscription.ts @@ -8,7 +8,6 @@ import { Reducer, Transducer } from "@thi.ng/transducers/api"; import { comp } from "@thi.ng/transducers/func/comp"; import { isReduced, unreduced } from "@thi.ng/transducers/reduced"; import { push } from "@thi.ng/transducers/rfn/push"; - import { __State, DEBUG, @@ -16,6 +15,7 @@ import { ISubscriber, State } from "./api"; +import { nextID } from "./utils/idgen"; /** * Creates a new `Subscription` instance, the fundamental datatype & @@ -64,8 +64,6 @@ export class Subscription implements ISubscriber, ISubscribable { - static NEXT_ID = 0; - id: string; protected parent: ISubscribable; @@ -77,7 +75,7 @@ export class Subscription implements constructor(sub?: ISubscriber, xform?: Transducer, parent?: ISubscribable, id?: string) { this.parent = parent; - this.id = id || `sub-${Subscription.NEXT_ID++}`; + this.id = id || `sub-${nextID()}`; this.last = SEMAPHORE; this.subs = []; if (sub) { @@ -113,7 +111,7 @@ export class Subscription implements case 2: if (isFunction(args[0])) { xform = args[0]; - id = args[1] || `xform-${Subscription.NEXT_ID++}`; + id = args[1] || `xform-${nextID()}`; } else { sub = args[0]; if (isFunction(args[1])) { From d1e275bd718f2889139c13cb855563cac808fc89 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 5 Jan 2019 15:27:30 +0000 Subject: [PATCH 207/333] fix(rstream): avoid Subscription ctor to workaround parceljs build issue - use `subscription()` factory instead of `new Subscription` - solves issue w/ parcel's scope hoisting build flag --- packages/rstream/src/pubsub.ts | 4 ++-- packages/rstream/src/subscription.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/rstream/src/pubsub.ts b/packages/rstream/src/pubsub.ts index 2a6253fd39..3eab862b94 100644 --- a/packages/rstream/src/pubsub.ts +++ b/packages/rstream/src/pubsub.ts @@ -3,7 +3,7 @@ import { EquivMap } from "@thi.ng/associative/equiv-map"; import { unsupported } from "@thi.ng/errors/unsupported"; import { Transducer } from "@thi.ng/transducers/api"; import { DEBUG, ISubscriber } from "./api"; -import { Subscription } from "./subscription"; +import { Subscription, subscription } from "./subscription"; import { nextID } from "./utils/idgen"; export interface PubSubOpts { @@ -84,7 +84,7 @@ export class PubSub extends Subscription { subscribeTopic(topicID: any, sub: any, id?: string): Subscription { let t = this.topics.get(topicID); if (!t) { - this.topics.set(topicID, t = new Subscription()); + this.topics.set(topicID, t = subscription()); } return t.subscribe(sub, id); } diff --git a/packages/rstream/src/subscription.ts b/packages/rstream/src/subscription.ts index 64a7dc9ec6..4ede83e114 100644 --- a/packages/rstream/src/subscription.ts +++ b/packages/rstream/src/subscription.ts @@ -130,7 +130,7 @@ export class Subscription implements if (implementsFunction(sub, "subscribe")) { sub.parent = this; } else { - sub = new Subscription(sub, xform, this, id); + sub = subscription(sub, xform, this, id); } if (this.last !== SEMAPHORE) { sub.next(this.last); From 92bce73d4ff94416800aa71a96c6f285ea525848 Mon Sep 17 00:00:00 2001 From: Arthur Carabott Date: Sun, 6 Jan 2019 16:15:48 +0000 Subject: [PATCH 208/333] fix(vectors): fix NaNs in Mat23.scaleWithCenter lack of 0 mat index caused incorrect indexing into point --- packages/vectors/src/mat23.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vectors/src/mat23.ts b/packages/vectors/src/mat23.ts index f7e3683be9..dbd72e5654 100644 --- a/packages/vectors/src/mat23.ts +++ b/packages/vectors/src/mat23.ts @@ -192,7 +192,7 @@ export class Mat23 implements } static scaleWithCenter(p: Readonly, sx: number, sy = sx) { - return new Mat23(scaleWithCenter23([], p.buf, sx, sy, p.i, p.s)); + return new Mat23(scaleWithCenter23([], p.buf, sx, sy, 0, p.i, p.s)); } static translation(v: Readonly): Mat23; From 4be67c59611539fb6a226a6606473a6926e2c228 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 7 Jan 2019 01:40:25 +0000 Subject: [PATCH 209/333] build: prep api, atom, bench, binary, checks, equiv, errors, paths for multi outputs - update tsconfig files for ES6 module output - update build scripts in these 8 modules - update atom: Cursor/View NEXT_ID, replace w/ nextID() helper fn - update various tests - update .*ignore files --- .gitignore | 1 + packages/api/.npmignore | 9 +- packages/api/package.json | 22 ++- packages/api/src/decorators/deprecated.ts | 2 +- packages/api/test/index.ts | 1 + packages/api/test/tsconfig.json | 4 +- packages/api/tsconfig.json | 4 +- packages/atom/.npmignore | 8 +- packages/atom/package.json | 28 +++- packages/atom/src/atom.ts | 6 +- packages/atom/src/cursor.ts | 7 +- packages/atom/src/history.ts | 6 +- packages/atom/src/idgen.ts | 3 + packages/atom/src/view.ts | 6 +- packages/atom/test/atom.ts | 12 +- packages/atom/test/cursor.ts | 10 +- packages/atom/test/index.ts | 4 + packages/atom/test/tsconfig.json | 3 +- packages/atom/test/view.ts | 30 ++-- packages/atom/tsconfig.json | 3 +- packages/bench/.npmignore | 8 +- packages/bench/package.json | 25 ++- packages/bench/test/tsconfig.json | 6 +- packages/bench/tsconfig.json | 6 +- packages/binary/package.json | 15 +- packages/binary/test/tsconfig.json | 6 +- packages/binary/tsconfig.json | 6 +- packages/checks/.npmignore | 8 +- packages/checks/package.json | 22 ++- packages/checks/test/index.ts | 188 +++++++++++----------- packages/checks/test/tsconfig.json | 4 +- packages/checks/tsconfig.json | 4 +- packages/equiv/.npmignore | 8 +- packages/equiv/package.json | 28 +++- packages/equiv/test/index.ts | 136 ++++++++-------- packages/equiv/test/tsconfig.json | 6 +- packages/equiv/tsconfig.json | 6 +- packages/errors/.npmignore | 8 +- packages/errors/package.json | 22 ++- packages/errors/test/tsconfig.json | 6 +- packages/errors/tsconfig.json | 6 +- packages/paths/.npmignore | 8 +- packages/paths/package.json | 26 ++- packages/paths/test/index.ts | 30 ++-- packages/paths/test/tsconfig.json | 6 +- packages/paths/tsconfig.json | 6 +- scripts/minify-module | 14 ++ tsconfig.json | 5 +- 48 files changed, 476 insertions(+), 312 deletions(-) create mode 100644 packages/api/test/index.ts create mode 100644 packages/atom/src/idgen.ts create mode 100644 packages/atom/test/index.ts create mode 100755 scripts/minify-module diff --git a/.gitignore b/.gitignore index 4641eed96e..176e6402e9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules +.cache .nyc_output coverage build diff --git a/packages/api/.npmignore b/packages/api/.npmignore index 478163840f..756c6f6ea9 100644 --- a/packages/api/.npmignore +++ b/packages/api/.npmignore @@ -1,9 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output -*.tgz -*.html +tsconfig.json diff --git a/packages/api/package.json b/packages/api/package.json index e4585050a9..5486ba7ffa 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -2,7 +2,8 @@ "name": "@thi.ng/api", "version": "4.2.4", "description": "Common, generic types & interfaces for thi.ng projects", - "main": "./index.js", + "main": "./lib/index.js", + "module": "./index.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +13,16 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc decorators mixins", + "build": "yarn clean && yarn build:es6 && yarn build:parcel && yarn build:parcel:min", + "build:es6": "tsc --declaration", + "build:parcel:min": "parcel build --global thing_api -o index.min.js -d lib --experimental-scope-hoisting src/index.ts", + "build:parcel": "parcel build --global thing_api -d lib --no-minify --experimental-scope-hoisting src/index.ts && prettier --write lib/index.js", + "build:gzip": "gzip -c lib/index.min.js > lib/index.min.js.gz", + "clean": "rimraf *.js *.d.ts .cache .nyc_output build coverage doc lib", + "test": "rimraf build && parcel build -d build --no-cache --no-minify --no-source-maps test/index.ts && nyc mocha build/index.js", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -42,5 +47,12 @@ ], "publishConfig": { "access": "public" + }, + "browserslist": [ + "since 2018-07" + ], + "browser": { + "process": false, + "setTimeout": false } } \ No newline at end of file diff --git a/packages/api/src/decorators/deprecated.ts b/packages/api/src/decorators/deprecated.ts index e3a918bb37..da6650fa42 100644 --- a/packages/api/src/decorators/deprecated.ts +++ b/packages/api/src/decorators/deprecated.ts @@ -1,4 +1,4 @@ -import { illegalArgs } from "@thi.ng/errors"; +import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; /** * Method property decorator factory. Augments original method with diff --git a/packages/api/test/index.ts b/packages/api/test/index.ts new file mode 100644 index 0000000000..6a03f273cd --- /dev/null +++ b/packages/api/test/index.ts @@ -0,0 +1 @@ +export * from "./mixins"; diff --git a/packages/api/test/tsconfig.json b/packages/api/test/tsconfig.json index 13d45669e5..c93bb84899 100644 --- a/packages/api/test/tsconfig.json +++ b/packages/api/test/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", diff --git a/packages/api/tsconfig.json b/packages/api/tsconfig.json index f6c291a0a0..bcf03f18b4 100644 --- a/packages/api/tsconfig.json +++ b/packages/api/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" diff --git a/packages/atom/.npmignore b/packages/atom/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/atom/.npmignore +++ b/packages/atom/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/atom/package.json b/packages/atom/package.json index e55b7e9662..307e8b6c87 100644 --- a/packages/atom/package.json +++ b/packages/atom/package.json @@ -1,8 +1,9 @@ { "name": "@thi.ng/atom", "version": "1.5.8", - "description": "Mutable wrapper for immutable values", - "main": "./index.js", + "description": "Mutable wrappers for nested immutable values w/ optional undo/redo history", + "module": "./index.js", + "main": "./lib/index.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +13,16 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:parcel && yarn build:parcel:min", + "build:es6": "tsc --declaration", + "build:parcel:min": "parcel build --global thing_atom -o index.min.js -d lib --experimental-scope-hoisting src/index.ts", + "build:parcel": "parcel build --global thing_atom -d lib --no-minify --experimental-scope-hoisting src/index.ts && prettier --write lib/index.js", + "build:gzip": "gzip -c lib/index.min.js > lib/index.min.js.gz", + "clean": "rimraf *.js *.d.ts .cache .nyc_output build coverage doc lib", + "test": "rimraf build && parcel build -d build --no-cache --no-minify --no-source-maps test/index.ts && nyc mocha build/index.js", "cover": "yarn test && nyc report --reporter=lcov", "doc": "typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -35,15 +40,24 @@ "@thi.ng/paths": "^1.6.6" }, "keywords": [ + "derived views", "cursor", - "datastructure", + "data structure", "ES6", "history", "immutable", + "redo", "typescript", "undo" ], "publishConfig": { "access": "public" + }, + "browserslist": [ + "since 2018-07" + ], + "browser": { + "process": false, + "setTimeout": false } } \ No newline at end of file diff --git a/packages/atom/src/atom.ts b/packages/atom/src/atom.ts index 888d2226cc..2f9bdd0886 100644 --- a/packages/atom/src/atom.ts +++ b/packages/atom/src/atom.ts @@ -72,19 +72,19 @@ export class Atom implements // mixin stub /* istanbul ignore next */ - addWatch(id: string, fn: Watch) { + addWatch(_: string, __: Watch) { return false; } // mixin stub /* istanbul ignore next */ - removeWatch(id: string) { + removeWatch(_: string) { return false; } // mixin stub /* istanbul ignore next */ - notifyWatches(oldState: T, newState: T) { } + notifyWatches(_: T, __: T) { } addView(path: Path, tx?: ViewTransform, lazy = true): IView { return new View(this, path, tx, lazy); diff --git a/packages/atom/src/cursor.ts b/packages/atom/src/cursor.ts index 04e74535d7..713be975ad 100644 --- a/packages/atom/src/cursor.ts +++ b/packages/atom/src/cursor.ts @@ -4,7 +4,6 @@ import { isFunction } from "@thi.ng/checks/is-function"; import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; import { illegalArity } from "@thi.ng/errors/illegal-arity"; import { getter, Path, setter } from "@thi.ng/paths"; - import { CursorOpts, IAtom, @@ -13,9 +12,9 @@ import { ViewTransform } from "./api"; import { Atom } from "./atom"; +import { nextID } from "./idgen"; import { View } from "./view"; - /** * A cursor provides read/write access to a path location within a * nested parent state (Atom or another Cursor). Cursors behave like @@ -46,8 +45,6 @@ export class Cursor implements IID, IRelease { - static NEXT_ID = 0; - readonly id: string; parent: IAtom; @@ -89,7 +86,7 @@ export class Cursor implements illegalArity(args.length); } this.parent = parent; - this.id = id || `cursor-${Cursor.NEXT_ID++}`; + this.id = id || `cursor-${nextID()}`; this.selfUpdate = false; if (!lookup || !update) { illegalArgs(); diff --git a/packages/atom/src/history.ts b/packages/atom/src/history.ts index fe473c38ce..9f04b70f4b 100644 --- a/packages/atom/src/history.ts +++ b/packages/atom/src/history.ts @@ -255,14 +255,14 @@ export class History implements return true; } - addListener(id: string, fn: (e: Event) => void, scope?: any): boolean { + addListener(_: string, __: (e: Event) => void, ___?: any): boolean { return false; } - removeListener(id: string, fn: (e: Event) => void, scope?: any): boolean { + removeListener(_: string, __: (e: Event) => void, ___?: any): boolean { return false; } - notify(event: Event): void { + notify(_: Event): void { } } diff --git a/packages/atom/src/idgen.ts b/packages/atom/src/idgen.ts new file mode 100644 index 0000000000..6a23983489 --- /dev/null +++ b/packages/atom/src/idgen.ts @@ -0,0 +1,3 @@ +let NEXT_ID = 0; + +export const nextID = () => NEXT_ID++; diff --git a/packages/atom/src/view.ts b/packages/atom/src/view.ts index d0ae30f58c..4462d32899 100644 --- a/packages/atom/src/view.ts +++ b/packages/atom/src/view.ts @@ -1,7 +1,7 @@ import { equiv as _equiv } from "@thi.ng/equiv"; import { getter, Path, toPath } from "@thi.ng/paths"; - import { IView, ReadonlyAtom, ViewTransform } from "./api"; +import { nextID } from "./idgen"; /** * This class implements readonly access to a deeply nested value with @@ -47,8 +47,6 @@ import { IView, ReadonlyAtom, ViewTransform } from "./api"; export class View implements IView { - protected static NEXT_ID = 0; - readonly id: string; readonly parent: ReadonlyAtom; @@ -62,7 +60,7 @@ export class View implements constructor(parent: ReadonlyAtom, path: Path, tx?: ViewTransform, lazy = true, equiv = _equiv) { this.parent = parent; - this.id = `view-${View.NEXT_ID++}`; + this.id = `view-${nextID()}`; this.tx = tx || ((x: any) => x); this.path = toPath(path); this.isDirty = true; diff --git a/packages/atom/test/atom.ts b/packages/atom/test/atom.ts index 937b2710f7..86350ad5c6 100644 --- a/packages/atom/test/atom.ts +++ b/packages/atom/test/atom.ts @@ -15,8 +15,8 @@ describe("atom", function () { }); it("can be equiv'd", () => { - assert(a.equiv(a)); - assert(!a.equiv(new Atom(23))); + assert.ok(a.equiv(a)); + assert.ok(!a.equiv(new Atom(23))); }); it("can be reset", () => { @@ -30,10 +30,10 @@ describe("atom", function () { }); it("can add & remove watch", () => { - assert(a.addWatch("foo", () => { }), "can't add watch"); - assert((a)._watches && (a)._watches.foo, "watch missing"); - assert(a.removeWatch("foo"), "can't remove watch"); - assert(!a.removeWatch("foo"), "should fail to remove invalid watch id"); + assert.ok(a.addWatch("foo", () => { }), "can't add watch"); + assert.ok((a)._watches && (a)._watches.foo, "watch missing"); + assert.ok(a.removeWatch("foo"), "can't remove watch"); + assert.ok(!a.removeWatch("foo"), "should fail to remove invalid watch id"); }); it("can be watched", () => { diff --git a/packages/atom/test/cursor.ts b/packages/atom/test/cursor.ts index 6b59f4e76d..348bd479a1 100644 --- a/packages/atom/test/cursor.ts +++ b/packages/atom/test/cursor.ts @@ -126,17 +126,17 @@ describe("cursor", function () { c = new Cursor(a, "a"); let id = c.id; assert.notEqual((a)._watches[id], null); - assert(c.release()); + assert.ok(c.release()); assert.strictEqual(c.parent, undefined); assert.strictEqual((a)._watches[id], undefined); }); it("can add & remove watch", () => { c = new Cursor(a, "a.b.c"); - assert(c.addWatch("foo", () => { }), "can't add watch"); - assert((c).local._watches && (c).local._watches.foo, "watch missing"); - assert(c.removeWatch("foo"), "can't remove watch"); - assert(!c.removeWatch("foo"), "should fail to remove invalid watch id"); + assert.ok(c.addWatch("foo", () => { }), "can't add watch"); + assert.ok((c).local._watches && (c).local._watches.foo, "watch missing"); + assert.ok(c.removeWatch("foo"), "can't remove watch"); + assert.ok(!c.removeWatch("foo"), "should fail to remove invalid watch id"); }); it("can be watched", () => { diff --git a/packages/atom/test/index.ts b/packages/atom/test/index.ts new file mode 100644 index 0000000000..ff27842a95 --- /dev/null +++ b/packages/atom/test/index.ts @@ -0,0 +1,4 @@ +export * from "./atom"; +export * from "./cursor"; +export * from "./history"; +export * from "./view"; diff --git a/packages/atom/test/tsconfig.json b/packages/atom/test/tsconfig.json index e077d51a4c..c93bb84899 100644 --- a/packages/atom/test/tsconfig.json +++ b/packages/atom/test/tsconfig.json @@ -2,7 +2,8 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "noUnusedParameters": false + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", diff --git a/packages/atom/test/view.ts b/packages/atom/test/view.ts index 7c29de165c..5eeaf7e38e 100644 --- a/packages/atom/test/view.ts +++ b/packages/atom/test/view.ts @@ -18,20 +18,20 @@ describe("view", () => { it("can be created from atom", () => { s = a.addView("e"); - assert(s instanceof View); + assert.ok(s instanceof View); assert.equal(s.deref(), 4); s = a.addView("e", (x) => x * 10); - assert(s instanceof View); + assert.ok(s instanceof View); assert.equal(s.deref(), 40); }); it("can be created from cursor", () => { let c = new Cursor(a, "b"); s = c.addView("d"); - assert(s instanceof View); + assert.ok(s instanceof View); assert.equal(s.deref(), 3); s = c.addView("c", (x: number) => x * 10); - assert(s instanceof View); + assert.ok(s instanceof View); assert.equal(s.deref(), 20); }); @@ -55,33 +55,33 @@ describe("view", () => { it("reflects updates", () => { s = new View(a, "b.c", (x) => x * 10); - assert(s.changed(), "not dirty"); + assert.ok(s.changed(), "not dirty"); assert.equal(s.deref(), 20); - assert(!s.changed(), "changed"); + assert.ok(!s.changed(), "changed"); a.swap((state) => updateIn(state, "b.c", (x) => x + 1)); - assert(s.changed(), "not dirty #2"); + assert.ok(s.changed(), "not dirty #2"); assert.equal(s.deref(), 30); - assert(!s.changed(), "changed #2"); + assert.ok(!s.changed(), "changed #2"); }); it("reflects updates (initially undefined)", () => { s = new View(a, "f"); - assert(s.changed(), "not dirty"); + assert.ok(s.changed(), "not dirty"); assert.equal(s.deref(), undefined); - assert(!s.changed(), "changed"); + assert.ok(!s.changed(), "changed"); a.swap((state) => setIn(state, "f", 100)); - assert(s.changed(), "not dirty #2"); + assert.ok(s.changed(), "not dirty #2"); assert.equal(s.deref(), 100); }); it("can be released", () => { s = new View(a, "b.c") assert.equal(s.deref(), 2); - assert(!s.changed(), "changed"); - assert(s.release()); - assert(s.changed(), "not dirty"); + assert.ok(!s.changed(), "changed"); + assert.ok(s.release()); + assert.ok(s.changed(), "not dirty"); assert.equal(s.deref(), undefined); - assert(!s.changed(), "changed #2"); + assert.ok(!s.changed(), "changed #2"); assert.equal(s.deref(), undefined); }); diff --git a/packages/atom/tsconfig.json b/packages/atom/tsconfig.json index 7e59425303..bcf03f18b4 100644 --- a/packages/atom/tsconfig.json +++ b/packages/atom/tsconfig.json @@ -2,7 +2,8 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", - "noUnusedParameters": false + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" diff --git a/packages/bench/.npmignore b/packages/bench/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/bench/.npmignore +++ b/packages/bench/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/bench/package.json b/packages/bench/package.json index 937ddf6514..b30ab6a162 100644 --- a/packages/bench/package.json +++ b/packages/bench/package.json @@ -2,7 +2,8 @@ "name": "@thi.ng/bench", "version": "0.3.1", "description": "Basic benchmarking helpers", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +13,16 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:parcel && yarn build:parcel:min", + "build:es6": "tsc --declaration", + "build:parcel:min": "parcel build --global thing_bench -o index.min.js -d lib --experimental-scope-hoisting src/index.ts", + "build:parcel": "parcel build --global thing_bench -d lib --no-minify --experimental-scope-hoisting src/index.ts && prettier --write lib/index.js", + "build:gzip": "gzip -c lib/index.min.js > lib/index.min.js.gz", + "clean": "rimraf *.js *.d.ts .cache .nyc_output build coverage doc lib", + "test": "rimraf build && parcel build -d build --no-cache --no-minify --no-source-maps test/index.ts && nyc mocha build/index.js", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -30,10 +35,20 @@ "keywords": [ "benchmark", "ES6", + "execution", + "function", + "measure", "timing", "typescript" ], "publishConfig": { "access": "public" + }, + "browserslist": [ + "since 2018-07" + ], + "browser": { + "process": false, + "setTimeout": false } } \ No newline at end of file diff --git a/packages/bench/test/tsconfig.json b/packages/bench/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/bench/test/tsconfig.json +++ b/packages/bench/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/bench/tsconfig.json b/packages/bench/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/bench/tsconfig.json +++ b/packages/bench/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/binary/package.json b/packages/binary/package.json index a0b58f809a..9c4c6e2e38 100644 --- a/packages/binary/package.json +++ b/packages/binary/package.json @@ -2,7 +2,8 @@ "name": "@thi.ng/binary", "version": "0.1.2", "description": "Assorted binary / bitwise operations, conversions, utilities.", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +13,16 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:parcel && yarn build:parcel:min", + "build:es6": "tsc --declaration", + "build:parcel:min": "parcel build --global thing_binary -o index.min.js -d lib --experimental-scope-hoisting src/index.ts", + "build:parcel": "parcel build --global thing_binary -d lib --no-minify --experimental-scope-hoisting src/index.ts && prettier --write lib/index.js", + "build:gzip": "gzip -c lib/index.min.js > lib/index.min.js.gz", + "clean": "rimraf *.js *.d.ts .cache .nyc_output build coverage doc lib", + "test": "rimraf build && parcel build -d build --no-cache --no-minify --no-source-maps test/index.ts && nyc mocha build/index.js", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", diff --git a/packages/binary/test/tsconfig.json b/packages/binary/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/binary/test/tsconfig.json +++ b/packages/binary/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/binary/tsconfig.json b/packages/binary/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/binary/tsconfig.json +++ b/packages/binary/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/checks/.npmignore b/packages/checks/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/checks/.npmignore +++ b/packages/checks/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/checks/package.json b/packages/checks/package.json index 48aecd8bbb..0212ffb531 100644 --- a/packages/checks/package.json +++ b/packages/checks/package.json @@ -2,7 +2,8 @@ "name": "@thi.ng/checks", "version": "1.5.14", "description": "Single-function sub-modules for type, feature & value checks", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +13,16 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:parcel && yarn build:parcel:min", + "build:es6": "tsc --declaration", + "build:parcel:min": "parcel build --global thing_checks -o index.min.js -d lib --experimental-scope-hoisting src/index.ts", + "build:parcel": "parcel build --global thing_checks -d lib --no-minify --experimental-scope-hoisting src/index.ts && prettier --write lib/index.js", + "build:gzip": "gzip -c lib/index.min.js > lib/index.min.js.gz", + "test": "rimraf build && parcel build -d build --no-cache --no-minify --no-source-maps test/index.ts && nyc mocha build/index.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -39,5 +44,12 @@ ], "publishConfig": { "access": "public" + }, + "browserslist": [ + "since 2018-07" + ], + "browser": { + "process": false, + "setTimeout": false } } \ No newline at end of file diff --git a/packages/checks/test/index.ts b/packages/checks/test/index.ts index a735b68aa5..c70a02cc61 100644 --- a/packages/checks/test/index.ts +++ b/packages/checks/test/index.ts @@ -15,132 +15,132 @@ import { isTypedArray } from "../src/is-typedarray"; describe("checks", function () { it("existsAndNotNull", () => { - assert(existsAndNotNull([]), "empty array"); - assert(existsAndNotNull(new Uint8Array(1)), "typedarray"); - assert(existsAndNotNull({}), "obj"); - assert(existsAndNotNull("[]"), "string"); - assert(existsAndNotNull(0), "zero"); - assert(!existsAndNotNull({}["foobar"]), "prop"); - assert(!existsAndNotNull(null), "null"); - assert(!existsAndNotNull(undefined), "null"); + assert.ok(existsAndNotNull([]), "empty array"); + assert.ok(existsAndNotNull(new Uint8Array(1)), "typedarray"); + assert.ok(existsAndNotNull({}), "obj"); + assert.ok(existsAndNotNull("[]"), "string"); + assert.ok(existsAndNotNull(0), "zero"); + assert.ok(!existsAndNotNull({}["foobar"]), "prop"); + assert.ok(!existsAndNotNull(null), "null"); + assert.ok(!existsAndNotNull(undefined), "null"); }); it("isArray", () => { - assert(isArray([]), "empty array"); - assert(!isArray(new Uint8Array(1)), "typedarray"); - assert(!isArray({}), "obj"); - assert(!isArray("[]"), "string"); - assert(!isArray(0), "zero"); - assert(!isArray(null), "null"); - assert(!isArray(undefined), "null"); + assert.ok(isArray([]), "empty array"); + assert.ok(!isArray(new Uint8Array(1)), "typedarray"); + assert.ok(!isArray({}), "obj"); + assert.ok(!isArray("[]"), "string"); + assert.ok(!isArray(0), "zero"); + assert.ok(!isArray(null), "null"); + assert.ok(!isArray(undefined), "null"); }); it("isTypedArray", () => { - assert(isTypedArray(new Uint8Array(1)), "u8"); - assert(isTypedArray(new Uint8ClampedArray(1)), "u8c"); - assert(isTypedArray(new Uint16Array(1)), "u16"); - assert(isTypedArray(new Uint32Array(1)), "u32"); - assert(isTypedArray(new Int8Array(1)), "i8"); - assert(isTypedArray(new Int16Array(1)), "i16"); - assert(isTypedArray(new Int32Array(1)), "i32"); - assert(isTypedArray(new Float32Array(1)), "f32"); - assert(isTypedArray(new Float64Array(1)), "f64"); - assert(!isTypedArray([]), "empty array"); - assert(!isTypedArray({}), "obj"); - assert(!isTypedArray("[]"), "string"); - assert(!isTypedArray(0), "zero"); - assert(!isTypedArray(null), "null"); - assert(!isTypedArray(undefined), "null"); + assert.ok(isTypedArray(new Uint8Array(1)), "u8"); + assert.ok(isTypedArray(new Uint8ClampedArray(1)), "u8c"); + assert.ok(isTypedArray(new Uint16Array(1)), "u16"); + assert.ok(isTypedArray(new Uint32Array(1)), "u32"); + assert.ok(isTypedArray(new Int8Array(1)), "i8"); + assert.ok(isTypedArray(new Int16Array(1)), "i16"); + assert.ok(isTypedArray(new Int32Array(1)), "i32"); + assert.ok(isTypedArray(new Float32Array(1)), "f32"); + assert.ok(isTypedArray(new Float64Array(1)), "f64"); + assert.ok(!isTypedArray([]), "empty array"); + assert.ok(!isTypedArray({}), "obj"); + assert.ok(!isTypedArray("[]"), "string"); + assert.ok(!isTypedArray(0), "zero"); + assert.ok(!isTypedArray(null), "null"); + assert.ok(!isTypedArray(undefined), "null"); }); it("isArrayLike", () => { - assert(isArrayLike([]), "empty array"); - assert(isArrayLike(new Uint8Array(1)), "typedarray"); - assert(isArrayLike({ length: 1 }), "obj.length"); - assert(isArrayLike("[]"), "string"); - assert(!isArrayLike({}), "empty obj"); - assert(!isArrayLike(0), "zero"); - assert(!isArrayLike(null), "null"); - assert(!isArrayLike(undefined), "null"); - assert(!isArrayLike((x, y) => x + y), "null"); + assert.ok(isArrayLike([]), "empty array"); + assert.ok(isArrayLike(new Uint8Array(1)), "typedarray"); + assert.ok(isArrayLike({ length: 1 }), "obj.length"); + assert.ok(isArrayLike("[]"), "string"); + assert.ok(!isArrayLike({}), "empty obj"); + assert.ok(!isArrayLike(0), "zero"); + assert.ok(!isArrayLike(null), "null"); + assert.ok(!isArrayLike(undefined), "null"); + assert.ok(!isArrayLike((x, y) => x + y), "null"); }); it("isObject", () => { function Foo() { }; - assert(isObject([]), "empty array"); - assert(isObject(new Uint8Array(1)), "typedarray"); - assert(isObject({}), "obj"); - assert(isObject(new Foo()), "class"); - assert(!isObject(Foo), "fn"); - assert(!isObject("[]"), "string"); - assert(!isObject(0), "zero"); - assert(!isObject(null), "null"); - assert(!isObject(undefined), "null"); + assert.ok(isObject([]), "empty array"); + assert.ok(isObject(new Uint8Array(1)), "typedarray"); + assert.ok(isObject({}), "obj"); + assert.ok(isObject(new Foo()), "class"); + assert.ok(!isObject(Foo), "fn"); + assert.ok(!isObject("[]"), "string"); + assert.ok(!isObject(0), "zero"); + assert.ok(!isObject(null), "null"); + assert.ok(!isObject(undefined), "null"); }); it("isPlainObject", () => { function Foo() { }; - assert(isPlainObject({}), "obj"); - assert(isPlainObject(new Object()), "obj ctor"); - assert(!isPlainObject(Foo), "fn"); - assert(!isPlainObject(new Foo()), "class"); - assert(!isPlainObject([]), "empty array"); - assert(!isPlainObject(new Uint8Array(1)), "typedarray"); - assert(!isPlainObject("[]"), "string"); - assert(!isPlainObject(0), "zero"); - assert(!isPlainObject(null), "null"); - assert(!isPlainObject(undefined), "null"); + assert.ok(isPlainObject({}), "obj"); + assert.ok(isPlainObject(new Object()), "obj ctor"); + assert.ok(!isPlainObject(Foo), "fn"); + assert.ok(!isPlainObject(new Foo()), "class"); + assert.ok(!isPlainObject([]), "empty array"); + assert.ok(!isPlainObject(new Uint8Array(1)), "typedarray"); + assert.ok(!isPlainObject("[]"), "string"); + assert.ok(!isPlainObject(0), "zero"); + assert.ok(!isPlainObject(null), "null"); + assert.ok(!isPlainObject(undefined), "null"); }); it("isString", () => { - assert(isString(""), "empty string"); - assert(isString("a"), "empty string"); - assert(!isString({}), "obj"); - assert(!isString([]), "array"); - assert(!isString(new Uint8Array(1)), "typedarray"); - assert(!isString(0), "zero"); - assert(!isString(null), "null"); - assert(!isString(undefined), "null"); + assert.ok(isString(""), "empty string"); + assert.ok(isString("a"), "empty string"); + assert.ok(!isString({}), "obj"); + assert.ok(!isString([]), "array"); + assert.ok(!isString(new Uint8Array(1)), "typedarray"); + assert.ok(!isString(0), "zero"); + assert.ok(!isString(null), "null"); + assert.ok(!isString(undefined), "null"); }); it("isFunction", () => { - assert(isFunction((_) => null), "fn"); - assert(isFunction(Uint8Array), "ctor"); - assert(isFunction("a".toString), "toString"); - assert(!isFunction("a"), "empty string"); - assert(!isFunction({}), "obj"); - assert(!isFunction([]), "array"); - assert(!isFunction(new Uint8Array(1)), "typedarray"); - assert(!isFunction(0), "zero"); - assert(!isFunction(null), "null"); - assert(!isFunction(undefined), "undefined"); + assert.ok(isFunction((_) => null), "fn"); + assert.ok(isFunction(Uint8Array), "ctor"); + assert.ok(isFunction("a".toString), "toString"); + assert.ok(!isFunction("a"), "empty string"); + assert.ok(!isFunction({}), "obj"); + assert.ok(!isFunction([]), "array"); + assert.ok(!isFunction(new Uint8Array(1)), "typedarray"); + assert.ok(!isFunction(0), "zero"); + assert.ok(!isFunction(null), "null"); + assert.ok(!isFunction(undefined), "undefined"); }); it("implementsFunction", () => { - assert(implementsFunction({ a: () => true }, "a"), "obj"); - assert(implementsFunction([], Symbol.iterator), "arr iterator"); - assert(implementsFunction("", Symbol.iterator), "string iterator"); - assert(!implementsFunction(0, Symbol.iterator), "zero"); - assert(!implementsFunction(null, Symbol.iterator), "null"); - assert(!implementsFunction(undefined, Symbol.iterator), "undefined"); + assert.ok(implementsFunction({ a: () => true }, "a"), "obj"); + assert.ok(implementsFunction([], Symbol.iterator), "arr iterator"); + assert.ok(implementsFunction("", Symbol.iterator), "string iterator"); + assert.ok(!implementsFunction(0, Symbol.iterator), "zero"); + assert.ok(!implementsFunction(null, Symbol.iterator), "null"); + assert.ok(!implementsFunction(undefined, Symbol.iterator), "undefined"); }); it("isSymbol", () => { - assert(isSymbol(Symbol.iterator), "iterator"); - assert(!isSymbol("iterator"), "string"); - assert(!isFunction(0), "zero"); - assert(!isFunction(null), "null"); - assert(!isFunction(undefined), "undefined"); + assert.ok(isSymbol(Symbol.iterator), "iterator"); + assert.ok(!isSymbol("iterator"), "string"); + assert.ok(!isFunction(0), "zero"); + assert.ok(!isFunction(null), "null"); + assert.ok(!isFunction(undefined), "undefined"); }); it("isTransferable", () => { - assert(isTransferable(new ArrayBuffer(4)), "arraybuffer"); - assert(!isTransferable(new Uint8Array(4)), "typedarray"); - assert(!isTransferable([]), "array"); - assert(!isTransferable("a"), "string"); - assert(!isTransferable(0), "zero"); - assert(!isTransferable(null), "null"); - assert(!isTransferable(undefined), "undefined"); + assert.ok(isTransferable(new ArrayBuffer(4)), "arraybuffer"); + assert.ok(!isTransferable(new Uint8Array(4)), "typedarray"); + assert.ok(!isTransferable([]), "array"); + assert.ok(!isTransferable("a"), "string"); + assert.ok(!isTransferable(0), "zero"); + assert.ok(!isTransferable(null), "null"); + assert.ok(!isTransferable(undefined), "undefined"); }); }); diff --git a/packages/checks/test/tsconfig.json b/packages/checks/test/tsconfig.json index 13d45669e5..c93bb84899 100644 --- a/packages/checks/test/tsconfig.json +++ b/packages/checks/test/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", diff --git a/packages/checks/tsconfig.json b/packages/checks/tsconfig.json index f6c291a0a0..bcf03f18b4 100644 --- a/packages/checks/tsconfig.json +++ b/packages/checks/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" diff --git a/packages/equiv/.npmignore b/packages/equiv/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/equiv/.npmignore +++ b/packages/equiv/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/equiv/package.json b/packages/equiv/package.json index eab69efb7d..d82579f5f5 100644 --- a/packages/equiv/package.json +++ b/packages/equiv/package.json @@ -2,7 +2,8 @@ "name": "@thi.ng/equiv", "version": "0.1.15", "description": "Extensible deep equivalence checking for any data types", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +13,16 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:parcel && yarn build:parcel:min", + "build:es6": "tsc --declaration", + "build:parcel:min": "parcel build --global thing_equiv -o index.min.js -d lib --experimental-scope-hoisting src/index.ts", + "build:parcel": "parcel build --global thing_equiv -d lib --no-minify --experimental-scope-hoisting src/index.ts && prettier --write lib/index.js", + "build:gzip": "gzip -c lib/index.min.js > lib/index.min.js.gz", + "clean": "rimraf *.js *.d.ts .cache .nyc_output build coverage doc lib", + "test": "rimraf build && parcel build -d build --no-cache --no-minify --no-source-maps test/index.ts && nyc mocha build/index.js", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -30,11 +35,22 @@ }, "keywords": [ "deep", + "equal", "equality", + "extensible", + "interface", "ES6", - "typescript" + "typescript", + "value" ], "publishConfig": { "access": "public" + }, + "browserslist": [ + "since 2018-07" + ], + "browser": { + "process": false, + "setTimeout": false } } \ No newline at end of file diff --git a/packages/equiv/test/index.ts b/packages/equiv/test/index.ts index acaae4c6f3..4ed9489fd4 100644 --- a/packages/equiv/test/index.ts +++ b/packages/equiv/test/index.ts @@ -5,63 +5,63 @@ import { equiv } from "../src/"; describe("equiv", () => { it("null", () => { - assert(equiv(null, null)); - assert(equiv(null, undefined)); - assert(equiv(undefined, null)); + assert.ok(equiv(null, null)); + assert.ok(equiv(null, undefined)); + assert.ok(equiv(undefined, null)); }); it("boolean", () => { - assert(!equiv(null, false)); - assert(!equiv(false, null)); - assert(!equiv(undefined, false)); - assert(!equiv(false, undefined)); + assert.ok(!equiv(null, false)); + assert.ok(!equiv(false, null)); + assert.ok(!equiv(undefined, false)); + assert.ok(!equiv(false, undefined)); }); it("number", () => { - assert(!equiv(null, 0)); - assert(!equiv(0, null)); - assert(!equiv(0, undefined)); - assert(!equiv(undefined, 0)); - - assert(equiv(0, 0)); - assert(equiv(0, 0.0)); - assert(!equiv(0, 1)); - assert(!equiv(1, 0)); - assert(!equiv(0, "0")); - assert(!equiv("0", 0)); - assert(!equiv(0, [0])); - assert(!equiv([0], 0)); + assert.ok(!equiv(null, 0)); + assert.ok(!equiv(0, null)); + assert.ok(!equiv(0, undefined)); + assert.ok(!equiv(undefined, 0)); + + assert.ok(equiv(0, 0)); + assert.ok(equiv(0, 0.0)); + assert.ok(!equiv(0, 1)); + assert.ok(!equiv(1, 0)); + assert.ok(!equiv(0, "0")); + assert.ok(!equiv("0", 0)); + assert.ok(!equiv(0, [0])); + assert.ok(!equiv([0], 0)); }); it("string", () => { - assert(!equiv(null, "")); - assert(!equiv("", null)); - assert(equiv("a", "a")); - assert(!equiv("a", "ab")); + assert.ok(!equiv(null, "")); + assert.ok(!equiv("", null)); + assert.ok(equiv("a", "a")); + assert.ok(!equiv("a", "ab")); }); it("array", () => { - assert(equiv([], [])); - assert(equiv([], [])); - assert(equiv([], { length: 0 })); - assert(equiv({ length: 0 }, [])); - assert(equiv(["a"], ["a"])); - assert(!equiv(["a"], ["b"])); + assert.ok(equiv([], [])); + assert.ok(equiv([], [])); + assert.ok(equiv([], { length: 0 })); + assert.ok(equiv({ length: 0 }, [])); + assert.ok(equiv(["a"], ["a"])); + assert.ok(!equiv(["a"], ["b"])); }); it("object", () => { - assert(!equiv(undefined, {})); - assert(!equiv({}, undefined)); - assert(!equiv(null, {})); - assert(!equiv({}, null)); - - assert(equiv({}, {})); - assert(!equiv({}, [])); - assert(!equiv([], {})); - assert(equiv({ a: 0 }, { a: 0 })); - assert(equiv({ a: 0, b: { c: 1 } }, { a: 0, b: { c: 1 } })); - assert(!equiv({ a: 0, b: { c: 1 } }, { a: 0, b: { c: 2 } })); - assert(!equiv({ a: 0, b: { c: 1 } }, { a: 0, b: {} })); + assert.ok(!equiv(undefined, {})); + assert.ok(!equiv({}, undefined)); + assert.ok(!equiv(null, {})); + assert.ok(!equiv({}, null)); + + assert.ok(equiv({}, {})); + assert.ok(!equiv({}, [])); + assert.ok(!equiv([], {})); + assert.ok(equiv({ a: 0 }, { a: 0 })); + assert.ok(equiv({ a: 0, b: { c: 1 } }, { a: 0, b: { c: 1 } })); + assert.ok(!equiv({ a: 0, b: { c: 1 } }, { a: 0, b: { c: 2 } })); + assert.ok(!equiv({ a: 0, b: { c: 1 } }, { a: 0, b: {} })); }); it("equiv impl", () => { @@ -76,43 +76,43 @@ describe("equiv", () => { } } - assert(!equiv(new A(1), null)); - assert(!equiv(new A(1), undefined)); - assert(!equiv(null, new A(1))); - assert(!equiv(undefined, new A(1))); - assert(equiv(new A(1), new A(1))); - assert(equiv(new A(1), 1)); - assert(equiv(1, new A(1))); - assert(equiv(1, { equiv(x) { return x === 1; } })); - assert(equiv({ equiv(x) { return x === 1; } }, 1)); - assert(!equiv(new A(1), new A(2))); - assert(!equiv(new A(1), 2)); + assert.ok(!equiv(new A(1), null)); + assert.ok(!equiv(new A(1), undefined)); + assert.ok(!equiv(null, new A(1))); + assert.ok(!equiv(undefined, new A(1))); + assert.ok(equiv(new A(1), new A(1))); + assert.ok(equiv(new A(1), 1)); + assert.ok(equiv(1, new A(1))); + assert.ok(equiv(1, { equiv(x) { return x === 1; } })); + assert.ok(equiv({ equiv(x) { return x === 1; } }, 1)); + assert.ok(!equiv(new A(1), new A(2))); + assert.ok(!equiv(new A(1), 2)); }); it("set", () => { const a = new Set([1, 2, 3]); - assert(equiv(a, a)); - assert(equiv(a, new Set([3, 2, 1]))); - assert(equiv(new Set([{ a: 1 }, new Set([{ b: 2 }, [3]])]), new Set([new Set([[3], { b: 2 }]), { a: 1 }]))); - assert(!equiv(a, new Set([3, 2, 0]))); - assert(!equiv(a, [3, 2, 0])); - assert(!equiv(a, new Map([[3, 3], [2, 2], [1, 1]]))); - assert(!equiv(a, null)); - assert(!equiv(null, a)); + assert.ok(equiv(a, a)); + assert.ok(equiv(a, new Set([3, 2, 1]))); + assert.ok(equiv(new Set([{ a: 1 }, new Set([{ b: 2 }, [3]])]), new Set([new Set([[3], { b: 2 }]), { a: 1 }]))); + assert.ok(!equiv(a, new Set([3, 2, 0]))); + assert.ok(!equiv(a, [3, 2, 0])); + assert.ok(!equiv(a, new Map([[3, 3], [2, 2], [1, 1]]))); + assert.ok(!equiv(a, null)); + assert.ok(!equiv(null, a)); }); it("date", () => { const a = new Date(123456); - assert(equiv(a, a)); - assert(equiv(a, new Date(123456))); - assert(!equiv(a, new Date(123))); + assert.ok(equiv(a, a)); + assert.ok(equiv(a, new Date(123456))); + assert.ok(!equiv(a, new Date(123))); }); it("regexp", () => { const a = /(\w+)/g; - assert(equiv(a, a)); - assert(equiv(a, /(\w+)/g)); - assert(!equiv(a, /(\w+)/)); - assert(!equiv(a, /(\w*)/g)); + assert.ok(equiv(a, a)); + assert.ok(equiv(a, /(\w+)/g)); + assert.ok(!equiv(a, /(\w+)/)); + assert.ok(!equiv(a, /(\w*)/g)); }); }); diff --git a/packages/equiv/test/tsconfig.json b/packages/equiv/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/equiv/test/tsconfig.json +++ b/packages/equiv/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/equiv/tsconfig.json b/packages/equiv/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/equiv/tsconfig.json +++ b/packages/equiv/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/errors/.npmignore b/packages/errors/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/errors/.npmignore +++ b/packages/errors/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/errors/package.json b/packages/errors/package.json index d0bd9f2fdb..50df7c0ab4 100644 --- a/packages/errors/package.json +++ b/packages/errors/package.json @@ -2,7 +2,8 @@ "name": "@thi.ng/errors", "version": "0.1.12", "description": "Custom error types and helper fns.", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +13,16 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:parcel && yarn build:parcel:min", + "build:es6": "tsc --declaration", + "build:parcel:min": "parcel build --global thing_errors -o index.min.js -d lib --experimental-scope-hoisting src/index.ts", + "build:parcel": "parcel build --global thing_errors -d lib --no-minify --experimental-scope-hoisting src/index.ts && prettier --write lib/index.js", + "build:gzip": "gzip -c lib/index.min.js > lib/index.min.js.gz", + "clean": "rimraf *.js *.d.ts .cache .nyc_output build coverage doc lib", + "test": "rimraf build && parcel build -d build --no-cache --no-minify --no-source-maps test/index.ts && nyc mocha build/index.js", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -34,5 +39,12 @@ ], "publishConfig": { "access": "public" + }, + "browserslist": [ + "since 2018-07" + ], + "browser": { + "process": false, + "setTimeout": false } } \ No newline at end of file diff --git a/packages/errors/test/tsconfig.json b/packages/errors/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/errors/test/tsconfig.json +++ b/packages/errors/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/errors/tsconfig.json b/packages/errors/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/errors/tsconfig.json +++ b/packages/errors/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/paths/.npmignore b/packages/paths/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/paths/.npmignore +++ b/packages/paths/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/paths/package.json b/packages/paths/package.json index e613e1afd4..87e88244f9 100644 --- a/packages/paths/package.json +++ b/packages/paths/package.json @@ -2,7 +2,8 @@ "name": "@thi.ng/paths", "version": "1.6.6", "description": "immutable, optimized path-based object property / array accessors", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +13,16 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:parcel && yarn build:parcel:min", + "build:es6": "tsc --declaration", + "build:parcel:min": "parcel build --global thing_paths -o index.min.js -d lib --experimental-scope-hoisting src/index.ts", + "build:parcel": "parcel build --global thing_paths -d lib --no-minify --experimental-scope-hoisting src/index.ts && prettier --write lib/index.js", + "build:gzip": "gzip -c lib/index.min.js > lib/index.min.js.gz", + "clean": "rimraf *.js *.d.ts .cache .nyc_output build coverage doc lib", + "test": "rimraf build && parcel build -d build --no-cache --no-minify test/index.ts && nyc mocha build/index.js", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -35,6 +40,7 @@ "accessors", "array", "ES6", + "delete", "getter", "immutable", "nested", @@ -42,9 +48,17 @@ "path", "property", "setter", - "typescript" + "typescript", + "update" ], "publishConfig": { "access": "public" + }, + "browserslist": [ + "since 2018-07" + ], + "browser": { + "process": false, + "setTimeout": false } } \ No newline at end of file diff --git a/packages/paths/test/index.ts b/packages/paths/test/index.ts index 0b4567d410..b4de130c80 100644 --- a/packages/paths/test/index.ts +++ b/packages/paths/test/index.ts @@ -157,25 +157,25 @@ describe("paths", () => { a, { x: { y: { z: 1 } }, u: { v: 2 } } ); - assert(a.x === b.x); - assert(a.x.y === b.x.y); - assert(a.u === b.u); + assert.ok(a.x === b.x); + assert.ok(a.x.y === b.x.y); + assert.ok(a.u === b.u); }); it("exists", () => { const a = { a: { b: null } }; const b = { x: { y: { z: [1, 2, { u: 3, v: undefined }] } } }; - assert(!exists(null, "x.y.z"), "x.y.z"); - assert(!exists(0, "x.y.z"), "x.y.z"); - assert(exists("", "length"), "length"); - assert(exists(a, "a.b"), "a.b"); - assert(!exists(a, "a.b.c"), "a.b.c"); - assert(exists(b, "x"), "x"); - assert(exists(b, "x.y.z"), "x.y.z"); - assert(exists(b, "x.y.z.2.u"), "x.y.z.2.u"); - assert(exists(b, "x.y.z.2.v"), "x.y.z.2.v"); - assert(!exists(b, "x.y.z.3"), "x.y.z.3"); - assert(!exists(b, "x.y.z.3.u"), "x.y.z.3.u"); - assert(!exists(b, "x.z.y.2.u"), "x.z.y.2.u"); + assert.ok(!exists(null, "x.y.z"), "x.y.z"); + assert.ok(!exists(0, "x.y.z"), "x.y.z"); + assert.ok(exists("", "length"), "length"); + assert.ok(exists(a, "a.b"), "a.b"); + assert.ok(!exists(a, "a.b.c"), "a.b.c"); + assert.ok(exists(b, "x"), "x"); + assert.ok(exists(b, "x.y.z"), "x.y.z"); + assert.ok(exists(b, "x.y.z.2.u"), "x.y.z.2.u"); + assert.ok(exists(b, "x.y.z.2.v"), "x.y.z.2.v"); + assert.ok(!exists(b, "x.y.z.3"), "x.y.z.3"); + assert.ok(!exists(b, "x.y.z.3.u"), "x.y.z.3.u"); + assert.ok(!exists(b, "x.z.y.2.u"), "x.z.y.2.u"); }) }); diff --git a/packages/paths/test/tsconfig.json b/packages/paths/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/paths/test/tsconfig.json +++ b/packages/paths/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/paths/tsconfig.json b/packages/paths/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/paths/tsconfig.json +++ b/packages/paths/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/scripts/minify-module b/scripts/minify-module new file mode 100755 index 0000000000..bf9cf27932 --- /dev/null +++ b/scripts/minify-module @@ -0,0 +1,14 @@ +#!/usr/bin/env node +const fs = require("fs"); +const execSync = require('child_process').execSync; + +const roots = process.argv.slice(2); + +for (let root of roots) { + for (let f of fs.readdirSync(root)) { + if (f.endsWith(".js")) { + const ff = root + "/" + f; + execSync(`terser --module --ecma 6 -c -m -o ${ff} ${ff}`); + } + } +} diff --git a/tsconfig.json b/tsconfig.json index 4777c2b7bd..67f0c1e296 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,11 +1,12 @@ { "compilerOptions": { - "module": "commonjs", + "module": "es6", "target": "es6", "experimentalDecorators": true, "noUnusedParameters": true, "noUnusedLocals": true, - "preserveConstEnums": true + "preserveConstEnums": true, + "moduleResolution": "node" }, "exclude": [ "./**/node_modules" From 28f77e601f3ae6d5dd3d60b81fc423285902e598 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 7 Jan 2019 01:57:01 +0000 Subject: [PATCH 210/333] build: update tsconfig & .npmignore files in all packages --- packages/associative/.npmignore | 8 ++++--- packages/associative/test/tsconfig.json | 6 +++-- packages/associative/tsconfig.json | 6 +++-- packages/bitstream/.npmignore | 8 ++++--- packages/bitstream/test/tsconfig.json | 4 +++- packages/bitstream/tsconfig.json | 4 +++- packages/cache/.npmignore | 8 ++++--- packages/cache/test/tsconfig.json | 6 +++-- packages/cache/tsconfig.json | 6 +++-- packages/compare/.npmignore | 8 ++++--- packages/compare/test/tsconfig.json | 6 +++-- packages/compare/tsconfig.json | 6 +++-- packages/compose/.npmignore | 8 ++++--- packages/compose/test/tsconfig.json | 6 +++-- packages/compose/tsconfig.json | 6 +++-- packages/csp/.npmignore | 8 ++++--- packages/csp/test/tsconfig.json | 4 +++- packages/csp/tsconfig.json | 4 +++- packages/dcons/.npmignore | 8 ++++--- packages/dcons/test/tsconfig.json | 4 +++- packages/dcons/tsconfig.json | 4 +++- packages/defmulti/.npmignore | 8 ++++--- packages/defmulti/test/tsconfig.json | 6 +++-- packages/defmulti/tsconfig.json | 6 +++-- packages/dgraph/.npmignore | 8 ++++--- packages/dgraph/test/tsconfig.json | 6 +++-- packages/dgraph/tsconfig.json | 6 +++-- packages/diff/.npmignore | 8 ++++--- packages/diff/test/tsconfig.json | 6 +++-- packages/diff/tsconfig.json | 6 +++-- packages/dlogic/.npmignore | 8 ++++--- packages/dlogic/test/tsconfig.json | 6 +++-- packages/dlogic/tsconfig.json | 6 +++-- packages/dot/.npmignore | 8 ++++--- packages/dot/test/tsconfig.json | 6 +++-- packages/dot/tsconfig.json | 6 +++-- packages/dsp/.npmignore | 8 ++++--- packages/dsp/test/tsconfig.json | 6 +++-- packages/dsp/tsconfig.json | 6 +++-- packages/fsm/.npmignore | 9 ++++---- packages/fsm/test/tsconfig.json | 6 +++-- packages/fsm/tsconfig.json | 6 +++-- packages/geom-accel/.npmignore | 8 ++++--- packages/geom-accel/test/tsconfig.json | 6 +++-- packages/geom-accel/tsconfig.json | 6 +++-- packages/geom/.npmignore | 8 ++++--- packages/geom/test/tsconfig.json | 6 +++-- packages/geom/tsconfig.json | 4 +++- packages/hdom-canvas/.npmignore | 8 ++++--- packages/hdom-canvas/test/tsconfig.json | 6 +++-- packages/hdom-canvas/tsconfig.json | 6 +++-- packages/hdom-components/.npmignore | 8 ++++--- packages/hdom-components/test/tsconfig.json | 6 +++-- packages/hdom-components/tsconfig.json | 6 +++-- packages/hdom-mock/.npmignore | 9 ++++---- packages/hdom-mock/test/tsconfig.json | 6 +++-- packages/hdom-mock/tsconfig.json | 6 +++-- packages/hdom/.npmignore | 8 ++++--- packages/hdom/test/tsconfig.json | 6 +++-- packages/hdom/tsconfig.json | 6 +++-- packages/heaps/.npmignore | 8 ++++--- packages/heaps/test/tsconfig.json | 6 +++-- packages/heaps/tsconfig.json | 6 +++-- packages/hiccup-carbon-icons/.npmignore | 11 +++++----- .../hiccup-carbon-icons/test/tsconfig.json | 6 +++-- packages/hiccup-carbon-icons/tsconfig.json | 6 +++-- packages/hiccup-css/.npmignore | 8 ++++--- packages/hiccup-css/test/tsconfig.json | 4 +++- packages/hiccup-css/tsconfig.json | 6 +++-- packages/hiccup-markdown/.npmignore | 9 ++++---- packages/hiccup-markdown/test/tsconfig.json | 6 +++-- packages/hiccup-markdown/tsconfig.json | 3 ++- packages/hiccup-svg/.npmignore | 8 ++++--- packages/hiccup-svg/test/tsconfig.json | 6 +++-- packages/hiccup-svg/tsconfig.json | 6 +++-- packages/hiccup/.npmignore | 8 ++++--- packages/hiccup/test/tsconfig.json | 4 +++- packages/hiccup/tsconfig.json | 4 +++- packages/iges/.npmignore | 8 ++++--- packages/iges/test/tsconfig.json | 6 +++-- packages/iges/tsconfig.json | 6 +++-- packages/interceptors/.npmignore | 8 ++++--- packages/interceptors/test/tsconfig.json | 6 +++-- packages/interceptors/tsconfig.json | 6 +++-- packages/intervals/.npmignore | 9 ++++---- packages/intervals/test/tsconfig.json | 6 +++-- packages/intervals/tsconfig.json | 6 +++-- packages/iterators/.npmignore | 8 ++++--- packages/iterators/test/tsconfig.json | 4 +++- packages/iterators/tsconfig.json | 4 +++- packages/malloc/.npmignore | 9 ++++---- packages/malloc/test/tsconfig.json | 6 +++-- packages/malloc/tsconfig.json | 6 +++-- packages/math/.npmignore | 8 ++++--- packages/math/test/tsconfig.json | 6 +++-- packages/math/tsconfig.json | 6 +++-- packages/memoize/.npmignore | 8 ++++--- packages/memoize/test/tsconfig.json | 6 +++-- packages/memoize/tsconfig.json | 6 +++-- packages/morton/.npmignore | 8 ++++--- packages/morton/test/tsconfig.json | 6 +++-- packages/morton/tsconfig.json | 6 +++-- packages/pointfree-lang/.npmignore | 8 ++++--- packages/pointfree-lang/test/tsconfig.json | 6 +++-- packages/pointfree-lang/tsconfig.json | 6 +++-- packages/pointfree/.npmignore | 9 ++++---- packages/pointfree/test/tsconfig.json | 6 +++-- packages/pointfree/tsconfig.json | 6 +++-- packages/random/.npmignore | 9 ++++---- packages/random/test/tsconfig.json | 6 +++-- packages/random/tsconfig.json | 6 +++-- packages/range-coder/.npmignore | 22 +++++++++---------- packages/range-coder/test/tsconfig.json | 4 +++- packages/range-coder/tsconfig.json | 6 +++-- packages/resolve-map/.npmignore | 8 ++++--- packages/resolve-map/test/tsconfig.json | 6 +++-- packages/resolve-map/tsconfig.json | 6 +++-- packages/rle-pack/.npmignore | 8 ++++--- packages/rle-pack/test/tsconfig.json | 4 +++- packages/rle-pack/tsconfig.json | 4 +++- packages/router/.npmignore | 8 ++++--- packages/router/test/tsconfig.json | 6 +++-- packages/router/tsconfig.json | 6 +++-- packages/rstream-csp/.npmignore | 8 ++++--- packages/rstream-csp/test/tsconfig.json | 4 +++- packages/rstream-csp/tsconfig.json | 4 +++- packages/rstream-dot/.npmignore | 8 ++++--- packages/rstream-dot/test/tsconfig.json | 6 +++-- packages/rstream-dot/tsconfig.json | 6 +++-- packages/rstream-gestures/.npmignore | 8 ++++--- packages/rstream-gestures/test/tsconfig.json | 6 +++-- packages/rstream-gestures/tsconfig.json | 6 +++-- packages/rstream-graph/.npmignore | 8 ++++--- packages/rstream-graph/test/tsconfig.json | 6 +++-- packages/rstream-graph/tsconfig.json | 6 +++-- packages/rstream-log/.npmignore | 8 ++++--- packages/rstream-log/test/tsconfig.json | 4 +++- packages/rstream-log/tsconfig.json | 4 +++- packages/rstream-query/.npmignore | 8 ++++--- packages/rstream-query/test/tsconfig.json | 6 +++-- packages/rstream-query/tsconfig.json | 6 +++-- packages/rstream/.npmignore | 8 ++++--- packages/rstream/test/tsconfig.json | 4 +++- packages/rstream/tsconfig.json | 4 +++- packages/sax/.npmignore | 8 ++++--- packages/sax/test/tsconfig.json | 6 +++-- packages/sax/tsconfig.json | 6 +++-- packages/strings/.npmignore | 8 ++++--- packages/strings/test/tsconfig.json | 6 +++-- packages/strings/tsconfig.json | 6 +++-- packages/transducers-fsm/.npmignore | 8 ++++--- packages/transducers-fsm/test/tsconfig.json | 6 +++-- packages/transducers-fsm/tsconfig.json | 6 +++-- packages/transducers-hdom/.npmignore | 8 ++++--- packages/transducers-hdom/test/tsconfig.json | 6 +++-- packages/transducers-hdom/tsconfig.json | 6 +++-- packages/transducers-stats/.npmignore | 8 ++++--- packages/transducers-stats/test/tsconfig.json | 6 +++-- packages/transducers-stats/tsconfig.json | 6 +++-- packages/transducers/.npmignore | 8 ++++--- packages/transducers/test/tsconfig.json | 4 +++- packages/transducers/tsconfig.json | 4 +++- packages/unionstruct/.npmignore | 8 ++++--- packages/unionstruct/test/tsconfig.json | 4 +++- packages/unionstruct/tsconfig.json | 4 +++- packages/vectors/.npmignore | 8 ++++--- packages/vectors/test/tsconfig.json | 6 +++-- packages/vectors/tsconfig.json | 6 +++-- 168 files changed, 706 insertions(+), 385 deletions(-) diff --git a/packages/associative/.npmignore b/packages/associative/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/associative/.npmignore +++ b/packages/associative/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/associative/test/tsconfig.json b/packages/associative/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/associative/test/tsconfig.json +++ b/packages/associative/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/associative/tsconfig.json b/packages/associative/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/associative/tsconfig.json +++ b/packages/associative/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/bitstream/.npmignore b/packages/bitstream/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/bitstream/.npmignore +++ b/packages/bitstream/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/bitstream/test/tsconfig.json b/packages/bitstream/test/tsconfig.json index 13d45669e5..c93bb84899 100644 --- a/packages/bitstream/test/tsconfig.json +++ b/packages/bitstream/test/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", diff --git a/packages/bitstream/tsconfig.json b/packages/bitstream/tsconfig.json index f6c291a0a0..bcf03f18b4 100644 --- a/packages/bitstream/tsconfig.json +++ b/packages/bitstream/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" diff --git a/packages/cache/.npmignore b/packages/cache/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/cache/.npmignore +++ b/packages/cache/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/cache/test/tsconfig.json b/packages/cache/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/cache/test/tsconfig.json +++ b/packages/cache/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/cache/tsconfig.json b/packages/cache/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/cache/tsconfig.json +++ b/packages/cache/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/compare/.npmignore b/packages/compare/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/compare/.npmignore +++ b/packages/compare/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/compare/test/tsconfig.json b/packages/compare/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/compare/test/tsconfig.json +++ b/packages/compare/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/compare/tsconfig.json b/packages/compare/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/compare/tsconfig.json +++ b/packages/compare/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/compose/.npmignore b/packages/compose/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/compose/.npmignore +++ b/packages/compose/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/compose/test/tsconfig.json b/packages/compose/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/compose/test/tsconfig.json +++ b/packages/compose/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/compose/tsconfig.json b/packages/compose/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/compose/tsconfig.json +++ b/packages/compose/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/csp/.npmignore b/packages/csp/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/csp/.npmignore +++ b/packages/csp/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/csp/test/tsconfig.json b/packages/csp/test/tsconfig.json index 13d45669e5..c93bb84899 100644 --- a/packages/csp/test/tsconfig.json +++ b/packages/csp/test/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", diff --git a/packages/csp/tsconfig.json b/packages/csp/tsconfig.json index f6c291a0a0..bcf03f18b4 100644 --- a/packages/csp/tsconfig.json +++ b/packages/csp/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" diff --git a/packages/dcons/.npmignore b/packages/dcons/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/dcons/.npmignore +++ b/packages/dcons/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/dcons/test/tsconfig.json b/packages/dcons/test/tsconfig.json index 13d45669e5..c93bb84899 100644 --- a/packages/dcons/test/tsconfig.json +++ b/packages/dcons/test/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", diff --git a/packages/dcons/tsconfig.json b/packages/dcons/tsconfig.json index f6c291a0a0..bcf03f18b4 100644 --- a/packages/dcons/tsconfig.json +++ b/packages/dcons/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" diff --git a/packages/defmulti/.npmignore b/packages/defmulti/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/defmulti/.npmignore +++ b/packages/defmulti/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/defmulti/test/tsconfig.json b/packages/defmulti/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/defmulti/test/tsconfig.json +++ b/packages/defmulti/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/defmulti/tsconfig.json b/packages/defmulti/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/defmulti/tsconfig.json +++ b/packages/defmulti/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/dgraph/.npmignore b/packages/dgraph/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/dgraph/.npmignore +++ b/packages/dgraph/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/dgraph/test/tsconfig.json b/packages/dgraph/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/dgraph/test/tsconfig.json +++ b/packages/dgraph/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/dgraph/tsconfig.json b/packages/dgraph/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/dgraph/tsconfig.json +++ b/packages/dgraph/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/diff/.npmignore b/packages/diff/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/diff/.npmignore +++ b/packages/diff/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/diff/test/tsconfig.json b/packages/diff/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/diff/test/tsconfig.json +++ b/packages/diff/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/diff/tsconfig.json b/packages/diff/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/diff/tsconfig.json +++ b/packages/diff/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/dlogic/.npmignore b/packages/dlogic/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/dlogic/.npmignore +++ b/packages/dlogic/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/dlogic/test/tsconfig.json b/packages/dlogic/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/dlogic/test/tsconfig.json +++ b/packages/dlogic/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/dlogic/tsconfig.json b/packages/dlogic/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/dlogic/tsconfig.json +++ b/packages/dlogic/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/dot/.npmignore b/packages/dot/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/dot/.npmignore +++ b/packages/dot/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/dot/test/tsconfig.json b/packages/dot/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/dot/test/tsconfig.json +++ b/packages/dot/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/dot/tsconfig.json b/packages/dot/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/dot/tsconfig.json +++ b/packages/dot/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/dsp/.npmignore b/packages/dsp/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/dsp/.npmignore +++ b/packages/dsp/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/dsp/test/tsconfig.json b/packages/dsp/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/dsp/test/tsconfig.json +++ b/packages/dsp/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/dsp/tsconfig.json b/packages/dsp/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/dsp/tsconfig.json +++ b/packages/dsp/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/fsm/.npmignore b/packages/fsm/.npmignore index ec83d74c9d..756c6f6ea9 100644 --- a/packages/fsm/.npmignore +++ b/packages/fsm/.npmignore @@ -1,11 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc -export src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/fsm/test/tsconfig.json b/packages/fsm/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/fsm/test/tsconfig.json +++ b/packages/fsm/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/fsm/tsconfig.json b/packages/fsm/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/fsm/tsconfig.json +++ b/packages/fsm/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/geom-accel/.npmignore b/packages/geom-accel/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/geom-accel/.npmignore +++ b/packages/geom-accel/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/geom-accel/test/tsconfig.json b/packages/geom-accel/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/geom-accel/test/tsconfig.json +++ b/packages/geom-accel/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/geom-accel/tsconfig.json b/packages/geom-accel/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/geom-accel/tsconfig.json +++ b/packages/geom-accel/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/geom/.npmignore b/packages/geom/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/geom/.npmignore +++ b/packages/geom/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/geom/test/tsconfig.json b/packages/geom/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/geom/test/tsconfig.json +++ b/packages/geom/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/geom/tsconfig.json b/packages/geom/tsconfig.json index f6c291a0a0..bcf03f18b4 100644 --- a/packages/geom/tsconfig.json +++ b/packages/geom/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" diff --git a/packages/hdom-canvas/.npmignore b/packages/hdom-canvas/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/hdom-canvas/.npmignore +++ b/packages/hdom-canvas/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/hdom-canvas/test/tsconfig.json b/packages/hdom-canvas/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/hdom-canvas/test/tsconfig.json +++ b/packages/hdom-canvas/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/hdom-canvas/tsconfig.json b/packages/hdom-canvas/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/hdom-canvas/tsconfig.json +++ b/packages/hdom-canvas/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/hdom-components/.npmignore b/packages/hdom-components/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/hdom-components/.npmignore +++ b/packages/hdom-components/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/hdom-components/test/tsconfig.json b/packages/hdom-components/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/hdom-components/test/tsconfig.json +++ b/packages/hdom-components/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/hdom-components/tsconfig.json b/packages/hdom-components/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/hdom-components/tsconfig.json +++ b/packages/hdom-components/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/hdom-mock/.npmignore b/packages/hdom-mock/.npmignore index ec83d74c9d..756c6f6ea9 100644 --- a/packages/hdom-mock/.npmignore +++ b/packages/hdom-mock/.npmignore @@ -1,11 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc -export src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/hdom-mock/test/tsconfig.json b/packages/hdom-mock/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/hdom-mock/test/tsconfig.json +++ b/packages/hdom-mock/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/hdom-mock/tsconfig.json b/packages/hdom-mock/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/hdom-mock/tsconfig.json +++ b/packages/hdom-mock/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/hdom/.npmignore b/packages/hdom/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/hdom/.npmignore +++ b/packages/hdom/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/hdom/test/tsconfig.json b/packages/hdom/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/hdom/test/tsconfig.json +++ b/packages/hdom/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/hdom/tsconfig.json b/packages/hdom/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/hdom/tsconfig.json +++ b/packages/hdom/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/heaps/.npmignore b/packages/heaps/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/heaps/.npmignore +++ b/packages/heaps/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/heaps/test/tsconfig.json b/packages/heaps/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/heaps/test/tsconfig.json +++ b/packages/heaps/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/heaps/tsconfig.json b/packages/heaps/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/heaps/tsconfig.json +++ b/packages/heaps/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/hiccup-carbon-icons/.npmignore b/packages/hiccup-carbon-icons/.npmignore index 8c71fc307f..756c6f6ea9 100644 --- a/packages/hiccup-carbon-icons/.npmignore +++ b/packages/hiccup-carbon-icons/.npmignore @@ -1,13 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc -export src* test -.nyc_output tsconfig.json -*.tgz -*.html - -convert-icons diff --git a/packages/hiccup-carbon-icons/test/tsconfig.json b/packages/hiccup-carbon-icons/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/hiccup-carbon-icons/test/tsconfig.json +++ b/packages/hiccup-carbon-icons/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/hiccup-carbon-icons/tsconfig.json b/packages/hiccup-carbon-icons/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/hiccup-carbon-icons/tsconfig.json +++ b/packages/hiccup-carbon-icons/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/hiccup-css/.npmignore b/packages/hiccup-css/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/hiccup-css/.npmignore +++ b/packages/hiccup-css/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/hiccup-css/test/tsconfig.json b/packages/hiccup-css/test/tsconfig.json index 13d45669e5..c93bb84899 100644 --- a/packages/hiccup-css/test/tsconfig.json +++ b/packages/hiccup-css/test/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", diff --git a/packages/hiccup-css/tsconfig.json b/packages/hiccup-css/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/hiccup-css/tsconfig.json +++ b/packages/hiccup-css/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/hiccup-markdown/.npmignore b/packages/hiccup-markdown/.npmignore index ec83d74c9d..756c6f6ea9 100644 --- a/packages/hiccup-markdown/.npmignore +++ b/packages/hiccup-markdown/.npmignore @@ -1,11 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc -export src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/hiccup-markdown/test/tsconfig.json b/packages/hiccup-markdown/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/hiccup-markdown/test/tsconfig.json +++ b/packages/hiccup-markdown/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/hiccup-markdown/tsconfig.json b/packages/hiccup-markdown/tsconfig.json index bed3f606cb..bcf03f18b4 100644 --- a/packages/hiccup-markdown/tsconfig.json +++ b/packages/hiccup-markdown/tsconfig.json @@ -2,7 +2,8 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", - "preserveConstEnums": false + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" diff --git a/packages/hiccup-svg/.npmignore b/packages/hiccup-svg/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/hiccup-svg/.npmignore +++ b/packages/hiccup-svg/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/hiccup-svg/test/tsconfig.json b/packages/hiccup-svg/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/hiccup-svg/test/tsconfig.json +++ b/packages/hiccup-svg/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/hiccup-svg/tsconfig.json b/packages/hiccup-svg/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/hiccup-svg/tsconfig.json +++ b/packages/hiccup-svg/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/hiccup/.npmignore b/packages/hiccup/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/hiccup/.npmignore +++ b/packages/hiccup/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/hiccup/test/tsconfig.json b/packages/hiccup/test/tsconfig.json index 13d45669e5..c93bb84899 100644 --- a/packages/hiccup/test/tsconfig.json +++ b/packages/hiccup/test/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", diff --git a/packages/hiccup/tsconfig.json b/packages/hiccup/tsconfig.json index f6c291a0a0..bcf03f18b4 100644 --- a/packages/hiccup/tsconfig.json +++ b/packages/hiccup/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" diff --git a/packages/iges/.npmignore b/packages/iges/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/iges/.npmignore +++ b/packages/iges/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/iges/test/tsconfig.json b/packages/iges/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/iges/test/tsconfig.json +++ b/packages/iges/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/iges/tsconfig.json b/packages/iges/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/iges/tsconfig.json +++ b/packages/iges/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/interceptors/.npmignore b/packages/interceptors/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/interceptors/.npmignore +++ b/packages/interceptors/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/interceptors/test/tsconfig.json b/packages/interceptors/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/interceptors/test/tsconfig.json +++ b/packages/interceptors/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/interceptors/tsconfig.json b/packages/interceptors/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/interceptors/tsconfig.json +++ b/packages/interceptors/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/intervals/.npmignore b/packages/intervals/.npmignore index ec83d74c9d..756c6f6ea9 100644 --- a/packages/intervals/.npmignore +++ b/packages/intervals/.npmignore @@ -1,11 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc -export src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/intervals/test/tsconfig.json b/packages/intervals/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/intervals/test/tsconfig.json +++ b/packages/intervals/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/intervals/tsconfig.json b/packages/intervals/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/intervals/tsconfig.json +++ b/packages/intervals/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/iterators/.npmignore b/packages/iterators/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/iterators/.npmignore +++ b/packages/iterators/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/iterators/test/tsconfig.json b/packages/iterators/test/tsconfig.json index 13d45669e5..c93bb84899 100644 --- a/packages/iterators/test/tsconfig.json +++ b/packages/iterators/test/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", diff --git a/packages/iterators/tsconfig.json b/packages/iterators/tsconfig.json index f6c291a0a0..bcf03f18b4 100644 --- a/packages/iterators/tsconfig.json +++ b/packages/iterators/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" diff --git a/packages/malloc/.npmignore b/packages/malloc/.npmignore index ec83d74c9d..756c6f6ea9 100644 --- a/packages/malloc/.npmignore +++ b/packages/malloc/.npmignore @@ -1,11 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc -export src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/malloc/test/tsconfig.json b/packages/malloc/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/malloc/test/tsconfig.json +++ b/packages/malloc/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/malloc/tsconfig.json b/packages/malloc/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/malloc/tsconfig.json +++ b/packages/malloc/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/math/.npmignore b/packages/math/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/math/.npmignore +++ b/packages/math/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/math/test/tsconfig.json b/packages/math/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/math/test/tsconfig.json +++ b/packages/math/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/math/tsconfig.json b/packages/math/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/math/tsconfig.json +++ b/packages/math/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/memoize/.npmignore b/packages/memoize/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/memoize/.npmignore +++ b/packages/memoize/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/memoize/test/tsconfig.json b/packages/memoize/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/memoize/test/tsconfig.json +++ b/packages/memoize/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/memoize/tsconfig.json b/packages/memoize/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/memoize/tsconfig.json +++ b/packages/memoize/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/morton/.npmignore b/packages/morton/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/morton/.npmignore +++ b/packages/morton/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/morton/test/tsconfig.json b/packages/morton/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/morton/test/tsconfig.json +++ b/packages/morton/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/morton/tsconfig.json b/packages/morton/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/morton/tsconfig.json +++ b/packages/morton/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/pointfree-lang/.npmignore b/packages/pointfree-lang/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/pointfree-lang/.npmignore +++ b/packages/pointfree-lang/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/pointfree-lang/test/tsconfig.json b/packages/pointfree-lang/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/pointfree-lang/test/tsconfig.json +++ b/packages/pointfree-lang/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/pointfree-lang/tsconfig.json b/packages/pointfree-lang/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/pointfree-lang/tsconfig.json +++ b/packages/pointfree-lang/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/pointfree/.npmignore b/packages/pointfree/.npmignore index d8b97762a7..756c6f6ea9 100644 --- a/packages/pointfree/.npmignore +++ b/packages/pointfree/.npmignore @@ -1,11 +1,12 @@ -bench +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/pointfree/test/tsconfig.json b/packages/pointfree/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/pointfree/test/tsconfig.json +++ b/packages/pointfree/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/pointfree/tsconfig.json b/packages/pointfree/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/pointfree/tsconfig.json +++ b/packages/pointfree/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/random/.npmignore b/packages/random/.npmignore index ec83d74c9d..756c6f6ea9 100644 --- a/packages/random/.npmignore +++ b/packages/random/.npmignore @@ -1,11 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc -export src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/random/test/tsconfig.json b/packages/random/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/random/test/tsconfig.json +++ b/packages/random/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/random/tsconfig.json b/packages/random/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/random/tsconfig.json +++ b/packages/random/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/range-coder/.npmignore b/packages/range-coder/.npmignore index 538f8b608d..756c6f6ea9 100644 --- a/packages/range-coder/.npmignore +++ b/packages/range-coder/.npmignore @@ -1,14 +1,12 @@ -bench/* -build/* -dev/* -node_modules -src* -test* -bundle.* -tsconfig.json -webpack.config.js +.cache +.nyc_output +*.gz *.html *.tgz -!doc/* -!*.d.ts -!*.js +build +coverage +dev +doc +src* +test +tsconfig.json diff --git a/packages/range-coder/test/tsconfig.json b/packages/range-coder/test/tsconfig.json index 13d45669e5..c93bb84899 100644 --- a/packages/range-coder/test/tsconfig.json +++ b/packages/range-coder/test/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", diff --git a/packages/range-coder/tsconfig.json b/packages/range-coder/tsconfig.json index fe4ca75067..bcf03f18b4 100644 --- a/packages/range-coder/tsconfig.json +++ b/packages/range-coder/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ - "./src/**/*.ts", + "./src/**/*.ts" ] } \ No newline at end of file diff --git a/packages/resolve-map/.npmignore b/packages/resolve-map/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/resolve-map/.npmignore +++ b/packages/resolve-map/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/resolve-map/test/tsconfig.json b/packages/resolve-map/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/resolve-map/test/tsconfig.json +++ b/packages/resolve-map/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/resolve-map/tsconfig.json b/packages/resolve-map/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/resolve-map/tsconfig.json +++ b/packages/resolve-map/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/rle-pack/.npmignore b/packages/rle-pack/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/rle-pack/.npmignore +++ b/packages/rle-pack/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/rle-pack/test/tsconfig.json b/packages/rle-pack/test/tsconfig.json index 13d45669e5..c93bb84899 100644 --- a/packages/rle-pack/test/tsconfig.json +++ b/packages/rle-pack/test/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", diff --git a/packages/rle-pack/tsconfig.json b/packages/rle-pack/tsconfig.json index f6c291a0a0..bcf03f18b4 100644 --- a/packages/rle-pack/tsconfig.json +++ b/packages/rle-pack/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" diff --git a/packages/router/.npmignore b/packages/router/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/router/.npmignore +++ b/packages/router/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/router/test/tsconfig.json b/packages/router/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/router/test/tsconfig.json +++ b/packages/router/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/router/tsconfig.json b/packages/router/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/router/tsconfig.json +++ b/packages/router/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/rstream-csp/.npmignore b/packages/rstream-csp/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/rstream-csp/.npmignore +++ b/packages/rstream-csp/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/rstream-csp/test/tsconfig.json b/packages/rstream-csp/test/tsconfig.json index 13d45669e5..c93bb84899 100644 --- a/packages/rstream-csp/test/tsconfig.json +++ b/packages/rstream-csp/test/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", diff --git a/packages/rstream-csp/tsconfig.json b/packages/rstream-csp/tsconfig.json index f6c291a0a0..bcf03f18b4 100644 --- a/packages/rstream-csp/tsconfig.json +++ b/packages/rstream-csp/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" diff --git a/packages/rstream-dot/.npmignore b/packages/rstream-dot/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/rstream-dot/.npmignore +++ b/packages/rstream-dot/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/rstream-dot/test/tsconfig.json b/packages/rstream-dot/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/rstream-dot/test/tsconfig.json +++ b/packages/rstream-dot/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/rstream-dot/tsconfig.json b/packages/rstream-dot/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/rstream-dot/tsconfig.json +++ b/packages/rstream-dot/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/rstream-gestures/.npmignore b/packages/rstream-gestures/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/rstream-gestures/.npmignore +++ b/packages/rstream-gestures/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/rstream-gestures/test/tsconfig.json b/packages/rstream-gestures/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/rstream-gestures/test/tsconfig.json +++ b/packages/rstream-gestures/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/rstream-gestures/tsconfig.json b/packages/rstream-gestures/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/rstream-gestures/tsconfig.json +++ b/packages/rstream-gestures/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/rstream-graph/.npmignore b/packages/rstream-graph/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/rstream-graph/.npmignore +++ b/packages/rstream-graph/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/rstream-graph/test/tsconfig.json b/packages/rstream-graph/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/rstream-graph/test/tsconfig.json +++ b/packages/rstream-graph/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/rstream-graph/tsconfig.json b/packages/rstream-graph/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/rstream-graph/tsconfig.json +++ b/packages/rstream-graph/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/rstream-log/.npmignore b/packages/rstream-log/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/rstream-log/.npmignore +++ b/packages/rstream-log/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/rstream-log/test/tsconfig.json b/packages/rstream-log/test/tsconfig.json index 13d45669e5..c93bb84899 100644 --- a/packages/rstream-log/test/tsconfig.json +++ b/packages/rstream-log/test/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", diff --git a/packages/rstream-log/tsconfig.json b/packages/rstream-log/tsconfig.json index f6c291a0a0..bcf03f18b4 100644 --- a/packages/rstream-log/tsconfig.json +++ b/packages/rstream-log/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" diff --git a/packages/rstream-query/.npmignore b/packages/rstream-query/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/rstream-query/.npmignore +++ b/packages/rstream-query/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/rstream-query/test/tsconfig.json b/packages/rstream-query/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/rstream-query/test/tsconfig.json +++ b/packages/rstream-query/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/rstream-query/tsconfig.json b/packages/rstream-query/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/rstream-query/tsconfig.json +++ b/packages/rstream-query/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/rstream/.npmignore b/packages/rstream/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/rstream/.npmignore +++ b/packages/rstream/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/rstream/test/tsconfig.json b/packages/rstream/test/tsconfig.json index 13d45669e5..c93bb84899 100644 --- a/packages/rstream/test/tsconfig.json +++ b/packages/rstream/test/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", diff --git a/packages/rstream/tsconfig.json b/packages/rstream/tsconfig.json index f6c291a0a0..bcf03f18b4 100644 --- a/packages/rstream/tsconfig.json +++ b/packages/rstream/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" diff --git a/packages/sax/.npmignore b/packages/sax/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/sax/.npmignore +++ b/packages/sax/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/sax/test/tsconfig.json b/packages/sax/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/sax/test/tsconfig.json +++ b/packages/sax/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/sax/tsconfig.json b/packages/sax/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/sax/tsconfig.json +++ b/packages/sax/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/strings/.npmignore b/packages/strings/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/strings/.npmignore +++ b/packages/strings/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/strings/test/tsconfig.json b/packages/strings/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/strings/test/tsconfig.json +++ b/packages/strings/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/strings/tsconfig.json b/packages/strings/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/strings/tsconfig.json +++ b/packages/strings/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/transducers-fsm/.npmignore b/packages/transducers-fsm/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/transducers-fsm/.npmignore +++ b/packages/transducers-fsm/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/transducers-fsm/test/tsconfig.json b/packages/transducers-fsm/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/transducers-fsm/test/tsconfig.json +++ b/packages/transducers-fsm/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/transducers-fsm/tsconfig.json b/packages/transducers-fsm/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/transducers-fsm/tsconfig.json +++ b/packages/transducers-fsm/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/transducers-hdom/.npmignore b/packages/transducers-hdom/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/transducers-hdom/.npmignore +++ b/packages/transducers-hdom/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/transducers-hdom/test/tsconfig.json b/packages/transducers-hdom/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/transducers-hdom/test/tsconfig.json +++ b/packages/transducers-hdom/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/transducers-hdom/tsconfig.json b/packages/transducers-hdom/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/transducers-hdom/tsconfig.json +++ b/packages/transducers-hdom/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/transducers-stats/.npmignore b/packages/transducers-stats/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/transducers-stats/.npmignore +++ b/packages/transducers-stats/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/transducers-stats/test/tsconfig.json b/packages/transducers-stats/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/transducers-stats/test/tsconfig.json +++ b/packages/transducers-stats/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/transducers-stats/tsconfig.json b/packages/transducers-stats/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/transducers-stats/tsconfig.json +++ b/packages/transducers-stats/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/transducers/.npmignore b/packages/transducers/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/transducers/.npmignore +++ b/packages/transducers/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/transducers/test/tsconfig.json b/packages/transducers/test/tsconfig.json index 13d45669e5..c93bb84899 100644 --- a/packages/transducers/test/tsconfig.json +++ b/packages/transducers/test/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", diff --git a/packages/transducers/tsconfig.json b/packages/transducers/tsconfig.json index f6c291a0a0..bcf03f18b4 100644 --- a/packages/transducers/tsconfig.json +++ b/packages/transducers/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" diff --git a/packages/unionstruct/.npmignore b/packages/unionstruct/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/unionstruct/.npmignore +++ b/packages/unionstruct/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/unionstruct/test/tsconfig.json b/packages/unionstruct/test/tsconfig.json index 13d45669e5..c93bb84899 100644 --- a/packages/unionstruct/test/tsconfig.json +++ b/packages/unionstruct/test/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", diff --git a/packages/unionstruct/tsconfig.json b/packages/unionstruct/tsconfig.json index f6c291a0a0..bcf03f18b4 100644 --- a/packages/unionstruct/tsconfig.json +++ b/packages/unionstruct/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" diff --git a/packages/vectors/.npmignore b/packages/vectors/.npmignore index d703bda97a..756c6f6ea9 100644 --- a/packages/vectors/.npmignore +++ b/packages/vectors/.npmignore @@ -1,10 +1,12 @@ +.cache +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/vectors/test/tsconfig.json b/packages/vectors/test/tsconfig.json index bcf29ace54..c93bb84899 100644 --- a/packages/vectors/test/tsconfig.json +++ b/packages/vectors/test/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "es6", + "target": "es6" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/vectors/tsconfig.json b/packages/vectors/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/vectors/tsconfig.json +++ b/packages/vectors/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file From 3e1467fae0d9ef12ad73392eabec45d004d5ab0c Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 7 Jan 2019 14:35:13 +0000 Subject: [PATCH 211/333] refactor(rstream-log): use rstream nextID() util (fix regression) --- packages/rstream-log/src/logger.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rstream-log/src/logger.ts b/packages/rstream-log/src/logger.ts index 3c7b723aef..226fba8968 100644 --- a/packages/rstream-log/src/logger.ts +++ b/packages/rstream-log/src/logger.ts @@ -1,7 +1,7 @@ import { illegalArity } from "@thi.ng/errors/illegal-arity"; import { ISubscribable } from "@thi.ng/rstream/api"; import { StreamMerge } from "@thi.ng/rstream/stream-merge"; -import { Subscription } from "@thi.ng/rstream/subscription"; +import { nextID } from "@thi.ng/rstream/utils/idgen"; import { ILogger, Level, LogEntry } from "./api"; @@ -34,7 +34,7 @@ export class Logger extends StreamMerge implements default: illegalArity(args.length); } - id = id || `logger-${Subscription.NEXT_ID++}`; + id = id || `logger-${nextID()}`; super({ src, id, close: false }); this.level = level; } From a42b2e1158adb3758c7f92a8d54805de5f629f5d Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 7 Jan 2019 14:35:31 +0000 Subject: [PATCH 212/333] refactor(rstream-query): use rstream nextID() util (fix regression) --- packages/rstream-query/src/store.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rstream-query/src/store.ts b/packages/rstream-query/src/store.ts index 1640fe16ef..14f90bd59e 100644 --- a/packages/rstream-query/src/store.ts +++ b/packages/rstream-query/src/store.ts @@ -13,6 +13,7 @@ import { ISubscribable } from "@thi.ng/rstream/api"; import { Stream } from "@thi.ng/rstream/stream"; import { sync } from "@thi.ng/rstream/stream-sync"; import { Subscription } from "@thi.ng/rstream/subscription"; +import { nextID } from "@thi.ng/rstream/utils/idgen"; import { Reducer, Transducer } from "@thi.ng/transducers/api"; import { comp } from "@thi.ng/transducers/func/comp"; import { compR } from "@thi.ng/transducers/func/compr"; @@ -22,7 +23,6 @@ import { transduce } from "@thi.ng/transducers/transduce"; import { dedupe } from "@thi.ng/transducers/xform/dedupe"; import { map } from "@thi.ng/transducers/xform/map"; import { mapIndexed } from "@thi.ng/transducers/xform/map-indexed"; - import { BindFn, DEBUG, @@ -251,7 +251,7 @@ export class TripleStore implements if (!resolve) { illegalArgs("at least 1 query variable is required in pattern"); } - id || (id = `query-${Subscription.NEXT_ID++}`); + id || (id = `query-${nextID()}`); const query = >this.addPatternQuery( [vs ? null : s, vp ? null : p, vo ? null : o], id + "-raw" From d3944fb02369bb76c261fa0a2465f313ab46c2a0 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 7 Jan 2019 14:51:35 +0000 Subject: [PATCH 213/333] build: switch travis to use node 10 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 60be2f977b..cb8d32e4f1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: - - "9" + - "10" branches: only: From 7fee857347f4695be84def0c5c915d8323fab0ba Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 8 Jan 2019 02:11:25 +0000 Subject: [PATCH 214/333] build: update shared dev deps, rewrite bundle-module script --- package.json | 2 + scripts/bundle-module | 60 ++ scripts/minify-module | 14 - yarn.lock | 1434 +++++++++++++++++++++-------------------- 4 files changed, 788 insertions(+), 722 deletions(-) create mode 100755 scripts/bundle-module delete mode 100755 scripts/minify-module diff --git a/package.json b/package.json index 139fc9b44a..844bb95fe0 100644 --- a/package.json +++ b/package.json @@ -5,11 +5,13 @@ ], "devDependencies": { "benchmark": "^2.1.4", + "gzip-size": "^5.0.0", "lerna": "^3.8.5", "mocha": "^5.2.0", "nyc": "^13.1.0", "parcel-bundler": "^1.11.0", "rimraf": "^2.6.3", + "rollup": "^1.0.2", "terser": "^3.14.1", "tslint": "^5.12.0", "typescript": "^3.2.2" diff --git a/scripts/bundle-module b/scripts/bundle-module new file mode 100755 index 0000000000..cd259fe86d --- /dev/null +++ b/scripts/bundle-module @@ -0,0 +1,60 @@ +#!/usr/bin/env node +const fs = require("fs"); +const rollup = require("rollup"); +const terser = require("terser"); +const gz = require("gzip-size"); + +const name = process.argv[2]; + +const deps = process.argv.slice(3).reduce( + (acc, x) => (acc[`@thi.ng/${x}`] = `thi.ng.${x}`, acc), + {} +); + +const inOpts = { + external: Object.keys(deps), + input: "./index.js" +}; + +const terserOpts = { + compress: true, + mangle: true, + ecma: 6 +}; + +const size = (x) => (x / 1024).toFixed(2) + "KB"; + +const buildVersion = async (dest, outOpts) => { + console.log(`bundling (${outOpts.format}): ${dest}`); + const bundle = await rollup.rollup(inOpts); + const bundleOut = await bundle.generate(outOpts); + const terserOut = terser.minify(bundleOut.output[0].code, terserOpts); + fs.writeFileSync(dest, terserOut.code); + console.log(`\tsize: ${size(terserOut.code.length)} / gzipped: ${size(gz.sync(terserOut.code))}`); +}; + +if (!fs.existsSync("lib")) { + fs.mkdirSync("lib"); +} + +const build = async () => { + + await buildVersion( + "lib/index.js", + { + format: "cjs" + } + ); + + await buildVersion( + "lib/index.umd.js", + { + format: "umd", + globals: deps, + name: `thi.ng.${name}`, + } + ); + +}; + +build(); diff --git a/scripts/minify-module b/scripts/minify-module deleted file mode 100755 index bf9cf27932..0000000000 --- a/scripts/minify-module +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env node -const fs = require("fs"); -const execSync = require('child_process').execSync; - -const roots = process.argv.slice(2); - -for (let root of roots) { - for (let f of fs.readdirSync(root)) { - if (f.endsWith(".js")) { - const ff = root + "/" + f; - execSync(`terser --module --ecma 6 -c -m -o ${ff} ${ff}`); - } - } -} diff --git a/yarn.lock b/yarn.lock index 50f6c88cf5..02d20650f7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,31 +10,31 @@ "@babel/highlight" "^7.0.0" "@babel/core@^7.0.0": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.1.2.tgz#f8d2a9ceb6832887329a7b60f9d035791400ba4e" - integrity sha512-IFeSSnjXdhDaoysIlev//UzHZbdEmm7D0EIH2qtse9xK7mXEZQpYjs2P00XlP1qYsYvid79p+Zgg6tz1mp6iVw== + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.2.2.tgz#07adba6dde27bb5ad8d8672f15fde3e08184a687" + integrity sha512-59vB0RWt09cAct5EIe58+NzGP4TFSD3Bz//2/ELy3ZeTeKF6VTD1AXlH8BGGbCX0PuobZBsIzO7IAI9PH67eKw== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.1.2" - "@babel/helpers" "^7.1.2" - "@babel/parser" "^7.1.2" - "@babel/template" "^7.1.2" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.1.2" + "@babel/generator" "^7.2.2" + "@babel/helpers" "^7.2.0" + "@babel/parser" "^7.2.2" + "@babel/template" "^7.2.2" + "@babel/traverse" "^7.2.2" + "@babel/types" "^7.2.2" convert-source-map "^1.1.0" - debug "^3.1.0" - json5 "^0.5.0" + debug "^4.1.0" + json5 "^2.1.0" lodash "^4.17.10" resolve "^1.3.2" semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.0.0", "@babel/generator@^7.1.2", "@babel/generator@^7.1.3": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.1.3.tgz#2103ec9c42d9bdad9190a6ad5ff2d456fd7b8673" - integrity sha512-ZoCZGcfIJFJuZBqxcY9OjC1KW2lWK64qrX1o4UYL3yshVhwKFYgzpWZ0vvtGMNJdTlvkw0W+HR1VnYN8q3QPFQ== +"@babel/generator@^7.0.0", "@babel/generator@^7.2.2": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.2.2.tgz#18c816c70962640eab42fe8cae5f3947a5c65ccc" + integrity sha512-I4o675J/iS8k+P38dvJ3IBGqObLXyQLTxtrR4u9cSUJOURvafeEWb/pFMOTwtNrmq73mJzyF6ueTbO1BtN0Zeg== dependencies: - "@babel/types" "^7.1.3" + "@babel/types" "^7.2.2" jsesc "^2.5.1" lodash "^4.17.10" source-map "^0.5.0" @@ -127,15 +127,15 @@ "@babel/types" "^7.0.0" "@babel/helper-module-transforms@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.1.0.tgz#470d4f9676d9fad50b324cdcce5fbabbc3da5787" - integrity sha512-0JZRd2yhawo79Rcm4w0LwSMILFmFXjugG3yqf+P/UsKsRS1mJCmMwwlHDlMg7Avr9LrvSpp4ZSULO9r8jpCzcw== + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.2.2.tgz#ab2f8e8d231409f8370c883d20c335190284b963" + integrity sha512-YRD7I6Wsv+IHuTPkAmAS4HhY0dkPobgLftHp0cRGZSdrRvmZY8rFvae/GVu3bD00qscuvK3WPHB3YdNpBXUqrA== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-simple-access" "^7.1.0" "@babel/helper-split-export-declaration" "^7.0.0" - "@babel/template" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/template" "^7.2.2" + "@babel/types" "^7.2.2" lodash "^4.17.10" "@babel/helper-optimise-call-expression@^7.0.0": @@ -169,13 +169,13 @@ "@babel/types" "^7.0.0" "@babel/helper-replace-supers@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.1.0.tgz#5fc31de522ec0ef0899dc9b3e7cf6a5dd655f362" - integrity sha512-BvcDWYZRWVuDeXTYZWxekQNO5D4kO55aArwZOTFXw6rlLQA8ZaDicJR1sO47h+HrnCiDFiww0fSPV0d713KBGQ== + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.2.3.tgz#19970020cf22677d62b3a689561dbd9644d8c5e5" + integrity sha512-GyieIznGUfPXPWu0yLS6U55Mz67AZD9cUk0BfirOWlPrXlBcan9Gz+vHGz+cPfuoweZSnPzPIm67VtQM0OWZbA== dependencies: "@babel/helper-member-expression-to-functions" "^7.0.0" "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/traverse" "^7.1.0" + "@babel/traverse" "^7.2.3" "@babel/types" "^7.0.0" "@babel/helper-simple-access@^7.1.0": @@ -194,23 +194,23 @@ "@babel/types" "^7.0.0" "@babel/helper-wrap-function@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.1.0.tgz#8cf54e9190706067f016af8f75cb3df829cc8c66" - integrity sha512-R6HU3dete+rwsdAfrOzTlE9Mcpk4RjU3aX3gi9grtmugQY0u79X7eogUvfXA5sI81Mfq1cn6AgxihfN33STjJA== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz#c4e0012445769e2815b55296ead43a958549f6fa" + integrity sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ== dependencies: "@babel/helper-function-name" "^7.1.0" "@babel/template" "^7.1.0" "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/types" "^7.2.0" -"@babel/helpers@^7.1.2": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.1.2.tgz#ab752e8c35ef7d39987df4e8586c63b8846234b5" - integrity sha512-Myc3pUE8eswD73aWcartxB16K6CGmHDv9KxOmD2CeOs/FaEAQodr3VYGmlvOmog60vNQ2w8QbatuahepZwrHiA== +"@babel/helpers@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.2.0.tgz#8335f3140f3144270dc63c4732a4f8b0a50b7a21" + integrity sha512-Fr07N+ea0dMcMN8nFpuK6dUIT7/ivt9yKQdEEnjVS83tG2pHwPi03gYmk/tyuwONnZ+sY+GFFPlWGgCtW1hF9A== dependencies: "@babel/template" "^7.1.2" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.1.2" + "@babel/traverse" "^7.1.5" + "@babel/types" "^7.2.0" "@babel/highlight@^7.0.0": version "7.0.0" @@ -221,130 +221,130 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.2", "@babel/parser@^7.1.3": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.3.tgz#2c92469bac2b7fbff810b67fca07bd138b48af77" - integrity sha512-gqmspPZOMW3MIRb9HlrnbZHXI1/KHTOroBwN1NcLL6pWxzqzEKGvRTq0W/PxS45OtQGbaFikSQpkS5zbnsQm2w== +"@babel/parser@^7.0.0", "@babel/parser@^7.2.2", "@babel/parser@^7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.2.3.tgz#32f5df65744b70888d17872ec106b02434ba1489" + integrity sha512-0LyEcVlfCoFmci8mXx8A5oIkpkOgyo8dRHtxBnK9RRBwxO2+JZPNsqtVEZQ7mJFPxnXF9lfmU24mHOPI0qnlkA== -"@babel/plugin-proposal-async-generator-functions@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.1.0.tgz#41c1a702e10081456e23a7b74d891922dd1bb6ce" - integrity sha512-Fq803F3Jcxo20MXUSDdmZZXrPe6BWyGcWBPPNB/M7WaUYESKDeKMOGIxEzQOjGSmW/NWb6UaPZrtTB2ekhB/ew== +"@babel/plugin-proposal-async-generator-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e" + integrity sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-remap-async-to-generator" "^7.1.0" - "@babel/plugin-syntax-async-generators" "^7.0.0" + "@babel/plugin-syntax-async-generators" "^7.2.0" -"@babel/plugin-proposal-json-strings@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.0.0.tgz#3b4d7b5cf51e1f2e70f52351d28d44fc2970d01e" - integrity sha512-kfVdUkIAGJIVmHmtS/40i/fg/AGnw/rsZBCaapY5yjeO5RA9m165Xbw9KMOu2nqXP5dTFjEjHdfNdoVcHv133Q== +"@babel/plugin-proposal-json-strings@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz#568ecc446c6148ae6b267f02551130891e29f317" + integrity sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-json-strings" "^7.0.0" + "@babel/plugin-syntax-json-strings" "^7.2.0" -"@babel/plugin-proposal-object-rest-spread@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0.tgz#9a17b547f64d0676b6c9cecd4edf74a82ab85e7e" - integrity sha512-14fhfoPcNu7itSen7Py1iGN0gEm87hX/B+8nZPqkdmANyyYWYMY2pjA3r8WXbWVKMzfnSNS0xY8GVS0IjXi/iw== +"@babel/plugin-proposal-object-rest-spread@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.2.0.tgz#88f5fec3e7ad019014c97f7ee3c992f0adbf7fb8" + integrity sha512-1L5mWLSvR76XYUQJXkd/EEQgjq8HHRP6lQuZTTg0VA4tTGPpGemmCdAfQIz1rzEuWAm+ecP8PyyEm30jC1eQCg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.2.0" -"@babel/plugin-proposal-optional-catch-binding@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.0.0.tgz#b610d928fe551ff7117d42c8bb410eec312a6425" - integrity sha512-JPqAvLG1s13B/AuoBjdBYvn38RqW6n1TzrQO839/sIpqLpbnXKacsAgpZHzLD83Sm8SDXMkkrAvEnJ25+0yIpw== +"@babel/plugin-proposal-optional-catch-binding@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz#135d81edb68a081e55e56ec48541ece8065c38f5" + integrity sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.0.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" -"@babel/plugin-proposal-unicode-property-regex@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.0.0.tgz#498b39cd72536cd7c4b26177d030226eba08cd33" - integrity sha512-tM3icA6GhC3ch2SkmSxv7J/hCWKISzwycub6eGsDrFDgukD4dZ/I+x81XgW0YslS6mzNuQ1Cbzh5osjIMgepPQ== +"@babel/plugin-proposal-unicode-property-regex@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.2.0.tgz#abe7281fe46c95ddc143a65e5358647792039520" + integrity sha512-LvRVYb7kikuOtIoUeWTkOxQEV1kYvL5B6U3iWEGCzPNRus1MzJweFqORTj+0jkxozkTSYNJozPOddxmqdqsRpw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" regexpu-core "^4.2.0" -"@babel/plugin-syntax-async-generators@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0.tgz#bf0891dcdbf59558359d0c626fdc9490e20bc13c" - integrity sha512-im7ged00ddGKAjcZgewXmp1vxSZQQywuQXe2B1A7kajjZmDeY/ekMPmWr9zJgveSaQH0k7BcGrojQhcK06l0zA== +"@babel/plugin-syntax-async-generators@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz#69e1f0db34c6f5a0cf7e2b3323bf159a76c8cb7f" + integrity sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-flow@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.0.0.tgz#70638aeaad9ee426bc532e51523cff8ff02f6f17" - integrity sha512-zGcuZWiWWDa5qTZ6iAnpG0fnX/GOu49pGR5PFvkQ9GmKNaSphXQnlNXh/LG20sqWtNrx/eB6krzfEzcwvUyeFA== +"@babel/plugin-syntax-flow@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.2.0.tgz#a765f061f803bc48f240c26f8747faf97c26bf7c" + integrity sha512-r6YMuZDWLtLlu0kqIim5o/3TNRAlWb073HwT3e2nKf9I8IIvOggPrnILYPsrrKilmn/mYEMCf/Z07w3yQJF6dg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-json-strings@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.0.0.tgz#0d259a68090e15b383ce3710e01d5b23f3770cbd" - integrity sha512-UlSfNydC+XLj4bw7ijpldc1uZ/HB84vw+U6BTuqMdIEmz/LDe63w/GHtpQMdXWdqQZFeAI9PjnHe/vDhwirhKA== +"@babel/plugin-syntax-json-strings@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz#72bd13f6ffe1d25938129d2a186b11fd62951470" + integrity sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-jsx@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.0.0.tgz#034d5e2b4e14ccaea2e4c137af7e4afb39375ffd" - integrity sha512-PdmL2AoPsCLWxhIr3kG2+F9v4WH06Q3z+NoGVpQgnUNGcagXHq5sB3OXxkSahKq9TLdNMN/AJzFYSOo8UKDMHg== +"@babel/plugin-syntax-jsx@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz#0b85a3b4bc7cdf4cc4b8bf236335b907ca22e7c7" + integrity sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-object-rest-spread@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0.tgz#37d8fbcaf216bd658ea1aebbeb8b75e88ebc549b" - integrity sha512-5A0n4p6bIiVe5OvQPxBnesezsgFJdHhSs3uFSvaPdMqtsovajLZ+G2vZyvNe10EzJBWWo3AcHGKhAFUxqwp2dw== +"@babel/plugin-syntax-object-rest-spread@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e" + integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-optional-catch-binding@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0.tgz#886f72008b3a8b185977f7cb70713b45e51ee475" - integrity sha512-Wc+HVvwjcq5qBg1w5RG9o9RVzmCaAg/Vp0erHCKpAYV8La6I94o4GQAmFYNmkzoMO6gzoOSulpKeSSz6mPEoZw== +"@babel/plugin-syntax-optional-catch-binding@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz#a94013d6eda8908dfe6a477e7f9eda85656ecf5c" + integrity sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-arrow-functions@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0.tgz#a6c14875848c68a3b4b3163a486535ef25c7e749" - integrity sha512-2EZDBl1WIO/q4DIkIp4s86sdp4ZifL51MoIviLY/gG/mLSuOIEg7J8o6mhbxOTvUJkaN50n+8u41FVsr5KLy/w== +"@babel/plugin-transform-arrow-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz#9aeafbe4d6ffc6563bf8f8372091628f00779550" + integrity sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-async-to-generator@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.1.0.tgz#109e036496c51dd65857e16acab3bafdf3c57811" - integrity sha512-rNmcmoQ78IrvNCIt/R9U+cixUHeYAzgusTFgIAv+wQb9HJU4szhpDD6e5GCACmj/JP5KxuCwM96bX3L9v4ZN/g== +"@babel/plugin-transform-async-to-generator@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.2.0.tgz#68b8a438663e88519e65b776f8938f3445b1a2ff" + integrity sha512-CEHzg4g5UraReozI9D4fblBYABs7IM6UerAVG7EJVrTLC5keh00aEuLUT+O40+mJCEzaXkYfTCUKIyeDfMOFFQ== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-remap-async-to-generator" "^7.1.0" -"@babel/plugin-transform-block-scoped-functions@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.0.0.tgz#482b3f75103927e37288b3b67b65f848e2aa0d07" - integrity sha512-AOBiyUp7vYTqz2Jibe1UaAWL0Hl9JUXEgjFvvvcSc9MVDItv46ViXFw2F7SVt1B5k+KWjl44eeXOAk3UDEaJjQ== +"@babel/plugin-transform-block-scoped-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz#5d3cc11e8d5ddd752aa64c9148d0db6cb79fd190" + integrity sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-block-scoping@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.0.0.tgz#1745075edffd7cdaf69fab2fb6f9694424b7e9bc" - integrity sha512-GWEMCrmHQcYWISilUrk9GDqH4enf3UmhOEbNbNrlNAX1ssH3MsS1xLOS6rdjRVPgA7XXVPn87tRkdTEoA/dxEg== +"@babel/plugin-transform-block-scoping@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.2.0.tgz#f17c49d91eedbcdf5dd50597d16f5f2f770132d4" + integrity sha512-vDTgf19ZEV6mx35yiPJe4fS02mPQUUcBNwWQSZFXSzTSbsJFQvHt7DqyS3LK8oOWALFOsJ+8bbqBgkirZteD5Q== dependencies: "@babel/helper-plugin-utils" "^7.0.0" lodash "^4.17.10" -"@babel/plugin-transform-classes@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.1.0.tgz#ab3f8a564361800cbc8ab1ca6f21108038432249" - integrity sha512-rNaqoD+4OCBZjM7VaskladgqnZ1LO6o2UxuWSDzljzW21pN1KXkB7BstAVweZdxQkHAujps5QMNOTWesBciKFg== +"@babel/plugin-transform-classes@^7.2.0": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.2.2.tgz#6c90542f210ee975aa2aa8c8b5af7fa73a126953" + integrity sha512-gEZvgTy1VtcDOaQty1l10T3jQmJKlNVxLDCs+3rCVPr6nMkODLELxViq5X9l+rfxbie3XrfrMCYYY6eX3aOcOQ== dependencies: "@babel/helper-annotate-as-pure" "^7.0.0" "@babel/helper-define-map" "^7.1.0" @@ -355,103 +355,103 @@ "@babel/helper-split-export-declaration" "^7.0.0" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0.tgz#2fbb8900cd3e8258f2a2ede909b90e7556185e31" - integrity sha512-ubouZdChNAv4AAWAgU7QKbB93NU5sHwInEWfp+/OzJKA02E6Woh9RVoX4sZrbRwtybky/d7baTUqwFx+HgbvMA== +"@babel/plugin-transform-computed-properties@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz#83a7df6a658865b1c8f641d510c6f3af220216da" + integrity sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-destructuring@^7.0.0": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.1.3.tgz#e69ff50ca01fac6cb72863c544e516c2b193012f" - integrity sha512-Mb9M4DGIOspH1ExHOUnn2UUXFOyVTiX84fXCd+6B5iWrQg/QMeeRmSwpZ9lnjYLSXtZwiw80ytVMr3zue0ucYw== +"@babel/plugin-transform-destructuring@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.2.0.tgz#e75269b4b7889ec3a332cd0d0c8cff8fed0dc6f3" + integrity sha512-coVO2Ayv7g0qdDbrNiadE4bU7lvCd9H539m2gMknyVjjMdwF/iCOM7R+E8PkntoqLkltO0rk+3axhpp/0v68VQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-dotall-regex@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.0.0.tgz#73a24da69bc3c370251f43a3d048198546115e58" - integrity sha512-00THs8eJxOJUFVx1w8i1MBF4XH4PsAjKjQ1eqN/uCH3YKwP21GCKfrn6YZFZswbOk9+0cw1zGQPHVc1KBlSxig== +"@babel/plugin-transform-dotall-regex@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.2.0.tgz#f0aabb93d120a8ac61e925ea0ba440812dbe0e49" + integrity sha512-sKxnyHfizweTgKZf7XsXu/CNupKhzijptfTM+bozonIuyVrLWVUvYjE2bhuSBML8VQeMxq4Mm63Q9qvcvUcciQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" regexpu-core "^4.1.3" -"@babel/plugin-transform-duplicate-keys@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.0.0.tgz#a0601e580991e7cace080e4cf919cfd58da74e86" - integrity sha512-w2vfPkMqRkdxx+C71ATLJG30PpwtTpW7DDdLqYt2acXU7YjztzeWW2Jk1T6hKqCLYCcEA5UQM/+xTAm+QCSnuQ== +"@babel/plugin-transform-duplicate-keys@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz#d952c4930f312a4dbfff18f0b2914e60c35530b3" + integrity sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-exponentiation-operator@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.1.0.tgz#9c34c2ee7fd77e02779cfa37e403a2e1003ccc73" - integrity sha512-uZt9kD1Pp/JubkukOGQml9tqAeI8NkE98oZnHZ2qHRElmeKCodbTZgOEUtujSCSLhHSBWbzNiFSDIMC4/RBTLQ== +"@babel/plugin-transform-exponentiation-operator@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz#a63868289e5b4007f7054d46491af51435766008" + integrity sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A== dependencies: "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-flow-strip-types@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.0.0.tgz#c40ced34c2783985d90d9f9ac77a13e6fb396a01" - integrity sha512-WhXUNb4It5a19RsgKKbQPrjmy4yWOY1KynpEbNw7bnd1QTcrT/EIl3MJvnGgpgvrKyKbqX7nUNOJfkpLOnoDKA== + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.2.3.tgz#e3ac2a594948454e7431c7db33e1d02d51b5cd69" + integrity sha512-xnt7UIk9GYZRitqCnsVMjQK1O2eKZwFB3CvvHjf5SGx6K6vr/MScCKQDnf1DxRaj501e3pXjti+inbSXX2ZUoQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.0.0" + "@babel/plugin-syntax-flow" "^7.2.0" -"@babel/plugin-transform-for-of@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0.tgz#f2ba4eadb83bd17dc3c7e9b30f4707365e1c3e39" - integrity sha512-TlxKecN20X2tt2UEr2LNE6aqA0oPeMT1Y3cgz8k4Dn1j5ObT8M3nl9aA37LLklx0PBZKETC9ZAf9n/6SujTuXA== +"@babel/plugin-transform-for-of@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.2.0.tgz#ab7468befa80f764bb03d3cb5eef8cc998e1cad9" + integrity sha512-Kz7Mt0SsV2tQk6jG5bBv5phVbkd0gd27SgYD4hH1aLMJRchM0dzHaXvrWhVZ+WxAlDoAKZ7Uy3jVTW2mKXQ1WQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-function-name@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.1.0.tgz#29c5550d5c46208e7f730516d41eeddd4affadbb" - integrity sha512-VxOa1TMlFMtqPW2IDYZQaHsFrq/dDoIjgN098NowhexhZcz3UGlvPgZXuE1jEvNygyWyxRacqDpCZt+par1FNg== +"@babel/plugin-transform-function-name@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.2.0.tgz#f7930362829ff99a3174c39f0afcc024ef59731a" + integrity sha512-kWgksow9lHdvBC2Z4mxTsvc7YdY7w/V6B2vy9cTIPtLEE9NhwoWivaxdNM/S37elu5bqlLP/qOY906LukO9lkQ== dependencies: "@babel/helper-function-name" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-literals@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0.tgz#2aec1d29cdd24c407359c930cdd89e914ee8ff86" - integrity sha512-1NTDBWkeNXgpUcyoVFxbr9hS57EpZYXpje92zv0SUzjdu3enaRwF/l3cmyRnXLtIdyJASyiS6PtybK+CgKf7jA== +"@babel/plugin-transform-literals@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz#690353e81f9267dad4fd8cfd77eafa86aba53ea1" + integrity sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-modules-amd@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.1.0.tgz#f9e0a7072c12e296079b5a59f408ff5b97bf86a8" - integrity sha512-wt8P+xQ85rrnGNr2x1iV3DW32W8zrB6ctuBkYBbf5/ZzJY99Ob4MFgsZDFgczNU76iy9PWsy4EuxOliDjdKw6A== +"@babel/plugin-transform-modules-amd@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz#82a9bce45b95441f617a24011dc89d12da7f4ee6" + integrity sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw== dependencies: "@babel/helper-module-transforms" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-modules-commonjs@^7.0.0", "@babel/plugin-transform-modules-commonjs@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.1.0.tgz#0a9d86451cbbfb29bd15186306897c67f6f9a05c" - integrity sha512-wtNwtMjn1XGwM0AXPspQgvmE6msSJP15CX2RVfpTSTNPLhKhaOjaIfBaVfj4iUZ/VrFSodcFedwtPg/NxwQlPA== +"@babel/plugin-transform-modules-commonjs@^7.0.0", "@babel/plugin-transform-modules-commonjs@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.2.0.tgz#c4f1933f5991d5145e9cfad1dfd848ea1727f404" + integrity sha512-V6y0uaUQrQPXUrmj+hgnks8va2L0zcZymeU7TtWEgdRLNkceafKXEduv7QzgQAE4lT+suwooG9dC7LFhdRAbVQ== dependencies: "@babel/helper-module-transforms" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-simple-access" "^7.1.0" -"@babel/plugin-transform-modules-systemjs@^7.0.0": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.1.3.tgz#2119a3e3db612fd74a19d88652efbfe9613a5db0" - integrity sha512-PvTxgjxQAq4pvVUZF3mD5gEtVDuId8NtWkJsZLEJZMZAW3TvgQl1pmydLLN1bM8huHFVVU43lf0uvjQj9FRkKw== +"@babel/plugin-transform-modules-systemjs@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.2.0.tgz#912bfe9e5ff982924c81d0937c92d24994bb9068" + integrity sha512-aYJwpAhoK9a+1+O625WIjvMY11wkB/ok0WClVwmeo3mCjcNRjt+/8gHWrB5i+00mUju0gWsBkQnPpdvQ7PImmQ== dependencies: "@babel/helper-hoist-variables" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-modules-umd@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.1.0.tgz#a29a7d85d6f28c3561c33964442257cc6a21f2a8" - integrity sha512-enrRtn5TfRhMmbRwm7F8qOj0qEYByqUvTttPEGimcBH4CJHphjyK1Vg7sdU7JjeEmgSpM890IT/efS2nMHwYig== +"@babel/plugin-transform-modules-umd@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz#7678ce75169f0877b8eb2235538c074268dd01ae" + integrity sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw== dependencies: "@babel/helper-module-transforms" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -463,31 +463,31 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-object-super@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.1.0.tgz#b1ae194a054b826d8d4ba7ca91486d4ada0f91bb" - integrity sha512-/O02Je1CRTSk2SSJaq0xjwQ8hG4zhZGNjE8psTsSNPXyLRCODv7/PBozqT5AmQMzp7MI3ndvMhGdqp9c96tTEw== +"@babel/plugin-transform-object-super@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz#b35d4c10f56bab5d650047dad0f1d8e8814b6598" + integrity sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-replace-supers" "^7.1.0" -"@babel/plugin-transform-parameters@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.1.0.tgz#44f492f9d618c9124026e62301c296bf606a7aed" - integrity sha512-vHV7oxkEJ8IHxTfRr3hNGzV446GAb+0hgbA7o/0Jd76s+YzccdWuTU296FOCOl/xweU4t/Ya4g41yWz80RFCRw== +"@babel/plugin-transform-parameters@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.2.0.tgz#0d5ad15dc805e2ea866df4dd6682bfe76d1408c2" + integrity sha512-kB9+hhUidIgUoBQ0MsxMewhzr8i60nMa2KgeJKQWYrqQpqcBYtnpR+JgkadZVZoaEZ/eKu9mclFaVwhRpLNSzA== dependencies: "@babel/helper-call-delegate" "^7.1.0" "@babel/helper-get-function-arity" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-react-jsx@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.0.0.tgz#524379e4eca5363cd10c4446ba163f093da75f3e" - integrity sha512-0TMP21hXsSUjIQJmu/r7RiVxeFrXRcMUigbKu0BLegJK9PkYodHstaszcig7zxXfaBji2LYUdtqIkHs+hgYkJQ== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.2.0.tgz#ca36b6561c4d3b45524f8efb6f0fbc9a0d1d622f" + integrity sha512-h/fZRel5wAfCqcKgq3OhbmYaReo7KkoJBpt8XnvpS7wqaNMqtw5xhxutzcm35iMUWucfAdT/nvGTsWln0JTg2Q== dependencies: "@babel/helper-builder-react-jsx" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.0.0" + "@babel/plugin-syntax-jsx" "^7.2.0" "@babel/plugin-transform-regenerator@^7.0.0": version "7.0.0" @@ -496,134 +496,134 @@ dependencies: regenerator-transform "^0.13.3" -"@babel/plugin-transform-shorthand-properties@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0.tgz#85f8af592dcc07647541a0350e8c95c7bf419d15" - integrity sha512-g/99LI4vm5iOf5r1Gdxq5Xmu91zvjhEG5+yZDJW268AZELAu4J1EiFLnkSG3yuUsZyOipVOVUKoGPYwfsTymhw== +"@babel/plugin-transform-shorthand-properties@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz#6333aee2f8d6ee7e28615457298934a3b46198f0" + integrity sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-spread@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0.tgz#93583ce48dd8c85e53f3a46056c856e4af30b49b" - integrity sha512-L702YFy2EvirrR4shTj0g2xQp7aNwZoWNCkNu2mcoU0uyzMl0XRwDSwzB/xp6DSUFiBmEXuyAyEN16LsgVqGGQ== +"@babel/plugin-transform-spread@^7.2.0": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz#3103a9abe22f742b6d406ecd3cd49b774919b406" + integrity sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-sticky-regex@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.0.0.tgz#30a9d64ac2ab46eec087b8530535becd90e73366" - integrity sha512-LFUToxiyS/WD+XEWpkx/XJBrUXKewSZpzX68s+yEOtIbdnsRjpryDw9U06gYc6klYEij/+KQVRnD3nz3AoKmjw== +"@babel/plugin-transform-sticky-regex@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz#a1e454b5995560a9c1e0d537dfc15061fd2687e1" + integrity sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" -"@babel/plugin-transform-template-literals@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0.tgz#084f1952efe5b153ddae69eb8945f882c7a97c65" - integrity sha512-vA6rkTCabRZu7Nbl9DfLZE1imj4tzdWcg5vtdQGvj+OH9itNNB6hxuRMHuIY8SGnEt1T9g5foqs9LnrHzsqEFg== +"@babel/plugin-transform-template-literals@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.2.0.tgz#d87ed01b8eaac7a92473f608c97c089de2ba1e5b" + integrity sha512-FkPix00J9A/XWXv4VoKJBMeSkyY9x/TqIh76wzcdfl57RJJcf8CehQ08uwfhCDNtRQYtHQKBTwKZDEyjE13Lwg== dependencies: "@babel/helper-annotate-as-pure" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-typeof-symbol@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.0.0.tgz#4dcf1e52e943e5267b7313bff347fdbe0f81cec9" - integrity sha512-1r1X5DO78WnaAIvs5uC48t41LLckxsYklJrZjNKcevyz83sF2l4RHbw29qrCPr/6ksFsdfRpT/ZgxNWHXRnffg== +"@babel/plugin-transform-typeof-symbol@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz#117d2bcec2fbf64b4b59d1f9819894682d29f2b2" + integrity sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-unicode-regex@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.0.0.tgz#c6780e5b1863a76fe792d90eded9fcd5b51d68fc" - integrity sha512-uJBrJhBOEa3D033P95nPHu3nbFwFE9ZgXsfEitzoIXIwqAZWk7uXcg06yFKXz9FSxBH5ucgU/cYdX0IV8ldHKw== +"@babel/plugin-transform-unicode-regex@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.2.0.tgz#4eb8db16f972f8abb5062c161b8b115546ade08b" + integrity sha512-m48Y0lMhrbXEJnVUaYly29jRXbQ3ksxPrS1Tg8t+MHqzXhtBYAvI51euOBaoAlZLPHsieY9XPVMf80a5x0cPcA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" regexpu-core "^4.1.3" "@babel/preset-env@^7.0.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.1.0.tgz#e67ea5b0441cfeab1d6f41e9b5c79798800e8d11" - integrity sha512-ZLVSynfAoDHB/34A17/JCZbyrzbQj59QC1Anyueb4Bwjh373nVPq5/HMph0z+tCmcDjXDe+DlKQq9ywQuvWrQg== + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.2.3.tgz#948c8df4d4609c99c7e0130169f052ea6a7a8933" + integrity sha512-AuHzW7a9rbv5WXmvGaPX7wADxFkZIqKlbBh1dmZUQp4iwiPpkE/Qnrji6SC4UQCQzvWY/cpHET29eUhXS9cLPw== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-async-generator-functions" "^7.1.0" - "@babel/plugin-proposal-json-strings" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.0.0" - "@babel/plugin-syntax-async-generators" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.0.0" - "@babel/plugin-transform-arrow-functions" "^7.0.0" - "@babel/plugin-transform-async-to-generator" "^7.1.0" - "@babel/plugin-transform-block-scoped-functions" "^7.0.0" - "@babel/plugin-transform-block-scoping" "^7.0.0" - "@babel/plugin-transform-classes" "^7.1.0" - "@babel/plugin-transform-computed-properties" "^7.0.0" - "@babel/plugin-transform-destructuring" "^7.0.0" - "@babel/plugin-transform-dotall-regex" "^7.0.0" - "@babel/plugin-transform-duplicate-keys" "^7.0.0" - "@babel/plugin-transform-exponentiation-operator" "^7.1.0" - "@babel/plugin-transform-for-of" "^7.0.0" - "@babel/plugin-transform-function-name" "^7.1.0" - "@babel/plugin-transform-literals" "^7.0.0" - "@babel/plugin-transform-modules-amd" "^7.1.0" - "@babel/plugin-transform-modules-commonjs" "^7.1.0" - "@babel/plugin-transform-modules-systemjs" "^7.0.0" - "@babel/plugin-transform-modules-umd" "^7.1.0" + "@babel/plugin-proposal-async-generator-functions" "^7.2.0" + "@babel/plugin-proposal-json-strings" "^7.2.0" + "@babel/plugin-proposal-object-rest-spread" "^7.2.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.2.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.2.0" + "@babel/plugin-syntax-async-generators" "^7.2.0" + "@babel/plugin-syntax-object-rest-spread" "^7.2.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" + "@babel/plugin-transform-arrow-functions" "^7.2.0" + "@babel/plugin-transform-async-to-generator" "^7.2.0" + "@babel/plugin-transform-block-scoped-functions" "^7.2.0" + "@babel/plugin-transform-block-scoping" "^7.2.0" + "@babel/plugin-transform-classes" "^7.2.0" + "@babel/plugin-transform-computed-properties" "^7.2.0" + "@babel/plugin-transform-destructuring" "^7.2.0" + "@babel/plugin-transform-dotall-regex" "^7.2.0" + "@babel/plugin-transform-duplicate-keys" "^7.2.0" + "@babel/plugin-transform-exponentiation-operator" "^7.2.0" + "@babel/plugin-transform-for-of" "^7.2.0" + "@babel/plugin-transform-function-name" "^7.2.0" + "@babel/plugin-transform-literals" "^7.2.0" + "@babel/plugin-transform-modules-amd" "^7.2.0" + "@babel/plugin-transform-modules-commonjs" "^7.2.0" + "@babel/plugin-transform-modules-systemjs" "^7.2.0" + "@babel/plugin-transform-modules-umd" "^7.2.0" "@babel/plugin-transform-new-target" "^7.0.0" - "@babel/plugin-transform-object-super" "^7.1.0" - "@babel/plugin-transform-parameters" "^7.1.0" + "@babel/plugin-transform-object-super" "^7.2.0" + "@babel/plugin-transform-parameters" "^7.2.0" "@babel/plugin-transform-regenerator" "^7.0.0" - "@babel/plugin-transform-shorthand-properties" "^7.0.0" - "@babel/plugin-transform-spread" "^7.0.0" - "@babel/plugin-transform-sticky-regex" "^7.0.0" - "@babel/plugin-transform-template-literals" "^7.0.0" - "@babel/plugin-transform-typeof-symbol" "^7.0.0" - "@babel/plugin-transform-unicode-regex" "^7.0.0" - browserslist "^4.1.0" + "@babel/plugin-transform-shorthand-properties" "^7.2.0" + "@babel/plugin-transform-spread" "^7.2.0" + "@babel/plugin-transform-sticky-regex" "^7.2.0" + "@babel/plugin-transform-template-literals" "^7.2.0" + "@babel/plugin-transform-typeof-symbol" "^7.2.0" + "@babel/plugin-transform-unicode-regex" "^7.2.0" + browserslist "^4.3.4" invariant "^2.2.2" js-levenshtein "^1.1.3" semver "^5.3.0" "@babel/runtime@^7.0.0": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.1.2.tgz#81c89935f4647706fc54541145e6b4ecfef4b8e3" - integrity sha512-Y3SCjmhSupzFB6wcv1KmmFucH6gDVnI30WjOcicV10ju0cZjak3Jcs67YLIXBrmZYw1xCrVeJPbycFwrqNyxpg== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.2.0.tgz#b03e42eeddf5898e00646e4c840fa07ba8dcad7f" + integrity sha512-oouEibCbHMVdZSDlJBO6bZmID/zA/G/Qx3H1d3rSNPTD+L8UNKvCat7aKWSJ74zYbm5zWGh0GQN0hKj8zYFTCg== dependencies: regenerator-runtime "^0.12.0" -"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.1.2": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.1.2.tgz#090484a574fef5a2d2d7726a674eceda5c5b5644" - integrity sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag== +"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.1.2", "@babel/template@^7.2.2": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.2.2.tgz#005b3fdf0ed96e88041330379e0da9a708eb2907" + integrity sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.1.2" - "@babel/types" "^7.1.2" + "@babel/parser" "^7.2.2" + "@babel/types" "^7.2.2" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0": - version "7.1.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.1.4.tgz#f4f83b93d649b4b2c91121a9087fa2fa949ec2b4" - integrity sha512-my9mdrAIGdDiSVBuMjpn/oXYpva0/EZwWL3sm3Wcy/AVWO2eXnsoZruOT9jOGNRXU8KbCIu5zsKnXcAJ6PcV6Q== +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5", "@babel/traverse@^7.2.2", "@babel/traverse@^7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.2.3.tgz#7ff50cefa9c7c0bd2d81231fdac122f3957748d8" + integrity sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.1.3" + "@babel/generator" "^7.2.2" "@babel/helper-function-name" "^7.1.0" "@babel/helper-split-export-declaration" "^7.0.0" - "@babel/parser" "^7.1.3" - "@babel/types" "^7.1.3" - debug "^3.1.0" + "@babel/parser" "^7.2.3" + "@babel/types" "^7.2.2" + debug "^4.1.0" globals "^11.1.0" lodash "^4.17.10" -"@babel/types@^7.0.0", "@babel/types@^7.1.2", "@babel/types@^7.1.3": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.1.3.tgz#3a767004567060c2f40fca49a304712c525ee37d" - integrity sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA== +"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.2.2": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.2.2.tgz#44e10fc24e33af524488b716cdaee5360ea8ed1e" + integrity sha512-fKCuD6UFUMkR541eDWL+2ih/xFZBXPOg/7EQFeTluMDebfqR4jrpaCjLhkWlQS4hT6nRa2PMEgXKbRB5/H2fpg== dependencies: esutils "^2.0.2" lodash "^4.17.10" @@ -1234,10 +1234,10 @@ call-me-maybe "^1.0.1" glob-to-regexp "^0.3.0" -"@nodelib/fs.stat@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.2.tgz#54c5a964462be3d4d78af631363c18d6fa91ac26" - integrity sha512-yprFYuno9FtNsSHVlSWd+nRlmGoAbqbeCwOryP6sC/zoCjhpArcRMYp19EvpSUSizJAlsXEwJv+wcWS9XaXdMw== +"@nodelib/fs.stat@^1.1.2": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" + integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== "@parcel/fs@^1.11.0": version "1.11.0" @@ -1280,6 +1280,11 @@ "@parcel/utils" "^1.11.0" physical-cpu-count "^2.0.0" +"@types/estree@0.0.39": + version "0.0.39" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== + "@types/events@*": version "1.2.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" @@ -1302,9 +1307,9 @@ "@types/node" "*" "@types/handlebars@^4.0.38": - version "4.0.39" - resolved "https://registry.yarnpkg.com/@types/handlebars/-/handlebars-4.0.39.tgz#961fb54db68030890942e6aeffe9f93a957807bd" - integrity sha512-vjaS7Q0dVqFp85QhyPSZqDKnTTCemcSHNHFvDdalO1s0Ifz5KuE64jQD5xoUkfdWwF4WpqdJEl7LsWH8rzhKJA== + version "4.0.40" + resolved "https://registry.yarnpkg.com/@types/handlebars/-/handlebars-4.0.40.tgz#b714e13d296a75bff3f199316d1311933ca79ffd" + integrity sha512-sGWNtsjNrLOdKha2RV1UeF8+UbQnPSG7qbe5wwbni0mw4h2gHXyPFUMOC+xwGirIiiydM/HSqjDO4rk6NFB18w== "@types/highlight.js@^9.12.3": version "9.12.3" @@ -1312,9 +1317,9 @@ integrity sha512-pGF/zvYOACZ/gLGWdQH8zSwteQS1epp68yRcVLJMgUck/MjEn/FBYmPub9pXT8C1e4a8YZfHo1CKyV8q1vKUnQ== "@types/lodash@^4.14.110": - version "4.14.117" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.117.tgz#695a7f514182771a1e0f4345d189052ee33c8778" - integrity sha512-xyf2m6tRbz8qQKcxYZa7PA4SllYcay+eh25DN3jmNYY6gSTL7Htc/bttVdkqj2wfJGbeWlQiX8pIyJpKU+tubw== + version "4.14.119" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.119.tgz#be847e5f4bc3e35e46d041c394ead8b603ad8b39" + integrity sha512-Z3TNyBL8Vd/M9D9Ms2S3LmFq2sSMzahodD6rCS9V2N44HUMINb75jNkSuwAx7eo2ufqTdfOdtGQpNbieUjPQmw== "@types/marked@^0.4.0": version "0.4.2" @@ -1331,15 +1336,15 @@ resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.5.tgz#8a4accfc403c124a0bafe8a9fc61a05ec1032073" integrity sha512-lAVp+Kj54ui/vLUFxsJTMtWvZraZxum3w3Nwkble2dNuV5VnPA+Mi2oGX9XYJAaIvZi3tn3cbjS/qcJXRb6Bww== -"@types/node@*", "@types/node@^10.11.7": - version "10.12.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.0.tgz#ea6dcbddbc5b584c83f06c60e82736d8fbb0c235" - integrity sha512-3TUHC3jsBAB7qVRGxT6lWyYo2v96BMmD2PTcl47H25Lu7UXtFH/2qqmKiVrnel6Ne//0TFYf6uvNX+HW2FRkLQ== +"@types/node@*", "@types/node@^10.11.7", "@types/node@^10.12.15": + version "10.12.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" + integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== -"@types/node@^10.12.15": - version "10.12.15" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.15.tgz#20e85651b62fd86656e57c9c9bc771ab1570bc59" - integrity sha512-9kROxduaN98QghwwHmxXO2Xz3MaWf+I1sLVAA6KJDF5xix+IyXVhds0MAfdNwtcpSrzhaTsNB0/jnL86fgUhqA== +"@types/q@^1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.1.tgz#48fd98c1561fe718b61733daed46ff115b496e18" + integrity sha512-eqz8c/0kwNi/OEHQfvIuJVLTst3in0e7uTKeuY+WL/zfKn0xVujOTp42bS/vUUokhK5P2BppLd9JXMOMHcgbjA== "@types/semver@^5.5.0": version "5.5.0" @@ -1347,9 +1352,9 @@ integrity sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ== "@types/shelljs@^0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.8.0.tgz#0caa56b68baae4f68f44e0dd666ab30b098e3632" - integrity sha512-vs1hCC8RxLHRu2bwumNyYRNrU3o8BtZhLysH5A4I98iYmA2APl6R3uNQb5ihl+WiwH0xdC9LLO+vRrXLs/Kyxg== + version "0.8.1" + resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.8.1.tgz#133e874b5fb816a2e1c8647839c82d76760b1191" + integrity sha512-1lQw+48BuVgp6c1+z8EMipp18IdnV2dLh6KQGwOm+kJy9nPjEkaqRKmwbDNEYf//EKBvKcwOC6V2cDrNxVoQeQ== dependencies: "@types/glob" "*" "@types/node" "*" @@ -1377,6 +1382,11 @@ acorn@^5.0.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== +acorn@^6.0.4: + version "6.0.5" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.5.tgz#81730c0815f3f3b34d8efa95cb7430965f4d887a" + integrity sha512-i33Zgp3XWtmZBMNvCr4azvOFeWVw1Rk6p3hfi3LUDvIFraOMywb1kAtrbi+med14m4Xfpqm3zRZMT+c0FNE7kg== + agent-base@4, agent-base@^4.1.0, agent-base@~4.2.0: version "4.2.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" @@ -1385,21 +1395,21 @@ agent-base@4, agent-base@^4.1.0, agent-base@~4.2.0: es6-promisify "^5.0.0" agentkeepalive@^3.4.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-3.5.1.tgz#4eba75cf2ad258fc09efd506cdb8d8c2971d35a4" - integrity sha512-Cte/sTY9/XcygXjJ0q58v//SnEQ7ViWExKyJpLJlLqomDbQyMLh6Is4KuWJ/wmxzhiwkGRple7Gqv1zf6Syz5w== + version "3.5.2" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-3.5.2.tgz#a113924dd3fa24a0bc3b78108c450c2abee00f67" + integrity sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ== dependencies: humanize-ms "^1.2.1" -ajv@^5.3.0: - version "5.5.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" - integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU= +ajv@^6.5.5: + version "6.6.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.6.2.tgz#caceccf474bf3fc3ce3b147443711a24063cc30d" + integrity sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g== dependencies: - co "^4.6.0" - fast-deep-equal "^1.0.0" + fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.3.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" alphanum-sort@^1.0.0, alphanum-sort@^1.0.1, alphanum-sort@^1.0.2: version "1.0.2" @@ -1421,6 +1431,11 @@ ansi-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= +ansi-regex@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.0.0.tgz#70de791edf021404c3fd615aa89118ae0432e5a9" + integrity sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w== + ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" @@ -1434,9 +1449,9 @@ ansi-styles@^3.2.1: color-convert "^1.9.0" ansi-to-html@^0.6.4: - version "0.6.6" - resolved "https://registry.yarnpkg.com/ansi-to-html/-/ansi-to-html-0.6.6.tgz#58a8d04b87ec9a85e3ad273c12a5fbc7147b9c42" - integrity sha512-90M/2sZna3OsoOEbSyXK46poFnlClBC53Rx6etNKQK7iShsX5fI5E/M9Ld6FurtLaxAWLuAPi0Jp8p3y5oAkxg== + version "0.6.9" + resolved "https://registry.yarnpkg.com/ansi-to-html/-/ansi-to-html-0.6.9.tgz#f4f2e2361792269cc62da85944f39759fc71b1e2" + integrity sha512-hwNdg2DNgCzsrvaNc+LDqSxJkpxf9oEt4R7KE0IeURXhEOlontEqNpXNiGeFBpSes8TZF+ZZ9sjB85QzjPsI6A== dependencies: entities "^1.1.1" @@ -1731,16 +1746,11 @@ block-stream@*: dependencies: inherits "~2.0.0" -bluebird@^3.5.0, bluebird@^3.5.2, bluebird@^3.5.3: +bluebird@^3.5.0, bluebird@^3.5.1, bluebird@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7" integrity sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw== -bluebird@^3.5.1: - version "3.5.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.2.tgz#1be0908e054a751754549c270489c1505d4ab15a" - integrity sha512-dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg== - bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: version "4.11.8" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" @@ -1862,14 +1872,14 @@ browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6: caniuse-db "^1.0.30000639" electron-to-chromium "^1.2.7" -browserslist@^4.0.0, browserslist@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.2.1.tgz#257a24c879d1cd4016348eee5c25de683260b21d" - integrity sha512-1oO0c7Zhejwd+LXihS89WqtKionSbz298rJZKJgfrHIZhrV8AC15gw553VcB0lcEugja7IhWD7iAlrsamfYVPA== +browserslist@^4.0.0, browserslist@^4.1.0, browserslist@^4.3.4: + version "4.3.7" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.3.7.tgz#f1de479a6466ea47a0a26dcc725e7504817e624a" + integrity sha512-pWQv51Ynb0MNk9JGMCZ8VkM785/4MQNXiFYtPqI7EEP0TJO+/d/NqRVn1uiAN0DNbnlUSpL2sh16Kspasv3pUQ== dependencies: - caniuse-lite "^1.0.30000890" - electron-to-chromium "^1.3.79" - node-releases "^1.0.0-alpha.14" + caniuse-lite "^1.0.30000925" + electron-to-chromium "^1.3.96" + node-releases "^1.1.3" buffer-equal@0.0.1: version "0.0.1" @@ -1916,48 +1926,28 @@ byline@^5.0.0: integrity sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE= byte-size@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-4.0.3.tgz#b7c095efc68eadf82985fccd9a2df43a74fa2ccd" - integrity sha512-JGC3EV2bCzJH/ENSh3afyJrH4vwxbHTuO5ljLoI5+2iJOcEpMgP8T782jH9b5qGxf2mSUIp1lfGnfKNrRHpvVg== - -cacache@^11.0.1: - version "11.2.0" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.2.0.tgz#617bdc0b02844af56310e411c0878941d5739965" - integrity sha512-IFWl6lfK6wSeYCHUXh+N1lY72UDrpyrYQJNIVQf48paDuWbv5RbAtJYf/4gUQFObTCHZwdZ5sI8Iw7nqwP6nlQ== - dependencies: - bluebird "^3.5.1" - chownr "^1.0.1" - figgy-pudding "^3.1.0" - glob "^7.1.2" - graceful-fs "^4.1.11" - lru-cache "^4.1.3" - mississippi "^3.0.0" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - promise-inflight "^1.0.1" - rimraf "^2.6.2" - ssri "^6.0.0" - unique-filename "^1.1.0" - y18n "^4.0.0" + version "4.0.4" + resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-4.0.4.tgz#29d381709f41aae0d89c631f1c81aec88cd40b23" + integrity sha512-82RPeneC6nqCdSwCX2hZUz3JPOvN5at/nTEw/CMf05Smu3Hrpo9Psb7LjN+k+XndNArG1EY8L4+BM3aTM4BCvw== -cacache@^11.2.0: - version "11.3.1" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.1.tgz#d09d25f6c4aca7a6d305d141ae332613aa1d515f" - integrity sha512-2PEw4cRRDu+iQvBTTuttQifacYjLPhET+SYO/gEFMy8uhi+jlJREDAjSF5FWSdV/Aw5h18caHA7vMTw2c+wDzA== +cacache@^11.0.1, cacache@^11.3.2: + version "11.3.2" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.2.tgz#2d81e308e3d258ca38125b676b98b2ac9ce69bfa" + integrity sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg== dependencies: - bluebird "^3.5.1" - chownr "^1.0.1" - figgy-pudding "^3.1.0" - glob "^7.1.2" - graceful-fs "^4.1.11" - lru-cache "^4.1.3" + bluebird "^3.5.3" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.3" + graceful-fs "^4.1.15" + lru-cache "^5.1.1" mississippi "^3.0.0" mkdirp "^0.5.1" move-concurrently "^1.0.1" promise-inflight "^1.0.1" rimraf "^2.6.2" - ssri "^6.0.0" - unique-filename "^1.1.0" + ssri "^6.0.1" + unique-filename "^1.1.1" y18n "^4.0.0" cache-base@^1.0.1: @@ -1990,6 +1980,25 @@ call-me-maybe@^1.0.1: resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= +caller-callsite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + dependencies: + callsites "^2.0.0" + +caller-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + dependencies: + caller-callsite "^2.0.0" + +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + camelcase-keys@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" @@ -2017,6 +2026,11 @@ camelcase@^4.1.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= +camelcase@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" + integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== + caniuse-api@^1.5.2: version "1.6.1" resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.6.1.tgz#b534e7c734c4f81ec5fbe8aca2ad24354b962c6c" @@ -2038,14 +2052,14 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: - version "1.0.30000892" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000892.tgz#3a03ecec4283caa5dac49facf024d13113c4499f" - integrity sha512-as/DXjiFJg051+GSJLmkY0hckkVsmTB4nuDUPLwK1sMHk94XsYuocNJuU0wdOpobwI/3sqNeW5ETebvdPGvwBQ== + version "1.0.30000927" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000927.tgz#9906eecf59ae7ee5d1bb2c16cf06fc31b642bfda" + integrity sha512-CX/QvLA8oh7kQ9cHCCzFm0UZW4KwSyQSRJ5A1XtH42HaMJQ0yh+9fEVWagMqv9I1vSCtaqA5Mb8k0uKfv7jhDw== -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000890: - version "1.0.30000892" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000892.tgz#344d2b51ee3ff5977537da4aa449c90eec40b759" - integrity sha512-X9rxMaWZNbJB5qjkDqPtNv/yfViTeUL6ILk0QJNxLV3OhKC5Acn5vxsuUvllR6B48mog8lmS+whwHq/QIYSL9w== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000925: + version "1.0.30000927" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000927.tgz#114a9de4ff1e01f5790fe578ecd93421c7524665" + integrity sha512-ogq4NbUWf1uG/j66k0AmiO3GjqJAlQyF8n4w8a954cbCyFKmYGvRtgz6qkq2fWuduTXHibX7GyYL5Pg58Aks2g== caseless@~0.12.0: version "0.12.0" @@ -2064,9 +2078,9 @@ chalk@^1.1.3: supports-color "^2.0.0" chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" - integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== dependencies: ansi-styles "^3.2.1" escape-string-regexp "^1.0.5" @@ -2097,7 +2111,7 @@ chokidar@^2.0.3: optionalDependencies: fsevents "^1.2.2" -chownr@^1.0.1, chownr@^1.1.1: +chownr@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== @@ -2168,10 +2182,10 @@ clone@^2.1.1: resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= -clones@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/clones/-/clones-1.1.0.tgz#87e904132d6140c5c0b72006c08c0d05bd7b63b3" - integrity sha1-h+kEEy1hQMXAtyAGwIwNBb17Y7M= +clones@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/clones/-/clones-1.2.0.tgz#b34c872045446a9f264ccceb7731bca05c529b71" + integrity sha512-FXDYw4TjR8wgPZYui2LeTqWh1BLpfQ8lB6upMtlpDF6WlOOxghmTTxWyngdKTgozqBgKnHbTVwTE+hOHqAykuQ== cmd-shim@^2.0.2: version "2.0.2" @@ -2181,11 +2195,6 @@ cmd-shim@^2.0.2: graceful-fs "^4.1.2" mkdirp "~0.5.0" -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= - coa@~1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.4.tgz#a9ef153660d6a86a8bdec0289a5c684d217432fd" @@ -2194,10 +2203,12 @@ coa@~1.0.1: q "^1.1.2" coa@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.1.tgz#f3f8b0b15073e35d70263fb1042cb2c023db38af" - integrity sha512-5wfTTO8E2/ja4jFSxePXlG5nRu5bBtL/r1HCIpJW/lzT6yDtKl0u0Z4o/Vpz32IpKmBn7HerheEZQgA9N2DarQ== + version "2.0.2" + resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" + integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA== dependencies: + "@types/q" "^1.5.1" + chalk "^2.4.1" q "^1.1.2" code-point-at@^1.0.0: @@ -2344,7 +2355,7 @@ concat-stream@^1.5.0, concat-stream@^1.6.0, concat-stream@~1.6.0: readable-stream "^2.2.2" typedarray "^0.0.6" -config-chain@^1.1.11, config-chain@~1.1.5: +config-chain@^1.1.11, config-chain@^1.1.12: version "1.1.12" resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA== @@ -2477,9 +2488,9 @@ copy-descriptor@^0.1.0: integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= core-js@^2.4.0: - version "2.5.7" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" - integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw== + version "2.6.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.1.tgz#87416ae817de957a3f249b3b5ca475d4aaed6042" + integrity sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg== core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" @@ -2487,10 +2498,11 @@ core-util-is@1.0.2, core-util-is@~1.0.0: integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= cosmiconfig@^5.0.0, cosmiconfig@^5.0.2: - version "5.0.6" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.6.tgz#dca6cf680a0bd03589aff684700858c81abeeb39" - integrity sha512-6DWfizHriCrFWURP1/qyhsiFvYdlJzbCzmtFWh744+KyWsJo5+kPzUZZaMRSSItoYc0pxFX7gEO7ZC1/gN/7AQ== + version "5.0.7" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.7.tgz#39826b292ee0d78eda137dfa3173bd1c21a43b04" + integrity sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA== dependencies: + import-fresh "^2.0.0" is-directory "^0.3.1" js-yaml "^3.9.0" parse-json "^4.0.0" @@ -2585,19 +2597,19 @@ css-declaration-sorter@^4.0.1: timsort "^0.3.0" css-select-base-adapter@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.0.tgz#0102b3d14630df86c3eb9fa9f5456270106cf990" - integrity sha1-AQKz0UYw34bD65+p9UVicBBs+ZA= + version "0.1.1" + resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" + integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== css-select@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.0.0.tgz#7aa2921392114831f68db175c0b6a555df74bbd5" - integrity sha512-MGhoq1S9EyPgZIGnts8Yz5WwUOyHmPMdlqeifsYs/xFX7AAm3hY0RJe1dqVlXtYPI66Nsk39R/sa5/ree6L2qg== + version "2.0.2" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.0.2.tgz#ab4386cec9e1f668855564b17c3733b43b2a5ede" + integrity sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ== dependencies: boolbase "^1.0.0" - css-what "2.1" + css-what "^2.1.2" domutils "^1.7.0" - nth-check "^1.0.1" + nth-check "^1.0.2" css-tree@1.0.0-alpha.28: version "1.0.0-alpha.28" @@ -2625,27 +2637,32 @@ css-url-regex@^1.1.0: resolved "https://registry.yarnpkg.com/css-url-regex/-/css-url-regex-1.1.0.tgz#83834230cc9f74c457de59eebd1543feeb83b7ec" integrity sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w= -css-what@2.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd" - integrity sha1-lGfQMsOM+u+58teVASUwYvh/ob0= +css-what@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.2.tgz#c0876d9d0480927d7d4920dcd72af3595649554d" + integrity sha512-wan8dMWQ0GUeF7DGEPVjhHemVW/vy6xUYmFzRY8RYqgA0JtXC9rJmbScBjqSu6dg9q0lwPQy6ZAmJVr3PPTvqQ== -cssnano-preset-default@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.2.tgz#1de3f27e73b7f0fbf87c1d7fd7a63ae980ac3774" - integrity sha512-zO9PeP84l1E4kbrdyF7NSLtA/JrJY1paX5FHy5+w/ziIXO2kDqDMfJ/mosXkaHHSa3RPiIY3eB6aEgwx3IiGqA== +cssesc@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" + integrity sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg== + +cssnano-preset-default@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.6.tgz#92379e2a6db4a91c0ea727f5f556eeac693eab6a" + integrity sha512-UPboYbFaJFtDUhJ4fqctThWbbyF4q01/7UhsZbLzp35l+nUxtzh1SifoVlEfyLM3n3Z0htd8B1YlCxy9i+bQvg== dependencies: css-declaration-sorter "^4.0.1" cssnano-util-raw-cache "^4.0.1" postcss "^7.0.0" - postcss-calc "^6.0.2" + postcss-calc "^7.0.0" postcss-colormin "^4.0.2" postcss-convert-values "^4.0.1" postcss-discard-comments "^4.0.1" postcss-discard-duplicates "^4.0.2" postcss-discard-empty "^4.0.1" postcss-discard-overridden "^4.0.1" - postcss-merge-longhand "^4.0.6" + postcss-merge-longhand "^4.0.10" postcss-merge-rules "^4.0.2" postcss-minify-font-values "^4.0.2" postcss-minify-gradients "^4.0.1" @@ -2727,12 +2744,12 @@ cssnano@^3.4.0: postcss-zindex "^2.0.1" cssnano@^4.0.0: - version "4.1.4" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.4.tgz#55b71e3d8f5451dd3edc7955673415c98795788f" - integrity sha512-wP0wbOM9oqsek14CiNRYrK9N3w3jgadtGZKHXysgC/OMVpy0KZgWVPdNqODSZbz7txO9Gekr9taOfcCgL0pOOw== + version "4.1.8" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.8.tgz#8014989679d5fd42491e4499a521dbfb85c95fd1" + integrity sha512-5GIY0VzAHORpbKiL3rMXp4w4M1Ki+XlXgEXyuWXVd3h6hlASb+9Vo76dNP56/elLMVBBsUfusCo1q56uW0UWig== dependencies: cosmiconfig "^5.0.0" - cssnano-preset-default "^4.0.2" + cssnano-preset-default "^4.0.6" is-resolvable "^1.0.0" postcss "^7.0.0" @@ -2821,6 +2838,13 @@ debug@^3.1.0: dependencies: ms "^2.1.1" +debug@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" @@ -2834,18 +2858,11 @@ decamelize-keys@^1.0.0: decamelize "^1.1.0" map-obj "^1.0.0" -decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.1.2: +decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= -decamelize@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-2.0.0.tgz#656d7bbc8094c4c788ea53c5840908c9c7d063c7" - integrity sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg== - dependencies: - xregexp "4.0.0" - decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" @@ -2880,7 +2897,7 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" -define-properties@^1.1.2: +define-properties@^1.1.2, define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== @@ -2996,9 +3013,9 @@ domain-browser@^1.1.1: integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== domelementtype@1, domelementtype@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2" - integrity sha1-sXrtguirWeUt2cGbF1bg/BhyBMI= + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== domelementtype@~1.1.1: version "1.1.3" @@ -3074,7 +3091,7 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -editorconfig@^0.15.0: +editorconfig@^0.15.2: version "0.15.2" resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.2.tgz#047be983abb9ab3c2eefe5199cb2b7c5689f0702" integrity sha512-GWjSI19PVJAM9IZRGOS+YKI8LN+/sjkSjNyvxL5ucqP9/IqtYNXBaQ/6c/hkPNYQHyOHra2KoXZI/JVpuqwmcQ== @@ -3091,10 +3108,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.79: - version "1.3.79" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.79.tgz#774718f06284a4bf8f578ac67e74508fe659f13a" - integrity sha512-LQdY3j4PxuUl6xfxiFruTSlCniTrTrzAd8/HfsLEMi0PUpaQ0Iy+Pr4N4VllDYjs0Hyu2lkTbvzqlG+PX9NsNw== +electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.96: + version "1.3.98" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.98.tgz#f200bdac84b1110d7d9904f34f4fc6d5573a8a9c" + integrity sha512-WIZdNuvE3dFr6kkPgv4d/cfswNZD6XbeLBM8baOIQTsnbf4xWrVEaLvp7oNnbnMWWXDqq7Tbv+H5JfciLTJm4Q== elliptic@^6.0.0: version "6.4.1" @@ -3129,9 +3146,9 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0: once "^1.4.0" entities@^1.1.1, entities@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" - integrity sha1-blwtClYhtdra7O+AuQ7ftc13cvA= + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== err-code@^1.0.0: version "1.1.2" @@ -3145,18 +3162,19 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.5.1, es-abstract@^1.6.1: - version "1.12.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" - integrity sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA== +es-abstract@^1.12.0, es-abstract@^1.5.1: + version "1.13.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" + integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg== dependencies: - es-to-primitive "^1.1.1" + es-to-primitive "^1.2.0" function-bind "^1.1.1" - has "^1.0.1" - is-callable "^1.1.3" + has "^1.0.3" + is-callable "^1.1.4" is-regex "^1.0.4" + object-keys "^1.0.12" -es-to-primitive@^1.1.1: +es-to-primitive@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== @@ -3259,19 +3277,6 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: md5.js "^1.3.4" safe-buffer "^5.1.1" -execa@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50" - integrity sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw== - dependencies: - cross-spawn "^6.0.0" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - execa@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" @@ -3374,21 +3379,21 @@ falafel@^2.1.0: isarray "0.0.1" object-keys "^1.0.6" -fast-deep-equal@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" - integrity sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ= +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= fast-glob@^2.0.2, fast-glob@^2.2.2: - version "2.2.3" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.3.tgz#d09d378e9ef6b0076a0fa1ba7519d9d4d9699c28" - integrity sha512-NiX+JXjnx43RzvVFwRWfPKo4U+1BrK5pJPsHQdKMlLoFHrrGktXglQhHliSihWAq+m1z6fHk3uwGHrtRbS9vLA== + version "2.2.4" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.4.tgz#e54f4b66d378040e0e4d6a68ec36bbc5b04363c0" + integrity sha512-FjK2nCGI/McyzgNtTESqaWP3trPvHyRyoyY70hxjc3oKPNmDe8taohLZpoVKoUjW85tbU5txaYUZCNtVzygl1g== dependencies: "@mrmlnc/readdir-enhanced" "^2.2.1" - "@nodelib/fs.stat" "^1.0.1" + "@nodelib/fs.stat" "^1.1.2" glob-parent "^3.1.0" is-glob "^4.0.0" - merge2 "^1.2.1" + merge2 "^1.2.3" micromatch "^3.1.10" fast-json-stable-stringify@^2.0.0: @@ -3401,7 +3406,7 @@ fast-levenshtein@~2.0.4: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= -figgy-pudding@^3.1.0, figgy-pudding@^3.4.1, figgy-pudding@^3.5.1: +figgy-pudding@^3.4.1, figgy-pudding@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== @@ -3530,9 +3535,9 @@ from2@^2.1.0: readable-stream "^2.0.0" fs-extra@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.0.tgz#8cc3f47ce07ef7b3593a11b9fb245f7e34c041d6" - integrity sha512-EglNDLRpmaTWiD/qraZn6HREAEAHJcJOmxNEYwq6xeMKnVMAy3GUcFB+wXt2C6k4CNvB/mP1y/U3dzvKKj5OtQ== + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== dependencies: graceful-fs "^4.1.2" jsonfile "^4.0.0" @@ -3587,7 +3592,7 @@ fstream@^1.0.0, fstream@^1.0.2: mkdirp ">=0.5 0" rimraf "2" -function-bind@^1.1.0, function-bind@^1.1.1: +function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== @@ -3734,7 +3739,7 @@ glob@7.1.2: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: +glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: version "7.1.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== @@ -3747,9 +3752,9 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: path-is-absolute "^1.0.0" globals@^11.1.0: - version "11.8.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.8.0.tgz#c1ef45ee9bed6badf0663c5cb90e8d1adec1321d" - integrity sha512-io6LkyPVuzCHBSQV9fmOwxZkUk6nIaGmxheLDgmuFv89j0fm2aqDbIXKAGfzCMHqz3HLF2Zf8WSG6VqMh2qFmA== + version "11.9.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249" + integrity sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg== globby@^8.0.1: version "8.0.1" @@ -3764,10 +3769,10 @@ globby@^8.0.1: pify "^3.0.0" slash "^1.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: - version "4.1.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" - integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg= +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6: + version "4.1.15" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" + integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== grapheme-breaker@^0.3.2: version "0.3.2" @@ -3782,6 +3787,14 @@ growl@1.10.5: resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== +gzip-size@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.0.0.tgz#a55ecd99222f4c48fd8c01c625ce3b349d0a0e80" + integrity sha512-5iI7omclyqrnWw4XbXAmGhPsABkSIDQonv2K0h61lybgofWa6iZyvrI3r2zsJH4P8Nb64fFVzlvfhs0g7BBxAA== + dependencies: + duplexer "^0.1.1" + pify "^3.0.0" + handlebars@^4.0.11, handlebars@^4.0.2, handlebars@^4.0.6: version "4.0.12" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5" @@ -3799,11 +3812,11 @@ har-schema@^2.0.0: integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= har-validator@~5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.0.tgz#44657f5688a22cfd4b72486e81b3a3fb11742c29" - integrity sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA== + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== dependencies: - ajv "^5.3.0" + ajv "^6.5.5" har-schema "^2.0.0" has-ansi@^2.0.0: @@ -3864,7 +3877,7 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" -has@^1.0.0, has@^1.0.1: +has@^1.0.0, has@^1.0.1, has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== @@ -3880,9 +3893,9 @@ hash-base@^3.0.0: safe-buffer "^5.0.1" hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.5" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.5.tgz#e38ab4b85dfb1e0c40fe9265c0e9b54854c23812" - integrity sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA== + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== dependencies: inherits "^2.0.3" minimalistic-assert "^1.0.1" @@ -3944,16 +3957,16 @@ htmlnano@^0.1.9: terser "^3.8.1" htmlparser2@^3.9.2: - version "3.9.2" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.9.2.tgz#1bdf87acca0f3f9e53fa4fcceb0f4b4cbb00b338" - integrity sha1-G9+HrMoPP55T+k/M6w9LTLsAszg= + version "3.10.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.0.tgz#5f5e422dcf6119c0d983ed36260ce9ded0bee464" + integrity sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ== dependencies: domelementtype "^1.3.0" domhandler "^2.3.0" domutils "^1.5.1" entities "^1.1.1" inherits "^2.0.1" - readable-stream "^2.0.2" + readable-stream "^3.0.6" http-cache-semantics@^3.8.1: version "3.8.1" @@ -4036,6 +4049,14 @@ ignore@^3.3.5: resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== +import-fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + dependencies: + caller-path "^2.0.0" + resolve-from "^3.0.0" + import-local@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" @@ -4109,9 +4130,9 @@ init-package-json@^1.10.3: validate-npm-package-name "^3.0.0" inquirer@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.0.tgz#51adcd776f661369dc1e894859c2560a224abdd8" - integrity sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg== + version "6.2.1" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.1.tgz#9943fc4882161bdb0b0c9276769c75b32dbfcd52" + integrity sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg== dependencies: ansi-escapes "^3.0.0" chalk "^2.0.0" @@ -4124,13 +4145,13 @@ inquirer@^6.2.0: run-async "^2.2.0" rxjs "^6.1.0" string-width "^2.1.0" - strip-ansi "^4.0.0" + strip-ansi "^5.0.0" through "^2.3.6" interpret@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" - integrity sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ= + version "1.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" + integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== invariant@^2.2.2: version "2.2.4" @@ -4202,7 +4223,7 @@ is-builtin-module@^1.0.0: dependencies: builtin-modules "^1.0.0" -is-callable@^1.1.3, is-callable@^1.1.4: +is-callable@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== @@ -4507,17 +4528,18 @@ istanbul-reports@^2.0.1: handlebars "^4.0.11" js-base64@^2.1.9: - version "2.4.9" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.9.tgz#748911fb04f48a60c4771b375cac45a80df11c03" - integrity sha512-xcinL3AuDJk7VSzsHgb9DvvIXayBbadtMZ4HFPx8rUszbW1MuNMlwYVC4zzCZ6e1sqZpnNS5ZFYOhXqA39T7LQ== + version "2.5.0" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.0.tgz#42255ba183ab67ce59a0dee640afdc00ab5ae93e" + integrity sha512-wlEBIZ5LP8usDylWbDNhKPEFVFdI5hCHpnVoT/Ysvoi/PRhJENm/Rlh9TvjYB38HFfKZN7OzEbRjmjvLkFw11g== -js-beautify@^1.7.5: - version "1.8.7" - resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.8.7.tgz#d87100f714aeb3c388bce9ef011442fc07bda93a" - integrity sha512-yhAMCTv0L9GNg6Gql7i+g4C1z9rQhfHXy4J0TGYFoBzzHR4reWYS573gkRrPuE58dYOH451LmBeAb8L1pLEfdA== +js-beautify@^1.8.9: + version "1.8.9" + resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.8.9.tgz#08e3c05ead3ecfbd4f512c3895b1cda76c87d523" + integrity sha512-MwPmLywK9RSX0SPsUJjN7i+RQY9w/yC17Lbrq9ViEefpLRgqAR2BgrMN2AbifkUuhDV8tRauLhLda/9+bE0YQA== dependencies: - config-chain "~1.1.5" - editorconfig "^0.15.0" + config-chain "^1.1.12" + editorconfig "^0.15.2" + glob "^7.1.3" mkdirp "~0.5.0" nopt "~4.0.1" @@ -4537,9 +4559,9 @@ js-tokens@^3.0.2: integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= js-yaml@^3.10.0, js-yaml@^3.12.0, js-yaml@^3.7.0, js-yaml@^3.9.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" - integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== + version "3.12.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.1.tgz#295c8632a18a23e054cf5c9d3cecafe678167600" + integrity sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA== dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -4558,9 +4580,9 @@ jsbn@~0.1.0: integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= jsesc@^2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.1.tgz#e421a2a8e20d6b0819df28908f782526b96dd1fe" - integrity sha1-5CGiqOINawgZ3yiQj3glJrlt0f4= + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== jsesc@~0.5.0: version "0.5.0" @@ -4572,10 +4594,10 @@ json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1: resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== -json-schema-traverse@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" - integrity sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A= +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-schema@0.2.3: version "0.2.3" @@ -4587,11 +4609,6 @@ json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= -json5@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= - json5@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" @@ -4599,6 +4616,13 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +json5@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" + integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ== + dependencies: + minimist "^1.2.0" + jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -4917,13 +4941,20 @@ loud-rejection@^1.0.0: signal-exit "^3.0.0" lru-cache@^4.0.1, lru-cache@^4.1.2, lru-cache@^4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" - integrity sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA== + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== dependencies: pseudomap "^1.0.2" yallist "^2.1.2" +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + magic-string@^0.22.4: version "0.22.5" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.22.5.tgz#8e9cf5afddf44385c1da5bc2a6a0dbd10b03657e" @@ -4956,9 +4987,9 @@ make-fetch-happen@^4.0.1: ssri "^6.0.0" map-age-cleaner@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.2.tgz#098fb15538fd3dbe461f12745b0ca8568d4e3f74" - integrity sha512-UN1dNocxQq44IhJyMI4TU8phc2m9BddacHRPRjKGLYaF0jqd3xLz0jS0skpAU9WgYyoR4gHtUpzytNBS385FWQ== + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== dependencies: p-defer "^1.0.0" @@ -5081,7 +5112,7 @@ merge-source-map@^1.1.0: dependencies: source-map "^0.6.1" -merge2@^1.2.1: +merge2@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== @@ -5113,17 +5144,17 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@~1.36.0: - version "1.36.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.36.0.tgz#5020478db3c7fe93aad7bbcc4dcf869c43363397" - integrity sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw== +mime-db@~1.37.0: + version "1.37.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" + integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg== mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.20" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.20.tgz#930cb719d571e903738520f8470911548ca2cc19" - integrity sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A== + version "2.1.21" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96" + integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg== dependencies: - mime-db "~1.36.0" + mime-db "~1.37.0" mime@1.4.1: version "1.4.1" @@ -5175,15 +5206,7 @@ minimist@~0.0.1: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= -minipass@^2.2.1, minipass@^2.3.3: - version "2.3.4" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.4.tgz#4768d7605ed6194d6d576169b9e12ef71e9d9957" - integrity sha512-mlouk1OHlaUE8Odt1drMtG1bAJA4ZA6B/ehysgV0LUIrDHdKgo1KorZq3pK0b/7Z7LJIQ12MNM6aC+Tn6lUZ5w== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - -minipass@^2.3.4, minipass@^2.3.5: +minipass@^2.2.1, minipass@^2.3.4, minipass@^2.3.5: version "2.3.5" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== @@ -5191,13 +5214,6 @@ minipass@^2.3.4, minipass@^2.3.5: safe-buffer "^5.1.2" yallist "^3.0.0" -minizlib@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.1.tgz#6734acc045a46e61d596a43bb9d9cd326e19cc42" - integrity sha512-TrfjCjk4jLhcJyGMYymBH6oTXcWjYbUAXTHDbtnWHjZC25h0cdajHuPE1zxb4DVmu8crfh+HwH/WMuyLG0nHBg== - dependencies: - minipass "^2.2.1" - minizlib@^1.1.1: version "1.2.1" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" @@ -5290,15 +5306,20 @@ multimatch@^2.1.0: arrify "^1.0.0" minimatch "^3.0.0" -mute-stream@0.0.7, mute-stream@~0.0.4: +mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= +mute-stream@~0.0.4: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + nan@^2.9.2: - version "2.11.1" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" - integrity sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA== + version "2.12.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552" + integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw== nanomatch@^1.2.9: version "1.2.13" @@ -5413,10 +5434,10 @@ node-pre-gyp@^0.10.0: semver "^5.3.0" tar "^4" -node-releases@^1.0.0-alpha.14: - version "1.0.0-alpha.14" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.0.0-alpha.14.tgz#da9e2780add4bbb59ad890af9e2018a1d9c0034b" - integrity sha512-G8nnF9cP9QPP/jUmYWw/uUUhumHmkm+X/EarCugYFjYm2uXRMFeOD6CVT3RLdoyCvDUNy51nirGfUItKWs/S1g== +node-releases@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.3.tgz#aad9ce0dcb98129c753f772c0aa01360fb90fbd2" + integrity sha512-6VrvH7z6jqqNFY200kdB6HdzkgM96Oaj9v3dqGfgp6mF+cHmU4wyQKZ2/WPDRVoR0Jz9KqbamaBN0ZhdUaysUQ== dependencies: semver "^5.3.0" @@ -5507,9 +5528,9 @@ npm-logical-tree@^1.2.1: validate-npm-package-name "^3.0.0" npm-packlist@^1.1.12, npm-packlist@^1.1.6: - version "1.1.12" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.12.tgz#22bde2ebc12e72ca482abd67afc51eb49377243a" - integrity sha512-WJKFOVMeAlsU/pjXuqVdzU0WfgtIBCupkEVwn+1Y0ERAbUfWw8R4GjgVbaKnUjRoD2FoQbHOCbOyT5Mbs9Lw4g== + version "1.2.0" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.2.0.tgz#55a60e793e272f00862c7089274439a4cc31fc7f" + integrity sha512-7Mni4Z8Xkx0/oegoqlcao/JpPCPEMtUvsmB0q7mgvlMinykJLSRTYuFqoQLYgGY8biuxIeiHO+QNJKbCfljewQ== dependencies: ignore-walk "^3.0.1" npm-bundled "^1.0.1" @@ -5561,10 +5582,10 @@ npm-run-path@^2.0.0: gauge "~2.7.3" set-blocking "~2.0.0" -nth-check@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.1.tgz#9929acdf628fc2c41098deab82ac580cf149aae4" - integrity sha1-mSms32KPwsQQmN6rgqxYDPFJquQ= +nth-check@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== dependencies: boolbase "~1.0.0" @@ -5661,14 +5682,14 @@ object.pick@^1.3.0: isobject "^3.0.1" object.values@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.0.4.tgz#e524da09b4f66ff05df457546ec72ac99f13069a" - integrity sha1-5STaCbT2b/Bd9FdUbscqyZ8TBpo= + version "1.1.0" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.0.tgz#bf6810ef5da3e5325790eaaa2be213ea84624da9" + integrity sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg== dependencies: - define-properties "^1.1.2" - es-abstract "^1.6.1" - function-bind "^1.1.0" - has "^1.0.1" + define-properties "^1.1.3" + es-abstract "^1.12.0" + function-bind "^1.1.1" + has "^1.0.3" on-finished@~2.3.0: version "2.3.0" @@ -5750,11 +5771,11 @@ os-locale@^2.0.0: mem "^1.1.0" os-locale@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.0.1.tgz#3b014fbf01d87f60a1e5348d80fe870dc82c4620" - integrity sha512-7g5e7dmXPtzcP4bgsZ8ixDVqA7oWYuEz4lOSujeWyliPai4gfVDiFIcwBg3aGCPnmSGfzOKTK3ccPn0CKv3DBw== + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== dependencies: - execa "^0.10.0" + execa "^1.0.0" lcid "^2.0.0" mem "^4.0.0" @@ -5794,9 +5815,9 @@ p-limit@^1.1.0: p-try "^1.0.0" p-limit@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.0.0.tgz#e624ed54ee8c460a778b3c9f3670496ff8a57aec" - integrity sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A== + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.1.0.tgz#1d5a0d20fb12707c758a655f6bbc4386b5930d68" + integrity sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g== dependencies: p-try "^2.0.0" @@ -5864,16 +5885,16 @@ package-hash@^2.0.0: release-zalgo "^1.0.0" pacote@^9.2.3: - version "9.2.3" - resolved "https://registry.yarnpkg.com/pacote/-/pacote-9.2.3.tgz#48cfe87beb9177acd6594355a584a538835424b3" - integrity sha512-Y3+yY3nBRAxMlZWvr62XLJxOwCmG9UmkGZkFurWHoCjqF0cZL72cTOCRJTvWw8T4OhJS2RTg13x4oYYriauvEw== + version "9.3.0" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-9.3.0.tgz#ec0d21b739a625d81a19ae546386fedee3300bc1" + integrity sha512-uy5xghB5wUtmFS+uNhQGhlsIF9rfsfxw6Zsu2VpmSz4/f+8D2+5V1HwjHdSn7W6aQTrxNNmmoUF5qNE10/EVdA== dependencies: - bluebird "^3.5.2" - cacache "^11.2.0" + bluebird "^3.5.3" + cacache "^11.3.2" figgy-pudding "^3.5.1" get-stream "^4.1.0" glob "^7.1.3" - lru-cache "^4.1.3" + lru-cache "^5.1.1" make-fetch-happen "^4.0.1" minimatch "^3.0.4" minipass "^2.3.5" @@ -5892,7 +5913,7 @@ pacote@^9.2.3: safe-buffer "^5.1.2" semver "^5.6.0" ssri "^6.0.1" - tar "^4.4.6" + tar "^4.4.8" unique-filename "^1.1.1" which "^1.3.1" @@ -5902,9 +5923,9 @@ pako@^0.2.5: integrity sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU= pako@~1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" - integrity sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg== + version "1.0.7" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.7.tgz#2473439021b57f1516c82f58be7275ad8ef1bb27" + integrity sha512-3HNK5tW4x8o5mO8RuHZp3Ydw9icZXx0RANAOMzlMzx7LVXhMJ4mo3MOBpzyd7r/+RUu8BmndP47LXT+vzjtWcQ== parallel-transform@^1.1.0: version "1.1.0" @@ -6055,7 +6076,7 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= -path-parse@^1.0.5: +path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== @@ -6087,10 +6108,10 @@ pbkdf2@^3.0.3: safe-buffer "^5.0.1" sha.js "^2.4.8" -pegjs@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/pegjs/-/pegjs-0.10.0.tgz#cf8bafae6eddff4b5a7efb185269eaaf4610ddbd" - integrity sha1-z4uvrm7d/0tafvsYUmnqr0YQ3b0= +pegjs@^0.11.0-dev.325: + version "0.11.0-dev.325" + resolved "https://registry.yarnpkg.com/pegjs/-/pegjs-0.11.0-dev.325.tgz#5af06561c8b3f10ef57dcfcba89075a677af393a" + integrity sha512-7YGSJyY9YHMS16zY14sVO6zF+SRGgIGVVtK4/SerLuOOyeWz/MFlE6RB5jJRBjODM5//OsfPrPBIpQDPEMh+/A== performance-now@^2.1.0: version "2.1.0" @@ -6157,15 +6178,15 @@ postcss-calc@^5.2.0: postcss-message-helpers "^2.0.0" reduce-css-calc "^1.2.6" -postcss-calc@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-6.0.2.tgz#4d9a43e27dbbf27d095fecb021ac6896e2318337" - integrity sha512-fiznXjEN5T42Qm7qqMCVJXS3roaj9r4xsSi+meaBVe7CJBl8t/QLOXu02Z2E6oWAMWIvCuF6JrvzFekmVEbOKA== +postcss-calc@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.1.tgz#36d77bab023b0ecbb9789d84dcb23c4941145436" + integrity sha512-oXqx0m6tb4N3JGdmeMSc/i91KppbYsFZKdH0xMOqK8V1rJlzrKlTdokz8ozUXLVejydRN6u2IddxpcijRj2FqQ== dependencies: css-unit-converter "^1.1.1" - postcss "^7.0.2" - postcss-selector-parser "^2.2.2" - reduce-css-calc "^2.0.0" + postcss "^7.0.5" + postcss-selector-parser "^5.0.0-rc.4" + postcss-value-parser "^3.3.1" postcss-colormin@^2.1.8: version "2.2.2" @@ -6290,10 +6311,10 @@ postcss-merge-longhand@^2.0.1: dependencies: postcss "^5.0.4" -postcss-merge-longhand@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-4.0.6.tgz#2b938fa3529c3d1657e53dc7ff0fd604dbc85ff1" - integrity sha512-JavnI+V4IHWsaUAfOoKeMEiJQGXTraEy1nHM0ILlE6NIQPEZrJDAnPh3lNGZ5HAk2mSSrwp66JoGhvjp6SqShA== +postcss-merge-longhand@^4.0.10: + version "4.0.10" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-4.0.10.tgz#c4d63ab57bdc054ab4067ab075d488c8c2978380" + integrity sha512-hME10s6CSjm9nlVIcO1ukR7Jr5RisTaaC1y83jWCivpuBtPohA3pZE7cGTIVSYjXvLnXozHTiVOkG4dnnl756g== dependencies: css-color-names "0.0.4" postcss "^7.0.0" @@ -6582,6 +6603,15 @@ postcss-selector-parser@^3.0.0: indexes-of "^1.0.1" uniq "^1.0.1" +postcss-selector-parser@^5.0.0-rc.4: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz#249044356697b33b64f1a8f7c80922dddee7195c" + integrity sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ== + dependencies: + cssesc "^2.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + postcss-svgo@^2.1.1: version "2.1.6" resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-2.1.6.tgz#b6df18aa613b666e133f08adb5219c2684ac108d" @@ -6644,16 +6674,7 @@ postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0 source-map "^0.5.6" supports-color "^3.2.3" -postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.2: - version "7.0.5" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.5.tgz#70e6443e36a6d520b0fd4e7593fcca3635ee9f55" - integrity sha512-HBNpviAUFCKvEh7NZhw1e8MBPivRszIiUnhrJ+sBFVSYSqubrzwX3KG51mYgcRHX8j/cAgZJedONZcm5jTBdgQ== - dependencies: - chalk "^2.4.1" - source-map "^0.6.1" - supports-color "^5.5.0" - -postcss@^7.0.5: +postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.5: version "7.0.7" resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.7.tgz#2754d073f77acb4ef08f1235c36c5721a7201614" integrity sha512-HThWSJEPkupqew2fnuQMEI2YcTj/8gMV3n80cMdJsKxfIh5tHf7nM5JigNX6LxVMqo6zkgQNAI88hyFvBk41Pg== @@ -6719,9 +6740,9 @@ process@^0.11.10: integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= progress@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.1.tgz#c9242169342b1c29d275889c95734621b1952e31" - integrity sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg== + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== promise-inflight@^1.0.1: version "1.0.1" @@ -6761,9 +6782,9 @@ pseudomap@^1.0.2: integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= psl@^1.1.24: - version "1.1.29" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" - integrity sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ== + version "1.1.31" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184" + integrity sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw== public-encrypt@^4.0.0: version "4.0.3" @@ -6968,7 +6989,7 @@ read@1, read@~1.0.1: dependencies: mute-stream "~0.0.4" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.3: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.3, readable-stream@~2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== @@ -6981,6 +7002,15 @@ read@1, read@~1.0.1: string_decoder "~1.1.1" util-deprecate "~1.0.1" +readable-stream@^3.0.6: + version "3.1.1" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.1.1.tgz#ed6bbc6c5ba58b090039ff18ce670515795aeb06" + integrity sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readdir-scoped-modules@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.0.2.tgz#9fafa37d286be5d92cbaebdee030dc9b5f406747" @@ -7032,14 +7062,6 @@ reduce-css-calc@^1.2.6: math-expression-evaluator "^1.2.14" reduce-function-call "^1.0.1" -reduce-css-calc@^2.0.0: - version "2.1.5" - resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.1.5.tgz#f283712f0c9708ef952d328f4b16112d57b03714" - integrity sha512-AybiBU03FKbjYzyvJvwkJZY6NLN+80Ufc2EqEs+41yQH+8wqBEslD6eGiS0oIeq5TNLA5PrhBeYHXWdn8gtW7A== - dependencies: - css-unit-converter "^1.1.1" - postcss-value-parser "^3.3.0" - reduce-function-call@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/reduce-function-call/-/reduce-function-call-1.0.2.tgz#5a200bf92e0e37751752fe45b0ab330fd4b6be99" @@ -7085,26 +7107,26 @@ regex-not@^1.0.0, regex-not@^1.0.2: safe-regex "^1.1.0" regexpu-core@^4.1.3, regexpu-core@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.2.0.tgz#a3744fa03806cffe146dea4421a3e73bdcc47b1d" - integrity sha512-Z835VSnJJ46CNBttalHD/dB+Sj2ezmY6Xp38npwU87peK6mqOzOpV8eYktdkLTEkzzD+JsTcxd84ozd8I14+rw== + version "4.4.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.4.0.tgz#8d43e0d1266883969720345e70c275ee0aec0d32" + integrity sha512-eDDWElbwwI3K0Lo6CqbQbA6FwgtCz4kYTarrri1okfkRLZAqstU+B3voZBCjg8Fl6iq0gXrJG6MvRgLthfvgOA== dependencies: regenerate "^1.4.0" regenerate-unicode-properties "^7.0.0" - regjsgen "^0.4.0" - regjsparser "^0.3.0" + regjsgen "^0.5.0" + regjsparser "^0.6.0" unicode-match-property-ecmascript "^1.0.4" unicode-match-property-value-ecmascript "^1.0.2" -regjsgen@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.4.0.tgz#c1eb4c89a209263f8717c782591523913ede2561" - integrity sha512-X51Lte1gCYUdlwhF28+2YMO0U6WeN0GLpgpA7LK7mbdDnkQYiwvEpmpe0F/cv5L14EbxgrdayAG3JETBv0dbXA== +regjsgen@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.0.tgz#a7634dc08f89209c2049adda3525711fb97265dd" + integrity sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA== -regjsparser@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.3.0.tgz#3c326da7fcfd69fa0d332575a41c8c0cdf588c96" - integrity sha512-zza72oZBBHzt64G7DxdqrOo/30bhHkwMUoT0WqfGu98XLd7N+1tsy5MJ96Bk4MD0y74n629RhmrGW6XlnLLwCA== +regjsparser@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.0.tgz#f1e6ae8b7da2bae96c99399b868cd6c933a2ba9c" + integrity sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ== dependencies: jsesc "~0.5.0" @@ -7196,11 +7218,11 @@ resolve-url@^0.2.1: integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= resolve@^1.1.5, resolve@^1.1.6, resolve@^1.3.2, resolve@^1.4.0: - version "1.8.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" - integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== + version "1.9.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.9.0.tgz#a14c6fdfa8f92a7df1d996cb7105fa744658ea06" + integrity sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ== dependencies: - path-parse "^1.0.5" + path-parse "^1.0.6" restore-cursor@^2.0.0: version "2.0.0" @@ -7230,14 +7252,7 @@ rgba-regex@^1.0.0: resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= -rimraf@2, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" - integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== - dependencies: - glob "^7.0.5" - -rimraf@^2.6.3: +rimraf@2, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== @@ -7252,6 +7267,15 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" +rollup@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.0.2.tgz#df88abda5cfe96afaa07dbd540510f87e60d1baf" + integrity sha512-FkkSrWUVo1WliS+/GIgEmKQPILubgVdBRTWampfdhkasxx7sM2nfwSfKiX3paIBVnN0HG3DvkTy13RfjkyBX9w== + dependencies: + "@types/estree" "0.0.39" + "@types/node" "*" + acorn "^6.0.4" + run-async@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" @@ -7290,12 +7314,12 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -safer-eval@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/safer-eval/-/safer-eval-1.2.3.tgz#73ba74a34bc8a07d6a44135c815fd18a8eebe7a0" - integrity sha512-nDwXOhiheoaBT6op02n8wzsshjLXHhh4YAeqsDEoVmy1k2+lGv/ENLsGaWqkaKArUkUx48VO12/ZPa3sI/OEqQ== +safer-eval@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/safer-eval/-/safer-eval-1.3.0.tgz#dc4fc5fe0221434c117cfc41b899fe2b33c8c20e" + integrity sha512-4qkBS8VzJatFR7F0eZfKoJyjqo43jY1jBvRhB5WXM0eJNjx9fiSmph5NApJefqKqpASKWPfaIJCJMMeWePSzfw== dependencies: - clones "^1.1.0" + clones "^1.2.0" sax@^1.2.4, sax@~1.2.1, sax@~1.2.4: version "1.2.4" @@ -7332,12 +7356,12 @@ send@0.16.2: statuses "~1.4.0" serialize-to-js@^1.1.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/serialize-to-js/-/serialize-to-js-1.2.1.tgz#2e87f61f938826d24c463a7cbd0dd2929ec38008" - integrity sha512-TK6d30GNkOLeFDPuP6Jfy1Q1V31GxzppYTt2lzr8KWmIUKomFj+260QP5o4AhHLu0pr6urgyS8i/Z1PqurjBoA== + version "1.2.2" + resolved "https://registry.yarnpkg.com/serialize-to-js/-/serialize-to-js-1.2.2.tgz#1a567b0c9bf557bc7d7b77b503dfae0a8218d15d" + integrity sha512-mUc8vA5iJghe+O+3s0YDGFLMJcqitVFk787YKiv8a4sf6RX5W0u81b+gcHrp15O0fFa010dRBVZvwcKXOWsL9Q== dependencies: - js-beautify "^1.7.5" - safer-eval "^1.2.3" + js-beautify "^1.8.9" + safer-eval "^1.3.0" serve-static@^1.12.4: version "1.13.2" @@ -7410,9 +7434,9 @@ shebang-regex@^1.0.0: integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= shelljs@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.2.tgz#345b7df7763f4c2340d584abb532c5f752ca9e35" - integrity sha512-pRXeNrCA2Wd9itwhvLp5LZQvPJ0wU6bcjaTMywHHGX5XWhVN2nzSu7WV0q+oUY7mGK3mgSkDDzP3MgjqdyIgbQ== + version "0.8.3" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.3.tgz#a7f3319520ebf09ee81275b2368adb286659b097" + integrity sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A== dependencies: glob "^7.0.0" interpret "^1.0.0" @@ -7489,9 +7513,9 @@ socks-proxy-agent@^4.0.0: socks "~2.2.0" socks@~2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.2.1.tgz#68ad678b3642fbc5d99c64c165bc561eab0215f9" - integrity sha512-0GabKw7n9mI46vcNrVfs0o6XzWzjVa3h6GaSo2UPxtWAROXUWavfJWh1M4PR5tnE0dcnQXZIDFP4yrAysLze/w== + version "2.2.2" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.2.2.tgz#f061219fc2d4d332afb4af93e865c84d3fa26e2b" + integrity sha512-g6wjBnnMOZpE0ym6e0uHSddz9p3a+WsBaaYQaBaSCJYvrC4IXykQR9MNGjLQf38e9iIIhp3b1/Zk8YZI3KGJ0Q== dependencies: ip "^1.1.5" smart-buffer "^4.0.1" @@ -7557,9 +7581,9 @@ spawn-wrap@^1.4.2: which "^1.3.0" spdx-correct@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.2.tgz#19bb409e91b47b1ad54159243f7312a858db3c2e" - integrity sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ== + version "3.1.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" + integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== dependencies: spdx-expression-parse "^3.0.0" spdx-license-ids "^3.0.0" @@ -7578,9 +7602,9 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.1.tgz#e2a303236cac54b04031fa7a5a79c7e701df852f" - integrity sha512-TfOfPcYGBB5sDuPn3deByxPhmfegAhpDYKSOXZQN81Oyrrif8ZCodOLzK3AesELnCx03kikhyDwh0pfvvQvF8w== + version "3.0.3" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz#81c0ce8f21474756148bbb5f3bfc0f36bf15d76e" + integrity sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g== split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" @@ -7609,9 +7633,9 @@ sprintf-js@~1.0.2: integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= sshpk@^1.7.0: - version "1.15.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.15.1.tgz#b79a089a732e346c6e0714830f36285cd38191a2" - integrity sha512-mSdgNUaidk+dRU5MhYtN9zebdzF2iG0cNPWy8HG+W8y+fT1JnSkh0fzzpjOa0L7P8i1Rscz38t0h4gPcKz43xA== + version "1.16.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.0.tgz#1d4963a2fbffe58050aa9084ca20be81741c07de" + integrity sha512-Zhev35/y7hRMcID/upReIvRse+I9SVhyVre/KTJSJQWMz3C3+G+HpO7m1wK/yckEtujKZ7dS4hkVxAnmHaIGVQ== dependencies: asn1 "~0.2.3" assert-plus "^1.0.0" @@ -7734,7 +7758,14 @@ string-width@^1.0.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string_decoder@^1.0.0, string_decoder@~1.1.1: +string_decoder@^1.0.0, string_decoder@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" + integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w== + dependencies: + safe-buffer "~5.1.0" + +string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== @@ -7760,6 +7791,13 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" +strip-ansi@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.0.0.tgz#f78f68b5d0866c20b2c9b8c61b5298508dc8756f" + integrity sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow== + dependencies: + ansi-regex "^4.0.0" + strip-bom@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" @@ -7795,11 +7833,10 @@ strip-json-comments@~2.0.1: integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= strong-log-transformer@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-2.0.0.tgz#fa6d8e0a9e62b3c168c3cad5ae5d00dc97ba26cc" - integrity sha512-FQmNqAXJgOX8ygOcvPLlGWBNT41mvNJ9ALoYf0GTwVt9t30mGTqpmp/oJx5gLcu52DXK10kS7dVWhx8aPXDTlg== + version "2.1.0" + resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz#0f5ed78d325e0421ac6f90f7f10e691d6ae3ae10" + integrity sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA== dependencies: - byline "^5.0.0" duplexer "^0.1.1" minimist "^1.2.0" through "^2.3.4" @@ -7881,20 +7918,7 @@ tar@^2.0.0: fstream "^1.0.2" inherits "2" -tar@^4: - version "4.4.6" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.6.tgz#63110f09c00b4e60ac8bcfe1bf3c8660235fbc9b" - integrity sha512-tMkTnh9EdzxyfW+6GK6fCahagXsnYk6kE6S9Gr9pjVdys769+laCTbodXDhPAjzVtEBazRgP0gYqOjnk9dQzLg== - dependencies: - chownr "^1.0.1" - fs-minipass "^1.2.5" - minipass "^2.3.3" - minizlib "^1.1.0" - mkdirp "^0.5.0" - safe-buffer "^5.1.2" - yallist "^3.0.2" - -tar@^4.4.6, tar@^4.4.8: +tar@^4, tar@^4.4.8: version "4.4.8" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== @@ -7924,7 +7948,7 @@ temp-write@^3.4.0: temp-dir "^1.0.0" uuid "^3.0.1" -terser@^3.14.1: +terser@^3.14.1, terser@^3.7.3, terser@^3.8.1: version "3.14.1" resolved "https://registry.yarnpkg.com/terser/-/terser-3.14.1.tgz#cc4764014af570bc79c79742358bd46926018a32" integrity sha512-NSo3E99QDbYSMeJaEk9YW2lTg3qS9V0aKGlb+PlOrei1X02r1wSBHCNX/O+yeTRFSWPKPIGj6MqvvdqV4rnVGw== @@ -7933,15 +7957,6 @@ terser@^3.14.1: source-map "~0.6.1" source-map-support "~0.5.6" -terser@^3.7.3, terser@^3.8.1: - version "3.10.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-3.10.1.tgz#59c8cf87262d59e018ded4df30f834b602b1e232" - integrity sha512-GE0ShECt1/dZUZt9Kyr/IC6xXG46pTbm1C1WfzQbbnRB5LhdJlF8p5NBZ38RjspD7hEM9O5ud8aIcOFY6evl4A== - dependencies: - commander "~2.17.1" - source-map "~0.6.1" - source-map-support "~0.5.6" - test-exclude@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.0.0.tgz#cdce7cece785e0e829cd5c2b27baf18bc583cfb7" @@ -7958,11 +7973,11 @@ text-extensions@^1.0.0: integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== through2@^2.0.0, through2@^2.0.2, through2@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" - integrity sha1-AARWmzfHx0ujnEPzzteNGtlBQL4= + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== dependencies: - readable-stream "^2.1.5" + readable-stream "~2.3.6" xtend "~4.0.1" through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6: @@ -8230,7 +8245,7 @@ uniqs@^2.0.0: resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= -unique-filename@^1.1.0, unique-filename@^1.1.1: +unique-filename@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== @@ -8267,6 +8282,13 @@ upath@^1.0.5: resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw== +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" @@ -8285,7 +8307,7 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== -util-deprecate@~1.0.1: +util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= @@ -8467,11 +8489,6 @@ ws@^5.1.1: dependencies: async-limiter "~1.0.0" -xregexp@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.0.0.tgz#e698189de49dd2a18cc5687b05e17c8e43943020" - integrity sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg== - xtend@^4.0.0, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" @@ -8493,16 +8510,17 @@ yallist@^2.1.2: integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= yallist@^3.0.0, yallist@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" - integrity sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k= + version "3.0.3" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" + integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== -yargs-parser@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" - integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== +yargs-parser@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" + integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== dependencies: - camelcase "^4.1.0" + camelcase "^5.0.0" + decamelize "^1.2.0" yargs-parser@^9.0.2: version "9.0.2" @@ -8530,12 +8548,12 @@ yargs@11.1.0: yargs-parser "^9.0.2" yargs@^12.0.1: - version "12.0.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.2.tgz#fe58234369392af33ecbef53819171eff0f5aadc" - integrity sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ== + version "12.0.5" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" + integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== dependencies: cliui "^4.0.0" - decamelize "^2.0.0" + decamelize "^1.2.0" find-up "^3.0.0" get-caller-file "^1.0.1" os-locale "^3.0.0" @@ -8545,4 +8563,4 @@ yargs@^12.0.1: string-width "^2.0.0" which-module "^2.0.0" y18n "^3.2.1 || ^4.0.0" - yargs-parser "^10.1.0" + yargs-parser "^11.1.1" From f913d7bfa7c84b986a05546d4a99efaf43bd6038 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 8 Jan 2019 02:16:29 +0000 Subject: [PATCH 215/333] build(api): update package build scripts / outputs BREAKING CHANGE: rename mixins to avoid name clashes, update decorators - append `Mixin` suffix to all mixins (i.e. `INotify` => `INotifyMixin`) - update re-exports of mixins & decorators (no more nested child namespace) --- packages/api/package.json | 16 +++---- packages/api/src/api.ts | 12 ++++- packages/api/src/decorators/configurable.ts | 10 ++-- packages/api/src/decorators/deprecated.ts | 7 ++- packages/api/src/decorators/index.ts | 4 -- packages/api/src/decorators/nomixin.ts | 7 +-- packages/api/src/decorators/sealed.ts | 9 ++-- packages/api/src/index.ts | 17 ++++--- packages/api/src/mixin.ts | 53 +++++++++++---------- packages/api/src/mixins/ienable.ts | 13 +++-- packages/api/src/mixins/index.ts | 4 -- packages/api/src/mixins/inotify.ts | 40 +++++++++------- packages/api/src/mixins/iterable.ts | 10 ++-- packages/api/src/mixins/iwatch.ts | 51 ++++++++++---------- packages/api/test/tsconfig.json | 3 +- 15 files changed, 136 insertions(+), 120 deletions(-) delete mode 100644 packages/api/src/decorators/index.ts delete mode 100644 packages/api/src/mixins/index.ts diff --git a/packages/api/package.json b/packages/api/package.json index 5486ba7ffa..91def34a86 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -2,8 +2,9 @@ "name": "@thi.ng/api", "version": "4.2.4", "description": "Common, generic types & interfaces for thi.ng projects", - "main": "./lib/index.js", "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -13,13 +14,11 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && yarn build:es6 && yarn build:parcel && yarn build:parcel:min", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", "build:es6": "tsc --declaration", - "build:parcel:min": "parcel build --global thing_api -o index.min.js -d lib --experimental-scope-hoisting src/index.ts", - "build:parcel": "parcel build --global thing_api -d lib --no-minify --experimental-scope-hoisting src/index.ts && prettier --write lib/index.js", - "build:gzip": "gzip -c lib/index.min.js > lib/index.min.js.gz", - "clean": "rimraf *.js *.d.ts .cache .nyc_output build coverage doc lib", - "test": "rimraf build && parcel build -d build --no-cache --no-minify --no-source-maps test/index.ts && nyc mocha build/index.js", + "build:bundle": "../../scripts/bundle-module api errors", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib decorators mixins", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public" @@ -54,5 +53,6 @@ "browser": { "process": false, "setTimeout": false - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/api/src/api.ts b/packages/api/src/api.ts index c698bff645..cbb01063a4 100644 --- a/packages/api/src/api.ts +++ b/packages/api/src/api.ts @@ -19,7 +19,17 @@ export type Comparator = (a: T, b: T) => number; /** * A single arg function from A => B. */ -export type Fn = (x: A) => B; +export type Fn = (a: A) => B; + +/** + * A 2-arg function from A,B => C. + */ +export type Fn2 = (a: A, b: B) => C; + +/** + * A 3-arg function from A,B,C => D. + */ +export type Fn3 = (a: A, b: B, c: C) => D; /** * A vararg arg function to type T. diff --git a/packages/api/src/decorators/configurable.ts b/packages/api/src/decorators/configurable.ts index d8e9510539..afe5f3b6e9 100644 --- a/packages/api/src/decorators/configurable.ts +++ b/packages/api/src/decorators/configurable.ts @@ -4,8 +4,8 @@ * * @param state */ -export function configurable(state: boolean): MethodDecorator { - return function (_: any, __: string | symbol, descriptor: PropertyDescriptor) { - descriptor.configurable = state; - }; -} +export const configurable = + (state: boolean): MethodDecorator => + function (_: any, __: string | symbol, descriptor: PropertyDescriptor) { + descriptor.configurable = state; + }; diff --git a/packages/api/src/decorators/deprecated.ts b/packages/api/src/decorators/deprecated.ts index da6650fa42..e8dcc40d03 100644 --- a/packages/api/src/decorators/deprecated.ts +++ b/packages/api/src/decorators/deprecated.ts @@ -1,4 +1,4 @@ -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { illegalArgs } from "@thi.ng/errors"; /** * Method property decorator factory. Augments original method with @@ -8,8 +8,8 @@ import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; * * @param msg deprecation message */ -export function deprecated(msg?: string, log = console.log): MethodDecorator { - return function (target: any, prop: string | symbol, descriptor: PropertyDescriptor) { +export const deprecated = (msg?: string, log = console.log): MethodDecorator => + function (target: any, prop: string | symbol, descriptor: PropertyDescriptor) { const signature = `${target.constructor.name}#${prop.toString()}`; const fn = descriptor.value; if (typeof fn !== "function") { @@ -21,4 +21,3 @@ export function deprecated(msg?: string, log = console.log): MethodDecorator { }; return descriptor; }; -} diff --git a/packages/api/src/decorators/index.ts b/packages/api/src/decorators/index.ts deleted file mode 100644 index 2788d027e7..0000000000 --- a/packages/api/src/decorators/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./configurable"; -export * from "./deprecated"; -export * from "./nomixin"; -export * from "./sealed"; diff --git a/packages/api/src/decorators/nomixin.ts b/packages/api/src/decorators/nomixin.ts index 8df3a24b35..1e180c5ab4 100644 --- a/packages/api/src/decorators/nomixin.ts +++ b/packages/api/src/decorators/nomixin.ts @@ -5,6 +5,7 @@ * partial implementations of mixed-in behaviors in target class and * avoid them being overidden by mixed-in behaviour. */ -export function nomixin(_: any, __: string, descriptor: PropertyDescriptor) { - descriptor.configurable = false; -} +export const nomixin = + (_: any, __: string, descriptor: PropertyDescriptor) => { + descriptor.configurable = false; + }; diff --git a/packages/api/src/decorators/sealed.ts b/packages/api/src/decorators/sealed.ts index 39fc0b1085..240602bcfe 100644 --- a/packages/api/src/decorators/sealed.ts +++ b/packages/api/src/decorators/sealed.ts @@ -3,7 +3,8 @@ * * @param constructor */ -export function sealed(constructor: Function) { - Object.seal(constructor); - Object.seal(constructor.prototype); -} +export const sealed = + (constructor: Function) => { + Object.seal(constructor); + Object.seal(constructor.prototype); + }; diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts index 4da35daf6f..72dbae8669 100644 --- a/packages/api/src/index.ts +++ b/packages/api/src/index.ts @@ -1,8 +1,11 @@ -import * as decorators from "./decorators"; -import * as mixins from "./mixins"; -export { - decorators, - mixins, -} - export * from "./api"; + +export * from "./decorators/configurable"; +export * from "./decorators/deprecated"; +export * from "./decorators/nomixin"; +export * from "./decorators/sealed"; + +export * from "./mixins/ienable"; +export * from "./mixins/inotify"; +export * from "./mixins/iterable"; +export * from "./mixins/iwatch"; diff --git a/packages/api/src/mixin.ts b/packages/api/src/mixin.ts index c060776535..55e75cfae4 100644 --- a/packages/api/src/mixin.ts +++ b/packages/api/src/mixin.ts @@ -10,35 +10,36 @@ * @param sharedBehaviour * @returns decorator function */ -export function mixin(behaviour: any, sharedBehaviour = {}) { - const instanceKeys = Reflect.ownKeys(behaviour); - const sharedKeys = Reflect.ownKeys(sharedBehaviour); - const typeTag = Symbol("isa"); +export const mixin = + (behaviour: any, sharedBehaviour = {}) => { + const instanceKeys = Reflect.ownKeys(behaviour); + const sharedKeys = Reflect.ownKeys(sharedBehaviour); + const typeTag = Symbol("isa"); - function _mixin(clazz) { - for (let key of instanceKeys) { - const existing = Object.getOwnPropertyDescriptor(clazz.prototype, key); - if (!existing || existing.configurable) { - Object.defineProperty(clazz.prototype, key, { - value: behaviour[key], - writable: true, - }); - } else { - console.log(`not patching: ${clazz.name}.${key.toString()}`); + function _mixin(clazz) { + for (let key of instanceKeys) { + const existing = Object.getOwnPropertyDescriptor(clazz.prototype, key); + if (!existing || existing.configurable) { + Object.defineProperty(clazz.prototype, key, { + value: behaviour[key], + writable: true, + }); + } else { + console.log(`not patching: ${clazz.name}.${key.toString()}`); + } } + Object.defineProperty(clazz.prototype, typeTag, { value: true }); + return clazz; } - Object.defineProperty(clazz.prototype, typeTag, { value: true }); - return clazz; - } - for (let key of sharedKeys) { - Object.defineProperty(_mixin, key, { - value: sharedBehaviour[key], - enumerable: sharedBehaviour.propertyIsEnumerable(key), - }); - } + for (let key of sharedKeys) { + Object.defineProperty(_mixin, key, { + value: sharedBehaviour[key], + enumerable: sharedBehaviour.propertyIsEnumerable(key), + }); + } - Object.defineProperty(_mixin, Symbol.hasInstance, { value: (x) => !!x[typeTag] }); + Object.defineProperty(_mixin, Symbol.hasInstance, { value: (x) => !!x[typeTag] }); - return _mixin; -} + return _mixin; + } diff --git a/packages/api/src/mixins/ienable.ts b/packages/api/src/mixins/ienable.ts index 838b45a1f7..a4e1f01504 100644 --- a/packages/api/src/mixins/ienable.ts +++ b/packages/api/src/mixins/ienable.ts @@ -1,4 +1,9 @@ -import * as api from "../api"; +import { + Event, + EVENT_DISABLE, + EVENT_ENABLE, + IEnable +} from "../api"; import { mixin } from "../mixin"; /** @@ -7,7 +12,7 @@ import { mixin } from "../mixin"; * interface, `enable()` and `disable()` will automatically emit the * respective events. */ -export const IEnable = mixin(>{ +export const IEnableMixin = mixin(>{ _enabled: true, @@ -18,14 +23,14 @@ export const IEnable = mixin(>{ enable() { this._enabled = true; if (this.notify) { - this.notify({ id: api.EVENT_ENABLE, target: this }); + this.notify({ id: EVENT_ENABLE, target: this }); } }, disable() { this._enabled = false; if (this.notify) { - this.notify({ id: api.EVENT_DISABLE, target: this }); + this.notify({ id: EVENT_DISABLE, target: this }); } }, diff --git a/packages/api/src/mixins/index.ts b/packages/api/src/mixins/index.ts deleted file mode 100644 index edd9378eb5..0000000000 --- a/packages/api/src/mixins/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./ienable"; -export * from "./inotify"; -export * from "./iterable"; -export * from "./iwatch"; diff --git a/packages/api/src/mixins/inotify.ts b/packages/api/src/mixins/inotify.ts index 114ce2bd19..1515b3b68d 100644 --- a/packages/api/src/mixins/inotify.ts +++ b/packages/api/src/mixins/inotify.ts @@ -1,27 +1,31 @@ -import * as api from "../api"; +import { + Event, + EVENT_ALL, + INotify, + Listener +} from "../api"; import { mixin } from "../mixin"; -export function inotify_dispatch(listeners: any[][], e: api.Event) { - if (!listeners) return; - const n = listeners.length; - let i = 0, l; - for (i = 0; i < n; i++) { - l = listeners[i]; - l[0].call(l[1], e); - if (e.canceled) { - return; +export const inotify_dispatch = + (listeners: any[][], e: Event) => { + if (!listeners) return; + for (let i = 0, n = listeners.length, l; i < n; i++) { + l = listeners[i]; + l[0].call(l[1], e); + if (e.canceled) { + return; + } } - } -} + }; /** * Mixin class decorator, injects INotify default implementation, incl. * a lazily instantiated `_listeners` property object, storing * registered listeners. */ -export const INotify = mixin({ +export const INotifyMixin = mixin({ - addListener(id: PropertyKey, fn: api.Listener, scope?: any) { + addListener(id: PropertyKey, fn: Listener, scope?: any) { let l = (this._listeners = this._listeners || {})[id]; if (!l) { l = this._listeners[id] = []; @@ -33,7 +37,7 @@ export const INotify = mixin({ return false; }, - removeListener(id: PropertyKey, fn: api.Listener, scope?: any) { + removeListener(id: PropertyKey, fn: Listener, scope?: any) { if (!this._listeners) return false; const l: any[][] = this._listeners[id]; if (l) { @@ -46,14 +50,14 @@ export const INotify = mixin({ return false; }, - notify(e: api.Event) { + notify(e: Event) { if (!this._listeners) return; e.target === undefined && (e.target = this); inotify_dispatch(this._listeners[e.id], e); - inotify_dispatch(this._listeners[api.EVENT_ALL], e); + inotify_dispatch(this._listeners[EVENT_ALL], e); }, - __listener(listeners: any[][], f: api.Listener, scope: any) { + __listener(listeners: any[][], f: Listener, scope: any) { let i = listeners.length; while (--i >= 0) { const l = listeners[i]; diff --git a/packages/api/src/mixins/iterable.ts b/packages/api/src/mixins/iterable.ts index 1677bce57b..e457619e7d 100644 --- a/packages/api/src/mixins/iterable.ts +++ b/packages/api/src/mixins/iterable.ts @@ -1,7 +1,7 @@ import { mixin } from "../mixin"; -export function iterable(prop: PropertyKey) { - return mixin({ - *[Symbol.iterator]() { yield* (this[prop]); }, - }); -} +export const iterable = + (prop: PropertyKey) => + mixin({ + *[Symbol.iterator]() { yield* (this[prop]); }, + }); diff --git a/packages/api/src/mixins/iwatch.ts b/packages/api/src/mixins/iwatch.ts index 84df30cc41..54d0af5e11 100644 --- a/packages/api/src/mixins/iwatch.ts +++ b/packages/api/src/mixins/iwatch.ts @@ -1,32 +1,33 @@ -import * as api from "../api"; +import { IWatch } from "../api"; import { mixin } from "../mixin"; -export const IWatch = mixin(>{ +export const IWatchMixin = + mixin(>{ - addWatch(id: string, fn: (id: string, oldState: any, newState: any) => void) { - this._watches = this._watches || {}; - if (this._watches[id]) { - return false; - } - this._watches[id] = fn; - return true; - }, - - removeWatch(id: string) { - if (!this._watches) return; - if (this._watches[id]) { - delete this._watches[id]; + addWatch(id: string, fn: (id: string, oldState: any, newState: any) => void) { + this._watches = this._watches || {}; + if (this._watches[id]) { + return false; + } + this._watches[id] = fn; return true; - } - return false; - }, + }, + + removeWatch(id: string) { + if (!this._watches) return; + if (this._watches[id]) { + delete this._watches[id]; + return true; + } + return false; + }, - notifyWatches(oldState: any, newState: any) { - if (!this._watches) return; - const w = this._watches; - for (let id in w) { - w[id](id, oldState, newState); + notifyWatches(oldState: any, newState: any) { + if (!this._watches) return; + const w = this._watches; + for (let id in w) { + w[id](id, oldState, newState); + } } - } -}); + }); diff --git a/packages/api/test/tsconfig.json b/packages/api/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/api/test/tsconfig.json +++ b/packages/api/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", From b54b703d4d694f86845925de40d919f7451b5e2b Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 8 Jan 2019 02:28:20 +0000 Subject: [PATCH 216/333] build: update package build scripts & outputs, imports in ~50 packages BREAKING CHANGE: enabled multi-outputs (ES6 modules, CJS, UMD) - build scripts now first build ES6 modules in package root, then call `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` - all imports MUST be updated to only refer to package level (not individual files anymore). tree shaking in user land will get rid of all unused imported symbols. --- packages/associative/package.json | 17 +- packages/associative/src/api.ts | 2 +- packages/associative/src/array-set.ts | 2 +- packages/associative/src/common-keys.ts | 2 +- packages/associative/src/equiv-map.ts | 3 +- packages/associative/src/invert.ts | 3 +- packages/associative/src/join.ts | 3 +- packages/associative/src/ll-set.ts | 3 +- packages/associative/src/merge-apply.ts | 5 +- packages/associative/src/merge-deep.ts | 5 +- packages/associative/src/merge-with.ts | 3 +- packages/associative/src/merge.ts | 2 +- packages/associative/src/rename-keys.ts | 3 +- packages/associative/src/select-keys.ts | 3 +- packages/associative/src/sorted-map.ts | 16 +- packages/associative/src/sorted-set.ts | 6 +- packages/associative/src/utils.ts | 2 +- packages/associative/test/tsconfig.json | 3 +- packages/atom/package.json | 14 +- packages/atom/src/api.ts | 25 +- packages/atom/src/atom.ts | 14 +- packages/atom/src/cursor.ts | 8 +- packages/atom/src/history.ts | 12 +- packages/atom/test/atom.ts | 6 +- packages/atom/test/cursor.ts | 5 +- packages/atom/test/history.ts | 1 - packages/atom/test/tsconfig.json | 3 +- packages/atom/test/view.ts | 4 +- packages/bench/package.json | 14 +- packages/bench/test/tsconfig.json | 3 +- packages/binary/package.json | 14 +- packages/binary/test/tsconfig.json | 3 +- packages/bitstream/package.json | 17 +- packages/bitstream/test/index.ts | 2 +- packages/bitstream/test/tsconfig.json | 3 +- packages/cache/package.json | 17 +- packages/cache/src/api.ts | 2 +- packages/cache/src/lru.ts | 6 +- packages/cache/src/mru.ts | 1 - packages/cache/src/tlru.ts | 1 - packages/cache/test/tsconfig.json | 3 +- packages/checks/package.json | 12 +- packages/checks/test/tsconfig.json | 3 +- packages/compare/package.json | 17 +- packages/compare/test/tsconfig.json | 3 +- packages/compose/package.json | 19 +- packages/compose/src/comp.ts | 4 +- packages/compose/src/juxt.ts | 2 +- packages/compose/src/partial.ts | 2 +- packages/compose/src/thread-first.ts | 2 +- packages/compose/src/thread-last.ts | 2 +- packages/compose/test/tsconfig.json | 3 +- packages/csp/package.json | 15 +- packages/csp/src/api.ts | 3 +- packages/csp/src/buffer.ts | 4 +- packages/csp/src/channel.ts | 32 +- packages/csp/src/mult.ts | 5 +- packages/csp/src/pubsub.ts | 7 +- packages/csp/test/node.ts | 7 +- packages/csp/test/tsconfig.json | 3 +- packages/dcons/package.json | 17 +- packages/dcons/src/index.ts | 10 +- packages/dcons/test/tsconfig.json | 3 +- packages/defmulti/package.json | 17 +- packages/defmulti/src/index.ts | 11 +- packages/defmulti/test/tsconfig.json | 3 +- packages/dgraph/package.json | 17 +- packages/dgraph/src/index.ts | 11 +- packages/dgraph/test/tsconfig.json | 3 +- packages/diff/package.json | 22 +- packages/diff/src/api.ts | 2 +- packages/diff/src/object.ts | 2 +- packages/diff/test/tsconfig.json | 3 +- packages/dlogic/package.json | 17 +- packages/dlogic/test/tsconfig.json | 3 +- packages/dot/package.json | 17 +- packages/dot/src/api.ts | 2 +- packages/dot/src/serialize.ts | 5 +- packages/dot/test/tsconfig.json | 3 +- packages/dsp/package.json | 17 +- packages/dsp/src/api.ts | 3 +- packages/dsp/src/osc.ts | 11 +- packages/dsp/test/tsconfig.json | 3 +- packages/equiv/package.json | 14 +- packages/equiv/test/tsconfig.json | 3 +- packages/errors/package.json | 14 +- packages/errors/test/tsconfig.json | 3 +- packages/fsm/package.json | 17 +- packages/fsm/src/fsm.ts | 8 +- packages/fsm/test/tsconfig.json | 3 +- packages/geom-accel/package.json | 18 +- packages/geom-accel/src/kdtree.ts | 10 +- packages/geom-accel/test/tsconfig.json | 3 +- packages/geom/package.json | 18 +- packages/geom/src/api.ts | 10 +- packages/geom/src/arc2.ts | 29 +- packages/geom/src/bezier2.ts | 14 +- packages/geom/src/circle2.ts | 14 +- packages/geom/src/container2.ts | 3 +- packages/geom/src/container3.ts | 5 +- packages/geom/src/fit.ts | 3 +- packages/geom/src/index.ts | 3 - packages/geom/src/internal/arc-length.ts | 2 +- packages/geom/src/internal/area.ts | 2 +- packages/geom/src/internal/args.ts | 8 +- packages/geom/src/internal/barycentric.ts | 3 +- packages/geom/src/internal/bounds.ts | 2 +- packages/geom/src/internal/centroid.ts | 55 ++-- packages/geom/src/internal/circumcenter.ts | 4 +- packages/geom/src/internal/closest-point.ts | 2 +- packages/geom/src/internal/collate.ts | 14 +- packages/geom/src/internal/corner.ts | 5 +- .../internal/douglas\342\200\223peucker.ts" | 4 +- packages/geom/src/internal/edges.ts | 9 +- packages/geom/src/internal/eq-delta.ts | 19 +- packages/geom/src/internal/graham-scan.ts | 49 ++-- packages/geom/src/internal/liang-barsky.ts | 4 +- .../geom/src/internal/line-intersection.ts | 55 ++-- .../geom/src/internal/sutherland-hodgeman.ts | 53 ++-- packages/geom/src/line2.ts | 12 +- packages/geom/src/path2.ts | 18 +- packages/geom/src/polygon2.ts | 30 +- packages/geom/src/polyline2.ts | 10 +- packages/geom/src/quad2.ts | 3 +- packages/geom/src/rect2.ts | 7 +- packages/geom/src/sampler.ts | 4 +- packages/geom/src/subdiv-curve.ts | 18 +- packages/geom/src/tessellate.ts | 33 ++- packages/geom/src/triangle2.ts | 11 +- packages/geom/src/warp.ts | 23 +- packages/geom/test/circle2.ts | 4 +- packages/geom/test/tsconfig.json | 3 +- packages/heaps/package.json | 17 +- packages/heaps/src/api.ts | 2 +- packages/heaps/src/dheap.ts | 2 +- packages/heaps/src/heap.ts | 2 +- packages/heaps/test/tsconfig.json | 3 +- packages/hiccup-carbon-icons/package.json | 27 +- .../hiccup-carbon-icons/test/tsconfig.json | 3 +- packages/hiccup-css/package.json | 17 +- packages/hiccup-css/src/api.ts | 2 +- packages/hiccup-css/src/conditional.ts | 3 +- packages/hiccup-css/src/css.ts | 12 +- packages/hiccup-css/src/impl.ts | 32 +- packages/hiccup-css/test/tsconfig.json | 3 +- packages/hiccup-markdown/package.json | 17 +- packages/hiccup-markdown/src/parse.ts | 22 +- packages/hiccup-markdown/src/serialize.ts | 17 +- packages/hiccup-markdown/test/tsconfig.json | 3 +- packages/hiccup-svg/package.json | 21 +- packages/hiccup-svg/src/circle.ts | 15 +- packages/hiccup-svg/src/convert.ts | 277 +++++++++--------- packages/hiccup-svg/src/defs.ts | 5 +- packages/hiccup-svg/src/format.ts | 12 +- packages/hiccup-svg/src/gradients.ts | 36 +-- packages/hiccup-svg/src/group.ts | 5 +- packages/hiccup-svg/src/image.ts | 15 +- packages/hiccup-svg/src/line.ts | 27 +- packages/hiccup-svg/src/path.ts | 63 ++-- packages/hiccup-svg/src/points.ts | 43 +-- packages/hiccup-svg/src/polygon.ts | 5 +- packages/hiccup-svg/src/polyline.ts | 5 +- packages/hiccup-svg/src/rect.ts | 5 +- packages/hiccup-svg/src/svg.ts | 17 +- packages/hiccup-svg/src/text.ts | 13 +- packages/hiccup-svg/test/tsconfig.json | 3 +- packages/hiccup/package.json | 17 +- packages/hiccup/src/css.ts | 2 +- packages/hiccup/src/deref.ts | 2 +- packages/hiccup/src/serialize.ts | 14 +- packages/hiccup/test/tsconfig.json | 3 +- packages/iges/package.json | 17 +- packages/iges/src/index.ts | 24 +- packages/iges/test/tsconfig.json | 3 +- packages/interceptors/package.json | 17 +- packages/interceptors/src/api.ts | 2 +- packages/interceptors/src/event-bus.ts | 18 +- packages/interceptors/src/interceptors.ts | 1 - packages/interceptors/test/tsconfig.json | 3 +- packages/intervals/package.json | 17 +- packages/intervals/src/index.ts | 10 +- packages/intervals/test/tsconfig.json | 3 +- packages/iterators/package.json | 17 +- packages/iterators/src/dedupe-with.ts | 3 +- packages/iterators/src/drop-while.ts | 3 +- packages/iterators/src/ensure.ts | 3 +- packages/iterators/src/every.ts | 3 +- packages/iterators/src/filter.ts | 3 +- packages/iterators/src/fork.ts | 1 - packages/iterators/src/interleave.ts | 3 +- packages/iterators/src/partition.ts | 3 +- packages/iterators/src/some.ts | 3 +- packages/iterators/src/take-while.ts | 3 +- packages/iterators/src/walk.ts | 2 +- packages/iterators/test/tsconfig.json | 3 +- packages/malloc/package.json | 17 +- packages/malloc/src/index.ts | 6 +- packages/malloc/test/tsconfig.json | 3 +- packages/math/package.json | 17 +- packages/math/test/tsconfig.json | 3 +- packages/memoize/package.json | 17 +- packages/memoize/src/defonce.ts | 2 +- packages/memoize/src/memoizej.ts | 2 +- packages/memoize/test/tsconfig.json | 3 +- packages/morton/package.json | 17 +- packages/morton/src/index.ts | 8 +- packages/morton/test/tsconfig.json | 3 +- packages/paths/package.json | 14 +- packages/paths/src/index.ts | 4 +- packages/paths/test/tsconfig.json | 3 +- packages/pointfree-lang/package.json | 23 +- packages/pointfree-lang/src/index.ts | 5 +- packages/pointfree-lang/test/tsconfig.json | 3 +- packages/pointfree/package.json | 17 +- packages/pointfree/src/index.ts | 12 +- packages/pointfree/test/tsconfig.json | 3 +- packages/random/package.json | 17 +- packages/random/src/api.ts | 2 +- packages/random/src/smush32.ts | 2 +- packages/random/src/xorshift128.ts | 2 +- packages/random/src/xorwow.ts | 2 +- packages/random/src/xsadd.ts | 2 +- packages/random/test/tsconfig.json | 3 +- packages/range-coder/package.json | 17 +- packages/range-coder/test/index.ts | 6 +- packages/range-coder/test/tsconfig.json | 3 +- packages/resolve-map/package.json | 19 +- packages/resolve-map/src/index.ts | 14 +- packages/resolve-map/test/tsconfig.json | 3 +- packages/rle-pack/package.json | 23 +- packages/rle-pack/src/index.ts | 2 +- packages/rle-pack/test/tsconfig.json | 3 +- packages/router/package.json | 23 +- packages/router/src/api.ts | 2 +- packages/router/src/basic.ts | 12 +- packages/router/src/history.ts | 3 +- packages/router/test/tsconfig.json | 3 +- packages/sax/package.json | 17 +- packages/sax/src/index.ts | 3 +- packages/sax/test/tsconfig.json | 3 +- packages/strings/package.json | 32 +- packages/strings/src/center.ts | 2 +- packages/strings/src/float.ts | 2 +- packages/strings/src/format.ts | 31 +- packages/strings/src/pad-left.ts | 2 +- packages/strings/src/pad-right.ts | 2 +- packages/strings/src/parse.ts | 18 +- packages/strings/src/percent.ts | 5 +- packages/strings/src/radix.ts | 3 +- packages/strings/src/repeat.ts | 2 +- packages/strings/src/splice.ts | 37 +-- packages/strings/src/truncate-left.ts | 3 +- packages/strings/src/truncate.ts | 3 +- packages/strings/src/units.ts | 3 +- packages/strings/src/wrap.ts | 3 +- packages/strings/test/tsconfig.json | 3 +- packages/transducers-fsm/package.json | 17 +- packages/transducers-fsm/src/index.ts | 14 +- packages/transducers-fsm/test/tsconfig.json | 3 +- packages/transducers-hdom/test/tsconfig.json | 3 +- packages/transducers-stats/package.json | 18 +- packages/transducers-stats/src/bollinger.ts | 17 +- packages/transducers-stats/src/donchian.ts | 13 +- packages/transducers-stats/src/ema.ts | 11 +- packages/transducers-stats/src/hma.ts | 15 +- packages/transducers-stats/src/macd.ts | 12 +- packages/transducers-stats/src/momentum.ts | 11 +- packages/transducers-stats/src/roc.ts | 11 +- packages/transducers-stats/src/rsi.ts | 15 +- packages/transducers-stats/src/sd.ts | 17 +- packages/transducers-stats/src/sma.ts | 11 +- packages/transducers-stats/src/stochastic.ts | 12 +- packages/transducers-stats/src/trix.ts | 5 +- packages/transducers-stats/src/wma.ts | 17 +- packages/transducers-stats/test/tsconfig.json | 3 +- packages/transducers/package.json | 20 +- packages/transducers/src/api.ts | 2 +- .../transducers/src/func/binary-search.ts | 2 +- packages/transducers/src/func/comp.ts | 3 +- .../transducers/src/func/deep-transform.ts | 3 +- packages/transducers/src/func/ensure-array.ts | 3 +- .../transducers/src/func/ensure-iterable.ts | 2 +- packages/transducers/src/func/even.ts | 2 +- packages/transducers/src/func/fuzzy-match.ts | 2 +- packages/transducers/src/func/hex.ts | 3 +- packages/transducers/src/func/juxt.ts | 2 +- packages/transducers/src/func/odd.ts | 2 +- packages/transducers/src/func/renamer.ts | 2 +- packages/transducers/src/iter/pairs.ts | 2 +- packages/transducers/src/iter/permutations.ts | 2 +- packages/transducers/src/iter/range2d.ts | 3 +- packages/transducers/src/iter/range3d.ts | 3 +- packages/transducers/src/iter/vals.ts | 2 +- packages/transducers/src/iter/wrap.ts | 2 +- packages/transducers/src/iterator.ts | 4 +- packages/transducers/src/reduce.ts | 7 +- packages/transducers/src/reduced.ts | 2 +- packages/transducers/src/rfn/assoc-map.ts | 5 +- packages/transducers/src/rfn/assoc-obj.ts | 3 +- packages/transducers/src/rfn/every.ts | 3 +- packages/transducers/src/rfn/fill.ts | 5 +- packages/transducers/src/rfn/frequencies.ts | 3 +- packages/transducers/src/rfn/group-binary.ts | 3 +- packages/transducers/src/rfn/group-by-obj.ts | 5 +- packages/transducers/src/rfn/max-compare.ts | 3 +- packages/transducers/src/rfn/min-compare.ts | 3 +- packages/transducers/src/rfn/some.ts | 3 +- packages/transducers/src/transduce.ts | 3 +- packages/transducers/src/xform/convolve.ts | 3 +- packages/transducers/src/xform/dedupe.ts | 3 +- packages/transducers/src/xform/drop-while.ts | 3 +- .../transducers/src/xform/filter-fuzzy.ts | 3 +- packages/transducers/src/xform/hex-dump.ts | 3 +- packages/transducers/src/xform/labeled.ts | 3 +- packages/transducers/src/xform/map-keys.ts | 3 +- packages/transducers/src/xform/map-nth.ts | 3 +- packages/transducers/src/xform/map-vals.ts | 3 +- packages/transducers/src/xform/map.ts | 3 +- packages/transducers/src/xform/mapcat.ts | 3 +- .../transducers/src/xform/moving-average.ts | 3 +- .../transducers/src/xform/multiplex-obj.ts | 3 +- .../transducers/src/xform/partition-by.ts | 3 +- .../transducers/src/xform/partition-sync.ts | 5 +- packages/transducers/src/xform/rename.ts | 5 +- packages/transducers/src/xform/struct.ts | 3 +- packages/transducers/src/xform/take-while.ts | 3 +- packages/transducers/src/xform/throttle.ts | 3 +- packages/transducers/test/partition-bits.ts | 2 +- packages/transducers/test/tsconfig.json | 3 +- packages/unionstruct/package.json | 18 +- packages/unionstruct/src/index.ts | 145 +++++---- packages/unionstruct/test/tsconfig.json | 3 +- packages/vectors/package.json | 17 +- packages/vectors/src/api.ts | 8 +- packages/vectors/src/codegen.ts | 18 +- packages/vectors/src/common.ts | 3 +- packages/vectors/src/gvec.ts | 20 +- packages/vectors/src/mat23.ts | 6 +- packages/vectors/src/mat33.ts | 6 +- packages/vectors/src/mat44.ts | 6 +- packages/vectors/src/vec2.ts | 22 +- packages/vectors/src/vec3.ts | 20 +- packages/vectors/src/vec4.ts | 18 +- packages/vectors/test/tsconfig.json | 3 +- 344 files changed, 1862 insertions(+), 1595 deletions(-) diff --git a/packages/associative/package.json b/packages/associative/package.json index 72fa50cebc..240c201b25 100644 --- a/packages/associative/package.json +++ b/packages/associative/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/associative", "version": "0.6.23", "description": "Alternative Set & Map data type implementations with customizable equality semantics & supporting operations", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module associative api checks compare dcons equiv errors transducers", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -53,5 +57,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/associative/src/api.ts b/packages/associative/src/api.ts index bcb6d9c5cf..3b92d71fcf 100644 --- a/packages/associative/src/api.ts +++ b/packages/associative/src/api.ts @@ -4,7 +4,7 @@ import { IEmpty, IEquiv, Predicate2 -} from "@thi.ng/api/api"; +} from "@thi.ng/api"; export interface IEquivSet extends Set, diff --git a/packages/associative/src/array-set.ts b/packages/associative/src/array-set.ts index f6da3eeddf..3e4098fd53 100644 --- a/packages/associative/src/array-set.ts +++ b/packages/associative/src/array-set.ts @@ -1,4 +1,4 @@ -import { Pair, Predicate2, SEMAPHORE } from "@thi.ng/api/api"; +import { Pair, Predicate2, SEMAPHORE } from "@thi.ng/api"; import { equiv } from "@thi.ng/equiv"; import { EquivSetOpts, IEquivSet } from "./api"; diff --git a/packages/associative/src/common-keys.ts b/packages/associative/src/common-keys.ts index bb647f358d..ce5b8962dc 100644 --- a/packages/associative/src/common-keys.ts +++ b/packages/associative/src/common-keys.ts @@ -1,4 +1,4 @@ -import { IObjectOf } from "@thi.ng/api/api"; +import { IObjectOf } from "@thi.ng/api"; /** * Like `commonKeysObj()`, but for ES6 Maps. diff --git a/packages/associative/src/equiv-map.ts b/packages/associative/src/equiv-map.ts index e66f961a9b..883f7ac8c8 100644 --- a/packages/associative/src/equiv-map.ts +++ b/packages/associative/src/equiv-map.ts @@ -5,9 +5,8 @@ import { IObjectOf, Pair, SEMAPHORE -} from "@thi.ng/api/api"; +} from "@thi.ng/api"; import { equiv } from "@thi.ng/equiv"; - import { EquivMapOpts, IEquivSet } from "./api"; import { ArraySet } from "./array-set"; diff --git a/packages/associative/src/invert.ts b/packages/associative/src/invert.ts index 2429da833e..88eac4c0dd 100644 --- a/packages/associative/src/invert.ts +++ b/packages/associative/src/invert.ts @@ -1,5 +1,4 @@ -import { IObjectOf } from "@thi.ng/api/api"; - +import { IObjectOf } from "@thi.ng/api"; import { empty } from "./utils"; /** diff --git a/packages/associative/src/join.ts b/packages/associative/src/join.ts index e3c2421759..040c825fb1 100644 --- a/packages/associative/src/join.ts +++ b/packages/associative/src/join.ts @@ -1,5 +1,4 @@ -import { IObjectOf } from "@thi.ng/api/api"; - +import { IObjectOf } from "@thi.ng/api"; import { commonKeysObj } from "./common-keys"; import { indexed } from "./indexed"; import { invertObj } from "./invert"; diff --git a/packages/associative/src/ll-set.ts b/packages/associative/src/ll-set.ts index b537782cd6..23fa0542f4 100644 --- a/packages/associative/src/ll-set.ts +++ b/packages/associative/src/ll-set.ts @@ -1,7 +1,6 @@ -import { Pair, Predicate2, SEMAPHORE } from "@thi.ng/api/api"; +import { Pair, Predicate2, SEMAPHORE } from "@thi.ng/api"; import { DCons } from "@thi.ng/dcons"; import { equiv } from "@thi.ng/equiv"; - import { EquivSetOpts, IEquivSet } from "./api"; interface SetProps { diff --git a/packages/associative/src/merge-apply.ts b/packages/associative/src/merge-apply.ts index 4947a2d9c5..4f9c77c8be 100644 --- a/packages/associative/src/merge-apply.ts +++ b/packages/associative/src/merge-apply.ts @@ -1,6 +1,5 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { isFunction } from "@thi.ng/checks/is-function"; - +import { IObjectOf } from "@thi.ng/api"; +import { isFunction } from "@thi.ng/checks"; import { copy } from "./utils"; /** diff --git a/packages/associative/src/merge-deep.ts b/packages/associative/src/merge-deep.ts index 11e41b6b97..577a8f0e8e 100644 --- a/packages/associative/src/merge-deep.ts +++ b/packages/associative/src/merge-deep.ts @@ -1,6 +1,5 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { isPlainObject } from "@thi.ng/checks/is-plain-object"; - +import { IObjectOf } from "@thi.ng/api"; +import { isPlainObject } from "@thi.ng/checks"; import { mergeObjWith } from "./merge-with"; export const mergeDeepObj = diff --git a/packages/associative/src/merge-with.ts b/packages/associative/src/merge-with.ts index 64f79b80ed..2f3adb9fd3 100644 --- a/packages/associative/src/merge-with.ts +++ b/packages/associative/src/merge-with.ts @@ -1,5 +1,4 @@ -import { IObjectOf } from "@thi.ng/api/api"; - +import { IObjectOf } from "@thi.ng/api"; import { copy } from "./utils"; export const mergeMapWith = ( diff --git a/packages/associative/src/merge.ts b/packages/associative/src/merge.ts index da901fa7f0..3ddea8e7d3 100644 --- a/packages/associative/src/merge.ts +++ b/packages/associative/src/merge.ts @@ -1,4 +1,4 @@ -import { IObjectOf } from "@thi.ng/api/api"; +import { IObjectOf } from "@thi.ng/api"; /** * Merges all given maps in left-to-right order into `dest`. diff --git a/packages/associative/src/rename-keys.ts b/packages/associative/src/rename-keys.ts index af06d7e462..5dbf167e55 100644 --- a/packages/associative/src/rename-keys.ts +++ b/packages/associative/src/rename-keys.ts @@ -1,5 +1,4 @@ -import { IObjectOf } from "@thi.ng/api/api"; - +import { IObjectOf } from "@thi.ng/api"; import { empty } from "./utils"; /** diff --git a/packages/associative/src/select-keys.ts b/packages/associative/src/select-keys.ts index 9307b4e6e8..9494862568 100644 --- a/packages/associative/src/select-keys.ts +++ b/packages/associative/src/select-keys.ts @@ -1,5 +1,4 @@ -import { IObjectOf } from "@thi.ng/api/api"; - +import { IObjectOf } from "@thi.ng/api"; import { empty } from "./utils"; /** diff --git a/packages/associative/src/sorted-map.ts b/packages/associative/src/sorted-map.ts index 49b7763a8c..465d43e8d6 100644 --- a/packages/associative/src/sorted-map.ts +++ b/packages/associative/src/sorted-map.ts @@ -8,15 +8,17 @@ import { Pair, Predicate2, SEMAPHORE -} from "@thi.ng/api/api"; -import { isArray } from "@thi.ng/checks/is-array"; +} from "@thi.ng/api"; +import { isArray } from "@thi.ng/checks"; import { compare } from "@thi.ng/compare"; import { equiv } from "@thi.ng/equiv"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { IReducible, ReductionFn } from "@thi.ng/transducers/api"; -import { isReduced } from "@thi.ng/transducers/reduced"; -import { map } from "@thi.ng/transducers/xform/map"; - +import { illegalArgs } from "@thi.ng/errors"; +import { + IReducible, + isReduced, + map, + ReductionFn +} from "@thi.ng/transducers"; import { SortedMapOpts } from "./api"; // stores private properties for all instances diff --git a/packages/associative/src/sorted-set.ts b/packages/associative/src/sorted-set.ts index 10f2ba080b..657426c76e 100644 --- a/packages/associative/src/sorted-set.ts +++ b/packages/associative/src/sorted-set.ts @@ -1,10 +1,8 @@ -import { ICompare, Pair, } from "@thi.ng/api/api"; import { compare } from "@thi.ng/compare"; -import { IReducible, ReductionFn } from "@thi.ng/transducers/api"; -import { map } from "@thi.ng/transducers/xform/map"; - +import { IReducible, map, ReductionFn } from "@thi.ng/transducers"; import { IEquivSet, SortedSetOpts } from "./api"; import { SortedMap } from "./sorted-map"; +import { ICompare, Pair, } from "@thi.ng/api"; const __private = new WeakMap, SortedMap>(); diff --git a/packages/associative/src/utils.ts b/packages/associative/src/utils.ts index 7082e43c53..51da602328 100644 --- a/packages/associative/src/utils.ts +++ b/packages/associative/src/utils.ts @@ -1,4 +1,4 @@ -import { implementsFunction } from "@thi.ng/checks/implements-function"; +import { implementsFunction } from "@thi.ng/checks"; export const empty = (x, ctor) => implementsFunction(x, "empty") ? x.empty() : new (x[Symbol.species] || ctor)(); diff --git a/packages/associative/test/tsconfig.json b/packages/associative/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/associative/test/tsconfig.json +++ b/packages/associative/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/atom/package.json b/packages/atom/package.json index 307e8b6c87..5b0e55f4ee 100644 --- a/packages/atom/package.json +++ b/packages/atom/package.json @@ -4,6 +4,7 @@ "description": "Mutable wrappers for nested immutable values w/ optional undo/redo history", "module": "./index.js", "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -13,13 +14,11 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && yarn build:es6 && yarn build:parcel && yarn build:parcel:min", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", "build:es6": "tsc --declaration", - "build:parcel:min": "parcel build --global thing_atom -o index.min.js -d lib --experimental-scope-hoisting src/index.ts", - "build:parcel": "parcel build --global thing_atom -d lib --no-minify --experimental-scope-hoisting src/index.ts && prettier --write lib/index.js", - "build:gzip": "gzip -c lib/index.min.js > lib/index.min.js.gz", - "clean": "rimraf *.js *.d.ts .cache .nyc_output build coverage doc lib", - "test": "rimraf build && parcel build -d build --no-cache --no-minify --no-source-maps test/index.ts && nyc mocha build/index.js", + "build:bundle": "../../scripts/bundle-module atom api checks equiv errors paths", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public" @@ -59,5 +58,6 @@ "browser": { "process": false, "setTimeout": false - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/atom/src/api.ts b/packages/atom/src/api.ts index 2f64fc85a1..68ed2ca515 100644 --- a/packages/atom/src/api.ts +++ b/packages/atom/src/api.ts @@ -1,4 +1,11 @@ -import * as api from "@thi.ng/api/api"; +import { + IDeref, + IID, + INotify, + IRelease, + IWatch, + Predicate +} from "@thi.ng/api"; import { Path } from "@thi.ng/paths"; export type SwapFn = (curr: T, ...args: any[]) => T; @@ -6,9 +13,9 @@ export type SwapFn = (curr: T, ...args: any[]) => T; export type ViewTransform = (x: any) => T; export interface ReadonlyAtom extends - api.IDeref, - api.IRelease, - api.IWatch, + IDeref, + IRelease, + IWatch, IViewable { } @@ -29,9 +36,9 @@ export interface ISwap { } export interface IView extends - api.IDeref, - api.IID, - api.IRelease { + IDeref, + IID, + IRelease { readonly path: PropertyKey[]; readonly value: T; @@ -47,13 +54,13 @@ export interface IViewable { export interface CursorOpts { parent: IAtom; path: Path | [(s: any) => T, (s: any, v: T) => any]; - validate?: api.Predicate; + validate?: Predicate; id?: string; } export interface IHistory extends IAtom, - api.INotify { + INotify { canUndo(): boolean; canRedo(): boolean; diff --git a/packages/atom/src/atom.ts b/packages/atom/src/atom.ts index 2f9bdd0886..3aaebf8749 100644 --- a/packages/atom/src/atom.ts +++ b/packages/atom/src/atom.ts @@ -1,8 +1,11 @@ -import { IEquiv, Predicate, Watch } from "@thi.ng/api/api"; -import { IWatch } from "@thi.ng/api/mixins/iwatch"; -import { illegalState } from "@thi.ng/errors/illegal-state"; +import { + IEquiv, + IWatchMixin, + Predicate, + Watch +} from "@thi.ng/api"; +import { illegalState } from "@thi.ng/errors"; import { Path, setIn, updateIn } from "@thi.ng/paths"; - import { IAtom, IView, @@ -11,11 +14,12 @@ import { } from "./api"; import { View } from "./view"; + /** * Mutable wrapper for an (usually) immutable value. Support for * watches. */ -@IWatch +@IWatchMixin export class Atom implements IAtom, IEquiv { diff --git a/packages/atom/src/cursor.ts b/packages/atom/src/cursor.ts index 713be975ad..23f249272d 100644 --- a/packages/atom/src/cursor.ts +++ b/packages/atom/src/cursor.ts @@ -1,8 +1,6 @@ -import { IID, IRelease, Watch } from "@thi.ng/api/api"; -import { isArray } from "@thi.ng/checks/is-array"; -import { isFunction } from "@thi.ng/checks/is-function"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { illegalArity } from "@thi.ng/errors/illegal-arity"; +import { IID, IRelease, Watch } from "@thi.ng/api"; +import { isArray, isFunction } from "@thi.ng/checks"; +import { illegalArgs, illegalArity } from "@thi.ng/errors"; import { getter, Path, setter } from "@thi.ng/paths"; import { CursorOpts, diff --git a/packages/atom/src/history.ts b/packages/atom/src/history.ts index 9f04b70f4b..3b806945b3 100644 --- a/packages/atom/src/history.ts +++ b/packages/atom/src/history.ts @@ -1,5 +1,9 @@ -import { Event, Predicate2, Watch } from "@thi.ng/api/api"; -import * as mixin from "@thi.ng/api/mixins/inotify"; +import { + Event, + INotifyMixin, + Predicate2, + Watch +} from "@thi.ng/api"; import { equiv } from "@thi.ng/equiv"; import { getIn, @@ -7,7 +11,6 @@ import { setIn, updateIn } from "@thi.ng/paths"; - import { IAtom, IHistory, @@ -17,6 +20,7 @@ import { } from "./api"; import { View } from "./view"; + /** * Undo/redo history stack wrapper for atoms and cursors. Implements * `IAtom` interface and so can be used directly in place and delegates @@ -26,7 +30,7 @@ import { View } from "./view"; * `INotify` interface to support event listeners for `undo()`, `redo()` * and `record()`. */ -@mixin.INotify +@INotifyMixin export class History implements IHistory { diff --git a/packages/atom/test/atom.ts b/packages/atom/test/atom.ts index 86350ad5c6..c81ff901bb 100644 --- a/packages/atom/test/atom.ts +++ b/packages/atom/test/atom.ts @@ -1,6 +1,6 @@ +import { isNumber } from "@thi.ng/checks"; import * as assert from "assert"; import { Atom } from "../src/index"; -import { isNumber } from "@thi.ng/checks/is-number"; describe("atom", function () { @@ -51,7 +51,7 @@ describe("atom", function () { assert.equal(a.reset(2), 2); assert.equal(a.reset("3"), 2); assert.equal(a.reset(null), 2); - assert.equal(a.swap((x) => "3"), 2); - assert.equal(a.swap((x) => null), 2); + assert.equal(a.swap(() => "3"), 2); + assert.equal(a.swap(() => null), 2); }); }); diff --git a/packages/atom/test/cursor.ts b/packages/atom/test/cursor.ts index 348bd479a1..bd168fbada 100644 --- a/packages/atom/test/cursor.ts +++ b/packages/atom/test/cursor.ts @@ -1,8 +1,7 @@ -import * as assert from "assert"; +import { isNumber } from "@thi.ng/checks"; import { getIn } from "@thi.ng/paths"; - +import * as assert from "assert"; import { Atom, Cursor } from "../src/index"; -import { isNumber } from "@thi.ng/checks/is-number"; describe("cursor", function () { diff --git a/packages/atom/test/history.ts b/packages/atom/test/history.ts index 6b0445693e..20a7e49732 100644 --- a/packages/atom/test/history.ts +++ b/packages/atom/test/history.ts @@ -1,5 +1,4 @@ import * as assert from "assert"; - import { Atom } from "../src/atom"; import { Cursor } from "../src/cursor"; import { History } from "../src/history"; diff --git a/packages/atom/test/tsconfig.json b/packages/atom/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/atom/test/tsconfig.json +++ b/packages/atom/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/atom/test/view.ts b/packages/atom/test/view.ts index 5eeaf7e38e..c755ec7017 100644 --- a/packages/atom/test/view.ts +++ b/packages/atom/test/view.ts @@ -1,7 +1,5 @@ -import * as assert from "assert"; - import { setIn, updateIn } from "@thi.ng/paths"; - +import * as assert from "assert"; import { IView } from "../src/api"; import { Atom } from "../src/atom"; import { Cursor } from "../src/cursor"; diff --git a/packages/bench/package.json b/packages/bench/package.json index b30ab6a162..66cf9cbf82 100644 --- a/packages/bench/package.json +++ b/packages/bench/package.json @@ -4,6 +4,7 @@ "description": "Basic benchmarking helpers", "module": "./index.js", "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -13,13 +14,11 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && yarn build:es6 && yarn build:parcel && yarn build:parcel:min", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", "build:es6": "tsc --declaration", - "build:parcel:min": "parcel build --global thing_bench -o index.min.js -d lib --experimental-scope-hoisting src/index.ts", - "build:parcel": "parcel build --global thing_bench -d lib --no-minify --experimental-scope-hoisting src/index.ts && prettier --write lib/index.js", - "build:gzip": "gzip -c lib/index.min.js > lib/index.min.js.gz", - "clean": "rimraf *.js *.d.ts .cache .nyc_output build coverage doc lib", - "test": "rimraf build && parcel build -d build --no-cache --no-minify --no-source-maps test/index.ts && nyc mocha build/index.js", + "build:bundle": "../../scripts/bundle-module bench", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public" @@ -50,5 +49,6 @@ "browser": { "process": false, "setTimeout": false - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/bench/test/tsconfig.json b/packages/bench/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/bench/test/tsconfig.json +++ b/packages/bench/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/binary/package.json b/packages/binary/package.json index 9c4c6e2e38..1dce3e0718 100644 --- a/packages/binary/package.json +++ b/packages/binary/package.json @@ -4,6 +4,7 @@ "description": "Assorted binary / bitwise operations, conversions, utilities.", "module": "./index.js", "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -13,13 +14,11 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && yarn build:es6 && yarn build:parcel && yarn build:parcel:min", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", "build:es6": "tsc --declaration", - "build:parcel:min": "parcel build --global thing_binary -o index.min.js -d lib --experimental-scope-hoisting src/index.ts", - "build:parcel": "parcel build --global thing_binary -d lib --no-minify --experimental-scope-hoisting src/index.ts && prettier --write lib/index.js", - "build:gzip": "gzip -c lib/index.min.js > lib/index.min.js.gz", - "clean": "rimraf *.js *.d.ts .cache .nyc_output build coverage doc lib", - "test": "rimraf build && parcel build -d build --no-cache --no-minify --no-source-maps test/index.ts && nyc mocha build/index.js", + "build:bundle": "../../scripts/bundle-module binary", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public" @@ -47,5 +46,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/binary/test/tsconfig.json b/packages/binary/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/binary/test/tsconfig.json +++ b/packages/binary/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/bitstream/package.json b/packages/bitstream/package.json index 2477e45577..99ba9fd229 100644 --- a/packages/bitstream/package.json +++ b/packages/bitstream/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/bitstream", "version": "0.4.21", "description": "ES6 iterator based read/write bit streams & support for variable word widths", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module bitstream errors", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "dependencies": { "@thi.ng/errors": "^0.1.12" @@ -41,5 +45,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/bitstream/test/index.ts b/packages/bitstream/test/index.ts index 34f9102512..da632c1d66 100644 --- a/packages/bitstream/test/index.ts +++ b/packages/bitstream/test/index.ts @@ -1,5 +1,5 @@ -import * as bits from "../src/index"; import * as assert from "assert"; +import * as bits from "../src/index"; describe("BitInputStream", function () { let src = new Uint8Array([0xbe, 0xef, 0xde, 0xca, 0xfb, 0xad, 0xf0, 0x0b, 0xaa]); diff --git a/packages/bitstream/test/tsconfig.json b/packages/bitstream/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/bitstream/test/tsconfig.json +++ b/packages/bitstream/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/cache/package.json b/packages/cache/package.json index 9195bf1efe..fcbd6c3d34 100644 --- a/packages/cache/package.json +++ b/packages/cache/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/cache", "version": "0.2.40", "description": "In-memory cache implementations with ES6 Map-like API and different eviction strategies", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module cache api dcons transducers", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -45,5 +49,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/cache/src/api.ts b/packages/cache/src/api.ts index 442a225f3f..537a8b95c9 100644 --- a/packages/cache/src/api.ts +++ b/packages/cache/src/api.ts @@ -3,7 +3,7 @@ import { IEmpty, ILength, IRelease -} from "@thi.ng/api/api"; +} from "@thi.ng/api"; export interface ICache extends Iterable]>>, diff --git a/packages/cache/src/lru.ts b/packages/cache/src/lru.ts index 8c9d18026a..82fa66cd75 100644 --- a/packages/cache/src/lru.ts +++ b/packages/cache/src/lru.ts @@ -1,9 +1,9 @@ import { ConsCell, DCons } from "@thi.ng/dcons"; -import { map } from "@thi.ng/transducers/xform/map"; - +import { map } from "@thi.ng/transducers"; import { CacheEntry, CacheOpts, ICache } from "./api"; -export class LRUCache implements ICache { +export class LRUCache implements + ICache { protected map: Map>>; protected items: DCons>; diff --git a/packages/cache/src/mru.ts b/packages/cache/src/mru.ts index ae8e3632b0..8131202fd6 100644 --- a/packages/cache/src/mru.ts +++ b/packages/cache/src/mru.ts @@ -1,5 +1,4 @@ import { ConsCell } from "@thi.ng/dcons"; - import { CacheEntry, CacheOpts } from "./api"; import { LRUCache } from "./lru"; diff --git a/packages/cache/src/tlru.ts b/packages/cache/src/tlru.ts index 4d0e2f71b9..4090bd396b 100644 --- a/packages/cache/src/tlru.ts +++ b/packages/cache/src/tlru.ts @@ -1,5 +1,4 @@ import { ConsCell, DCons } from "@thi.ng/dcons"; - import { CacheEntry, CacheOpts } from "./api"; import { LRUCache } from "./lru"; diff --git a/packages/cache/test/tsconfig.json b/packages/cache/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/cache/test/tsconfig.json +++ b/packages/cache/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/checks/package.json b/packages/checks/package.json index 0212ffb531..691204453a 100644 --- a/packages/checks/package.json +++ b/packages/checks/package.json @@ -4,6 +4,7 @@ "description": "Single-function sub-modules for type, feature & value checks", "module": "./index.js", "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -13,12 +14,10 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && yarn build:es6 && yarn build:parcel && yarn build:parcel:min", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", "build:es6": "tsc --declaration", - "build:parcel:min": "parcel build --global thing_checks -o index.min.js -d lib --experimental-scope-hoisting src/index.ts", - "build:parcel": "parcel build --global thing_checks -d lib --no-minify --experimental-scope-hoisting src/index.ts && prettier --write lib/index.js", - "build:gzip": "gzip -c lib/index.min.js > lib/index.min.js.gz", - "test": "rimraf build && parcel build -d build --no-cache --no-minify --no-source-maps test/index.ts && nyc mocha build/index.js", + "build:bundle": "../../scripts/bundle-module checks", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", @@ -51,5 +50,6 @@ "browser": { "process": false, "setTimeout": false - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/checks/test/tsconfig.json b/packages/checks/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/checks/test/tsconfig.json +++ b/packages/checks/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/compare/package.json b/packages/compare/package.json index a923750465..981f7a6b36 100644 --- a/packages/compare/package.json +++ b/packages/compare/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/compare", "version": "0.1.12", "description": "Comparator with optional delegation for types implementing @thi.ng/api/ICompare interface", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module compare", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -34,5 +38,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/compare/test/tsconfig.json b/packages/compare/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/compare/test/tsconfig.json +++ b/packages/compare/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/compose/package.json b/packages/compose/package.json index 42320ef003..a81361a813 100644 --- a/packages/compose/package.json +++ b/packages/compose/package.json @@ -1,8 +1,10 @@ { "name": "@thi.ng/compose", "version": "0.3.0", - "description": "Functional composition helpers", - "main": "./index.js", + "description": "Arity-optimized functional composition helpers", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module compose api errors", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -39,5 +43,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/compose/src/comp.ts b/packages/compose/src/comp.ts index bbd0a4f12a..26903fbfd3 100644 --- a/packages/compose/src/comp.ts +++ b/packages/compose/src/comp.ts @@ -1,5 +1,5 @@ -import { Fn, FnAny } from "@thi.ng/api/api"; -import { illegalArity } from "@thi.ng/errors/illegal-arity"; +import { Fn, FnAny } from "@thi.ng/api"; +import { illegalArity } from "@thi.ng/errors"; /** * Returns the right-to-left composition of given functions. I.e. when diff --git a/packages/compose/src/juxt.ts b/packages/compose/src/juxt.ts index 9c0113be54..4064f77b1c 100644 --- a/packages/compose/src/juxt.ts +++ b/packages/compose/src/juxt.ts @@ -1,4 +1,4 @@ -import { Fn } from "@thi.ng/api/api"; +import { Fn } from "@thi.ng/api"; export function juxt(a: Fn): Fn; export function juxt(a: Fn, b: Fn): Fn; diff --git a/packages/compose/src/partial.ts b/packages/compose/src/partial.ts index d8ba1c883d..b8bd0e82bd 100644 --- a/packages/compose/src/partial.ts +++ b/packages/compose/src/partial.ts @@ -1,4 +1,4 @@ -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { illegalArgs } from "@thi.ng/errors"; export function partial(fn: (a: A, ...args: any[]) => T, a: A): (...args: any[]) => T; export function partial(fn: (a: A, b: B, ...args: any[]) => T, a: A, b: B): (...args: any[]) => T; diff --git a/packages/compose/src/thread-first.ts b/packages/compose/src/thread-first.ts index 9b268b93c5..a4fad7a5c8 100644 --- a/packages/compose/src/thread-first.ts +++ b/packages/compose/src/thread-first.ts @@ -1,4 +1,4 @@ -import { FnAny } from "@thi.ng/api/api"; +import { FnAny } from "@thi.ng/api"; /** * Takes an `init` value and a number of functions and/or function diff --git a/packages/compose/src/thread-last.ts b/packages/compose/src/thread-last.ts index e06ff76ac6..24a511445a 100644 --- a/packages/compose/src/thread-last.ts +++ b/packages/compose/src/thread-last.ts @@ -1,4 +1,4 @@ -import { FnAny } from "@thi.ng/api/api"; +import { FnAny } from "@thi.ng/api"; /** * Takes an `init` value and a number of functions and/or function diff --git a/packages/compose/test/tsconfig.json b/packages/compose/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/compose/test/tsconfig.json +++ b/packages/compose/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/csp/package.json b/packages/csp/package.json index cac40b2aac..ab3b139512 100644 --- a/packages/csp/package.json +++ b/packages/csp/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/csp", "version": "0.3.79", "description": "ES6 promise based CSP implementation", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc utils", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module csp api checks dcons errors transducers", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/index.js", "testasync": "tsc -p test && node build/test/async.js", "testfile": "tsc -p test && node build/test/file.js", "testgraph": "tsc -p test && node build/test/graph.js", @@ -53,5 +57,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/csp/src/api.ts b/packages/csp/src/api.ts index 12326397bc..adff2752be 100644 --- a/packages/csp/src/api.ts +++ b/packages/csp/src/api.ts @@ -1,5 +1,4 @@ -import { IID, ILength, IRelease } from "@thi.ng/api/api"; - +import { IID, ILength, IRelease } from "@thi.ng/api"; import { Channel } from "./channel"; export const enum State { diff --git a/packages/csp/src/buffer.ts b/packages/csp/src/buffer.ts index 98cc936b26..0162e55234 100644 --- a/packages/csp/src/buffer.ts +++ b/packages/csp/src/buffer.ts @@ -1,8 +1,8 @@ import { DCons } from "@thi.ng/dcons"; - import { ChannelItem, IBuffer } from "./api"; -export class FixedBuffer implements IBuffer { +export class FixedBuffer implements + IBuffer { buf: DCons>; limit: number; diff --git a/packages/csp/src/channel.ts b/packages/csp/src/channel.ts index 9b8e48bea4..1b82f0f929 100644 --- a/packages/csp/src/channel.ts +++ b/packages/csp/src/channel.ts @@ -1,13 +1,16 @@ -import { Predicate } from "@thi.ng/api/api"; -import { illegalArity } from "@thi.ng/errors/illegal-arity"; -import { isFunction } from "@thi.ng/checks/is-function"; +import { Predicate } from "@thi.ng/api"; +import { isFunction } from "@thi.ng/checks"; import { DCons } from "@thi.ng/dcons"; -import { Reducer, Transducer } from "@thi.ng/transducers/api"; -import { cycle } from "@thi.ng/transducers/iter/cycle"; -import { range } from "@thi.ng/transducers/iter/range"; -import { isReduced, unreduced } from "@thi.ng/transducers/reduced"; -import { delayed } from "@thi.ng/transducers/xform/delayed"; - +import { illegalArity } from "@thi.ng/errors"; +import { + cycle, + delayed, + isReduced, + range, + Reducer, + Transducer, + unreduced +} from "@thi.ng/transducers"; import { ChannelItem, ErrorHandler, @@ -561,10 +564,9 @@ export class Channel implements } } -function defaultErrorHandler(e: Error, chan: Channel, val?: any) { - console.log(chan.id, "error occurred", e.message, (val !== undefined ? val : "")); -} +const defaultErrorHandler = + (e: Error, chan: Channel, val?: any) => + console.log(chan.id, "error occurred", e.message, (val !== undefined ? val : "")); -function maybeBuffer(x) { - return x instanceof FixedBuffer || typeof x === "number"; -} +const maybeBuffer = (x) => + x instanceof FixedBuffer || typeof x === "number"; diff --git a/packages/csp/src/mult.ts b/packages/csp/src/mult.ts index a5d09addb7..3907574af6 100644 --- a/packages/csp/src/mult.ts +++ b/packages/csp/src/mult.ts @@ -1,7 +1,6 @@ -import { illegalArity } from "@thi.ng/errors/illegal-arity"; import { DCons } from "@thi.ng/dcons"; -import { Transducer } from "@thi.ng/transducers/api"; - +import { illegalArity } from "@thi.ng/errors"; +import { Transducer } from "@thi.ng/transducers"; import { IWriteableChannel } from "./api"; import { Channel } from "./channel"; diff --git a/packages/csp/src/pubsub.ts b/packages/csp/src/pubsub.ts index 56820e6163..a0f33c9815 100644 --- a/packages/csp/src/pubsub.ts +++ b/packages/csp/src/pubsub.ts @@ -1,7 +1,6 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { illegalArity } from "@thi.ng/errors/illegal-arity"; -import { Transducer } from "@thi.ng/transducers/api"; - +import { IObjectOf } from "@thi.ng/api"; +import { illegalArity } from "@thi.ng/errors"; +import { Transducer } from "@thi.ng/transducers"; import { IWriteableChannel, TopicFn } from "./api"; import { Channel } from "./channel"; import { Mult } from "./mult"; diff --git a/packages/csp/test/node.ts b/packages/csp/test/node.ts index 4af2ecdeba..af20a74836 100644 --- a/packages/csp/test/node.ts +++ b/packages/csp/test/node.ts @@ -1,11 +1,10 @@ -import { IEnable, IID, IObjectOf } from "@thi.ng/api/api"; -import { implementsFunction } from "@thi.ng/checks/implements-function"; -// import { DCons } from "@thi.ng/dcons"; +import { IEnable, IID, IObjectOf } from "@thi.ng/api"; +import { implementsFunction } from "@thi.ng/checks"; import * as tx from "@thi.ng/transducers"; - import { IBuffer, IWriteableChannel } from "../src/api"; import { Channel } from "../src/channel"; import { Mult } from "../src/mult"; +// import { DCons } from "@thi.ng/dcons"; export type NodeInput = NodeInputSpec | Channel | Mult | tx.Transducer; export type NodeOutput = NodeOutputSpec | IWriteableChannel; diff --git a/packages/csp/test/tsconfig.json b/packages/csp/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/csp/test/tsconfig.json +++ b/packages/csp/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/dcons/package.json b/packages/dcons/package.json index 3f0c731a4a..3695f10345 100644 --- a/packages/dcons/package.json +++ b/packages/dcons/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/dcons", "version": "1.1.23", "description": "Comprehensive doubly linked list structure w/ iterator support", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module dcons api checks compare equiv errors transducers", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -48,5 +52,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/dcons/src/index.ts b/packages/dcons/src/index.ts index 97686dbd57..a861aae749 100644 --- a/packages/dcons/src/index.ts +++ b/packages/dcons/src/index.ts @@ -8,14 +8,12 @@ import { IRelease, IStack, Predicate -} from "@thi.ng/api/api"; -import { isArrayLike } from "@thi.ng/checks/is-arraylike"; +} from "@thi.ng/api"; +import { isArrayLike } from "@thi.ng/checks"; import { compare } from "@thi.ng/compare"; import { equiv } from "@thi.ng/equiv"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { illegalState } from "@thi.ng/errors/illegal-state"; -import { IReducible, ReductionFn } from "@thi.ng/transducers/api"; -import { isReduced } from "@thi.ng/transducers/reduced"; +import { illegalArgs, illegalState } from "@thi.ng/errors"; +import { IReducible, isReduced, ReductionFn } from "@thi.ng/transducers"; export interface ConsCell { value: T; diff --git a/packages/dcons/test/tsconfig.json b/packages/dcons/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/dcons/test/tsconfig.json +++ b/packages/dcons/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/defmulti/package.json b/packages/defmulti/package.json index af2fe4b369..eddf10edd7 100644 --- a/packages/defmulti/package.json +++ b/packages/defmulti/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/defmulti", "version": "0.7.0", "description": "Dynamically extensible multiple dispatch via user supplied dispatch function.", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module defmulti api errors", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -37,5 +41,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/defmulti/src/index.ts b/packages/defmulti/src/index.ts index 202714b8f7..d7e1ed664e 100644 --- a/packages/defmulti/src/index.ts +++ b/packages/defmulti/src/index.ts @@ -1,6 +1,5 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { unsupported } from "@thi.ng/errors/unsupported"; -import { illegalArity } from "@thi.ng/errors/illegal-arity"; +import { IObjectOf } from "@thi.ng/api"; +import { illegalArity, unsupported } from "@thi.ng/errors"; export const DEFAULT: unique symbol = Symbol(); @@ -247,14 +246,14 @@ const makeRels = (spec: AncestorDefs) => { * @param impls * @param fallback */ -export function defmultiN( +export const defmultiN = ( impls: { [id: number]: Implementation }, fallback?: Implementation -) { +) => { const fn = defmulti((...args: any[]) => args.length); fn.add(DEFAULT, fallback || ((...args) => illegalArity(args.length))); for (let id in impls) { fn.add(id, impls[id]); } return fn; -} +}; diff --git a/packages/defmulti/test/tsconfig.json b/packages/defmulti/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/defmulti/test/tsconfig.json +++ b/packages/defmulti/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/dgraph/package.json b/packages/dgraph/package.json index b7b121df78..d03047aa40 100644 --- a/packages/dgraph/package.json +++ b/packages/dgraph/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/dgraph", "version": "0.2.35", "description": "Type-agnostic directed acyclic graph (DAG) & graph operations", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module dgraph api associative equiv errors transducers", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -44,5 +48,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/dgraph/src/index.ts b/packages/dgraph/src/index.ts index 369b8725e2..3db28c2f7c 100644 --- a/packages/dgraph/src/index.ts +++ b/packages/dgraph/src/index.ts @@ -1,11 +1,8 @@ -import { ICopy } from "@thi.ng/api/api"; -import { EquivMap } from "@thi.ng/associative/equiv-map"; -import { LLSet } from "@thi.ng/associative/ll-set"; -import { union } from "@thi.ng/associative/union"; +import { ICopy } from "@thi.ng/api"; +import { EquivMap, LLSet, union } from "@thi.ng/associative"; import { equiv } from "@thi.ng/equiv"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { reduce, reducer } from "@thi.ng/transducers/reduce"; -import { filter } from "@thi.ng/transducers/xform/filter"; +import { illegalArgs } from "@thi.ng/errors"; +import { filter, reduce, reducer } from "@thi.ng/transducers"; export class DGraph implements Iterable, diff --git a/packages/dgraph/test/tsconfig.json b/packages/dgraph/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/dgraph/test/tsconfig.json +++ b/packages/dgraph/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/diff/package.json b/packages/diff/package.json index 05f660152c..bbe005f914 100644 --- a/packages/diff/package.json +++ b/packages/diff/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/diff", "version": "2.0.2", "description": "Array & object Diff", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,11 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module diff api equiv", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", + "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -30,14 +35,17 @@ "@thi.ng/equiv": "^0.1.15" }, "keywords": [ + "additions", "array", "diff", - "edit", + "edits", "ES6", "nested", + "removals", "typescript" ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/diff/src/api.ts b/packages/diff/src/api.ts index b23f67e1ee..c5100c21d1 100644 --- a/packages/diff/src/api.ts +++ b/packages/diff/src/api.ts @@ -1,4 +1,4 @@ -import { IObjectOf } from "@thi.ng/api/api"; +import { IObjectOf } from "@thi.ng/api"; export type DiffKeyMap = IObjectOf; diff --git a/packages/diff/src/object.ts b/packages/diff/src/object.ts index a1f7c04319..26bc6990f3 100644 --- a/packages/diff/src/object.ts +++ b/packages/diff/src/object.ts @@ -1,4 +1,4 @@ -import { IObjectOf, Predicate2 } from "@thi.ng/api/api"; +import { IObjectOf, Predicate2 } from "@thi.ng/api"; import { equiv } from "@thi.ng/equiv"; import { DiffMode, ObjectDiff } from "./api"; diff --git a/packages/diff/test/tsconfig.json b/packages/diff/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/diff/test/tsconfig.json +++ b/packages/diff/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/dlogic/package.json b/packages/dlogic/package.json index 626923e384..ea427b895b 100644 --- a/packages/dlogic/package.json +++ b/packages/dlogic/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/dlogic", "version": "0.1.2", "description": "Assorted digital logic ops / constructs.", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module dlogic", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -39,5 +43,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/dlogic/test/tsconfig.json b/packages/dlogic/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/dlogic/test/tsconfig.json +++ b/packages/dlogic/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/dot/package.json b/packages/dot/package.json index 384f93f9ca..0696a6097f 100644 --- a/packages/dot/package.json +++ b/packages/dot/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/dot", "version": "0.1.18", "description": "Graphviz DOM abstraction as vanilla JS objects & serialization to DOT format", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module dot api checks", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -37,5 +41,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/dot/src/api.ts b/packages/dot/src/api.ts index 3efffb6b0f..5cd087298d 100644 --- a/packages/dot/src/api.ts +++ b/packages/dot/src/api.ts @@ -1,4 +1,4 @@ -import { IObjectOf } from "@thi.ng/api/api"; +import { IObjectOf } from "@thi.ng/api"; export type NodeShape = "box" | diff --git a/packages/dot/src/serialize.ts b/packages/dot/src/serialize.ts index 48495c7804..93589dc65a 100644 --- a/packages/dot/src/serialize.ts +++ b/packages/dot/src/serialize.ts @@ -1,6 +1,5 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { isArray } from "@thi.ng/checks/is-array"; - +import { IObjectOf } from "@thi.ng/api"; +import { isArray } from "@thi.ng/checks"; import { Edge, Graph, diff --git a/packages/dot/test/tsconfig.json b/packages/dot/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/dot/test/tsconfig.json +++ b/packages/dot/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/dsp/package.json b/packages/dsp/package.json index 6bd4ff6ad9..83d1da83ea 100644 --- a/packages/dsp/package.json +++ b/packages/dsp/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/dsp", "version": "0.1.3", "description": "Assorted DSP utils, oscillators etc.", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module dsp math", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -44,5 +48,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/dsp/src/api.ts b/packages/dsp/src/api.ts index 99bd50b70f..c364d97acd 100644 --- a/packages/dsp/src/api.ts +++ b/packages/dsp/src/api.ts @@ -1 +1,2 @@ -export type StatelessOscillator = (phase: number, freq: number, amp?: number, dc?: number, opts?: any) => number; +export type StatelessOscillator = + (phase: number, freq: number, amp?: number, dc?: number, opts?: any) => number; diff --git a/packages/dsp/src/osc.ts b/packages/dsp/src/osc.ts index ce932921eb..f0fef27574 100644 --- a/packages/dsp/src/osc.ts +++ b/packages/dsp/src/osc.ts @@ -1,7 +1,10 @@ -import { HALF_PI, TAU } from "@thi.ng/math/api"; -import { mix as _mix } from "@thi.ng/math/mix"; -import { wrap01 } from "@thi.ng/math/interval"; -import { fract } from "@thi.ng/math/prec"; +import { + fract, + HALF_PI, + mix as _mix, + TAU, + wrap01 +} from "@thi.ng/math"; import { StatelessOscillator } from "./api"; export class Oscillator implements diff --git a/packages/dsp/test/tsconfig.json b/packages/dsp/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/dsp/test/tsconfig.json +++ b/packages/dsp/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/equiv/package.json b/packages/equiv/package.json index d82579f5f5..a3cd21fe3e 100644 --- a/packages/equiv/package.json +++ b/packages/equiv/package.json @@ -4,6 +4,7 @@ "description": "Extensible deep equivalence checking for any data types", "module": "./index.js", "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -13,13 +14,11 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && yarn build:es6 && yarn build:parcel && yarn build:parcel:min", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", "build:es6": "tsc --declaration", - "build:parcel:min": "parcel build --global thing_equiv -o index.min.js -d lib --experimental-scope-hoisting src/index.ts", - "build:parcel": "parcel build --global thing_equiv -d lib --no-minify --experimental-scope-hoisting src/index.ts && prettier --write lib/index.js", - "build:gzip": "gzip -c lib/index.min.js > lib/index.min.js.gz", - "clean": "rimraf *.js *.d.ts .cache .nyc_output build coverage doc lib", - "test": "rimraf build && parcel build -d build --no-cache --no-minify --no-source-maps test/index.ts && nyc mocha build/index.js", + "build:bundle": "../../scripts/bundle-module equiv", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public" @@ -52,5 +51,6 @@ "browser": { "process": false, "setTimeout": false - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/equiv/test/tsconfig.json b/packages/equiv/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/equiv/test/tsconfig.json +++ b/packages/equiv/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/errors/package.json b/packages/errors/package.json index 50df7c0ab4..bc85cb9123 100644 --- a/packages/errors/package.json +++ b/packages/errors/package.json @@ -4,6 +4,7 @@ "description": "Custom error types and helper fns.", "module": "./index.js", "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -13,13 +14,11 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && yarn build:es6 && yarn build:parcel && yarn build:parcel:min", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", "build:es6": "tsc --declaration", - "build:parcel:min": "parcel build --global thing_errors -o index.min.js -d lib --experimental-scope-hoisting src/index.ts", - "build:parcel": "parcel build --global thing_errors -d lib --no-minify --experimental-scope-hoisting src/index.ts && prettier --write lib/index.js", - "build:gzip": "gzip -c lib/index.min.js > lib/index.min.js.gz", - "clean": "rimraf *.js *.d.ts .cache .nyc_output build coverage doc lib", - "test": "rimraf build && parcel build -d build --no-cache --no-minify --no-source-maps test/index.ts && nyc mocha build/index.js", + "build:bundle": "../../scripts/bundle-module errors", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public" @@ -46,5 +45,6 @@ "browser": { "process": false, "setTimeout": false - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/errors/test/tsconfig.json b/packages/errors/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/errors/test/tsconfig.json +++ b/packages/errors/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/fsm/package.json b/packages/fsm/package.json index da80319859..1d03346c8d 100644 --- a/packages/fsm/package.json +++ b/packages/fsm/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/fsm", "version": "0.1.0", "description": "Composable primitives for building declarative, transducer based Finite-State machines & parsers for arbitrary data streams", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module fsm api equiv errors transducers", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -49,5 +53,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/fsm/src/fsm.ts b/packages/fsm/src/fsm.ts index 72a026b6bf..52133a1b45 100644 --- a/packages/fsm/src/fsm.ts +++ b/packages/fsm/src/fsm.ts @@ -1,13 +1,13 @@ import { IObjectOf } from "@thi.ng/api"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { illegalState } from "@thi.ng/errors/illegal-state"; -import { Reducer, Transducer } from "@thi.ng/transducers/api"; +import { illegalArgs, illegalState } from "@thi.ng/errors"; import { ensureReduced, isReduced, reduced, + Reducer, + Transducer, unreduced -} from "@thi.ng/transducers/reduced"; +} from "@thi.ng/transducers"; import { Match, Matcher } from "./api"; /** diff --git a/packages/fsm/test/tsconfig.json b/packages/fsm/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/fsm/test/tsconfig.json +++ b/packages/fsm/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/geom-accel/package.json b/packages/geom-accel/package.json index 4c933a24b2..6c51e80c8f 100644 --- a/packages/geom-accel/package.json +++ b/packages/geom-accel/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/geom-accel", "version": "0.1.11", "description": "TODO", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module geomAccel api heaps math transducers vectors", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib internal", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -31,6 +35,7 @@ "@thi.ng/api": "^4.2.4", "@thi.ng/heaps": "^0.3.1", "@thi.ng/math": "^0.2.2", + "@thi.ng/transducers": "^2.3.2", "@thi.ng/vectors": "^1.4.12" }, "keywords": [ @@ -45,5 +50,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/geom-accel/src/kdtree.ts b/packages/geom-accel/src/kdtree.ts index 5cd86491f3..d7be2eedab 100644 --- a/packages/geom-accel/src/kdtree.ts +++ b/packages/geom-accel/src/kdtree.ts @@ -1,8 +1,8 @@ -import { ICopy, IEmpty, Pair } from "@thi.ng/api/api"; -import { Heap } from "@thi.ng/heaps/heap"; -import { EPS } from "@thi.ng/math/api"; -import { ensureArray } from "@thi.ng/transducers/func/ensure-array"; -import { IDistance } from "@thi.ng/vectors/api"; +import { ICopy, IEmpty, Pair } from "@thi.ng/api"; +import { Heap } from "@thi.ng/heaps"; +import { EPS } from "@thi.ng/math"; +import { ensureArray } from "@thi.ng/transducers"; +import { IDistance } from "@thi.ng/vectors"; export type KdIndexable = IDistance & IEmpty; diff --git a/packages/geom-accel/test/tsconfig.json b/packages/geom-accel/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/geom-accel/test/tsconfig.json +++ b/packages/geom-accel/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/geom/package.json b/packages/geom/package.json index 547bdedf79..bd08be6182 100644 --- a/packages/geom/package.json +++ b/packages/geom/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/geom", "version": "0.2.11", "description": "2D/3D geometry primitives", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc internal", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module geom api checks errors math transducers vectors", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib internal", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -30,6 +34,7 @@ "dependencies": { "@thi.ng/api": "^4.2.4", "@thi.ng/checks": "^1.5.14", + "@thi.ng/errors": "^0.1.12", "@thi.ng/math": "^0.2.2", "@thi.ng/transducers": "^2.3.2", "@thi.ng/vectors": "^1.4.12" @@ -45,5 +50,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/geom/src/api.ts b/packages/geom/src/api.ts index 333cf71b61..f15cc72701 100644 --- a/packages/geom/src/api.ts +++ b/packages/geom/src/api.ts @@ -1,6 +1,10 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { IVector, ReadonlyVec, Vec } from "@thi.ng/vectors/api"; -import { Vec2 } from "@thi.ng/vectors/vec2"; +import { IObjectOf } from "@thi.ng/api"; +import { + IVector, + ReadonlyVec, + Vec, + Vec2 +} from "@thi.ng/vectors"; export const DEFAULT_SAMPLES = 32; diff --git a/packages/geom/src/arc2.ts b/packages/geom/src/arc2.ts index 2916ef26e9..26b9d8e5c1 100644 --- a/packages/geom/src/arc2.ts +++ b/packages/geom/src/arc2.ts @@ -1,29 +1,30 @@ import { ICopy } from "@thi.ng/api"; -import { isNumber } from "@thi.ng/checks/is-number"; -import { isPlainObject } from "@thi.ng/checks/is-plain-object"; -import { sincos } from "@thi.ng/math/angle"; +import { isNumber, isPlainObject } from "@thi.ng/checks"; import { EPS, HALF_PI, + inRange, + mix, PI, + roundEps, + sincos, TAU -} from "@thi.ng/math/api"; -import { inRange } from "@thi.ng/math/interval"; -import { mix } from "@thi.ng/math/mix"; -import { roundEps } from "@thi.ng/math/prec"; -import { range } from "@thi.ng/transducers/iter/range"; -import { push } from "@thi.ng/transducers/rfn/push"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { filter } from "@thi.ng/transducers/xform/filter"; -import { map } from "@thi.ng/transducers/xform/map"; -import { Vec } from "@thi.ng/vectors/api"; +} from "@thi.ng/math"; +import { + filter, + map, + push, + range, + transduce +} from "@thi.ng/transducers"; import { add2, asVec2, rotate2, setS2, + Vec, Vec2 -} from "@thi.ng/vectors/vec2"; +} from "@thi.ng/vectors"; import { Attribs, DEFAULT_SAMPLES, diff --git a/packages/geom/src/bezier2.ts b/packages/geom/src/bezier2.ts index b3e6da3469..5e8e8f78fa 100644 --- a/packages/geom/src/bezier2.ts +++ b/packages/geom/src/bezier2.ts @@ -1,10 +1,12 @@ import { ICopy } from "@thi.ng/api"; -import { isNumber } from "@thi.ng/checks/is-number"; -import { isPlainObject } from "@thi.ng/checks/is-plain-object"; -import { clamp01 } from "@thi.ng/math/interval"; -import { mixCubic as _mixC, mixQuadratic as _mixQ } from "@thi.ng/math/mix"; -import { IMath, ReadonlyVec, Vec } from "@thi.ng/vectors/api"; -import { Vec2 } from "@thi.ng/vectors/vec2"; +import { isNumber, isPlainObject } from "@thi.ng/checks"; +import { clamp01, mixCubic as _mixC, mixQuadratic as _mixQ } from "@thi.ng/math"; +import { + IMath, + ReadonlyVec, + Vec, + Vec2 +} from "@thi.ng/vectors"; import { Attribs, DEFAULT_SAMPLES, diff --git a/packages/geom/src/circle2.ts b/packages/geom/src/circle2.ts index edbec805e1..1f49dde94f 100644 --- a/packages/geom/src/circle2.ts +++ b/packages/geom/src/circle2.ts @@ -1,16 +1,14 @@ -import { IToHiccup } from "@thi.ng/api/api"; -import { isArrayLike } from "@thi.ng/checks/is-arraylike"; -import { isNumber } from "@thi.ng/checks/is-number"; -import { isPlainObject } from "@thi.ng/checks/is-plain-object"; -import { PI, TAU } from "@thi.ng/math/api"; -import { eqDelta } from "@thi.ng/math/eqdelta"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors/api"; +import { IToHiccup } from "@thi.ng/api"; +import { isArrayLike, isNumber, isPlainObject } from "@thi.ng/checks"; +import { eqDelta, PI, TAU } from "@thi.ng/math"; import { asVec2, + ReadonlyVec, setS2, toCartesian2, + Vec, Vec2 -} from "@thi.ng/vectors/vec2"; +} from "@thi.ng/vectors"; import { Attribs, DEFAULT_SAMPLES, diff --git a/packages/geom/src/container2.ts b/packages/geom/src/container2.ts index d3f8c066fa..f4660564d3 100644 --- a/packages/geom/src/container2.ts +++ b/packages/geom/src/container2.ts @@ -1,5 +1,4 @@ -import { Mat23 } from "@thi.ng/vectors/mat23"; -import { Vec2 } from "@thi.ng/vectors/vec2"; +import { Mat23, Vec2 } from "@thi.ng/vectors"; import { Attribs, CollateOpts, diff --git a/packages/geom/src/container3.ts b/packages/geom/src/container3.ts index c8149bfad0..81cbd867f9 100644 --- a/packages/geom/src/container3.ts +++ b/packages/geom/src/container3.ts @@ -1,6 +1,5 @@ -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { Mat44 } from "@thi.ng/vectors/mat44"; -import { Vec3, vec3 } from "@thi.ng/vectors/vec3"; +import { illegalArgs } from "@thi.ng/errors"; +import { Mat44, Vec3, vec3 } from "@thi.ng/vectors"; import { Attribs, CollateOpts, diff --git a/packages/geom/src/fit.ts b/packages/geom/src/fit.ts index 2c7828dcbb..8d43994e33 100644 --- a/packages/geom/src/fit.ts +++ b/packages/geom/src/fit.ts @@ -1,5 +1,4 @@ -import { Mat23 } from "@thi.ng/vectors/mat23"; -import { Vec2 } from "@thi.ng/vectors/vec2"; +import { Mat23, Vec2 } from "@thi.ng/vectors"; import { IBounds, ICentroid, ITransformable } from "./api"; import { collBounds } from "./internal/bounds"; import { Rect2 } from "./rect2"; diff --git a/packages/geom/src/index.ts b/packages/geom/src/index.ts index 46762d01db..98b9fc69da 100644 --- a/packages/geom/src/index.ts +++ b/packages/geom/src/index.ts @@ -1,7 +1,4 @@ export * from "./api"; -export * from "./container2"; -export * from "./container3"; - export * from "./arc2"; export * from "./bezier2"; export * from "./circle2"; diff --git a/packages/geom/src/internal/arc-length.ts b/packages/geom/src/internal/arc-length.ts index 31ed1e0fbe..1d539f0af5 100644 --- a/packages/geom/src/internal/arc-length.ts +++ b/packages/geom/src/internal/arc-length.ts @@ -1,4 +1,4 @@ -import { IVector } from "@thi.ng/vectors/api"; +import { IVector } from "@thi.ng/vectors"; export const arcLength = >(pts: ReadonlyArray, closed = false) => { const num = pts.length; diff --git a/packages/geom/src/internal/area.ts b/packages/geom/src/internal/area.ts index 73b8d795b9..95197e5eed 100644 --- a/packages/geom/src/internal/area.ts +++ b/packages/geom/src/internal/area.ts @@ -1,4 +1,4 @@ -import { Vec2 } from "@thi.ng/vectors/vec2"; +import { Vec2 } from "@thi.ng/vectors"; export const polygonArea = (pts: ReadonlyArray) => { let res = 0; diff --git a/packages/geom/src/internal/args.ts b/packages/geom/src/internal/args.ts index 8d430d07b3..150bdcc193 100644 --- a/packages/geom/src/internal/args.ts +++ b/packages/geom/src/internal/args.ts @@ -1,8 +1,6 @@ -import { isArrayLike } from "@thi.ng/checks/is-arraylike"; -import { isNumber } from "@thi.ng/checks/is-number"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { ReadonlyVec } from "@thi.ng/vectors/api"; -import { asVec2, Vec2 } from "@thi.ng/vectors/vec2"; +import { isArrayLike, isNumber } from "@thi.ng/checks"; +import { illegalArgs } from "@thi.ng/errors"; +import { asVec2, ReadonlyVec, Vec2 } from "@thi.ng/vectors"; export const args3 = (args: any[]) => { let points = args[0], attribs; diff --git a/packages/geom/src/internal/barycentric.ts b/packages/geom/src/internal/barycentric.ts index 0eb94072f0..f0c873a0dd 100644 --- a/packages/geom/src/internal/barycentric.ts +++ b/packages/geom/src/internal/barycentric.ts @@ -1,5 +1,4 @@ -import { IVector } from "@thi.ng/vectors/api"; -import { Vec3 } from "@thi.ng/vectors/vec3"; +import { IVector, Vec3 } from "@thi.ng/vectors"; export const toBarycentric = > diff --git a/packages/geom/src/internal/bounds.ts b/packages/geom/src/internal/bounds.ts index 5d4cb1118d..0f834b5ba8 100644 --- a/packages/geom/src/internal/bounds.ts +++ b/packages/geom/src/internal/bounds.ts @@ -1,4 +1,4 @@ -import { IVector } from "@thi.ng/vectors/api"; +import { IVector } from "@thi.ng/vectors"; import { IBounds, IUnion } from "../api"; export const axisBounds = diff --git a/packages/geom/src/internal/centroid.ts b/packages/geom/src/internal/centroid.ts index e84643f1ef..a356869195 100644 --- a/packages/geom/src/internal/centroid.ts +++ b/packages/geom/src/internal/centroid.ts @@ -1,29 +1,30 @@ -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { IVector } from "@thi.ng/vectors/api"; -import { Vec2 } from "@thi.ng/vectors/vec2"; +import { illegalArgs } from "@thi.ng/errors"; +import { IVector, Vec2 } from "@thi.ng/vectors"; -export const centroid = >(pts: ReadonlyArray, c?: T) => { - const num = pts.length; - !num && illegalArgs("no points available"); - !c && (c = pts[0].empty()); - for (let i = num; --i >= 0;) { - c.add(pts[i]); - } - return c.divN(num); -}; +export const centroid = + >(pts: ReadonlyArray, c?: T) => { + const num = pts.length; + !num && illegalArgs("no points available"); + !c && (c = pts[0].empty()); + for (let i = num; --i >= 0;) { + c.add(pts[i]); + } + return c.divN(num); + }; -export const centerOfWeight = (pts: Vec2[], c?: Vec2) => { - let area = 0; - let x = 0; - let y = 0; - for (let n = pts.length - 1, i = pts[n], j = pts[0], k = 0; k <= n; k++ , i = j, j = pts[k]) { - const z = i.cross(j); - area += z; - x += (i.x + j.x) * z; - y += (i.y + j.y) * z; - } - area = 1 / (area * 3); - x *= area; - y *= area; - return c ? c.setS(x, y) : new Vec2([x, y]); -}; +export const centerOfWeight = + (pts: Vec2[], c?: Vec2) => { + let area = 0; + let x = 0; + let y = 0; + for (let n = pts.length - 1, i = pts[n], j = pts[0], k = 0; k <= n; k++ , i = j, j = pts[k]) { + const z = i.cross(j); + area += z; + x += (i.x + j.x) * z; + y += (i.y + j.y) * z; + } + area = 1 / (area * 3); + x *= area; + y *= area; + return c ? c.setS(x, y) : new Vec2([x, y]); + }; diff --git a/packages/geom/src/internal/circumcenter.ts b/packages/geom/src/internal/circumcenter.ts index 65517cf648..b0e4d4768b 100644 --- a/packages/geom/src/internal/circumcenter.ts +++ b/packages/geom/src/internal/circumcenter.ts @@ -1,5 +1,5 @@ -import { EPS } from "@thi.ng/math/api"; -import { Vec2 } from "@thi.ng/vectors/vec2"; +import { EPS } from "@thi.ng/math"; +import { Vec2 } from "@thi.ng/vectors"; export const circumCenter = (a: Readonly, b: Readonly, c: Readonly, eps = EPS) => { diff --git a/packages/geom/src/internal/closest-point.ts b/packages/geom/src/internal/closest-point.ts index ca8db6d33f..485313641e 100644 --- a/packages/geom/src/internal/closest-point.ts +++ b/packages/geom/src/internal/closest-point.ts @@ -1,4 +1,4 @@ -import { IVector } from "@thi.ng/vectors/api"; +import { IVector } from "@thi.ng/vectors"; export const closestPoint = >(p: T, pts: T[]) => { diff --git a/packages/geom/src/internal/collate.ts b/packages/geom/src/internal/collate.ts index c29f1e1a28..4fa27e767c 100644 --- a/packages/geom/src/internal/collate.ts +++ b/packages/geom/src/internal/collate.ts @@ -1,7 +1,13 @@ -import { Vec, IVec } from "@thi.ng/vectors/api"; +import { IVec, Vec } from "@thi.ng/vectors"; import { CollateOpts } from "../api"; -export const remap = (buf: Vec, pts: IVec[], start: number, cstride: number, estride: number) => { +export const remap = ( + buf: Vec, + pts: IVec[], + start: number, + cstride: number, + estride: number +) => { for (let i = pts.length; --i >= 0;) { const p = pts[i]; p.buf = buf; @@ -15,8 +21,8 @@ export const collateWith = ( fn: (buf: Vec, src: Iterable>, start, cstride, estride) => Vec, pts: T[], opts: Partial, - stride: number) => { - + stride: number +) => { opts = { start: 0, cstride: 1, diff --git a/packages/geom/src/internal/corner.ts b/packages/geom/src/internal/corner.ts index 8bf3274009..b817da7d0f 100644 --- a/packages/geom/src/internal/corner.ts +++ b/packages/geom/src/internal/corner.ts @@ -1,6 +1,5 @@ -import { sign } from "@thi.ng/math/abs"; -import { EPS } from "@thi.ng/math/api"; -import { Vec2 } from "@thi.ng/vectors/vec2"; +import { EPS, sign } from "@thi.ng/math"; +import { Vec2 } from "@thi.ng/vectors"; export const corner = (a: Readonly, b: Readonly, c: Readonly) => { diff --git "a/packages/geom/src/internal/douglas\342\200\223peucker.ts" "b/packages/geom/src/internal/douglas\342\200\223peucker.ts" index b2a7061dc1..5f6ae4e122 100644 --- "a/packages/geom/src/internal/douglas\342\200\223peucker.ts" +++ "b/packages/geom/src/internal/douglas\342\200\223peucker.ts" @@ -1,5 +1,5 @@ -import { peek } from "@thi.ng/transducers/func/peek"; -import { IVector } from "@thi.ng/vectors/api"; +import { peek } from "@thi.ng/transducers"; +import { IVector } from "@thi.ng/vectors"; import { farthestPointSegment } from "./closest-point"; // https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm diff --git a/packages/geom/src/internal/edges.ts b/packages/geom/src/internal/edges.ts index fe9bed6d49..537fe27010 100644 --- a/packages/geom/src/internal/edges.ts +++ b/packages/geom/src/internal/edges.ts @@ -1,6 +1,5 @@ -import { wrap } from "@thi.ng/transducers/iter/wrap"; -import { partition } from "@thi.ng/transducers/xform/partition"; +import { partition, wrap } from "@thi.ng/transducers"; -export const edges = (vertices: Iterable, closed = false) => { - return partition(2, 1, closed ? wrap(vertices, 1, false, true) : vertices); -}; +export const edges = + (vertices: Iterable, closed = false) => + partition(2, 1, closed ? wrap(vertices, 1, false, true) : vertices); diff --git a/packages/geom/src/internal/eq-delta.ts b/packages/geom/src/internal/eq-delta.ts index 657aea90b1..26a715de2a 100644 --- a/packages/geom/src/internal/eq-delta.ts +++ b/packages/geom/src/internal/eq-delta.ts @@ -1,11 +1,12 @@ -import { EPS } from "@thi.ng/math/api"; -import { IVector } from "@thi.ng/vectors/api"; +import { EPS } from "@thi.ng/math"; +import { IVector } from "@thi.ng/vectors"; -export const containsDelta = >(pts: Iterable, q: Readonly, eps = EPS) => { - for (let p of pts) { - if (p.eqDelta(q, eps)) { - return true; +export const containsDelta = + >(pts: Iterable, q: Readonly, eps = EPS) => { + for (let p of pts) { + if (p.eqDelta(q, eps)) { + return true; + } } - } - return false; -}; + return false; + }; diff --git a/packages/geom/src/internal/graham-scan.ts b/packages/geom/src/internal/graham-scan.ts index eb446aa0b4..4134e7647c 100644 --- a/packages/geom/src/internal/graham-scan.ts +++ b/packages/geom/src/internal/graham-scan.ts @@ -1,4 +1,4 @@ -import { Vec2 } from "@thi.ng/vectors/vec2"; +import { Vec2 } from "@thi.ng/vectors"; import { corner } from "./corner"; /** @@ -9,29 +9,30 @@ import { corner } from "./corner"; * * @param pts */ -export const convexHull = (pts: ReadonlyArray) => { - const num = pts.length; - const res: Vec2[] = []; - let h = 0, i; - pts = pts.slice().sort(Vec2.comparator(0, 1)); +export const convexHull = + (pts: ReadonlyArray) => { + const num = pts.length; + const res: Vec2[] = []; + let h = 0, i; + pts = pts.slice().sort(Vec2.comparator(0, 1)); - const scan = (p: Vec2, thresh: number) => { - while (h >= thresh && corner(res[h - 2], res[h - 1], p) >= 0) { - res.pop(); - h--; + const scan = (p: Vec2, thresh: number) => { + while (h >= thresh && corner(res[h - 2], res[h - 1], p) >= 0) { + res.pop(); + h--; + } + res[h++] = p; + }; + + for (i = 0; i < num; i++) { + scan(pts[i], 2); + } + res.pop(); + h--; + const h2 = h + 2; + for (i = num - 1; i >= 0; i--) { + scan(pts[i], h2); } - res[h++] = p; + res.pop(); + return res; }; - - for (i = 0; i < num; i++) { - scan(pts[i], 2); - } - res.pop(); - h--; - const h2 = h + 2; - for (i = num - 1; i >= 0; i--) { - scan(pts[i], h2); - } - res.pop(); - return res; -}; diff --git a/packages/geom/src/internal/liang-barsky.ts b/packages/geom/src/internal/liang-barsky.ts index 9106f6faf3..e08223f671 100644 --- a/packages/geom/src/internal/liang-barsky.ts +++ b/packages/geom/src/internal/liang-barsky.ts @@ -1,5 +1,5 @@ -import { EPS } from "@thi.ng/math/api"; -import { Vec2 } from "@thi.ng/vectors/vec2"; +import { EPS } from "@thi.ng/math"; +import { Vec2 } from "@thi.ng/vectors"; // https://en.wikipedia.org/wiki/Liang%E2%80%93Barsky_algorithm // https://github.com/thi-ng/c-thing/blob/master/src/geom/clip/liangbarsky.c diff --git a/packages/geom/src/internal/line-intersection.ts b/packages/geom/src/internal/line-intersection.ts index 583a098dd4..0272f666bd 100644 --- a/packages/geom/src/internal/line-intersection.ts +++ b/packages/geom/src/internal/line-intersection.ts @@ -1,31 +1,32 @@ -import { Vec2 } from "@thi.ng/vectors/vec2"; +import { Vec2 } from "@thi.ng/vectors"; import { LineIntersection, LineIntersectionType } from "../api"; -export const intersectLines2 = (a: Vec2, b: Vec2, c: Vec2, d: Vec2) => { - const bax = b.x - a.x; - const bay = b.y - a.y; - const dcx = d.x - c.x; - const dcy = d.y - c.y; - const acx = a.x - c.x; - const acy = a.y - c.y; - const det = dcy * bax - dcx * bay; - let alpha = dcx * acy - dcy * acx; - let beta = bax * acy - bay * acx; - if (det === 0) { - if (alpha === 0 && beta === 0) { - return { type: LineIntersectionType.COINCIDENT }; +export const intersectLines2 = + (a: Vec2, b: Vec2, c: Vec2, d: Vec2) => { + const bax = b.x - a.x; + const bay = b.y - a.y; + const dcx = d.x - c.x; + const dcy = d.y - c.y; + const acx = a.x - c.x; + const acy = a.y - c.y; + const det = dcy * bax - dcx * bay; + let alpha = dcx * acy - dcy * acx; + let beta = bax * acy - bay * acx; + if (det === 0) { + if (alpha === 0 && beta === 0) { + return { type: LineIntersectionType.COINCIDENT }; + } + return { type: LineIntersectionType.PARALLEL }; } - return { type: LineIntersectionType.PARALLEL }; - } - alpha /= det; - beta /= det; - return >{ - type: (0 <= alpha && alpha <= 1) && (0 <= beta && beta <= 1) ? - LineIntersectionType.INTERSECT : - LineIntersectionType.INTERSECT_OUTSIDE, - isec: a.mixNewN(b, alpha), - alpha, - beta, - det, + alpha /= det; + beta /= det; + return >{ + type: (0 <= alpha && alpha <= 1) && (0 <= beta && beta <= 1) ? + LineIntersectionType.INTERSECT : + LineIntersectionType.INTERSECT_OUTSIDE, + isec: a.mixNewN(b, alpha), + alpha, + beta, + det, + }; }; -}; diff --git a/packages/geom/src/internal/sutherland-hodgeman.ts b/packages/geom/src/internal/sutherland-hodgeman.ts index fe4b1ea771..9b8175aab5 100644 --- a/packages/geom/src/internal/sutherland-hodgeman.ts +++ b/packages/geom/src/internal/sutherland-hodgeman.ts @@ -1,4 +1,4 @@ -import { Vec2 } from "@thi.ng/vectors/vec2"; +import { Vec2 } from "@thi.ng/vectors"; import { classify } from "./corner"; import { intersectLines2 } from "./line-intersection"; @@ -14,30 +14,31 @@ import { intersectLines2 } from "./line-intersection"; * @param bc pre-computed boundary centroid * @param eps edge classification tolerance */ -export const clipConvex = (poly: Vec2[], bounds: Vec2[], bc: Vec2, eps = 1e-4) => { - for (let ne = bounds.length, j = ne - 1, i = 0; i < ne; j = i, i++) { - const clipped = []; - const ca = bounds[j]; - const cb = bounds[i]; - const sign = classify(ca, cb, bc, eps); - for (let np = poly.length, k = np - 1, l = 0; l < np; k = l, l++) { - const p = poly[k]; - const q = poly[l]; - const cqsign = classify(ca, cb, q, eps); - if (classify(ca, cb, p, eps) === sign) { - clipped.push( - cqsign !== sign ? - intersectLines2(ca, cb, p, q).isec : - q - ); - } else if (cqsign === sign) { - clipped.push(intersectLines2(ca, cb, p, q).isec, q); +export const clipConvex = + (poly: Vec2[], bounds: Vec2[], bc: Vec2, eps = 1e-4) => { + for (let ne = bounds.length, j = ne - 1, i = 0; i < ne; j = i, i++) { + const clipped = []; + const ca = bounds[j]; + const cb = bounds[i]; + const sign = classify(ca, cb, bc, eps); + for (let np = poly.length, k = np - 1, l = 0; l < np; k = l, l++) { + const p = poly[k]; + const q = poly[l]; + const cqsign = classify(ca, cb, q, eps); + if (classify(ca, cb, p, eps) === sign) { + clipped.push( + cqsign !== sign ? + intersectLines2(ca, cb, p, q).isec : + q + ); + } else if (cqsign === sign) { + clipped.push(intersectLines2(ca, cb, p, q).isec, q); + } } + if (clipped.length < 2) { + return []; + } + poly = clipped; } - if (clipped.length < 2) { - return []; - } - poly = clipped; - } - return poly; -}; + return poly; + }; diff --git a/packages/geom/src/line2.ts b/packages/geom/src/line2.ts index 0b98609b26..e545dc5a0c 100644 --- a/packages/geom/src/line2.ts +++ b/packages/geom/src/line2.ts @@ -1,8 +1,10 @@ -import { isArrayLike } from "@thi.ng/checks/is-arraylike"; -import { isNumber } from "@thi.ng/checks/is-number"; -import { isPlainObject } from "@thi.ng/checks/is-plain-object"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors/api"; -import { asVec2, Vec2 } from "@thi.ng/vectors/vec2"; +import { isArrayLike, isNumber, isPlainObject } from "@thi.ng/checks"; +import { + asVec2, + ReadonlyVec, + Vec, + Vec2 +} from "@thi.ng/vectors"; import { Attribs, HiccupLine2, diff --git a/packages/geom/src/path2.ts b/packages/geom/src/path2.ts index f826489522..4e89502311 100644 --- a/packages/geom/src/path2.ts +++ b/packages/geom/src/path2.ts @@ -1,10 +1,12 @@ -import { isNumber } from "@thi.ng/checks/is-number"; -import { implementsFunction } from "@thi.ng/checks/implements-function"; -import { rad } from "@thi.ng/math/angle"; -import { eqDelta } from "@thi.ng/math/eqdelta"; -import { ensureArray } from "@thi.ng/transducers/func/ensure-array"; -import { peek } from "@thi.ng/transducers/func/peek"; -import { Vec2 } from "@thi.ng/vectors/vec2"; +import { implementsFunction, isNumber } from "@thi.ng/checks"; +import { eqDelta, rad } from "@thi.ng/math"; +import { + ensureArray, + map, + mapcat, + peek +} from "@thi.ng/transducers"; +import { Vec2 } from "@thi.ng/vectors"; import { Attribs, IBounds, @@ -22,8 +24,6 @@ import { Polygon2 } from "./polygon2"; import { Polyline2 } from "./polyline2"; import { Rect2 } from "./rect2"; import { simplifyPolyline } from "./internal/douglas–peucker"; -import { mapcat } from "@thi.ng/transducers/xform/mapcat"; -import { map } from "@thi.ng/transducers/xform/map"; export class Path2 implements Iterable, diff --git a/packages/geom/src/polygon2.ts b/packages/geom/src/polygon2.ts index 3fbb535288..cd5b255c07 100644 --- a/packages/geom/src/polygon2.ts +++ b/packages/geom/src/polygon2.ts @@ -1,15 +1,21 @@ -import { ICopy, IToHiccup } from "@thi.ng/api/api"; -import { isNumber } from "@thi.ng/checks/is-number"; -import { isPlainObject } from "@thi.ng/checks/is-plain-object"; -import { TAU } from "@thi.ng/math/api"; -import { cycle } from "@thi.ng/transducers/iter/cycle"; -import { normRange } from "@thi.ng/transducers/iter/norm-range"; -import { tuples } from "@thi.ng/transducers/iter/tuples"; -import { push } from "@thi.ng/transducers/rfn/push"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { map } from "@thi.ng/transducers/xform/map"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors/api"; -import { asVec2, toCartesian2, Vec2 } from "@thi.ng/vectors/vec2"; +import { ICopy, IToHiccup } from "@thi.ng/api"; +import { isNumber, isPlainObject } from "@thi.ng/checks"; +import { TAU } from "@thi.ng/math"; +import { + cycle, + map, + normRange, + push, + transduce, + tuples +} from "@thi.ng/transducers"; +import { + asVec2, + ReadonlyVec, + toCartesian2, + Vec, + Vec2 +} from "@thi.ng/vectors"; import { Attribs, HiccupPolygon2, diff --git a/packages/geom/src/polyline2.ts b/packages/geom/src/polyline2.ts index 37c159e4a1..552289fdee 100644 --- a/packages/geom/src/polyline2.ts +++ b/packages/geom/src/polyline2.ts @@ -1,9 +1,7 @@ -import { ICopy, IToHiccup } from "@thi.ng/api/api"; -import { isPlainObject } from "@thi.ng/checks/is-plain-object"; -import { map } from "@thi.ng/transducers/xform/map"; -import { partition } from "@thi.ng/transducers/xform/partition"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors/api"; -import { Vec2 } from "@thi.ng/vectors/vec2"; +import { ICopy, IToHiccup } from "@thi.ng/api"; +import { isPlainObject } from "@thi.ng/checks"; +import { map, partition } from "@thi.ng/transducers"; +import { ReadonlyVec, Vec, Vec2 } from "@thi.ng/vectors"; import { Attribs, IArcLength, diff --git a/packages/geom/src/quad2.ts b/packages/geom/src/quad2.ts index 4a2c07dbbc..e5dfdaf6a8 100644 --- a/packages/geom/src/quad2.ts +++ b/packages/geom/src/quad2.ts @@ -1,6 +1,5 @@ import { ICopy } from "@thi.ng/api"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors/api"; -import { Vec2 } from "@thi.ng/vectors/vec2"; +import { ReadonlyVec, Vec, Vec2 } from "@thi.ng/vectors"; import { Attribs, IArcLength, diff --git a/packages/geom/src/rect2.ts b/packages/geom/src/rect2.ts index b6d3527645..12e6b5a21c 100644 --- a/packages/geom/src/rect2.ts +++ b/packages/geom/src/rect2.ts @@ -1,9 +1,6 @@ import { ICopy } from "@thi.ng/api"; -import { isArrayLike } from "@thi.ng/checks/is-arraylike"; -import { isNumber } from "@thi.ng/checks/is-number"; -import { isPlainObject } from "@thi.ng/checks/is-plain-object"; -import { ReadonlyVec } from "@thi.ng/vectors/api"; -import { asVec2, Vec2 } from "@thi.ng/vectors/vec2"; +import { isArrayLike, isNumber, isPlainObject } from "@thi.ng/checks"; +import { asVec2, ReadonlyVec, Vec2 } from "@thi.ng/vectors"; import { Attribs, CollateOpts, diff --git a/packages/geom/src/sampler.ts b/packages/geom/src/sampler.ts index 2f6a6a3c18..df343220e5 100644 --- a/packages/geom/src/sampler.ts +++ b/packages/geom/src/sampler.ts @@ -1,5 +1,5 @@ -import { peek } from "@thi.ng/transducers/func/peek"; -import { IVector } from "@thi.ng/vectors/api"; +import { peek } from "@thi.ng/transducers"; +import { IVector } from "@thi.ng/vectors"; export class Sampler> { diff --git a/packages/geom/src/subdiv-curve.ts b/packages/geom/src/subdiv-curve.ts index 31b3e93ebd..56300fef80 100644 --- a/packages/geom/src/subdiv-curve.ts +++ b/packages/geom/src/subdiv-curve.ts @@ -1,10 +1,12 @@ -import { comp } from "@thi.ng/transducers/func/comp"; -import { wrap } from "@thi.ng/transducers/iter/wrap"; -import { push } from "@thi.ng/transducers/rfn/push"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { indexed } from "@thi.ng/transducers/xform/indexed"; -import { mapcat } from "@thi.ng/transducers/xform/mapcat"; -import { partition } from "@thi.ng/transducers/xform/partition"; +import { + comp, + indexed, + mapcat, + partition, + push, + transduce, + wrap +} from "@thi.ng/transducers"; import { IVector } from "@thi.ng/vectors/api"; import { SubdivKernel } from "./api"; @@ -21,7 +23,7 @@ const madd3 = const madd5 = > (a: Readonly, b: Readonly, c: Readonly, d: Readonly, e: Readonly, - ua: number, ub: number, uc: number, ud: number, ue: number) => + ua: number, ub: number, uc: number, ud: number, ue: number) => a.mulNewN(ua).maddN(b, ub).maddN(c, uc).maddN(d, ud).maddN(e, ue); export const subdivKernel2 = diff --git a/packages/geom/src/tessellate.ts b/packages/geom/src/tessellate.ts index dc100dc8e8..78be1ab2c3 100644 --- a/packages/geom/src/tessellate.ts +++ b/packages/geom/src/tessellate.ts @@ -1,19 +1,20 @@ -import { isFunction } from "@thi.ng/checks/is-function"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { range } from "@thi.ng/transducers/iter/range"; -import { repeat } from "@thi.ng/transducers/iter/repeat"; -import { tuples } from "@thi.ng/transducers/iter/tuples"; -import { wrap } from "@thi.ng/transducers/iter/wrap"; -import { reducer } from "@thi.ng/transducers/reduce"; -import { last } from "@thi.ng/transducers/rfn/last"; -import { push } from "@thi.ng/transducers/rfn/push"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { map } from "@thi.ng/transducers/xform/map"; -import { mapcat } from "@thi.ng/transducers/xform/mapcat"; -import { partition } from "@thi.ng/transducers/xform/partition"; -import { scan } from "@thi.ng/transducers/xform/scan"; -import { IVector } from "@thi.ng/vectors/api"; -import { Vec2 } from "@thi.ng/vectors/vec2"; +import { isFunction } from "@thi.ng/checks"; +import { + comp, + last, + map, + mapcat, + partition, + push, + range, + reducer, + repeat, + scan, + transduce, + tuples, + wrap +} from "@thi.ng/transducers"; +import { IVector, Vec2 } from "@thi.ng/vectors"; import { Tessellator } from "./api"; import { polygonArea } from "./internal/area"; import { centroid } from "./internal/centroid"; diff --git a/packages/geom/src/triangle2.ts b/packages/geom/src/triangle2.ts index faa20596c1..0b7f1e1d16 100644 --- a/packages/geom/src/triangle2.ts +++ b/packages/geom/src/triangle2.ts @@ -1,8 +1,11 @@ import { ICopy } from "@thi.ng/api"; -import { PI } from "@thi.ng/math/api"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors/api"; -import { Vec2 } from "@thi.ng/vectors/vec2"; -import { Vec3 } from "@thi.ng/vectors/vec3"; +import { PI } from "@thi.ng/math"; +import { + ReadonlyVec, + Vec, + Vec2, + Vec3 +} from "@thi.ng/vectors"; import { Attribs, IArcLength, diff --git a/packages/geom/src/warp.ts b/packages/geom/src/warp.ts index 839d58c47d..6628ae86b9 100644 --- a/packages/geom/src/warp.ts +++ b/packages/geom/src/warp.ts @@ -1,12 +1,15 @@ +import { IVector } from "@thi.ng/vectors"; import { IPointMap } from "./api"; -import { IVector } from "@thi.ng/vectors/api"; -export const warpPoints = - , V2 extends IVector, A extends IPointMap, B extends IPointMap> - (dest: B, src: ReadonlyArray, srcBounds: A) => { - const res: V[] = []; - for (let n = src.length, i = 0; i < n; i++) { - res.push(dest.unmapPoint(srcBounds.mapPoint(src[i]))); - } - return res; - }; +export const warpPoints = < + V extends IVector, + V2 extends IVector, + A extends IPointMap, + B extends IPointMap +>(dest: B, src: ReadonlyArray, srcBounds: A) => { + const res: V[] = []; + for (let n = src.length, i = 0; i < n; i++) { + res.push(dest.unmapPoint(srcBounds.mapPoint(src[i]))); + } + return res; +}; diff --git a/packages/geom/test/circle2.ts b/packages/geom/test/circle2.ts index 4ab293f658..d5f877c2f9 100644 --- a/packages/geom/test/circle2.ts +++ b/packages/geom/test/circle2.ts @@ -1,6 +1,6 @@ import { equiv } from "@thi.ng/equiv"; -import { PI, TAU, HALF_PI } from "@thi.ng/math/api"; -import { eqDelta2array, vec2 } from "@thi.ng/vectors/vec2"; +import { HALF_PI, PI, TAU } from "@thi.ng/math"; +import { eqDelta2array, vec2 } from "@thi.ng/vectors"; import * as assert from "assert"; import { circle2, Circle2, HiccupCircle2 } from "../src"; diff --git a/packages/geom/test/tsconfig.json b/packages/geom/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/geom/test/tsconfig.json +++ b/packages/geom/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/heaps/package.json b/packages/heaps/package.json index 1f16da8306..80b1811122 100644 --- a/packages/heaps/package.json +++ b/packages/heaps/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/heaps", "version": "0.3.1", "description": "Generic binary heap & d-ary heap implementations with customizable ordering", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module heaps api compare", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -42,5 +46,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/heaps/src/api.ts b/packages/heaps/src/api.ts index 18b1b4466b..ebdd8abf85 100644 --- a/packages/heaps/src/api.ts +++ b/packages/heaps/src/api.ts @@ -1,4 +1,4 @@ -import { Comparator } from "@thi.ng/api/api"; +import { Comparator } from "@thi.ng/api"; export interface HeapOpts { compare: Comparator; diff --git a/packages/heaps/src/dheap.ts b/packages/heaps/src/dheap.ts index 87c5dea5b1..acfa8a7bf8 100644 --- a/packages/heaps/src/dheap.ts +++ b/packages/heaps/src/dheap.ts @@ -1,4 +1,4 @@ -import { ICopy, IEmpty } from "@thi.ng/api/api"; +import { ICopy, IEmpty } from "@thi.ng/api"; import { compare } from "@thi.ng/compare"; import { DHeapOpts } from "./api"; diff --git a/packages/heaps/src/heap.ts b/packages/heaps/src/heap.ts index a32d49cd46..f396ba8fd1 100644 --- a/packages/heaps/src/heap.ts +++ b/packages/heaps/src/heap.ts @@ -3,7 +3,7 @@ import { ICopy, IEmpty, ILength -} from "@thi.ng/api/api"; +} from "@thi.ng/api"; import { compare } from "@thi.ng/compare"; import { HeapOpts } from "./api"; diff --git a/packages/heaps/test/tsconfig.json b/packages/heaps/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/heaps/test/tsconfig.json +++ b/packages/heaps/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/hiccup-carbon-icons/package.json b/packages/hiccup-carbon-icons/package.json index 59b90d3fdc..636cab1374 100644 --- a/packages/hiccup-carbon-icons/package.json +++ b/packages/hiccup-carbon-icons/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/hiccup-carbon-icons", "version": "0.1.2", "description": "TODO", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module hiccupCarbonIcons", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@thi.ng/hiccup": "^2.7.2", @@ -29,10 +33,19 @@ "typescript": "^3.2.2" }, "keywords": [ + "assets", + "carbon", "ES6", - "typescript" + "hdom", + "hiccup", + "IBM", + "icons", + "svg", + "typescript", + "UI" ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/hiccup-carbon-icons/test/tsconfig.json b/packages/hiccup-carbon-icons/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/hiccup-carbon-icons/test/tsconfig.json +++ b/packages/hiccup-carbon-icons/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/hiccup-css/package.json b/packages/hiccup-css/package.json index ac4af4e875..18f9f4d00c 100644 --- a/packages/hiccup-css/package.json +++ b/packages/hiccup-css/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/hiccup-css", "version": "0.3.5", "description": "CSS from nested JS data structures", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module hiccupCss api checks errors transducers", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -49,5 +53,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/hiccup-css/src/api.ts b/packages/hiccup-css/src/api.ts index c604a121a3..6dcb8741dd 100644 --- a/packages/hiccup-css/src/api.ts +++ b/packages/hiccup-css/src/api.ts @@ -1,4 +1,4 @@ -import { IObjectOf } from "@thi.ng/api/api"; +import { IObjectOf } from "@thi.ng/api"; /** * Function type used by `at_xxx()` functions or any diff --git a/packages/hiccup-css/src/conditional.ts b/packages/hiccup-css/src/conditional.ts index 80fe10e627..40bba5d43e 100644 --- a/packages/hiccup-css/src/conditional.ts +++ b/packages/hiccup-css/src/conditional.ts @@ -1,5 +1,4 @@ -import { isString } from "@thi.ng/checks/is-string"; - +import { isString } from "@thi.ng/checks"; import { Conditional, CSSOpts, RuleFn } from "./api"; import { expand, indent } from "./impl"; diff --git a/packages/hiccup-css/src/css.ts b/packages/hiccup-css/src/css.ts index 821331f81a..b161242cd3 100644 --- a/packages/hiccup-css/src/css.ts +++ b/packages/hiccup-css/src/css.ts @@ -1,8 +1,10 @@ -import { isArray } from "@thi.ng/checks/is-array"; -import { isFunction } from "@thi.ng/checks/is-function"; -import { isIterable } from "@thi.ng/checks/is-iterable"; -import { isPlainObject } from "@thi.ng/checks/is-plain-object"; -import { isString } from "@thi.ng/checks/is-string"; +import { + isArray, + isFunction, + isIterable, + isPlainObject, + isString +} from "@thi.ng/checks"; import { COMPACT, CSSOpts, DEFAULT_VENDORS } from "./api"; import { expand, formatDecls } from "./impl"; diff --git a/packages/hiccup-css/src/impl.ts b/packages/hiccup-css/src/impl.ts index fc874a4f2f..b9f01d1487 100644 --- a/packages/hiccup-css/src/impl.ts +++ b/packages/hiccup-css/src/impl.ts @@ -1,17 +1,21 @@ -import { isArray } from "@thi.ng/checks/is-array"; -import { isFunction } from "@thi.ng/checks/is-function"; -import { isIterable } from "@thi.ng/checks/is-iterable"; -import { isPlainObject } from "@thi.ng/checks/is-plain-object"; -import { isString } from "@thi.ng/checks/is-string"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { Transducer } from "@thi.ng/transducers/api"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { permutations } from "@thi.ng/transducers/iter/permutations"; -import { repeat } from "@thi.ng/transducers/iter/repeat"; -import { str } from "@thi.ng/transducers/rfn/str"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { flatten } from "@thi.ng/transducers/xform/flatten"; -import { map } from "@thi.ng/transducers/xform/map"; +import { + isArray, + isFunction, + isIterable, + isPlainObject, + isString +} from "@thi.ng/checks"; +import { illegalArgs } from "@thi.ng/errors"; +import { + comp, + flatten, + map, + permutations, + repeat, + str, + transduce, + Transducer +} from "@thi.ng/transducers"; import { CSSOpts } from "./api"; const EMPTY = new Set(); diff --git a/packages/hiccup-css/test/tsconfig.json b/packages/hiccup-css/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/hiccup-css/test/tsconfig.json +++ b/packages/hiccup-css/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/hiccup-markdown/package.json b/packages/hiccup-markdown/package.json index 13c044dd82..8f5fd411bc 100644 --- a/packages/hiccup-markdown/package.json +++ b/packages/hiccup-markdown/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/hiccup-markdown", "version": "0.2.0", "description": "Markdown serialization of hiccup DOM trees", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module hiccupMarkdown checks defmulti errors fsm hiccup strings transducers", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -50,5 +54,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/hiccup-markdown/src/parse.ts b/packages/hiccup-markdown/src/parse.ts index 47516b611f..937537c9e8 100644 --- a/packages/hiccup-markdown/src/parse.ts +++ b/packages/hiccup-markdown/src/parse.ts @@ -1,13 +1,15 @@ -import { alts } from "@thi.ng/fsm/alts"; -import { ResultBody } from "@thi.ng/fsm/api"; -import { fsm } from "@thi.ng/fsm/fsm"; -import { not } from "@thi.ng/fsm/not"; -import { whitespace } from "@thi.ng/fsm/range"; -import { repeat } from "@thi.ng/fsm/repeat"; -import { seq } from "@thi.ng/fsm/seq"; -import { str } from "@thi.ng/fsm/str"; -import { until } from "@thi.ng/fsm/until"; -import { peek } from "@thi.ng/transducers/func/peek"; +import { + alts, + fsm, + not, + repeat, + ResultBody, + seq, + str, + until, + whitespace +} from "@thi.ng/fsm"; +import { peek } from "@thi.ng/transducers"; import { TagFactories } from "./api"; type ParseResult = ResultBody; diff --git a/packages/hiccup-markdown/src/serialize.ts b/packages/hiccup-markdown/src/serialize.ts index 397bf0ebb3..96f516e3e8 100644 --- a/packages/hiccup-markdown/src/serialize.ts +++ b/packages/hiccup-markdown/src/serialize.ts @@ -1,12 +1,13 @@ -import { implementsFunction } from "@thi.ng/checks/implements-function"; -import { isFunction } from "@thi.ng/checks/is-function"; -import { isNotStringAndIterable } from "@thi.ng/checks/is-not-string-iterable"; -import { isString } from "@thi.ng/checks/is-string"; +import { + implementsFunction, + isFunction, + isNotStringAndIterable, + isString +} from "@thi.ng/checks"; import { DEFAULT, defmulti, MultiFn3 } from "@thi.ng/defmulti"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { normalize } from "@thi.ng/hiccup/serialize"; -import { repeat } from "@thi.ng/strings/repeat"; -import { wrap } from "@thi.ng/strings/wrap"; +import { illegalArgs } from "@thi.ng/errors"; +import { normalize } from "@thi.ng/hiccup"; +import { repeat, wrap } from "@thi.ng/strings"; export const serialize = (tree: any, ctx) => _serialize(tree, ctx, { indent: 0, sep: "" }); diff --git a/packages/hiccup-markdown/test/tsconfig.json b/packages/hiccup-markdown/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/hiccup-markdown/test/tsconfig.json +++ b/packages/hiccup-markdown/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/hiccup-svg/package.json b/packages/hiccup-svg/package.json index 6e35918f13..1c83318a92 100644 --- a/packages/hiccup-svg/package.json +++ b/packages/hiccup-svg/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/hiccup-svg", "version": "2.0.10", "description": "SVG element functions for @thi.ng/hiccup & @thi.ng/hdom", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module hiccup-svg checks hiccup", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -28,19 +32,24 @@ "typescript": "^3.2.2" }, "dependencies": { + "@thi.ng/checks": "^1.5.14", "@thi.ng/hiccup": "^2.7.2" }, "keywords": [ "components", + "convert", "ES6", + "generator", "hiccup", "hdom", "SVG", + "serialize", "typescript", "UI", "visualization" ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/hiccup-svg/src/circle.ts b/packages/hiccup-svg/src/circle.ts index bde7615028..a902c298d3 100644 --- a/packages/hiccup-svg/src/circle.ts +++ b/packages/hiccup-svg/src/circle.ts @@ -1,10 +1,11 @@ import { Vec2Like } from "./api"; import { ff } from "./format"; -export const circle = (p: Vec2Like, r: number, attribs?: any): any[] => - ["circle", { - cx: ff(p[0]), - cy: ff(p[1]), - r: ff(r), - ...attribs - }]; +export const circle = + (p: Vec2Like, r: number, attribs?: any): any[] => + ["circle", { + cx: ff(p[0]), + cy: ff(p[1]), + r: ff(r), + ...attribs + }]; diff --git a/packages/hiccup-svg/src/convert.ts b/packages/hiccup-svg/src/convert.ts index 9b409f3ed9..094cca3aa9 100644 --- a/packages/hiccup-svg/src/convert.ts +++ b/packages/hiccup-svg/src/convert.ts @@ -1,6 +1,4 @@ -import { isArray } from "@thi.ng/checks/is-array"; -import { isArrayLike } from "@thi.ng/checks/is-arraylike"; - +import { isArray, isArrayLike } from "@thi.ng/checks"; import { PathSegment } from "./api"; import { circle } from "./circle"; import { ff } from "./format"; @@ -40,149 +38,152 @@ const TEXT_ALIGN = { * * @param tree */ -export const convertTree = (tree: any[]): any[] => { - const type = tree[0]; - if (isArray(type)) { - return tree.map(convertTree); - } - let attribs = convertAttribs(tree[1]); - switch (tree[0]) { - case "svg": - case "defs": - case "g": { - const res: any[] = [type, attribs]; - for (let i = 2, n = tree.length; i < n; i++) { - const c = convertTree(tree[i]); - c != null && res.push(c); - } - return res; +export const convertTree = + (tree: any[]): any[] => { + const type = tree[0]; + if (isArray(type)) { + return tree.map(convertTree); } - case "linearGradient": - return linearGradient( - attribs.id, - attribs.from, - attribs.to, - tree[2], - { - gradientUnits: attribs.gradientUnits || "userSpaceOnUse", - gradientTransform: attribs.gradientTransform, - } - ); - case "radialGradient": - return radialGradient( - attribs.id, - attribs.from, - attribs.to, - attribs.r1, - attribs.r2, - tree[2], - { - gradientUnits: attribs.gradientUnits || "userSpaceOnUse", - gradientTransform: attribs.gradientTransform, + let attribs = convertAttribs(tree[1]); + switch (tree[0]) { + case "svg": + case "defs": + case "g": { + const res: any[] = [type, attribs]; + for (let i = 2, n = tree.length; i < n; i++) { + const c = convertTree(tree[i]); + c != null && res.push(c); } - ); - case "circle": - return circle(tree[2], tree[3], attribs); - case "rect": { - const r = tree[5] || 0; - return roundedRect(tree[2], tree[3], tree[4], r, r, attribs); - } - case "line": - return line(tree[2], tree[3], attribs); - case "hline": - return hline(tree[2], attribs); - case "vline": - return vline(tree[2], attribs); - case "polyline": - case "polygon": - return polygon(tree[2], attribs); - case "path": { - let segments: PathSegment[] = []; - for (let seg of tree[2]) { - switch (seg[0].toLowerCase()) { - case "s": - case "t": - // TODO compute reflected control point - // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#Cubic_B%C3%A9zier_Curve - // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#Quadratic_B%C3%A9zier_Curve - break; - default: - segments.push(seg); + return res; + } + case "linearGradient": + return linearGradient( + attribs.id, + attribs.from, + attribs.to, + tree[2], + { + gradientUnits: attribs.gradientUnits || "userSpaceOnUse", + gradientTransform: attribs.gradientTransform, + } + ); + case "radialGradient": + return radialGradient( + attribs.id, + attribs.from, + attribs.to, + attribs.r1, + attribs.r2, + tree[2], + { + gradientUnits: attribs.gradientUnits || "userSpaceOnUse", + gradientTransform: attribs.gradientTransform, + } + ); + case "circle": + return circle(tree[2], tree[3], attribs); + case "rect": { + const r = tree[5] || 0; + return roundedRect(tree[2], tree[3], tree[4], r, r, attribs); + } + case "line": + return line(tree[2], tree[3], attribs); + case "hline": + return hline(tree[2], attribs); + case "vline": + return vline(tree[2], attribs); + case "polyline": + case "polygon": + return polygon(tree[2], attribs); + case "path": { + let segments: PathSegment[] = []; + for (let seg of tree[2]) { + switch (seg[0].toLowerCase()) { + case "s": + case "t": + // TODO compute reflected control point + // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#Cubic_B%C3%A9zier_Curve + // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#Quadratic_B%C3%A9zier_Curve + break; + default: + segments.push(seg); + } } + return path(segments, attribs); } - return path(segments, attribs); + case "text": + return text(tree[2], tree[3], attribs); + case "img": + return image(tree[2], tree[3].src, attribs); + case "points": + return points(tree[2], attribs.shape, attribs.size, attribs); + default: + return tree; } - case "text": - return text(tree[2], tree[3], attribs); - case "img": - return image(tree[2], tree[3].src, attribs); - case "points": - return points(tree[2], attribs.shape, attribs.size, attribs); - default: - return tree; - } -}; + }; -const convertAttribs = (attribs: any) => { - const res: any = convertTransforms(attribs); - for (let id in attribs) { - const v = attribs[id]; - if (ATTRIB_ALIASES[id]) { - res[ATTRIB_ALIASES[id]] = v; - } else { - switch (id) { - case "fill": - case "stroke": - res[id] = v[0] === "$" ? `url(#${v.substr(1)})` : v; - break; - case "font": { - const i = v.indexOf(" "); - res["font-size"] = v.substr(0, i); - res["font-family"] = v.substr(i + 1); - break; +const convertAttribs = + (attribs: any) => { + const res: any = convertTransforms(attribs); + for (let id in attribs) { + const v = attribs[id]; + if (ATTRIB_ALIASES[id]) { + res[ATTRIB_ALIASES[id]] = v; + } else { + switch (id) { + case "fill": + case "stroke": + res[id] = v[0] === "$" ? `url(#${v.substr(1)})` : v; + break; + case "font": { + const i = v.indexOf(" "); + res["font-size"] = v.substr(0, i); + res["font-family"] = v.substr(i + 1); + break; + } + case "align": + res["text-anchor"] = TEXT_ALIGN[v]; + break; + case "baseline": + // no SVG support? + case "filter": + // TODO needs to be translated into def first + // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/filter + // https://developer.mozilla.org/en-US/docs/Web/SVG/Element/filter + case "transform": + case "translate": + case "rotate": + case "scale": + break; + default: + res[id] = v; } - case "align": - res["text-anchor"] = TEXT_ALIGN[v]; - break; - case "baseline": - // no SVG support? - case "filter": - // TODO needs to be translated into def first - // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/filter - // https://developer.mozilla.org/en-US/docs/Web/SVG/Element/filter - case "transform": - case "translate": - case "rotate": - case "scale": - break; - default: - res[id] = v; } } - } - return res; -}; + return res; + }; -const convertTransforms = (attribs: any) => { - const res: any = {}; - if (!attribs) return res; - let v: any; - if ((v = attribs.transform) || - attribs.translate || - attribs.scale || - attribs.rotate) { +const convertTransforms = + (attribs: any) => { + const res: any = {}; + if (!attribs) return res; + let v: any; + if ((v = attribs.transform) || + attribs.translate || + attribs.scale || + attribs.rotate) { - const tx: string[] = []; - (v = attribs.transform) && tx.push(`matrix(${[...v].map(ff).join(" ")})`); - (v = attribs.translate) && tx.push(`translate(${ff(v[0])} ${ff(v[1])})`); - (v = attribs.rotate) && tx.push(`rotate(${ff(v * 180 / Math.PI)})`); - (v = attribs.scale) && - tx.push( - isArrayLike(v) ? - `scale(${ff(v[0])} ${ff(v[1])})` : - `scale(${ff(v)})` - ); - res.transform = tx.join(" "); - } - return res; -}; + const tx: string[] = []; + (v = attribs.transform) && tx.push(`matrix(${[...v].map(ff).join(" ")})`); + (v = attribs.translate) && tx.push(`translate(${ff(v[0])} ${ff(v[1])})`); + (v = attribs.rotate) && tx.push(`rotate(${ff(v * 180 / Math.PI)})`); + (v = attribs.scale) && + tx.push( + isArrayLike(v) ? + `scale(${ff(v[0])} ${ff(v[1])})` : + `scale(${ff(v)})` + ); + res.transform = tx.join(" "); + } + return res; + }; diff --git a/packages/hiccup-svg/src/defs.ts b/packages/hiccup-svg/src/defs.ts index fb03902b40..90966fb709 100644 --- a/packages/hiccup-svg/src/defs.ts +++ b/packages/hiccup-svg/src/defs.ts @@ -1,2 +1,3 @@ -export const defs = (...defs: any[]): any[] => - ["defs", {}, ...defs]; +export const defs = + (...defs: any[]): any[] => + ["defs", {}, ...defs]; diff --git a/packages/hiccup-svg/src/format.ts b/packages/hiccup-svg/src/format.ts index fd1359f41b..dceba79fbf 100644 --- a/packages/hiccup-svg/src/format.ts +++ b/packages/hiccup-svg/src/format.ts @@ -2,10 +2,14 @@ import { Vec2Like } from "./api"; let PRECISION = 2; -export const setPrecision = (n: number) => (PRECISION = n); +export const setPrecision = + (n: number) => (PRECISION = n); -export const ff = (x: number) => x.toFixed(PRECISION); +export const ff = + (x: number) => x.toFixed(PRECISION); -export const fpoint = (p: Vec2Like) => ff(p[0]) + "," + ff(p[1]); +export const fpoint = + (p: Vec2Like) => ff(p[0]) + "," + ff(p[1]); -export const fpoints = (pts: Vec2Like[], sep = " ") => pts ? pts.map(fpoint).join(sep) : ""; +export const fpoints = + (pts: Vec2Like[], sep = " ") => pts ? pts.map(fpoint).join(sep) : ""; diff --git a/packages/hiccup-svg/src/gradients.ts b/packages/hiccup-svg/src/gradients.ts index f754ab6fe1..cc2131f266 100644 --- a/packages/hiccup-svg/src/gradients.ts +++ b/packages/hiccup-svg/src/gradients.ts @@ -3,24 +3,26 @@ import { ff } from "./format"; const RE_ALPHA_COLOR = /(rgb|hsl)a\(([a-z0-9.-]+),([0-9.%]+),([0-9.%]+),([0-9.]+)\)/; -const gradient = (type: string, attribs: any, stops: GradientStop[]): any[] => - [ - type, - attribs, - ...stops.map(gradientStop) - ]; +const gradient = + (type: string, attribs: any, stops: GradientStop[]): any[] => + [ + type, + attribs, + ...stops.map(gradientStop) + ]; -const gradientStop = ([offset, col]: GradientStop) => { - // use stop-opacity attrib for safari compatibility - // https://stackoverflow.com/a/26220870/294515 - let opacity: string; - const parts = RE_ALPHA_COLOR.exec(col); - if (parts) { - col = `${parts[1]}(${parts[2]},${parts[3]},${parts[4]})`; - opacity = parts[5]; - } - return ["stop", { offset, "stop-color": col, "stop-opacity": opacity }]; -}; +const gradientStop = + ([offset, col]: GradientStop) => { + // use stop-opacity attrib for safari compatibility + // https://stackoverflow.com/a/26220870/294515 + let opacity: string; + const parts = RE_ALPHA_COLOR.exec(col); + if (parts) { + col = `${parts[1]}(${parts[2]},${parts[3]},${parts[4]})`; + opacity = parts[5]; + } + return ["stop", { offset, "stop-color": col, "stop-opacity": opacity }]; + }; export const linearGradient = ( id: string, diff --git a/packages/hiccup-svg/src/group.ts b/packages/hiccup-svg/src/group.ts index 3795760626..49129ef197 100644 --- a/packages/hiccup-svg/src/group.ts +++ b/packages/hiccup-svg/src/group.ts @@ -1,2 +1,3 @@ -export const group = (attr: any, ...body: any[]): any[] => - ["g", attr, ...body]; +export const group = + (attr: any, ...body: any[]): any[] => + ["g", attr, ...body]; diff --git a/packages/hiccup-svg/src/image.ts b/packages/hiccup-svg/src/image.ts index 02b18d907a..c3536c7aaf 100644 --- a/packages/hiccup-svg/src/image.ts +++ b/packages/hiccup-svg/src/image.ts @@ -1,10 +1,11 @@ import { Vec2Like } from "./api"; import { ff } from "./format"; -export const image = (pos: Vec2Like, url: string, attribs?: any): any[] => - ["image", { - // TODO replace w/ SVG2 `href` once Safari supports it - "xlink:href": url, - x: ff(pos[0]), y: ff(pos[1]), - ...attribs - }]; +export const image = + (pos: Vec2Like, url: string, attribs?: any): any[] => + ["image", { + // TODO replace w/ SVG2 `href` once Safari supports it + "xlink:href": url, + x: ff(pos[0]), y: ff(pos[1]), + ...attribs + }]; diff --git a/packages/hiccup-svg/src/line.ts b/packages/hiccup-svg/src/line.ts index 791009211d..de925124e1 100644 --- a/packages/hiccup-svg/src/line.ts +++ b/packages/hiccup-svg/src/line.ts @@ -1,17 +1,20 @@ import { Vec2Like } from "./api"; import { ff } from "./format"; -export const line = (a: Vec2Like, b: Vec2Like, attribs?: any): any[] => - ["line", { - x1: ff(a[0]), - y1: ff(a[1]), - x2: ff(b[0]), - y2: ff(b[1]), - ...attribs - }]; +export const line = + (a: Vec2Like, b: Vec2Like, attribs?: any): any[] => + ["line", { + x1: ff(a[0]), + y1: ff(a[1]), + x2: ff(b[0]), + y2: ff(b[1]), + ...attribs + }]; -export const hline = (y: number, attribs?: any) => - line([-1e6, y], [1e6, y], attribs); +export const hline = + (y: number, attribs?: any) => + line([-1e6, y], [1e6, y], attribs); -export const vline = (x: number, attribs?: any) => - line([x, -1e6], [x, 1e6], attribs); +export const vline = + (x: number, attribs?: any) => + line([x, -1e6], [x, 1e6], attribs); diff --git a/packages/hiccup-svg/src/path.ts b/packages/hiccup-svg/src/path.ts index daffdf041c..7ca825ff68 100644 --- a/packages/hiccup-svg/src/path.ts +++ b/packages/hiccup-svg/src/path.ts @@ -1,35 +1,36 @@ import { PathSegment } from "./api"; import { ff, fpoint, fpoints } from "./format"; -export const path = (segments: PathSegment[], attribs?: any): any[] => { - let res = []; - for (let seg of segments) { - res.push(seg[0]); - switch (seg[0].toLowerCase()) { - case "a": - res.push([ - ff(seg[1]), - ff(seg[2]), - ff(seg[3]), - seg[4] ? 1 : 0, - seg[5] ? 1 : 0, - ff(seg[6][0]), - ff(seg[6][1]), - ].join(",")); - break; - case "h": - case "v": - res.push(ff(seg[1])); - break; - case "m": - case "l": - res.push(fpoint(seg[1])); - break; - case "z": - break; - default: - res.push(fpoints((seg).slice(1), ",")); +export const path = + (segments: PathSegment[], attribs?: any): any[] => { + let res = []; + for (let seg of segments) { + res.push(seg[0]); + switch (seg[0].toLowerCase()) { + case "a": + res.push([ + ff(seg[1]), + ff(seg[2]), + ff(seg[3]), + seg[4] ? 1 : 0, + seg[5] ? 1 : 0, + ff(seg[6][0]), + ff(seg[6][1]), + ].join(",")); + break; + case "h": + case "v": + res.push(ff(seg[1])); + break; + case "m": + case "l": + res.push(fpoint(seg[1])); + break; + case "z": + break; + default: + res.push(fpoints((seg).slice(1), ",")); + } } - } - return ["path", { ...attribs, d: res.join("") }]; -}; + return ["path", { ...attribs, d: res.join("") }]; + }; diff --git a/packages/hiccup-svg/src/points.ts b/packages/hiccup-svg/src/points.ts index bcf110be8d..9e27d618b5 100644 --- a/packages/hiccup-svg/src/points.ts +++ b/packages/hiccup-svg/src/points.ts @@ -12,24 +12,25 @@ import { ff } from "./format"; * @param size * @param attribs */ -export const points = (pts: Iterable, shape: string, size = 1, attribs?: any): any[] => { - const group = ["g", attribs]; - let href: string; - if (!shape || shape[0] !== "#") { - const r = ff(size); - href = "_" + ((Math.random() * 1e6) | 0).toString(36); - group.push(["g", { opacity: 0 }, - shape === "circle" ? - ["circle", { id: href, cx: 0, cy: 0, r: r }] : - ["rect", { id: href, x: 0, y: 0, width: r, height: r }] - ]); - href = "#" + href; - } else { - href = shape; - } - for (let p of pts) { - // TODO replace w/ SVG2 `href` once Safari supports it - group.push(["use", { "xlink:href": href, x: ff(p[0]), y: ff(p[1]) }]); - } - return group; -}; +export const points = + (pts: Iterable, shape: string, size = 1, attribs?: any): any[] => { + const group = ["g", attribs]; + let href: string; + if (!shape || shape[0] !== "#") { + const r = ff(size); + href = "_" + ((Math.random() * 1e6) | 0).toString(36); + group.push(["g", { opacity: 0 }, + shape === "circle" ? + ["circle", { id: href, cx: 0, cy: 0, r: r }] : + ["rect", { id: href, x: 0, y: 0, width: r, height: r }] + ]); + href = "#" + href; + } else { + href = shape; + } + for (let p of pts) { + // TODO replace w/ SVG2 `href` once Safari supports it + group.push(["use", { "xlink:href": href, x: ff(p[0]), y: ff(p[1]) }]); + } + return group; + }; diff --git a/packages/hiccup-svg/src/polygon.ts b/packages/hiccup-svg/src/polygon.ts index 566b13786a..f3b593ae2f 100644 --- a/packages/hiccup-svg/src/polygon.ts +++ b/packages/hiccup-svg/src/polygon.ts @@ -1,5 +1,6 @@ import { Vec2Like } from "./api"; import { fpoints } from "./format"; -export const polygon = (pts: Vec2Like[], attribs?: any): any[] => - ["polygon", { points: fpoints(pts), ...attribs }]; +export const polygon = + (pts: Vec2Like[], attribs?: any): any[] => + ["polygon", { points: fpoints(pts), ...attribs }]; diff --git a/packages/hiccup-svg/src/polyline.ts b/packages/hiccup-svg/src/polyline.ts index d27a056443..5ea000444a 100644 --- a/packages/hiccup-svg/src/polyline.ts +++ b/packages/hiccup-svg/src/polyline.ts @@ -1,5 +1,6 @@ import { Vec2Like } from "./api"; import { fpoints } from "./format"; -export const polyline = (pts: Vec2Like[], attribs?: any): any[] => - ["polyline", { points: fpoints(pts), ...attribs }]; +export const polyline = + (pts: Vec2Like[], attribs?: any): any[] => + ["polyline", { points: fpoints(pts), ...attribs }]; diff --git a/packages/hiccup-svg/src/rect.ts b/packages/hiccup-svg/src/rect.ts index 65decabbc3..81338dcd45 100644 --- a/packages/hiccup-svg/src/rect.ts +++ b/packages/hiccup-svg/src/rect.ts @@ -1,8 +1,9 @@ import { Vec2Like } from "./api"; import { ff } from "./format"; -export const rect = (p: Vec2Like, width: number, height: number, attribs?: any) => - roundedRect(p, width, height, 0, 0, attribs); +export const rect = + (p: Vec2Like, width: number, height: number, attribs?: any) => + roundedRect(p, width, height, 0, 0, attribs); export const roundedRect = ( p: Vec2Like, diff --git a/packages/hiccup-svg/src/svg.ts b/packages/hiccup-svg/src/svg.ts index ba20816ee1..365191fce6 100644 --- a/packages/hiccup-svg/src/svg.ts +++ b/packages/hiccup-svg/src/svg.ts @@ -1,4 +1,4 @@ -import { SVG_NS, XLINK_NS } from "@thi.ng/hiccup/api"; +import { SVG_NS, XLINK_NS } from "@thi.ng/hiccup"; /** * Defines an root element with default XML namespaces. By default @@ -8,10 +8,11 @@ import { SVG_NS, XLINK_NS } from "@thi.ng/hiccup/api"; * @param attribs * @param body */ -export const svg = (attribs: any, ...body: any[]): any[] => - ["svg", { - version: "1.1", - xmlns: SVG_NS, - "xmlns:xlink": XLINK_NS, - ...attribs - }, ...body]; +export const svg = + (attribs: any, ...body: any[]): any[] => + ["svg", { + version: "1.1", + xmlns: SVG_NS, + "xmlns:xlink": XLINK_NS, + ...attribs + }, ...body]; diff --git a/packages/hiccup-svg/src/text.ts b/packages/hiccup-svg/src/text.ts index b453a33c58..9ee29591f9 100644 --- a/packages/hiccup-svg/src/text.ts +++ b/packages/hiccup-svg/src/text.ts @@ -1,9 +1,10 @@ import { Vec2Like } from "./api"; import { ff } from "./format"; -export const text = (p: Vec2Like, body: string, attribs?: any): any[] => - ["text", { - x: ff(p[0]), - y: ff(p[1]), - ...attribs - }, body]; +export const text = + (p: Vec2Like, body: string, attribs?: any): any[] => + ["text", { + x: ff(p[0]), + y: ff(p[1]), + ...attribs + }, body]; diff --git a/packages/hiccup-svg/test/tsconfig.json b/packages/hiccup-svg/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/hiccup-svg/test/tsconfig.json +++ b/packages/hiccup-svg/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/hiccup/package.json b/packages/hiccup/package.json index 8c5b64ba68..4f22894840 100644 --- a/packages/hiccup/package.json +++ b/packages/hiccup/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/hiccup", "version": "2.7.2", "description": "HTML/SVG/XML serialization of nested data structures, iterables & closures", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module hiccup checks errors", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@thi.ng/atom": "^1.5.8", @@ -48,5 +52,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/hiccup/src/css.ts b/packages/hiccup/src/css.ts index dee596eb47..afb0f76a07 100644 --- a/packages/hiccup/src/css.ts +++ b/packages/hiccup/src/css.ts @@ -1,4 +1,4 @@ -import { isFunction } from "@thi.ng/checks/is-function"; +import { isFunction } from "@thi.ng/checks"; export const css = (rules: any) => { diff --git a/packages/hiccup/src/deref.ts b/packages/hiccup/src/deref.ts index b6b18427a6..76bf890fc3 100644 --- a/packages/hiccup/src/deref.ts +++ b/packages/hiccup/src/deref.ts @@ -1,4 +1,4 @@ -import { implementsFunction } from "@thi.ng/checks/implements-function"; +import { implementsFunction } from "@thi.ng/checks"; /** * Takes an arbitrary `ctx` object and array of `keys`. Attempts to call diff --git a/packages/hiccup/src/serialize.ts b/packages/hiccup/src/serialize.ts index a776ef49d2..801be8ac6d 100644 --- a/packages/hiccup/src/serialize.ts +++ b/packages/hiccup/src/serialize.ts @@ -1,9 +1,11 @@ -import { implementsFunction } from "@thi.ng/checks/implements-function"; -import { isFunction } from "@thi.ng/checks/is-function"; -import { isNotStringAndIterable } from "@thi.ng/checks/is-not-string-iterable"; -import { isPlainObject } from "@thi.ng/checks/is-plain-object"; -import { isString } from "@thi.ng/checks/is-string"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { + implementsFunction, + isFunction, + isNotStringAndIterable, + isPlainObject, + isString +} from "@thi.ng/checks"; +import { illegalArgs } from "@thi.ng/errors"; import { COMMENT, NO_SPANS, diff --git a/packages/hiccup/test/tsconfig.json b/packages/hiccup/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/hiccup/test/tsconfig.json +++ b/packages/hiccup/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/iges/package.json b/packages/iges/package.json index aa21eedbc4..7d1d7e824d 100644 --- a/packages/iges/package.json +++ b/packages/iges/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/iges", "version": "0.2.30", "description": "IGES 5.3 serializer for (currently only) polygonal geometry, both open & closed", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module iges api defmulti strings transducers", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -44,5 +48,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/iges/src/index.ts b/packages/iges/src/index.ts index ad47f45b24..0323c74ba3 100644 --- a/packages/iges/src/index.ts +++ b/packages/iges/src/index.ts @@ -1,16 +1,16 @@ import { defmulti } from "@thi.ng/defmulti"; -import { float } from "@thi.ng/strings/float"; -import { padLeft } from "@thi.ng/strings/pad-left"; -import { padRight } from "@thi.ng/strings/pad-right"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { wrap } from "@thi.ng/transducers/iter/wrap"; -import { push } from "@thi.ng/transducers/rfn/push"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { map } from "@thi.ng/transducers/xform/map"; -import { mapIndexed } from "@thi.ng/transducers/xform/map-indexed"; -import { mapcat } from "@thi.ng/transducers/xform/mapcat"; -import { partition } from "@thi.ng/transducers/xform/partition"; -import { wordWrap } from "@thi.ng/transducers/xform/word-wrap"; +import { float, padLeft, padRight } from "@thi.ng/strings"; +import { + comp, + map, + mapcat, + mapIndexed, + partition, + push, + transduce, + wordWrap, + wrap +} from "@thi.ng/transducers"; import { DEFAULT_GLOBALS, DictEntry, diff --git a/packages/iges/test/tsconfig.json b/packages/iges/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/iges/test/tsconfig.json +++ b/packages/iges/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/interceptors/package.json b/packages/interceptors/package.json index 1447b62f63..0df9b10a38 100644 --- a/packages/interceptors/package.json +++ b/packages/interceptors/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/interceptors", "version": "1.9.2", "description": "Interceptor based event bus, side effect & immutable state handling", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module interceptors api atom checks errors paths", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -40,5 +44,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/interceptors/src/api.ts b/packages/interceptors/src/api.ts index 94718cd81a..f95cb5f824 100644 --- a/packages/interceptors/src/api.ts +++ b/packages/interceptors/src/api.ts @@ -1,4 +1,4 @@ -import { ReadonlyAtom } from "@thi.ng/atom/api"; +import { ReadonlyAtom } from "@thi.ng/atom"; export type InterceptorFn = (state: any, e: Event, bus?: IDispatch, ctx?: InterceptorContext) => InterceptorContext | void; export type InterceptorPredicate = (state: any, e: Event, bus?: IDispatch, ctx?: InterceptorContext) => boolean; diff --git a/packages/interceptors/src/event-bus.ts b/packages/interceptors/src/event-bus.ts index ce00512b2c..8fd413b629 100644 --- a/packages/interceptors/src/event-bus.ts +++ b/packages/interceptors/src/event-bus.ts @@ -1,13 +1,13 @@ -import { IDeref, IObjectOf } from "@thi.ng/api/api"; -import { IAtom } from "@thi.ng/atom/api"; -import { Atom } from "@thi.ng/atom/atom"; -import { implementsFunction } from "@thi.ng/checks/implements-function"; -import { isArray } from "@thi.ng/checks/is-array"; -import { isFunction } from "@thi.ng/checks/is-function"; -import { isPromise } from "@thi.ng/checks/is-promise"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { IDeref, IObjectOf } from "@thi.ng/api"; +import { Atom, IAtom } from "@thi.ng/atom"; +import { + implementsFunction, + isArray, + isFunction, + isPromise +} from "@thi.ng/checks"; +import { illegalArgs } from "@thi.ng/errors"; import { setIn, updateIn } from "@thi.ng/paths"; - import * as api from "./api"; const FX_CANCEL = api.FX_CANCEL; diff --git a/packages/interceptors/src/interceptors.ts b/packages/interceptors/src/interceptors.ts index e085687a4d..6361d7c5f4 100644 --- a/packages/interceptors/src/interceptors.ts +++ b/packages/interceptors/src/interceptors.ts @@ -14,7 +14,6 @@ import { InterceptorPredicate } from "./api"; - /** * Debug interceptor to log the current event to the console. */ diff --git a/packages/interceptors/test/tsconfig.json b/packages/interceptors/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/interceptors/test/tsconfig.json +++ b/packages/interceptors/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/intervals/package.json b/packages/intervals/package.json index 0172b565e3..5def147018 100644 --- a/packages/intervals/package.json +++ b/packages/intervals/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/intervals", "version": "0.2.0", "description": "Closed/open/semi-open interval data type, queries & operations", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module intervals api errors", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -45,5 +49,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/intervals/src/index.ts b/packages/intervals/src/index.ts index 9b3abe4ae7..72568bc93f 100644 --- a/packages/intervals/src/index.ts +++ b/packages/intervals/src/index.ts @@ -1,5 +1,11 @@ -import { ICopy, IEquiv, IContains, Fn, ICompare } from "@thi.ng/api/api"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { + Fn, + ICompare, + IContains, + ICopy, + IEquiv +} from "@thi.ng/api"; +import { illegalArgs } from "@thi.ng/errors"; export const enum Classifier { DISJOINT_LEFT, diff --git a/packages/intervals/test/tsconfig.json b/packages/intervals/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/intervals/test/tsconfig.json +++ b/packages/intervals/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/iterators/package.json b/packages/iterators/package.json index f07d61f1b5..c367001ae8 100644 --- a/packages/iterators/package.json +++ b/packages/iterators/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/iterators", "version": "4.2.4", "description": "clojure.core inspired, composable ES6 iterators & generators", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module iterators api dcons errors", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -45,5 +49,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/iterators/src/dedupe-with.ts b/packages/iterators/src/dedupe-with.ts index 7e3f603e24..45a6431d57 100644 --- a/packages/iterators/src/dedupe-with.ts +++ b/packages/iterators/src/dedupe-with.ts @@ -1,5 +1,4 @@ -import { Predicate2 } from "@thi.ng/api/api"; - +import { Predicate2 } from "@thi.ng/api"; import { iterator } from "./iterator"; export function* dedupeWith(equiv: Predicate2, input: Iterable) { diff --git a/packages/iterators/src/drop-while.ts b/packages/iterators/src/drop-while.ts index b3711238b1..21d94b41c7 100644 --- a/packages/iterators/src/drop-while.ts +++ b/packages/iterators/src/drop-while.ts @@ -1,5 +1,4 @@ -import { Predicate } from "@thi.ng/api/api"; - +import { Predicate } from "@thi.ng/api"; import { ensureIterator } from "./ensure"; export function* dropWhile(pred: Predicate, input: Iterable) { diff --git a/packages/iterators/src/ensure.ts b/packages/iterators/src/ensure.ts index e4a2171a25..6dfe8a38f1 100644 --- a/packages/iterators/src/ensure.ts +++ b/packages/iterators/src/ensure.ts @@ -1,5 +1,4 @@ -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; - +import { illegalArgs } from "@thi.ng/errors"; import { iterator } from "./iterator"; export const ensureIterable = diff --git a/packages/iterators/src/every.ts b/packages/iterators/src/every.ts index 241e5a3907..c63a6cfe98 100644 --- a/packages/iterators/src/every.ts +++ b/packages/iterators/src/every.ts @@ -1,5 +1,4 @@ -import { Predicate } from "@thi.ng/api/api"; - +import { Predicate } from "@thi.ng/api"; import { iterator } from "./iterator"; export const every = diff --git a/packages/iterators/src/filter.ts b/packages/iterators/src/filter.ts index 91b41b5332..566c288ee5 100644 --- a/packages/iterators/src/filter.ts +++ b/packages/iterators/src/filter.ts @@ -1,5 +1,4 @@ -import { Predicate } from "@thi.ng/api/api"; - +import { Predicate } from "@thi.ng/api"; import { iterator } from "./iterator"; export function* filter(pred: Predicate, input: Iterable) { diff --git a/packages/iterators/src/fork.ts b/packages/iterators/src/fork.ts index 4c083db35f..54e80ab5bc 100644 --- a/packages/iterators/src/fork.ts +++ b/packages/iterators/src/fork.ts @@ -1,5 +1,4 @@ import { DCons } from "@thi.ng/dcons"; - import { iterator } from "./iterator"; export const fork = diff --git a/packages/iterators/src/interleave.ts b/packages/iterators/src/interleave.ts index bc830f399b..890c10a828 100644 --- a/packages/iterators/src/interleave.ts +++ b/packages/iterators/src/interleave.ts @@ -1,5 +1,4 @@ -import { illegalArity } from "@thi.ng/errors/illegal-arity"; - +import { illegalArity } from "@thi.ng/errors"; import { cycle } from "./cycle"; import { iterator } from "./iterator"; import { map } from "./map"; diff --git a/packages/iterators/src/partition.ts b/packages/iterators/src/partition.ts index 0a5e110e79..ed8fdfa439 100644 --- a/packages/iterators/src/partition.ts +++ b/packages/iterators/src/partition.ts @@ -1,5 +1,4 @@ -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; - +import { illegalArgs } from "@thi.ng/errors"; import { consume } from "./consume"; import { iterator } from "./iterator"; diff --git a/packages/iterators/src/some.ts b/packages/iterators/src/some.ts index a526f90ceb..21490541c6 100644 --- a/packages/iterators/src/some.ts +++ b/packages/iterators/src/some.ts @@ -1,5 +1,4 @@ -import { Predicate } from "@thi.ng/api/api"; - +import { Predicate } from "@thi.ng/api"; import { iterator } from "./iterator"; export const some = diff --git a/packages/iterators/src/take-while.ts b/packages/iterators/src/take-while.ts index e7dcfc106c..5390b8953b 100644 --- a/packages/iterators/src/take-while.ts +++ b/packages/iterators/src/take-while.ts @@ -1,5 +1,4 @@ -import { Predicate } from "@thi.ng/api/api"; - +import { Predicate } from "@thi.ng/api"; import { iterator } from "./iterator"; export function* takeWhile(pred: Predicate, input: Iterable) { diff --git a/packages/iterators/src/walk.ts b/packages/iterators/src/walk.ts index af21b87c15..177dd4fec5 100644 --- a/packages/iterators/src/walk.ts +++ b/packages/iterators/src/walk.ts @@ -1,6 +1,6 @@ +import { Fn } from "@thi.ng/api"; import { iterator, maybeIterator } from "./iterator"; import { maybeObjectIterator } from "./object-iterator"; -import { Fn } from "@thi.ng/api/api"; export const walkable = (x) => diff --git a/packages/iterators/test/tsconfig.json b/packages/iterators/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/iterators/test/tsconfig.json +++ b/packages/iterators/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/malloc/package.json b/packages/malloc/package.json index 3ea6a55f0d..2fff668e8a 100644 --- a/packages/malloc/package.json +++ b/packages/malloc/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/malloc", "version": "0.2.1", "description": "ArrayBuffer based malloc() impl for hybrid JS/WASM use cases, based on thi.ng/tinyalloc", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module malloc api binary checks errors", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -39,5 +43,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/malloc/src/index.ts b/packages/malloc/src/index.ts index b99cca4c6f..067f6e8cf3 100644 --- a/packages/malloc/src/index.ts +++ b/packages/malloc/src/index.ts @@ -1,7 +1,7 @@ import { IObjectOf, IRelease, TypedArray } from "@thi.ng/api"; -import { align } from "@thi.ng/binary/align"; -import { isNumber } from "@thi.ng/checks/is-number"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { align } from "@thi.ng/binary"; +import { isNumber } from "@thi.ng/checks"; +import { illegalArgs } from "@thi.ng/errors"; export const enum Type { U8, diff --git a/packages/malloc/test/tsconfig.json b/packages/malloc/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/malloc/test/tsconfig.json +++ b/packages/malloc/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/math/package.json b/packages/math/package.json index ce3f6a78f6..a7becea398 100644 --- a/packages/math/package.json +++ b/packages/math/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/math", "version": "0.2.2", "description": "Assorted common math functions & utilities", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module math", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -38,5 +42,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/math/test/tsconfig.json b/packages/math/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/math/test/tsconfig.json +++ b/packages/math/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/memoize/package.json b/packages/memoize/package.json index 16051bbd60..c3743dea12 100644 --- a/packages/memoize/package.json +++ b/packages/memoize/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/memoize", "version": "0.2.6", "description": "Function memoization with configurable caches", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module memoize api", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -39,5 +43,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/memoize/src/defonce.ts b/packages/memoize/src/defonce.ts index 9af67bbe56..cf28036be7 100644 --- a/packages/memoize/src/defonce.ts +++ b/packages/memoize/src/defonce.ts @@ -1,4 +1,4 @@ -import { Fn0 } from "@thi.ng/memoize/src/api"; +import { Fn0 } from "./api"; const cache: any = {}; diff --git a/packages/memoize/src/memoizej.ts b/packages/memoize/src/memoizej.ts index e3cb361313..cb7508be4e 100644 --- a/packages/memoize/src/memoizej.ts +++ b/packages/memoize/src/memoizej.ts @@ -1,4 +1,4 @@ -import { IObjectOf } from "@thi.ng/api/api"; +import { IObjectOf } from "@thi.ng/api"; import { Fn1, Fn2, Fn3, Fn4, FnAny } from "./api"; /** diff --git a/packages/memoize/test/tsconfig.json b/packages/memoize/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/memoize/test/tsconfig.json +++ b/packages/memoize/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/morton/package.json b/packages/morton/package.json index 2985274ac8..9e51bf51b3 100644 --- a/packages/morton/package.json +++ b/packages/morton/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/morton", "version": "0.2.2", "description": "Z-order-curve / Morton encoding & decoding for 1D, 2D, 3D", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module morton binary errors math", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -43,5 +47,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/morton/src/index.ts b/packages/morton/src/index.ts index c368dea5b7..8cc52f4ce5 100644 --- a/packages/morton/src/index.ts +++ b/packages/morton/src/index.ts @@ -1,8 +1,6 @@ -import { MASKS } from "@thi.ng/binary/api"; -import { ceilPow2 } from "@thi.ng/binary/pow"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { fit, fit01 } from "@thi.ng/math/fit"; -import { inRange } from "@thi.ng/math/interval"; +import { ceilPow2, MASKS } from "@thi.ng/binary"; +import { illegalArgs } from "@thi.ng/errors"; +import { fit, fit01, inRange } from "@thi.ng/math"; const MIN = [0, 0, 0]; const MAX = [1, 1, 1]; diff --git a/packages/morton/test/tsconfig.json b/packages/morton/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/morton/test/tsconfig.json +++ b/packages/morton/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/paths/package.json b/packages/paths/package.json index 87e88244f9..4812cd6513 100644 --- a/packages/paths/package.json +++ b/packages/paths/package.json @@ -4,6 +4,7 @@ "description": "immutable, optimized path-based object property / array accessors", "module": "./index.js", "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -13,13 +14,11 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && yarn build:es6 && yarn build:parcel && yarn build:parcel:min", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", "build:es6": "tsc --declaration", - "build:parcel:min": "parcel build --global thing_paths -o index.min.js -d lib --experimental-scope-hoisting src/index.ts", - "build:parcel": "parcel build --global thing_paths -d lib --no-minify --experimental-scope-hoisting src/index.ts && prettier --write lib/index.js", - "build:gzip": "gzip -c lib/index.min.js > lib/index.min.js.gz", - "clean": "rimraf *.js *.d.ts .cache .nyc_output build coverage doc lib", - "test": "rimraf build && parcel build -d build --no-cache --no-minify test/index.ts && nyc mocha build/index.js", + "build:bundle": "../../scripts/bundle-module paths checks errors", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public" @@ -60,5 +59,6 @@ "browser": { "process": false, "setTimeout": false - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/paths/src/index.ts b/packages/paths/src/index.ts index 7ee36b787a..f7efef715a 100644 --- a/packages/paths/src/index.ts +++ b/packages/paths/src/index.ts @@ -1,5 +1,5 @@ -import { isString } from "@thi.ng/checks/is-string"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { isString } from "@thi.ng/checks"; +import { illegalArgs } from "@thi.ng/errors"; export type Path = PropertyKey | PropertyKey[]; diff --git a/packages/paths/test/tsconfig.json b/packages/paths/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/paths/test/tsconfig.json +++ b/packages/paths/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/pointfree-lang/package.json b/packages/pointfree-lang/package.json index 978992ce77..5a1eb51432 100644 --- a/packages/pointfree-lang/package.json +++ b/packages/pointfree-lang/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/pointfree-lang", "version": "0.2.27", "description": "Forth style syntax layer/compiler for the @thi.ng/pointfree DSL", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,20 +14,22 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration && yarn peg", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration && yarn peg", + "build:bundle": "../../scripts/bundle-module pointfree-lang api errors pointfree", + "test": "rimraf build && tsc -p test/tsconfig.json && yarn pegtest && nyc mocha build/test/*.js", + "peg": "pegjs -f es -o parser.js src/grammar.pegjs", + "pegtest": "pegjs -o build/src/parser.js src/grammar.pegjs", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "peg": "pegjs -o parser.js src/grammar.pegjs", - "pegtest": "pegjs -o build/src/parser.js src/grammar.pegjs", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && yarn pegtest && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", - "pegjs": "^0.10.0", + "pegjs": "^0.11.0-dev.325", "typedoc": "^0.14.0", "typescript": "^3.2.2" }, @@ -49,5 +53,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/pointfree-lang/src/index.ts b/packages/pointfree-lang/src/index.ts index 18035ecbcd..cf217b2987 100644 --- a/packages/pointfree-lang/src/index.ts +++ b/packages/pointfree-lang/src/index.ts @@ -1,6 +1,5 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { illegalState } from "@thi.ng/errors/illegal-state"; +import { IObjectOf } from "@thi.ng/api"; +import { illegalArgs, illegalState } from "@thi.ng/errors"; import * as pf from "@thi.ng/pointfree"; import { diff --git a/packages/pointfree-lang/test/tsconfig.json b/packages/pointfree-lang/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/pointfree-lang/test/tsconfig.json +++ b/packages/pointfree-lang/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/pointfree/package.json b/packages/pointfree/package.json index b386e0f8f1..1014a41bef 100644 --- a/packages/pointfree/package.json +++ b/packages/pointfree/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/pointfree", "version": "0.8.15", "description": "Pointfree functional composition / Forth style stack execution engine", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module pointfree api checks compose equiv errors", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -50,5 +54,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/pointfree/src/index.ts b/packages/pointfree/src/index.ts index bd97041471..9c816b4e44 100644 --- a/packages/pointfree/src/index.ts +++ b/packages/pointfree/src/index.ts @@ -1,11 +1,8 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { isArray } from "@thi.ng/checks/is-array"; -import { isFunction } from "@thi.ng/checks/is-function"; -import { isPlainObject } from "@thi.ng/checks/is-plain-object"; -import { compL } from "@thi.ng/compose/comp"; +import { IObjectOf } from "@thi.ng/api"; +import { isArray, isFunction, isPlainObject } from "@thi.ng/checks"; +import { compL } from "@thi.ng/compose"; import { equiv as _equiv } from "@thi.ng/equiv"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { illegalState } from "@thi.ng/errors/illegal-state"; +import { illegalArgs, illegalState } from "@thi.ng/errors"; import { Stack, StackContext, @@ -15,7 +12,6 @@ import { StackProgram } from "./api"; - let SAFE = true; export const safeMode = (state: boolean) => (SAFE = state); diff --git a/packages/pointfree/test/tsconfig.json b/packages/pointfree/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/pointfree/test/tsconfig.json +++ b/packages/pointfree/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/random/package.json b/packages/random/package.json index 7761a15324..0c917cb8f9 100644 --- a/packages/random/package.json +++ b/packages/random/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/random", "version": "0.1.1", "description": "Pseudo-random number generators w/ unified API", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module random api", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -39,5 +43,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/random/src/api.ts b/packages/random/src/api.ts index 078cc71f35..3cc92b0296 100644 --- a/packages/random/src/api.ts +++ b/packages/random/src/api.ts @@ -1,4 +1,4 @@ -import { ICopy } from "@thi.ng/api/api"; +import { ICopy } from "@thi.ng/api"; export interface IRandom { int(): number; diff --git a/packages/random/src/smush32.ts b/packages/random/src/smush32.ts index 48cf7df311..0cf7a3f2e3 100644 --- a/packages/random/src/smush32.ts +++ b/packages/random/src/smush32.ts @@ -1,4 +1,4 @@ -import { IBuffered, ICopy } from "@thi.ng/api/api"; +import { IBuffered, ICopy } from "@thi.ng/api"; import { ARandom, ISeedable } from "./api"; // https://github.com/thi-ng/ct-head/blob/master/random.h diff --git a/packages/random/src/xorshift128.ts b/packages/random/src/xorshift128.ts index f30f24f21c..ef36fd480b 100644 --- a/packages/random/src/xorshift128.ts +++ b/packages/random/src/xorshift128.ts @@ -1,4 +1,4 @@ -import { IBuffered, ICopy } from "@thi.ng/api/api"; +import { IBuffered, ICopy } from "@thi.ng/api"; import { ARandom, ISeedable } from "./api"; // https://en.wikipedia.org/wiki/Xorshift diff --git a/packages/random/src/xorwow.ts b/packages/random/src/xorwow.ts index 8ac281751b..2fb7f3635a 100644 --- a/packages/random/src/xorwow.ts +++ b/packages/random/src/xorwow.ts @@ -1,4 +1,4 @@ -import { IBuffered, ICopy } from "@thi.ng/api/api"; +import { IBuffered, ICopy } from "@thi.ng/api"; import { ARandom, ISeedable } from "./api"; // https://en.wikipedia.org/wiki/Xorshift#xorwow diff --git a/packages/random/src/xsadd.ts b/packages/random/src/xsadd.ts index 2bf75a106f..479416e8ee 100644 --- a/packages/random/src/xsadd.ts +++ b/packages/random/src/xsadd.ts @@ -1,4 +1,4 @@ -import { IBuffered, ICopy } from "@thi.ng/api/api"; +import { IBuffered, ICopy } from "@thi.ng/api"; import { ARandom, ISeedable } from "./api"; // https://github.com/MersenneTwister-Lab/XSadd/blob/master/xsadd.h diff --git a/packages/random/test/tsconfig.json b/packages/random/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/random/test/tsconfig.json +++ b/packages/random/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/range-coder/package.json b/packages/range-coder/package.json index fe7fe12408..262d62bf26 100644 --- a/packages/range-coder/package.json +++ b/packages/range-coder/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/range-coder", "version": "0.1.28", "description": "Binary data range encoder / decoder", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module rangeCoder bitstream", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@thi.ng/transducers": "^2.3.2", @@ -41,5 +45,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/range-coder/test/index.ts b/packages/range-coder/test/index.ts index 1c9d6abba8..3709477bdd 100644 --- a/packages/range-coder/test/index.ts +++ b/packages/range-coder/test/index.ts @@ -21,6 +21,6 @@ describe("range-coder", () => { }); }); -function randomArray(n: number, len: number) { - return new Uint8Array([...repeatedly(() => ~~(Math.random() * 256), n), ...repeat(0, len - n)]); -} +const randomArray = + (n: number, len: number) => + new Uint8Array([...repeatedly(() => ~~(Math.random() * 256), n), ...repeat(0, len - n)]); diff --git a/packages/range-coder/test/tsconfig.json b/packages/range-coder/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/range-coder/test/tsconfig.json +++ b/packages/range-coder/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/resolve-map/package.json b/packages/resolve-map/package.json index 72e8f8ef47..164c9db410 100644 --- a/packages/resolve-map/package.json +++ b/packages/resolve-map/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/resolve-map", "version": "3.0.16", "description": "DAG resolution of vanilla objects & arrays with internally linked values", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,11 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module resolveMap api checks errors paths", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", + "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -26,6 +31,7 @@ "typescript": "^3.2.2" }, "dependencies": { + "@thi.ng/api": "^4.2.4", "@thi.ng/checks": "^1.5.14", "@thi.ng/errors": "^0.1.12", "@thi.ng/paths": "^1.6.6" @@ -41,5 +47,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/resolve-map/src/index.ts b/packages/resolve-map/src/index.ts index e2e14335b9..5e8985a905 100644 --- a/packages/resolve-map/src/index.ts +++ b/packages/resolve-map/src/index.ts @@ -1,9 +1,11 @@ -import { SEMAPHORE } from "@thi.ng/api/api"; -import { isArray } from "@thi.ng/checks/is-array"; -import { isFunction } from "@thi.ng/checks/is-function"; -import { isPlainObject } from "@thi.ng/checks/is-plain-object"; -import { isString } from "@thi.ng/checks/is-string"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { SEMAPHORE } from "@thi.ng/api"; +import { + isArray, + isFunction, + isPlainObject, + isString +} from "@thi.ng/checks"; +import { illegalArgs } from "@thi.ng/errors"; import { exists, getIn, mutIn } from "@thi.ng/paths"; const RE_ARGS = /^(function\s+\w+)?\s*\(\{([\w\s,:]+)\}/ diff --git a/packages/resolve-map/test/tsconfig.json b/packages/resolve-map/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/resolve-map/test/tsconfig.json +++ b/packages/resolve-map/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/rle-pack/package.json b/packages/rle-pack/package.json index a6ad426339..2f89c6a710 100644 --- a/packages/rle-pack/package.json +++ b/packages/rle-pack/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/rle-pack", "version": "1.0.8", "description": "Binary run-length encoding packer w/ flexible repeat bit widths", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module rlePack bitstream errors", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -35,12 +39,17 @@ "keywords": [ "binary", "bits", + "compression", "ES6", "packer", "RLE", - "typescript" + "run-length", + "typescript", + "variable width", + "wordsize" ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/rle-pack/src/index.ts b/packages/rle-pack/src/index.ts index deeae4cb88..e665c8c04f 100644 --- a/packages/rle-pack/src/index.ts +++ b/packages/rle-pack/src/index.ts @@ -1,5 +1,5 @@ import { BitInputStream, BitOutputStream } from "@thi.ng/bitstream"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { illegalArgs } from "@thi.ng/errors"; export type RLESizes = [number, number, number, number]; diff --git a/packages/rle-pack/test/tsconfig.json b/packages/rle-pack/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/rle-pack/test/tsconfig.json +++ b/packages/rle-pack/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/router/package.json b/packages/router/package.json index 39713d7e6f..d2eda13522 100644 --- a/packages/router/package.json +++ b/packages/router/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/router", "version": "0.1.30", "description": "Generic router for browser & non-browser based applications", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,11 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module router api checks equiv errors", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", + "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -33,16 +38,20 @@ "@thi.ng/errors": "^0.1.12" }, "keywords": [ + "browser", "declarative", "ES6", "html", "history", "parametric", "router", + "SPA", "typescript", - "validation" + "validation", + "UI" ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/router/src/api.ts b/packages/router/src/api.ts index 05077031cc..40269510ff 100644 --- a/packages/router/src/api.ts +++ b/packages/router/src/api.ts @@ -1,4 +1,4 @@ -import { IID, IObjectOf } from "@thi.ng/api/api"; +import { IID, IObjectOf } from "@thi.ng/api"; /** * A validation function to for authenticated routes. If this function diff --git a/packages/router/src/basic.ts b/packages/router/src/basic.ts index 6a0082ebd3..a03e628fa7 100644 --- a/packages/router/src/basic.ts +++ b/packages/router/src/basic.ts @@ -1,15 +1,13 @@ import { Event, INotify, + INotifyMixin, IObjectOf, Listener -} from "@thi.ng/api/api"; -import * as mixin from "@thi.ng/api/mixins/inotify"; -import { isString } from "@thi.ng/checks/is-string"; +} from "@thi.ng/api"; +import { isString } from "@thi.ng/checks"; import { equiv } from "@thi.ng/equiv"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { illegalArity } from "@thi.ng/errors/illegal-arity"; - +import { illegalArgs, illegalArity } from "@thi.ng/errors"; import { EVENT_ROUTE_CHANGED, Route, @@ -18,7 +16,7 @@ import { RouterConfig } from "./api"; -@mixin.INotify +@INotifyMixin export class BasicRouter implements INotify { diff --git a/packages/router/src/history.ts b/packages/router/src/history.ts index 0a9b650adf..b6dfdb8245 100644 --- a/packages/router/src/history.ts +++ b/packages/router/src/history.ts @@ -1,7 +1,6 @@ +import { isString } from "@thi.ng/checks"; import { equiv } from "@thi.ng/equiv"; import { illegalArity } from "@thi.ng/errors"; -import { isString } from "@thi.ng/checks/is-string"; - import { HTMLRouterConfig, RouteMatch, RouterConfig } from "./api"; import { BasicRouter } from "./basic"; diff --git a/packages/router/test/tsconfig.json b/packages/router/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/router/test/tsconfig.json +++ b/packages/router/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/sax/package.json b/packages/sax/package.json index 69fce5f6a6..0b655adc84 100644 --- a/packages/sax/package.json +++ b/packages/sax/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/sax", "version": "0.5.13", "description": "Transducer-based, SAX-like, non-validating, speedy & tiny XML parser", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module sax api transducers transducers-fsm", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib internal", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -43,5 +47,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/sax/src/index.ts b/packages/sax/src/index.ts index 4765924d6b..4d04b26c61 100644 --- a/packages/sax/src/index.ts +++ b/packages/sax/src/index.ts @@ -1,7 +1,6 @@ import { IObjectOf } from "@thi.ng/api"; +import { $iter, iterator, Transducer } from "@thi.ng/transducers"; import { fsm, FSMState, FSMStateMap } from "@thi.ng/transducers-fsm"; -import { Transducer } from "@thi.ng/transducers/api"; -import { $iter, iterator } from "@thi.ng/transducers/iterator"; export interface ParseOpts { /** diff --git a/packages/sax/test/tsconfig.json b/packages/sax/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/sax/test/tsconfig.json +++ b/packages/sax/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/strings/package.json b/packages/strings/package.json index 8d0f4ca941..d3a8ec684d 100644 --- a/packages/strings/package.json +++ b/packages/strings/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/strings", "version": "0.7.1", "description": "Various string formatting & utility functions", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module strings errors memoize", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -32,16 +36,28 @@ "@thi.ng/memoize": "^0.2.6" }, "keywords": [ + "composition", "ES6", + "camelcase", + "center", + "float", "format", "functional", + "hex", "higher order", - "padding", + "kebabcase", "number", + "padding", + "percent", + "radix", + "slugify", + "snakecase", "string", - "typescript" + "typescript", + "wordwrap" ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/strings/src/center.ts b/packages/strings/src/center.ts index a2a6597b5c..261b2da014 100644 --- a/packages/strings/src/center.ts +++ b/packages/strings/src/center.ts @@ -1,4 +1,4 @@ -import { memoizeJ } from "@thi.ng/memoize/memoizej"; +import { memoizeJ } from "@thi.ng/memoize"; import { Stringer } from "./api"; import { repeat } from "./repeat"; diff --git a/packages/strings/src/float.ts b/packages/strings/src/float.ts index 5b8d2f71d6..f85b028c35 100644 --- a/packages/strings/src/float.ts +++ b/packages/strings/src/float.ts @@ -1,4 +1,4 @@ -import { memoizeJ } from "@thi.ng/memoize/memoizej"; +import { memoizeJ } from "@thi.ng/memoize"; import { Stringer } from "./api"; diff --git a/packages/strings/src/format.ts b/packages/strings/src/format.ts index cb3f15c0c9..0b675165a6 100644 --- a/packages/strings/src/format.ts +++ b/packages/strings/src/format.ts @@ -1,15 +1,16 @@ -export const format = (fmt: any[], ...args: any[]) => { - const acc: any[] = []; - for (let i = 0, j = 0, n = fmt.length; i < n; i++) { - const f = fmt[i]; - const t = typeof f; - acc.push( - t === "function" ? - f(args[j++]) : - t === "object" ? - f[args[j++]] : - f - ); - } - return acc.join(""); -}; +export const format = + (fmt: any[], ...args: any[]) => { + const acc: any[] = []; + for (let i = 0, j = 0, n = fmt.length; i < n; i++) { + const f = fmt[i]; + const t = typeof f; + acc.push( + t === "function" ? + f(args[j++]) : + t === "object" ? + f[args[j++]] : + f + ); + } + return acc.join(""); + }; diff --git a/packages/strings/src/pad-left.ts b/packages/strings/src/pad-left.ts index 9f77c0153f..489a77ba46 100644 --- a/packages/strings/src/pad-left.ts +++ b/packages/strings/src/pad-left.ts @@ -1,4 +1,4 @@ -import { memoizeJ } from "@thi.ng/memoize/memoizej"; +import { memoizeJ } from "@thi.ng/memoize"; import { Stringer } from "./api"; import { repeat } from "./repeat"; diff --git a/packages/strings/src/pad-right.ts b/packages/strings/src/pad-right.ts index 2b2ff2e29f..73daa72358 100644 --- a/packages/strings/src/pad-right.ts +++ b/packages/strings/src/pad-right.ts @@ -1,4 +1,4 @@ -import { memoizeJ } from "@thi.ng/memoize/memoizej"; +import { memoizeJ } from "@thi.ng/memoize"; import { Stringer } from "./api"; import { repeat } from "./repeat"; diff --git a/packages/strings/src/parse.ts b/packages/strings/src/parse.ts index ada5e7bae6..86ada2b373 100644 --- a/packages/strings/src/parse.ts +++ b/packages/strings/src/parse.ts @@ -1,9 +1,11 @@ -export const maybeParseInt = (x: string, defaultVal: any = 0, radix = 10) => { - const n = parseInt(x, radix); - return isNaN(n) ? defaultVal : n; -}; +export const maybeParseInt = + (x: string, defaultVal: any = 0, radix = 10) => { + const n = parseInt(x, radix); + return isNaN(n) ? defaultVal : n; + }; -export const maybeParseFloat = (x: string, defaultVal: any = 0) => { - const n = parseFloat(x); - return isNaN(n) ? defaultVal : n; -}; +export const maybeParseFloat = + (x: string, defaultVal: any = 0) => { + const n = parseFloat(x); + return isNaN(n) ? defaultVal : n; + }; diff --git a/packages/strings/src/percent.ts b/packages/strings/src/percent.ts index cd6bd93645..fb1baf6e9d 100644 --- a/packages/strings/src/percent.ts +++ b/packages/strings/src/percent.ts @@ -6,5 +6,6 @@ import { Stringer } from "./api"; * * @param prec number of fractional digits (default: 0) */ -export const percent = (prec = 0): Stringer => - (x: number) => (x * 100).toFixed(prec) + "%"; +export const percent = + (prec = 0): Stringer => + (x: number) => (x * 100).toFixed(prec) + "%"; diff --git a/packages/strings/src/radix.ts b/packages/strings/src/radix.ts index fd3a84c46b..d404d748cc 100644 --- a/packages/strings/src/radix.ts +++ b/packages/strings/src/radix.ts @@ -1,5 +1,4 @@ -import { memoizeJ } from "@thi.ng/memoize/memoizej"; - +import { memoizeJ } from "@thi.ng/memoize"; import { Stringer } from "./api"; import { repeat } from "./repeat"; diff --git a/packages/strings/src/repeat.ts b/packages/strings/src/repeat.ts index 86738ee717..9813e2aa67 100644 --- a/packages/strings/src/repeat.ts +++ b/packages/strings/src/repeat.ts @@ -1,4 +1,4 @@ -import { memoizeJ } from "@thi.ng/memoize/memoizej"; +import { memoizeJ } from "@thi.ng/memoize"; /** * @param ch character diff --git a/packages/strings/src/splice.ts b/packages/strings/src/splice.ts index 7aa846314d..8b2f809fed 100644 --- a/packages/strings/src/splice.ts +++ b/packages/strings/src/splice.ts @@ -1,4 +1,4 @@ -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { illegalArgs } from "@thi.ng/errors"; /** * Forms a new strings which inserts given `insert` string into `src` @@ -13,20 +13,21 @@ import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; * @param from * @param to */ -export const splice = (src: string, insert: string, from: number, to = from) => { - if (from < 0) { - from += src.length; - } - if (to < 0) { - to += src.length; - } - if (from > to) { - illegalArgs("'from' index must be <= 'to'"); - } - to = Math.max(to, 0); - return from <= 0 ? - insert + src.substr(to) : - from >= src.length ? - src + insert : - src.substr(0, from) + insert + src.substr(to); -}; +export const splice = + (src: string, insert: string, from: number, to = from) => { + if (from < 0) { + from += src.length; + } + if (to < 0) { + to += src.length; + } + if (from > to) { + illegalArgs("'from' index must be <= 'to'"); + } + to = Math.max(to, 0); + return from <= 0 ? + insert + src.substr(to) : + from >= src.length ? + src + insert : + src.substr(0, from) + insert + src.substr(to); + }; diff --git a/packages/strings/src/truncate-left.ts b/packages/strings/src/truncate-left.ts index 27f0d44371..2534290364 100644 --- a/packages/strings/src/truncate-left.ts +++ b/packages/strings/src/truncate-left.ts @@ -1,5 +1,4 @@ -import { memoizeJ } from "@thi.ng/memoize/memoizej"; - +import { memoizeJ } from "@thi.ng/memoize"; import { Stringer } from "./api"; export const truncateLeft: (n: number, prefix?: string) => Stringer = diff --git a/packages/strings/src/truncate.ts b/packages/strings/src/truncate.ts index c470a25fd1..b4030b9461 100644 --- a/packages/strings/src/truncate.ts +++ b/packages/strings/src/truncate.ts @@ -1,5 +1,4 @@ -import { memoizeJ } from "@thi.ng/memoize/memoizej"; - +import { memoizeJ } from "@thi.ng/memoize"; import { Stringer } from "./api"; export const truncate: (n: number, suffix?: string) => Stringer = diff --git a/packages/strings/src/units.ts b/packages/strings/src/units.ts index efac24e8c9..3e6674f61f 100644 --- a/packages/strings/src/units.ts +++ b/packages/strings/src/units.ts @@ -1,5 +1,4 @@ -import { memoizeJ } from "@thi.ng/memoize/memoizej"; - +import { memoizeJ } from "@thi.ng/memoize"; import { Stringer } from "./api"; export const units: (exp: [number, string, number?][], base: string, prec?: number) => Stringer = diff --git a/packages/strings/src/wrap.ts b/packages/strings/src/wrap.ts index 95df096538..3fc08f4af4 100644 --- a/packages/strings/src/wrap.ts +++ b/packages/strings/src/wrap.ts @@ -1,5 +1,4 @@ -import { memoizeJ } from "@thi.ng/memoize/memoizej"; - +import { memoizeJ } from "@thi.ng/memoize"; import { Stringer } from "./api"; /** diff --git a/packages/strings/test/tsconfig.json b/packages/strings/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/strings/test/tsconfig.json +++ b/packages/strings/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/transducers-fsm/package.json b/packages/transducers-fsm/package.json index 95855071d9..115c279295 100644 --- a/packages/transducers-fsm/package.json +++ b/packages/transducers-fsm/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/transducers-fsm", "version": "0.2.36", "description": "Transducer-based Finite State Machine transformer", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module transducersFsm api transducers", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -40,5 +44,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/transducers-fsm/src/index.ts b/packages/transducers-fsm/src/index.ts index b11e2b44c9..32f024b832 100644 --- a/packages/transducers-fsm/src/index.ts +++ b/packages/transducers-fsm/src/index.ts @@ -1,8 +1,12 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { Reducer, Transducer } from "@thi.ng/transducers/api"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { compR } from "@thi.ng/transducers/func/compr"; -import { ensureReduced, isReduced } from "@thi.ng/transducers/reduced"; +import { IObjectOf } from "@thi.ng/api"; +import { + comp, + compR, + ensureReduced, + isReduced, + Reducer, + Transducer +} from "@thi.ng/transducers"; export interface FSMState { state: PropertyKey; diff --git a/packages/transducers-fsm/test/tsconfig.json b/packages/transducers-fsm/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/transducers-fsm/test/tsconfig.json +++ b/packages/transducers-fsm/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/transducers-hdom/test/tsconfig.json b/packages/transducers-hdom/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/transducers-hdom/test/tsconfig.json +++ b/packages/transducers-hdom/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/transducers-stats/package.json b/packages/transducers-stats/package.json index fa1b6b3414..852f154157 100644 --- a/packages/transducers-stats/package.json +++ b/packages/transducers-stats/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/transducers-stats", "version": "0.4.23", "description": "Transducers for statistical / technical analysis", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module transducersStats checks dcons errors transducers", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -28,6 +32,7 @@ "typescript": "^3.2.2" }, "dependencies": { + "@thi.ng/checks": "^1.5.14", "@thi.ng/dcons": "^1.1.23", "@thi.ng/errors": "^0.1.12", "@thi.ng/transducers": "^2.3.2" @@ -38,5 +43,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/transducers-stats/src/bollinger.ts b/packages/transducers-stats/src/bollinger.ts index 944547f04e..830362fe96 100644 --- a/packages/transducers-stats/src/bollinger.ts +++ b/packages/transducers-stats/src/bollinger.ts @@ -1,11 +1,12 @@ -import { Transducer } from "@thi.ng/transducers/api"; -import { $iter } from "@thi.ng/transducers/iterator"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { drop } from "@thi.ng/transducers/xform/drop"; -import { map } from "@thi.ng/transducers/xform/map"; -import { multiplex } from "@thi.ng/transducers/xform/multiplex"; -import { partition } from "@thi.ng/transducers/xform/partition"; - +import { + $iter, + comp, + drop, + map, + multiplex, + partition, + Transducer +} from "@thi.ng/transducers"; import { mse } from "./mse"; import { sma } from "./sma"; diff --git a/packages/transducers-stats/src/donchian.ts b/packages/transducers-stats/src/donchian.ts index 10dc29094c..460e16494e 100644 --- a/packages/transducers-stats/src/donchian.ts +++ b/packages/transducers-stats/src/donchian.ts @@ -1,9 +1,10 @@ -import { Transducer } from "@thi.ng/transducers/api"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { iterator } from "@thi.ng/transducers/iterator"; -import { map } from "@thi.ng/transducers/xform/map"; -import { partition } from "@thi.ng/transducers/xform/partition"; - +import { + comp, + iterator, + map, + partition, + Transducer +} from "@thi.ng/transducers"; import { bounds } from "./bounds"; /** diff --git a/packages/transducers-stats/src/ema.ts b/packages/transducers-stats/src/ema.ts index 005e5f62fa..406e1507a3 100644 --- a/packages/transducers-stats/src/ema.ts +++ b/packages/transducers-stats/src/ema.ts @@ -1,7 +1,10 @@ -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { Reducer, Transducer } from "@thi.ng/transducers/api"; -import { compR } from "@thi.ng/transducers/func/compr"; -import { iterator1 } from "@thi.ng/transducers/iterator"; +import { illegalArgs } from "@thi.ng/errors"; +import { + compR, + iterator1, + Reducer, + Transducer +} from "@thi.ng/transducers"; /** * https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average diff --git a/packages/transducers-stats/src/hma.ts b/packages/transducers-stats/src/hma.ts index ab70bd4282..4c80ab79a7 100644 --- a/packages/transducers-stats/src/hma.ts +++ b/packages/transducers-stats/src/hma.ts @@ -1,10 +1,11 @@ -import { Transducer } from "@thi.ng/transducers/api"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { iterator1 } from "@thi.ng/transducers/iterator"; -import { drop } from "@thi.ng/transducers/xform/drop"; -import { map } from "@thi.ng/transducers/xform/map"; -import { multiplex } from "@thi.ng/transducers/xform/multiplex"; - +import { + comp, + drop, + iterator1, + map, + multiplex, + Transducer +} from "@thi.ng/transducers"; import { wma } from "./wma"; /** diff --git a/packages/transducers-stats/src/macd.ts b/packages/transducers-stats/src/macd.ts index c6206d4eb7..f98989d7da 100644 --- a/packages/transducers-stats/src/macd.ts +++ b/packages/transducers-stats/src/macd.ts @@ -1,8 +1,10 @@ -import { Reducer, Transducer } from "@thi.ng/transducers/api"; -import { compR } from "@thi.ng/transducers/func/compr"; -import { $iter } from "@thi.ng/transducers/iterator"; -import { step } from "@thi.ng/transducers/step"; - +import { + $iter, + compR, + Reducer, + step, + Transducer +} from "@thi.ng/transducers"; import { ema } from "./ema"; export interface MACD { diff --git a/packages/transducers-stats/src/momentum.ts b/packages/transducers-stats/src/momentum.ts index 5273474dad..492fc7146e 100644 --- a/packages/transducers-stats/src/momentum.ts +++ b/packages/transducers-stats/src/momentum.ts @@ -1,8 +1,11 @@ import { DCons } from "@thi.ng/dcons"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { Reducer, Transducer } from "@thi.ng/transducers/api"; -import { compR } from "@thi.ng/transducers/func/compr"; -import { iterator1 } from "@thi.ng/transducers/iterator"; +import { illegalArgs } from "@thi.ng/errors"; +import { + compR, + iterator1, + Reducer, + Transducer +} from "@thi.ng/transducers"; /** * https://en.wikipedia.org/wiki/Momentum_(technical_analysis) diff --git a/packages/transducers-stats/src/roc.ts b/packages/transducers-stats/src/roc.ts index b20dbf464a..18ae1fea0a 100644 --- a/packages/transducers-stats/src/roc.ts +++ b/packages/transducers-stats/src/roc.ts @@ -1,8 +1,11 @@ import { DCons } from "@thi.ng/dcons"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { Reducer, Transducer } from "@thi.ng/transducers/api"; -import { compR } from "@thi.ng/transducers/func/compr"; -import { iterator1 } from "@thi.ng/transducers/iterator"; +import { illegalArgs } from "@thi.ng/errors"; +import { + compR, + iterator1, + Reducer, + Transducer +} from "@thi.ng/transducers"; /** * Rate of change. diff --git a/packages/transducers-stats/src/rsi.ts b/packages/transducers-stats/src/rsi.ts index 0f6fb8e38d..3b1c9427b6 100644 --- a/packages/transducers-stats/src/rsi.ts +++ b/packages/transducers-stats/src/rsi.ts @@ -1,10 +1,11 @@ -import { Transducer } from "@thi.ng/transducers/api"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { iterator1 } from "@thi.ng/transducers/iterator"; -import { drop } from "@thi.ng/transducers/xform/drop"; -import { map } from "@thi.ng/transducers/xform/map"; -import { multiplex } from "@thi.ng/transducers/xform/multiplex"; - +import { + comp, + drop, + iterator1, + map, + multiplex, + Transducer +} from "@thi.ng/transducers"; import { momentum } from "./momentum"; import { sma } from "./sma"; diff --git a/packages/transducers-stats/src/sd.ts b/packages/transducers-stats/src/sd.ts index 7c3ae0df08..99decec5ef 100644 --- a/packages/transducers-stats/src/sd.ts +++ b/packages/transducers-stats/src/sd.ts @@ -1,13 +1,14 @@ -import { Transducer } from "@thi.ng/transducers/api"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { drop } from "@thi.ng/transducers/xform/drop"; -import { map } from "@thi.ng/transducers/xform/map"; -import { multiplex } from "@thi.ng/transducers/xform/multiplex"; -import { partition } from "@thi.ng/transducers/xform/partition"; - +import { + $iter, + comp, + drop, + map, + multiplex, + partition, + Transducer +} from "@thi.ng/transducers"; import { mse } from "./mse"; import { sma } from "./sma"; -import { $iter } from "@thi.ng/transducers/iterator"; /** * Moving standard deviation, calculates mean square error to SMA and diff --git a/packages/transducers-stats/src/sma.ts b/packages/transducers-stats/src/sma.ts index b76353accd..d824082acf 100644 --- a/packages/transducers-stats/src/sma.ts +++ b/packages/transducers-stats/src/sma.ts @@ -1,8 +1,11 @@ import { DCons } from "@thi.ng/dcons"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { Reducer, Transducer } from "@thi.ng/transducers/api"; -import { compR } from "@thi.ng/transducers/func/compr"; -import { iterator1 } from "@thi.ng/transducers/iterator"; +import { illegalArgs } from "@thi.ng/errors"; +import { + compR, + iterator1, + Reducer, + Transducer +} from "@thi.ng/transducers"; /** * Like @thi.ng/transducers `movingAverage`, but using more efficient diff --git a/packages/transducers-stats/src/stochastic.ts b/packages/transducers-stats/src/stochastic.ts index e3c326de89..27d7edcf0e 100644 --- a/packages/transducers-stats/src/stochastic.ts +++ b/packages/transducers-stats/src/stochastic.ts @@ -1,8 +1,10 @@ -import { Reducer, Transducer } from "@thi.ng/transducers/api"; -import { compR } from "@thi.ng/transducers/func/compr"; -import { $iter } from "@thi.ng/transducers/iterator"; -import { step } from "@thi.ng/transducers/step"; - +import { + $iter, + compR, + Reducer, + step, + Transducer +} from "@thi.ng/transducers"; import { donchian } from "./donchian"; import { sma } from "./sma"; diff --git a/packages/transducers-stats/src/trix.ts b/packages/transducers-stats/src/trix.ts index 15222027c8..a66ea94467 100644 --- a/packages/transducers-stats/src/trix.ts +++ b/packages/transducers-stats/src/trix.ts @@ -1,7 +1,4 @@ -import { Transducer } from "@thi.ng/transducers/api"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { iterator1 } from "@thi.ng/transducers/iterator"; - +import { comp, iterator1, Transducer } from "@thi.ng/transducers"; import { ema } from "./ema"; import { roc } from "./roc"; diff --git a/packages/transducers-stats/src/wma.ts b/packages/transducers-stats/src/wma.ts index 8b5c5dea53..93bef142de 100644 --- a/packages/transducers-stats/src/wma.ts +++ b/packages/transducers-stats/src/wma.ts @@ -1,11 +1,12 @@ -import { isNumber } from "@thi.ng/checks/is-number"; -import { Transducer } from "@thi.ng/transducers/api"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { range } from "@thi.ng/transducers/iter/range"; -import { iterator1 } from "@thi.ng/transducers/iterator"; -import { map } from "@thi.ng/transducers/xform/map"; -import { partition } from "@thi.ng/transducers/xform/partition"; - +import { isNumber } from "@thi.ng/checks"; +import { + comp, + iterator1, + map, + partition, + range, + Transducer +} from "@thi.ng/transducers"; import { dot } from "./dot"; /** diff --git a/packages/transducers-stats/test/tsconfig.json b/packages/transducers-stats/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/transducers-stats/test/tsconfig.json +++ b/packages/transducers-stats/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/transducers/package.json b/packages/transducers/package.json index aadb83465a..420e44a7fa 100644 --- a/packages/transducers/package.json +++ b/packages/transducers/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/transducers", "version": "2.3.2", "description": "Lightweight transducer implementations for ES6 / TypeScript", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc func iter rfn xform", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module transducers api checks compare compose equiv errors strings", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib func iter rfn xform", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -37,6 +41,9 @@ "@thi.ng/strings": "^0.7.1" }, "keywords": [ + "array", + "composition", + "data", "ES6", "functional", "generators", @@ -49,5 +56,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/transducers/src/api.ts b/packages/transducers/src/api.ts index b6265e275a..22eed2828c 100644 --- a/packages/transducers/src/api.ts +++ b/packages/transducers/src/api.ts @@ -1,4 +1,4 @@ -import { Comparator, Fn, IObjectOf } from "@thi.ng/api/api"; +import { Comparator, Fn, IObjectOf } from "@thi.ng/api"; import { Reduced } from "./reduced"; diff --git a/packages/transducers/src/func/binary-search.ts b/packages/transducers/src/func/binary-search.ts index 01093cdccf..1e0086b713 100644 --- a/packages/transducers/src/func/binary-search.ts +++ b/packages/transducers/src/func/binary-search.ts @@ -1,4 +1,4 @@ -import { Comparator, Fn } from "@thi.ng/api/api"; +import { Comparator, Fn } from "@thi.ng/api"; /** * Returns the supposed index of `x` in pre-sorted array-like collection diff --git a/packages/transducers/src/func/comp.ts b/packages/transducers/src/func/comp.ts index 8e17710c1c..5f14212095 100644 --- a/packages/transducers/src/func/comp.ts +++ b/packages/transducers/src/func/comp.ts @@ -1,5 +1,4 @@ -import { comp as _comp } from "@thi.ng/compose/comp"; - +import { comp as _comp } from "@thi.ng/compose"; import { Transducer } from "../api"; export function comp(a: Transducer): Transducer; diff --git a/packages/transducers/src/func/deep-transform.ts b/packages/transducers/src/func/deep-transform.ts index 4b78417788..b2fa9e69a6 100644 --- a/packages/transducers/src/func/deep-transform.ts +++ b/packages/transducers/src/func/deep-transform.ts @@ -1,5 +1,4 @@ -import { isFunction } from "@thi.ng/checks/is-function"; - +import { isFunction } from "@thi.ng/checks"; import { TransformSpec } from "../api"; /** diff --git a/packages/transducers/src/func/ensure-array.ts b/packages/transducers/src/func/ensure-array.ts index 94bdbaac25..0de070f414 100644 --- a/packages/transducers/src/func/ensure-array.ts +++ b/packages/transducers/src/func/ensure-array.ts @@ -1,5 +1,4 @@ -import { isArray } from "@thi.ng/checks/is-array"; -import { isArrayLike } from "@thi.ng/checks/is-arraylike"; +import { isArray, isArrayLike } from "@thi.ng/checks"; import { ensureIterable } from "./ensure-iterable"; /** diff --git a/packages/transducers/src/func/ensure-iterable.ts b/packages/transducers/src/func/ensure-iterable.ts index 9a92cc19cc..dd9acf06c5 100644 --- a/packages/transducers/src/func/ensure-iterable.ts +++ b/packages/transducers/src/func/ensure-iterable.ts @@ -1,4 +1,4 @@ -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { illegalArgs } from "@thi.ng/errors"; export const ensureIterable = (x: any): IterableIterator => { diff --git a/packages/transducers/src/func/even.ts b/packages/transducers/src/func/even.ts index 9d30160522..4fecc9bc95 100644 --- a/packages/transducers/src/func/even.ts +++ b/packages/transducers/src/func/even.ts @@ -1 +1 @@ -export { isEven as even } from "@thi.ng/checks/is-even"; +export { isEven as even } from "@thi.ng/checks"; diff --git a/packages/transducers/src/func/fuzzy-match.ts b/packages/transducers/src/func/fuzzy-match.ts index bc4a123062..d9476ff966 100644 --- a/packages/transducers/src/func/fuzzy-match.ts +++ b/packages/transducers/src/func/fuzzy-match.ts @@ -1,4 +1,4 @@ -import { Predicate2 } from "@thi.ng/api/api"; +import { Predicate2 } from "@thi.ng/api"; import { equiv } from "@thi.ng/equiv"; /** diff --git a/packages/transducers/src/func/hex.ts b/packages/transducers/src/func/hex.ts index f0c60ec00d..c2d5d6eb94 100644 --- a/packages/transducers/src/func/hex.ts +++ b/packages/transducers/src/func/hex.ts @@ -1,5 +1,4 @@ -import { Stringer } from "@thi.ng/strings/api"; -import { radix } from "@thi.ng/strings/radix"; +import { radix, Stringer } from "@thi.ng/strings"; /** * @deprecated use thi.ng/strings `radix()` instead diff --git a/packages/transducers/src/func/juxt.ts b/packages/transducers/src/func/juxt.ts index 6c9a09f973..f6dc86f79a 100644 --- a/packages/transducers/src/func/juxt.ts +++ b/packages/transducers/src/func/juxt.ts @@ -1 +1 @@ -export * from "@thi.ng/compose/juxt"; +export { juxt } from "@thi.ng/compose"; diff --git a/packages/transducers/src/func/odd.ts b/packages/transducers/src/func/odd.ts index f2914aff55..ab3065656e 100644 --- a/packages/transducers/src/func/odd.ts +++ b/packages/transducers/src/func/odd.ts @@ -1 +1 @@ -export { isOdd as odd } from "@thi.ng/checks/is-odd"; +export { isOdd as odd } from "@thi.ng/checks"; diff --git a/packages/transducers/src/func/renamer.ts b/packages/transducers/src/func/renamer.ts index 51f352aca4..1aefe1fd82 100644 --- a/packages/transducers/src/func/renamer.ts +++ b/packages/transducers/src/func/renamer.ts @@ -1,4 +1,4 @@ -import { IObjectOf } from "@thi.ng/api/api"; +import { IObjectOf } from "@thi.ng/api"; export const renamer = (kmap: IObjectOf) => { diff --git a/packages/transducers/src/iter/pairs.ts b/packages/transducers/src/iter/pairs.ts index 66a44b9a25..d8cc39c265 100644 --- a/packages/transducers/src/iter/pairs.ts +++ b/packages/transducers/src/iter/pairs.ts @@ -1,4 +1,4 @@ -import { IObjectOf } from "@thi.ng/api/api"; +import { IObjectOf } from "@thi.ng/api"; export function* pairs(x: IObjectOf): IterableIterator<[string, T]> { for (let k in x) { diff --git a/packages/transducers/src/iter/permutations.ts b/packages/transducers/src/iter/permutations.ts index 71377ebace..67c7fd2c50 100644 --- a/packages/transducers/src/iter/permutations.ts +++ b/packages/transducers/src/iter/permutations.ts @@ -1,4 +1,4 @@ -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { illegalArgs } from "@thi.ng/errors"; import { ensureArrayLike } from "../func/ensure-array"; import { range } from "./range"; diff --git a/packages/transducers/src/iter/range2d.ts b/packages/transducers/src/iter/range2d.ts index c20ce2cbf2..e1ef9e799d 100644 --- a/packages/transducers/src/iter/range2d.ts +++ b/packages/transducers/src/iter/range2d.ts @@ -1,5 +1,4 @@ -import { illegalArity } from "@thi.ng/errors/illegal-arity"; - +import { illegalArity } from "@thi.ng/errors"; import { range } from "./range"; export function range2d(toX: number, toY: number): IterableIterator<[number, number]>; diff --git a/packages/transducers/src/iter/range3d.ts b/packages/transducers/src/iter/range3d.ts index 3325ed43e5..cb68fc54f2 100644 --- a/packages/transducers/src/iter/range3d.ts +++ b/packages/transducers/src/iter/range3d.ts @@ -1,5 +1,4 @@ -import { illegalArity } from "@thi.ng/errors/illegal-arity"; - +import { illegalArity } from "@thi.ng/errors"; import { range } from "./range"; export function range3d(toX: number, toY: number, toZ: number): IterableIterator<[number, number, number]>; diff --git a/packages/transducers/src/iter/vals.ts b/packages/transducers/src/iter/vals.ts index 36c2acb2c5..679f9e862f 100644 --- a/packages/transducers/src/iter/vals.ts +++ b/packages/transducers/src/iter/vals.ts @@ -1,4 +1,4 @@ -import { IObjectOf } from "@thi.ng/api/api"; +import { IObjectOf } from "@thi.ng/api"; export function* vals(x: IObjectOf): IterableIterator { for (let k in x) { diff --git a/packages/transducers/src/iter/wrap.ts b/packages/transducers/src/iter/wrap.ts index b67d78c3e0..100e857528 100644 --- a/packages/transducers/src/iter/wrap.ts +++ b/packages/transducers/src/iter/wrap.ts @@ -1,4 +1,4 @@ -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { illegalArgs } from "@thi.ng/errors"; import { ensureArray } from "../func/ensure-array"; /** diff --git a/packages/transducers/src/iterator.ts b/packages/transducers/src/iterator.ts index fc161055ad..59bb3e21bd 100644 --- a/packages/transducers/src/iterator.ts +++ b/packages/transducers/src/iterator.ts @@ -1,5 +1,5 @@ -import { SEMAPHORE } from "@thi.ng/api/api"; -import { isIterable } from "@thi.ng/checks/is-iterable"; +import { SEMAPHORE } from "@thi.ng/api"; +import { isIterable } from "@thi.ng/checks"; import { Reducer, Transducer } from "./api"; import { isReduced, unreduced } from "./reduced"; diff --git a/packages/transducers/src/reduce.ts b/packages/transducers/src/reduce.ts index c2d01b0da6..7d1bb84562 100644 --- a/packages/transducers/src/reduce.ts +++ b/packages/transducers/src/reduce.ts @@ -1,8 +1,5 @@ -import { implementsFunction } from "@thi.ng/checks/implements-function"; -import { isArrayLike } from "@thi.ng/checks/is-arraylike"; -import { isIterable } from "@thi.ng/checks/is-iterable"; -import { illegalArity } from "@thi.ng/errors/illegal-arity"; - +import { implementsFunction, isArrayLike, isIterable } from "@thi.ng/checks"; +import { illegalArity } from "@thi.ng/errors"; import { IReducible, Reducer } from "./api"; import { isReduced, Reduced, unreduced } from "./reduced"; diff --git a/packages/transducers/src/reduced.ts b/packages/transducers/src/reduced.ts index 7e9f40afb9..e0e944c1bb 100644 --- a/packages/transducers/src/reduced.ts +++ b/packages/transducers/src/reduced.ts @@ -1,4 +1,4 @@ -import { IDeref } from "@thi.ng/api/api"; +import { IDeref } from "@thi.ng/api"; export class Reduced implements IDeref { diff --git a/packages/transducers/src/rfn/assoc-map.ts b/packages/transducers/src/rfn/assoc-map.ts index 24acf2f757..7f7ecefebd 100644 --- a/packages/transducers/src/rfn/assoc-map.ts +++ b/packages/transducers/src/rfn/assoc-map.ts @@ -1,7 +1,6 @@ -import { Pair } from "@thi.ng/api/api"; - +import { Pair } from "@thi.ng/api"; import { Reducer } from "../api"; -import { reducer, reduce } from "../reduce"; +import { reduce, reducer } from "../reduce"; /** * Reducer accepting key-value pairs / tuples and transforming / adding diff --git a/packages/transducers/src/rfn/assoc-obj.ts b/packages/transducers/src/rfn/assoc-obj.ts index 410f78eeaa..f29e0aa7c5 100644 --- a/packages/transducers/src/rfn/assoc-obj.ts +++ b/packages/transducers/src/rfn/assoc-obj.ts @@ -1,5 +1,4 @@ -import { IObjectOf, Pair } from "@thi.ng/api/api"; - +import { IObjectOf, Pair } from "@thi.ng/api"; import { Reducer } from "../api"; import { reduce, reducer } from "../reduce"; diff --git a/packages/transducers/src/rfn/every.ts b/packages/transducers/src/rfn/every.ts index e18a366709..3f882b3e05 100644 --- a/packages/transducers/src/rfn/every.ts +++ b/packages/transducers/src/rfn/every.ts @@ -1,5 +1,4 @@ -import { Predicate } from "@thi.ng/api/api"; - +import { Predicate } from "@thi.ng/api"; import { Reducer } from "../api"; import { $$reduce, reducer } from "../reduce"; import { reduced } from "../reduced"; diff --git a/packages/transducers/src/rfn/fill.ts b/packages/transducers/src/rfn/fill.ts index c68a89370a..742de3667c 100644 --- a/packages/transducers/src/rfn/fill.ts +++ b/packages/transducers/src/rfn/fill.ts @@ -1,7 +1,6 @@ -import { NumericArray } from "@thi.ng/api/api"; - +import { NumericArray } from "@thi.ng/api"; import { Reducer } from "../api"; -import { reducer, $$reduce } from "../reduce"; +import { $$reduce, reducer } from "../reduce"; /** * Reducer which starts filling array with results from given `start` diff --git a/packages/transducers/src/rfn/frequencies.ts b/packages/transducers/src/rfn/frequencies.ts index 3554709c87..1fa9467aa0 100644 --- a/packages/transducers/src/rfn/frequencies.ts +++ b/packages/transducers/src/rfn/frequencies.ts @@ -1,5 +1,4 @@ -import { Fn } from "@thi.ng/api/api"; - +import { Fn } from "@thi.ng/api"; import { Reducer } from "../api"; import { identity } from "../func/identity"; import { $$reduce } from "../reduce"; diff --git a/packages/transducers/src/rfn/group-binary.ts b/packages/transducers/src/rfn/group-binary.ts index e1bcc28a32..a0539edac3 100644 --- a/packages/transducers/src/rfn/group-binary.ts +++ b/packages/transducers/src/rfn/group-binary.ts @@ -1,5 +1,4 @@ -import { IObjectOf } from "@thi.ng/api/api"; - +import { IObjectOf } from "@thi.ng/api"; import { Reducer } from "../api"; import { groupByObj } from "./group-by-obj"; import { push } from "./push"; diff --git a/packages/transducers/src/rfn/group-by-obj.ts b/packages/transducers/src/rfn/group-by-obj.ts index 4f706a67bd..0e075ed96c 100644 --- a/packages/transducers/src/rfn/group-by-obj.ts +++ b/packages/transducers/src/rfn/group-by-obj.ts @@ -1,8 +1,7 @@ -import { IObjectOf } from "@thi.ng/api/api"; - +import { IObjectOf } from "@thi.ng/api"; import { GroupByOpts, Reducer } from "../api"; import { identity } from "../func/identity"; -import { reducer, $$reduce } from "../reduce"; +import { $$reduce, reducer } from "../reduce"; import { push } from "./push"; export function groupByObj(opts?: Partial>): Reducer, SRC>; diff --git a/packages/transducers/src/rfn/max-compare.ts b/packages/transducers/src/rfn/max-compare.ts index f49a78648f..6cca468f6a 100644 --- a/packages/transducers/src/rfn/max-compare.ts +++ b/packages/transducers/src/rfn/max-compare.ts @@ -1,6 +1,5 @@ -import { Comparator } from "@thi.ng/api/api"; +import { Comparator } from "@thi.ng/api"; import { compare } from "@thi.ng/compare"; - import { Reducer } from "../api"; import { $$reduce, reducer } from "../reduce"; diff --git a/packages/transducers/src/rfn/min-compare.ts b/packages/transducers/src/rfn/min-compare.ts index 381fe86420..f97ba5a3ce 100644 --- a/packages/transducers/src/rfn/min-compare.ts +++ b/packages/transducers/src/rfn/min-compare.ts @@ -1,6 +1,5 @@ -import { Comparator } from "@thi.ng/api/api"; +import { Comparator } from "@thi.ng/api"; import { compare } from "@thi.ng/compare"; - import { Reducer } from "../api"; import { $$reduce, reducer } from "../reduce"; diff --git a/packages/transducers/src/rfn/some.ts b/packages/transducers/src/rfn/some.ts index 266727ceab..90e67242b5 100644 --- a/packages/transducers/src/rfn/some.ts +++ b/packages/transducers/src/rfn/some.ts @@ -1,5 +1,4 @@ -import { Predicate } from "@thi.ng/api/api"; - +import { Predicate } from "@thi.ng/api"; import { Reducer } from "../api"; import { $$reduce, reducer } from "../reduce"; import { reduced } from "../reduced"; diff --git a/packages/transducers/src/transduce.ts b/packages/transducers/src/transduce.ts index 028bbf1bf8..91212f5ce0 100644 --- a/packages/transducers/src/transduce.ts +++ b/packages/transducers/src/transduce.ts @@ -1,5 +1,4 @@ -import { illegalArity } from "@thi.ng/errors/illegal-arity"; - +import { illegalArity } from "@thi.ng/errors"; import { IReducible, Reducer, Transducer } from "./api"; import { reduce } from "./reduce"; import { map } from "./xform/map"; diff --git a/packages/transducers/src/xform/convolve.ts b/packages/transducers/src/xform/convolve.ts index 6953b56044..b4dcbd15ab 100644 --- a/packages/transducers/src/xform/convolve.ts +++ b/packages/transducers/src/xform/convolve.ts @@ -1,5 +1,4 @@ -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; - +import { illegalArgs } from "@thi.ng/errors"; import { Transducer } from "../api"; import { range2d } from "../iter/range2d"; import { tuples } from "../iter/tuples"; diff --git a/packages/transducers/src/xform/dedupe.ts b/packages/transducers/src/xform/dedupe.ts index 9834e7bb89..dacf24a2ba 100644 --- a/packages/transducers/src/xform/dedupe.ts +++ b/packages/transducers/src/xform/dedupe.ts @@ -1,5 +1,4 @@ -import { Predicate2, SEMAPHORE } from "@thi.ng/api/api"; - +import { Predicate2, SEMAPHORE } from "@thi.ng/api"; import { Reducer, Transducer } from "../api"; import { compR } from "../func/compr"; import { $iter } from "../iterator"; diff --git a/packages/transducers/src/xform/drop-while.ts b/packages/transducers/src/xform/drop-while.ts index a950d72180..abaa872067 100644 --- a/packages/transducers/src/xform/drop-while.ts +++ b/packages/transducers/src/xform/drop-while.ts @@ -1,5 +1,4 @@ -import { Predicate } from "@thi.ng/api/api"; - +import { Predicate } from "@thi.ng/api"; import { Reducer, Transducer } from "../api"; import { compR } from "../func/compr"; import { $iter } from "../iterator"; diff --git a/packages/transducers/src/xform/filter-fuzzy.ts b/packages/transducers/src/xform/filter-fuzzy.ts index 13d91830c3..9679fdc655 100644 --- a/packages/transducers/src/xform/filter-fuzzy.ts +++ b/packages/transducers/src/xform/filter-fuzzy.ts @@ -1,5 +1,4 @@ -import { Fn, Predicate2 } from "@thi.ng/api/api"; - +import { Fn, Predicate2 } from "@thi.ng/api"; import { Transducer } from "../api"; import { fuzzyMatch } from "../func/fuzzy-match"; import { $iter } from "../iterator"; diff --git a/packages/transducers/src/xform/hex-dump.ts b/packages/transducers/src/xform/hex-dump.ts index a25491038d..9c6cbbbcff 100644 --- a/packages/transducers/src/xform/hex-dump.ts +++ b/packages/transducers/src/xform/hex-dump.ts @@ -1,5 +1,4 @@ -import { U32, U8 } from "@thi.ng/strings/radix"; - +import { U32, U8 } from "@thi.ng/strings"; import { Transducer } from "../api"; import { comp } from "../func/comp"; import { juxt } from "../func/juxt"; diff --git a/packages/transducers/src/xform/labeled.ts b/packages/transducers/src/xform/labeled.ts index 73341868ae..611a5bbc19 100644 --- a/packages/transducers/src/xform/labeled.ts +++ b/packages/transducers/src/xform/labeled.ts @@ -1,5 +1,4 @@ -import { isFunction } from "@thi.ng/checks/is-function"; - +import { isFunction } from "@thi.ng/checks"; import { Transducer } from "../api"; import { iterator1 } from "../iterator"; import { map } from "./map"; diff --git a/packages/transducers/src/xform/map-keys.ts b/packages/transducers/src/xform/map-keys.ts index ff646a9b03..35ea24b9eb 100644 --- a/packages/transducers/src/xform/map-keys.ts +++ b/packages/transducers/src/xform/map-keys.ts @@ -1,5 +1,4 @@ -import { Fn, IObjectOf } from "@thi.ng/api/api"; - +import { Fn, IObjectOf } from "@thi.ng/api"; import { Transducer } from "../api"; import { $iter } from "../iterator"; import { map } from "./map"; diff --git a/packages/transducers/src/xform/map-nth.ts b/packages/transducers/src/xform/map-nth.ts index cc2750b894..95ab9e8bd1 100644 --- a/packages/transducers/src/xform/map-nth.ts +++ b/packages/transducers/src/xform/map-nth.ts @@ -1,5 +1,4 @@ -import { Fn } from "@thi.ng/api/api"; - +import { Fn } from "@thi.ng/api"; import { Reducer, Transducer } from "../api"; import { compR } from "../func/compr"; import { $iter } from "../iterator"; diff --git a/packages/transducers/src/xform/map-vals.ts b/packages/transducers/src/xform/map-vals.ts index 90eb39f13d..1a4f60cc7b 100644 --- a/packages/transducers/src/xform/map-vals.ts +++ b/packages/transducers/src/xform/map-vals.ts @@ -1,5 +1,4 @@ -import { Fn, IObjectOf } from "@thi.ng/api/api"; - +import { Fn, IObjectOf } from "@thi.ng/api"; import { Transducer } from "../api"; import { $iter } from "../iterator"; import { map } from "./map"; diff --git a/packages/transducers/src/xform/map.ts b/packages/transducers/src/xform/map.ts index 3a409a5247..ddbf92550c 100644 --- a/packages/transducers/src/xform/map.ts +++ b/packages/transducers/src/xform/map.ts @@ -1,5 +1,4 @@ -import { Fn } from "@thi.ng/api/api"; - +import { Fn } from "@thi.ng/api"; import { Reducer, Transducer } from "../api"; import { compR } from "../func/compr"; import { iterator1 } from "../iterator"; diff --git a/packages/transducers/src/xform/mapcat.ts b/packages/transducers/src/xform/mapcat.ts index 5038dac1a6..552afd5e0e 100644 --- a/packages/transducers/src/xform/mapcat.ts +++ b/packages/transducers/src/xform/mapcat.ts @@ -1,5 +1,4 @@ -import { Fn } from "@thi.ng/api/api"; - +import { Fn } from "@thi.ng/api"; import { Transducer } from "../api"; import { comp } from "../func/comp"; import { iterator } from "../iterator"; diff --git a/packages/transducers/src/xform/moving-average.ts b/packages/transducers/src/xform/moving-average.ts index 3100013a3a..178bdfa64c 100644 --- a/packages/transducers/src/xform/moving-average.ts +++ b/packages/transducers/src/xform/moving-average.ts @@ -1,5 +1,4 @@ -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; - +import { illegalArgs } from "@thi.ng/errors"; import { Reducer, Transducer } from "../api"; import { compR } from "../func/compr"; import { iterator1 } from "../iterator"; diff --git a/packages/transducers/src/xform/multiplex-obj.ts b/packages/transducers/src/xform/multiplex-obj.ts index d0b9680df8..f9aa5f79cd 100644 --- a/packages/transducers/src/xform/multiplex-obj.ts +++ b/packages/transducers/src/xform/multiplex-obj.ts @@ -1,5 +1,4 @@ -import { IObjectOf } from "@thi.ng/api/api"; - +import { IObjectOf } from "@thi.ng/api"; import { Reducer, Transducer } from "../api"; import { comp } from "../func/comp"; import { $iter } from "../iterator"; diff --git a/packages/transducers/src/xform/partition-by.ts b/packages/transducers/src/xform/partition-by.ts index d40fd7b025..4966cb002c 100644 --- a/packages/transducers/src/xform/partition-by.ts +++ b/packages/transducers/src/xform/partition-by.ts @@ -1,5 +1,4 @@ -import { Fn, SEMAPHORE } from "@thi.ng/api/api"; - +import { Fn, SEMAPHORE } from "@thi.ng/api"; import { Transducer } from "../api"; import { $iter, iterator } from "../iterator"; import { isReduced } from "../reduced"; diff --git a/packages/transducers/src/xform/partition-sync.ts b/packages/transducers/src/xform/partition-sync.ts index f81291b21a..c02e180bde 100644 --- a/packages/transducers/src/xform/partition-sync.ts +++ b/packages/transducers/src/xform/partition-sync.ts @@ -1,6 +1,5 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { isArray } from "@thi.ng/checks/is-array"; - +import { IObjectOf } from "@thi.ng/api"; +import { isArray } from "@thi.ng/checks"; import { Reducer, Transducer } from "../api"; import { identity } from "../func/identity"; import { $iter, iterator } from "../iterator"; diff --git a/packages/transducers/src/xform/rename.ts b/packages/transducers/src/xform/rename.ts index af52156a98..2e55ddbbef 100644 --- a/packages/transducers/src/xform/rename.ts +++ b/packages/transducers/src/xform/rename.ts @@ -1,6 +1,5 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { isArray } from "@thi.ng/checks/is-array"; - +import { IObjectOf } from "@thi.ng/api"; +import { isArray } from "@thi.ng/checks"; import { Reducer, Transducer } from "../api"; import { comp } from "../func/comp"; import { renamer } from "../func/renamer"; diff --git a/packages/transducers/src/xform/struct.ts b/packages/transducers/src/xform/struct.ts index 577f0078c6..76a2c9e632 100644 --- a/packages/transducers/src/xform/struct.ts +++ b/packages/transducers/src/xform/struct.ts @@ -1,5 +1,4 @@ -import { Fn } from "@thi.ng/api/api"; - +import { Fn } from "@thi.ng/api"; import { Transducer } from "../api"; import { comp } from "../func/comp"; import { iterator } from "../iterator"; diff --git a/packages/transducers/src/xform/take-while.ts b/packages/transducers/src/xform/take-while.ts index 5a6e3798ba..a1a25b2d84 100644 --- a/packages/transducers/src/xform/take-while.ts +++ b/packages/transducers/src/xform/take-while.ts @@ -1,5 +1,4 @@ -import { Predicate } from "@thi.ng/api/api"; - +import { Predicate } from "@thi.ng/api"; import { Reducer, Transducer } from "../api"; import { compR } from "../func/compr"; import { $iter } from "../iterator"; diff --git a/packages/transducers/src/xform/throttle.ts b/packages/transducers/src/xform/throttle.ts index e8564cc139..a86fb2bb51 100644 --- a/packages/transducers/src/xform/throttle.ts +++ b/packages/transducers/src/xform/throttle.ts @@ -1,5 +1,4 @@ -import { StatefulPredicate } from "@thi.ng/api/api"; - +import { StatefulPredicate } from "@thi.ng/api"; import { Reducer, Transducer } from "../api"; import { compR } from "../func/compr"; import { iterator1 } from "../iterator"; diff --git a/packages/transducers/test/partition-bits.ts b/packages/transducers/test/partition-bits.ts index 9e6d09809e..deceb1fbe6 100644 --- a/packages/transducers/test/partition-bits.ts +++ b/packages/transducers/test/partition-bits.ts @@ -1,5 +1,5 @@ import * as assert from "assert"; -import { radix } from "@thi.ng/strings/radix"; +import { radix } from "@thi.ng/strings"; import { comp } from "../src/func/comp"; import { range } from "../src/iter/range"; diff --git a/packages/transducers/test/tsconfig.json b/packages/transducers/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/transducers/test/tsconfig.json +++ b/packages/transducers/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/unionstruct/package.json b/packages/unionstruct/package.json index 1ee2cb8f8f..58ec64ef70 100644 --- a/packages/unionstruct/package.json +++ b/packages/unionstruct/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/unionstruct", "version": "0.1.19", "description": "C-style struct, union and bitfield views of ArrayBuffers", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module unionstruct", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -34,11 +38,13 @@ "c", "cpp", "ES6", + "interop", "struct", "typescript", "union" ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/unionstruct/src/index.ts b/packages/unionstruct/src/index.ts index 88cfd8d40b..e735d0947b 100644 --- a/packages/unionstruct/src/index.ts +++ b/packages/unionstruct/src/index.ts @@ -24,35 +24,45 @@ const TYPES = { const UNION = "union"; const STRUCT = "struct"; -let isBitField = (f: Field) => typeof f[2] === "number" && /^(u|i)\d+$/.test(f[1]); +const isBitField = + (f: Field) => + typeof f[2] === "number" && /^(u|i)\d+$/.test(f[1]); -let align = (bitOffset: number, type: string, spec: any) => { - if (type === UNION) { - spec = (spec.__spec || spec); - let a = 0, f; - for (let i = 0; i < spec.length; i++) { - f = spec[i]; - a = Math.max(align(bitOffset, f[1], f[2]), a); +const align = + (bitOffset: number, type: string, spec: any) => { + if (type === UNION) { + spec = (spec.__spec || spec); + let a = 0, f; + for (let i = 0; i < spec.length; i++) { + f = spec[i]; + a = Math.max(align(bitOffset, f[1], f[2]), a); + } + return a; + } else if (type === STRUCT) { + spec = (spec.__spec || spec)[0]; + return align(bitOffset, spec[1], spec[2]); } - return a; - } else if (type === STRUCT) { - spec = (spec.__spec || spec)[0]; - return align(bitOffset, spec[1], spec[2]); - } - let block = TYPES[type][0]; - return block > 8 ? (bitOffset + block - 1) & -block : bitOffset; -}; + let block = TYPES[type][0]; + return block > 8 ? (bitOffset + block - 1) & -block : bitOffset; + }; -let maybePad = (offset: number, spec: any[], i: number) => { - let f = spec[i], width; - if (i === spec.length - 1 || !isBitField(spec[i + 1])) { - width = TYPES[f[1]][0]; - offset += ((offset + width - 1) & ~(width - 1)) - offset; - } - return offset; -}; +const maybePad = + (offset: number, spec: any[], i: number) => { + let f = spec[i], width; + if (i === spec.length - 1 || !isBitField(spec[i + 1])) { + width = TYPES[f[1]][0]; + offset += ((offset + width - 1) & ~(width - 1)) - offset; + } + return offset; + }; -let _sizeOf = (spec: Field[], union: boolean, doAlign: boolean, bitOffset: number, total: number) => { +const _sizeOf = ( + spec: Field[], + union: boolean, + doAlign: boolean, + bitOffset: number, + total: number +) => { for (let i = 0; i < spec.length; i++) { let f = spec[i], type = f[1], size = f[2], isBF = isBitField(f); bitOffset = doAlign && !isBF ? align(bitOffset, type, size) : bitOffset; @@ -71,36 +81,46 @@ let _sizeOf = (spec: Field[], union: boolean, doAlign: boolean, bitOffset: numbe return [total, bitOffset]; }; -export let sizeOf = (spec: Field[], union = false, doAlign = true) => - _sizeOf(spec, union, doAlign, 0, 0)[0]; +export const sizeOf = + (spec: Field[], union = false, doAlign = true) => + _sizeOf(spec, union, doAlign, 0, 0)[0]; -let bitReader = (dv: DataView, byteOffset: number, bit: number, size: number) => { - const b = bit - size; - if (b >= 0) { - return () => dv.getUint32(byteOffset, false) >>> b & (1 << size) - 1; - } - return () => ((dv.getUint32(byteOffset, false) & (1 << bit) - 1) << -b) | - (dv.getUint32(byteOffset + 4, false) >>> (32 + b)); -}; +const bitReader = + (dv: DataView, byteOffset: number, bit: number, size: number) => { + const b = bit - size; + if (b >= 0) { + return () => dv.getUint32(byteOffset, false) >>> b & (1 << size) - 1; + } + return () => ((dv.getUint32(byteOffset, false) & (1 << bit) - 1) << -b) | + (dv.getUint32(byteOffset + 4, false) >>> (32 + b)); + }; -let bitWriter = (dv: DataView, byteOffset: number, bit: number, size: number) => { - const b = bit - size; - let m = bit < 32 ? ~((1 << bit) - 1) : 0; - if (b >= 0) { - m |= (1 << b) - 1; - return (x) => { - dv.setUint32(byteOffset, (dv.getUint32(byteOffset, false) & m) | (x << b & ~m), false); - }; - } else { - let bb = 32 + b; - return (x) => { - dv.setUint32(byteOffset, (dv.getUint32(byteOffset, false) & m) | (x >>> -b & ~m), false); - dv.setUint32(byteOffset + 4, (dv.getUint32(byteOffset + 4, false) & (1 << bb) - 1) | x << bb, false); +const bitWriter = + (dv: DataView, byteOffset: number, bit: number, size: number) => { + const b = bit - size; + let m = bit < 32 ? ~((1 << bit) - 1) : 0; + if (b >= 0) { + m |= (1 << b) - 1; + return (x) => { + dv.setUint32(byteOffset, (dv.getUint32(byteOffset, false) & m) | (x << b & ~m), false); + }; + } else { + let bb = 32 + b; + return (x) => { + dv.setUint32(byteOffset, (dv.getUint32(byteOffset, false) & m) | (x >>> -b & ~m), false); + dv.setUint32(byteOffset + 4, (dv.getUint32(byteOffset + 4, false) & (1 << bb) - 1) | x << bb, false); + } } - } -}; + }; -let makeField = (field: Field, obj: any, dv: DataView, bitOffset: number, doAlign: boolean, le: boolean) => { +const makeField = ( + field: Field, + obj: any, + dv: DataView, + bitOffset: number, + doAlign: boolean, + le: boolean +) => { let [id, type, size] = field; const isBF = isBitField(field); bitOffset = doAlign && !isBF ? align(bitOffset, type, size) : bitOffset; @@ -146,7 +166,14 @@ let makeField = (field: Field, obj: any, dv: DataView, bitOffset: number, doAlig return bitOffset; }; -export let typedef = (spec: Field[], struct: boolean, buf?: ArrayBuffer, offset = 0, doAlign = true, le = false) => { +export const typedef = ( + spec: Field[], + struct: boolean, + buf?: ArrayBuffer, + offset = 0, + doAlign = true, + le = false +) => { let size = sizeOf(spec, !struct, doAlign); let dv = new DataView(buf || new ArrayBuffer(((size + 7) & -8) >>> 3)); let off = offset << 3; @@ -169,10 +196,12 @@ export let typedef = (spec: Field[], struct: boolean, buf?: ArrayBuffer, offset return obj; }; -export let union = (spec: Field[], buf?: ArrayBuffer, offset?: number, doAlign?: boolean, le?: boolean) => { - return typedef(spec, false, buf, offset, doAlign, le); -} +export const union = + (spec: Field[], buf?: ArrayBuffer, offset?: number, doAlign?: boolean, le?: boolean) => { + return typedef(spec, false, buf, offset, doAlign, le); + } -export let struct = (spec: Field[], buf?: ArrayBuffer, offset?: number, doAlign?: boolean, le?: boolean) => { - return typedef(spec, true, buf, offset, doAlign, le); -} +export const struct = + (spec: Field[], buf?: ArrayBuffer, offset?: number, doAlign?: boolean, le?: boolean) => { + return typedef(spec, true, buf, offset, doAlign, le); + } diff --git a/packages/unionstruct/test/tsconfig.json b/packages/unionstruct/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/unionstruct/test/tsconfig.json +++ b/packages/unionstruct/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/vectors/package.json b/packages/vectors/package.json index f198471cff..0081e3567e 100644 --- a/packages/vectors/package.json +++ b/packages/vectors/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/vectors", "version": "1.4.12", "description": "Vector algebra for fixed & variable sizes, memory mapped, flexible layouts", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module vectors api checks errors math transducers", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -46,5 +50,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/vectors/src/api.ts b/packages/vectors/src/api.ts index c3ece347d7..afff2a2c45 100644 --- a/packages/vectors/src/api.ts +++ b/packages/vectors/src/api.ts @@ -1,12 +1,12 @@ import { + ICompare, ICopy, + IEmpty, IEqualsDelta, IEquiv, - NumericArray, - IEmpty, ILength, - ICompare -} from "@thi.ng/api/api"; + NumericArray +} from "@thi.ng/api"; export type Vec = NumericArray; export type ReadonlyVec = ArrayLike & Iterable; diff --git a/packages/vectors/src/codegen.ts b/packages/vectors/src/codegen.ts index 089d4ce6cc..3e840bcc65 100644 --- a/packages/vectors/src/codegen.ts +++ b/packages/vectors/src/codegen.ts @@ -1,11 +1,13 @@ -import { comp } from "@thi.ng/transducers/func/comp"; -import { range } from "@thi.ng/transducers/iter/range"; -import { tuples } from "@thi.ng/transducers/iter/tuples"; -import { push } from "@thi.ng/transducers/rfn/push"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { map } from "@thi.ng/transducers/xform/map"; -import { mapcat } from "@thi.ng/transducers/xform/mapcat"; -import { take } from "@thi.ng/transducers/xform/take"; +import { + comp, + map, + mapcat, + push, + range, + take, + transduce, + tuples +} from "@thi.ng/transducers"; import { Vec, VecOp1, diff --git a/packages/vectors/src/common.ts b/packages/vectors/src/common.ts index 1d6dd58ec9..4e4664af96 100644 --- a/packages/vectors/src/common.ts +++ b/packages/vectors/src/common.ts @@ -1,5 +1,4 @@ -import { EPS } from "@thi.ng/math/api"; -import { eqDelta as _eqDelta } from "@thi.ng/math/eqdelta"; +import { EPS, eqDelta as _eqDelta } from "@thi.ng/math"; import { ReadonlyVec, ReadonlyVecOp1, diff --git a/packages/vectors/src/gvec.ts b/packages/vectors/src/gvec.ts index c0a65e9cea..e4aa908a30 100644 --- a/packages/vectors/src/gvec.ts +++ b/packages/vectors/src/gvec.ts @@ -3,14 +3,17 @@ import { IEqualsDelta, IEquiv, ILength -} from "@thi.ng/api/api"; -import { isArrayLike } from "@thi.ng/checks/is-arraylike"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { sign as _sign } from "@thi.ng/math/abs"; -import { EPS } from "@thi.ng/math/api"; -import { clamp as _clamp } from "@thi.ng/math/interval"; -import { fract as _fract } from "@thi.ng/math/prec"; -import { smoothStep as _smoothStep, step as _step } from "@thi.ng/math/step"; +} from "@thi.ng/api"; +import { isArrayLike } from "@thi.ng/checks"; +import { illegalArgs } from "@thi.ng/errors"; +import { + clamp as _clamp, + EPS, + fract as _fract, + sign as _sign, + smoothStep as _smoothStep, + step as _step +} from "@thi.ng/math"; import { IDotProduct, IMagnitude, @@ -24,7 +27,6 @@ import { } from "./api"; import { $iter, eqDelta, equiv } from "./common"; - export const opg0 = (fn: () => number, a: Vec, num = a.length, i = 0, s = 1) => { i += num * s; while (i -= s, --num >= 0) { diff --git a/packages/vectors/src/mat23.ts b/packages/vectors/src/mat23.ts index dbd72e5654..8e412ad833 100644 --- a/packages/vectors/src/mat23.ts +++ b/packages/vectors/src/mat23.ts @@ -1,6 +1,6 @@ -import { ICopy, IEqualsDelta } from "@thi.ng/api/api"; -import { isArrayLike } from "@thi.ng/checks/is-arraylike"; -import { EPS } from "@thi.ng/math/api"; +import { ICopy, IEqualsDelta } from "@thi.ng/api"; +import { isArrayLike } from "@thi.ng/checks"; +import { EPS } from "@thi.ng/math"; import { Mat, ReadonlyMat, diff --git a/packages/vectors/src/mat33.ts b/packages/vectors/src/mat33.ts index b4235482ef..8019b6393b 100644 --- a/packages/vectors/src/mat33.ts +++ b/packages/vectors/src/mat33.ts @@ -1,6 +1,6 @@ -import { ICopy, IEqualsDelta } from "@thi.ng/api/api"; -import { isArrayLike } from "@thi.ng/checks/is-arraylike"; -import { EPS } from "@thi.ng/math/api"; +import { ICopy, IEqualsDelta } from "@thi.ng/api"; +import { isArrayLike } from "@thi.ng/checks"; +import { EPS } from "@thi.ng/math"; import { Mat, ReadonlyMat, diff --git a/packages/vectors/src/mat44.ts b/packages/vectors/src/mat44.ts index fdb447d5a1..7dfae1fae6 100644 --- a/packages/vectors/src/mat44.ts +++ b/packages/vectors/src/mat44.ts @@ -1,5 +1,6 @@ -import { ICopy, IEqualsDelta } from "@thi.ng/api/api"; -import { isArrayLike } from "@thi.ng/checks/is-arraylike"; +import { ICopy, IEqualsDelta } from "@thi.ng/api"; +import { isArrayLike } from "@thi.ng/checks"; +import { DEG2RAD, EPS } from "@thi.ng/math"; import { Mat, ReadonlyMat, @@ -20,7 +21,6 @@ import { Vec3 } from "./vec3"; import { dot4, setS4, Vec4 } from "./vec4"; -import { EPS, DEG2RAD } from "@thi.ng/math/api"; export const get44 = (a: Mat, i = 0) => a.slice(i, i + 16); diff --git a/packages/vectors/src/vec2.ts b/packages/vectors/src/vec2.ts index d13aa63d09..7a3ee8ea46 100644 --- a/packages/vectors/src/vec2.ts +++ b/packages/vectors/src/vec2.ts @@ -1,11 +1,17 @@ -import { isArrayLike } from "@thi.ng/checks/is-arraylike"; -import { atan2Abs } from "@thi.ng/math/angle"; -import { EPS, HALF_PI, PI } from "@thi.ng/math/api"; -import { eqDelta } from "@thi.ng/math/eqdelta"; -import { max2id, min2id } from "@thi.ng/math/interval"; -import { mixBilinear } from "@thi.ng/math/mix"; -import { fract } from "@thi.ng/math/prec"; -import { smoothStep, step } from "@thi.ng/math/step"; +import { isArrayLike } from "@thi.ng/checks"; +import { + atan2Abs, + EPS, + eqDelta, + fract, + HALF_PI, + max2id, + min2id, + mixBilinear, + PI, + smoothStep, + step +} from "@thi.ng/math"; import { IAngleBetween, ICrossProduct, diff --git a/packages/vectors/src/vec3.ts b/packages/vectors/src/vec3.ts index 1ce2dfd6c4..c8003a52ec 100644 --- a/packages/vectors/src/vec3.ts +++ b/packages/vectors/src/vec3.ts @@ -1,11 +1,15 @@ -import { isArrayLike } from "@thi.ng/checks/is-arraylike"; -import { atan2Abs } from "@thi.ng/math/angle"; -import { EPS } from "@thi.ng/math/api"; -import { eqDelta } from "@thi.ng/math/eqdelta"; -import { max3id, min3id } from "@thi.ng/math/interval"; -import { mixBilinear } from "@thi.ng/math/mix"; -import { fract } from "@thi.ng/math/prec"; -import { smoothStep, step } from "@thi.ng/math/step"; +import { isArrayLike } from "@thi.ng/checks"; +import { + atan2Abs, + EPS, + eqDelta, + fract, + max3id, + min3id, + mixBilinear, + smoothStep, + step +} from "@thi.ng/math"; import { IAngleBetween, ICrossProduct, diff --git a/packages/vectors/src/vec4.ts b/packages/vectors/src/vec4.ts index 310f1ca4a8..90f83ae776 100644 --- a/packages/vectors/src/vec4.ts +++ b/packages/vectors/src/vec4.ts @@ -1,10 +1,14 @@ -import { isArrayLike } from "@thi.ng/checks/is-arraylike"; -import { EPS } from "@thi.ng/math/api"; -import { eqDelta } from "@thi.ng/math/eqdelta"; -import { max4id, min4id } from "@thi.ng/math/interval"; -import { mixBilinear } from "@thi.ng/math/mix"; -import { fract } from "@thi.ng/math/prec"; -import { smoothStep, step } from "@thi.ng/math/step"; +import { isArrayLike } from "@thi.ng/checks"; +import { + EPS, + eqDelta, + fract, + max4id, + min4id, + mixBilinear, + smoothStep, + step +} from "@thi.ng/math"; import { IVec, IVector, diff --git a/packages/vectors/test/tsconfig.json b/packages/vectors/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/vectors/test/tsconfig.json +++ b/packages/vectors/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", From f912a84acddcacd415b1af71b9b1b81ada5d4e49 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 8 Jan 2019 10:17:39 +0000 Subject: [PATCH 217/333] build: update package scripts, outputs, imports in remaining packages BREAKING CHANGE: enable multi-outputs (ES6 modules, CJS, UMD) - build scripts now first build ES6 modules in package root, then call `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` - all imports MUST be updated to only refer to package level (not individual files anymore). tree shaking in user land will get rid of all unused imported symbols --- packages/hdom-canvas/package.json | 17 +++++--- packages/hdom-canvas/src/index.ts | 17 ++++---- packages/hdom-canvas/test/tsconfig.json | 3 +- packages/hdom-components/package.json | 17 +++++--- packages/hdom-components/src/button-group.ts | 5 +-- packages/hdom-components/src/button.ts | 2 +- packages/hdom-components/src/fps-counter.ts | 4 +- packages/hdom-components/src/link.ts | 2 +- packages/hdom-components/src/notification.ts | 2 +- packages/hdom-components/src/pager.ts | 3 +- packages/hdom-components/src/sparkline.ts | 5 +-- packages/hdom-components/test/tsconfig.json | 3 +- packages/hdom-mock/package.json | 20 ++++++---- packages/hdom-mock/src/index.ts | 16 +++++--- packages/hdom-mock/test/tsconfig.json | 3 +- packages/hdom/package.json | 22 +++++++--- packages/hdom/src/api.ts | 2 +- packages/hdom/src/diff.ts | 6 +-- packages/hdom/src/dom.ts | 11 +++-- packages/hdom/src/index.ts | 2 + packages/hdom/src/normalize.ts | 14 +++---- packages/hdom/src/render-once.ts | 2 +- packages/hdom/src/start.ts | 2 +- packages/hdom/src/utils.ts | 2 +- packages/hdom/test/index.ts | 19 ++++----- packages/hdom/test/tsconfig.json | 3 +- packages/rstream-csp/package.json | 17 +++++--- packages/rstream-csp/src/from/channel.ts | 7 ++-- packages/rstream-csp/test/tsconfig.json | 3 +- packages/rstream-csp/tsconfig.json | 2 +- packages/rstream-dot/package.json | 17 +++++--- packages/rstream-dot/src/index.ts | 10 +++-- packages/rstream-dot/test/tsconfig.json | 3 +- packages/rstream-gestures/package.json | 17 +++++--- packages/rstream-gestures/src/index.ts | 7 ++-- packages/rstream-gestures/test/tsconfig.json | 3 +- packages/rstream-graph/package.json | 18 ++++++--- packages/rstream-graph/src/api.ts | 6 +-- packages/rstream-graph/src/graph.ts | 24 +++++------ packages/rstream-graph/src/nodes/extract.ts | 3 +- packages/rstream-graph/src/nodes/math.ts | 5 +-- packages/rstream-graph/test/index.ts | 3 +- packages/rstream-graph/test/tsconfig.json | 3 +- packages/rstream-log/package.json | 17 +++++--- packages/rstream-log/src/api.ts | 4 +- packages/rstream-log/src/logger.ts | 7 +--- packages/rstream-log/src/output/console.ts | 2 +- packages/rstream-log/src/output/file.ts | 6 +-- packages/rstream-log/src/xform/filter.ts | 7 ++-- packages/rstream-log/src/xform/format.ts | 3 +- packages/rstream-log/test/tsconfig.json | 3 +- packages/rstream-query/package.json | 17 +++++--- packages/rstream-query/src/api.ts | 4 +- packages/rstream-query/src/convert.ts | 7 +--- packages/rstream-query/src/pattern.ts | 3 +- packages/rstream-query/src/qvar.ts | 2 +- packages/rstream-query/src/store.ts | 40 ++++++++++--------- packages/rstream-query/test/tsconfig.json | 3 +- packages/rstream/package.json | 17 +++++--- packages/rstream/src/api.ts | 5 +-- packages/rstream/src/from/atom.ts | 4 +- packages/rstream/src/from/promises.ts | 3 +- packages/rstream/src/from/raf.ts | 2 +- packages/rstream/src/from/view.ts | 6 +-- packages/rstream/src/index.ts | 1 + packages/rstream/src/pubsub.ts | 8 ++-- packages/rstream/src/stream-merge.ts | 4 +- packages/rstream/src/stream-sync.ts | 16 ++++---- packages/rstream/src/stream.ts | 6 +-- packages/rstream/src/subs/bisect.ts | 3 +- packages/rstream/src/subs/post-worker.ts | 5 +-- packages/rstream/src/subs/resolve.ts | 2 +- .../rstream/src/subs/sidechain-partition.ts | 2 +- packages/rstream/src/subs/sidechain-toggle.ts | 2 +- packages/rstream/src/subs/transduce.ts | 5 +-- packages/rstream/src/subscription.ts | 21 +++++----- packages/rstream/src/utils/worker.ts | 6 +-- packages/rstream/test/tsconfig.json | 3 +- packages/transducers-hdom/package.json | 19 +++++---- packages/transducers-hdom/src/index.ts | 14 ++++--- scripts/bundle-module | 16 ++++---- 81 files changed, 347 insertions(+), 300 deletions(-) diff --git a/packages/hdom-canvas/package.json b/packages/hdom-canvas/package.json index acc3c113d7..505d1a67f5 100644 --- a/packages/hdom-canvas/package.json +++ b/packages/hdom-canvas/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/hdom-canvas", "version": "0.1.20", "description": "Declarative canvas scenegraph & visualization for @thi.ng/hdom", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module hdomCanvas api checks diff hdom", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -46,5 +50,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/hdom-canvas/src/index.ts b/packages/hdom-canvas/src/index.ts index 30f88e22eb..3be1838b54 100644 --- a/packages/hdom-canvas/src/index.ts +++ b/packages/hdom-canvas/src/index.ts @@ -1,11 +1,12 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { isArray } from "@thi.ng/checks/is-array"; -import { isArrayLike } from "@thi.ng/checks/is-arraylike"; -import { isNotStringAndIterable } from "@thi.ng/checks/is-not-string-iterable"; -import { DiffMode } from "@thi.ng/diff/api"; -import { diffArray } from "@thi.ng/diff/array"; -import { HDOMImplementation, HDOMOpts } from "@thi.ng/hdom/api"; -import { equiv, releaseTree } from "@thi.ng/hdom/diff"; +import { IObjectOf } from "@thi.ng/api"; +import { isArray, isArrayLike, isNotStringAndIterable } from "@thi.ng/checks"; +import { diffArray, DiffMode } from "@thi.ng/diff"; +import { + equiv, + HDOMImplementation, + HDOMOpts, + releaseTree +} from "@thi.ng/hdom"; interface DrawState { attribs: IObjectOf; diff --git a/packages/hdom-canvas/test/tsconfig.json b/packages/hdom-canvas/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/hdom-canvas/test/tsconfig.json +++ b/packages/hdom-canvas/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/hdom-components/package.json b/packages/hdom-components/package.json index f625863697..d246a91ec6 100644 --- a/packages/hdom-components/package.json +++ b/packages/hdom-components/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/hdom-components", "version": "2.4.6", "description": "Raw, skinnable UI & SVG components for @thi.ng/hdom", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module hdomComponents api checks math transducers transducers-stats", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -41,5 +45,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/hdom-components/src/button-group.ts b/packages/hdom-components/src/button-group.ts index ad4f6d5109..294ab5cbfc 100644 --- a/packages/hdom-components/src/button-group.ts +++ b/packages/hdom-components/src/button-group.ts @@ -1,6 +1,5 @@ -import { IObjectOf } from "@thi.ng/api/api"; - -import { ButtonArgs, Button } from "./button"; +import { IObjectOf } from "@thi.ng/api"; +import { Button, ButtonArgs } from "./button"; import { mergeAttribs } from "./utils/merge-attribs"; /** diff --git a/packages/hdom-components/src/button.ts b/packages/hdom-components/src/button.ts index 96c4490fe1..e188584ccb 100644 --- a/packages/hdom-components/src/button.ts +++ b/packages/hdom-components/src/button.ts @@ -1,4 +1,4 @@ -import { IObjectOf } from "@thi.ng/api/api"; +import { IObjectOf } from "@thi.ng/api"; import { mergeAttribs } from "./utils/merge-attribs"; export interface ButtonOpts { diff --git a/packages/hdom-components/src/fps-counter.ts b/packages/hdom-components/src/fps-counter.ts index 695272d16e..9110b09785 100644 --- a/packages/hdom-components/src/fps-counter.ts +++ b/packages/hdom-components/src/fps-counter.ts @@ -1,5 +1,5 @@ -import { sma } from "@thi.ng/transducers-stats/sma"; -import { step } from "@thi.ng/transducers/step"; +import { step } from "@thi.ng/transducers"; +import { sma } from "@thi.ng/transducers-stats"; import { sparkline, SparklineOpts } from "./sparkline"; export interface FpsCounterOpts { diff --git a/packages/hdom-components/src/link.ts b/packages/hdom-components/src/link.ts index 3c8992ecd0..ff365e4246 100644 --- a/packages/hdom-components/src/link.ts +++ b/packages/hdom-components/src/link.ts @@ -1,4 +1,4 @@ -import { isString } from "@thi.ng/checks/is-string"; +import { isString } from "@thi.ng/checks"; export const link = (attribs: any, body: any) => ["a", isString(attribs) ? { href: attribs } : attribs, body]; diff --git a/packages/hdom-components/src/notification.ts b/packages/hdom-components/src/notification.ts index ce84778af9..94992beece 100644 --- a/packages/hdom-components/src/notification.ts +++ b/packages/hdom-components/src/notification.ts @@ -1,4 +1,4 @@ -import { IObjectOf } from "@thi.ng/api/api"; +import { IObjectOf } from "@thi.ng/api"; import { appLink } from "./link"; export interface NotificationOpts { diff --git a/packages/hdom-components/src/pager.ts b/packages/hdom-components/src/pager.ts index e729868f3f..a7a3426179 100644 --- a/packages/hdom-components/src/pager.ts +++ b/packages/hdom-components/src/pager.ts @@ -1,5 +1,4 @@ -import { range } from "@thi.ng/transducers/iter/range"; -import { map } from "@thi.ng/transducers/xform/map"; +import { map, range } from "@thi.ng/transducers"; /** * Configuration options for pager components. diff --git a/packages/hdom-components/src/sparkline.ts b/packages/hdom-components/src/sparkline.ts index d322b3e6b5..6938ed664b 100644 --- a/packages/hdom-components/src/sparkline.ts +++ b/packages/hdom-components/src/sparkline.ts @@ -1,6 +1,5 @@ -import { fitClamped } from "@thi.ng/math/fit"; -import { str } from "@thi.ng/transducers/rfn/str"; -import { mapIndexed } from "@thi.ng/transducers/xform/map-indexed"; +import { fitClamped } from "@thi.ng/math"; +import { mapIndexed, str } from "@thi.ng/transducers"; export interface SparklineOpts { /** diff --git a/packages/hdom-components/test/tsconfig.json b/packages/hdom-components/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/hdom-components/test/tsconfig.json +++ b/packages/hdom-components/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/hdom-mock/package.json b/packages/hdom-mock/package.json index 4cae0a8bb4..acadd78cdc 100644 --- a/packages/hdom-mock/package.json +++ b/packages/hdom-mock/package.json @@ -1,8 +1,10 @@ { "name": "@thi.ng/hdom-mock", "version": "0.1.5", - "description": "TODO", - "main": "./index.js", + "description": "Mock base implementation for @thi.ng/hdom API", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module hdomMock api checks hdom", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -29,6 +33,7 @@ }, "dependencies": { "@thi.ng/api": "^4.2.4", + "@thi.ng/checks": "^1.5.14", "@thi.ng/hdom": "^6.1.0" }, "keywords": [ @@ -37,5 +42,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/hdom-mock/src/index.ts b/packages/hdom-mock/src/index.ts index 5c9cc3f1f9..dce84334cd 100644 --- a/packages/hdom-mock/src/index.ts +++ b/packages/hdom-mock/src/index.ts @@ -1,9 +1,13 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { isFunction } from "@thi.ng/checks/is-function"; -import { HDOMImplementation, HDOMOpts } from "@thi.ng/hdom/api"; -import { diffTree } from "@thi.ng/hdom/diff"; -import { createTree, hydrateTree } from "@thi.ng/hdom/dom"; -import { normalizeTree } from "@thi.ng/hdom/normalize"; +import { IObjectOf } from "@thi.ng/api"; +import { isFunction } from "@thi.ng/checks"; +import { + createTree, + diffTree, + HDOMImplementation, + HDOMOpts, + hydrateTree, + normalizeTree +} from "@thi.ng/hdom"; export const TEXT = Symbol(); diff --git a/packages/hdom-mock/test/tsconfig.json b/packages/hdom-mock/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/hdom-mock/test/tsconfig.json +++ b/packages/hdom-mock/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/hdom/package.json b/packages/hdom/package.json index 7d0d2fc27d..78b605829c 100644 --- a/packages/hdom/package.json +++ b/packages/hdom/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/hdom", "version": "6.1.0", "description": "Lightweight vanilla ES6 UI component trees with customizable branch-local behaviors", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module hdom api checks diff equiv errors hiccup", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@thi.ng/atom": "^1.5.8", @@ -33,15 +37,20 @@ "@thi.ng/checks": "^1.5.14", "@thi.ng/diff": "^2.0.2", "@thi.ng/equiv": "^0.1.15", + "@thi.ng/errors": "^0.1.12", "@thi.ng/hiccup": "^2.7.2" }, "keywords": [ "browser", "components", + "data driven", + "declarative", "diff", "DOM", "ES6", + "functional", "IOC", + "iterators", "reactive", "typescript", "UI", @@ -49,5 +58,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/hdom/src/api.ts b/packages/hdom/src/api.ts index 4432edda9f..05a1f643d4 100644 --- a/packages/hdom/src/api.ts +++ b/packages/hdom/src/api.ts @@ -1,4 +1,4 @@ -import { IObjectOf } from "@thi.ng/api/api"; +import { IObjectOf } from "@thi.ng/api"; export interface ILifecycle { /** diff --git a/packages/hdom/src/diff.ts b/packages/hdom/src/diff.ts index d8717af3cd..aa29cdda68 100644 --- a/packages/hdom/src/diff.ts +++ b/packages/hdom/src/diff.ts @@ -1,7 +1,5 @@ -import { IObjectOf, SEMAPHORE } from "@thi.ng/api/api"; -import { DiffMode } from "@thi.ng/diff/api"; -import { diffArray } from "@thi.ng/diff/array"; -import { diffObject } from "@thi.ng/diff/object"; +import { IObjectOf, SEMAPHORE } from "@thi.ng/api"; +import { diffArray, DiffMode, diffObject } from "@thi.ng/diff"; import { equiv as _equiv, equivArrayLike, diff --git a/packages/hdom/src/dom.ts b/packages/hdom/src/dom.ts index 712823ff9d..06aa938878 100644 --- a/packages/hdom/src/dom.ts +++ b/packages/hdom/src/dom.ts @@ -1,11 +1,10 @@ -import * as isa from "@thi.ng/checks/is-array"; -import * as isi from "@thi.ng/checks/is-not-string-iterable"; -import { SVG_NS, SVG_TAGS } from "@thi.ng/hiccup/api"; -import { css } from "@thi.ng/hiccup/css"; +import { isArray as isa, isNotStringAndIterable as isi } from "@thi.ng/checks"; +import { SVG_NS, SVG_TAGS } from "@thi.ng/hiccup"; +import { css } from "@thi.ng/hiccup"; import { HDOMImplementation, HDOMOpts } from "./api"; -const isArray = isa.isArray; -const isNotStringAndIterable = isi.isNotStringAndIterable +const isArray = isa; +const isNotStringAndIterable = isi; /** * See `HDOMImplementation` interface for further details. diff --git a/packages/hdom/src/index.ts b/packages/hdom/src/index.ts index e33ab1e275..deb7075b81 100644 --- a/packages/hdom/src/index.ts +++ b/packages/hdom/src/index.ts @@ -5,3 +5,5 @@ export * from "./dom"; export * from "./normalize"; export * from "./render-once"; export * from "./start"; + +export * from "./utils"; diff --git a/packages/hdom/src/normalize.ts b/packages/hdom/src/normalize.ts index 2cd36f3422..575fa7c46c 100644 --- a/packages/hdom/src/normalize.ts +++ b/packages/hdom/src/normalize.ts @@ -1,13 +1,11 @@ -import * as isa from "@thi.ng/checks/is-array"; -import * as insi from "@thi.ng/checks/is-not-string-iterable"; -import * as iso from "@thi.ng/checks/is-plain-object"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { NO_SPANS, TAG_REGEXP } from "@thi.ng/hiccup/api"; +import { isArray as isa, isNotStringAndIterable as isi, isPlainObject as iso } from "@thi.ng/checks"; +import { illegalArgs } from "@thi.ng/errors"; +import { NO_SPANS, TAG_REGEXP } from "@thi.ng/hiccup"; import { HDOMOpts } from "./api"; -const isArray = isa.isArray; -const isNotStringAndIterable = insi.isNotStringAndIterable; -const isPlainObject = iso.isPlainObject; +const isArray = isa; +const isNotStringAndIterable = isi; +const isPlainObject = iso; /** * Expands single hiccup element/component into its canonical form: diff --git a/packages/hdom/src/render-once.ts b/packages/hdom/src/render-once.ts index 740f558a29..63bc0b9985 100644 --- a/packages/hdom/src/render-once.ts +++ b/packages/hdom/src/render-once.ts @@ -1,4 +1,4 @@ -import { derefContext } from "@thi.ng/hiccup/deref"; +import { derefContext } from "@thi.ng/hiccup"; import { HDOMImplementation, HDOMOpts } from "./api"; import { DEFAULT_IMPL } from "./default"; import { resolveRoot } from "./utils"; diff --git a/packages/hdom/src/start.ts b/packages/hdom/src/start.ts index 6478803a9a..7efa32557c 100644 --- a/packages/hdom/src/start.ts +++ b/packages/hdom/src/start.ts @@ -1,4 +1,4 @@ -import { derefContext } from "@thi.ng/hiccup/deref"; +import { derefContext } from "@thi.ng/hiccup"; import { HDOMImplementation, HDOMOpts } from "./api"; import { DEFAULT_IMPL } from "./default"; import { resolveRoot } from "./utils"; diff --git a/packages/hdom/src/utils.ts b/packages/hdom/src/utils.ts index c2b1cdf99c..465f06addd 100644 --- a/packages/hdom/src/utils.ts +++ b/packages/hdom/src/utils.ts @@ -1,4 +1,4 @@ -import { isString } from "@thi.ng/checks/is-string"; +import { isString } from "@thi.ng/checks"; import { HDOMImplementation } from "./api"; export const resolveRoot = diff --git a/packages/hdom/test/index.ts b/packages/hdom/test/index.ts index 020c098d77..67d343e5bb 100644 --- a/packages/hdom/test/index.ts +++ b/packages/hdom/test/index.ts @@ -1,18 +1,15 @@ +import { Atom } from "@thi.ng/atom"; +import { derefContext } from "@thi.ng/hiccup"; +import { map, range } from "@thi.ng/iterators"; import * as assert from "assert"; - -import { Atom } from "@thi.ng/atom/atom"; -import { map } from "@thi.ng/iterators/map"; -import { range } from "@thi.ng/iterators/range"; import { normalizeTree } from "../src/normalize"; -import { derefContext } from "@thi.ng/hiccup/deref"; -function _check(a, b, ctx = null) { - assert.deepEqual(normalizeTree({ ctx, keys: false, span: false }, a), b); -} +const _check = + (a, b, ctx = null) => + assert.deepEqual(normalizeTree({ ctx, keys: false, span: false }, a), b); -function check(id, a, b) { - it(id, () => _check(a, b)); -} +const check = + (id, a, b) => it(id, () => _check(a, b)); describe("hdom", () => { diff --git a/packages/hdom/test/tsconfig.json b/packages/hdom/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/hdom/test/tsconfig.json +++ b/packages/hdom/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/rstream-csp/package.json b/packages/rstream-csp/package.json index e2dc43550f..e74935ac7d 100644 --- a/packages/rstream-csp/package.json +++ b/packages/rstream-csp/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/rstream-csp", "version": "0.1.125", "description": "@thi.ng/csp bridge module for @thi.ng/rstream", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc from", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module rstreamCsp csp rstream", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib from", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -41,5 +45,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/rstream-csp/src/from/channel.ts b/packages/rstream-csp/src/from/channel.ts index 6d5ca7f14d..790850eaf3 100644 --- a/packages/rstream-csp/src/from/channel.ts +++ b/packages/rstream-csp/src/from/channel.ts @@ -1,6 +1,5 @@ -import { Channel } from "@thi.ng/csp/channel"; -import { DEBUG } from "@thi.ng/rstream/api"; -import { Stream } from "@thi.ng/rstream/stream"; +import { Channel } from "@thi.ng/csp"; +import { DEBUG, Stream } from "@thi.ng/rstream"; /** * @@ -30,5 +29,5 @@ export const fromChannel = isActive = false; }; }, - `obs-${src.id}` + `channel-${src.id}` ); diff --git a/packages/rstream-csp/test/tsconfig.json b/packages/rstream-csp/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/rstream-csp/test/tsconfig.json +++ b/packages/rstream-csp/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/rstream-csp/tsconfig.json b/packages/rstream-csp/tsconfig.json index bcf03f18b4..ad49a0c5d4 100644 --- a/packages/rstream-csp/tsconfig.json +++ b/packages/rstream-csp/tsconfig.json @@ -3,7 +3,7 @@ "compilerOptions": { "outDir": ".", "module": "es6", - "target": "es6" + "target": "esnext" }, "include": [ "./src/**/*.ts" diff --git a/packages/rstream-dot/package.json b/packages/rstream-dot/package.json index 746796a435..5681c72eee 100644 --- a/packages/rstream-dot/package.json +++ b/packages/rstream-dot/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/rstream-dot", "version": "0.2.64", "description": "Graphviz DOT conversion of @thi.ng/rstream dataflow graph topologies", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module rstreamDot rstream", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -44,5 +48,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/rstream-dot/src/index.ts b/packages/rstream-dot/src/index.ts index bb0d49496e..9745ad37fe 100644 --- a/packages/rstream-dot/src/index.ts +++ b/packages/rstream-dot/src/index.ts @@ -1,8 +1,10 @@ +import { + ISubscribable, + Stream, + StreamMerge, + StreamSync +} from "@thi.ng/rstream"; import { DotOpts, Node, WalkState } from "./api"; -import { ISubscribable } from "@thi.ng/rstream/api"; -import { Stream } from "@thi.ng/rstream/stream"; -import { StreamMerge } from "@thi.ng/rstream/stream-merge"; -import { StreamSync } from "@thi.ng/rstream/stream-sync"; export * from "./api"; diff --git a/packages/rstream-dot/test/tsconfig.json b/packages/rstream-dot/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/rstream-dot/test/tsconfig.json +++ b/packages/rstream-dot/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/rstream-gestures/package.json b/packages/rstream-gestures/package.json index 07c67dd4b4..145d3532a0 100644 --- a/packages/rstream-gestures/package.json +++ b/packages/rstream-gestures/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/rstream-gestures", "version": "0.6.9", "description": "Unified mouse, mouse wheel & single-touch event stream abstraction", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module rstreamGestures api rstream transducers", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -40,11 +44,12 @@ "mouse", "mousewheel", "stream", + "rstream", "touch", "typescript" ], "publishConfig": { "access": "public" }, - "gitHead": "673bf50ff571fc65bd984d1f83929bcc69a8b394" + "sideEffects": false } \ No newline at end of file diff --git a/packages/rstream-gestures/src/index.ts b/packages/rstream-gestures/src/index.ts index 861c1c1b63..9cad9f5730 100644 --- a/packages/rstream-gestures/src/index.ts +++ b/packages/rstream-gestures/src/index.ts @@ -1,7 +1,6 @@ -import { IID } from "@thi.ng/api/api"; -import { fromEvent } from "@thi.ng/rstream/from/event"; -import { merge, StreamMerge } from "@thi.ng/rstream/stream-merge"; -import { map } from "@thi.ng/transducers/xform/map"; +import { IID } from "@thi.ng/api"; +import { fromEvent, merge, StreamMerge } from "@thi.ng/rstream"; +import { map } from "@thi.ng/transducers"; export const enum GestureType { START, diff --git a/packages/rstream-gestures/test/tsconfig.json b/packages/rstream-gestures/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/rstream-gestures/test/tsconfig.json +++ b/packages/rstream-gestures/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/rstream-graph/package.json b/packages/rstream-graph/package.json index b769a30180..1bc3c62df1 100644 --- a/packages/rstream-graph/package.json +++ b/packages/rstream-graph/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/rstream-graph", "version": "2.1.50", "description": "Declarative dataflow graph construction for @thi.ng/rstream", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc nodes", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module rstreamGraph api checks errors paths resolve-map rstream transducers", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -42,10 +46,12 @@ "ES6", "graph", "reactive", + "stream", "rstream", "typescript" ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/rstream-graph/src/api.ts b/packages/rstream-graph/src/api.ts index 17e8b6d9ec..cffd521299 100644 --- a/packages/rstream-graph/src/api.ts +++ b/packages/rstream-graph/src/api.ts @@ -1,8 +1,8 @@ -import { Fn, IObjectOf } from "@thi.ng/api/api"; +import { Fn, IObjectOf } from "@thi.ng/api"; import { Path } from "@thi.ng/paths"; import { ResolveFn } from "@thi.ng/resolve-map"; -import { ISubscribable } from "@thi.ng/rstream/api"; -import { Transducer } from "@thi.ng/transducers/api"; +import { ISubscribable } from "@thi.ng/rstream"; +import { Transducer } from "@thi.ng/transducers"; /** * A function which constructs and returns an `ISubscribable` using diff --git a/packages/rstream-graph/src/graph.ts b/packages/rstream-graph/src/graph.ts index a07afb0056..83bca12679 100644 --- a/packages/rstream-graph/src/graph.ts +++ b/packages/rstream-graph/src/graph.ts @@ -1,17 +1,17 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { IAtom } from "@thi.ng/atom/api"; -import { isFunction } from "@thi.ng/checks/is-function"; -import { isPlainObject } from "@thi.ng/checks/is-plain-object"; -import { isString } from "@thi.ng/checks/is-string"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { IObjectOf } from "@thi.ng/api"; +import { IAtom } from "@thi.ng/atom"; +import { isFunction, isPlainObject, isString } from "@thi.ng/checks"; +import { illegalArgs } from "@thi.ng/errors"; import { getIn } from "@thi.ng/paths"; import { absPath, resolve, ResolveFn } from "@thi.ng/resolve-map"; -import { ISubscribable } from "@thi.ng/rstream/api"; -import { fromIterableSync } from "@thi.ng/rstream/from/iterable"; -import { fromView } from "@thi.ng/rstream/from/view"; -import { StreamSync, sync } from "@thi.ng/rstream/stream-sync"; -import { Transducer } from "@thi.ng/transducers/api"; -import { map } from "@thi.ng/transducers/xform/map"; +import { + fromIterableSync, + fromView, + ISubscribable, + StreamSync, + sync +} from "@thi.ng/rstream"; +import { map, Transducer } from "@thi.ng/transducers"; import { Graph, GraphSpec, diff --git a/packages/rstream-graph/src/nodes/extract.ts b/packages/rstream-graph/src/nodes/extract.ts index 98b092ec57..6a4bbcd773 100644 --- a/packages/rstream-graph/src/nodes/extract.ts +++ b/packages/rstream-graph/src/nodes/extract.ts @@ -1,6 +1,5 @@ import { getIn, Path } from "@thi.ng/paths"; -import { map } from "@thi.ng/transducers/xform/map"; - +import { map } from "@thi.ng/transducers"; import { NodeFactory } from "../api"; import { node1 } from "../graph"; diff --git a/packages/rstream-graph/src/nodes/math.ts b/packages/rstream-graph/src/nodes/math.ts index 6878a3c3ec..7e0b76b02b 100644 --- a/packages/rstream-graph/src/nodes/math.ts +++ b/packages/rstream-graph/src/nodes/math.ts @@ -1,6 +1,5 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { map } from "@thi.ng/transducers/xform/map"; - +import { IObjectOf } from "@thi.ng/api"; +import { map } from "@thi.ng/transducers"; import { NodeFactory } from "../api"; import { node } from "../graph"; diff --git a/packages/rstream-graph/test/index.ts b/packages/rstream-graph/test/index.ts index ab6d50717f..1fa9786f8b 100644 --- a/packages/rstream-graph/test/index.ts +++ b/packages/rstream-graph/test/index.ts @@ -1,8 +1,7 @@ import { Atom } from "@thi.ng/atom"; import * as rs from "@thi.ng/rstream"; -import { map } from "@thi.ng/transducers/xform/map"; +import { map } from "@thi.ng/transducers"; import * as assert from "assert"; - import * as rsg from "../src"; describe("rstream-graph", () => { diff --git a/packages/rstream-graph/test/tsconfig.json b/packages/rstream-graph/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/rstream-graph/test/tsconfig.json +++ b/packages/rstream-graph/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/rstream-log/package.json b/packages/rstream-log/package.json index ea40694367..399c00a7be 100644 --- a/packages/rstream-log/package.json +++ b/packages/rstream-log/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/rstream-log", "version": "1.0.76", "description": "Structured, multilevel & hierarchical loggers based on @thi.ng/rstream", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc output xform", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module rstreamLog api checks errors rstream transducers", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -47,5 +51,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/rstream-log/src/api.ts b/packages/rstream-log/src/api.ts index 38942c1ca8..35356cf87b 100644 --- a/packages/rstream-log/src/api.ts +++ b/packages/rstream-log/src/api.ts @@ -1,5 +1,5 @@ -import { IID } from "@thi.ng/api/api"; -import { ISubscribable } from "@thi.ng/rstream/api"; +import { IID } from "@thi.ng/api"; +import { ISubscribable } from "@thi.ng/rstream"; export const enum Level { FINE, diff --git a/packages/rstream-log/src/logger.ts b/packages/rstream-log/src/logger.ts index 226fba8968..c662eb0c97 100644 --- a/packages/rstream-log/src/logger.ts +++ b/packages/rstream-log/src/logger.ts @@ -1,8 +1,5 @@ -import { illegalArity } from "@thi.ng/errors/illegal-arity"; -import { ISubscribable } from "@thi.ng/rstream/api"; -import { StreamMerge } from "@thi.ng/rstream/stream-merge"; -import { nextID } from "@thi.ng/rstream/utils/idgen"; - +import { illegalArity } from "@thi.ng/errors"; +import { ISubscribable, nextID, StreamMerge } from "@thi.ng/rstream"; import { ILogger, Level, LogEntry } from "./api"; export class Logger extends StreamMerge implements diff --git a/packages/rstream-log/src/output/console.ts b/packages/rstream-log/src/output/console.ts index 3c1da18296..8d93f3a145 100644 --- a/packages/rstream-log/src/output/console.ts +++ b/packages/rstream-log/src/output/console.ts @@ -1 +1 @@ -export { trace as writeConsole } from "@thi.ng/rstream/subs/trace"; +export { trace as writeConsole } from "@thi.ng/rstream"; diff --git a/packages/rstream-log/src/output/file.ts b/packages/rstream-log/src/output/file.ts index ef410ea80f..3e0d153e2f 100644 --- a/packages/rstream-log/src/output/file.ts +++ b/packages/rstream-log/src/output/file.ts @@ -1,6 +1,6 @@ -import { isNode } from "@thi.ng/checks/is-node"; -import { unsupported } from "@thi.ng/errors/unsupported"; -import { ISubscriber } from "@thi.ng/rstream/api"; +import { isNode } from "@thi.ng/checks"; +import { unsupported } from "@thi.ng/errors"; +import { ISubscriber } from "@thi.ng/rstream"; export const writeFile = (path: string): ISubscriber => { diff --git a/packages/rstream-log/src/xform/filter.ts b/packages/rstream-log/src/xform/filter.ts index 4fdfb48096..fa3496e097 100644 --- a/packages/rstream-log/src/xform/filter.ts +++ b/packages/rstream-log/src/xform/filter.ts @@ -1,7 +1,6 @@ -import { isString } from "@thi.ng/checks/is-string"; -import { Transducer } from "@thi.ng/transducers/api"; -import { filter } from "@thi.ng/transducers/xform/filter"; - +import { isString } from "@thi.ng/checks"; +import { Transducer } from "@thi.ng/transducers"; +import { filter } from "@thi.ng/transducers"; import { Level, LogEntry } from "../api"; export const onlyLevel = diff --git a/packages/rstream-log/src/xform/format.ts b/packages/rstream-log/src/xform/format.ts index 93690007d6..cb4560b320 100644 --- a/packages/rstream-log/src/xform/format.ts +++ b/packages/rstream-log/src/xform/format.ts @@ -1,5 +1,4 @@ -import { Transducer } from "@thi.ng/transducers/api"; -import { map } from "@thi.ng/transducers/xform/map"; +import { map, Transducer } from "@thi.ng/transducers"; import { __Level, BodyFormat, diff --git a/packages/rstream-log/test/tsconfig.json b/packages/rstream-log/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/rstream-log/test/tsconfig.json +++ b/packages/rstream-log/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/rstream-query/package.json b/packages/rstream-query/package.json index b1c1a98590..acadeea0b0 100644 --- a/packages/rstream-query/package.json +++ b/packages/rstream-query/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/rstream-query", "version": "0.3.63", "description": "@thi.ng/rstream based triple store & reactive query engine", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module rstreamQuery api associative checks equiv errors rstream rstream-dot transducers", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -53,5 +57,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/rstream-query/src/api.ts b/packages/rstream-query/src/api.ts index a23af9c641..905ffb9ab9 100644 --- a/packages/rstream-query/src/api.ts +++ b/packages/rstream-query/src/api.ts @@ -1,5 +1,5 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { ISubscribable } from "@thi.ng/rstream/api"; +import { IObjectOf } from "@thi.ng/api"; +import { ISubscribable } from "@thi.ng/rstream"; export let DEBUG = false; diff --git a/packages/rstream-query/src/convert.ts b/packages/rstream-query/src/convert.ts index ca03bee3bc..4a4105a3ef 100644 --- a/packages/rstream-query/src/convert.ts +++ b/packages/rstream-query/src/convert.ts @@ -1,8 +1,5 @@ -import { isArray } from "@thi.ng/checks/is-array"; -import { isPlainObject } from "@thi.ng/checks/is-plain-object"; -import { concat } from "@thi.ng/transducers/iter/concat"; -import { pairs } from "@thi.ng/transducers/iter/pairs"; -import { mapcat } from "@thi.ng/transducers/xform/mapcat"; +import { isArray, isPlainObject } from "@thi.ng/checks"; +import { concat, pairs, mapcat } from "@thi.ng/transducers"; let NEXT_ID = 0; diff --git a/packages/rstream-query/src/pattern.ts b/packages/rstream-query/src/pattern.ts index 97ae8667bc..66282f7f51 100644 --- a/packages/rstream-query/src/pattern.ts +++ b/packages/rstream-query/src/pattern.ts @@ -1,5 +1,4 @@ -import { repeatedly } from "@thi.ng/transducers/iter/repeatedly"; - +import { repeatedly } from "@thi.ng/transducers"; import { PathPattern, Pattern } from "./api"; import { autoQVar, isQVar, qvarName } from "./qvar"; diff --git a/packages/rstream-query/src/qvar.ts b/packages/rstream-query/src/qvar.ts index 5e0373fdf4..a5a7b597cd 100644 --- a/packages/rstream-query/src/qvar.ts +++ b/packages/rstream-query/src/qvar.ts @@ -1,4 +1,4 @@ -import { isString } from "@thi.ng/checks/is-string"; +import { isString } from "@thi.ng/checks"; import { Triple } from "./api"; const AUTO_QVAR_PREFIX = "?__q"; diff --git a/packages/rstream-query/src/store.ts b/packages/rstream-query/src/store.ts index 14f90bd59e..af25261415 100644 --- a/packages/rstream-query/src/store.ts +++ b/packages/rstream-query/src/store.ts @@ -1,28 +1,32 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { intersection } from "@thi.ng/associative/intersection"; -import { join } from "@thi.ng/associative/join"; +import { IObjectOf } from "@thi.ng/api"; +import { intersection, join } from "@thi.ng/associative"; import { equiv } from "@thi.ng/equiv"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { illegalArgs } from "@thi.ng/errors"; +import { + ISubscribable, + nextID, + Stream, + Subscription, + sync +} from "@thi.ng/rstream"; import { DotOpts, IToDot, toDot, walk } from "@thi.ng/rstream-dot"; -import { ISubscribable } from "@thi.ng/rstream/api"; -import { Stream } from "@thi.ng/rstream/stream"; -import { sync } from "@thi.ng/rstream/stream-sync"; -import { Subscription } from "@thi.ng/rstream/subscription"; -import { nextID } from "@thi.ng/rstream/utils/idgen"; -import { Reducer, Transducer } from "@thi.ng/transducers/api"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { compR } from "@thi.ng/transducers/func/compr"; -import { keySelector } from "@thi.ng/transducers/func/key-selector"; -import { assocObj } from "@thi.ng/transducers/rfn/assoc-obj"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { dedupe } from "@thi.ng/transducers/xform/dedupe"; -import { map } from "@thi.ng/transducers/xform/map"; -import { mapIndexed } from "@thi.ng/transducers/xform/map-indexed"; +import { + assocObj, + comp, + compR, + dedupe, + keySelector, + map, + mapIndexed, + Reducer, + transduce, + Transducer +} from "@thi.ng/transducers"; import { BindFn, DEBUG, diff --git a/packages/rstream-query/test/tsconfig.json b/packages/rstream-query/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/rstream-query/test/tsconfig.json +++ b/packages/rstream-query/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/rstream/package.json b/packages/rstream/package.json index a0db67dd8c..9d394ddab7 100644 --- a/packages/rstream/package.json +++ b/packages/rstream/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/rstream", "version": "1.14.9", "description": "Reactive multi-tap streams, dataflow & transformation pipeline constructs", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc from subs utils", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module rstream api associative atom checks errors paths transducers", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib from subs utils", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -50,5 +54,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/rstream/src/api.ts b/packages/rstream/src/api.ts index 4de3d382a9..cd7a98ba41 100644 --- a/packages/rstream/src/api.ts +++ b/packages/rstream/src/api.ts @@ -1,6 +1,5 @@ -import { IDeref, IID } from "@thi.ng/api/api"; -import { Transducer } from "@thi.ng/transducers/api"; - +import { IDeref, IID } from "@thi.ng/api"; +import { Transducer } from "@thi.ng/transducers"; import { Stream } from "./stream"; import { Subscription } from "./subscription"; diff --git a/packages/rstream/src/from/atom.ts b/packages/rstream/src/from/atom.ts index 4918b1aea7..a3bcded55b 100644 --- a/packages/rstream/src/from/atom.ts +++ b/packages/rstream/src/from/atom.ts @@ -1,5 +1,5 @@ -import { Predicate2 } from "@thi.ng/api/api"; -import { ReadonlyAtom } from "@thi.ng/atom/api"; +import { Predicate2 } from "@thi.ng/api"; +import { ReadonlyAtom } from "@thi.ng/atom"; import { Stream } from "../stream"; import { nextID } from "../utils/idgen"; diff --git a/packages/rstream/src/from/promises.ts b/packages/rstream/src/from/promises.ts index e270152323..13919b3681 100644 --- a/packages/rstream/src/from/promises.ts +++ b/packages/rstream/src/from/promises.ts @@ -1,5 +1,4 @@ -import { mapcat } from "@thi.ng/transducers/xform/mapcat"; - +import { mapcat } from "@thi.ng/transducers"; import { Subscription } from "../subscription"; import { fromPromise } from "./promise"; diff --git a/packages/rstream/src/from/raf.ts b/packages/rstream/src/from/raf.ts index 5709308fef..edf0701c04 100644 --- a/packages/rstream/src/from/raf.ts +++ b/packages/rstream/src/from/raf.ts @@ -1,4 +1,4 @@ -import { isNode } from "@thi.ng/checks/is-node"; +import { isNode } from "@thi.ng/checks"; import { Stream } from "../stream"; import { nextID } from "../utils/idgen"; import { fromInterval } from "./interval"; diff --git a/packages/rstream/src/from/view.ts b/packages/rstream/src/from/view.ts index 5727abf681..62cf8f91ab 100644 --- a/packages/rstream/src/from/view.ts +++ b/packages/rstream/src/from/view.ts @@ -1,6 +1,6 @@ -import { Predicate2 } from "@thi.ng/api/api"; -import { ReadonlyAtom, ViewTransform } from "@thi.ng/atom/api"; -import { View } from "@thi.ng/atom/view"; +import { Predicate2 } from "@thi.ng/api"; +import { ReadonlyAtom, ViewTransform } from "@thi.ng/atom"; +import { View } from "@thi.ng/atom"; import { Path } from "@thi.ng/paths"; import { Stream } from "../stream"; import { nextID } from "../utils/idgen"; diff --git a/packages/rstream/src/index.ts b/packages/rstream/src/index.ts index 007933fc25..3e76db7cf1 100644 --- a/packages/rstream/src/index.ts +++ b/packages/rstream/src/index.ts @@ -25,4 +25,5 @@ export * from "./subs/trace"; export * from "./subs/transduce"; export * from "./subs/tunnel"; +export * from "./utils/idgen"; export * from "./utils/worker"; diff --git a/packages/rstream/src/pubsub.ts b/packages/rstream/src/pubsub.ts index 3eab862b94..f357d53b9d 100644 --- a/packages/rstream/src/pubsub.ts +++ b/packages/rstream/src/pubsub.ts @@ -1,7 +1,7 @@ -import { Predicate2 } from "@thi.ng/api/api"; -import { EquivMap } from "@thi.ng/associative/equiv-map"; -import { unsupported } from "@thi.ng/errors/unsupported"; -import { Transducer } from "@thi.ng/transducers/api"; +import { Predicate2 } from "@thi.ng/api"; +import { EquivMap } from "@thi.ng/associative"; +import { unsupported } from "@thi.ng/errors"; +import { Transducer } from "@thi.ng/transducers"; import { DEBUG, ISubscriber } from "./api"; import { Subscription, subscription } from "./subscription"; import { nextID } from "./utils/idgen"; diff --git a/packages/rstream/src/stream-merge.ts b/packages/rstream/src/stream-merge.ts index d85de9b07b..6ba2696e3c 100644 --- a/packages/rstream/src/stream-merge.ts +++ b/packages/rstream/src/stream-merge.ts @@ -1,5 +1,5 @@ -import { IID } from "@thi.ng/api/api"; -import { Transducer } from "@thi.ng/transducers/api"; +import { IID } from "@thi.ng/api"; +import { Transducer } from "@thi.ng/transducers"; import { ISubscribable, State } from "./api"; import { Subscription } from "./subscription"; import { nextID } from "./utils/idgen"; diff --git a/packages/rstream/src/stream-sync.ts b/packages/rstream/src/stream-sync.ts index 9e84af3855..dd3c46196d 100644 --- a/packages/rstream/src/stream-sync.ts +++ b/packages/rstream/src/stream-sync.ts @@ -1,10 +1,12 @@ -import { IID, IObjectOf } from "@thi.ng/api/api"; -import { isPlainObject } from "@thi.ng/checks/is-plain-object"; -import { Transducer } from "@thi.ng/transducers/api"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { labeled } from "@thi.ng/transducers/xform/labeled"; -import { mapVals } from "@thi.ng/transducers/xform/map-vals"; -import { partitionSync } from "@thi.ng/transducers/xform/partition-sync"; +import { IID, IObjectOf } from "@thi.ng/api"; +import { isPlainObject } from "@thi.ng/checks"; +import { + comp, + labeled, + mapVals, + partitionSync, + Transducer +} from "@thi.ng/transducers"; import { ISubscribable, State } from "./api"; import { Subscription } from "./subscription"; import { nextID } from "./utils/idgen"; diff --git a/packages/rstream/src/stream.ts b/packages/rstream/src/stream.ts index e18066a007..dc96d2902e 100644 --- a/packages/rstream/src/stream.ts +++ b/packages/rstream/src/stream.ts @@ -1,6 +1,6 @@ -import { isString } from "@thi.ng/checks/is-string"; -import { illegalArity } from "@thi.ng/errors/illegal-arity"; -import { Transducer } from "@thi.ng/transducers/api"; +import { isString } from "@thi.ng/checks"; +import { illegalArity } from "@thi.ng/errors"; +import { Transducer } from "@thi.ng/transducers"; import { DEBUG, IStream, diff --git a/packages/rstream/src/subs/bisect.ts b/packages/rstream/src/subs/bisect.ts index 5d8d7b03eb..a3e7068fdf 100644 --- a/packages/rstream/src/subs/bisect.ts +++ b/packages/rstream/src/subs/bisect.ts @@ -1,5 +1,4 @@ -import { Predicate } from "@thi.ng/api/api"; - +import { Predicate } from "@thi.ng/api"; import { ISubscriber } from "../api"; import { PubSub } from "../pubsub"; diff --git a/packages/rstream/src/subs/post-worker.ts b/packages/rstream/src/subs/post-worker.ts index 581263b593..f1fc5d2df2 100644 --- a/packages/rstream/src/subs/post-worker.ts +++ b/packages/rstream/src/subs/post-worker.ts @@ -1,6 +1,5 @@ -import { isTransferable } from "@thi.ng/checks/is-transferable"; -import { isTypedArray } from "@thi.ng/checks/is-typedarray"; - +import { isTransferable } from "@thi.ng/checks"; +import { isTypedArray } from "@thi.ng/checks"; import { DEBUG, ISubscriber } from "../api"; import { makeWorker } from "../utils/worker"; diff --git a/packages/rstream/src/subs/resolve.ts b/packages/rstream/src/subs/resolve.ts index 8973c7d873..ef1323751c 100644 --- a/packages/rstream/src/subs/resolve.ts +++ b/packages/rstream/src/subs/resolve.ts @@ -1,4 +1,4 @@ -import { IID } from "@thi.ng/api/api"; +import { IID } from "@thi.ng/api"; import { __State, DEBUG, State } from "../api"; import { Subscription } from "../subscription"; import { nextID } from "../utils/idgen"; diff --git a/packages/rstream/src/subs/sidechain-partition.ts b/packages/rstream/src/subs/sidechain-partition.ts index f39c331e4a..b05d8efaab 100644 --- a/packages/rstream/src/subs/sidechain-partition.ts +++ b/packages/rstream/src/subs/sidechain-partition.ts @@ -1,4 +1,4 @@ -import { Predicate } from "@thi.ng/api/api"; +import { Predicate } from "@thi.ng/api"; import { ISubscribable, State } from "../api"; import { Subscription } from "../subscription"; import { nextID } from "../utils/idgen"; diff --git a/packages/rstream/src/subs/sidechain-toggle.ts b/packages/rstream/src/subs/sidechain-toggle.ts index 5c0aac4e00..fe2983dad5 100644 --- a/packages/rstream/src/subs/sidechain-toggle.ts +++ b/packages/rstream/src/subs/sidechain-toggle.ts @@ -1,4 +1,4 @@ -import { Predicate } from "@thi.ng/api/api"; +import { Predicate } from "@thi.ng/api"; import { ISubscribable } from "../api"; import { Subscription } from "../subscription"; import { nextID } from "../utils/idgen"; diff --git a/packages/rstream/src/subs/transduce.ts b/packages/rstream/src/subs/transduce.ts index 22d7b8231b..1be3645bd2 100644 --- a/packages/rstream/src/subs/transduce.ts +++ b/packages/rstream/src/subs/transduce.ts @@ -1,6 +1,5 @@ -import { Reducer, Transducer } from "@thi.ng/transducers/api"; -import { isReduced } from "@thi.ng/transducers/reduced"; - +import { Reducer, Transducer } from "@thi.ng/transducers"; +import { isReduced } from "@thi.ng/transducers"; import { Subscription } from "../subscription"; /** diff --git a/packages/rstream/src/subscription.ts b/packages/rstream/src/subscription.ts index 4ede83e114..d2357da73b 100644 --- a/packages/rstream/src/subscription.ts +++ b/packages/rstream/src/subscription.ts @@ -1,13 +1,14 @@ -import { IDeref, SEMAPHORE } from "@thi.ng/api/api"; -import { implementsFunction } from "@thi.ng/checks/implements-function"; -import { isFunction } from "@thi.ng/checks/is-function"; -import { isString } from "@thi.ng/checks/is-string"; -import { illegalArity } from "@thi.ng/errors/illegal-arity"; -import { illegalState } from "@thi.ng/errors/illegal-state"; -import { Reducer, Transducer } from "@thi.ng/transducers/api"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { isReduced, unreduced } from "@thi.ng/transducers/reduced"; -import { push } from "@thi.ng/transducers/rfn/push"; +import { IDeref, SEMAPHORE } from "@thi.ng/api"; +import { implementsFunction, isFunction, isString } from "@thi.ng/checks"; +import { illegalArity, illegalState } from "@thi.ng/errors"; +import { + comp, + isReduced, + push, + Reducer, + Transducer, + unreduced +} from "@thi.ng/transducers"; import { __State, DEBUG, diff --git a/packages/rstream/src/utils/worker.ts b/packages/rstream/src/utils/worker.ts index 20588eba9a..017d98a747 100644 --- a/packages/rstream/src/utils/worker.ts +++ b/packages/rstream/src/utils/worker.ts @@ -1,6 +1,6 @@ -export function inlineWorker(src: string) { - return makeWorker(new Blob([src], { type: "text/javascript" })); -} +export const inlineWorker = + (src: string) => + makeWorker(new Blob([src], { type: "text/javascript" })); export const makeWorker = (worker: Worker | string | Blob) => diff --git a/packages/rstream/test/tsconfig.json b/packages/rstream/test/tsconfig.json index c93bb84899..2c9c12a650 100644 --- a/packages/rstream/test/tsconfig.json +++ b/packages/rstream/test/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "es6", - "target": "es6" + "module": "commonjs", }, "include": [ "./**/*.ts", diff --git a/packages/transducers-hdom/package.json b/packages/transducers-hdom/package.json index bedf9e3ec6..7013d62553 100644 --- a/packages/transducers-hdom/package.json +++ b/packages/transducers-hdom/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/transducers-hdom", "version": "1.2.16", "description": "Transducer based UI updater for @thi.ng/hdom", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,12 +14,14 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn clean && tsc --declaration", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module transducersHdom hdom hiccup transducers", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public", - "test": "rimraf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -28,8 +32,8 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/checks": "^1.5.14", "@thi.ng/hdom": "^6.1.0", + "@thi.ng/hiccup": "^2.7.2", "@thi.ng/transducers": "^2.3.2" }, "keywords": [ @@ -44,5 +48,6 @@ ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/transducers-hdom/src/index.ts b/packages/transducers-hdom/src/index.ts index 58a1c03194..2174571045 100644 --- a/packages/transducers-hdom/src/index.ts +++ b/packages/transducers-hdom/src/index.ts @@ -1,9 +1,11 @@ -import { HDOMImplementation, HDOMOpts } from "@thi.ng/hdom/api"; -import { DEFAULT_IMPL } from "@thi.ng/hdom/default"; -import { resolveRoot } from "@thi.ng/hdom/utils"; -import { derefContext } from "@thi.ng/hiccup/deref"; -import { Transducer } from "@thi.ng/transducers/api"; -import { scan } from "@thi.ng/transducers/xform/scan"; +import { + DEFAULT_IMPL, + HDOMImplementation, + HDOMOpts, + resolveRoot +} from "@thi.ng/hdom"; +import { derefContext } from "@thi.ng/hiccup"; +import { scan, Transducer } from "@thi.ng/transducers"; /** * Side-effecting & stateful transducer which receives @thi.ng/hdom diff --git a/scripts/bundle-module b/scripts/bundle-module index cd259fe86d..2c2890eee5 100755 --- a/scripts/bundle-module +++ b/scripts/bundle-module @@ -4,10 +4,16 @@ const rollup = require("rollup"); const terser = require("terser"); const gz = require("gzip-size"); +const camelCase = + (x) => x.replace(/\-+(\w)/g, (_, c) => c.toUpperCase()); + +const size = + (x) => (x / 1024).toFixed(2) + "KB"; + const name = process.argv[2]; const deps = process.argv.slice(3).reduce( - (acc, x) => (acc[`@thi.ng/${x}`] = `thi.ng.${x}`, acc), + (acc, x) => (acc[`@thi.ng/${x}`] = `thi.ng.${camelCase(x)}`, acc), {} ); @@ -22,8 +28,6 @@ const terserOpts = { ecma: 6 }; -const size = (x) => (x / 1024).toFixed(2) + "KB"; - const buildVersion = async (dest, outOpts) => { console.log(`bundling (${outOpts.format}): ${dest}`); const bundle = await rollup.rollup(inOpts); @@ -33,12 +37,10 @@ const buildVersion = async (dest, outOpts) => { console.log(`\tsize: ${size(terserOut.code.length)} / gzipped: ${size(gz.sync(terserOut.code))}`); }; -if (!fs.existsSync("lib")) { - fs.mkdirSync("lib"); -} - const build = async () => { + !fs.existsSync("lib") && fs.mkdirSync("lib"); + await buildVersion( "lib/index.js", { From b198c1953a8613af73fc7b584af00873d383df20 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 8 Jan 2019 14:43:55 +0000 Subject: [PATCH 218/333] fix(hiccup-markdown): re-export TagFactories interface --- packages/hiccup-markdown/src/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/hiccup-markdown/src/index.ts b/packages/hiccup-markdown/src/index.ts index 96dd664954..6bfb5018e7 100644 --- a/packages/hiccup-markdown/src/index.ts +++ b/packages/hiccup-markdown/src/index.ts @@ -1,2 +1,3 @@ +export * from "./api"; export * from "./parse"; export * from "./serialize"; From 227be4b52bd5e8055deedf80c836026d763f50e5 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 8 Jan 2019 14:45:39 +0000 Subject: [PATCH 219/333] fix(pointfree-lang): update NodeType handling --- packages/pointfree-lang/src/api.ts | 4 +- packages/pointfree-lang/src/grammar.pegjs | 60 +++++++++++------------ packages/pointfree-lang/src/index.ts | 3 +- packages/pointfree-lang/tsconfig.json | 3 +- 4 files changed, 35 insertions(+), 35 deletions(-) diff --git a/packages/pointfree-lang/src/api.ts b/packages/pointfree-lang/src/api.ts index 66e48dab41..b5070a1184 100644 --- a/packages/pointfree-lang/src/api.ts +++ b/packages/pointfree-lang/src/api.ts @@ -1,4 +1,4 @@ -import { IObjectOf } from "@thi.ng/api/api"; +import { IObjectOf } from "@thi.ng/api"; import * as pf from "@thi.ng/pointfree"; export interface ASTNode { @@ -34,7 +34,7 @@ export const enum NodeType { /** * Reverse lookup for `NodeType` enums */ -export const __NodeType = (exports).NodeType; +// export const __NodeType = (exports).NodeType; export const ALIASES: IObjectOf = { "?drop": pf.dropif, diff --git a/packages/pointfree-lang/src/grammar.pegjs b/packages/pointfree-lang/src/grammar.pegjs index 0b628fee70..7176fc2892 100644 --- a/packages/pointfree-lang/src/grammar.pegjs +++ b/packages/pointfree-lang/src/grammar.pegjs @@ -1,19 +1,19 @@ { - const __NodeType = require("./api").__NodeType; - - // const __NodeType = {}; - // __NodeType[__NodeType["SYM"] = 1] = "SYM"; - // __NodeType[__NodeType["WORD"] = 2] = "WORD"; - // __NodeType[__NodeType["VAR_DEREF"] = 3] = "VAR_DEREF"; - // __NodeType[__NodeType["VAR_STORE"] = 4] = "VAR_STORE"; - // __NodeType[__NodeType["NIL"] = 5] = "NIL"; - // __NodeType[__NodeType["NUMBER"] = 6] = "NUMBER"; - // __NodeType[__NodeType["BOOLEAN"] = 7] = "BOOLEAN"; - // __NodeType[__NodeType["STRING"] = 8] = "STRING"; - // __NodeType[__NodeType["ARRAY"] = 9] = "ARRAY"; - // __NodeType[__NodeType["OBJ"] = 10] = "OBJ"; - // __NodeType[__NodeType["COMMENT"] = 11] = "COMMENT"; - // __NodeType[__NodeType["STACK_COMMENT"] = 12] = "STACK_COMMENT"; + // const __NodeType = require("./api").__NodeType; + + const NodeType = {}; + NodeType[NodeType["SYM"] = 1] = "SYM"; + NodeType[NodeType["WORD"] = 2] = "WORD"; + NodeType[NodeType["VAR_DEREF"] = 3] = "VAR_DEREF"; + NodeType[NodeType["VAR_STORE"] = 4] = "VAR_STORE"; + NodeType[NodeType["NIL"] = 5] = "NIL"; + NodeType[NodeType["NUMBER"] = 6] = "NUMBER"; + NodeType[NodeType["BOOLEAN"] = 7] = "BOOLEAN"; + NodeType[NodeType["STRING"] = 8] = "STRING"; + NodeType[NodeType["ARRAY"] = 9] = "ARRAY"; + NodeType[NodeType["OBJ"] = 10] = "OBJ"; + NodeType[NodeType["COMMENT"] = 11] = "COMMENT"; + NodeType[NodeType["STACK_COMMENT"] = 12] = "STACK_COMMENT"; const ast = (node) => { const loc = location().start; @@ -42,7 +42,7 @@ NonWordExpr Word = ":" __ id:Sym locals:LocalVars? body:NonWordExpr+ ";" { - return { type: __NodeType.WORD, id: id.id, locals, body}; + return { type: NodeType.WORD, id: id.id, locals, body}; } LocalVars @@ -55,12 +55,12 @@ SymList Array = "[" body:NonWordExpr* "]" { - return { type: __NodeType.ARRAY, body }; + return { type: NodeType.ARRAY, body }; } Obj = "{" _ body:ObjPair* "}" { - return { type: __NodeType.OBJ, body }; + return { type: NodeType.OBJ, body }; } ObjPair @@ -92,17 +92,17 @@ Atom Nil = "nil" { - return {type: __NodeType.NIL, body: null}; + return {type: NodeType.NIL, body: null}; } Boolean = $("T" / "F") { - return {type: __NodeType.BOOLEAN, body: text() == "T"}; + return {type: NodeType.BOOLEAN, body: text() == "T"}; } Sym = id:$((Alpha / SymChars) (AlphaNum / SymChars)*) { - return {type: __NodeType.SYM, id}; + return {type: NodeType.SYM, id}; } SymChars @@ -114,35 +114,35 @@ Var VarDeref = "@" id:Sym { - return {type: __NodeType.VAR_DEREF, id: id.id} + return {type: NodeType.VAR_DEREF, id: id.id} } VarStore = id:Sym "!" { - return {type: __NodeType.VAR_STORE, id: id.id} + return {type: NodeType.VAR_STORE, id: id.id} } LitQuote = "'" body:NonWordExpr { - return {type: __NodeType.ARRAY, body: [body]}; + return {type: NodeType.ARRAY, body: [body]}; } Comment = "("+ body:$(!")" .)* ")" { return body.indexOf("--") > 0 ? { - type: __NodeType.STACK_COMMENT, + type: NodeType.STACK_COMMENT, body: body.split("--").map(x => x.trim()) } : { - type: __NodeType.COMMENT, + type: NodeType.COMMENT, body: body.trim() }; } String = "\"" body:$(!"\"" .)* "\"" { - return {type: __NodeType.STRING, body }; + return {type: NodeType.STRING, body }; } Number @@ -154,12 +154,12 @@ Sign = [-+] Binary = "0b" n:$[01]+ { - return {type: __NodeType.NUMBER, radix: 2, body: parseInt(n, 2)}; + return {type: NodeType.NUMBER, radix: 2, body: parseInt(n, 2)}; } Hex = "0x" n:$[0-9a-fA-F]+ { - return {type: __NodeType.NUMBER, radix: 16, body: parseInt(n, 16)}; + return {type: NodeType.NUMBER, radix: 16, body: parseInt(n, 16)}; } Int @@ -170,7 +170,7 @@ Uint Decimal = Int ("." Uint?)? ("e" Int)? { - return {type: __NodeType.NUMBER, body: parseFloat(text())}; + return {type: NodeType.NUMBER, body: parseFloat(text())}; } AlphaNum diff --git a/packages/pointfree-lang/src/index.ts b/packages/pointfree-lang/src/index.ts index cf217b2987..29186c09ff 100644 --- a/packages/pointfree-lang/src/index.ts +++ b/packages/pointfree-lang/src/index.ts @@ -3,7 +3,6 @@ import { illegalArgs, illegalState } from "@thi.ng/errors"; import * as pf from "@thi.ng/pointfree"; import { - __NodeType, ALIASES, ASTNode, NodeType, @@ -186,7 +185,7 @@ const endvar = (id: string) => (ctx: pf.StackContext) => { * @param state */ const visit = (node: ASTNode, ctx: pf.StackContext, state: VisitorState) => { - DEBUG && console.log("visit", __NodeType[node.type], node, ctx[0].toString()); + DEBUG && console.log("visit", node.type, node, ctx[0].toString()); switch (node.type) { case NodeType.SYM: return visitSym(node, ctx, state); diff --git a/packages/pointfree-lang/tsconfig.json b/packages/pointfree-lang/tsconfig.json index bcf03f18b4..faed4e5fe7 100644 --- a/packages/pointfree-lang/tsconfig.json +++ b/packages/pointfree-lang/tsconfig.json @@ -3,7 +3,8 @@ "compilerOptions": { "outDir": ".", "module": "es6", - "target": "es6" + "target": "es6", + "preserveConstEnums": false }, "include": [ "./src/**/*.ts" From b238a3a9d059987f2cd31c90cd47ce234426528e Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 8 Jan 2019 14:46:58 +0000 Subject: [PATCH 220/333] fix(rstream): disable __State reverse enum lookups --- packages/rstream/src/api.ts | 2 +- packages/rstream/src/subs/resolve.ts | 4 ++-- packages/rstream/src/subscription.ts | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/rstream/src/api.ts b/packages/rstream/src/api.ts index cd7a98ba41..622a4f5479 100644 --- a/packages/rstream/src/api.ts +++ b/packages/rstream/src/api.ts @@ -14,7 +14,7 @@ export const enum State { /** * Reverse lookup for `State` enums */ -export const __State = (exports).State; +// export const __State = (exports).State; export type Fn = (x: T) => void; diff --git a/packages/rstream/src/subs/resolve.ts b/packages/rstream/src/subs/resolve.ts index ef1323751c..1504af823e 100644 --- a/packages/rstream/src/subs/resolve.ts +++ b/packages/rstream/src/subs/resolve.ts @@ -1,5 +1,5 @@ import { IID } from "@thi.ng/api"; -import { __State, DEBUG, State } from "../api"; +import { DEBUG, State } from "../api"; import { Subscription } from "../subscription"; import { nextID } from "../utils/idgen"; @@ -54,7 +54,7 @@ export class Resolver extends Subscription, T> { this.done(); } } else { - DEBUG && console.log(`resolved value in ${__State[this.state]} state (${x})`); + DEBUG && console.log(`resolved value in state ${this.state} (${x})`); } }, (e) => { diff --git a/packages/rstream/src/subscription.ts b/packages/rstream/src/subscription.ts index d2357da73b..dbdd3d9804 100644 --- a/packages/rstream/src/subscription.ts +++ b/packages/rstream/src/subscription.ts @@ -10,7 +10,6 @@ import { unreduced } from "@thi.ng/transducers"; import { - __State, DEBUG, ISubscribable, ISubscriber, @@ -299,7 +298,7 @@ export class Subscription implements protected ensureState() { if (this.state >= State.DONE) { - illegalState(`operation not allowed in ${__State[this.state]} state`); + illegalState(`operation not allowed in state ${this.state}`); } } From 19449e8d9291657f1273dc77777267dfacfd1d12 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 8 Jan 2019 14:47:44 +0000 Subject: [PATCH 221/333] fix(rstream-gestures): disable __GestureType reverse enum export --- packages/rstream-gestures/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rstream-gestures/src/index.ts b/packages/rstream-gestures/src/index.ts index 9cad9f5730..b2872ed99e 100644 --- a/packages/rstream-gestures/src/index.ts +++ b/packages/rstream-gestures/src/index.ts @@ -13,7 +13,7 @@ export const enum GestureType { /** * Reverse lookup for `GestureType` enums */ -export const __GestureType = (exports).GestureType; +// export const __GestureType = (exports).GestureType; export interface GestureInfo { pos: number[]; From d89f28fd1b829b808dd21c6282a6dabe1ce23fe3 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 8 Jan 2019 14:48:58 +0000 Subject: [PATCH 222/333] fix(rstream-log): remove __Level reverse enum lookup, update Level (non const) --- packages/rstream-log/src/api.ts | 4 ++-- packages/rstream-log/src/xform/format.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/rstream-log/src/api.ts b/packages/rstream-log/src/api.ts index 35356cf87b..f9dcdbe55e 100644 --- a/packages/rstream-log/src/api.ts +++ b/packages/rstream-log/src/api.ts @@ -1,7 +1,7 @@ import { IID } from "@thi.ng/api"; import { ISubscribable } from "@thi.ng/rstream"; -export const enum Level { +export enum Level { FINE, DEBUG, INFO, @@ -13,7 +13,7 @@ export const enum Level { /** * Reverse lookup for `Level` enums */ -export const __Level = (exports).Level; +// export const __Level = (exports).Level; export interface LogEntry extends Array { [0]: Level; diff --git a/packages/rstream-log/src/xform/format.ts b/packages/rstream-log/src/xform/format.ts index cb4560b320..397b4e4980 100644 --- a/packages/rstream-log/src/xform/format.ts +++ b/packages/rstream-log/src/xform/format.ts @@ -1,6 +1,6 @@ import { map, Transducer } from "@thi.ng/transducers"; import { - __Level, + Level, BodyFormat, DateFormat, LogEntry, @@ -15,7 +15,7 @@ export const formatString = ( bodyFmt = bodyFmt || ((x) => x.toString()); return map( ([level, id, time, ...body]) => - `[${__Level[level]}] [${id}] ${dtFmt(time)} ${bodyFmt(body)}` + `[${Level[level]}] [${id}] ${dtFmt(time)} ${bodyFmt(body)}` ); }; @@ -31,7 +31,7 @@ export const formatJSON = return map( ([level, id, time, ...body]) => JSON.stringify({ - level: __Level[level], + level: Level[level], id, time: dtfmt(time), body From 3b8576f3c748e1a8d29f3f2133beae8a01e312fa Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 8 Jan 2019 14:49:33 +0000 Subject: [PATCH 223/333] fix(csp): disable __State reverse enum lookup --- packages/csp/src/api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/csp/src/api.ts b/packages/csp/src/api.ts index adff2752be..b38084f7b6 100644 --- a/packages/csp/src/api.ts +++ b/packages/csp/src/api.ts @@ -10,7 +10,7 @@ export const enum State { /** * Reverse lookup for `State` enums */ -export const __State = (exports).State; +// export const __State = (exports).State; export interface ChannelItem { value: () => Promise; From 3747ad7bf65bc736ad4febf0a93373cb90a1b08a Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 8 Jan 2019 14:52:57 +0000 Subject: [PATCH 224/333] refactor(examples): update imports & deps of all examples --- examples/async-effect/package.json | 1 - examples/async-effect/src/index.ts | 12 +- examples/async-effect/tsconfig.json | 1 + examples/canvas-dial/package.json | 4 +- examples/canvas-dial/src/dial.ts | 14 +- examples/canvas-dial/src/index.ts | 9 +- examples/canvas-dial/tsconfig.json | 1 + examples/cellular-automata/package.json | 1 - examples/cellular-automata/src/index.ts | 156 ++++++++++-------- examples/cellular-automata/tsconfig.json | 1 + examples/commit-table-ssr/src/client/index.ts | 25 +-- .../src/common/components/repo-table.ts | 15 +- .../src/common/components/table.ts | 4 +- examples/commit-table-ssr/src/server/git.ts | 1 - examples/commit-table-ssr/src/server/html.ts | 5 +- examples/commit-table-ssr/src/server/index.ts | 3 +- .../commit-table-ssr/src/server/static.ts | 1 - examples/commit-table-ssr/tsconfig.json | 3 +- examples/crypto-chart/package.json | 8 +- examples/crypto-chart/src/index.ts | 70 ++++---- examples/crypto-chart/tsconfig.json | 1 + examples/dashboard/tsconfig.json | 1 + examples/devcards/src/index.ts | 5 +- examples/devcards/tsconfig.json | 1 + examples/geom-knn/src/index.ts | 10 +- examples/geom-knn/tsconfig.json | 3 +- examples/geom-tessel/package.json | 5 +- examples/geom-tessel/src/index.ts | 25 +-- examples/geom-tessel/tsconfig.json | 3 +- examples/gesture-analysis/src/config.ts | 3 +- examples/gesture-analysis/src/index.ts | 37 +++-- examples/gesture-analysis/tsconfig.json | 1 + examples/hdom-basics/tsconfig.json | 1 + examples/hdom-benchmark/package.json | 1 - examples/hdom-benchmark/src/index.ts | 23 +-- examples/hdom-benchmark/tsconfig.json | 1 + examples/hdom-benchmark2/src/index.ts | 28 ++-- examples/hdom-benchmark2/tsconfig.json | 3 +- examples/hdom-canvas-clock/package.json | 6 +- examples/hdom-canvas-clock/src/index.ts | 7 +- examples/hdom-canvas-clock/tsconfig.json | 1 + examples/hdom-canvas-draw/src/index.ts | 23 +-- examples/hdom-canvas-draw/tsconfig.json | 3 +- examples/hdom-canvas-shapes/package.json | 3 +- examples/hdom-canvas-shapes/src/index.ts | 25 ++- examples/hdom-canvas-shapes/tsconfig.json | 6 +- examples/hdom-dropdown-fuzzy/package.json | 1 + examples/hdom-dropdown-fuzzy/src/dropdown.ts | 9 +- examples/hdom-dropdown-fuzzy/src/fuzzy.ts | 17 +- examples/hdom-dropdown-fuzzy/src/index.ts | 9 +- examples/hdom-dropdown-fuzzy/src/input.ts | 4 +- examples/hdom-dropdown-fuzzy/tsconfig.json | 1 + examples/hdom-dropdown/package.json | 1 + examples/hdom-dropdown/src/dropdown.ts | 9 +- examples/hdom-dropdown/src/index.ts | 8 +- examples/hdom-dropdown/tsconfig.json | 1 + examples/hdom-dyn-context/src/index.ts | 4 +- examples/hdom-dyn-context/tsconfig.json | 3 +- examples/hdom-skip/package.json | 5 +- examples/hdom-skip/tsconfig.json | 3 +- examples/hdom-theme-adr-0003/package.json | 3 +- examples/hdom-theme-adr-0003/src/index.ts | 4 +- examples/hdom-theme-adr-0003/tsconfig.json | 1 + examples/hmr-basics/src/index.ts | 6 +- examples/hmr-basics/src/state.ts | 15 +- examples/hmr-basics/tsconfig.json | 5 +- examples/hydrate-basics/package.json | 2 +- examples/hydrate-basics/src/index.ts | 7 +- examples/hydrate-basics/tsconfig.json | 1 + examples/interceptor-basics/package.json | 6 +- examples/interceptor-basics/src/index.ts | 17 +- examples/interceptor-basics/tsconfig.json | 3 +- examples/interceptor-basics2/package.json | 5 +- examples/interceptor-basics2/src/index.ts | 20 ++- examples/interceptor-basics2/tsconfig.json | 1 + examples/json-components/src/index.ts | 3 +- examples/json-components/tsconfig.json | 1 + examples/login-form/package.json | 3 +- examples/login-form/src/index.ts | 4 +- examples/login-form/tsconfig.json | 1 + examples/mandelbrot/package.json | 10 +- examples/mandelbrot/src/gradient.ts | 57 ++++--- examples/mandelbrot/src/index.ts | 13 +- examples/mandelbrot/src/worker.ts | 4 +- examples/mandelbrot/tsconfig.json | 3 +- examples/markdown/package.json | 1 + examples/markdown/src/index.ts | 9 +- examples/markdown/tsconfig.json | 3 +- examples/pointfree-svg/output.svg | 2 +- examples/pointfree-svg/tsconfig.json | 4 +- examples/router-basics/package.json | 2 + examples/router-basics/src/api.ts | 9 +- examples/router-basics/src/app.ts | 14 +- .../src/components/event-link.ts | 2 +- examples/router-basics/src/config.ts | 7 +- examples/router-basics/src/routes.ts | 2 +- examples/router-basics/tsconfig.json | 1 + examples/rstream-dataflow/package.json | 2 +- examples/rstream-dataflow/src/circle.ts | 24 +-- examples/rstream-dataflow/src/index.ts | 25 +-- examples/rstream-dataflow/tsconfig.json | 7 +- examples/rstream-grid/package.json | 5 + examples/rstream-grid/src/api.ts | 7 +- examples/rstream-grid/src/app.ts | 13 +- .../rstream-grid/src/components/event-link.ts | 2 +- examples/rstream-grid/src/config.ts | 9 +- examples/rstream-grid/src/dataflow.ts | 12 +- examples/rstream-grid/src/events.ts | 2 +- examples/rstream-grid/tsconfig.json | 5 +- examples/rstream-hdom/package.json | 5 +- examples/rstream-hdom/src/index.ts | 25 +-- examples/rstream-hdom/tsconfig.json | 1 + examples/svg-barchart/package.json | 6 +- examples/svg-barchart/src/index.ts | 4 +- examples/svg-barchart/tsconfig.json | 3 +- examples/svg-particles/src/index.ts | 8 +- examples/svg-particles/tsconfig.json | 1 + examples/svg-waveform/package.json | 2 + examples/svg-waveform/src/api.ts | 7 +- examples/svg-waveform/src/app.ts | 17 +- .../svg-waveform/src/components/event-link.ts | 2 +- .../svg-waveform/src/components/waveform.ts | 20 ++- examples/svg-waveform/src/events.ts | 2 +- examples/svg-waveform/tsconfig.json | 5 +- examples/talk-slides/package.json | 3 +- examples/talk-slides/src/index.ts | 28 ++-- examples/talk-slides/tsconfig.json | 3 +- examples/todo-list/package.json | 1 + examples/todo-list/src/index.ts | 7 +- examples/todo-list/tsconfig.json | 1 + examples/transducers-hdom/package.json | 1 + examples/transducers-hdom/src/index.ts | 8 +- examples/transducers-hdom/tsconfig.json | 1 + examples/triple-query/package.json | 5 + examples/triple-query/src/api.ts | 15 +- examples/triple-query/src/app.ts | 15 +- .../triple-query/src/components/event-link.ts | 2 +- .../src/components/query-results.ts | 5 +- .../triple-query/src/components/section.ts | 2 +- examples/triple-query/src/components/table.ts | 2 +- .../src/components/triple-table.ts | 2 +- examples/triple-query/src/handlers.ts | 30 ++-- examples/triple-query/src/index.ts | 2 - examples/triple-query/tsconfig.json | 4 +- examples/webgl/src/index.ts | 4 +- examples/webgl/tsconfig.json | 1 + examples/xml-converter/package.json | 3 + examples/xml-converter/src/convert.ts | 20 ++- examples/xml-converter/src/format.ts | 14 +- examples/xml-converter/src/index.ts | 6 +- examples/xml-converter/src/ui.ts | 2 +- examples/xml-converter/src/utils.ts | 39 +++-- examples/xml-converter/tsconfig.json | 3 +- 153 files changed, 718 insertions(+), 619 deletions(-) diff --git a/examples/async-effect/package.json b/examples/async-effect/package.json index 49117455ee..e35216328e 100644 --- a/examples/async-effect/package.json +++ b/examples/async-effect/package.json @@ -17,7 +17,6 @@ }, "dependencies": { "@thi.ng/api": "latest", - "@thi.ng/atom": "latest", "@thi.ng/hdom": "latest", "@thi.ng/interceptors": "latest" }, diff --git a/examples/async-effect/src/index.ts b/examples/async-effect/src/index.ts index f60a8c5da1..fdc827cef3 100644 --- a/examples/async-effect/src/index.ts +++ b/examples/async-effect/src/index.ts @@ -1,13 +1,13 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { start } from "@thi.ng/hdom/start"; +import { IObjectOf } from "@thi.ng/api"; +import { start } from "@thi.ng/hdom"; import { EffectDef, + EventBus, EventDef, FX_DISPATCH_ASYNC, - FX_DISPATCH_NOW -} from "@thi.ng/interceptors/api"; -import { EventBus } from "@thi.ng/interceptors/event-bus"; -import { valueSetter } from "@thi.ng/interceptors/interceptors"; + FX_DISPATCH_NOW, + valueSetter +} from "@thi.ng/interceptors"; // best practice tip: // define event & effect names as consts or enums and diff --git a/examples/async-effect/tsconfig.json b/examples/async-effect/tsconfig.json index b7d63aedf0..50a1cade93 100644 --- a/examples/async-effect/tsconfig.json +++ b/examples/async-effect/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/canvas-dial/package.json b/examples/canvas-dial/package.json index 32eddd14d2..f598c7cbd4 100644 --- a/examples/canvas-dial/package.json +++ b/examples/canvas-dial/package.json @@ -19,10 +19,12 @@ "@thi.ng/checks": "latest", "@thi.ng/hdom": "latest", "@thi.ng/hdom-components": "latest", + "@thi.ng/math": "latest", "@thi.ng/rstream": "latest", "@thi.ng/rstream-gestures": "latest", "@thi.ng/strings": "latest", - "@thi.ng/transducers": "latest" + "@thi.ng/transducers": "latest", + "@thi.ng/transducers-hdom": "latest" }, "browserslist": [ "last 3 Chrome versions" diff --git a/examples/canvas-dial/src/dial.ts b/examples/canvas-dial/src/dial.ts index 36fa94ad35..094943689c 100644 --- a/examples/canvas-dial/src/dial.ts +++ b/examples/canvas-dial/src/dial.ts @@ -1,11 +1,11 @@ -import { Fn } from "@thi.ng/api/api"; -import { isString } from "@thi.ng/checks/is-string"; -import { canvas2D } from "@thi.ng/hdom-components/canvas"; +import { Fn } from "@thi.ng/api"; +import { isString } from "@thi.ng/checks"; +import { canvas2D } from "@thi.ng/hdom-components"; +import { fitClamped } from "@thi.ng/math"; +import { Subscription } from "@thi.ng/rstream"; import { GestureEvent, gestureStream, GestureType } from "@thi.ng/rstream-gestures"; -import { Subscription } from "@thi.ng/rstream/subscription"; -import { peek } from "@thi.ng/transducers/func/peek"; -import { fitClamped } from "@thi.ng/math/fit"; -import { heading2, sub2 } from "@thi.ng/vectors/vec2"; +import { peek } from "@thi.ng/transducers"; +import { heading2, sub2 } from "@thi.ng/vectors"; /** * Dial component options. diff --git a/examples/canvas-dial/src/index.ts b/examples/canvas-dial/src/index.ts index b3fe03cc38..55f9059438 100644 --- a/examples/canvas-dial/src/index.ts +++ b/examples/canvas-dial/src/index.ts @@ -1,10 +1,7 @@ -import { stream } from "@thi.ng/rstream/stream"; -import { sync } from "@thi.ng/rstream/stream-sync"; -import { percent } from "@thi.ng/strings/percent"; +import { stream, sync } from "@thi.ng/rstream"; +import { percent } from "@thi.ng/strings"; +import { comp, map } from "@thi.ng/transducers"; import { updateDOM } from "@thi.ng/transducers-hdom"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { map } from "@thi.ng/transducers/xform/map"; - import { dial } from "./dial"; // hdom context & app state object diff --git a/examples/canvas-dial/tsconfig.json b/examples/canvas-dial/tsconfig.json index b7d63aedf0..50a1cade93 100644 --- a/examples/canvas-dial/tsconfig.json +++ b/examples/canvas-dial/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/cellular-automata/package.json b/examples/cellular-automata/package.json index 0f13799a9b..ada4f510cb 100644 --- a/examples/cellular-automata/package.json +++ b/examples/cellular-automata/package.json @@ -15,7 +15,6 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "latest", "@thi.ng/hdom": "latest", "@thi.ng/hdom-components": "latest", "@thi.ng/transducers": "latest" diff --git a/examples/cellular-automata/src/index.ts b/examples/cellular-automata/src/index.ts index 996f69a46b..6fa7cc29d1 100644 --- a/examples/cellular-automata/src/index.ts +++ b/examples/cellular-automata/src/index.ts @@ -1,18 +1,21 @@ import { start } from "@thi.ng/hdom"; -import { dropdown, DropDownOption } from "@thi.ng/hdom-components/dropdown"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { lookup2d } from "@thi.ng/transducers/func/lookup"; -import { range2d } from "@thi.ng/transducers/iter/range2d"; -import { repeatedly } from "@thi.ng/transducers/iter/repeatedly"; -import { push } from "@thi.ng/transducers/rfn/push"; -import { str } from "@thi.ng/transducers/rfn/str"; -import { step } from "@thi.ng/transducers/step"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { bits } from "@thi.ng/transducers/xform/bits"; -import { buildKernel2d, convolve2d } from "@thi.ng/transducers/xform/convolve"; -import { map } from "@thi.ng/transducers/xform/map"; -import { multiplex } from "@thi.ng/transducers/xform/multiplex"; -import { partition } from "@thi.ng/transducers/xform/partition"; +import { dropdown, DropDownOption } from "@thi.ng/hdom-components"; +import { + bits, + buildKernel2d, + comp, + convolve2d, + lookup2d, + map, + multiplex, + partition, + push, + range2d, + repeatedly, + step, + str, + transduce +} from "@thi.ng/transducers"; const W = 128; const H = 48; @@ -36,80 +39,97 @@ let rules: number[]; // 3x3 convolution kernel (Moore neighborhood) const kernel = buildKernel2d([1, 1, 1, 1, 0, 1, 1, 1, 1], 3, 3); -const setHash = () => (location.hash = rules.join("")); +const setHash = + () => (location.hash = rules.join("")); // build transducer to parse rules from string (e.g. location hash or preset) // (an older version used a preset format w/ "-" to separate rule groups) -const parseRules = step( - comp( - map((x: string) => parseInt(x.replace("-", ""), 2)), - bits(18) - ) -); +const parseRules = + step( + comp( + map((x: string) => parseInt(x.replace("-", ""), 2)), + bits(18) + ) + ); -const applyRules = (raw) => { - if (raw.length >= 18) { - rules = parseRules(raw); - randomizeGrid(); - setHash(); - } -}; +const applyRules = + (raw) => { + if (raw.length >= 18) { + rules = parseRules(raw); + randomizeGrid(); + setHash(); + } + }; // create random bit sequence w/ ones appearing in given probability -const randomSeq = (num, prob = 0.5) => [...repeatedly(() => Math.random() < prob ? 1 : 0, num)]; -const randomizeGrid = (prob = 0.5) => (grid = randomSeq(W * H, prob)); -const randomizeRules = () => { - rules = randomSeq(18); - randomizeGrid(); - setHash(); -}; +const randomSeq = + (num, prob = 0.5) => [...repeatedly(() => Math.random() < prob ? 1 : 0, num)]; + +const randomizeGrid = + (prob = 0.5) => (grid = randomSeq(W * H, prob)); + +const randomizeRules = + () => { + rules = randomSeq(18); + randomizeGrid(); + setHash(); + }; // apply convolution & CA rules (in basically 2 lines of code, i.e. the transducer part!!) // this produces the next generation of the CA // we're using `multiplex` to run 2 transducers in parallel and // produce a tuple of `[neighbor-count, orig-cell-value]` // this tuple is then used to lookup the next cell state using the current rule set -export const convolve = (src: number[], rules: number[], width: number, height: number, rstride = 9, wrap = true) => - transduce( - comp( - multiplex(convolve2d({ src, width, height, kernel, wrap }), map(lookup2d(src, width))), - map(lookup2d(rules, rstride)) - ), - push(), - range2d(width, height) - ); +export const convolve = + (src: number[], rules: number[], width: number, height: number, rstride = 9, wrap = true) => + transduce( + comp( + multiplex( + convolve2d({ src, width, height, kernel, wrap }), + map(lookup2d(src, width)) + ), + map(lookup2d(rules, rstride)) + ), + push(), + range2d(width, height) + ); // format grid values as string -const format = (src: number[], width: number, fill = "\u2588", empty = " ") => - transduce( - comp( - map((x: number) => x ? fill : empty), - partition(width), - map((x) => x.join("")) - ), - str("\n"), - src - ); +const format = + (src: number[], width: number, fill = "\u2588", empty = " ") => + transduce( + comp( + map((x: number) => x ? fill : empty), + partition(width), + map((x) => x.join("")) + ), + str("\n"), + src + ); // event handler for rule edits -const setRule = (i: number, j: number, s: number, rstride = 9) => { - rules[i * rstride + j] = s ? 1 : 0; - setHash(); -}; +const setRule = + (i: number, j: number, s: number, rstride = 9) => { + rules[i * rstride + j] = s ? 1 : 0; + setHash(); + }; // single checkbox component -const checkbox = (x, onchange) => ["input", { type: "checkbox", checked: !!x, onchange }]; +const checkbox = + (x, onchange) => ["input", { type: "checkbox", checked: !!x, onchange }]; // component for single CA rule group (alive / dead FSM) -const ruleBoxes = (prefix, i, rstride = 9) => - ["div", - ["label", prefix], - ...rules - .slice(i * rstride, (i + 1) * rstride) - .map((rule, j) => checkbox(rule, (e) => setRule(i, j, e.target.checked))), - ]; - -const isPreset = (id) => presets.findIndex((x) => x[0] === id) !== -1; +const ruleBoxes = + (prefix, i, rstride = 9) => + ["div", + ["label", prefix], + ...rules + .slice(i * rstride, (i + 1) * rstride) + .map((rule, j) => checkbox(rule, (e) => setRule(i, j, e.target.checked))), + ]; + +const isPreset = + (id) => presets.findIndex((x) => x[0] === id) !== -1; // Use Conway CA default state rules [[dead], [alive]] if no preset present in hash applyRules(location.hash.length > 18 ? location.hash.substr(1) : presets[1][0]); diff --git a/examples/cellular-automata/tsconfig.json b/examples/cellular-automata/tsconfig.json index b7d63aedf0..50a1cade93 100644 --- a/examples/cellular-automata/tsconfig.json +++ b/examples/cellular-automata/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/commit-table-ssr/src/client/index.ts b/examples/commit-table-ssr/src/client/index.ts index 0a9bb6abca..ad1b380993 100644 --- a/examples/commit-table-ssr/src/client/index.ts +++ b/examples/commit-table-ssr/src/client/index.ts @@ -1,16 +1,19 @@ import { resolve as resolveMap } from "@thi.ng/resolve-map"; -import { fromInterval } from "@thi.ng/rstream/from/interval"; -import { stream } from "@thi.ng/rstream/stream"; -import { sync } from "@thi.ng/rstream/stream-sync"; -import { resolve as resolvePromise } from "@thi.ng/rstream/subs/resolve"; +import { + fromInterval, + resolve as resolvePromise, + stream, + sync +} from "@thi.ng/rstream"; +import { + add, + conj, + map, + pluck, + throttleTime, + transduce +} from "@thi.ng/transducers"; import { updateDOM } from "@thi.ng/transducers-hdom"; -import { add } from "@thi.ng/transducers/rfn/add"; -import { conj } from "@thi.ng/transducers/rfn/conj"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { map } from "@thi.ng/transducers/xform/map"; -import { pluck } from "@thi.ng/transducers/xform/pluck"; -import { throttleTime } from "@thi.ng/transducers/xform/throttle-time"; - import { AppContext, Commit } from "../common/api"; import { header } from "../common/components/header"; import { link } from "../common/components/link"; diff --git a/examples/commit-table-ssr/src/common/components/repo-table.ts b/examples/commit-table-ssr/src/common/components/repo-table.ts index 13a672c284..a2d6559f26 100644 --- a/examples/commit-table-ssr/src/common/components/repo-table.ts +++ b/examples/commit-table-ssr/src/common/components/repo-table.ts @@ -1,10 +1,11 @@ -import { comp } from "@thi.ng/transducers/func/comp"; -import { repeat } from "@thi.ng/transducers/iter/repeat"; -import { iterator } from "@thi.ng/transducers/iterator"; -import { map } from "@thi.ng/transducers/xform/map"; -import { mapIndexed } from "@thi.ng/transducers/xform/map-indexed"; -import { partitionBy } from "@thi.ng/transducers/xform/partition-by"; - +import { + comp, + iterator, + map, + mapIndexed, + partitionBy, + repeat +} from "@thi.ng/transducers"; import { AppContext, Commit } from "../api"; import { commitLink } from "./commit-link"; import { table } from "./table"; diff --git a/examples/commit-table-ssr/src/common/components/table.ts b/examples/commit-table-ssr/src/common/components/table.ts index 4a32cb6258..3c781ce283 100644 --- a/examples/commit-table-ssr/src/common/components/table.ts +++ b/examples/commit-table-ssr/src/common/components/table.ts @@ -1,7 +1,5 @@ -import { map } from "@thi.ng/transducers/xform/map"; - +import { map, mapcat } from "@thi.ng/transducers"; import { AppContext } from "../api"; -import { mapcat } from "@thi.ng/transducers/xform/mapcat"; const thead = (ctx: AppContext, head: Iterable) => ["thead", diff --git a/examples/commit-table-ssr/src/server/git.ts b/examples/commit-table-ssr/src/server/git.ts index 8120bcca59..de5cd3ff02 100644 --- a/examples/commit-table-ssr/src/server/git.ts +++ b/examples/commit-table-ssr/src/server/git.ts @@ -11,7 +11,6 @@ import { } from "@thi.ng/transducers"; import { execSync } from "child_process"; import { resolve } from "path"; - import { Commit } from "../common/api"; /** diff --git a/examples/commit-table-ssr/src/server/html.ts b/examples/commit-table-ssr/src/server/html.ts index 07781d8d94..d98822d964 100644 --- a/examples/commit-table-ssr/src/server/html.ts +++ b/examples/commit-table-ssr/src/server/html.ts @@ -1,7 +1,6 @@ -import { mergeDeepObj } from "@thi.ng/associative/merge-deep"; +import { mergeDeepObj } from "@thi.ng/associative"; import { serialize } from "@thi.ng/hiccup"; -import { map } from "@thi.ng/transducers/xform/map"; - +import { map } from "@thi.ng/transducers"; import { AppContext, HTMLDoc } from "../common/api"; import { DEFAULT_DOC } from "../common/config"; diff --git a/examples/commit-table-ssr/src/server/index.ts b/examples/commit-table-ssr/src/server/index.ts index 0292329c79..99c1e6b754 100644 --- a/examples/commit-table-ssr/src/server/index.ts +++ b/examples/commit-table-ssr/src/server/index.ts @@ -1,8 +1,7 @@ import { TLRUCache } from "@thi.ng/cache"; import * as express from "express"; -import * as Bundler from "parcel-bundler"; import * as fs from "fs"; - +import * as Bundler from "parcel-bundler"; import { Commit } from "../common/api"; import { ctx } from "../common/config"; import { buildRepoTableHTML } from "./build-table"; diff --git a/examples/commit-table-ssr/src/server/static.ts b/examples/commit-table-ssr/src/server/static.ts index 4170ca5191..8691b1793a 100644 --- a/examples/commit-table-ssr/src/server/static.ts +++ b/examples/commit-table-ssr/src/server/static.ts @@ -1,5 +1,4 @@ import { writeFileSync } from "fs"; - import { ctx } from "../common/config"; import { buildRepoTableHTML } from "./build-table"; import { repoCommits } from "./git"; diff --git a/examples/commit-table-ssr/tsconfig.json b/examples/commit-table-ssr/tsconfig.json index 2210c34a04..50a1cade93 100644 --- a/examples/commit-table-ssr/tsconfig.json +++ b/examples/commit-table-ssr/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "build", + "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/crypto-chart/package.json b/examples/crypto-chart/package.json index ab1c7c6525..a88f34743f 100644 --- a/examples/crypto-chart/package.json +++ b/examples/crypto-chart/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { @@ -15,14 +15,13 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "latest", - "@thi.ng/hdom": "latest", "@thi.ng/hdom-components": "latest", "@thi.ng/hiccup-svg": "latest", "@thi.ng/resolve-map": "latest", "@thi.ng/rstream": "latest", "@thi.ng/strings": "latest", "@thi.ng/transducers": "latest", + "@thi.ng/transducers-hdom": "latest", "@thi.ng/transducers-stats": "latest" }, "browserslist": [ @@ -30,5 +29,6 @@ ], "browser": { "process": false - } + }, + "sideEffects": false } \ No newline at end of file diff --git a/examples/crypto-chart/src/index.ts b/examples/crypto-chart/src/index.ts index 9566131cb8..49d2ff9408 100644 --- a/examples/crypto-chart/src/index.ts +++ b/examples/crypto-chart/src/index.ts @@ -1,36 +1,44 @@ -import { dropdown, DropDownOption } from "@thi.ng/hdom-components/dropdown"; -import { group } from "@thi.ng/hiccup-svg/group"; -import { line } from "@thi.ng/hiccup-svg/line"; -import { polygon } from "@thi.ng/hiccup-svg/polygon"; -import { polyline } from "@thi.ng/hiccup-svg/polyline"; -import { rect } from "@thi.ng/hiccup-svg/rect"; -import { svg } from "@thi.ng/hiccup-svg/svg"; -import { text } from "@thi.ng/hiccup-svg/text"; +import { dropdown, DropDownOption } from "@thi.ng/hdom-components"; +import { + group, + line, + polygon, + polyline, + rect, + svg, + text +} from "@thi.ng/hiccup-svg"; import { resolve } from "@thi.ng/resolve-map"; -import { fromEvent } from "@thi.ng/rstream/from/event"; -import { fromInterval } from "@thi.ng/rstream/from/interval"; -import { stream } from "@thi.ng/rstream/stream"; -import { sync } from "@thi.ng/rstream/stream-sync"; -import { resolve as resolvePromise } from "@thi.ng/rstream/subs/resolve"; -import { trace } from "@thi.ng/rstream/subs/trace"; -import { padLeft } from "@thi.ng/strings/pad-left"; +import { + fromEvent, + fromInterval, + resolve as resolvePromise, + stream, + sync, + trace +} from "@thi.ng/rstream"; +import { padLeft } from "@thi.ng/strings"; +import { + comp, + filter, + map, + mapcat, + mapIndexed, + max, + min, + pairs, + pluck, + push, + range, + transduce +} from "@thi.ng/transducers"; import { updateDOM } from "@thi.ng/transducers-hdom"; -import { ema } from "@thi.ng/transducers-stats/ema"; -import { hma } from "@thi.ng/transducers-stats/hma"; -import { sma } from "@thi.ng/transducers-stats/sma"; -import { wma } from "@thi.ng/transducers-stats/wma"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { pairs } from "@thi.ng/transducers/iter/pairs"; -import { range } from "@thi.ng/transducers/iter/range"; -import { max } from "@thi.ng/transducers/rfn/max"; -import { min } from "@thi.ng/transducers/rfn/min"; -import { push } from "@thi.ng/transducers/rfn/push"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { filter } from "@thi.ng/transducers/xform/filter"; -import { map } from "@thi.ng/transducers/xform/map"; -import { mapIndexed } from "@thi.ng/transducers/xform/map-indexed"; -import { mapcat } from "@thi.ng/transducers/xform/mapcat"; -import { pluck } from "@thi.ng/transducers/xform/pluck"; +import { + ema, + hma, + sma, + wma +} from "@thi.ng/transducers-stats"; // this example demonstrates how to use @thi.ng/rstream & // @thi.ng/transducer constructs to create a basic cryptocurrency candle diff --git a/examples/crypto-chart/tsconfig.json b/examples/crypto-chart/tsconfig.json index b7d63aedf0..50a1cade93 100644 --- a/examples/crypto-chart/tsconfig.json +++ b/examples/crypto-chart/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/dashboard/tsconfig.json b/examples/dashboard/tsconfig.json index b7d63aedf0..50a1cade93 100644 --- a/examples/dashboard/tsconfig.json +++ b/examples/dashboard/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/devcards/src/index.ts b/examples/devcards/src/index.ts index 0db3e0b898..c49e03c7ed 100644 --- a/examples/devcards/src/index.ts +++ b/examples/devcards/src/index.ts @@ -1,6 +1,5 @@ -import { IAtom } from "@thi.ng/atom/api"; -import { Atom } from "@thi.ng/atom/atom"; -import { Cursor } from "@thi.ng/atom/cursor"; +import { IAtom } from "@thi.ng/atom"; +import { Atom, Cursor } from "@thi.ng/atom"; import { start } from "@thi.ng/hdom"; type CardFn = (state: IAtom) => any; diff --git a/examples/devcards/tsconfig.json b/examples/devcards/tsconfig.json index b7d63aedf0..50a1cade93 100644 --- a/examples/devcards/tsconfig.json +++ b/examples/devcards/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/geom-knn/src/index.ts b/examples/geom-knn/src/index.ts index 44d45482ad..f8de31f99a 100644 --- a/examples/geom-knn/src/index.ts +++ b/examples/geom-knn/src/index.ts @@ -1,13 +1,11 @@ import { timedResult } from "@thi.ng/bench"; -import { KdTree } from "@thi.ng/geom-accel/kdtree"; +import { KdTree } from "@thi.ng/geom-accel"; import { canvas } from "@thi.ng/hdom-canvas"; +import { sync, trigger } from "@thi.ng/rstream"; import { gestureStream } from "@thi.ng/rstream-gestures"; -import { sync } from "@thi.ng/rstream/stream-sync"; -import { trigger } from "@thi.ng/rstream/trigger"; +import { map, mapcat } from "@thi.ng/transducers"; import { updateDOM } from "@thi.ng/transducers-hdom"; -import { map } from "@thi.ng/transducers/xform/map"; -import { mapcat } from "@thi.ng/transducers/xform/mapcat"; -import { asVec2, Vec2 } from "@thi.ng/vectors/vec2"; +import { asVec2, Vec2 } from "@thi.ng/vectors"; const app = (main) => { // augment hdom-canvas component w/ `init` lifecycle method: this is diff --git a/examples/geom-knn/tsconfig.json b/examples/geom-knn/tsconfig.json index bbf112cc18..50a1cade93 100644 --- a/examples/geom-knn/tsconfig.json +++ b/examples/geom-knn/tsconfig.json @@ -2,10 +2,11 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/examples/geom-tessel/package.json b/examples/geom-tessel/package.json index 3f6496ff04..c20cf9d683 100644 --- a/examples/geom-tessel/package.json +++ b/examples/geom-tessel/package.json @@ -17,7 +17,10 @@ "dependencies": { "@thi.ng/compose": "latest", "@thi.ng/geom": "latest", - "@thi.ng/hdom-canvas": "latest" + "@thi.ng/hdom": "latest", + "@thi.ng/hdom-canvas": "latest", + "@thi.ng/math": "latest", + "@thi.ng/vectors": "latest" }, "browserslist": [ "last 3 Chrome versions" diff --git a/examples/geom-tessel/src/index.ts b/examples/geom-tessel/src/index.ts index 3e11ac592c..e91cd13ad0 100644 --- a/examples/geom-tessel/src/index.ts +++ b/examples/geom-tessel/src/index.ts @@ -1,14 +1,19 @@ -import { partial } from "@thi.ng/compose/partial"; -import { IArcLength, ICentroid, Tessellator } from "@thi.ng/geom/api"; -import { circle2 } from "@thi.ng/geom/circle2"; -import { polygon2, Polygon2 } from "@thi.ng/geom/polygon2"; -import { edgeSplit, quadFan, triFan } from "@thi.ng/geom/tessellate"; +import { partial } from "@thi.ng/compose"; +import { + circle2, + edgeSplit, + IArcLength, + ICentroid, + polygon2, + Polygon2, + quadFan, + Tessellator, + triFan +} from "@thi.ng/geom"; +import { start } from "@thi.ng/hdom"; import { canvas } from "@thi.ng/hdom-canvas"; -import { start } from "@thi.ng/hdom/start"; -import { deg } from "@thi.ng/math/angle"; -import { TAU } from "@thi.ng/math/api"; -import { fit01 } from "@thi.ng/math/fit"; -import { Vec2 } from "@thi.ng/vectors/vec2"; +import { deg, fit01, TAU } from "@thi.ng/math"; +import { Vec2 } from "@thi.ng/vectors"; type Tint = (p: Polygon2) => string; diff --git a/examples/geom-tessel/tsconfig.json b/examples/geom-tessel/tsconfig.json index bbf112cc18..50a1cade93 100644 --- a/examples/geom-tessel/tsconfig.json +++ b/examples/geom-tessel/tsconfig.json @@ -2,10 +2,11 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/examples/gesture-analysis/src/config.ts b/examples/gesture-analysis/src/config.ts index b03ccf284d..8d88e6e8bc 100644 --- a/examples/gesture-analysis/src/config.ts +++ b/examples/gesture-analysis/src/config.ts @@ -1,5 +1,4 @@ -import { transformVectors1 } from "@thi.ng/vectors/common"; -import { mul2, Vec2 } from "@thi.ng/vectors/vec2"; +import { mul2, transformVectors1, Vec2 } from "@thi.ng/vectors"; // initial call to action gesture // (recorded handwriting) diff --git a/examples/gesture-analysis/src/index.ts b/examples/gesture-analysis/src/index.ts index 124f311b04..983ad7d10a 100644 --- a/examples/gesture-analysis/src/index.ts +++ b/examples/gesture-analysis/src/index.ts @@ -1,23 +1,24 @@ -import { circle } from "@thi.ng/hiccup-svg/circle"; -import { group } from "@thi.ng/hiccup-svg/group"; -import { polyline } from "@thi.ng/hiccup-svg/polyline"; -import { svg } from "@thi.ng/hiccup-svg/svg"; +import { + circle, + group, + polyline, + svg +} from "@thi.ng/hiccup-svg"; +import { fromIterable, merge, sync } from "@thi.ng/rstream"; import { GestureEvent, gestureStream, GestureType } from "@thi.ng/rstream-gestures"; -import { fromIterable } from "@thi.ng/rstream/from/iterable"; -import { merge } from "@thi.ng/rstream/stream-merge"; -import { sync } from "@thi.ng/rstream/stream-sync"; +import { + comp, + filter, + identity, + map, + multiplexObj, + partition, + peek, + push, + transduce +} from "@thi.ng/transducers"; import { updateDOM } from "@thi.ng/transducers-hdom"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { identity } from "@thi.ng/transducers/func/identity"; -import { peek } from "@thi.ng/transducers/func/peek"; -import { push } from "@thi.ng/transducers/rfn/push"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { filter } from "@thi.ng/transducers/xform/filter"; -import { map } from "@thi.ng/transducers/xform/map"; -import { multiplexObj } from "@thi.ng/transducers/xform/multiplex-obj"; -import { partition } from "@thi.ng/transducers/xform/partition"; -import { Vec2 } from "@thi.ng/vectors/vec2"; - +import { Vec2 } from "@thi.ng/vectors"; import { CTA } from "./config"; /** diff --git a/examples/gesture-analysis/tsconfig.json b/examples/gesture-analysis/tsconfig.json index b7d63aedf0..50a1cade93 100644 --- a/examples/gesture-analysis/tsconfig.json +++ b/examples/gesture-analysis/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/hdom-basics/tsconfig.json b/examples/hdom-basics/tsconfig.json index b7d63aedf0..50a1cade93 100644 --- a/examples/hdom-basics/tsconfig.json +++ b/examples/hdom-basics/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/hdom-benchmark/package.json b/examples/hdom-benchmark/package.json index 69b6e84237..e12d401996 100644 --- a/examples/hdom-benchmark/package.json +++ b/examples/hdom-benchmark/package.json @@ -15,7 +15,6 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "latest", "@thi.ng/hdom": "latest", "@thi.ng/hdom-components": "latest", "@thi.ng/rstream": "latest", diff --git a/examples/hdom-benchmark/src/index.ts b/examples/hdom-benchmark/src/index.ts index e8bcc63db4..97ffd9290e 100644 --- a/examples/hdom-benchmark/src/index.ts +++ b/examples/hdom-benchmark/src/index.ts @@ -1,15 +1,16 @@ import { start } from "@thi.ng/hdom"; -import { dropdown } from "@thi.ng/hdom-components/dropdown"; -import { fromRAF } from "@thi.ng/rstream/from/raf"; -import { Stream } from "@thi.ng/rstream/stream"; -import { radix } from "@thi.ng/strings/radix"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { range } from "@thi.ng/transducers/iter/range"; -import { benchmark } from "@thi.ng/transducers/xform/benchmark"; -import { map } from "@thi.ng/transducers/xform/map"; -import { mapIndexed } from "@thi.ng/transducers/xform/map-indexed"; -import { movingAverage } from "@thi.ng/transducers/xform/moving-average"; -import { partition } from "@thi.ng/transducers/xform/partition"; +import { dropdown } from "@thi.ng/hdom-components"; +import { fromRAF, Stream } from "@thi.ng/rstream"; +import { radix } from "@thi.ng/strings"; +import { + benchmark, + comp, + map, + mapIndexed, + movingAverage, + partition, + range +} from "@thi.ng/transducers"; // pre-defined hex formatters const hex4 = radix(16, 4); diff --git a/examples/hdom-benchmark/tsconfig.json b/examples/hdom-benchmark/tsconfig.json index b7d63aedf0..50a1cade93 100644 --- a/examples/hdom-benchmark/tsconfig.json +++ b/examples/hdom-benchmark/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/hdom-benchmark2/src/index.ts b/examples/hdom-benchmark2/src/index.ts index 3b9328f071..29d2d37e6e 100644 --- a/examples/hdom-benchmark2/src/index.ts +++ b/examples/hdom-benchmark2/src/index.ts @@ -1,17 +1,17 @@ -import { splat4_24 } from "@thi.ng/binary/splat"; -import { dropdown } from "@thi.ng/hdom-components/dropdown"; -import { fpsCounter } from "@thi.ng/hdom-components/fps-counter"; -import { start } from "@thi.ng/hdom/start"; -import { css } from "@thi.ng/hiccup-css/css"; -import { injectStyleSheet } from "@thi.ng/hiccup-css/inject"; -import { U24 } from "@thi.ng/strings/radix"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { range } from "@thi.ng/transducers/iter/range"; -import { push } from "@thi.ng/transducers/rfn/push"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { map } from "@thi.ng/transducers/xform/map"; -import { mapIndexed } from "@thi.ng/transducers/xform/map-indexed"; -import { partition } from "@thi.ng/transducers/xform/partition"; +import { splat4_24 } from "@thi.ng/binary"; +import { start } from "@thi.ng/hdom"; +import { dropdown, fpsCounter } from "@thi.ng/hdom-components"; +import { css, injectStyleSheet } from "@thi.ng/hiccup-css"; +import { U24 } from "@thi.ng/strings"; +import { + comp, + map, + mapIndexed, + partition, + push, + range, + transduce +} from "@thi.ng/transducers"; const SIZE = "0.5rem"; diff --git a/examples/hdom-benchmark2/tsconfig.json b/examples/hdom-benchmark2/tsconfig.json index bbf112cc18..50a1cade93 100644 --- a/examples/hdom-benchmark2/tsconfig.json +++ b/examples/hdom-benchmark2/tsconfig.json @@ -2,10 +2,11 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/examples/hdom-canvas-clock/package.json b/examples/hdom-canvas-clock/package.json index e3d7f1d855..809c5cfa2f 100644 --- a/examples/hdom-canvas-clock/package.json +++ b/examples/hdom-canvas-clock/package.json @@ -15,9 +15,11 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "latest", "@thi.ng/hdom": "latest", - "@thi.ng/hdom-canvas": "latest" + "@thi.ng/hdom-canvas": "latest", + "@thi.ng/math": "latest", + "@thi.ng/transducers": "latest", + "@thi.ng/vectors": "latest" }, "browserslist": [ "last 3 Chrome versions" diff --git a/examples/hdom-canvas-clock/src/index.ts b/examples/hdom-canvas-clock/src/index.ts index 872c01b220..ff4126a2a6 100644 --- a/examples/hdom-canvas-clock/src/index.ts +++ b/examples/hdom-canvas-clock/src/index.ts @@ -1,9 +1,8 @@ import { start } from "@thi.ng/hdom"; import { canvas } from "@thi.ng/hdom-canvas"; -import { range } from "@thi.ng/transducers/iter/range"; -import { mapcat } from "@thi.ng/transducers/xform/mapcat"; -import { HALF_PI, TAU } from "@thi.ng/math/api"; -import { toCartesian2 } from "@thi.ng/vectors/vec2"; +import { HALF_PI, TAU } from "@thi.ng/math"; +import { mapcat, range } from "@thi.ng/transducers"; +import { toCartesian2 } from "@thi.ng/vectors"; const WEEKDAYS = ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"]; diff --git a/examples/hdom-canvas-clock/tsconfig.json b/examples/hdom-canvas-clock/tsconfig.json index b7d63aedf0..50a1cade93 100644 --- a/examples/hdom-canvas-clock/tsconfig.json +++ b/examples/hdom-canvas-clock/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/hdom-canvas-draw/src/index.ts b/examples/hdom-canvas-draw/src/index.ts index 4ee1cbf5d6..a026fc9f53 100644 --- a/examples/hdom-canvas-draw/src/index.ts +++ b/examples/hdom-canvas-draw/src/index.ts @@ -1,17 +1,18 @@ import { canvas } from "@thi.ng/hdom-canvas"; +import { HALF_PI, PI } from "@thi.ng/math"; +import { sync, trigger } from "@thi.ng/rstream"; import { GestureEvent, gestureStream, GestureType } from "@thi.ng/rstream-gestures"; -import { sync } from "@thi.ng/rstream/stream-sync"; -import { trigger } from "@thi.ng/rstream/trigger"; +import { + filter, + map, + mapcat, + normRange, + partition, + repeat, + tuples +} from "@thi.ng/transducers"; import { updateDOM } from "@thi.ng/transducers-hdom"; -import { normRange } from "@thi.ng/transducers/iter/norm-range"; -import { repeat } from "@thi.ng/transducers/iter/repeat"; -import { tuples } from "@thi.ng/transducers/iter/tuples"; -import { filter } from "@thi.ng/transducers/xform/filter"; -import { map } from "@thi.ng/transducers/xform/map"; -import { mapcat } from "@thi.ng/transducers/xform/mapcat"; -import { partition } from "@thi.ng/transducers/xform/partition"; -import { HALF_PI, PI } from "@thi.ng/math/api"; -import { dist2 } from "@thi.ng/vectors/vec2"; +import { dist2 } from "@thi.ng/vectors"; // canvas size const W = 480; diff --git a/examples/hdom-canvas-draw/tsconfig.json b/examples/hdom-canvas-draw/tsconfig.json index bbf112cc18..50a1cade93 100644 --- a/examples/hdom-canvas-draw/tsconfig.json +++ b/examples/hdom-canvas-draw/tsconfig.json @@ -2,10 +2,11 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/examples/hdom-canvas-shapes/package.json b/examples/hdom-canvas-shapes/package.json index 6e1cf9dac8..3136accd4a 100644 --- a/examples/hdom-canvas-shapes/package.json +++ b/examples/hdom-canvas-shapes/package.json @@ -21,7 +21,8 @@ "@thi.ng/hiccup-svg": "latest", "@thi.ng/rstream": "latest", "@thi.ng/transducers": "latest", - "@thi.ng/transducers-hdom": "latest" + "@thi.ng/transducers-hdom": "latest", + "@thi.ng/vectors": "latest" }, "browserslist": [ "last 3 Chrome versions" diff --git a/examples/hdom-canvas-shapes/src/index.ts b/examples/hdom-canvas-shapes/src/index.ts index cacd1843cf..eef9840ad8 100644 --- a/examples/hdom-canvas-shapes/src/index.ts +++ b/examples/hdom-canvas-shapes/src/index.ts @@ -1,23 +1,20 @@ import { canvas, normalizeTree } from "@thi.ng/hdom-canvas"; -// import { canvas2D, adaptDPI } from "@thi.ng/hdom-components/canvas"; -import { dropdown } from "@thi.ng/hdom-components/dropdown"; -import { stream } from "@thi.ng/rstream/stream"; -import { fromRAF } from "@thi.ng/rstream/from/raf"; -import { sync } from "@thi.ng/rstream/stream-sync"; +import { dropdown } from "@thi.ng/hdom-components"; +import { COMMENT, serialize } from "@thi.ng/hiccup"; +import { convertTree, svg } from "@thi.ng/hiccup-svg"; +import { fromRAF, stream, sync } from "@thi.ng/rstream"; +import { map, range, repeatedly } from "@thi.ng/transducers"; import { updateDOM } from "@thi.ng/transducers-hdom"; -import { range } from "@thi.ng/transducers/iter/range"; -import { repeatedly } from "@thi.ng/transducers/iter/repeatedly"; -import { map } from "@thi.ng/transducers/xform/map"; -import { Mat23 } from "@thi.ng/vectors/mat23"; +import { Mat23 } from "@thi.ng/vectors"; +// import { canvas2D, adaptDPI } from "@thi.ng/hdom-components/canvas"; // for testing SVG conversion -import { COMMENT, serialize } from "@thi.ng/hiccup"; -import { convertTree } from "@thi.ng/hiccup-svg/convert"; -import { svg } from "@thi.ng/hiccup-svg/svg"; - -import logo from "../assets/logo-64.png"; // ignore error, resolved by parcel import { download } from "./download"; +// ignore error, resolved by parcel +import logo from "../assets/logo-64.png"; +// const logo = "logo-64.63ccb91c.png"; + // canvas size const W = 300; const W2 = W / 2; diff --git a/examples/hdom-canvas-shapes/tsconfig.json b/examples/hdom-canvas-shapes/tsconfig.json index c1eeed2aa3..50a1cade93 100644 --- a/examples/hdom-canvas-shapes/tsconfig.json +++ b/examples/hdom-canvas-shapes/tsconfig.json @@ -2,9 +2,11 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", - "target": "es6" + "module": "es6", + "target": "es6", + "sourceMap": true }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/examples/hdom-dropdown-fuzzy/package.json b/examples/hdom-dropdown-fuzzy/package.json index 8add8bc01b..5069d6c296 100644 --- a/examples/hdom-dropdown-fuzzy/package.json +++ b/examples/hdom-dropdown-fuzzy/package.json @@ -16,6 +16,7 @@ }, "dependencies": { "@thi.ng/api": "latest", + "@thi.ng/atom": "latest", "@thi.ng/hdom": "latest", "@thi.ng/hdom-components": "latest", "@thi.ng/interceptors": "latest", diff --git a/examples/hdom-dropdown-fuzzy/src/dropdown.ts b/examples/hdom-dropdown-fuzzy/src/dropdown.ts index 44640e3708..bcb46d6522 100644 --- a/examples/hdom-dropdown-fuzzy/src/dropdown.ts +++ b/examples/hdom-dropdown-fuzzy/src/dropdown.ts @@ -1,9 +1,8 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { ReadonlyAtom } from "@thi.ng/atom/api"; +import { IObjectOf } from "@thi.ng/api"; +import { ReadonlyAtom } from "@thi.ng/atom"; import { isString } from "@thi.ng/checks"; -import { appLink } from "@thi.ng/hdom-components/link"; -import { EV_SET_VALUE, EV_TOGGLE_VALUE } from "@thi.ng/interceptors/api"; -import { EventBus } from "@thi.ng/interceptors/event-bus"; +import { appLink } from "@thi.ng/hdom-components"; +import { EventBus, EV_SET_VALUE, EV_TOGGLE_VALUE } from "@thi.ng/interceptors"; import { getIn, Path } from "@thi.ng/paths"; export interface BaseContext { diff --git a/examples/hdom-dropdown-fuzzy/src/fuzzy.ts b/examples/hdom-dropdown-fuzzy/src/fuzzy.ts index 4c551d0693..b01659f57a 100644 --- a/examples/hdom-dropdown-fuzzy/src/fuzzy.ts +++ b/examples/hdom-dropdown-fuzzy/src/fuzzy.ts @@ -1,11 +1,12 @@ -import { IView } from "@thi.ng/atom/api"; -import { EV_SET_VALUE } from "@thi.ng/interceptors/api"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { iterator } from "@thi.ng/transducers/iterator"; -import { filterFuzzy } from "@thi.ng/transducers/xform/filter-fuzzy"; -import { map } from "@thi.ng/transducers/xform/map"; - -import { dropdownListeners, DropdownState, DropdownItem } from "./dropdown"; +import { IView } from "@thi.ng/atom"; +import { EV_SET_VALUE } from "@thi.ng/interceptors"; +import { + comp, + filterFuzzy, + iterator, + map +} from "@thi.ng/transducers"; +import { DropdownItem, dropdownListeners, DropdownState } from "./dropdown"; export interface FuzzyArgs { state: IView; diff --git a/examples/hdom-dropdown-fuzzy/src/index.ts b/examples/hdom-dropdown-fuzzy/src/index.ts index 890bac3535..269c4ac088 100644 --- a/examples/hdom-dropdown-fuzzy/src/index.ts +++ b/examples/hdom-dropdown-fuzzy/src/index.ts @@ -1,8 +1,7 @@ -import { Atom } from "@thi.ng/atom/atom"; -import { start } from "@thi.ng/hdom/start"; -import { EventBus } from "@thi.ng/interceptors/event-bus"; -import { trace } from "@thi.ng/interceptors/interceptors"; - +import { Atom } from "@thi.ng/atom"; +import { start } from "@thi.ng/hdom"; +import { EventBus } from "@thi.ng/interceptors"; +import { trace } from "@thi.ng/interceptors"; import { state, theme } from "./config"; import { dropdown } from "./dropdown"; import { fuzzyDropdown } from "./fuzzy"; diff --git a/examples/hdom-dropdown-fuzzy/src/input.ts b/examples/hdom-dropdown-fuzzy/src/input.ts index 847ca34f1f..8d42a33dc5 100644 --- a/examples/hdom-dropdown-fuzzy/src/input.ts +++ b/examples/hdom-dropdown-fuzzy/src/input.ts @@ -1,5 +1,5 @@ -import { Path } from "@thi.ng/api/api"; -import { IView } from "@thi.ng/atom/api"; +import { Path } from "@thi.ng/api"; +import { IView } from "@thi.ng/atom"; import { getIn } from "@thi.ng/paths"; export interface InputArgs { diff --git a/examples/hdom-dropdown-fuzzy/tsconfig.json b/examples/hdom-dropdown-fuzzy/tsconfig.json index b7d63aedf0..50a1cade93 100644 --- a/examples/hdom-dropdown-fuzzy/tsconfig.json +++ b/examples/hdom-dropdown-fuzzy/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/hdom-dropdown/package.json b/examples/hdom-dropdown/package.json index bad9cdbfce..b0ce985271 100644 --- a/examples/hdom-dropdown/package.json +++ b/examples/hdom-dropdown/package.json @@ -16,6 +16,7 @@ }, "dependencies": { "@thi.ng/api": "latest", + "@thi.ng/atom": "latest", "@thi.ng/hdom": "latest", "@thi.ng/hdom-components": "latest", "@thi.ng/interceptors": "latest", diff --git a/examples/hdom-dropdown/src/dropdown.ts b/examples/hdom-dropdown/src/dropdown.ts index 2f02d09c89..a41e1afe72 100644 --- a/examples/hdom-dropdown/src/dropdown.ts +++ b/examples/hdom-dropdown/src/dropdown.ts @@ -1,8 +1,7 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { ReadonlyAtom } from "@thi.ng/atom/api"; -import { appLink } from "@thi.ng/hdom-components/link"; -import { EV_SET_VALUE, EV_TOGGLE_VALUE } from "@thi.ng/interceptors/api"; -import { EventBus } from "@thi.ng/interceptors/event-bus"; +import { IObjectOf } from "@thi.ng/api"; +import { ReadonlyAtom } from "@thi.ng/atom"; +import { appLink } from "@thi.ng/hdom-components"; +import { EV_SET_VALUE, EV_TOGGLE_VALUE, EventBus } from "@thi.ng/interceptors"; import { getIn, Path } from "@thi.ng/paths"; export interface BaseContext { diff --git a/examples/hdom-dropdown/src/index.ts b/examples/hdom-dropdown/src/index.ts index a33829c656..7cd45947b1 100644 --- a/examples/hdom-dropdown/src/index.ts +++ b/examples/hdom-dropdown/src/index.ts @@ -1,8 +1,6 @@ -import { Atom } from "@thi.ng/atom/atom"; -import { start } from "@thi.ng/hdom/start"; -import { EventBus } from "@thi.ng/interceptors/event-bus"; -import { trace } from "@thi.ng/interceptors/interceptors"; - +import { Atom } from "@thi.ng/atom"; +import { start } from "@thi.ng/hdom"; +import { EventBus, trace } from "@thi.ng/interceptors"; import { state, theme } from "./config"; import { dropdown, dropdownListeners } from "./dropdown"; diff --git a/examples/hdom-dropdown/tsconfig.json b/examples/hdom-dropdown/tsconfig.json index b7d63aedf0..50a1cade93 100644 --- a/examples/hdom-dropdown/tsconfig.json +++ b/examples/hdom-dropdown/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/hdom-dyn-context/src/index.ts b/examples/hdom-dyn-context/src/index.ts index abb460cb2e..9c4868ac90 100644 --- a/examples/hdom-dyn-context/src/index.ts +++ b/examples/hdom-dyn-context/src/index.ts @@ -1,5 +1,5 @@ -import { Atom } from "@thi.ng/atom/atom"; -import { start } from "@thi.ng/hdom/start"; +import { Atom } from "@thi.ng/atom"; +import { start } from "@thi.ng/hdom"; // theme definitions const THEMES = [ diff --git a/examples/hdom-dyn-context/tsconfig.json b/examples/hdom-dyn-context/tsconfig.json index bbf112cc18..50a1cade93 100644 --- a/examples/hdom-dyn-context/tsconfig.json +++ b/examples/hdom-dyn-context/tsconfig.json @@ -2,10 +2,11 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/examples/hdom-skip/package.json b/examples/hdom-skip/package.json index decb5f7656..9f3e5c79be 100644 --- a/examples/hdom-skip/package.json +++ b/examples/hdom-skip/package.json @@ -15,10 +15,7 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "latest", - "@thi.ng/atom": "latest", - "@thi.ng/rstream": "latest", - "@thi.ng/transducers-hdom": "latest" + "@thi.ng/hdom": "latest" }, "browserslist": [ "last 3 Chrome versions" diff --git a/examples/hdom-skip/tsconfig.json b/examples/hdom-skip/tsconfig.json index bbf112cc18..50a1cade93 100644 --- a/examples/hdom-skip/tsconfig.json +++ b/examples/hdom-skip/tsconfig.json @@ -2,10 +2,11 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/examples/hdom-theme-adr-0003/package.json b/examples/hdom-theme-adr-0003/package.json index bf358a6e87..f4456da1f3 100644 --- a/examples/hdom-theme-adr-0003/package.json +++ b/examples/hdom-theme-adr-0003/package.json @@ -16,7 +16,8 @@ }, "dependencies": { "@thi.ng/api": "latest", - "@thi.ng/hdom": "latest" + "@thi.ng/hdom": "latest", + "@thi.ng/paths": "latest" }, "browserslist": [ "last 3 Chrome versions" diff --git a/examples/hdom-theme-adr-0003/src/index.ts b/examples/hdom-theme-adr-0003/src/index.ts index 9e0b6e2735..1b992a881e 100644 --- a/examples/hdom-theme-adr-0003/src/index.ts +++ b/examples/hdom-theme-adr-0003/src/index.ts @@ -1,5 +1,5 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { start } from "@thi.ng/hdom/start"; +import { IObjectOf } from "@thi.ng/api"; +import { start } from "@thi.ng/hdom"; import { getIn, Path } from "@thi.ng/paths"; interface ButtonBehavior { diff --git a/examples/hdom-theme-adr-0003/tsconfig.json b/examples/hdom-theme-adr-0003/tsconfig.json index b7d63aedf0..50a1cade93 100644 --- a/examples/hdom-theme-adr-0003/tsconfig.json +++ b/examples/hdom-theme-adr-0003/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/hmr-basics/src/index.ts b/examples/hmr-basics/src/index.ts index a1181a8bb7..c2646ad1cc 100644 --- a/examples/hmr-basics/src/index.ts +++ b/examples/hmr-basics/src/index.ts @@ -1,8 +1,6 @@ -import { fromAtom } from "@thi.ng/rstream/from/atom"; -import { fromInterval } from "@thi.ng/rstream/from/interval"; -import { sync } from "@thi.ng/rstream/stream-sync"; +import { fromAtom, fromInterval, sync } from "@thi.ng/rstream"; +import { map } from "@thi.ng/transducers"; import { updateDOM } from "@thi.ng/transducers-hdom"; -import { map } from "@thi.ng/transducers/xform/map"; import { app } from "./app"; import { state } from "./state"; diff --git a/examples/hmr-basics/src/state.ts b/examples/hmr-basics/src/state.ts index be31ba6a61..451bc4a279 100644 --- a/examples/hmr-basics/src/state.ts +++ b/examples/hmr-basics/src/state.ts @@ -1,12 +1,13 @@ -import { Atom } from "@thi.ng/atom/atom"; -import { defonce } from "@thi.ng/memoize/defonce"; +import { Atom } from "@thi.ng/atom"; +import { defonce } from "@thi.ng/memoize"; // `defonce` is used here to protect the app stat atom from // re-initializing during hot module replacement. // in other words, the atom is *only* initialized once when the // application first loads / reloads -export const state = defonce("umbrella.example.hmr", () => - new Atom({ - launched: new Date(), - seed: (Math.random() * 100) | 0, - })); +export const state = + defonce("umbrella.example.hmr", () => + new Atom({ + launched: new Date(), + seed: (Math.random() * 100) | 0, + })); diff --git a/examples/hmr-basics/tsconfig.json b/examples/hmr-basics/tsconfig.json index 98e83903d2..50a1cade93 100644 --- a/examples/hmr-basics/tsconfig.json +++ b/examples/hmr-basics/tsconfig.json @@ -2,10 +2,9 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", - "sourceMap": true, - "noUnusedLocals": false, - "noUnusedParameters": false + "sourceMap": true }, "include": [ "./src/**/*.ts" diff --git a/examples/hydrate-basics/package.json b/examples/hydrate-basics/package.json index 3eeff85f23..388068ec87 100644 --- a/examples/hydrate-basics/package.json +++ b/examples/hydrate-basics/package.json @@ -15,7 +15,7 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "latest", + "@thi.ng/atom": "latest", "@thi.ng/hdom": "latest", "@thi.ng/hdom-components": "latest", "@thi.ng/hiccup": "latest" diff --git a/examples/hydrate-basics/src/index.ts b/examples/hydrate-basics/src/index.ts index 0faa1b3e45..025491b200 100644 --- a/examples/hydrate-basics/src/index.ts +++ b/examples/hydrate-basics/src/index.ts @@ -1,8 +1,7 @@ import { Atom } from "@thi.ng/atom"; -import { serialize } from "@thi.ng/hiccup/serialize"; -import { start } from "@thi.ng/hdom/start"; -import { canvas2D } from "@thi.ng/hdom-components/canvas"; -import { dropdown } from "@thi.ng/hdom-components/dropdown"; +import { start } from "@thi.ng/hdom"; +import { canvas2D, dropdown } from "@thi.ng/hdom-components"; +import { serialize } from "@thi.ng/hiccup"; // basic state container const state = new Atom({ diff --git a/examples/hydrate-basics/tsconfig.json b/examples/hydrate-basics/tsconfig.json index b7d63aedf0..50a1cade93 100644 --- a/examples/hydrate-basics/tsconfig.json +++ b/examples/hydrate-basics/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/interceptor-basics/package.json b/examples/interceptor-basics/package.json index 06cb1d3b78..a1f1e3b142 100644 --- a/examples/interceptor-basics/package.json +++ b/examples/interceptor-basics/package.json @@ -15,10 +15,10 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "latest", "@thi.ng/atom": "latest", - "@thi.ng/rstream": "latest", - "@thi.ng/transducers-hdom": "latest" + "@thi.ng/hdom": "latest", + "@thi.ng/interceptors": "latest", + "@thi.ng/transducers": "latest" }, "browserslist": [ "last 3 Chrome versions" diff --git a/examples/interceptor-basics/src/index.ts b/examples/interceptor-basics/src/index.ts index 428a3b2c46..1c29156961 100644 --- a/examples/interceptor-basics/src/index.ts +++ b/examples/interceptor-basics/src/index.ts @@ -1,7 +1,12 @@ import { Atom } from "@thi.ng/atom"; import { start } from "@thi.ng/hdom"; +import { + dispatchNow, + EventBus, + FX_STATE, + valueUpdater +} from "@thi.ng/interceptors"; import { choices } from "@thi.ng/transducers"; -import * as icep from "@thi.ng/interceptors"; // infinite iterator of random color choices const colors = choices(["cyan", "yellow", "magenta", "chartreuse"]); @@ -11,15 +16,15 @@ const db = new Atom({}); // event bus w/ handlers // see @thi.ng/interceptors for more details -const bus = new icep.EventBus(db, { +const bus = new EventBus(db, { "init": () => ({ - [icep.FX_STATE]: { clicks: 0, color: "grey" } + [FX_STATE]: { clicks: 0, color: "grey" } }), "inc-counter": [ - icep.valueUpdater("clicks", (x: number) => x + 1), - icep.dispatchNow(["randomize-color"]) + valueUpdater("clicks", (x: number) => x + 1), + dispatchNow(["randomize-color"]) ], - "randomize-color": icep.valueUpdater( + "randomize-color": valueUpdater( "color", () => colors.next().value ) }); diff --git a/examples/interceptor-basics/tsconfig.json b/examples/interceptor-basics/tsconfig.json index bbf112cc18..50a1cade93 100644 --- a/examples/interceptor-basics/tsconfig.json +++ b/examples/interceptor-basics/tsconfig.json @@ -2,10 +2,11 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/examples/interceptor-basics2/package.json b/examples/interceptor-basics2/package.json index 784456752c..276de1102b 100644 --- a/examples/interceptor-basics2/package.json +++ b/examples/interceptor-basics2/package.json @@ -16,8 +16,9 @@ }, "dependencies": { "@thi.ng/api": "latest", - "@thi.ng/atom": "latest", - "@thi.ng/hdom": "latest" + "@thi.ng/hdom": "latest", + "@thi.ng/intereptors": "latest", + "@thi.ng/paths": "latest" }, "browserslist": [ "last 3 Chrome versions" diff --git a/examples/interceptor-basics2/src/index.ts b/examples/interceptor-basics2/src/index.ts index 7027aeb40c..2c15f686a1 100644 --- a/examples/interceptor-basics2/src/index.ts +++ b/examples/interceptor-basics2/src/index.ts @@ -1,9 +1,17 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { start } from "@thi.ng/hdom/start"; -import { EffectDef, EventDef, IDispatch } from "@thi.ng/interceptors/api"; -import { EV_SET_VALUE, EV_UPDATE_VALUE, FX_DISPATCH_NOW } from "@thi.ng/interceptors/api"; -import { EventBus } from "@thi.ng/interceptors/event-bus"; -import { ensureStateGreaterThan, ensureStateLessThan, trace } from "@thi.ng/interceptors/interceptors"; +import { IObjectOf } from "@thi.ng/api"; +import { start } from "@thi.ng/hdom"; +import { + EffectDef, + ensureStateGreaterThan, + ensureStateLessThan, + EV_SET_VALUE, + EV_UPDATE_VALUE, + EventBus, + EventDef, + FX_DISPATCH_NOW, + IDispatch, + trace +} from "@thi.ng/interceptors"; import { Path } from "@thi.ng/paths"; /////////////////////////////////////////////////////////////////////// diff --git a/examples/interceptor-basics2/tsconfig.json b/examples/interceptor-basics2/tsconfig.json index b7d63aedf0..50a1cade93 100644 --- a/examples/interceptor-basics2/tsconfig.json +++ b/examples/interceptor-basics2/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/json-components/src/index.ts b/examples/json-components/src/index.ts index 728ae931aa..77452331ca 100644 --- a/examples/json-components/src/index.ts +++ b/examples/json-components/src/index.ts @@ -1,6 +1,5 @@ import { start } from "@thi.ng/hdom"; -import { TransformSubSpec } from "@thi.ng/transducers/api"; -import { deepTransform } from "@thi.ng/transducers/func/deep-transform"; +import { deepTransform, TransformSubSpec } from "@thi.ng/transducers"; // some dummy JSON records let db = [ diff --git a/examples/json-components/tsconfig.json b/examples/json-components/tsconfig.json index b7d63aedf0..50a1cade93 100644 --- a/examples/json-components/tsconfig.json +++ b/examples/json-components/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/login-form/package.json b/examples/login-form/package.json index 9a2f396e19..86f41ad8e0 100644 --- a/examples/login-form/package.json +++ b/examples/login-form/package.json @@ -16,7 +16,8 @@ }, "dependencies": { "@thi.ng/atom": "latest", - "@thi.ng/hdom": "latest" + "@thi.ng/hdom": "latest", + "@thi.ng/paths": "latest" }, "browserslist": [ "last 3 Chrome versions" diff --git a/examples/login-form/src/index.ts b/examples/login-form/src/index.ts index 089be68615..3a4f540a9b 100644 --- a/examples/login-form/src/index.ts +++ b/examples/login-form/src/index.ts @@ -1,5 +1,5 @@ -import { Atom } from "@thi.ng/atom/atom"; -import { start } from "@thi.ng/hdom/start"; +import { Atom } from "@thi.ng/atom"; +import { start } from "@thi.ng/hdom"; import { setIn } from "@thi.ng/paths"; // central immutable app state diff --git a/examples/login-form/tsconfig.json b/examples/login-form/tsconfig.json index b7d63aedf0..50a1cade93 100644 --- a/examples/login-form/tsconfig.json +++ b/examples/login-form/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/mandelbrot/package.json b/examples/mandelbrot/package.json index 35fe5eadf6..dc8873a6aa 100644 --- a/examples/mandelbrot/package.json +++ b/examples/mandelbrot/package.json @@ -7,7 +7,7 @@ "scripts": { "clean": "rm -rf .cache build out", "build": "yarn clean && yarn build:worker && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --detailed-report", - "build:worker": "parcel build src/worker.ts -d out --no-source-maps --no-cache --detailed-report", + "build:worker": "parcel build src/worker.ts -d out --no-source-maps --no-cache --detailed-report --experimental-scope-hoisting", "start": "yarn build:worker && parcel index.html -d out -p 8080 --open" }, "devDependencies": { @@ -17,8 +17,14 @@ }, "dependencies": { "@thi.ng/api": "latest", - "@thi.ng/atom": "latest", + "@thi.ng/compose": "latest", + "@thi.ng/equiv": "latest", + "@thi.ng/hdom-components": "latest", + "@thi.ng/math": "latest", "@thi.ng/rstream": "latest", + "@thi.ng/rstream-gestures": "latest", + "@thi.ng/strings": "latest", + "@thi.ng/transducers": "latest", "@thi.ng/transducers-hdom": "latest" }, "browserslist": [ diff --git a/examples/mandelbrot/src/gradient.ts b/examples/mandelbrot/src/gradient.ts index 752fd1d0b4..7292e5b1df 100644 --- a/examples/mandelbrot/src/gradient.ts +++ b/examples/mandelbrot/src/gradient.ts @@ -1,31 +1,34 @@ -import { TAU } from "@thi.ng/math/api"; -import { clamp01 } from "@thi.ng/math/interval"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { normRange } from "@thi.ng/transducers/iter/norm-range"; -import { tuples } from "@thi.ng/transducers/iter/tuples"; -import { push } from "@thi.ng/transducers/rfn/push"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { map } from "@thi.ng/transducers/xform/map"; +import { clamp01, TAU } from "@thi.ng/math"; +import { + comp, + map, + normRange, + push, + transduce, + tuples +} from "@thi.ng/transducers"; // see http://dev.thi.ng/gradients/ -const cosColor = (dc: number[], amp: number[], fmod: number[], phase: number[], t: number) => - transduce( - map( - ([a, b, c, d]) => clamp01(a + b * Math.cos(TAU * (c * t + d))) - ), - push(), - tuples(dc, amp, fmod, phase) - ); +const cosColor = + (dc: number[], amp: number[], fmod: number[], phase: number[], t: number) => + transduce( + map( + ([a, b, c, d]) => clamp01(a + b * Math.cos(TAU * (c * t + d))) + ), + push(), + tuples(dc, amp, fmod, phase) + ); -export const cosineGradient = (n: number, spec: number[][]) => { - const [dc, amp, fmod, phase] = spec; - return transduce( - comp( - map((t: number) => cosColor(dc, amp, fmod, phase, t)), - map(([r, g, b]) => (b * 255) << 16 | (g * 255) << 8 | (r * 255) | 0xff000000) - ), - push(), - normRange(n - 1) - ); -}; +export const cosineGradient = + (n: number, spec: number[][]) => { + const [dc, amp, fmod, phase] = spec; + return transduce( + comp( + map((t: number) => cosColor(dc, amp, fmod, phase, t)), + map(([r, g, b]) => (b * 255) << 16 | (g * 255) << 8 | (r * 255) | 0xff000000) + ), + push(), + normRange(n - 1) + ); + }; diff --git a/examples/mandelbrot/src/index.ts b/examples/mandelbrot/src/index.ts index de54786dbd..5577e14895 100644 --- a/examples/mandelbrot/src/index.ts +++ b/examples/mandelbrot/src/index.ts @@ -1,14 +1,11 @@ import { equiv } from "@thi.ng/equiv"; -import { canvas2D } from "@thi.ng/hdom-components/canvas"; -import { fit } from "@thi.ng/math/fit"; -import { mix } from "@thi.ng/math/mix"; +import { canvas2D } from "@thi.ng/hdom-components"; +import { fit, mix } from "@thi.ng/math"; +import { stream, sync, tunnel } from "@thi.ng/rstream"; import { gestureStream, GestureType } from "@thi.ng/rstream-gestures"; -import { stream } from "@thi.ng/rstream/stream"; -import { sync } from "@thi.ng/rstream/stream-sync"; -import { tunnel } from "@thi.ng/rstream/subs/tunnel"; +import { padLeft } from "@thi.ng/strings"; +import { map } from "@thi.ng/transducers"; import { updateDOM } from "@thi.ng/transducers-hdom"; -import { map } from "@thi.ng/transducers/xform/map"; -import { padLeft } from "@thi.ng/strings/pad-left"; import { download } from "./download"; // if enabled, auto-zoom out & export frames diff --git a/examples/mandelbrot/src/worker.ts b/examples/mandelbrot/src/worker.ts index 45e889820f..91247d47d0 100644 --- a/examples/mandelbrot/src/worker.ts +++ b/examples/mandelbrot/src/worker.ts @@ -1,5 +1,5 @@ -import { partial } from "@thi.ng/compose/partial"; -import { fit01 } from "@thi.ng/math/fit"; +import { partial } from "@thi.ng/compose"; +import { fit01 } from "@thi.ng/math"; import { cosineGradient } from "./gradient"; // see http://dev.thi.ng/gradients/ diff --git a/examples/mandelbrot/tsconfig.json b/examples/mandelbrot/tsconfig.json index bbf112cc18..50a1cade93 100644 --- a/examples/mandelbrot/tsconfig.json +++ b/examples/mandelbrot/tsconfig.json @@ -2,10 +2,11 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/examples/markdown/package.json b/examples/markdown/package.json index 99de136d8d..af2950e06d 100644 --- a/examples/markdown/package.json +++ b/examples/markdown/package.json @@ -17,6 +17,7 @@ }, "dependencies": { "@thi.ng/api": "latest", + "@thi.ng/bench": "latest", "@thi.ng/hiccup-markdown": "latest", "@thi.ng/rstream": "latest", "@thi.ng/transducers-hdom": "latest" diff --git a/examples/markdown/src/index.ts b/examples/markdown/src/index.ts index 18616d7f31..7c84089307 100644 --- a/examples/markdown/src/index.ts +++ b/examples/markdown/src/index.ts @@ -1,13 +1,12 @@ import { timedResult } from "@thi.ng/bench"; -import { TagFactories } from "@thi.ng/hiccup-markdown/api"; -import { parse } from "@thi.ng/hiccup-markdown/parse"; -import { stream, Stream } from "@thi.ng/rstream/stream"; +import { TagFactories, parse } from "@thi.ng/hiccup-markdown"; +import { stream, Stream } from "@thi.ng/rstream"; import { updateDOM } from "@thi.ng/transducers-hdom"; -import { iterator } from "@thi.ng/transducers/iterator"; -import { map } from "@thi.ng/transducers/xform/map"; +import { iterator, map } from "@thi.ng/transducers"; // ignore error, resolved by parcel import readme from "../README.md"; +// const readme = "README.af35c500.md" // custom tag factories (passed to parser) // uses Tachyons CSS classes for styling diff --git a/examples/markdown/tsconfig.json b/examples/markdown/tsconfig.json index bbf112cc18..50a1cade93 100644 --- a/examples/markdown/tsconfig.json +++ b/examples/markdown/tsconfig.json @@ -2,10 +2,11 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/examples/pointfree-svg/output.svg b/examples/pointfree-svg/output.svg index 5789d06190..cd29cbc172 100644 --- a/examples/pointfree-svg/output.svg +++ b/examples/pointfree-svg/output.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/examples/pointfree-svg/tsconfig.json b/examples/pointfree-svg/tsconfig.json index 9afed7f9d2..79a8c793a7 100644 --- a/examples/pointfree-svg/tsconfig.json +++ b/examples/pointfree-svg/tsconfig.json @@ -2,9 +2,9 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "commonjs", "target": "es6", - "sourceMap": true, - "noUnusedLocals": false, + "sourceMap": true }, "include": [ "./src/**/*.ts" diff --git a/examples/router-basics/package.json b/examples/router-basics/package.json index 7c5bc56019..311f284a49 100644 --- a/examples/router-basics/package.json +++ b/examples/router-basics/package.json @@ -12,7 +12,9 @@ "start": "yarn prep && parcel index.html -p 8080 --open -d out" }, "dependencies": { + "@thi.ng/api": "latest", "@thi.ng/atom": "latest", + "@thi.ng/checks": "latest", "@thi.ng/interceptors": "latest", "@thi.ng/hdom": "latest", "@thi.ng/router": "latest" diff --git a/examples/router-basics/src/api.ts b/examples/router-basics/src/api.ts index 296ce1831c..11e823b6ff 100644 --- a/examples/router-basics/src/api.ts +++ b/examples/router-basics/src/api.ts @@ -1,8 +1,7 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { IView, ViewTransform } from "@thi.ng/atom/api"; -import { EffectDef, EventDef } from "@thi.ng/interceptors/api"; -import { EventBus } from "@thi.ng/interceptors/event-bus"; -import { HTMLRouterConfig, RouteMatch } from "@thi.ng/router/api"; +import { IObjectOf } from "@thi.ng/api"; +import { IView, ViewTransform } from "@thi.ng/atom"; +import { EffectDef, EventBus, EventDef } from "@thi.ng/interceptors"; +import { HTMLRouterConfig, RouteMatch } from "@thi.ng/router"; // general types defined for the base app diff --git a/examples/router-basics/src/app.ts b/examples/router-basics/src/app.ts index c046f68e70..584c2c22a2 100644 --- a/examples/router-basics/src/app.ts +++ b/examples/router-basics/src/app.ts @@ -1,12 +1,9 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { Atom } from "@thi.ng/atom/atom"; -import { isArray } from "@thi.ng/checks/is-array"; +import { IObjectOf } from "@thi.ng/api"; +import { Atom } from "@thi.ng/atom"; +import { isArray } from "@thi.ng/checks"; import { start } from "@thi.ng/hdom"; -import { EventBus } from "@thi.ng/interceptors/event-bus"; -import { trace, valueSetter } from "@thi.ng/interceptors/interceptors"; -import { EVENT_ROUTE_CHANGED } from "@thi.ng/router/api"; -import { HTMLRouter } from "@thi.ng/router/history"; - +import { EventBus, trace, valueSetter } from "@thi.ng/interceptors"; +import { EVENT_ROUTE_CHANGED, HTMLRouter } from "@thi.ng/router"; import { AppConfig, AppContext, @@ -18,6 +15,7 @@ import { nav } from "./components/nav"; import * as fx from "./effects"; import * as ev from "./events"; + /** * Generic base app skeleton. You can use this as basis for your own * apps. diff --git a/examples/router-basics/src/components/event-link.ts b/examples/router-basics/src/components/event-link.ts index 810aac41a0..3104c74161 100644 --- a/examples/router-basics/src/components/event-link.ts +++ b/examples/router-basics/src/components/event-link.ts @@ -1,4 +1,4 @@ -import { Event } from "@thi.ng/interceptors/api"; +import { Event } from "@thi.ng/interceptors"; import { AppContext } from "../api"; diff --git a/examples/router-basics/src/config.ts b/examples/router-basics/src/config.ts index 0b15eb161d..616ebd2449 100644 --- a/examples/router-basics/src/config.ts +++ b/examples/router-basics/src/config.ts @@ -3,10 +3,9 @@ import { Event, FX_DELAY, FX_DISPATCH_ASYNC, - FX_DISPATCH_NOW -} from "@thi.ng/interceptors/api"; -import { valueUpdater } from "@thi.ng/interceptors/interceptors"; - + FX_DISPATCH_NOW, + valueUpdater +} from "@thi.ng/interceptors"; import { AppConfig, StatusType } from "./api"; import { allUsers } from "./components/all-users"; import { contact } from "./components/contact"; diff --git a/examples/router-basics/src/routes.ts b/examples/router-basics/src/routes.ts index 01a68be3fb..4bf0ec9a44 100644 --- a/examples/router-basics/src/routes.ts +++ b/examples/router-basics/src/routes.ts @@ -1,4 +1,4 @@ -import { Route } from "@thi.ng/router/api"; +import { Route } from "@thi.ng/router"; // route definitions: // routes are 1st class objects and used directly throughout the app diff --git a/examples/router-basics/tsconfig.json b/examples/router-basics/tsconfig.json index b7d63aedf0..50a1cade93 100644 --- a/examples/router-basics/tsconfig.json +++ b/examples/router-basics/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/rstream-dataflow/package.json b/examples/rstream-dataflow/package.json index ae22cad7b0..1726205766 100644 --- a/examples/rstream-dataflow/package.json +++ b/examples/rstream-dataflow/package.json @@ -15,8 +15,8 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "latest", "@thi.ng/atom": "latest", + "@thi.ng/equiv": "latest", "@thi.ng/hdom": "latest", "@thi.ng/paths": "latest", "@thi.ng/rstream": "latest", diff --git a/examples/rstream-dataflow/src/circle.ts b/examples/rstream-dataflow/src/circle.ts index 324ba14133..50e78e5497 100644 --- a/examples/rstream-dataflow/src/circle.ts +++ b/examples/rstream-dataflow/src/circle.ts @@ -1,15 +1,15 @@ const px = (x: number) => x.toFixed(3) + "px"; // @thi.ng/hdom UI component function -export function circle(col: string, x: number, y: number, w: number, h = w) { - return ["div", { - class: "absolute z-1 white f7 tc br-100 " + col, - style: { - left: px(x - w / 2), - top: px(y - h / 2), - width: px(w), - height: px(h), - "line-height": px(h), - } - }, `${x};${y}`]; -} +export const circle = + (col: string, x: number, y: number, w: number, h = w) => + ["div", { + class: "absolute z-1 white f7 tc br-100 " + col, + style: { + left: px(x - w / 2), + top: px(y - h / 2), + width: px(w), + height: px(h), + "line-height": px(h), + } + }, `${x};${y}`]; diff --git a/examples/rstream-dataflow/src/index.ts b/examples/rstream-dataflow/src/index.ts index d402f326d4..64ef333e62 100644 --- a/examples/rstream-dataflow/src/index.ts +++ b/examples/rstream-dataflow/src/index.ts @@ -1,18 +1,23 @@ -import { Atom } from "@thi.ng/atom/atom"; +import { Atom } from "@thi.ng/atom"; import { equiv } from "@thi.ng/equiv"; import { start } from "@thi.ng/hdom"; import { getIn } from "@thi.ng/paths"; +import { fromRAF } from "@thi.ng/rstream"; import { toDot, walk } from "@thi.ng/rstream-dot"; import { gestureStream } from "@thi.ng/rstream-gestures"; -import { initGraph, node, node1 } from "@thi.ng/rstream-graph/graph"; -import { extract } from "@thi.ng/rstream-graph/nodes/extract"; -import { mul } from "@thi.ng/rstream-graph/nodes/math"; -import { fromRAF } from "@thi.ng/rstream/from/raf"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { choices } from "@thi.ng/transducers/iter/choices"; -import { dedupe } from "@thi.ng/transducers/xform/dedupe"; -import { map } from "@thi.ng/transducers/xform/map"; - +import { + extract, + initGraph, + mul, + node, + node1 +} from "@thi.ng/rstream-graph"; +import { + choices, + comp, + dedupe, + map +} from "@thi.ng/transducers"; import { circle } from "./circle"; // infinite iterator of randomized colors (Tachyons CSS class names) diff --git a/examples/rstream-dataflow/tsconfig.json b/examples/rstream-dataflow/tsconfig.json index fa5ea1aab2..50a1cade93 100644 --- a/examples/rstream-dataflow/tsconfig.json +++ b/examples/rstream-dataflow/tsconfig.json @@ -2,14 +2,11 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", - "sourceMap": true, - "noUnusedLocals": false, + "sourceMap": true }, "include": [ "./src/**/*.ts" - ], - "exclude": [ - "**/node_modules" ] } \ No newline at end of file diff --git a/examples/rstream-grid/package.json b/examples/rstream-grid/package.json index 07b9693170..6731751d1c 100644 --- a/examples/rstream-grid/package.json +++ b/examples/rstream-grid/package.json @@ -11,10 +11,15 @@ "start": "parcel index.html -p 8080 --open" }, "dependencies": { + "@thi.ng/api": "latest", "@thi.ng/atom": "latest", + "@thi.ng/checks": "latest", "@thi.ng/hdom": "latest", + "@thi.ng/hiccup": "latest", "@thi.ng/hiccup-svg": "latest", "@thi.ng/interceptors": "latest", + "@thi.ng/paths": "latest", + "@thi.ng/rstream": "latest", "@thi.ng/rstream-graph": "latest", "@thi.ng/transducers": "latest" }, diff --git a/examples/rstream-grid/src/api.ts b/examples/rstream-grid/src/api.ts index 6f788867c0..a6ebf7199e 100644 --- a/examples/rstream-grid/src/api.ts +++ b/examples/rstream-grid/src/api.ts @@ -1,7 +1,6 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { IView, ViewTransform } from "@thi.ng/atom/api"; -import { EffectDef, EventDef } from "@thi.ng/interceptors/api"; -import { EventBus } from "@thi.ng/interceptors/event-bus"; +import { IObjectOf } from "@thi.ng/api"; +import { IView, ViewTransform } from "@thi.ng/atom"; +import { EffectDef, EventBus, EventDef } from "@thi.ng/interceptors"; /** * Function signature for main app components. diff --git a/examples/rstream-grid/src/app.ts b/examples/rstream-grid/src/app.ts index 8a8d10b1fe..54332df1b6 100644 --- a/examples/rstream-grid/src/app.ts +++ b/examples/rstream-grid/src/app.ts @@ -1,11 +1,8 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { Atom } from "@thi.ng/atom/atom"; -import { Cursor } from "@thi.ng/atom/cursor"; -import { History } from "@thi.ng/atom/history"; -import { isArray } from "@thi.ng/checks/is-array"; -import { start } from "@thi.ng/hdom/start"; -import { EventBus } from "@thi.ng/interceptors/event-bus"; - +import { IObjectOf } from "@thi.ng/api"; +import { Atom, Cursor, History } from "@thi.ng/atom"; +import { isArray } from "@thi.ng/checks"; +import { start } from "@thi.ng/hdom"; +import { EventBus } from "@thi.ng/interceptors"; import { AppConfig, AppContext, diff --git a/examples/rstream-grid/src/components/event-link.ts b/examples/rstream-grid/src/components/event-link.ts index ddc4c8bb7a..b0eb0a936c 100644 --- a/examples/rstream-grid/src/components/event-link.ts +++ b/examples/rstream-grid/src/components/event-link.ts @@ -1,4 +1,4 @@ -import { Event } from "@thi.ng/interceptors/api"; +import { Event } from "@thi.ng/interceptors"; import { AppContext } from "../api"; diff --git a/examples/rstream-grid/src/config.ts b/examples/rstream-grid/src/config.ts index 5b08bd848b..a812d509fd 100644 --- a/examples/rstream-grid/src/config.ts +++ b/examples/rstream-grid/src/config.ts @@ -1,9 +1,8 @@ -import { serialize } from "@thi.ng/hiccup/serialize"; -import { snapshot, valueSetter } from "@thi.ng/interceptors/interceptors"; +import { serialize } from "@thi.ng/hiccup"; +import { snapshot, valueSetter } from "@thi.ng/interceptors"; import { getIn } from "@thi.ng/paths"; -import { fromIterable } from "@thi.ng/rstream/from/iterable"; -import { range } from "@thi.ng/transducers/iter/range"; - +import { fromIterable } from "@thi.ng/rstream"; +import { range } from "@thi.ng/transducers"; import { AppConfig } from "./api"; import { main } from "./components/main"; import { download } from "./download"; diff --git a/examples/rstream-grid/src/dataflow.ts b/examples/rstream-grid/src/dataflow.ts index e17ea7ab81..42809b4425 100644 --- a/examples/rstream-grid/src/dataflow.ts +++ b/examples/rstream-grid/src/dataflow.ts @@ -1,11 +1,7 @@ -import { svg } from "@thi.ng/hiccup-svg/svg"; -import { group } from "@thi.ng/hiccup-svg/group"; -import { rect } from "@thi.ng/hiccup-svg/rect"; -import { EventBus } from "@thi.ng/interceptors/event-bus"; -import { initGraph, node } from "@thi.ng/rstream-graph/graph"; -import { range2d } from "@thi.ng/transducers/iter/range2d"; -import { map } from "@thi.ng/transducers/xform/map"; - +import { group, rect, svg } from "@thi.ng/hiccup-svg"; +import { EventBus } from "@thi.ng/interceptors"; +import { initGraph, node } from "@thi.ng/rstream-graph"; +import { map, range2d } from "@thi.ng/transducers"; import * as ev from "./events"; import * as paths from "./paths"; diff --git a/examples/rstream-grid/src/events.ts b/examples/rstream-grid/src/events.ts index 6ba34a9487..2402d9388b 100644 --- a/examples/rstream-grid/src/events.ts +++ b/examples/rstream-grid/src/events.ts @@ -1,4 +1,4 @@ -import { EV_REDO, EV_UNDO } from "@thi.ng/interceptors/api"; +import { EV_REDO, EV_UNDO } from "@thi.ng/interceptors"; // best practice tip: define event & effect names as consts or enums // and avoid hardcoded strings for more safety and easier refactoring diff --git a/examples/rstream-grid/tsconfig.json b/examples/rstream-grid/tsconfig.json index 614bda1f84..50a1cade93 100644 --- a/examples/rstream-grid/tsconfig.json +++ b/examples/rstream-grid/tsconfig.json @@ -2,10 +2,9 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", - "sourceMap": true, - "noUnusedParameters": true, - "noUnusedLocals": true + "sourceMap": true }, "include": [ "./src/**/*.ts" diff --git a/examples/rstream-hdom/package.json b/examples/rstream-hdom/package.json index 2decae4fec..ea7787e69a 100644 --- a/examples/rstream-hdom/package.json +++ b/examples/rstream-hdom/package.json @@ -15,10 +15,9 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "latest", - "@thi.ng/hdom": "latest", "@thi.ng/rstream": "latest", - "@thi.ng/transducers": "latest" + "@thi.ng/transducers": "latest", + "@thi.ng/transducers-hdom": "latest" }, "browserslist": [ "last 3 Chrome versions" diff --git a/examples/rstream-hdom/src/index.ts b/examples/rstream-hdom/src/index.ts index ca7f079685..56b79ba5a3 100644 --- a/examples/rstream-hdom/src/index.ts +++ b/examples/rstream-hdom/src/index.ts @@ -1,14 +1,19 @@ -import { ISubscribable } from "@thi.ng/rstream/api"; -import { fromRAF } from "@thi.ng/rstream/from/raf"; -import { sync } from "@thi.ng/rstream/stream-sync"; -import { sidechainPartition } from "@thi.ng/rstream/subs/sidechain-partition"; -import { Subscription, subscription } from "@thi.ng/rstream/subscription"; +import { + fromRAF, + ISubscribable, + sidechainPartition, + Subscription, + subscription, + sync +} from "@thi.ng/rstream"; +import { + map, + peek, + reducer, + scan, + vals +} from "@thi.ng/transducers"; import { updateDOM } from "@thi.ng/transducers-hdom"; -import { peek } from "@thi.ng/transducers/func/peek"; -import { vals } from "@thi.ng/transducers/iter/vals"; -import { reducer } from "@thi.ng/transducers/reduce"; -import { map } from "@thi.ng/transducers/xform/map"; -import { scan } from "@thi.ng/transducers/xform/scan"; // example user context object // here only used to provide style / theme config using diff --git a/examples/rstream-hdom/tsconfig.json b/examples/rstream-hdom/tsconfig.json index b7d63aedf0..50a1cade93 100644 --- a/examples/rstream-hdom/tsconfig.json +++ b/examples/rstream-hdom/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/svg-barchart/package.json b/examples/svg-barchart/package.json index 75290b28f1..6604191c11 100644 --- a/examples/svg-barchart/package.json +++ b/examples/svg-barchart/package.json @@ -15,10 +15,8 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "latest", - "@thi.ng/atom": "latest", - "@thi.ng/rstream": "latest", - "@thi.ng/transducers-hdom": "latest" + "@thi.ng/hdom": "latest", + "@thi.ng/transducers": "latest" }, "browserslist": [ "last 3 Chrome versions" diff --git a/examples/svg-barchart/src/index.ts b/examples/svg-barchart/src/index.ts index cdaa640e43..ffc7d76775 100644 --- a/examples/svg-barchart/src/index.ts +++ b/examples/svg-barchart/src/index.ts @@ -1,7 +1,5 @@ import { clearDOM, renderOnce } from "@thi.ng/hdom"; -import { range } from "@thi.ng/transducers/iter/range"; -import { map } from "@thi.ng/transducers/xform/map"; -import { mapcat } from "@thi.ng/transducers/xform/mapcat"; +import { range, map, mapcat } from "@thi.ng/transducers"; // fit `x` from range (a,b) => (c,d) const fit = (x, a, b, c, d) => (x - a) / (b - a) * (d - c) + c; diff --git a/examples/svg-barchart/tsconfig.json b/examples/svg-barchart/tsconfig.json index bbf112cc18..50a1cade93 100644 --- a/examples/svg-barchart/tsconfig.json +++ b/examples/svg-barchart/tsconfig.json @@ -2,10 +2,11 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/examples/svg-particles/src/index.ts b/examples/svg-particles/src/index.ts index 0e6cf49940..441a7cb056 100644 --- a/examples/svg-particles/src/index.ts +++ b/examples/svg-particles/src/index.ts @@ -1,6 +1,6 @@ import { start } from "@thi.ng/hdom"; -import { radix } from "@thi.ng/strings/radix"; -import { repeatedly } from "@thi.ng/transducers/iter/repeatedly"; +import { radix } from "@thi.ng/strings"; +import { repeatedly } from "@thi.ng/transducers"; const width = window.innerWidth; const height = window.innerHeight; @@ -37,7 +37,7 @@ const app = () => { for (let i = particles.length - 1; i > 0; i--) { updateParticle(particles[i][1], velocities[i]); } - return ["svg", { width, height }, particles]; + return ["svg", { width, height, __diff: false }, particles]; }; -start(app); \ No newline at end of file +start(app); diff --git a/examples/svg-particles/tsconfig.json b/examples/svg-particles/tsconfig.json index b7d63aedf0..50a1cade93 100644 --- a/examples/svg-particles/tsconfig.json +++ b/examples/svg-particles/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/svg-waveform/package.json b/examples/svg-waveform/package.json index b1492a28e3..0f998b01b7 100644 --- a/examples/svg-waveform/package.json +++ b/examples/svg-waveform/package.json @@ -11,7 +11,9 @@ "start": "parcel index.html -p 8080 --open" }, "dependencies": { + "@thi.ng/api": "latest", "@thi.ng/atom": "latest", + "@thi.ng/checks": "latest", "@thi.ng/hdom": "latest", "@thi.ng/hiccup-svg": "latest", "@thi.ng/interceptors": "latest", diff --git a/examples/svg-waveform/src/api.ts b/examples/svg-waveform/src/api.ts index bdafc7ba5a..05f240e789 100644 --- a/examples/svg-waveform/src/api.ts +++ b/examples/svg-waveform/src/api.ts @@ -1,7 +1,6 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { ViewTransform, IView } from "@thi.ng/atom/api"; -import { EventDef, EffectDef } from "@thi.ng/interceptors/api"; -import { EventBus } from "@thi.ng/interceptors/event-bus"; +import { IObjectOf } from "@thi.ng/api"; +import { IView, ViewTransform } from "@thi.ng/atom"; +import { EffectDef, EventBus, EventDef } from "@thi.ng/interceptors"; /** * Function signature for main app components. diff --git a/examples/svg-waveform/src/app.ts b/examples/svg-waveform/src/app.ts index 2e5bbf4c2a..1e1ad456a6 100644 --- a/examples/svg-waveform/src/app.ts +++ b/examples/svg-waveform/src/app.ts @@ -1,11 +1,14 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { Atom } from "@thi.ng/atom/atom"; -import { History } from "@thi.ng/atom/history"; -import { isArray } from "@thi.ng/checks/is-array"; +import { IObjectOf } from "@thi.ng/api"; +import { Atom, History } from "@thi.ng/atom"; +import { isArray } from "@thi.ng/checks"; import { start } from "@thi.ng/hdom"; -import { EventBus } from "@thi.ng/interceptors/event-bus"; - -import { AppConfig, AppContext, AppViews, ViewSpec } from "./api"; +import { EventBus } from "@thi.ng/interceptors"; +import { + AppConfig, + AppContext, + AppViews, + ViewSpec +} from "./api"; import * as ev from "./events"; /** diff --git a/examples/svg-waveform/src/components/event-link.ts b/examples/svg-waveform/src/components/event-link.ts index fce1ca8aa7..721bf6dd5d 100644 --- a/examples/svg-waveform/src/components/event-link.ts +++ b/examples/svg-waveform/src/components/event-link.ts @@ -1,4 +1,4 @@ -import { Event } from "@thi.ng/interceptors/api"; +import { Event } from "@thi.ng/interceptors"; import { AppContext } from "../api"; diff --git a/examples/svg-waveform/src/components/waveform.ts b/examples/svg-waveform/src/components/waveform.ts index 7940b64fe2..b196817f00 100644 --- a/examples/svg-waveform/src/components/waveform.ts +++ b/examples/svg-waveform/src/components/waveform.ts @@ -1,11 +1,15 @@ -import { svg } from "@thi.ng/hiccup-svg/svg"; -import { defs } from "@thi.ng/hiccup-svg/defs"; -import { linearGradient } from "@thi.ng/hiccup-svg/gradients"; -import { polyline } from "@thi.ng/hiccup-svg/polyline"; -import { map } from "@thi.ng/transducers/xform/map"; -import { range } from "@thi.ng/transducers/iter/range"; -import { reduce, reducer } from "@thi.ng/transducers/reduce"; - +import { + defs, + linearGradient, + polyline, + svg +} from "@thi.ng/hiccup-svg"; +import { + map, + range, + reduce, + reducer +} from "@thi.ng/transducers"; import { AppContext } from "../api"; const TAU = Math.PI * 2; diff --git a/examples/svg-waveform/src/events.ts b/examples/svg-waveform/src/events.ts index 4f9837bb18..e57f04400e 100644 --- a/examples/svg-waveform/src/events.ts +++ b/examples/svg-waveform/src/events.ts @@ -1,4 +1,4 @@ -import { EV_UNDO, EV_REDO } from "@thi.ng/interceptors/api"; +import { EV_UNDO, EV_REDO } from "@thi.ng/interceptors"; // best practice tip: define event & effect names as consts or enums // and avoid hardcoded strings for more safety and easier refactoring diff --git a/examples/svg-waveform/tsconfig.json b/examples/svg-waveform/tsconfig.json index 614bda1f84..50a1cade93 100644 --- a/examples/svg-waveform/tsconfig.json +++ b/examples/svg-waveform/tsconfig.json @@ -2,10 +2,9 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", - "sourceMap": true, - "noUnusedParameters": true, - "noUnusedLocals": true + "sourceMap": true }, "include": [ "./src/**/*.ts" diff --git a/examples/talk-slides/package.json b/examples/talk-slides/package.json index 86af6005ba..77e4271c95 100644 --- a/examples/talk-slides/package.json +++ b/examples/talk-slides/package.json @@ -15,9 +15,10 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "latest", + "@thi.ng/hdom": "latest", "@thi.ng/math": "latest", "@thi.ng/rstream": "latest", + "@thi.ng/strings": "latest", "@thi.ng/transducers": "latest", "@thi.ng/transducers-hdom": "latest" }, diff --git a/examples/talk-slides/src/index.ts b/examples/talk-slides/src/index.ts index ea1660cd0b..e87fb41fd3 100644 --- a/examples/talk-slides/src/index.ts +++ b/examples/talk-slides/src/index.ts @@ -1,16 +1,20 @@ -import { renderOnce } from "@thi.ng/hdom/render-once"; -import { clamp } from "@thi.ng/math/interval"; -import { fromEvent } from "@thi.ng/rstream/from/event"; -import { fromInterval } from "@thi.ng/rstream/from/interval"; -import { stream } from "@thi.ng/rstream/stream"; -import { sync } from "@thi.ng/rstream/stream-sync"; -import { padLeft } from "@thi.ng/strings/pad-left"; +import { renderOnce } from "@thi.ng/hdom"; +import { clamp } from "@thi.ng/math"; +import { + fromEvent, + fromInterval, + stream, + sync +} from "@thi.ng/rstream"; +import { padLeft } from "@thi.ng/strings"; +import { + dedupe, + map, + reducer, + scan, + sideEffect +} from "@thi.ng/transducers"; import { updateDOM } from "@thi.ng/transducers-hdom"; -import { reducer } from "@thi.ng/transducers/reduce"; -import { dedupe } from "@thi.ng/transducers/xform/dedupe"; -import { map } from "@thi.ng/transducers/xform/map"; -import { scan } from "@thi.ng/transducers/xform/scan"; -import { sideEffect } from "@thi.ng/transducers/xform/side-effect"; import { app, printApp } from "./components"; import { ctx } from "./config"; import { SLIDES } from "./slides"; diff --git a/examples/talk-slides/tsconfig.json b/examples/talk-slides/tsconfig.json index bbf112cc18..50a1cade93 100644 --- a/examples/talk-slides/tsconfig.json +++ b/examples/talk-slides/tsconfig.json @@ -2,10 +2,11 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/examples/todo-list/package.json b/examples/todo-list/package.json index 079ff4cbec..e9d8ab7bdc 100644 --- a/examples/todo-list/package.json +++ b/examples/todo-list/package.json @@ -15,6 +15,7 @@ "typescript": "^3.2.2" }, "dependencies": { + "@thi.ng/api": "latest", "@thi.ng/atom": "latest", "@thi.ng/hdom": "latest", "@thi.ng/paths": "latest", diff --git a/examples/todo-list/src/index.ts b/examples/todo-list/src/index.ts index f539dd9e96..48ba33b4aa 100644 --- a/examples/todo-list/src/index.ts +++ b/examples/todo-list/src/index.ts @@ -1,9 +1,8 @@ -import { IObjectOf } from "@thi.ng/api/api"; +import { IObjectOf } from "@thi.ng/api"; import { Atom, Cursor, History } from "@thi.ng/atom"; -import { start } from "@thi.ng/hdom/start"; +import { start } from "@thi.ng/hdom"; import { setIn, updateIn } from "@thi.ng/paths"; -import { pairs } from "@thi.ng/transducers/iter/pairs"; -import { map } from "@thi.ng/transducers/xform/map"; +import { map, pairs } from "@thi.ng/transducers"; interface Task { done: boolean; diff --git a/examples/todo-list/tsconfig.json b/examples/todo-list/tsconfig.json index b7d63aedf0..50a1cade93 100644 --- a/examples/todo-list/tsconfig.json +++ b/examples/todo-list/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/transducers-hdom/package.json b/examples/transducers-hdom/package.json index aabe19927d..0529941d81 100644 --- a/examples/transducers-hdom/package.json +++ b/examples/transducers-hdom/package.json @@ -16,6 +16,7 @@ }, "dependencies": { "@thi.ng/rstream": "latest", + "@thi.ng/transducers": "latest", "@thi.ng/transducers-hdom": "latest" }, "browserslist": [ diff --git a/examples/transducers-hdom/src/index.ts b/examples/transducers-hdom/src/index.ts index 8ae55763e1..52e47c407a 100644 --- a/examples/transducers-hdom/src/index.ts +++ b/examples/transducers-hdom/src/index.ts @@ -1,10 +1,6 @@ -import { fromInterval } from "@thi.ng/rstream/from/interval"; -import { stream } from "@thi.ng/rstream/stream"; -import { sync } from "@thi.ng/rstream/stream-sync"; +import { fromInterval, stream, sync } from "@thi.ng/rstream"; +import { count, map, scan } from "@thi.ng/transducers"; import { updateDOM } from "@thi.ng/transducers-hdom"; -import { count } from "@thi.ng/transducers/rfn/count"; -import { map } from "@thi.ng/transducers/xform/map"; -import { scan } from "@thi.ng/transducers/xform/scan"; // root component function // (using Tachyons CSS classes for styling) diff --git a/examples/transducers-hdom/tsconfig.json b/examples/transducers-hdom/tsconfig.json index b7d63aedf0..50a1cade93 100644 --- a/examples/transducers-hdom/tsconfig.json +++ b/examples/transducers-hdom/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, diff --git a/examples/triple-query/package.json b/examples/triple-query/package.json index 016b34009e..7c8d25302f 100644 --- a/examples/triple-query/package.json +++ b/examples/triple-query/package.json @@ -16,7 +16,12 @@ }, "dependencies": { "@thi.ng/api": "latest", + "@thi.ng/atom": "latest", + "@thi.ng/checks": "latest", + "@thi.ng/compare": "latest", "@thi.ng/hdom": "latest", + "@thi.ng/hdom-components": "latest", + "@thi.ng/paths": "latest", "@thi.ng/rstream-query": "latest", "@thi.ng/transducers": "latest" }, diff --git a/examples/triple-query/src/api.ts b/examples/triple-query/src/api.ts index dea7859178..680da2d331 100644 --- a/examples/triple-query/src/api.ts +++ b/examples/triple-query/src/api.ts @@ -1,9 +1,12 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { IView, ViewTransform } from "@thi.ng/atom/api"; -import { EffectDef, EventDef, InterceptorContext } from "@thi.ng/interceptors/api"; -import { EventBus } from "@thi.ng/interceptors/event-bus"; -import { QuerySpec } from "@thi.ng/rstream-query/api"; -import { TripleStore } from "@thi.ng/rstream-query/store"; +import { IObjectOf } from "@thi.ng/api"; +import { IView, ViewTransform } from "@thi.ng/atom"; +import { + EffectDef, + EventBus, + EventDef, + InterceptorContext +} from "@thi.ng/interceptors"; +import { QuerySpec, TripleStore } from "@thi.ng/rstream-query"; /** * Function signature for main app components. diff --git a/examples/triple-query/src/app.ts b/examples/triple-query/src/app.ts index 06a9aba1e5..0da6769183 100644 --- a/examples/triple-query/src/app.ts +++ b/examples/triple-query/src/app.ts @@ -1,11 +1,9 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { Atom } from "@thi.ng/atom/atom"; -import { isArray } from "@thi.ng/checks/is-array"; -import { start } from "@thi.ng/hdom/start"; -import { EV_SET_VALUE } from "@thi.ng/interceptors/api"; -import { EventBus } from "@thi.ng/interceptors/event-bus"; -import { TripleStore } from "@thi.ng/rstream-query/store"; - +import { IObjectOf } from "@thi.ng/api"; +import { Atom } from "@thi.ng/atom"; +import { isArray } from "@thi.ng/checks"; +import { start } from "@thi.ng/hdom"; +import { EV_SET_VALUE, EventBus } from "@thi.ng/interceptors"; +import { TripleStore } from "@thi.ng/rstream-query"; import { AppConfig, AppContext, @@ -14,6 +12,7 @@ import { } from "./api"; import * as ev from "./events"; + /** * Generic base app skeleton. You can use this as basis for your own * apps. diff --git a/examples/triple-query/src/components/event-link.ts b/examples/triple-query/src/components/event-link.ts index fce1ca8aa7..721bf6dd5d 100644 --- a/examples/triple-query/src/components/event-link.ts +++ b/examples/triple-query/src/components/event-link.ts @@ -1,4 +1,4 @@ -import { Event } from "@thi.ng/interceptors/api"; +import { Event } from "@thi.ng/interceptors"; import { AppContext } from "../api"; diff --git a/examples/triple-query/src/components/query-results.ts b/examples/triple-query/src/components/query-results.ts index c9dcfffc32..917e8b5c44 100644 --- a/examples/triple-query/src/components/query-results.ts +++ b/examples/triple-query/src/components/query-results.ts @@ -1,7 +1,4 @@ -import { repeat } from "@thi.ng/transducers/iter/repeat"; -import { map } from "@thi.ng/transducers/xform/map"; -import { mapIndexed } from "@thi.ng/transducers/xform/map-indexed"; - +import { map, mapIndexed, repeat } from "@thi.ng/transducers"; import { AppContext } from "../api"; import { section } from "./section"; import { table } from "./table"; diff --git a/examples/triple-query/src/components/section.ts b/examples/triple-query/src/components/section.ts index da0e102d10..9f73b69c37 100644 --- a/examples/triple-query/src/components/section.ts +++ b/examples/triple-query/src/components/section.ts @@ -1,4 +1,4 @@ -import { title } from "@thi.ng/hdom-components/title"; +import { title } from "@thi.ng/hdom-components"; const h1 = title({ subAttribs: { class: "moon-gray" } }); diff --git a/examples/triple-query/src/components/table.ts b/examples/triple-query/src/components/table.ts index d76fcd6b4b..0159f3c109 100644 --- a/examples/triple-query/src/components/table.ts +++ b/examples/triple-query/src/components/table.ts @@ -1,4 +1,4 @@ -import { map } from "@thi.ng/transducers/xform/map"; +import { map } from "@thi.ng/transducers"; import { AppContext } from "../api"; diff --git a/examples/triple-query/src/components/triple-table.ts b/examples/triple-query/src/components/triple-table.ts index c3f1ab3ad0..d830e09133 100644 --- a/examples/triple-query/src/components/triple-table.ts +++ b/examples/triple-query/src/components/triple-table.ts @@ -1,4 +1,4 @@ -import { pager } from "@thi.ng/hdom-components/pager"; +import { pager } from "@thi.ng/hdom-components"; import { AppContext } from "../api"; import { SET_PAGE, SET_SORT } from "../events"; diff --git a/examples/triple-query/src/handlers.ts b/examples/triple-query/src/handlers.ts index 769f3b5633..3c983e8dec 100644 --- a/examples/triple-query/src/handlers.ts +++ b/examples/triple-query/src/handlers.ts @@ -1,17 +1,23 @@ -import { IObjectOf } from "@thi.ng/api/api"; +import { IObjectOf } from "@thi.ng/api"; import { compare } from "@thi.ng/compare"; -import { FX_DISPATCH_NOW, FX_STATE } from "@thi.ng/interceptors/api"; -import { EffectDef, EventDef } from "@thi.ng/interceptors/api"; -import { dispatchNow, valueSetter } from "@thi.ng/interceptors/interceptors"; +import { + dispatchNow, + EffectDef, + EventDef, + FX_DISPATCH_NOW, + FX_STATE, + valueSetter +} from "@thi.ng/interceptors"; import { getIn, setIn } from "@thi.ng/paths"; -import { Triple } from "@thi.ng/rstream-query/api"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { repeat } from "@thi.ng/transducers/iter/repeat"; -import { iterator } from "@thi.ng/transducers/iterator"; -import { mapIndexed } from "@thi.ng/transducers/xform/map-indexed"; -import { padLast } from "@thi.ng/transducers/xform/pad-last"; -import { page } from "@thi.ng/transducers/xform/page"; - +import { Triple } from "@thi.ng/rstream-query"; +import { + comp, + iterator, + mapIndexed, + padLast, + page, + repeat +} from "@thi.ng/transducers"; import { AppInterceptorContext } from "./api"; import * as fx from "./effects"; import * as ev from "./events"; diff --git a/examples/triple-query/src/index.ts b/examples/triple-query/src/index.ts index 3031006634..408b3861c3 100644 --- a/examples/triple-query/src/index.ts +++ b/examples/triple-query/src/index.ts @@ -8,5 +8,3 @@ if (process.env.NODE_ENV == "development") { } else { new App(CONFIG).start(); } - -window["equiv"] = require("@thi.ng/equiv").equiv; \ No newline at end of file diff --git a/examples/triple-query/tsconfig.json b/examples/triple-query/tsconfig.json index 13b7ae5211..50a1cade93 100644 --- a/examples/triple-query/tsconfig.json +++ b/examples/triple-query/tsconfig.json @@ -2,9 +2,9 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", - "sourceMap": true, - "noUnusedLocals": false + "sourceMap": true }, "include": [ "./src/**/*.ts" diff --git a/examples/webgl/src/index.ts b/examples/webgl/src/index.ts index 3899b07843..602d5043fc 100644 --- a/examples/webgl/src/index.ts +++ b/examples/webgl/src/index.ts @@ -1,6 +1,6 @@ import { start } from "@thi.ng/hdom"; -import { canvasWebGL } from "@thi.ng/hdom-components/canvas"; -import { repeatedly } from "@thi.ng/transducers/iter/repeatedly"; +import { canvasWebGL } from "@thi.ng/hdom-components"; +import { repeatedly } from "@thi.ng/transducers"; // canvas init hook const initGL = (_: HTMLCanvasElement, __: WebGLRenderingContext) => { diff --git a/examples/webgl/tsconfig.json b/examples/webgl/tsconfig.json index 98e83903d2..21c832b5d7 100644 --- a/examples/webgl/tsconfig.json +++ b/examples/webgl/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true, "noUnusedLocals": false, diff --git a/examples/xml-converter/package.json b/examples/xml-converter/package.json index a41d418575..323f3b0e5a 100644 --- a/examples/xml-converter/package.json +++ b/examples/xml-converter/package.json @@ -16,9 +16,12 @@ "typescript": "^3.2.2" }, "dependencies": { + "@thi.ng/checks": "latest", + "@thi.ng/defmulti": "latest", "@thi.ng/rstream": "latest", "@thi.ng/sax": "latest", "@thi.ng/strings": "latest", + "@thi.ng/transducers": "latest", "@thi.ng/transducers-hdom": "latest", "commander": "^2.18.0" }, diff --git a/examples/xml-converter/src/convert.ts b/examples/xml-converter/src/convert.ts index 08bf73e1ff..347adc560f 100644 --- a/examples/xml-converter/src/convert.ts +++ b/examples/xml-converter/src/convert.ts @@ -1,18 +1,20 @@ -import { isString } from "@thi.ng/checks/is-string"; +import { isString } from "@thi.ng/checks"; import { parse, ParseElement, ParseEvent, Type } from "@thi.ng/sax"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { pairs } from "@thi.ng/transducers/iter/pairs"; -import { assocObj } from "@thi.ng/transducers/rfn/assoc-obj"; -import { last } from "@thi.ng/transducers/rfn/last"; -import { push } from "@thi.ng/transducers/rfn/push"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { filter } from "@thi.ng/transducers/xform/filter"; -import { map } from "@thi.ng/transducers/xform/map"; +import { + assocObj, + comp, + filter, + last, + map, + pairs, + push, + transduce +} from "@thi.ng/transducers"; import { DEFAULT_FORMAT, format, FormatOpts } from "./format"; export interface ConversionOpts { diff --git a/examples/xml-converter/src/format.ts b/examples/xml-converter/src/format.ts index db99cc652c..a8af1729dc 100644 --- a/examples/xml-converter/src/format.ts +++ b/examples/xml-converter/src/format.ts @@ -1,10 +1,12 @@ -import { isArray } from "@thi.ng/checks/is-array"; -import { isBoolean } from "@thi.ng/checks/is-boolean"; -import { isNumber } from "@thi.ng/checks/is-number"; -import { isPlainObject } from "@thi.ng/checks/is-plain-object"; +import { + isArray, + isBoolean, + isNumber, + isPlainObject +} from "@thi.ng/checks"; import { DEFAULT, defmulti } from "@thi.ng/defmulti"; -import { repeat } from "@thi.ng/strings/repeat"; -import { peek } from "@thi.ng/transducers/func/peek"; +import { repeat } from "@thi.ng/strings"; +import { peek } from "@thi.ng/transducers"; export interface FormatOpts { indent: number; diff --git a/examples/xml-converter/src/index.ts b/examples/xml-converter/src/index.ts index 402b9c11ef..cac40e5857 100644 --- a/examples/xml-converter/src/index.ts +++ b/examples/xml-converter/src/index.ts @@ -1,8 +1,6 @@ -import { stream } from "@thi.ng/rstream/stream"; -import { sync } from "@thi.ng/rstream/stream-sync"; +import { stream, sync } from "@thi.ng/rstream"; +import { map } from "@thi.ng/transducers"; import { updateDOM } from "@thi.ng/transducers-hdom"; -import { map } from "@thi.ng/transducers/xform/map"; - import { convertXML } from "./convert"; import { COMPACT_FORMAT, DEFAULT_FORMAT } from "./format"; import { app, UI } from "./ui"; diff --git a/examples/xml-converter/src/ui.ts b/examples/xml-converter/src/ui.ts index 738453d71d..1425e1aa41 100644 --- a/examples/xml-converter/src/ui.ts +++ b/examples/xml-converter/src/ui.ts @@ -1,4 +1,4 @@ -import { mapIndexed } from "@thi.ng/transducers/xform/map-indexed"; +import { mapIndexed } from "@thi.ng/transducers"; import { handleTab } from "./utils"; // converted from: diff --git a/examples/xml-converter/src/utils.ts b/examples/xml-converter/src/utils.ts index ecb05108a1..0cfd9a1838 100644 --- a/examples/xml-converter/src/utils.ts +++ b/examples/xml-converter/src/utils.ts @@ -1,26 +1,29 @@ -import { splice } from "@thi.ng/strings/splice"; -import { map } from "@thi.ng/transducers/xform/map"; +import { splice } from "@thi.ng/strings"; +import { map } from "@thi.ng/transducers"; -export const asSet = (x: string) => - new Set(map((x) => x.trim(), x.split(","))); +export const asSet = + (x: string) => + new Set(map((x) => x.trim(), x.split(","))); // helper transducer to convert a CSV string into an ES6 Set export const xformAsSet = map(asSet); // key event handler for textareas to override Tab key behavior and // insert spaces at cursor position instead of changing keyboard focus -export const handleTab = (stream) => - (e: KeyboardEvent) => { - // override tab to insert spaces at edit pos - if (e.key === "Tab") { - e.preventDefault(); - stream.next( - splice((e.target).value, " ", - (e.target).selectionStart - ) - ); - } - }; +export const handleTab = + (stream) => + (e: KeyboardEvent) => { + // override tab to insert spaces at edit pos + if (e.key === "Tab") { + e.preventDefault(); + stream.next( + splice((e.target).value, " ", + (e.target).selectionStart + ) + ); + } + }; -export const varName = (name: string) => - name.replace(/\-+/g, "_"); +export const varName = + (name: string) => + name.replace(/\-+/g, "_"); diff --git a/examples/xml-converter/tsconfig.json b/examples/xml-converter/tsconfig.json index bbf112cc18..50a1cade93 100644 --- a/examples/xml-converter/tsconfig.json +++ b/examples/xml-converter/tsconfig.json @@ -2,10 +2,11 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6", "sourceMap": true }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file From 3f1b79de546e1f8066f1275f65ed941460704796 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 8 Jan 2019 14:53:13 +0000 Subject: [PATCH 225/333] build: update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 176e6402e9..a6a89679d2 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,5 @@ bundle.* *.d.ts *.bak* *.zip +*.map /.gtm/ From d2d7952e5ba9eb479fcfd87d080fd1d10488a47f Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 8 Jan 2019 16:02:12 +0000 Subject: [PATCH 226/333] minor: update imports in readme's / examples --- examples/hdom-canvas-shapes/src/index.ts | 1 - examples/markdown/README.md | 2 +- examples/svg-waveform/src/config.ts | 2 +- packages/geom/src/subdiv-curve.ts | 2 +- packages/hdom-canvas/README.md | 2 +- packages/hdom-components/adr/0002-component-configuration.md | 2 +- packages/hdom/README.md | 2 +- packages/hiccup-carbon-icons/README.md | 2 +- packages/hiccup-markdown/README.md | 4 ++-- 9 files changed, 9 insertions(+), 10 deletions(-) diff --git a/examples/hdom-canvas-shapes/src/index.ts b/examples/hdom-canvas-shapes/src/index.ts index eef9840ad8..b6230c1041 100644 --- a/examples/hdom-canvas-shapes/src/index.ts +++ b/examples/hdom-canvas-shapes/src/index.ts @@ -6,7 +6,6 @@ import { fromRAF, stream, sync } from "@thi.ng/rstream"; import { map, range, repeatedly } from "@thi.ng/transducers"; import { updateDOM } from "@thi.ng/transducers-hdom"; import { Mat23 } from "@thi.ng/vectors"; -// import { canvas2D, adaptDPI } from "@thi.ng/hdom-components/canvas"; // for testing SVG conversion import { download } from "./download"; diff --git a/examples/markdown/README.md b/examples/markdown/README.md index afacc8854f..96e33d046e 100644 --- a/examples/markdown/README.md +++ b/examples/markdown/README.md @@ -83,7 +83,7 @@ for reference... import { iterator } from "@thi.ng/transducers"; import { serialize } from "@thi.ng/hiccup"; -import { parse } from "@thi.ng/hiccup-markdown/parse"; +import { parse } from "@thi.ng/hiccup-markdown"; const src = ` # Hello world diff --git a/examples/svg-waveform/src/config.ts b/examples/svg-waveform/src/config.ts index 3ddd2aa651..63454bf03e 100644 --- a/examples/svg-waveform/src/config.ts +++ b/examples/svg-waveform/src/config.ts @@ -1,4 +1,4 @@ -import { ensureParamRange, snapshot, valueSetter } from "@thi.ng/interceptors/interceptors" +import { ensureParamRange, snapshot, valueSetter } from "@thi.ng/interceptors" import { AppConfig } from "./api"; // import * as ev from "./events"; // import * as fx from "./effects"; diff --git a/packages/geom/src/subdiv-curve.ts b/packages/geom/src/subdiv-curve.ts index 56300fef80..4b8c36edc9 100644 --- a/packages/geom/src/subdiv-curve.ts +++ b/packages/geom/src/subdiv-curve.ts @@ -7,7 +7,7 @@ import { transduce, wrap } from "@thi.ng/transducers"; -import { IVector } from "@thi.ng/vectors/api"; +import { IVector } from "@thi.ng/vectors"; import { SubdivKernel } from "./api"; const madd2 = diff --git a/packages/hdom-canvas/README.md b/packages/hdom-canvas/README.md index f52ab7b9fe..fdc8a39d57 100644 --- a/packages/hdom-canvas/README.md +++ b/packages/hdom-canvas/README.md @@ -172,7 +172,7 @@ first be normalized (if not already) using hdom-canvas' `normalizeTree()`. ```ts -import { serialize } from "@thi.ng/hiccup/serialize"; +import { serialize } from "@thi.ng/hiccup"; import { convertTree, svg } from "@thi.ng/hiccup-svg"; import { normalizeTree } from "@thi.ng/hdom-canvas"; diff --git a/packages/hdom-components/adr/0002-component-configuration.md b/packages/hdom-components/adr/0002-component-configuration.md index a68e2c4ca6..34cd9e4630 100644 --- a/packages/hdom-components/adr/0002-component-configuration.md +++ b/packages/hdom-components/adr/0002-component-configuration.md @@ -86,7 +86,7 @@ component](../src/button.ts). ```ts // button.ts -import { IObjectOf } from "@thi.ng/api/api"; +import { IObjectOf } from "@thi.ng/api"; export interface ButtonOpts { /** diff --git a/packages/hdom/README.md b/packages/hdom/README.md index 9eed05fdf8..c5f73505c9 100644 --- a/packages/hdom/README.md +++ b/packages/hdom/README.md @@ -150,7 +150,7 @@ diffing via RAF). [standalone example](https://github.com/thi-ng/umbrella/tree/master/examples/transducers-hdom) ```ts -import { fromInterval, stream, sync } from "@thi.ng/rstream/stream"; +import { fromInterval, stream, sync } from "@thi.ng/rstream"; import { updateDOM } from "@thi.ng/rstream/transducers-hdom"; import * as tx from "@thi.ng/rstream/transducers"; diff --git a/packages/hiccup-carbon-icons/README.md b/packages/hiccup-carbon-icons/README.md index 2fd951f55e..036e5d5455 100644 --- a/packages/hiccup-carbon-icons/README.md +++ b/packages/hiccup-carbon-icons/README.md @@ -53,7 +53,7 @@ None. ```ts import { renderOnce } from "@thi.ng/hdom"; -import { CODE } from "@thi.ng/hiccup-carbon-icons/code"; +import { CODE } from "@thi.ng/hiccup-carbon-icons"; // using tachyons css classes for brevity const iconButton = (icon, onclick, label?) => diff --git a/packages/hiccup-markdown/README.md b/packages/hiccup-markdown/README.md index bb1677163b..dd5328cde5 100644 --- a/packages/hiccup-markdown/README.md +++ b/packages/hiccup-markdown/README.md @@ -113,7 +113,7 @@ requests are welcome, though! import { iterator } from "@thi.ng/transducers"; import { serialize } from "@thi.ng/hiccup"; -import { parse } from "@thi.ng/hiccup-markdown/parse"; +import { parse } from "@thi.ng/hiccup-markdown"; const src = ` # Hello world @@ -225,7 +225,7 @@ See source code for reference. ### Usage examples ```ts -import { serialize } from "@thi.ng/hiccup-markdown/serialize"; +import { serialize } from "@thi.ng/hiccup-markdown"; // list component // the 1st arg is the optional user context object From 1618c136eef158046355e9dd04559675365ff50c Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 9 Jan 2019 00:37:42 +0000 Subject: [PATCH 227/333] build(examples): enable scope hoisting in `yarn build` scripts --- examples/async-effect/package.json | 2 +- examples/canvas-dial/package.json | 2 +- examples/cellular-automata/package.json | 2 +- examples/commit-table-ssr/package.json | 2 +- examples/crypto-chart/package.json | 3 +-- examples/dashboard/package.json | 2 +- examples/devcards/package.json | 2 +- examples/geom-knn/package.json | 2 +- examples/geom-tessel/package.json | 2 +- examples/gesture-analysis/package.json | 2 +- examples/hdom-basics/package.json | 2 +- examples/hdom-benchmark/package.json | 2 +- examples/hdom-benchmark2/package.json | 2 +- examples/hdom-canvas-clock/package.json | 2 +- examples/hdom-canvas-draw/package.json | 2 +- examples/hdom-canvas-shapes/package.json | 2 +- examples/hdom-dropdown-fuzzy/package.json | 2 +- examples/hdom-dropdown/package.json | 2 +- examples/hdom-dyn-context/package.json | 2 +- examples/hdom-skip/package.json | 2 +- examples/hdom-theme-adr-0003/package.json | 2 +- examples/hmr-basics/package.json | 2 +- examples/hydrate-basics/package.json | 2 +- examples/interceptor-basics/package.json | 2 +- examples/interceptor-basics2/package.json | 2 +- examples/json-components/package.json | 2 +- examples/login-form/package.json | 2 +- examples/mandelbrot/package.json | 4 ++-- examples/markdown/package.json | 4 ++-- examples/router-basics/package.json | 2 +- examples/rstream-dataflow/package.json | 2 +- examples/rstream-grid/package.json | 2 +- examples/rstream-hdom/package.json | 2 +- examples/svg-barchart/package.json | 2 +- examples/svg-particles/package.json | 2 +- examples/svg-waveform/package.json | 2 +- examples/talk-slides/package.json | 2 +- examples/todo-list/package.json | 2 +- examples/transducers-hdom/package.json | 2 +- examples/triple-query/package.json | 2 +- examples/webgl/package.json | 2 +- examples/xml-converter/package.json | 2 +- 42 files changed, 44 insertions(+), 45 deletions(-) diff --git a/examples/async-effect/package.json b/examples/async-effect/package.json index e35216328e..b130613041 100644 --- a/examples/async-effect/package.json +++ b/examples/async-effect/package.json @@ -7,7 +7,7 @@ "scripts": { "clean": "rm -rf .cache build out", "prep": "yarn clean && mkdir -p out && cp foo.json out", - "build": "yarn prep && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn prep && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "yarn prep && parcel index.html -p 8080 --open -d out" }, "devDependencies": { diff --git a/examples/canvas-dial/package.json b/examples/canvas-dial/package.json index f598c7cbd4..87729f7f3c 100644 --- a/examples/canvas-dial/package.json +++ b/examples/canvas-dial/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/cellular-automata/package.json b/examples/cellular-automata/package.json index ada4f510cb..bbff746c27 100644 --- a/examples/cellular-automata/package.json +++ b/examples/cellular-automata/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/commit-table-ssr/package.json b/examples/commit-table-ssr/package.json index 4290c33267..a01f0c1209 100644 --- a/examples/commit-table-ssr/package.json +++ b/examples/commit-table-ssr/package.json @@ -8,7 +8,7 @@ "clean": "rm -rf .cache build out", "prep": "yarn clean && mkdir -p out && cp commits.json out", "build-static": "tsc && node build/server/static.js", - "build": "yarn prep && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn prep && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "tsc && node build/server/index.js" }, "devDependencies": { diff --git a/examples/crypto-chart/package.json b/examples/crypto-chart/package.json index a88f34743f..271b0f4832 100644 --- a/examples/crypto-chart/package.json +++ b/examples/crypto-chart/package.json @@ -29,6 +29,5 @@ ], "browser": { "process": false - }, - "sideEffects": false + } } \ No newline at end of file diff --git a/examples/dashboard/package.json b/examples/dashboard/package.json index 8dd96ed989..02bbef4ae1 100644 --- a/examples/dashboard/package.json +++ b/examples/dashboard/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/devcards/package.json b/examples/devcards/package.json index 1b56495ea9..561e345f86 100644 --- a/examples/devcards/package.json +++ b/examples/devcards/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/geom-knn/package.json b/examples/geom-knn/package.json index 6beffe1a45..68bca47bce 100644 --- a/examples/geom-knn/package.json +++ b/examples/geom-knn/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --detailed-report", + "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/geom-tessel/package.json b/examples/geom-tessel/package.json index c20cf9d683..4bee38930c 100644 --- a/examples/geom-tessel/package.json +++ b/examples/geom-tessel/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --detailed-report", + "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/gesture-analysis/package.json b/examples/gesture-analysis/package.json index 3ed3783c76..06e3e85405 100644 --- a/examples/gesture-analysis/package.json +++ b/examples/gesture-analysis/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/hdom-basics/package.json b/examples/hdom-basics/package.json index 0f8e338544..dc876dd0d3 100644 --- a/examples/hdom-basics/package.json +++ b/examples/hdom-basics/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/hdom-benchmark/package.json b/examples/hdom-benchmark/package.json index e12d401996..484e7f312c 100644 --- a/examples/hdom-benchmark/package.json +++ b/examples/hdom-benchmark/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/hdom-benchmark2/package.json b/examples/hdom-benchmark2/package.json index a026e49776..d2d9806b9d 100644 --- a/examples/hdom-benchmark2/package.json +++ b/examples/hdom-benchmark2/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --detailed-report", + "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/hdom-canvas-clock/package.json b/examples/hdom-canvas-clock/package.json index 809c5cfa2f..1e9ac18913 100644 --- a/examples/hdom-canvas-clock/package.json +++ b/examples/hdom-canvas-clock/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/hdom-canvas-draw/package.json b/examples/hdom-canvas-draw/package.json index 72cae997cf..c4da36655c 100644 --- a/examples/hdom-canvas-draw/package.json +++ b/examples/hdom-canvas-draw/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/hdom-canvas-shapes/package.json b/examples/hdom-canvas-shapes/package.json index 3136accd4a..f128d47906 100644 --- a/examples/hdom-canvas-shapes/package.json +++ b/examples/hdom-canvas-shapes/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open --no-cache" }, "devDependencies": { diff --git a/examples/hdom-dropdown-fuzzy/package.json b/examples/hdom-dropdown-fuzzy/package.json index 5069d6c296..00924c8105 100644 --- a/examples/hdom-dropdown-fuzzy/package.json +++ b/examples/hdom-dropdown-fuzzy/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/hdom-dropdown/package.json b/examples/hdom-dropdown/package.json index b0ce985271..7cc450c642 100644 --- a/examples/hdom-dropdown/package.json +++ b/examples/hdom-dropdown/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/hdom-dyn-context/package.json b/examples/hdom-dyn-context/package.json index 4d26dd4252..72bcbbbcab 100644 --- a/examples/hdom-dyn-context/package.json +++ b/examples/hdom-dyn-context/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --detailed-report", + "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/hdom-skip/package.json b/examples/hdom-skip/package.json index 9f3e5c79be..b597f024a5 100644 --- a/examples/hdom-skip/package.json +++ b/examples/hdom-skip/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --detailed-report", + "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/hdom-theme-adr-0003/package.json b/examples/hdom-theme-adr-0003/package.json index f4456da1f3..fb63f21faf 100644 --- a/examples/hdom-theme-adr-0003/package.json +++ b/examples/hdom-theme-adr-0003/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/hmr-basics/package.json b/examples/hmr-basics/package.json index af7b321481..552cc82391 100644 --- a/examples/hmr-basics/package.json +++ b/examples/hmr-basics/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/hydrate-basics/package.json b/examples/hydrate-basics/package.json index 388068ec87..5f5d5a2109 100644 --- a/examples/hydrate-basics/package.json +++ b/examples/hydrate-basics/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/interceptor-basics/package.json b/examples/interceptor-basics/package.json index a1f1e3b142..d90b3fcec4 100644 --- a/examples/interceptor-basics/package.json +++ b/examples/interceptor-basics/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/interceptor-basics2/package.json b/examples/interceptor-basics2/package.json index 276de1102b..e8a8c6dbaf 100644 --- a/examples/interceptor-basics2/package.json +++ b/examples/interceptor-basics2/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/json-components/package.json b/examples/json-components/package.json index a961527c47..4fdb499e6c 100644 --- a/examples/json-components/package.json +++ b/examples/json-components/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/login-form/package.json b/examples/login-form/package.json index 86f41ad8e0..d1dc3144ef 100644 --- a/examples/login-form/package.json +++ b/examples/login-form/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/mandelbrot/package.json b/examples/mandelbrot/package.json index dc8873a6aa..1f6eed6729 100644 --- a/examples/mandelbrot/package.json +++ b/examples/mandelbrot/package.json @@ -6,8 +6,8 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && yarn build:worker && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --detailed-report", - "build:worker": "parcel build src/worker.ts -d out --no-source-maps --no-cache --detailed-report --experimental-scope-hoisting", + "build": "yarn clean && yarn build:worker && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report", + "build:worker": "parcel build src/worker.ts -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --experimental-scope-hoisting", "start": "yarn build:worker && parcel index.html -d out -p 8080 --open" }, "devDependencies": { diff --git a/examples/markdown/package.json b/examples/markdown/package.json index af2950e06d..dc9fe49fd8 100644 --- a/examples/markdown/package.json +++ b/examples/markdown/package.json @@ -6,8 +6,8 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --detailed-report", - "build-parser": "yarn clean && parcel build src/parser.ts -d out --global md --public-url ./ --no-source-maps --no-cache --detailed-report --experimental-scope-hoisting", + "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report", + "build-parser": "yarn clean && parcel build src/parser.ts -d out --global md --public-url ./ --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --experimental-scope-hoisting", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/router-basics/package.json b/examples/router-basics/package.json index 311f284a49..7bf4be69e3 100644 --- a/examples/router-basics/package.json +++ b/examples/router-basics/package.json @@ -8,7 +8,7 @@ "scripts": { "clean": "rm -rf .cache build out", "prep": "yarn clean && mkdir -p out && cp -R assets out", - "build": "yarn prep && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn prep && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "yarn prep && parcel index.html -p 8080 --open -d out" }, "dependencies": { diff --git a/examples/rstream-dataflow/package.json b/examples/rstream-dataflow/package.json index 1726205766..0bd167f6a4 100644 --- a/examples/rstream-dataflow/package.json +++ b/examples/rstream-dataflow/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/rstream-grid/package.json b/examples/rstream-grid/package.json index 6731751d1c..375573a200 100644 --- a/examples/rstream-grid/package.json +++ b/examples/rstream-grid/package.json @@ -7,7 +7,7 @@ "license": "MIT", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "dependencies": { diff --git a/examples/rstream-hdom/package.json b/examples/rstream-hdom/package.json index ea7787e69a..2876fa7648 100644 --- a/examples/rstream-hdom/package.json +++ b/examples/rstream-hdom/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/svg-barchart/package.json b/examples/svg-barchart/package.json index 6604191c11..d2a663d0bd 100644 --- a/examples/svg-barchart/package.json +++ b/examples/svg-barchart/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --detailed-report", + "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/svg-particles/package.json b/examples/svg-particles/package.json index 1bedef4aed..42d070539d 100644 --- a/examples/svg-particles/package.json +++ b/examples/svg-particles/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/svg-waveform/package.json b/examples/svg-waveform/package.json index 0f998b01b7..58e8e6e115 100644 --- a/examples/svg-waveform/package.json +++ b/examples/svg-waveform/package.json @@ -7,7 +7,7 @@ "license": "MIT", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "dependencies": { diff --git a/examples/talk-slides/package.json b/examples/talk-slides/package.json index 77e4271c95..3b32d124de 100644 --- a/examples/talk-slides/package.json +++ b/examples/talk-slides/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --detailed-report", + "build": "parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/todo-list/package.json b/examples/todo-list/package.json index e9d8ab7bdc..f9232d952d 100644 --- a/examples/todo-list/package.json +++ b/examples/todo-list/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/transducers-hdom/package.json b/examples/transducers-hdom/package.json index 0529941d81..9a4ea7df2a 100644 --- a/examples/transducers-hdom/package.json +++ b/examples/transducers-hdom/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/triple-query/package.json b/examples/triple-query/package.json index 7c8d25302f..a3c4d323cb 100644 --- a/examples/triple-query/package.json +++ b/examples/triple-query/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/webgl/package.json b/examples/webgl/package.json index 66b19bdd5e..e612fbe6a2 100644 --- a/examples/webgl/package.json +++ b/examples/webgl/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./", + "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report --public-url ./", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { diff --git a/examples/xml-converter/package.json b/examples/xml-converter/package.json index 323f3b0e5a..dcb44b865d 100644 --- a/examples/xml-converter/package.json +++ b/examples/xml-converter/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "scripts": { "clean": "rm -rf .cache build out", - "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --detailed-report", + "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --experimental-scope-hoisting --detailed-report", "build-cli": "tsc -p tsconfig-cli.json", "start": "parcel index.html -p 8080 --open" }, From 4e28b5a6afb1c876e35ca209a473713dc563f5e8 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 9 Jan 2019 00:41:13 +0000 Subject: [PATCH 228/333] build(examples): update dev deps --- examples/async-effect/package.json | 4 ++-- examples/canvas-dial/package.json | 4 ++-- examples/cellular-automata/package.json | 4 ++-- examples/commit-table-ssr/package.json | 4 ++-- examples/crypto-chart/package.json | 4 ++-- examples/dashboard/package.json | 4 ++-- examples/devcards/package.json | 4 ++-- examples/geom-knn/package.json | 4 ++-- examples/geom-tessel/package.json | 4 ++-- examples/gesture-analysis/package.json | 4 ++-- examples/hdom-basics/package.json | 4 ++-- examples/hdom-benchmark/package.json | 4 ++-- examples/hdom-benchmark2/package.json | 4 ++-- examples/hdom-canvas-clock/package.json | 4 ++-- examples/hdom-canvas-draw/package.json | 4 ++-- examples/hdom-canvas-shapes/package.json | 4 ++-- examples/hdom-dropdown-fuzzy/package.json | 4 ++-- examples/hdom-dropdown/package.json | 4 ++-- examples/hdom-dyn-context/package.json | 4 ++-- examples/hdom-skip/package.json | 4 ++-- examples/hdom-theme-adr-0003/package.json | 4 ++-- examples/hmr-basics/package.json | 4 ++-- examples/hydrate-basics/package.json | 4 ++-- examples/interceptor-basics/package.json | 4 ++-- examples/interceptor-basics2/package.json | 4 ++-- examples/json-components/package.json | 4 ++-- examples/login-form/package.json | 4 ++-- examples/mandelbrot/package.json | 4 ++-- examples/markdown/package.json | 4 ++-- examples/router-basics/package.json | 4 ++-- examples/rstream-dataflow/package.json | 4 ++-- examples/rstream-grid/package.json | 4 ++-- examples/rstream-hdom/package.json | 4 ++-- examples/svg-barchart/package.json | 4 ++-- examples/svg-particles/package.json | 4 ++-- examples/svg-waveform/package.json | 4 ++-- examples/talk-slides/package.json | 4 ++-- examples/todo-list/package.json | 4 ++-- examples/transducers-hdom/package.json | 4 ++-- examples/triple-query/package.json | 4 ++-- examples/webgl/package.json | 4 ++-- examples/xml-converter/package.json | 4 ++-- 42 files changed, 84 insertions(+), 84 deletions(-) diff --git a/examples/async-effect/package.json b/examples/async-effect/package.json index b130613041..76c3a31231 100644 --- a/examples/async-effect/package.json +++ b/examples/async-effect/package.json @@ -11,8 +11,8 @@ "start": "yarn prep && parcel index.html -p 8080 --open -d out" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/canvas-dial/package.json b/examples/canvas-dial/package.json index 87729f7f3c..6fe997818c 100644 --- a/examples/canvas-dial/package.json +++ b/examples/canvas-dial/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/cellular-automata/package.json b/examples/cellular-automata/package.json index bbff746c27..2949a9e5ca 100644 --- a/examples/cellular-automata/package.json +++ b/examples/cellular-automata/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/commit-table-ssr/package.json b/examples/commit-table-ssr/package.json index a01f0c1209..07fae2ab2e 100644 --- a/examples/commit-table-ssr/package.json +++ b/examples/commit-table-ssr/package.json @@ -12,8 +12,8 @@ "start": "tsc && node build/server/index.js" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/crypto-chart/package.json b/examples/crypto-chart/package.json index 271b0f4832..0cacc2d8cc 100644 --- a/examples/crypto-chart/package.json +++ b/examples/crypto-chart/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/dashboard/package.json b/examples/dashboard/package.json index 02bbef4ae1..30bb565e92 100644 --- a/examples/dashboard/package.json +++ b/examples/dashboard/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/devcards/package.json b/examples/devcards/package.json index 561e345f86..515ed8e2c5 100644 --- a/examples/devcards/package.json +++ b/examples/devcards/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/geom-knn/package.json b/examples/geom-knn/package.json index 68bca47bce..ac4ce070a9 100644 --- a/examples/geom-knn/package.json +++ b/examples/geom-knn/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/geom-tessel/package.json b/examples/geom-tessel/package.json index 4bee38930c..b6a007b4cd 100644 --- a/examples/geom-tessel/package.json +++ b/examples/geom-tessel/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/gesture-analysis/package.json b/examples/gesture-analysis/package.json index 06e3e85405..8c0a4f1ff9 100644 --- a/examples/gesture-analysis/package.json +++ b/examples/gesture-analysis/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/hdom-basics/package.json b/examples/hdom-basics/package.json index dc876dd0d3..5802e501d6 100644 --- a/examples/hdom-basics/package.json +++ b/examples/hdom-basics/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/hdom-benchmark/package.json b/examples/hdom-benchmark/package.json index 484e7f312c..5f64b8531a 100644 --- a/examples/hdom-benchmark/package.json +++ b/examples/hdom-benchmark/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/hdom-benchmark2/package.json b/examples/hdom-benchmark2/package.json index d2d9806b9d..4eee0ca969 100644 --- a/examples/hdom-benchmark2/package.json +++ b/examples/hdom-benchmark2/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/hdom-canvas-clock/package.json b/examples/hdom-canvas-clock/package.json index 1e9ac18913..88d52d89e5 100644 --- a/examples/hdom-canvas-clock/package.json +++ b/examples/hdom-canvas-clock/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/hdom-canvas-draw/package.json b/examples/hdom-canvas-draw/package.json index c4da36655c..1eba6d4fc4 100644 --- a/examples/hdom-canvas-draw/package.json +++ b/examples/hdom-canvas-draw/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/hdom-canvas-shapes/package.json b/examples/hdom-canvas-shapes/package.json index f128d47906..46695975ce 100644 --- a/examples/hdom-canvas-shapes/package.json +++ b/examples/hdom-canvas-shapes/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open --no-cache" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/hdom-dropdown-fuzzy/package.json b/examples/hdom-dropdown-fuzzy/package.json index 00924c8105..a6b31a00c8 100644 --- a/examples/hdom-dropdown-fuzzy/package.json +++ b/examples/hdom-dropdown-fuzzy/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/hdom-dropdown/package.json b/examples/hdom-dropdown/package.json index 7cc450c642..3619b30329 100644 --- a/examples/hdom-dropdown/package.json +++ b/examples/hdom-dropdown/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/hdom-dyn-context/package.json b/examples/hdom-dyn-context/package.json index 72bcbbbcab..dbbba7e2b9 100644 --- a/examples/hdom-dyn-context/package.json +++ b/examples/hdom-dyn-context/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/hdom-skip/package.json b/examples/hdom-skip/package.json index b597f024a5..62e9bd8197 100644 --- a/examples/hdom-skip/package.json +++ b/examples/hdom-skip/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/hdom-theme-adr-0003/package.json b/examples/hdom-theme-adr-0003/package.json index fb63f21faf..d10a5151fc 100644 --- a/examples/hdom-theme-adr-0003/package.json +++ b/examples/hdom-theme-adr-0003/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/hmr-basics/package.json b/examples/hmr-basics/package.json index 552cc82391..9d4eb6fc54 100644 --- a/examples/hmr-basics/package.json +++ b/examples/hmr-basics/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/hydrate-basics/package.json b/examples/hydrate-basics/package.json index 5f5d5a2109..dc21ad11bc 100644 --- a/examples/hydrate-basics/package.json +++ b/examples/hydrate-basics/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/interceptor-basics/package.json b/examples/interceptor-basics/package.json index d90b3fcec4..b209dae0b3 100644 --- a/examples/interceptor-basics/package.json +++ b/examples/interceptor-basics/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/interceptor-basics2/package.json b/examples/interceptor-basics2/package.json index e8a8c6dbaf..da6e654725 100644 --- a/examples/interceptor-basics2/package.json +++ b/examples/interceptor-basics2/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/json-components/package.json b/examples/json-components/package.json index 4fdb499e6c..a8a4a3fd3d 100644 --- a/examples/json-components/package.json +++ b/examples/json-components/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/login-form/package.json b/examples/login-form/package.json index d1dc3144ef..639a3432ce 100644 --- a/examples/login-form/package.json +++ b/examples/login-form/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/mandelbrot/package.json b/examples/mandelbrot/package.json index 1f6eed6729..bea1fc5a6f 100644 --- a/examples/mandelbrot/package.json +++ b/examples/mandelbrot/package.json @@ -11,8 +11,8 @@ "start": "yarn build:worker && parcel index.html -d out -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/markdown/package.json b/examples/markdown/package.json index dc9fe49fd8..9fe5de8778 100644 --- a/examples/markdown/package.json +++ b/examples/markdown/package.json @@ -11,8 +11,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/router-basics/package.json b/examples/router-basics/package.json index 7bf4be69e3..5e69aefe18 100644 --- a/examples/router-basics/package.json +++ b/examples/router-basics/package.json @@ -20,8 +20,8 @@ "@thi.ng/router": "latest" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "browserslist": [ diff --git a/examples/rstream-dataflow/package.json b/examples/rstream-dataflow/package.json index 0bd167f6a4..98ca3abb35 100644 --- a/examples/rstream-dataflow/package.json +++ b/examples/rstream-dataflow/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/rstream-grid/package.json b/examples/rstream-grid/package.json index 375573a200..760a3b0f87 100644 --- a/examples/rstream-grid/package.json +++ b/examples/rstream-grid/package.json @@ -25,8 +25,8 @@ }, "devDependencies": { "@types/node": "^9.6.2", - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "browserslist": [ diff --git a/examples/rstream-hdom/package.json b/examples/rstream-hdom/package.json index 2876fa7648..c78c6361aa 100644 --- a/examples/rstream-hdom/package.json +++ b/examples/rstream-hdom/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/svg-barchart/package.json b/examples/svg-barchart/package.json index d2a663d0bd..961f66b2d1 100644 --- a/examples/svg-barchart/package.json +++ b/examples/svg-barchart/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/svg-particles/package.json b/examples/svg-particles/package.json index 42d070539d..a61e7116ae 100644 --- a/examples/svg-particles/package.json +++ b/examples/svg-particles/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/svg-waveform/package.json b/examples/svg-waveform/package.json index 58e8e6e115..f8add8cb71 100644 --- a/examples/svg-waveform/package.json +++ b/examples/svg-waveform/package.json @@ -21,8 +21,8 @@ }, "devDependencies": { "@types/node": "^9.6.2", - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "browserslist": [ diff --git a/examples/talk-slides/package.json b/examples/talk-slides/package.json index 3b32d124de..eea34b055b 100644 --- a/examples/talk-slides/package.json +++ b/examples/talk-slides/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/todo-list/package.json b/examples/todo-list/package.json index f9232d952d..f9982ad6d3 100644 --- a/examples/todo-list/package.json +++ b/examples/todo-list/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/transducers-hdom/package.json b/examples/transducers-hdom/package.json index 9a4ea7df2a..922591d1db 100644 --- a/examples/transducers-hdom/package.json +++ b/examples/transducers-hdom/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/triple-query/package.json b/examples/triple-query/package.json index a3c4d323cb..8913b5c0b8 100644 --- a/examples/triple-query/package.json +++ b/examples/triple-query/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/webgl/package.json b/examples/webgl/package.json index e612fbe6a2..b77b59b4ad 100644 --- a/examples/webgl/package.json +++ b/examples/webgl/package.json @@ -10,8 +10,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { diff --git a/examples/xml-converter/package.json b/examples/xml-converter/package.json index dcb44b865d..62410ee370 100644 --- a/examples/xml-converter/package.json +++ b/examples/xml-converter/package.json @@ -11,8 +11,8 @@ "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { From 27438f9c75bb8a226e8c0b678415fb73d696236a Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 9 Jan 2019 00:41:50 +0000 Subject: [PATCH 229/333] minor(examples): cleanup --- examples/hdom-basics/src/index.ts | 4 ++-- examples/hdom-canvas-shapes/src/index.ts | 1 - examples/router-basics/src/components/home.ts | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/hdom-basics/src/index.ts b/examples/hdom-basics/src/index.ts index d75a570397..5ff0052bd8 100644 --- a/examples/hdom-basics/src/index.ts +++ b/examples/hdom-basics/src/index.ts @@ -1,4 +1,4 @@ -import * as hdom from "@thi.ng/hdom"; +import { start } from "@thi.ng/hdom"; // stateless component w/ params // the first arg is an auto-injected context object @@ -18,7 +18,7 @@ const app = () => { }; // start update loop (browser only, see diagram below) -hdom.start(app()); +start(app()); // alternatively apply DOM tree only once // (stateful components won't update though) diff --git a/examples/hdom-canvas-shapes/src/index.ts b/examples/hdom-canvas-shapes/src/index.ts index b6230c1041..128afc6cf7 100644 --- a/examples/hdom-canvas-shapes/src/index.ts +++ b/examples/hdom-canvas-shapes/src/index.ts @@ -12,7 +12,6 @@ import { download } from "./download"; // ignore error, resolved by parcel import logo from "../assets/logo-64.png"; -// const logo = "logo-64.63ccb91c.png"; // canvas size const W = 300; diff --git a/examples/router-basics/src/components/home.ts b/examples/router-basics/src/components/home.ts index d04ff6a853..5ce2d56d24 100644 --- a/examples/router-basics/src/components/home.ts +++ b/examples/router-basics/src/components/home.ts @@ -27,6 +27,6 @@ export function home(ctx: AppContext) { ]], ["p", "Please see the related blog post and the commented source code for more details."], - ["p", "(total app file size: 11.8KB)"] + ["p", "(total app file size: 11.2KB)"] ]; } From bac59db62594e9a89145cf40508c8d9367889288 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 10 Jan 2019 12:46:22 +0000 Subject: [PATCH 230/333] feat(examples): add package-stats charting example --- examples/package-stats/.gitignore | 6 ++ examples/package-stats/README.md | 26 ++++++ examples/package-stats/package.json | 32 +++++++ examples/package-stats/src/dep-chart.ts | 91 +++++++++++++++++++ examples/package-stats/src/index.ts | 2 + examples/package-stats/src/size-chart.ts | 81 +++++++++++++++++ examples/package-stats/src/viz.ts | 107 +++++++++++++++++++++++ examples/package-stats/tsconfig.json | 13 +++ 8 files changed, 358 insertions(+) create mode 100644 examples/package-stats/.gitignore create mode 100644 examples/package-stats/README.md create mode 100644 examples/package-stats/package.json create mode 100644 examples/package-stats/src/dep-chart.ts create mode 100644 examples/package-stats/src/index.ts create mode 100644 examples/package-stats/src/size-chart.ts create mode 100644 examples/package-stats/src/viz.ts create mode 100644 examples/package-stats/tsconfig.json diff --git a/examples/package-stats/.gitignore b/examples/package-stats/.gitignore new file mode 100644 index 0000000000..5559447e1d --- /dev/null +++ b/examples/package-stats/.gitignore @@ -0,0 +1,6 @@ +.cache +out +node_modules +yarn.lock +*.js +*.svg diff --git a/examples/package-stats/README.md b/examples/package-stats/README.md new file mode 100644 index 0000000000..283cba90ab --- /dev/null +++ b/examples/package-stats/README.md @@ -0,0 +1,26 @@ +# package-stats + +This non-browser example generates several SVG charts of various package +stats in this mono-repo. The charts will be saved in this example's +directory. + +```bash +git clone https://github.com/thi-ng/umbrella.git + +# first need to build the entire mono-repo +# to produce necessary meta data +yarn install +yarn build + +# then run example +cd umbrella/examples/module-stats +yarn build +``` + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/examples/package-stats/package.json b/examples/package-stats/package.json new file mode 100644 index 0000000000..0ab15e5c0d --- /dev/null +++ b/examples/package-stats/package.json @@ -0,0 +1,32 @@ +{ + "name": "package-stats", + "version": "0.0.1", + "repository": "https://github.com/thi-ng/umbrella", + "author": "Karsten Schmidt ", + "license": "Apache-2.0", + "scripts": { + "clean": "rm -rf *.js *.svg lib", + "build": "yarn clean && tsc && node lib/index.js" + }, + "devDependencies": { + "parcel-bundler": "^1.10.3", + "terser": "^3.11.0", + "typescript": "^3.2.2" + }, + "dependencies": { + "@thi.ng/checks": "latest", + "@thi.ng/dgraph": "latest", + "@thi.ng/hiccup": "latest", + "@thi.ng/hiccup-svg": "latest", + "@thi.ng/math": "latest", + "@thi.ng/path": "latest", + "@thi.ng/strings": "latest", + "@thi.ng/transducers": "latest" + }, + "browserslist": [ + "last 3 Chrome versions" + ], + "browser": { + "process": false + } +} \ No newline at end of file diff --git a/examples/package-stats/src/dep-chart.ts b/examples/package-stats/src/dep-chart.ts new file mode 100644 index 0000000000..a8fc6c4903 --- /dev/null +++ b/examples/package-stats/src/dep-chart.ts @@ -0,0 +1,91 @@ +import { exists } from "@thi.ng/checks"; +import { DGraph } from "@thi.ng/dgraph"; +import { serialize } from "@thi.ng/hiccup"; +import { group, text } from "@thi.ng/hiccup-svg"; +import { + comp, + filter, + map, + mapcat, + mapIndexed, + max, + pluck, + push, + reducer, + repeat, + transduce, + tuples +} from "@thi.ng/transducers"; +import * as fs from "fs"; +import { + barChart, + labeledTickY, + labeledTickX, +} from "./viz"; + +const BASE_DIR = "../../packages/"; + +const packages = transduce( + comp( + map((f) => BASE_DIR + f), + filter((f) => fs.statSync(f).isDirectory()), + map((f) => { try { return fs.readFileSync(f + "/package.json"); } catch (_) { } }), + filter(exists), + map((p) => JSON.parse(p.toString())), + map((p) => ({ + id: p.name, + v: p.version, + deps: p.dependencies ? Object.keys(p.dependencies) : [] + })) + ), + push(), + fs.readdirSync(BASE_DIR) +); + +const graph = transduce( + mapcat((p: any) => tuples(repeat(p.id), p.deps)), + reducer(() => new DGraph(), (g, [p, d]) => g.addDependency(p, d)), + packages +); + +const packageDeps = packages + .map((p) => [p.id, graph.transitiveDependents(p.id).size]) + .sort((a, b) => b[1] - a[1]); + +const maxDeps = transduce(pluck(1), max(), packageDeps); + +fs.writeFileSync( + `package-deps.svg`, + serialize( + [barChart, + { + attribs: { + width: 1024, + height: 260, + "font-size": "10px", + "font-family": "Iosevka-Term-Light, Menlo, sans-serif" + }, + x: { + axis: [80, 1010, 170], + domain: [0, packageDeps.length, 1], + range: [80, 1020], + ticks: [...map((x) => x[0].substr(8), packageDeps)], + label: labeledTickX + }, + y: { + axis: [170, 10, 65], + domain: [0, maxDeps, 10], + range: [160, 20], + label: labeledTickY(1010) + }, + axis: "#666", + fill: "#0cc" + }, + mapIndexed((i, m) => [i, m[1]], packageDeps), + group({ "font-size": "20px", "text-anchor": "middle" }, + text([592, 28], "@thi.ng/umbrella internal re-use"), + text([592, 56], "(transitive dependents)"), + ) + ] + ) +); diff --git a/examples/package-stats/src/index.ts b/examples/package-stats/src/index.ts new file mode 100644 index 0000000000..3efde481ca --- /dev/null +++ b/examples/package-stats/src/index.ts @@ -0,0 +1,2 @@ +import "./dep-chart"; +import "./size-chart"; diff --git a/examples/package-stats/src/size-chart.ts b/examples/package-stats/src/size-chart.ts new file mode 100644 index 0000000000..8e3e1bc9ee --- /dev/null +++ b/examples/package-stats/src/size-chart.ts @@ -0,0 +1,81 @@ +import { serialize } from "@thi.ng/hiccup"; +import { group, text } from "@thi.ng/hiccup-svg"; +import { getter } from "@thi.ng/paths"; +import { bytes } from "@thi.ng/strings"; +import { + comp, + filter, + map, + mapcat, + mapIndexed, + max, + push, + transduce +} from "@thi.ng/transducers"; +import * as fs from "fs"; +import { barChart, labeledTickX, labeledTickY } from "./viz"; + +const BASE_DIR = "../../packages/"; + +const meta = transduce( + comp( + map((m: string) => [m, BASE_DIR + m + "/.meta/size.json"]), + filter(([_, path]) => fs.existsSync(path)), + map(([m, path]) => [m, JSON.parse(fs.readFileSync(path).toString())]) + ), + push(), + fs.readdirSync(BASE_DIR) +); + +const fileSizeChart = + (stats, modType, type) => { + + const get = getter([1, modType, type]); + stats = [...stats].sort((a, b) => get(b) - get(a)); + + const maxSize = transduce( + mapcat(([_, m]) => [m.esm[type], m.cjs[type], m.umd[type]]), + max(), + stats + ); + + fs.writeFileSync( + `package-sizes-${modType}.svg`, + serialize( + [barChart, + { + attribs: { + width: 1024, + height: 260, + "font-size": "10px", + "font-family": "Iosevka-Term-Light, Menlo, sans-serif" + }, + x: { + axis: [80, 1010, 170], + domain: [0, stats.length, 1], + range: [80, 1020], + ticks: [...map((x) => x[0], stats)], + label: labeledTickX + }, + y: { + axis: [170, 10, 65], + domain: [0, maxSize, 5 * 1024], + range: [160, 20], + label: labeledTickY(1010, bytes) + }, + axis: "#666", + fill: "#0cc" + }, + mapIndexed((i, m) => [i, get(m)], stats), + group({ "font-size": "20px", "text-anchor": "middle" }, + text([592, 28], `@thi.ng/umbrella package sizes (${modType.toUpperCase()})`), + text([592, 56], `(minified + gzipped)`), + ) + ] + ) + ); + }; + +fileSizeChart(meta, "esm", "gzip"); +fileSizeChart(meta, "cjs", "gzip"); +fileSizeChart(meta, "umd", "gzip"); diff --git a/examples/package-stats/src/viz.ts b/examples/package-stats/src/viz.ts new file mode 100644 index 0000000000..986d24fc86 --- /dev/null +++ b/examples/package-stats/src/viz.ts @@ -0,0 +1,107 @@ +import { group, line, svg, text, rect } from "@thi.ng/hiccup-svg"; +import { fit, fit01 } from "@thi.ng/math"; +import { map, mapcat, range, normRange, mapIndexed } from "@thi.ng/transducers"; + +// iterator of range mapped tuples: `[mapped, orig]` +const mappedRange = + (from: number, to: number, step: number, start: number, end: number) => + map( + (n) => [fit(n, from, to, start, end), n], + range(from, to, step) + ); + +const mappedTicks = + (start: number, end: number, ticks: any[]) => + mapIndexed( + (i, x) => [fit01(i / ticks.length, start, end), x], + 0, + ticks + ); + +// reusuable axis tick & label combo +export const tick = + (x1: number, y1: number, x2: number, y2: number, tx: number, ty: number, label: any) => [ + line([x1, y1], [x2, y2]), + text([tx, ty], label, { stroke: "none" }) + ]; + +// mapping fn for x-axis ticks +const tickX = + (y: number) => + ([x, n]: [number, any]) => + tick(x, y, x, y + 10, x, y + 20, n); + +// mapping fn for y-axis ticks +const tickY = + (x: number) => + ([y, n]: [number, any]) => + tick(x - 10, y, x, y, x - 15, y, n); + +export const labeledTickX = + (y) => + ([x, n]: any[]) => [ + line([x, y], [x, y + 5]), + text([x, y + 15], n, { + stroke: "none", + "text-anchor": "end", + transform: `rotate(-45 ${x} ${y + 15})` + }) + ]; + +export const labeledTickY = + (width, fmt = (x) => String(x)) => + (x) => + ([y, n]: [number, any]) => [ + ...tick(x - 5, y, x, y, x - 10, y + 4, n > 0 ? fmt(n) : 0), + n > 0 ? + line([x + 20, y], [width, y], { "stroke-dasharray": "1 3" }) : + null + ]; + +// x-axis with ticks as SVG group +const axisX = + ({ axis: a, domain: d, range: r, label, ticks }) => + ["g", { "text-anchor": "middle" }, + line([a[0], a[2]], [a[1], a[2]]), + mapcat( + (label || tickX)(a[2]), + ticks ? + mappedTicks(r[0], r[1], ticks) : + mappedRange(d[0], d[1], d[2], r[0], r[1]) + )]; + +// y-axis with ticks as SVG group +const axisY = + ({ axis: a, domain: d, range: r, label, ticks }) => + ["g", { "text-anchor": "end" }, + line([a[2], a[0]], [a[2], a[1]]), + mapcat( + (label || tickY)(a[2]), + ticks ? + mappedTicks(r[0], r[1], ticks) : + mappedRange(d[0], d[1], d[2], r[0], r[1]) + )]; + +// mapping fn to create a single bar from `[domainPos, value]` +const bar = + ({ domain: xd, range: xr }, { domain: yd, range: yr }) => + ([xx, yy]) => { + const y = fit(yy, yd[0], yd[1], yr[0], yr[1]); + return rect( + [fit(xx, xd[0], xd[1], xr[0], xr[1]) - 5, y], + 10, yr[0] - y + ); + }; + +// complete bar chart component +export const barChart = + (_, opts, values, ...xs) => + svg( + opts.attribs, + group({ stroke: opts.axis, fill: opts.axis }, + axisX(opts.x), + axisY(opts.y)), + group({ fill: opts.fill }, + map(bar(opts.x, opts.y), values)), + ...xs + ); diff --git a/examples/package-stats/tsconfig.json b/examples/package-stats/tsconfig.json new file mode 100644 index 0000000000..933ec03d70 --- /dev/null +++ b/examples/package-stats/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "lib", + "module": "commonjs", + "target": "es6", + "noUnusedLocals": false, + "noUnusedParameters": false, + }, + "include": [ + "./src/**/*.ts" + ] +} \ No newline at end of file From 5c3080d77712264a186d53290b1095b2ec013546 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 10 Jan 2019 13:01:14 +0000 Subject: [PATCH 231/333] build: temporarily add webpack until parcel-bundler/parcel#2513 is fixed --- package.json | 6 +- yarn.lock | 498 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 488 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 844bb95fe0..73c16d0d9a 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,11 @@ "rollup": "^1.0.2", "terser": "^3.14.1", "tslint": "^5.12.0", - "typescript": "^3.2.2" + "typescript": "^3.2.2", + "webpack": "^4.28.1", + "webpack-cli": "^3.2.1", + "ts-loader": "^5.3.3", + "file-loader": "^3.0.1" }, "scripts": { "bootstrap": "lerna bootstrap", diff --git a/yarn.lock b/yarn.lock index 02d20650f7..b05eff8d42 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1364,6 +1364,159 @@ resolved "https://registry.yarnpkg.com/@types/webgl2/-/webgl2-0.0.4.tgz#c3b0f9d6b465c66138e84e64cb3bdf8373c2c279" integrity sha512-PACt1xdErJbMUOUweSrbVM7gSIYm1vTncW2hF6Os/EeWi6TXYAYMPp+8v6rzHmypE5gHrxaxZNXgMkJVIdZpHw== +"@webassemblyjs/ast@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.11.tgz#b988582cafbb2b095e8b556526f30c90d057cace" + integrity sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA== + dependencies: + "@webassemblyjs/helper-module-context" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/wast-parser" "1.7.11" + +"@webassemblyjs/floating-point-hex-parser@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz#a69f0af6502eb9a3c045555b1a6129d3d3f2e313" + integrity sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg== + +"@webassemblyjs/helper-api-error@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz#c7b6bb8105f84039511a2b39ce494f193818a32a" + integrity sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg== + +"@webassemblyjs/helper-buffer@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz#3122d48dcc6c9456ed982debe16c8f37101df39b" + integrity sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w== + +"@webassemblyjs/helper-code-frame@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz#cf8f106e746662a0da29bdef635fcd3d1248364b" + integrity sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw== + dependencies: + "@webassemblyjs/wast-printer" "1.7.11" + +"@webassemblyjs/helper-fsm@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz#df38882a624080d03f7503f93e3f17ac5ac01181" + integrity sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A== + +"@webassemblyjs/helper-module-context@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz#d874d722e51e62ac202476935d649c802fa0e209" + integrity sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg== + +"@webassemblyjs/helper-wasm-bytecode@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz#dd9a1e817f1c2eb105b4cf1013093cb9f3c9cb06" + integrity sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ== + +"@webassemblyjs/helper-wasm-section@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz#9c9ac41ecf9fbcfffc96f6d2675e2de33811e68a" + integrity sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-buffer" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/wasm-gen" "1.7.11" + +"@webassemblyjs/ieee754@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz#c95839eb63757a31880aaec7b6512d4191ac640b" + integrity sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.7.11.tgz#d7267a1ee9c4594fd3f7e37298818ec65687db63" + integrity sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw== + dependencies: + "@xtuc/long" "4.2.1" + +"@webassemblyjs/utf8@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.7.11.tgz#06d7218ea9fdc94a6793aa92208160db3d26ee82" + integrity sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA== + +"@webassemblyjs/wasm-edit@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz#8c74ca474d4f951d01dbae9bd70814ee22a82005" + integrity sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-buffer" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/helper-wasm-section" "1.7.11" + "@webassemblyjs/wasm-gen" "1.7.11" + "@webassemblyjs/wasm-opt" "1.7.11" + "@webassemblyjs/wasm-parser" "1.7.11" + "@webassemblyjs/wast-printer" "1.7.11" + +"@webassemblyjs/wasm-gen@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz#9bbba942f22375686a6fb759afcd7ac9c45da1a8" + integrity sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/ieee754" "1.7.11" + "@webassemblyjs/leb128" "1.7.11" + "@webassemblyjs/utf8" "1.7.11" + +"@webassemblyjs/wasm-opt@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz#b331e8e7cef8f8e2f007d42c3a36a0580a7d6ca7" + integrity sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-buffer" "1.7.11" + "@webassemblyjs/wasm-gen" "1.7.11" + "@webassemblyjs/wasm-parser" "1.7.11" + +"@webassemblyjs/wasm-parser@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz#6e3d20fa6a3519f6b084ef9391ad58211efb0a1a" + integrity sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-api-error" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/ieee754" "1.7.11" + "@webassemblyjs/leb128" "1.7.11" + "@webassemblyjs/utf8" "1.7.11" + +"@webassemblyjs/wast-parser@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz#25bd117562ca8c002720ff8116ef9072d9ca869c" + integrity sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/floating-point-hex-parser" "1.7.11" + "@webassemblyjs/helper-api-error" "1.7.11" + "@webassemblyjs/helper-code-frame" "1.7.11" + "@webassemblyjs/helper-fsm" "1.7.11" + "@xtuc/long" "4.2.1" + +"@webassemblyjs/wast-printer@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz#c4245b6de242cb50a2cc950174fdbf65c78d7813" + integrity sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/wast-parser" "1.7.11" + "@xtuc/long" "4.2.1" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.1.tgz#5c85d662f76fa1d34575766c5dcd6615abcd30d8" + integrity sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g== + JSONStream@^1.0.4, JSONStream@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" @@ -1377,7 +1530,14 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -acorn@^5.0.0: +acorn-dynamic-import@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278" + integrity sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg== + dependencies: + acorn "^5.0.0" + +acorn@^5.0.0, acorn@^5.6.2: version "5.7.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== @@ -1401,7 +1561,17 @@ agentkeepalive@^3.4.1: dependencies: humanize-ms "^1.2.1" -ajv@^6.5.5: +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== + +ajv-keywords@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" + integrity sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo= + +ajv@^6.1.0, ajv@^6.5.5: version "6.6.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.6.2.tgz#caceccf474bf3fc3ce3b147443711a24063cc30d" integrity sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g== @@ -1718,6 +1888,11 @@ benchmark@^2.1.4: lodash "^4.17.4" platform "^1.3.3" +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + bin-links@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-1.1.2.tgz#fb74bd54bae6b7befc6c6221f25322ac830d9757" @@ -1930,7 +2105,7 @@ byte-size@^4.0.3: resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-4.0.4.tgz#29d381709f41aae0d89c631f1c81aec88cd40b23" integrity sha512-82RPeneC6nqCdSwCX2hZUz3JPOvN5at/nTEw/CMf05Smu3Hrpo9Psb7LjN+k+XndNArG1EY8L4+BM3aTM4BCvw== -cacache@^11.0.1, cacache@^11.3.2: +cacache@^11.0.1, cacache@^11.0.2, cacache@^11.3.2: version "11.3.2" resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.2.tgz#2d81e308e3d258ca38125b676b98b2ac9ce69bfa" integrity sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg== @@ -2091,7 +2266,7 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== -chokidar@^2.0.3: +chokidar@^2.0.2, chokidar@^2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" integrity sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ== @@ -2116,6 +2291,13 @@ chownr@^1.1.1: resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== +chrome-trace-event@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz#45a91bd2c20c9411f0963b5aaeb9a1b95e09cc48" + integrity sha512-xDbVgyfDTT2piup/h8dK/y4QZfJRSa73bw1WZ8b4XM1o7fsFubUVGYcE+1ANtOzJJELGpYoG2961z0Z6OAld9A== + dependencies: + tslib "^1.9.0" + ci-info@^1.5.0: version "1.6.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" @@ -2555,7 +2737,7 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^6.0.0, cross-spawn@^6.0.4: +cross-spawn@^6.0.0, cross-spawn@^6.0.4, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== @@ -2959,6 +3141,11 @@ destroy@~1.0.4: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= +detect-file@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" + integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= + detect-indent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" @@ -3126,6 +3313,11 @@ elliptic@^6.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.0" +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= + encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" @@ -3145,6 +3337,15 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0: dependencies: once "^1.4.0" +enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" + integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.4.0" + tapable "^1.0.0" + entities@^1.1.1, entities@~1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" @@ -3155,6 +3356,13 @@ err-code@^1.0.0: resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960" integrity sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA= +errno@^0.1.3, errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + dependencies: + prr "~1.0.1" + error-ex@^1.2.0, error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" @@ -3234,6 +3442,14 @@ escodegen@~1.9.0: optionalDependencies: source-map "~0.6.1" +eslint-scope@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" + integrity sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + esprima@^2.6.0: version "2.7.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" @@ -3249,7 +3465,14 @@ esprima@^4.0.0: resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -estraverse@^4.2.0: +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= @@ -3316,6 +3539,13 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= + dependencies: + homedir-polyfill "^1.0.1" + extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" @@ -3418,6 +3648,14 @@ figures@^2.0.0: dependencies: escape-string-regexp "^1.0.5" +file-loader@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-3.0.1.tgz#f8e0ba0b599918b51adfe45d66d1e771ad560faa" + integrity sha512-4sNIOXgtH/9WZq4NvlfU3Opn5ynUsqBwSLyM+I7UOwdGigTBYfVVQEwe/msZNX/j4pCJTIM14Fsw66Svo1oVrw== + dependencies: + loader-utils "^1.0.2" + schema-utils "^1.0.0" + filesize@^3.6.0: version "3.6.1" resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" @@ -3469,6 +3707,16 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" +findup-sync@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" + integrity sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw= + dependencies: + detect-file "^1.0.0" + is-glob "^3.1.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + flatten@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" @@ -3751,6 +3999,31 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" +global-modules-path@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/global-modules-path/-/global-modules-path-2.3.1.tgz#e541f4c800a1a8514a990477b267ac67525b9931" + integrity sha512-y+shkf4InI7mPRHSo2b/k6ix6+NLDtyccYv86whhxrSGX9wjPX1VMITmrDbE1eh7zkzhiWtW2sHklJYoQ62Cxg== + +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + globals@^11.1.0: version "11.9.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249" @@ -3924,6 +4197,13 @@ hmac-drbg@^1.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" +homedir-polyfill@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" + integrity sha1-TCu8inWJmP7r9e1oWA921GdotLw= + dependencies: + parse-passwd "^1.0.0" + hosted-git-info@^2.1.4, hosted-git-info@^2.6.0: version "2.7.1" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" @@ -4065,6 +4345,14 @@ import-local@^1.0.0: pkg-dir "^2.0.0" resolve-cwd "^2.0.0" +import-local@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== + dependencies: + pkg-dir "^3.0.0" + resolve-cwd "^2.0.0" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -4148,7 +4436,7 @@ inquirer@^6.2.0: strip-ansi "^5.0.0" through "^2.3.6" -interpret@^1.0.0: +interpret@^1.0.0, interpret@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== @@ -4433,7 +4721,7 @@ is-utf8@^0.2.0: resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= -is-windows@^1.0.2: +is-windows@^1.0.1, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== @@ -4589,7 +4877,7 @@ jsesc@~0.5.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= -json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1: +json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== @@ -4813,6 +5101,11 @@ libnpmteam@^1.0.1: get-stream "^4.0.0" npm-registry-fetch "^3.8.0" +lightercollective@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/lightercollective/-/lightercollective-0.1.0.tgz#70df102c530dcb8d0ccabfe6175a8d00d5f61300" + integrity sha512-J9tg5uraYoQKaWbmrzDDexbG6hHnMcWS1qLYgJSWE+mpA3U5OCSeMUhb+K55otgZJ34oFdR0ECvdIb3xuO5JOQ== + load-json-file@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" @@ -4834,6 +5127,20 @@ load-json-file@^4.0.0: pify "^3.0.0" strip-bom "^3.0.0" +loader-runner@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.1.tgz#026f12fe7c3115992896ac02ba022ba92971b979" + integrity sha512-By6ZFY7ETWOc9RFaAIb23IjJVcM4dvJC/N57nmdz9RSkMXvAXGI7SyVlAw3v8vjtDRlqThgVDVmTnr9fqMlxkw== + +loader-utils@^1.0.2, loader-utils@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" + integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== + dependencies: + big.js "^5.2.2" + emojis-list "^2.0.0" + json5 "^1.0.1" + locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" @@ -5067,6 +5374,14 @@ mem@^4.0.0: mimic-fn "^1.0.0" p-is-promise "^1.1.0" +memory-fs@^0.4.0, memory-fs@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + meow@^3.3.0: version "3.7.0" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" @@ -5117,7 +5432,7 @@ merge2@^1.2.3: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== -micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: +micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== @@ -5347,6 +5662,11 @@ needle@^2.2.1: iconv-lite "^0.4.4" sax "^1.2.4" +neo-async@^2.5.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.0.tgz#b9d15e4d71c6762908654b5183ed38b753340835" + integrity sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA== + nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" @@ -6029,6 +6349,11 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= + parseurl@~1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" @@ -6776,6 +7101,11 @@ protoduck@^5.0.1: dependencies: genfun "^5.0.0" +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" @@ -6989,7 +7319,7 @@ read@1, read@~1.0.1: dependencies: mute-stream "~0.0.4" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.3, readable-stream@~2.3.6: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.3, readable-stream@~2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== @@ -7202,6 +7532,14 @@ resolve-cwd@^2.0.0: dependencies: resolve-from "^3.0.0" +resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" @@ -7326,7 +7664,24 @@ sax@^1.2.4, sax@~1.2.1, sax@~1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: +schema-utils@^0.4.4: + version "0.4.7" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" + integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ== + dependencies: + ajv "^6.1.0" + ajv-keywords "^3.1.0" + +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + +"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@^5.0.1, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: version "5.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== @@ -7355,6 +7710,11 @@ send@0.16.2: range-parser "~1.2.0" statuses "~1.4.0" +serialize-javascript@^1.4.0: + version "1.6.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.6.1.tgz#4d1f697ec49429a847ca6f442a2a755126c4d879" + integrity sha512-A5MOagrPFga4YaKQSWHryl7AXvbQkEqpw4NNYMTNYUNV51bA8ABHgYFpqKx+YFFrw59xMV1qGH1R4AgoNIVgCw== + serialize-to-js@^1.1.1: version "1.2.2" resolved "https://registry.yarnpkg.com/serialize-to-js/-/serialize-to-js-1.2.2.tgz#1a567b0c9bf557bc7d7b77b503dfae0a8218d15d" @@ -7534,6 +7894,11 @@ sort-keys@^2.0.0: dependencies: is-plain-obj "^1.0.0" +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + source-map-resolve@^0.5.0: version "0.5.2" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" @@ -7909,6 +8274,11 @@ svgo@^1.0.0, svgo@^1.0.5: unquote "~1.1.1" util.promisify "~1.0.0" +tapable@^1.0.0, tapable@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.1.tgz#4d297923c5a72a42360de2ab52dadfaaec00018e" + integrity sha512-9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA== + tar@^2.0.0: version "2.2.1" resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" @@ -7948,6 +8318,20 @@ temp-write@^3.4.0: temp-dir "^1.0.0" uuid "^3.0.1" +terser-webpack-plugin@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.2.1.tgz#7545da9ae5f4f9ae6a0ac961eb46f5e7c845cc26" + integrity sha512-GGSt+gbT0oKcMDmPx4SRSfJPE1XaN3kQRWG4ghxKQw9cn5G9x6aCKSsgYdvyM0na9NJ4Drv0RG6jbBByZ5CMjw== + dependencies: + cacache "^11.0.2" + find-cache-dir "^2.0.0" + schema-utils "^1.0.0" + serialize-javascript "^1.4.0" + source-map "^0.6.1" + terser "^3.8.1" + webpack-sources "^1.1.0" + worker-farm "^1.5.2" + terser@^3.14.1, terser@^3.7.3, terser@^3.8.1: version "3.14.1" resolved "https://registry.yarnpkg.com/terser/-/terser-3.14.1.tgz#cc4764014af570bc79c79742358bd46926018a32" @@ -8084,6 +8468,17 @@ trim-right@^1.0.1: resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= +ts-loader@^5.3.3: + version "5.3.3" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-5.3.3.tgz#8b4af042e773132d86b3c99ef0acf3b4d325f473" + integrity sha512-KwF1SplmOJepnoZ4eRIloH/zXL195F51skt7reEsS6jvDqzgc/YSbz9b8E07GxIUwLXdcD4ssrJu6v8CwaTafA== + dependencies: + chalk "^2.3.0" + enhanced-resolve "^4.0.0" + loader-utils "^1.0.2" + micromatch "^3.1.4" + semver "^5.0.1" + tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" @@ -8339,7 +8734,7 @@ uuid@^3.0.1, uuid@^3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== -v8-compile-cache@^2.0.0: +v8-compile-cache@^2.0.0, v8-compile-cache@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.2.tgz#a428b28bb26790734c4fc8bc9fa106fccebf6a6c" integrity sha512-1wFuMUIM16MDJRCrpbpuEPTUGmM5QMUg0cr3KFwra2XgOgFcPGDQHDh3CszSCD2Zewc/dh/pamNEW8CbfDebUw== @@ -8385,6 +8780,15 @@ vm-browserify@0.0.4: dependencies: indexof "0.0.1" +watchpack@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" + integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== + dependencies: + chokidar "^2.0.2" + graceful-fs "^4.1.2" + neo-async "^2.5.0" + wcwidth@^1.0.0, wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" @@ -8397,6 +8801,63 @@ webidl-conversions@^4.0.2: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== +webpack-cli@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.2.1.tgz#779c696c82482491f0803907508db2e276ed3b61" + integrity sha512-jeJveHwz/vwpJ3B8bxEL5a/rVKIpRNJDsKggfKnxuYeohNDW4Y/wB9N/XHJA093qZyS0r6mYL+/crLsIol4WKA== + dependencies: + chalk "^2.4.1" + cross-spawn "^6.0.5" + enhanced-resolve "^4.1.0" + findup-sync "^2.0.0" + global-modules "^1.0.0" + global-modules-path "^2.3.0" + import-local "^2.0.0" + interpret "^1.1.0" + lightercollective "^0.1.0" + loader-utils "^1.1.0" + supports-color "^5.5.0" + v8-compile-cache "^2.0.2" + yargs "^12.0.4" + +webpack-sources@^1.1.0, webpack-sources@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85" + integrity sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack@^4.28.1: + version "4.28.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.28.1.tgz#d0e2856e75d1224b170bf16c30b6ca9b75f0d958" + integrity sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-module-context" "1.7.11" + "@webassemblyjs/wasm-edit" "1.7.11" + "@webassemblyjs/wasm-parser" "1.7.11" + acorn "^5.6.2" + acorn-dynamic-import "^3.0.0" + ajv "^6.1.0" + ajv-keywords "^3.1.0" + chrome-trace-event "^1.0.0" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.0" + json-parse-better-errors "^1.0.2" + loader-runner "^2.3.0" + loader-utils "^1.1.0" + memory-fs "~0.4.1" + micromatch "^3.1.8" + mkdirp "~0.5.0" + neo-async "^2.5.0" + node-libs-browser "^2.0.0" + schema-utils "^0.4.4" + tapable "^1.1.0" + terser-webpack-plugin "^1.1.0" + watchpack "^1.5.0" + webpack-sources "^1.3.0" + whatwg-url@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.0.0.tgz#fde926fa54a599f3adf82dff25a9f7be02dc6edd" @@ -8416,7 +8877,7 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@1, which@^1.2.9, which@^1.3.0, which@^1.3.1: +which@1, which@^1.2.14, which@^1.2.9, which@^1.3.0, which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -8440,6 +8901,13 @@ wordwrap@~1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= +worker-farm@^1.5.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.6.0.tgz#aecc405976fab5a95526180846f0dba288f3a4a0" + integrity sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ== + dependencies: + errno "~0.1.7" + wrap-ansi@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" @@ -8547,7 +9015,7 @@ yargs@11.1.0: y18n "^3.2.1" yargs-parser "^9.0.2" -yargs@^12.0.1: +yargs@^12.0.1, yargs@^12.0.4: version "12.0.5" resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== From a894a24a451242d6e906c114bf0f78834c74ade3 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 10 Jan 2019 14:22:18 +0000 Subject: [PATCH 232/333] fix(transducers): update juxt re-export --- packages/transducers/src/func/juxt.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/transducers/src/func/juxt.ts b/packages/transducers/src/func/juxt.ts index f6dc86f79a..00b819d738 100644 --- a/packages/transducers/src/func/juxt.ts +++ b/packages/transducers/src/func/juxt.ts @@ -1 +1,3 @@ -export { juxt } from "@thi.ng/compose"; +import { juxt as _juxt } from "@thi.ng/compose"; + +export const juxt = _juxt; From 4df9ec41d4b70292a846ed8c3ef8d5a514abec67 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 10 Jan 2019 14:35:54 +0000 Subject: [PATCH 233/333] build: update bundle-module outputs, emit meta data, update .gitignore - write non-minified CommonJS - write minified UMD - write minified + gzipped module sizes to .meta dir --- .gitignore | 2 ++ scripts/bundle-module | 77 +++++++++++++++++++++++++++---------------- 2 files changed, 50 insertions(+), 29 deletions(-) diff --git a/.gitignore b/.gitignore index a6a89679d2..7856ba86c6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ node_modules .cache +.meta .nyc_output coverage build @@ -12,6 +13,7 @@ examples/hdc examples/hdom-class examples/hdom-clj examples/ts-parse +lib .DS_Store tachyons.min.css bundle.* diff --git a/scripts/bundle-module b/scripts/bundle-module index 2c2890eee5..49cda6ae31 100755 --- a/scripts/bundle-module +++ b/scripts/bundle-module @@ -12,10 +12,12 @@ const size = const name = process.argv[2]; -const deps = process.argv.slice(3).reduce( - (acc, x) => (acc[`@thi.ng/${x}`] = `thi.ng.${camelCase(x)}`, acc), - {} -); +const deps = process.argv + .slice(3) + .reduce( + (acc, x) => (acc[`@thi.ng/${x}`] = `thi.ng.${camelCase(x)}`, acc), + {} + ); const inOpts = { external: Object.keys(deps), @@ -28,35 +30,52 @@ const terserOpts = { ecma: 6 }; -const buildVersion = async (dest, outOpts) => { - console.log(`bundling (${outOpts.format}): ${dest}`); - const bundle = await rollup.rollup(inOpts); - const bundleOut = await bundle.generate(outOpts); - const terserOut = terser.minify(bundleOut.output[0].code, terserOpts); - fs.writeFileSync(dest, terserOut.code); - console.log(`\tsize: ${size(terserOut.code.length)} / gzipped: ${size(gz.sync(terserOut.code))}`); -}; +const buildVersion = + async (dest, outOpts, write = true, compressed = false) => { + console.log(`bundling (${outOpts.format}): ${dest}`); + const bundle = await rollup.rollup(inOpts); + const bundleOut = (await bundle.generate(outOpts)).output[0].code; + const terserOut = terser.minify(bundleOut, terserOpts).code; + write && fs.writeFileSync(dest, compressed ? terserOut : bundleOut); -const build = async () => { + const gzSize = gz.sync(terserOut); + console.log(`\tsize: ${size(terserOut.length)} / gzipped: ${size(gzSize)}`); + return { raw: terserOut.length, gzip: gzSize }; + }; - !fs.existsSync("lib") && fs.mkdirSync("lib"); +const build = + async () => { - await buildVersion( - "lib/index.js", - { - format: "cjs" - } - ); + !fs.existsSync("lib") && fs.mkdirSync("lib"); + !fs.existsSync(".meta") && fs.mkdirSync(".meta"); - await buildVersion( - "lib/index.umd.js", - { - format: "umd", - globals: deps, - name: `thi.ng.${name}`, - } - ); + const cjs = await buildVersion( + "lib/index.cjs.js", + { + format: "cjs" + } + ); -}; + const esm = await buildVersion( + "lib/index.es6.js", + { + format: "esm" + }, + false + ); + + const umd = await buildVersion( + "lib/index.umd.js", + { + format: "umd", + globals: deps, + name: `thi.ng.${name}`, + }, + true, + true + ); + + fs.writeFileSync(".meta/size.json", JSON.stringify({ esm, cjs, umd })); + }; build(); From 1f01bf8f292495a33baa112334cd5c5557148947 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 10 Jan 2019 14:44:45 +0000 Subject: [PATCH 234/333] build: update make-module script --- scripts/make-module | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/scripts/make-module b/scripts/make-module index bf87bba7cf..700d126789 100755 --- a/scripts/make-module +++ b/scripts/make-module @@ -35,7 +35,9 @@ cat << EOF > $MODULE/package.json "name": "@thi.ng/$1", "version": "0.0.1", "description": "TODO", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -45,23 +47,25 @@ cat << EOF > $MODULE/package.json "author": "$AUTHOR <$EMAIL>", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module $1", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.3" + "@thi.ng/api": "^4.2.4" }, "keywords": [ "ES6", @@ -69,7 +73,8 @@ cat << EOF > $MODULE/package.json ], "publishConfig": { "access": "public" - } + }, + "sideEffects": false } EOF @@ -78,7 +83,9 @@ cat << EOF > $MODULE/tsconfig.json { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" @@ -91,7 +98,8 @@ cat << EOF > $MODULE/test/tsconfig.json { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "commonjs" }, "include": [ "./**/*.ts", @@ -109,6 +117,7 @@ doc export src* test +.meta .nyc_output tsconfig.json *.tgz From 8f270dfac01060d72ad29cdc07c97de3a684694e Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 10 Jan 2019 17:24:57 +0000 Subject: [PATCH 235/333] build: update project tpl scripts, ignore files --- .gitignore | 27 +++++++++++++------------ packages/hiccup-carbon-icons/.gitignore | 1 + scripts/make-example | 15 +++++--------- scripts/make-module | 8 ++++---- 4 files changed, 24 insertions(+), 27 deletions(-) create mode 100644 packages/hiccup-carbon-icons/.gitignore diff --git a/.gitignore b/.gitignore index 7856ba86c6..9b08949279 100644 --- a/.gitignore +++ b/.gitignore @@ -1,27 +1,28 @@ -node_modules .cache +.DS_Store .meta .nyc_output -coverage +*.bak* +*.d.ts +*.gz +*.js +*.log +*.map +*.tgz +*.zip +/.gtm/ build +bundle.* +coverage dev doc docs -export examples/dataflow-scenegraph examples/hdc examples/hdom-class examples/hdom-clj examples/ts-parse +export lib -.DS_Store +node_modules tachyons.min.css -bundle.* -*.log -*.tgz -*.js -*.d.ts -*.bak* -*.zip -*.map -/.gtm/ diff --git a/packages/hiccup-carbon-icons/.gitignore b/packages/hiccup-carbon-icons/.gitignore new file mode 100644 index 0000000000..2d19fc766d --- /dev/null +++ b/packages/hiccup-carbon-icons/.gitignore @@ -0,0 +1 @@ +*.html diff --git a/scripts/make-example b/scripts/make-example index 234cb5ac44..d1707237d2 100755 --- a/scripts/make-example +++ b/scripts/make-example @@ -27,18 +27,18 @@ cat << EOF > $MODULE/package.json "author": "$AUTHOR <$EMAIL>", "license": "Apache-2.0", "scripts": { - "clean": "rm -rf .cache build out", + "clean": "rimraf .cache build out", "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --detailed-report", "start": "parcel index.html -p 8080 --open" }, "devDependencies": { - "parcel-bundler": "^1.10.3", - "terser": "^3.11.0", + "parcel-bundler": "^1.11.0", + "rimraf": "^2.6.3", + "terser": "^3.14.1", "typescript": "^3.2.2" }, "dependencies": { "@thi.ng/api": "latest", - "@thi.ng/atom": "latest", "@thi.ng/rstream": "latest", "@thi.ng/transducers-hdom": "latest" }, @@ -101,12 +101,7 @@ cat << EOF > $MODULE/README.md [Live demo](http://demo.thi.ng/umbrella/$1/) -\`\`\`bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/$1 -yarn install -yarn start -\`\`\` +Please refer to the [example build instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) on the wiki. ## Authors diff --git a/scripts/make-module b/scripts/make-module index 700d126789..97073dd76c 100755 --- a/scripts/make-module +++ b/scripts/make-module @@ -110,6 +110,10 @@ EOF echo "writing .npmignore..." cat << EOF > $MODULE/.npmignore +.meta +.nyc_output +*.html +*.tgz build coverage dev @@ -117,11 +121,7 @@ doc export src* test -.meta -.nyc_output tsconfig.json -*.tgz -*.html EOF echo "writing README.md..." From cc26ae98e1076a7601fea6de3d81b85245937f8c Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 10 Jan 2019 17:25:51 +0000 Subject: [PATCH 236/333] docs(examples): update readmes to refer to wiki build instructions --- examples/async-effect/README.md | 9 +++------ examples/canvas-dial/README.md | 9 +++------ examples/cellular-automata/README.md | 9 +++------ examples/crypto-chart/README.md | 9 +++------ examples/dashboard/README.md | 9 +++------ examples/devcards/README.md | 9 +++------ examples/geom-knn/README.md | 9 +++------ examples/geom-tessel/README.md | 9 +++------ examples/gesture-analysis/README.md | 9 +++------ examples/hdom-basics/README.md | 17 +++++++++++------ examples/hdom-benchmark/README.md | 17 +++++++++++------ examples/hdom-benchmark2/README.md | 9 +++------ examples/hdom-canvas-clock/README.md | 17 ++++------------- examples/hdom-canvas-draw/README.md | 9 +++------ examples/hdom-canvas-shapes/README.md | 15 +++------------ examples/hdom-dropdown-fuzzy/README.md | 9 +++------ examples/hdom-dropdown/README.md | 9 +++------ examples/hdom-dyn-context/README.md | 9 +++------ examples/hdom-skip/README.md | 9 +++------ examples/hdom-theme-adr-0003/README.md | 9 +++------ examples/hmr-basics/README.md | 9 +++------ examples/hydrate-basics/README.md | 9 +++------ examples/interceptor-basics/README.md | 9 +++------ examples/interceptor-basics2/README.md | 17 +++++++++++------ examples/json-components/README.md | 17 +++++++++++------ examples/login-form/README.md | 17 +++++++++++------ examples/mandelbrot/README.md | 9 +++------ examples/markdown/README.md | 12 ++++-------- examples/pointfree-svg/README.md | 12 +++++++++++- examples/router-basics/README.md | 19 +++---------------- examples/rstream-dataflow/README.md | 20 +++++++++++--------- examples/rstream-grid/README.md | 25 ++++++------------------- examples/rstream-hdom/README.md | 9 +++------ examples/svg-barchart/README.md | 9 +++------ examples/svg-particles/README.md | 17 +++++++++++------ examples/svg-waveform/README.md | 25 ++++++------------------- examples/talk-slides/README.md | 9 +++------ examples/todo-list/README.md | 17 +++++++++++------ examples/transducers-hdom/README.md | 9 +++------ examples/triple-query/README.md | 9 +++------ examples/webgl/README.md | 17 +++++++++++------ examples/xml-converter/README.md | 12 ++++++------ 42 files changed, 217 insertions(+), 301 deletions(-) diff --git a/examples/async-effect/README.md b/examples/async-effect/README.md index 2793114889..00bc303112 100644 --- a/examples/async-effect/README.md +++ b/examples/async-effect/README.md @@ -2,9 +2,6 @@ [Live demo](https://demo.thi.ng/umbrella/async-effect/) -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/async-effect -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. diff --git a/examples/canvas-dial/README.md b/examples/canvas-dial/README.md index d74977360d..f0277ca369 100644 --- a/examples/canvas-dial/README.md +++ b/examples/canvas-dial/README.md @@ -5,12 +5,9 @@ Customizable canvas-based radial dial component with mouse & touch support. -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/canvas-dial -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/cellular-automata/README.md b/examples/cellular-automata/README.md index 8d0a4384d8..89bcf409eb 100644 --- a/examples/cellular-automata/README.md +++ b/examples/cellular-automata/README.md @@ -2,12 +2,9 @@ [Live demo](https://demo.thi.ng/umbrella/cellular-automata/) -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/cellular-automata -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Example configurations diff --git a/examples/crypto-chart/README.md b/examples/crypto-chart/README.md index 99d2d52d05..5a4dc6df14 100644 --- a/examples/crypto-chart/README.md +++ b/examples/crypto-chart/README.md @@ -24,12 +24,9 @@ The diagram below shows a schematic of the dataflow graph used: ## Building -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/crypto-chart -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/dashboard/README.md b/examples/dashboard/README.md index 652fa64438..c9c6ab7576 100644 --- a/examples/dashboard/README.md +++ b/examples/dashboard/README.md @@ -2,9 +2,6 @@ [Live demo here](https://demo.thi.ng/umbrella/dashboard/) -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/dashboard -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. diff --git a/examples/devcards/README.md b/examples/devcards/README.md index 1ac1638f32..e8852251d3 100644 --- a/examples/devcards/README.md +++ b/examples/devcards/README.md @@ -2,9 +2,6 @@ [Live demo](https://demo.thi.ng/umbrella/devcards/) -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/devcards -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. diff --git a/examples/geom-knn/README.md b/examples/geom-knn/README.md index 941f574ecb..b3aa5b1f1c 100644 --- a/examples/geom-knn/README.md +++ b/examples/geom-knn/README.md @@ -10,12 +10,9 @@ up to 200 neighboring points. Those points are highlighted in blue. For each of those a secondary KNN search is performed selecting up to 8 neighbors. These matches are visualized as lines. -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/geom-knn -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/geom-tessel/README.md b/examples/geom-tessel/README.md index f33a8c6287..8420136519 100644 --- a/examples/geom-tessel/README.md +++ b/examples/geom-tessel/README.md @@ -11,12 +11,9 @@ Note the lack of explicit hiccup shape defs in this example. All @thi.ng/geom types support auto-conversion via the [`IToHiccup` interface](https://github.com/thi-ng/umbrella/blob/master/packages/api/src/api.ts#L415). -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/geom-tessel -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/gesture-analysis/README.md b/examples/gesture-analysis/README.md index 850d99da18..ec6374fd8b 100644 --- a/examples/gesture-analysis/README.md +++ b/examples/gesture-analysis/README.md @@ -10,12 +10,9 @@ constructs and **Note: Currently only really works on desktop until I figured out a way to better attach touch events...** -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/gesture-analysis -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/hdom-basics/README.md b/examples/hdom-basics/README.md index d3137177d5..a4e78c004a 100644 --- a/examples/hdom-basics/README.md +++ b/examples/hdom-basics/README.md @@ -2,9 +2,14 @@ [Live demo](https://demo.thi.ng/umbrella/hdom-basics/) -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/hdom-basics -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/examples/hdom-benchmark/README.md b/examples/hdom-benchmark/README.md index 14b269d669..7c259cfa1e 100644 --- a/examples/hdom-benchmark/README.md +++ b/examples/hdom-benchmark/README.md @@ -2,9 +2,14 @@ [Live demo](https://demo.thi.ng/umbrella/hdom-benchmark/) -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/hdom-benchmark -yarn install -yarn start -``` \ No newline at end of file +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/examples/hdom-benchmark2/README.md b/examples/hdom-benchmark2/README.md index f08f0c4cff..ff2d2933f1 100644 --- a/examples/hdom-benchmark2/README.md +++ b/examples/hdom-benchmark2/README.md @@ -2,12 +2,9 @@ [Live demo](http://demo.thi.ng/umbrella/hdom-benchmark2/) -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/hdom-benchmark2 -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/hdom-canvas-clock/README.md b/examples/hdom-canvas-clock/README.md index c5b92f327a..4f1b55135f 100644 --- a/examples/hdom-canvas-clock/README.md +++ b/examples/hdom-canvas-clock/README.md @@ -2,7 +2,7 @@ [Live demo](http://demo.thi.ng/umbrella/hdom-canvas-clock/) -Declarative canvas drawing using the upcoming +Declarative canvas drawing using the [@thi.ng/hdom-canvas](https://github.com/thi-ng/umbrella/tree/master/packages/hdom-canvas) package. @@ -13,18 +13,9 @@ Related examples: ## Building -Note: Currently, some of the packages used by this demo are only -available as pre-releases (e.g. `"@thi.ng/hdom": "^5.0.0-alpha"`). - -The example project also assumes that [Parcel](https://parceljs.org) is -installed globally. - -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/hdom-canvas-clock -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/hdom-canvas-draw/README.md b/examples/hdom-canvas-draw/README.md index 5ca912c7a2..da13473855 100644 --- a/examples/hdom-canvas-draw/README.md +++ b/examples/hdom-canvas-draw/README.md @@ -2,12 +2,9 @@ [Live demo](http://demo.thi.ng/umbrella/hdom-canvas-draw/) -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/hdom-canvas-draw -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/hdom-canvas-shapes/README.md b/examples/hdom-canvas-shapes/README.md index 9ff45425fd..e8c88745e5 100644 --- a/examples/hdom-canvas-shapes/README.md +++ b/examples/hdom-canvas-shapes/README.md @@ -34,18 +34,9 @@ Dataflow diagram: ## Building -Note: Currently, some of the packages used by this demo are only -available as pre-releases (e.g. `"@thi.ng/hdom": "^5.0.0-alpha"`). - -The example project also assumes that [Parcel](https://parceljs.org) is -installed globally. - -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/hdom-canvas-shapes -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/hdom-dropdown-fuzzy/README.md b/examples/hdom-dropdown-fuzzy/README.md index fa2f87153f..687b27556e 100644 --- a/examples/hdom-dropdown-fuzzy/README.md +++ b/examples/hdom-dropdown-fuzzy/README.md @@ -5,12 +5,9 @@ **This example is a work-in-progress trying out different ideas. Do not (yet) take as reference for your own projects.** -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/hdom-dropdown-fuzzy -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/hdom-dropdown/README.md b/examples/hdom-dropdown/README.md index c9c006e3ab..0192fba45c 100644 --- a/examples/hdom-dropdown/README.md +++ b/examples/hdom-dropdown/README.md @@ -2,12 +2,9 @@ [Live demo](https://demo.thi.ng/umbrella/hdom-dropdown/) -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/hdom-dropdown -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/hdom-dyn-context/README.md b/examples/hdom-dyn-context/README.md index 5109ea6edf..1535023283 100644 --- a/examples/hdom-dyn-context/README.md +++ b/examples/hdom-dyn-context/README.md @@ -5,12 +5,9 @@ Minimal example demonstrating use of dynamic hdom user context values, here used for app-wide theme switching. -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/hdom-dyn-context -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/hdom-skip/README.md b/examples/hdom-skip/README.md index 6dbd95f5f0..b1efe64eb6 100644 --- a/examples/hdom-skip/README.md +++ b/examples/hdom-skip/README.md @@ -5,12 +5,9 @@ Minimal example demonstrating use of the hdom `__skip` control attribute to selectively skip diffing & updating DOM tree branches. -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/hdom-skip -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/hdom-theme-adr-0003/README.md b/examples/hdom-theme-adr-0003/README.md index 7d42d4a39c..c8e5434959 100644 --- a/examples/hdom-theme-adr-0003/README.md +++ b/examples/hdom-theme-adr-0003/README.md @@ -5,12 +5,9 @@ WIP demo of themed component proposal discussed in [ADR-0003](https://github.com/thi-ng/umbrella/blob/master/packages/hdom-components/adr/0003-component-configuration-via-context.md). -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/hdom-theme-adr-0003 -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/hmr-basics/README.md b/examples/hmr-basics/README.md index d1a10951a1..9c60480d57 100644 --- a/examples/hmr-basics/README.md +++ b/examples/hmr-basics/README.md @@ -6,12 +6,9 @@ Minimal example demonstrating the combined usage of @thi.ng/memoize's [`defonce`](https://github.com/thi-ng/umbrella/tree/master/packages/memoize/src/defonce.ts) and parcel's [Hot Module Replacement API](https://parceljs.org/hmr.html). -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/hmr-basics -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/hydrate-basics/README.md b/examples/hydrate-basics/README.md index 4fcad46175..cc4589d4fe 100644 --- a/examples/hydrate-basics/README.md +++ b/examples/hydrate-basics/README.md @@ -5,12 +5,9 @@ This example demonstrates how to hydrate a pre-created HTML DOM (e.g. server-side rendering) client-side. -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/hydrate-basics -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/interceptor-basics/README.md b/examples/interceptor-basics/README.md index 17744b1f5c..49c61fe778 100644 --- a/examples/interceptor-basics/README.md +++ b/examples/interceptor-basics/README.md @@ -2,12 +2,9 @@ [Live demo](http://demo.thi.ng/umbrella/interceptor-basics/) -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/interceptor-basics -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/interceptor-basics2/README.md b/examples/interceptor-basics2/README.md index 5ebb07a76f..a09cad11c0 100644 --- a/examples/interceptor-basics2/README.md +++ b/examples/interceptor-basics2/README.md @@ -2,9 +2,14 @@ [Live demo](https://demo.thi.ng/umbrella/interceptor-basics2/) -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/interceptor-basics2 -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/examples/json-components/README.md b/examples/json-components/README.md index ed374c29c4..b33c2e93ea 100644 --- a/examples/json-components/README.md +++ b/examples/json-components/README.md @@ -2,9 +2,14 @@ [Live demo](https://demo.thi.ng/umbrella/json-components/) -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/json-components -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/examples/login-form/README.md b/examples/login-form/README.md index 2ccd05549f..dce5b12170 100644 --- a/examples/login-form/README.md +++ b/examples/login-form/README.md @@ -2,9 +2,14 @@ [Live demo](https://demo.thi.ng/umbrella/login-form/) -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/login-form -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/examples/mandelbrot/README.md b/examples/mandelbrot/README.md index 5d03c89f3b..ab087eb66a 100644 --- a/examples/mandelbrot/README.md +++ b/examples/mandelbrot/README.md @@ -2,12 +2,9 @@ [Live demo](http://demo.thi.ng/umbrella/mandelbrot/) -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/mandelbrot -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/markdown/README.md b/examples/markdown/README.md index 96e33d046e..840d3f9e28 100644 --- a/examples/markdown/README.md +++ b/examples/markdown/README.md @@ -150,12 +150,9 @@ serialize(iterator(parse(tags), src)); ## Building locally -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/markdown -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors @@ -163,5 +160,4 @@ yarn start ## License -© 2018 - 2019 Karsten Schmidt // Apache Software License 2.0 - +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/examples/pointfree-svg/README.md b/examples/pointfree-svg/README.md index f2835888b0..34d974a6c2 100644 --- a/examples/pointfree-svg/README.md +++ b/examples/pointfree-svg/README.md @@ -1,6 +1,7 @@ # pointfree-svg -This is a non-interactive demo combining the following packages to generate the SVG graphic below: +This is a non-browser demo combining the following packages to generate +the SVG graphic below: - [@thi.ng/hiccup](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup) - [@thi.ng/hiccup-svg](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup-svg) @@ -21,5 +22,14 @@ The generated SVG file will be written in this example's directory... ```bash git clone https://github.com/thi-ng/umbrella.git cd umbrella/examples/pointfree-svg +yarn install yarn build ``` + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/examples/router-basics/README.md b/examples/router-basics/README.md index c9f2c4119b..f2e6ed58a2 100644 --- a/examples/router-basics/README.md +++ b/examples/router-basics/README.md @@ -2,14 +2,9 @@ [Live demo](https://demo.thi.ng/umbrella/router-basics/) -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/router-basics -yarn install -yarn start -``` - -Installs all dependencies, runs `parcel serve` and opens the app in your browser. +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## About @@ -28,14 +23,6 @@ Features covered: - Dynamic JSON content loading / transformation - Component styling with [Tachyons CSS](http://tachyons.io/) -### Production build - -```bash -yarn build -``` - -Builds a minified version of the app and places it in `/out` directory. - ## Authors - Karsten Schmidt diff --git a/examples/rstream-dataflow/README.md b/examples/rstream-dataflow/README.md index 0d5e0b1024..4b28b9a965 100644 --- a/examples/rstream-dataflow/README.md +++ b/examples/rstream-dataflow/README.md @@ -2,15 +2,9 @@ [Live demo](https://demo.thi.ng/umbrella/rstream-dataflow/) -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/rstream-dataflow -yarn install -yarn start -``` - -Installs all dependencies, runs `parcel serve` and opens the app in your -browser. +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## About @@ -32,3 +26,11 @@ package. - [@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/master/packages/transducers) - data transformations (here used for stream transforms) Please see detailed comments in the source code for further explanations. + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/examples/rstream-grid/README.md b/examples/rstream-grid/README.md index d26e34f992..5ecc6f2e6a 100644 --- a/examples/rstream-grid/README.md +++ b/examples/rstream-grid/README.md @@ -23,27 +23,14 @@ template. ### Development -```bash -git clone https://github.com/thi-ng/umbrella/ -cd umbrella/examples/rstream-grid -yarn install -yarn start -``` - -Installs all dependencies, runs `parcel serve` and opens the app in your -browser. - -### Production - -```bash -yarn build -``` - -Builds a minified version of the app and places it in the `/out` -directory. +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors - Karsten Schmidt -© 2018 \ No newline at end of file +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/examples/rstream-hdom/README.md b/examples/rstream-hdom/README.md index 23e391d662..5191cbcffd 100644 --- a/examples/rstream-hdom/README.md +++ b/examples/rstream-hdom/README.md @@ -8,12 +8,9 @@ constructs can be used for state handling and reactively trigger [@thi.ng/hdom](https://github.com/thi-ng/umbrella/tree/master/packages/hdom) updates only when any of the UI related streams have value changes. -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/rstream-hdom -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/svg-barchart/README.md b/examples/svg-barchart/README.md index 6068c24e7b..2c0026dddf 100644 --- a/examples/svg-barchart/README.md +++ b/examples/svg-barchart/README.md @@ -6,12 +6,9 @@ SVG bar chart component & one-off rendering. ![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/svg-barchart.png) -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/svg-barchart -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/svg-particles/README.md b/examples/svg-particles/README.md index 096e45720e..2d7fe896c8 100644 --- a/examples/svg-particles/README.md +++ b/examples/svg-particles/README.md @@ -2,9 +2,14 @@ [Live demo](https://demo.thi.ng/umbrella/svg-particles/) -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/svg-particles -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/examples/svg-waveform/README.md b/examples/svg-waveform/README.md index bb6fd12eb5..5d9cb17a14 100644 --- a/examples/svg-waveform/README.md +++ b/examples/svg-waveform/README.md @@ -14,27 +14,14 @@ template. ### Development -```bash -git clone https://github.com/thi-ng/umbrella/ -cd umbrella/examples/svg-waveform -yarn install -yarn start -``` - -Installs all dependencies, runs `parcel serve` and opens the app in your -browser. - -### Production - -```bash -yarn build -``` - -Builds a minified version of the app and places it in the `/out` -directory. +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors - Karsten Schmidt -© 2018 \ No newline at end of file +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/examples/talk-slides/README.md b/examples/talk-slides/README.md index ec44933758..0eefe8e574 100644 --- a/examples/talk-slides/README.md +++ b/examples/talk-slides/README.md @@ -30,12 +30,9 @@ As usual, all theming is done via [Tachyons CSS](http://tachyons.io), also see this useful site for quick reference: [Tachyons TL;DR](https://tachyons-tldr.now.sh/). -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/talk-slides -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/todo-list/README.md b/examples/todo-list/README.md index df37f41c20..a2260e0264 100644 --- a/examples/todo-list/README.md +++ b/examples/todo-list/README.md @@ -2,9 +2,14 @@ [Live demo here](https://demo.thi.ng/umbrella/todo-list/) -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/todo-list -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/examples/transducers-hdom/README.md b/examples/transducers-hdom/README.md index 5e95e328d6..8a04234d13 100644 --- a/examples/transducers-hdom/README.md +++ b/examples/transducers-hdom/README.md @@ -2,12 +2,9 @@ [Live demo](https://demo.thi.ng/umbrella/transducers-hdom/) -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/transducers-hdom -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/triple-query/README.md b/examples/triple-query/README.md index 3aaddfe213..c10f1deb11 100644 --- a/examples/triple-query/README.md +++ b/examples/triple-query/README.md @@ -2,12 +2,9 @@ [Live demo](https://demo.thi.ng/umbrella/triple-query/) -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/triple-query -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## Authors diff --git a/examples/webgl/README.md b/examples/webgl/README.md index baf68109e0..30c1423225 100644 --- a/examples/webgl/README.md +++ b/examples/webgl/README.md @@ -2,9 +2,14 @@ [Live demo](https://demo.thi.ng/umbrella/webgl/) -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/webgl -yarn install -yarn start -``` +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/examples/xml-converter/README.md b/examples/xml-converter/README.md index c3c9333baa..f46fd7a4a9 100644 --- a/examples/xml-converter/README.md +++ b/examples/xml-converter/README.md @@ -18,12 +18,10 @@ dataflow topology used by the browser app: ![dataflow](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/xml-converter.png) ## Browser version -```bash -git clone https://github.com/thi-ng/umbrella.git -cd umbrella/examples/xml-converter -yarn install -yarn start -``` + +Please refer to the [example build +instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) +on the wiki. ## CLI version @@ -33,6 +31,8 @@ written to stdout). ```bash # in this example's project root... +yarn install + yarn build-cli bin/hiccup --help From bb3db27cbe3fdc712d44c0edfe7b7b8b360635b2 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 10 Jan 2019 18:15:11 +0000 Subject: [PATCH 237/333] build(examples): update tsconfig for commit-table-ssr --- examples/commit-table-ssr/tsconfig.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/commit-table-ssr/tsconfig.json b/examples/commit-table-ssr/tsconfig.json index 50a1cade93..5ecdbdef82 100644 --- a/examples/commit-table-ssr/tsconfig.json +++ b/examples/commit-table-ssr/tsconfig.json @@ -1,8 +1,8 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": ".", - "module": "es6", + "outDir": "./build", + "module": "commonjs", "target": "es6", "sourceMap": true }, From bbe636f486030a4c89124bf1b85a28f6cc52b289 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 10 Jan 2019 18:15:40 +0000 Subject: [PATCH 238/333] fix(examples): add quote escaping in xml-converter --- examples/xml-converter/src/format.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/examples/xml-converter/src/format.ts b/examples/xml-converter/src/format.ts index a8af1729dc..13986f74e7 100644 --- a/examples/xml-converter/src/format.ts +++ b/examples/xml-converter/src/format.ts @@ -59,13 +59,19 @@ const formatVal = (opts: FormatOpts, x: any, indent = true) => x : isPlainObject(x) ? format(indent ? indentState(opts) : opts, "", x) : - opts.quote + x + opts.quote; + opts.quote + escape(opts, x) + opts.quote; // attrib key-value pair formatter w/ indentation const formatPair = (opts: FormatOpts, x: any, k: string) => spaces(opts.indent) + formatAttrib(opts, k) + ":" + opts.ws + formatVal(opts, x[k], k !== "style"); +const escape = + (opts: FormatOpts, x: any) => + opts.quote === "\"" ? + String(x).replace(/"/g, "\\\"") : + String(x).replace(/'/g, "\\\'"); + // multiple-dispatch function to format the transformed tree (hiccup // structure) into a more compact & legible format than produced by // standard: `JSON.stringify(tree, null, 4)` From f6e3cdd56c24f7961664cf24a10774412f6b4c05 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 10 Jan 2019 18:29:43 +0000 Subject: [PATCH 239/333] docs(examples): add troubleshooting notes --- examples/geom-knn/README.md | 4 ++++ examples/geom-tessel/README.md | 4 ++++ examples/gesture-analysis/README.md | 4 ++++ examples/hdom-canvas-shapes/README.md | 4 ++++ examples/xml-converter/README.md | 4 ++++ 5 files changed, 20 insertions(+) diff --git a/examples/geom-knn/README.md b/examples/geom-knn/README.md index b3aa5b1f1c..395bb29744 100644 --- a/examples/geom-knn/README.md +++ b/examples/geom-knn/README.md @@ -14,6 +14,10 @@ Please refer to the [example build instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) on the wiki. +**IMPORTANT:** Please also see the [troubleshooting +note](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions#troubleshooting) +and temporary workaround for this example. + ## Authors - Karsten Schmidt diff --git a/examples/geom-tessel/README.md b/examples/geom-tessel/README.md index 8420136519..ec07408b62 100644 --- a/examples/geom-tessel/README.md +++ b/examples/geom-tessel/README.md @@ -15,6 +15,10 @@ Please refer to the [example build instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) on the wiki. +**IMPORTANT:** Please also see the [troubleshooting +note](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions#troubleshooting) +and temporary workaround for this example. + ## Authors - Karsten Schmidt diff --git a/examples/gesture-analysis/README.md b/examples/gesture-analysis/README.md index ec6374fd8b..1105260ee7 100644 --- a/examples/gesture-analysis/README.md +++ b/examples/gesture-analysis/README.md @@ -14,6 +14,10 @@ Please refer to the [example build instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) on the wiki. +**IMPORTANT:** Please also see the [troubleshooting +note](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions#troubleshooting) +and temporary workaround for this example. + ## Authors - Karsten Schmidt diff --git a/examples/hdom-canvas-shapes/README.md b/examples/hdom-canvas-shapes/README.md index e8c88745e5..7b0b4bcf4a 100644 --- a/examples/hdom-canvas-shapes/README.md +++ b/examples/hdom-canvas-shapes/README.md @@ -38,6 +38,10 @@ Please refer to the [example build instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) on the wiki. +**IMPORTANT:** Please also see the [troubleshooting +note](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions#troubleshooting) +and temporary workaround for this example. + ## Authors - Karsten Schmidt diff --git a/examples/xml-converter/README.md b/examples/xml-converter/README.md index f46fd7a4a9..d60ae94e3e 100644 --- a/examples/xml-converter/README.md +++ b/examples/xml-converter/README.md @@ -23,6 +23,10 @@ Please refer to the [example build instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) on the wiki. +**IMPORTANT:** Please also see the [troubleshooting +note](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions#troubleshooting) +and temporary workaround for this example. + ## CLI version In addition to the above browser UI, this example can be built as a From 6be3a87100d862620f9687d38ae0e3f157951e82 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 10 Jan 2019 18:50:04 +0000 Subject: [PATCH 240/333] build: fix cjs output path in bundle-module script --- scripts/bundle-module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/bundle-module b/scripts/bundle-module index 49cda6ae31..1a804e8120 100755 --- a/scripts/bundle-module +++ b/scripts/bundle-module @@ -50,7 +50,7 @@ const build = !fs.existsSync(".meta") && fs.mkdirSync(".meta"); const cjs = await buildVersion( - "lib/index.cjs.js", + "lib/index.js", { format: "cjs" } From c91df5fceccc377f94a88f1c38600de0e46dc51a Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 10 Jan 2019 19:48:48 +0000 Subject: [PATCH 241/333] build: add test-only yarn script --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 73c16d0d9a..af2dd4ae12 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "doc": "lerna run doc", "examples": "scripts/build-examples", "pub": "lerna publish --registry https://registry.npmjs.org/ && yarn doc && scripts/upload-docs", - "test": "yarn build && lerna run test" + "test": "yarn build && yarn test-only", + "test-only": "lerna run test" } } \ No newline at end of file From ab159105b116437e52986d11c39175a21132d060 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 10 Jan 2019 19:49:12 +0000 Subject: [PATCH 242/333] test(api): fix import in mixin test --- packages/api/test/mixins.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/api/test/mixins.ts b/packages/api/test/mixins.ts index 1c4ee4ece0..70e4798de2 100644 --- a/packages/api/test/mixins.ts +++ b/packages/api/test/mixins.ts @@ -1,13 +1,13 @@ import * as assert from "assert"; import { Event, INotify, EVENT_ALL } from "../src/api"; -import * as mixins from "../src/mixins"; +import { INotifyMixin } from "../src/mixins/inotify"; describe("mixins", () => { it("INotify", () => { - @mixins.INotify + @INotifyMixin class Foo implements INotify { addListener(_: string, __: (e: Event) => void, ___?: any): boolean { throw new Error(); From 4e48cb982ca36b5b9a3b012c6835abf73d1b1bba Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 10 Jan 2019 22:57:20 +0000 Subject: [PATCH 243/333] build(color): build: update package scripts, outputs, imports - enable multi-outputs (ES6, CJS, UMD) --- packages/color/package.json | 29 +++++++++++++++------ packages/color/src/alpha.ts | 2 +- packages/color/src/api.ts | 5 ++-- packages/color/src/clamp.ts | 4 +-- packages/color/src/convert.ts | 2 +- packages/color/src/cosine-gradients.ts | 21 ++++++++------- packages/color/src/css.ts | 2 +- packages/color/src/hcya-rgba.ts | 5 ++-- packages/color/src/hcya.ts | 3 +-- packages/color/src/hsia-rgba.ts | 2 +- packages/color/src/hsia.ts | 3 +-- packages/color/src/hsla-css.ts | 2 +- packages/color/src/hsla-rgba.ts | 4 +-- packages/color/src/hsla.ts | 3 +-- packages/color/src/hsva-rgba.ts | 2 +- packages/color/src/hsva.ts | 3 +-- packages/color/src/hue-rgba.ts | 4 +-- packages/color/src/int-css.ts | 6 ++--- packages/color/src/int-rgba.ts | 4 +-- packages/color/src/int.ts | 2 +- packages/color/src/internal/acolor.ts | 7 +++-- packages/color/src/internal/ensure-alpha.ts | 2 +- packages/color/src/internal/matrix-ops.ts | 8 +++--- packages/color/src/invert.ts | 3 +-- packages/color/src/kelvin-rgba.ts | 2 +- packages/color/src/luminance.ts | 4 +-- packages/color/src/mix.ts | 5 ++-- packages/color/src/parse-css.ts | 8 +++--- packages/color/src/porter-duff.ts | 3 +-- packages/color/src/premultiply.ts | 3 +-- packages/color/src/rgba-css.ts | 4 +-- packages/color/src/rgba-hcva.ts | 5 ++-- packages/color/src/rgba-hcya.ts | 2 +- packages/color/src/rgba-hsia.ts | 10 ++++--- packages/color/src/rgba-hsla.ts | 2 +- packages/color/src/rgba-hsva.ts | 2 +- packages/color/src/rgba-int.ts | 2 +- packages/color/src/rgba-ycbcra.ts | 4 +-- packages/color/src/rgba.ts | 3 +-- packages/color/src/srgba.ts | 4 +-- packages/color/src/transform.ts | 2 +- packages/color/src/xyza.ts | 3 +-- packages/color/src/ycbcr.ts | 3 +-- packages/color/src/ycbcra-rgba.ts | 4 +-- packages/color/test/tsconfig.json | 5 ++-- packages/color/tsconfig.json | 4 ++- 46 files changed, 109 insertions(+), 103 deletions(-) diff --git a/packages/color/package.json b/packages/color/package.json index 720575028c..4a4fde5c60 100644 --- a/packages/color/package.json +++ b/packages/color/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/color", "version": "0.0.1", "description": "TODO", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,19 +14,21 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc internal", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module color api compose defmulti errors math strings transducers vectors3", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib internal", "cover": "yarn test && nyc report --reporter=lcov", - "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "doc": "typedoc --mode modules --out doc src", + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -32,6 +36,7 @@ "@thi.ng/compose": "^0.3.0", "@thi.ng/defmulti": "^0.7.0", "@thi.ng/errors": "^0.1.12", + "@thi.ng/math": "^0.2.2", "@thi.ng/strings": "^0.7.1", "@thi.ng/transducers": "^2.3.2", "@thi.ng/vectors3": "^0.0.1" @@ -61,5 +66,13 @@ ], "publishConfig": { "access": "public" - } + }, + "browserslist": [ + "since 2018-07" + ], + "browser": { + "process": false, + "setTimeout": false + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/color/src/alpha.ts b/packages/color/src/alpha.ts index b79a6d7d33..54d358d36a 100644 --- a/packages/color/src/alpha.ts +++ b/packages/color/src/alpha.ts @@ -1,4 +1,4 @@ -import { setC4 } from "@thi.ng/vectors3/setc"; +import { setC4 } from "@thi.ng/vectors3"; import { Color, ReadonlyColor } from "./api"; export const alpha = diff --git a/packages/color/src/api.ts b/packages/color/src/api.ts index 949091e6b7..70e914a4d3 100644 --- a/packages/color/src/api.ts +++ b/packages/color/src/api.ts @@ -1,6 +1,5 @@ -import { float } from "@thi.ng/strings/float"; -import { percent } from "@thi.ng/strings/percent"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { float, percent } from "@thi.ng/strings"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3"; export type Color = Vec; export type ReadonlyColor = ReadonlyVec; diff --git a/packages/color/src/clamp.ts b/packages/color/src/clamp.ts index 22a7706e80..0143d32a27 100644 --- a/packages/color/src/clamp.ts +++ b/packages/color/src/clamp.ts @@ -1,5 +1,5 @@ -import { clamp01 } from "@thi.ng/math/interval"; -import { setC4 } from "@thi.ng/vectors3/setc"; +import { clamp01 } from "@thi.ng/math"; +import { setC4 } from "@thi.ng/vectors3"; import { Color, ReadonlyColor } from "./api"; import { ensureAlpha } from "./internal/ensure-alpha"; import { ensureHue } from "./internal/ensure-hue"; diff --git a/packages/color/src/convert.ts b/packages/color/src/convert.ts index 45d7bd10b5..126e89b15a 100644 --- a/packages/color/src/convert.ts +++ b/packages/color/src/convert.ts @@ -4,7 +4,7 @@ import { Implementation3, MultiFn2O } from "@thi.ng/defmulti"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { illegalArgs } from "@thi.ng/errors"; import { __ColorMode, Color, diff --git a/packages/color/src/cosine-gradients.ts b/packages/color/src/cosine-gradients.ts index 669c28bb8a..10a1b5dcc9 100644 --- a/packages/color/src/cosine-gradients.ts +++ b/packages/color/src/cosine-gradients.ts @@ -1,13 +1,14 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { partial } from "@thi.ng/compose/partial"; -import { TAU } from "@thi.ng/math/api"; -import { clamp01 } from "@thi.ng/math/interval"; -import { interpolate } from "@thi.ng/transducers/iter/interpolate"; -import { normRange } from "@thi.ng/transducers/iter/norm-range"; -import { tuples } from "@thi.ng/transducers/iter/tuples"; -import { push } from "@thi.ng/transducers/rfn/push"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { map } from "@thi.ng/transducers/xform/map"; +import { IObjectOf } from "@thi.ng/api"; +import { partial } from "@thi.ng/compose"; +import { clamp01, TAU } from "@thi.ng/math"; +import { + interpolate, + map, + normRange, + push, + transduce, + tuples +} from "@thi.ng/transducers"; import { Color, CosGradientSpec, ReadonlyColor } from "./api"; import { clamp } from "./clamp"; diff --git a/packages/color/src/css.ts b/packages/color/src/css.ts index 82a308626d..4ba25b11a4 100644 --- a/packages/color/src/css.ts +++ b/packages/color/src/css.ts @@ -1,4 +1,4 @@ -import { ICopy, IDeref } from "@thi.ng/api/api"; +import { ICopy, IDeref } from "@thi.ng/api"; import { ColorMode, IColor } from "./api"; export const css = diff --git a/packages/color/src/hcya-rgba.ts b/packages/color/src/hcya-rgba.ts index 82a6a1b7e8..fd1ef8b4e7 100644 --- a/packages/color/src/hcya-rgba.ts +++ b/packages/color/src/hcya-rgba.ts @@ -1,6 +1,5 @@ -import { clamp01 } from "@thi.ng/math/interval"; -import { dot3 } from "@thi.ng/vectors3/dot"; -import { setC3 } from "@thi.ng/vectors3/setc"; +import { clamp01 } from "@thi.ng/math"; +import { dot3, setC3 } from "@thi.ng/vectors3"; import { Color, ReadonlyColor, RGB_LUMINANCE } from "./api"; import { hueRgba } from "./hue-rgba"; import { ensureAlpha } from "./internal/ensure-alpha"; diff --git a/packages/color/src/hcya.ts b/packages/color/src/hcya.ts index 9848810b40..a5cd327a0d 100644 --- a/packages/color/src/hcya.ts +++ b/packages/color/src/hcya.ts @@ -1,5 +1,4 @@ -import { IVector } from "@thi.ng/vectors3/api"; -import { declareIndices } from "@thi.ng/vectors3/internal/accessors"; +import { IVector, declareIndices } from "@thi.ng/vectors3"; import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ctor-args"; diff --git a/packages/color/src/hsia-rgba.ts b/packages/color/src/hsia-rgba.ts index f7170aa848..df77bc8c35 100644 --- a/packages/color/src/hsia-rgba.ts +++ b/packages/color/src/hsia-rgba.ts @@ -1,4 +1,4 @@ -import { setC3 } from "@thi.ng/vectors3/setc"; +import { setC3 } from "@thi.ng/vectors3"; import { Color, ReadonlyColor } from "./api"; import { clampH } from "./clamp"; diff --git a/packages/color/src/hsia.ts b/packages/color/src/hsia.ts index ca911f86ab..cfbc66021a 100644 --- a/packages/color/src/hsia.ts +++ b/packages/color/src/hsia.ts @@ -1,5 +1,4 @@ -import { IVector } from "@thi.ng/vectors3/api"; -import { declareIndices } from "@thi.ng/vectors3/internal/accessors"; +import { declareIndices, IVector } from "@thi.ng/vectors3"; import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ctor-args"; diff --git a/packages/color/src/hsla-css.ts b/packages/color/src/hsla-css.ts index 033ea052c1..5182d41401 100644 --- a/packages/color/src/hsla-css.ts +++ b/packages/color/src/hsla-css.ts @@ -1,4 +1,4 @@ -import { clamp01 } from "@thi.ng/math/interval"; +import { clamp01 } from "@thi.ng/math"; import { FF, PC, ReadonlyColor } from "./api"; import { ensureAlpha } from "./internal/ensure-alpha"; import { ensureHue } from "./internal/ensure-hue"; diff --git a/packages/color/src/hsla-rgba.ts b/packages/color/src/hsla-rgba.ts index 01d2ce8b51..79d2b02790 100644 --- a/packages/color/src/hsla-rgba.ts +++ b/packages/color/src/hsla-rgba.ts @@ -1,5 +1,5 @@ -import { clamp01 } from "@thi.ng/math/interval"; -import { setC3 } from "@thi.ng/vectors3/setc"; +import { clamp01 } from "@thi.ng/math"; +import { setC3 } from "@thi.ng/vectors3"; import { Color, ReadonlyColor } from "./api"; import { hueRgba } from "./hue-rgba"; import { ensureAlpha } from "./internal/ensure-alpha"; diff --git a/packages/color/src/hsla.ts b/packages/color/src/hsla.ts index cdc8687bd0..09b326eae4 100644 --- a/packages/color/src/hsla.ts +++ b/packages/color/src/hsla.ts @@ -1,5 +1,4 @@ -import { IVector } from "@thi.ng/vectors3/api"; -import { declareIndices } from "@thi.ng/vectors3/internal/accessors"; +import { declareIndices, IVector } from "@thi.ng/vectors3"; import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ctor-args"; diff --git a/packages/color/src/hsva-rgba.ts b/packages/color/src/hsva-rgba.ts index 74138104a3..cde4befe7c 100644 --- a/packages/color/src/hsva-rgba.ts +++ b/packages/color/src/hsva-rgba.ts @@ -1,4 +1,4 @@ -import { setC3 } from "@thi.ng/vectors3/setc"; +import { setC3 } from "@thi.ng/vectors3"; import { Color, ReadonlyColor } from "./api"; import { clampH } from "./clamp"; import { hueRgba } from "./hue-rgba"; diff --git a/packages/color/src/hsva.ts b/packages/color/src/hsva.ts index d2939f2f7f..cb164b2ffe 100644 --- a/packages/color/src/hsva.ts +++ b/packages/color/src/hsva.ts @@ -1,5 +1,4 @@ -import { IVector } from "@thi.ng/vectors3/api"; -import { declareIndices } from "@thi.ng/vectors3/internal/accessors"; +import { IVector, declareIndices } from "@thi.ng/vectors3"; import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ctor-args"; diff --git a/packages/color/src/hue-rgba.ts b/packages/color/src/hue-rgba.ts index 5e01aea0ad..a3c1544668 100644 --- a/packages/color/src/hue-rgba.ts +++ b/packages/color/src/hue-rgba.ts @@ -1,5 +1,5 @@ -import { clamp01 } from "@thi.ng/math/interval"; -import { setC4 } from "@thi.ng/vectors3/setc"; +import { clamp01 } from "@thi.ng/math"; +import { setC4 } from "@thi.ng/vectors3"; import { Color, Hue } from "./api"; import { ensureHue } from "./internal/ensure-hue"; diff --git a/packages/color/src/int-css.ts b/packages/color/src/int-css.ts index 2d0eec384e..d859808c3a 100644 --- a/packages/color/src/int-css.ts +++ b/packages/color/src/int-css.ts @@ -1,6 +1,6 @@ -import { U24 } from "@thi.ng/strings/radix"; -import { INV8BIT, FF } from "./api"; -import { IDeref } from "@thi.ng/api/api"; +import { IDeref } from "@thi.ng/api"; +import { U24 } from "@thi.ng/strings"; +import { FF, INV8BIT } from "./api"; export const int32Css = (src: number | IDeref) => { diff --git a/packages/color/src/int-rgba.ts b/packages/color/src/int-rgba.ts index 17861a5a56..295442e5bf 100644 --- a/packages/color/src/int-rgba.ts +++ b/packages/color/src/int-rgba.ts @@ -1,6 +1,6 @@ -import { setC4 } from "@thi.ng/vectors3/setc"; +import { IDeref } from "@thi.ng/api"; +import { setC4 } from "@thi.ng/vectors3"; import { Color, INV8BIT } from "./api"; -import { IDeref } from "@thi.ng/api/api"; export const int32Rgba = (out: Color, src: number | IDeref) => { diff --git a/packages/color/src/int.ts b/packages/color/src/int.ts index d96b88ffc8..6637befe8a 100644 --- a/packages/color/src/int.ts +++ b/packages/color/src/int.ts @@ -1,4 +1,4 @@ -import { ICopy, IDeref } from "@thi.ng/api/api"; +import { ICopy, IDeref } from "@thi.ng/api"; import { ColorMode, IColor } from "./api"; /** diff --git a/packages/color/src/internal/acolor.ts b/packages/color/src/internal/acolor.ts index 2a1e4dcd35..79d9c1e907 100644 --- a/packages/color/src/internal/acolor.ts +++ b/packages/color/src/internal/acolor.ts @@ -1,8 +1,7 @@ -import { EPS } from "@thi.ng/math/api"; -import { eqDelta4 } from "@thi.ng/vectors3/eqdelta"; -import { values } from "@thi.ng/vectors3/internal/vec-utils"; +import { IDeref } from "@thi.ng/api"; +import { EPS } from "@thi.ng/math"; +import { eqDelta4, values } from "@thi.ng/vectors3"; import { Color, IColor } from "../api"; -import { IDeref } from "@thi.ng/api/api"; export abstract class AColor implements IColor, diff --git a/packages/color/src/internal/ensure-alpha.ts b/packages/color/src/internal/ensure-alpha.ts index 136efc6acb..0dfed24831 100644 --- a/packages/color/src/internal/ensure-alpha.ts +++ b/packages/color/src/internal/ensure-alpha.ts @@ -1,4 +1,4 @@ -import { clamp01 } from "@thi.ng/math/interval"; +import { clamp01 } from "@thi.ng/math"; export const ensureAlpha = (x: number, def = 1) => diff --git a/packages/color/src/internal/matrix-ops.ts b/packages/color/src/internal/matrix-ops.ts index b3ccd933e5..fd3ca3fe49 100644 --- a/packages/color/src/internal/matrix-ops.ts +++ b/packages/color/src/internal/matrix-ops.ts @@ -1,7 +1,7 @@ -import { dotS3, dotS4 } from "@thi.ng/vectors3/dots"; -import { Color, ReadonlyColor, ColorMatrix } from "../api"; -import { clamp01 } from "@thi.ng/math/interval"; -import { setC4 } from "@thi.ng/vectors3/setc"; +import { clamp01 } from "@thi.ng/math"; +import { dotS3, dotS4 } from "@thi.ng/vectors3"; +import { setC4 } from "@thi.ng/vectors3"; +import { Color, ColorMatrix, ReadonlyColor } from "../api"; import { ensureAlpha } from "./ensure-alpha"; export const mulV33 = diff --git a/packages/color/src/invert.ts b/packages/color/src/invert.ts index eb4cfb44bb..c22ff4e4cb 100644 --- a/packages/color/src/invert.ts +++ b/packages/color/src/invert.ts @@ -1,5 +1,4 @@ -import { ONE3 } from "@thi.ng/vectors3/api"; -import { sub3 } from "@thi.ng/vectors3/sub"; +import { ONE3, sub3 } from "@thi.ng/vectors3"; import { Color, ReadonlyColor } from "./api"; import { clamp } from "./clamp"; diff --git a/packages/color/src/kelvin-rgba.ts b/packages/color/src/kelvin-rgba.ts index 2c5bb049f9..673db7b980 100644 --- a/packages/color/src/kelvin-rgba.ts +++ b/packages/color/src/kelvin-rgba.ts @@ -1,4 +1,4 @@ -import { clamp01 } from "@thi.ng/math/interval"; +import { clamp01 } from "@thi.ng/math"; const G1 = -0.6088425710866344; const G2 = -0.001748900018414868; diff --git a/packages/color/src/luminance.ts b/packages/color/src/luminance.ts index 69bab4cf93..3cfabb1839 100644 --- a/packages/color/src/luminance.ts +++ b/packages/color/src/luminance.ts @@ -1,6 +1,6 @@ import { DEFAULT, defmulti, MultiFn1O } from "@thi.ng/defmulti"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { dot3 } from "@thi.ng/vectors3/dot"; +import { illegalArgs } from "@thi.ng/errors"; +import { dot3 } from "@thi.ng/vectors3"; import { ColorMode, IColor, diff --git a/packages/color/src/mix.ts b/packages/color/src/mix.ts index d13fd79743..991880c29b 100644 --- a/packages/color/src/mix.ts +++ b/packages/color/src/mix.ts @@ -1,7 +1,6 @@ -import { mixN4 } from "@thi.ng/vectors3/mixn"; +import { mix as _mix } from "@thi.ng/math"; +import { mixN4, setC4 } from "@thi.ng/vectors3"; import { Color, ReadonlyColor } from "./api"; -import { setC4 } from "@thi.ng/vectors3/setc"; -import { mix as _mix } from "@thi.ng/math/mix"; export const mix: (out: Color, a: ReadonlyColor, b: ReadonlyColor, t: number) => Color = mixN4; diff --git a/packages/color/src/parse-css.ts b/packages/color/src/parse-css.ts index 61d0b772b3..a7efd3a36a 100644 --- a/packages/color/src/parse-css.ts +++ b/packages/color/src/parse-css.ts @@ -1,10 +1,10 @@ -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { clamp01 } from "@thi.ng/math/interval"; -import { maybeParseFloat, maybeParseInt } from "@thi.ng/strings/parse"; +import { IDeref } from "@thi.ng/api"; +import { illegalArgs } from "@thi.ng/errors"; +import { clamp01 } from "@thi.ng/math"; +import { maybeParseFloat, maybeParseInt } from "@thi.ng/strings"; import { Color, ColorMode, INV8BIT } from "./api"; import { convert } from "./convert"; import { CSS_NAMES } from "./names"; -import { IDeref } from "@thi.ng/api/api"; const RE_HEX = /^#?([0-9a-f]{3,8})$/i; const RE_CSS = /^(rgb|hsl)a?\(\s*([0-9.]+?),\s*([0-9.]+%?),\s*([0-9.]+%?),?\s*([0-9.]+)?\s*\)$/; diff --git a/packages/color/src/porter-duff.ts b/packages/color/src/porter-duff.ts index 1dd3090573..4db003c7b5 100644 --- a/packages/color/src/porter-duff.ts +++ b/packages/color/src/porter-duff.ts @@ -1,5 +1,4 @@ -import { setC4 } from "@thi.ng/vectors3/setc"; -import { setN4 } from "@thi.ng/vectors3/setn"; +import { setC4, setN4 } from "@thi.ng/vectors3"; import { Color, ReadonlyColor } from "./api"; import { postmultiply, premultiply } from "./premultiply"; diff --git a/packages/color/src/premultiply.ts b/packages/color/src/premultiply.ts index 574340c5ed..43355711e9 100644 --- a/packages/color/src/premultiply.ts +++ b/packages/color/src/premultiply.ts @@ -1,6 +1,5 @@ +import { set, setC4 } from "@thi.ng/vectors3"; import { Color, ReadonlyColor } from "./api"; -import { set } from "@thi.ng/vectors3/set"; -import { setC4 } from "@thi.ng/vectors3/setc"; /** * RGBA only. Multiplies RGB channels w/ alpha channel. Assumes alpha is diff --git a/packages/color/src/rgba-css.ts b/packages/color/src/rgba-css.ts index 3f5dae89ee..9423234004 100644 --- a/packages/color/src/rgba-css.ts +++ b/packages/color/src/rgba-css.ts @@ -1,5 +1,5 @@ -import { clamp01 } from "@thi.ng/math/interval"; -import { U24 } from "@thi.ng/strings/radix"; +import { clamp01 } from "@thi.ng/math"; +import { U24 } from "@thi.ng/strings"; import { FF, ReadonlyColor } from "./api"; import { ensureAlpha } from "./internal/ensure-alpha"; diff --git a/packages/color/src/rgba-hcva.ts b/packages/color/src/rgba-hcva.ts index d27d2afa50..cce29153a4 100644 --- a/packages/color/src/rgba-hcva.ts +++ b/packages/color/src/rgba-hcva.ts @@ -1,6 +1,5 @@ -import { EPS } from "@thi.ng/math/api"; -import { clamp01 } from "@thi.ng/math/interval"; -import { setC3 } from "@thi.ng/vectors3/setc"; +import { EPS, clamp01 } from "@thi.ng/math"; +import { setC3 } from "@thi.ng/vectors3"; import { Color, ReadonlyColor } from "./api"; import { clamp } from "./clamp"; diff --git a/packages/color/src/rgba-hcya.ts b/packages/color/src/rgba-hcya.ts index 368ee8495c..34de0347c1 100644 --- a/packages/color/src/rgba-hcya.ts +++ b/packages/color/src/rgba-hcya.ts @@ -1,4 +1,4 @@ -import { EPS } from "@thi.ng/math/api"; +import { EPS } from "@thi.ng/math"; import { Color, ReadonlyColor } from "./api"; import { hueRgba } from "./hue-rgba"; import { luminanceRGB } from "./luminance"; diff --git a/packages/color/src/rgba-hsia.ts b/packages/color/src/rgba-hsia.ts index 1b5aa687b5..e0b6470265 100644 --- a/packages/color/src/rgba-hsia.ts +++ b/packages/color/src/rgba-hsia.ts @@ -1,8 +1,12 @@ -import { setC3 } from "@thi.ng/vectors3/setc"; +import { + atan2Abs, + SQRT3, + TAU, + THIRD +} from "@thi.ng/math"; +import { setC3 } from "@thi.ng/vectors3"; import { Color, ReadonlyColor } from "./api"; import { clamp } from "./clamp"; -import { SQRT3, THIRD, TAU } from "@thi.ng/math/api"; -import { atan2Abs } from "@thi.ng/math/angle"; // https://en.wikipedia.org/wiki/HSL_and_HSV#Hue_and_chroma diff --git a/packages/color/src/rgba-hsla.ts b/packages/color/src/rgba-hsla.ts index e93da12c8a..7e14ec95c0 100644 --- a/packages/color/src/rgba-hsla.ts +++ b/packages/color/src/rgba-hsla.ts @@ -1,4 +1,4 @@ -import { EPS } from "@thi.ng/math/api"; +import { EPS } from "@thi.ng/math"; import { Color, ReadonlyColor } from "./api"; import { rgbaHcva } from "./rgba-hcva"; diff --git a/packages/color/src/rgba-hsva.ts b/packages/color/src/rgba-hsva.ts index fd35fc20d5..bda9a16f54 100644 --- a/packages/color/src/rgba-hsva.ts +++ b/packages/color/src/rgba-hsva.ts @@ -1,4 +1,4 @@ -import { EPS } from "@thi.ng/math/api"; +import { EPS } from "@thi.ng/math"; import { Color, ReadonlyColor } from "./api"; import { rgbaHcva } from "./rgba-hcva"; diff --git a/packages/color/src/rgba-int.ts b/packages/color/src/rgba-int.ts index 2e3d8a2a67..431bbb5cef 100644 --- a/packages/color/src/rgba-int.ts +++ b/packages/color/src/rgba-int.ts @@ -1,4 +1,4 @@ -import { clamp01 } from "@thi.ng/math/interval"; +import { clamp01 } from "@thi.ng/math"; import { ReadonlyColor } from "./api"; import { ensureAlpha } from "./internal/ensure-alpha"; diff --git a/packages/color/src/rgba-ycbcra.ts b/packages/color/src/rgba-ycbcra.ts index fc4245bb7b..923e5ab5a9 100644 --- a/packages/color/src/rgba-ycbcra.ts +++ b/packages/color/src/rgba-ycbcra.ts @@ -1,7 +1,7 @@ +import { setC3 } from "@thi.ng/vectors3"; import { Color, ReadonlyColor } from "./api"; -import { luminanceRGB } from "./luminance"; -import { setC3 } from "@thi.ng/vectors3/setc"; import { clamp } from "./clamp"; +import { luminanceRGB } from "./luminance"; export const rgbaYcbcra = (out: Color, src: ReadonlyColor) => { diff --git a/packages/color/src/rgba.ts b/packages/color/src/rgba.ts index 73cdbbebe5..3c324ecbbc 100644 --- a/packages/color/src/rgba.ts +++ b/packages/color/src/rgba.ts @@ -1,5 +1,4 @@ -import { IVector } from "@thi.ng/vectors3/api"; -import { declareIndices } from "@thi.ng/vectors3/internal/accessors"; +import { declareIndices, IVector } from "@thi.ng/vectors3"; import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ctor-args"; diff --git a/packages/color/src/srgba.ts b/packages/color/src/srgba.ts index 8d9049928f..c71f9915bc 100644 --- a/packages/color/src/srgba.ts +++ b/packages/color/src/srgba.ts @@ -1,5 +1,5 @@ -import { SRGB_ALPHA, ReadonlyColor, Color } from "./api"; -import { setC4 } from "@thi.ng/vectors3/setc"; +import { setC4 } from "@thi.ng/vectors3"; +import { Color, ReadonlyColor, SRGB_ALPHA } from "./api"; import { ensureAlpha } from "./internal/ensure-alpha"; /** diff --git a/packages/color/src/transform.ts b/packages/color/src/transform.ts index dc63c343af..e18ecb3fb3 100644 --- a/packages/color/src/transform.ts +++ b/packages/color/src/transform.ts @@ -1,4 +1,4 @@ -import { mix } from "@thi.ng/math/mix"; +import { mix } from "@thi.ng/math"; import { ColorMatrix, RGB_LUMINANCE, ReadonlyColor, WHITE } from "./api"; import { mulV45, mulM45 } from "./internal/matrix-ops"; diff --git a/packages/color/src/xyza.ts b/packages/color/src/xyza.ts index aa727f8a7f..386aec9c1f 100644 --- a/packages/color/src/xyza.ts +++ b/packages/color/src/xyza.ts @@ -1,5 +1,4 @@ -import { IVector } from "@thi.ng/vectors3/api"; -import { declareIndices } from "@thi.ng/vectors3/internal/accessors"; +import { declareIndices, IVector } from "@thi.ng/vectors3"; import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ctor-args"; diff --git a/packages/color/src/ycbcr.ts b/packages/color/src/ycbcr.ts index 3af05b2803..da59fbac57 100644 --- a/packages/color/src/ycbcr.ts +++ b/packages/color/src/ycbcr.ts @@ -1,5 +1,4 @@ -import { IVector } from "@thi.ng/vectors3/api"; -import { declareIndices } from "@thi.ng/vectors3/internal/accessors"; +import { declareIndices, IVector } from "@thi.ng/vectors3"; import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ctor-args"; diff --git a/packages/color/src/ycbcra-rgba.ts b/packages/color/src/ycbcra-rgba.ts index 77a4cc8a06..3b6cbdce1f 100644 --- a/packages/color/src/ycbcra-rgba.ts +++ b/packages/color/src/ycbcra-rgba.ts @@ -1,5 +1,5 @@ -import { clamp01 } from "@thi.ng/math/interval"; -import { setC4 } from "@thi.ng/vectors3/setc"; +import { clamp01 } from "@thi.ng/math"; +import { setC4 } from "@thi.ng/vectors3"; import { Color, ReadonlyColor } from "./api"; import { ensureAlpha } from "./internal/ensure-alpha"; diff --git a/packages/color/test/tsconfig.json b/packages/color/test/tsconfig.json index bcf29ace54..2c9c12a650 100644 --- a/packages/color/test/tsconfig.json +++ b/packages/color/test/tsconfig.json @@ -1,10 +1,11 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "commonjs", }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/color/tsconfig.json b/packages/color/tsconfig.json index f6c291a0a0..bcf03f18b4 100644 --- a/packages/color/tsconfig.json +++ b/packages/color/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" From e247386c716aa4189ec321e8d4b9d802fb41f34e Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 10 Jan 2019 22:59:21 +0000 Subject: [PATCH 244/333] build(geom): build: update package scripts, outputs, imports - enable multi-outputs (ES6, CJS, UMD) --- packages/geom2/package.json | 30 +++++++++---- packages/geom2/src/api.ts | 29 ++++++------ packages/geom2/src/arc.ts | 41 +++++++++-------- packages/geom2/src/bezier.ts | 25 ++++++----- packages/geom2/src/circle.ts | 33 +++++++------- packages/geom2/src/container2.ts | 4 +- packages/geom2/src/ellipse.ts | 20 +++++---- packages/geom2/src/internal/arc-length.ts | 3 +- packages/geom2/src/internal/arc.ts | 6 +-- packages/geom2/src/internal/barycentric.ts | 17 ++++--- packages/geom2/src/internal/bounds.ts | 13 +++--- packages/geom2/src/internal/centroid.ts | 15 ++++--- packages/geom2/src/internal/circumcenter.ts | 4 +- packages/geom2/src/internal/closest-point.ts | 19 ++++---- packages/geom2/src/internal/corner.ts | 6 +-- packages/geom2/src/internal/direction.ts | 11 +++-- .../internal/douglas\342\200\223peucker.ts" | 7 ++- packages/geom2/src/internal/edges.ts | 20 ++++----- packages/geom2/src/internal/graham-scan.ts | 4 +- .../geom2/src/internal/greiner-hormann.ts | 6 +-- packages/geom2/src/internal/liang-barsky.ts | 4 +- .../geom2/src/internal/line-intersection.ts | 6 +-- packages/geom2/src/internal/offset.ts | 4 +- packages/geom2/src/internal/perimeter.ts | 3 +- packages/geom2/src/internal/polygon.ts | 3 +- packages/geom2/src/internal/sampler.ts | 17 ++++--- packages/geom2/src/internal/subdiv-curve.ts | 25 +++++++---- .../geom2/src/internal/sutherland-hodgeman.ts | 2 +- packages/geom2/src/internal/transform.ts | 5 +-- packages/geom2/src/internal/warp.ts | 2 +- packages/geom2/src/line.ts | 13 +++--- packages/geom2/src/path.ts | 44 ++++++++++--------- packages/geom2/src/polygon.ts | 41 +++++++++-------- packages/geom2/src/polyline.ts | 9 ++-- packages/geom2/src/quad.ts | 11 +++-- packages/geom2/src/ray.ts | 3 +- packages/geom2/src/rect.ts | 19 ++++---- packages/geom2/src/sphere.ts | 14 +++--- packages/geom2/src/svg.ts | 4 +- packages/geom2/src/tessellate.ts | 39 +++++++++------- packages/geom2/src/triangle.ts | 25 ++++++----- packages/geom2/test/circle.ts | 5 +-- packages/geom2/test/tsconfig.json | 5 ++- packages/geom2/tsconfig.json | 6 ++- 44 files changed, 342 insertions(+), 280 deletions(-) diff --git a/packages/geom2/package.json b/packages/geom2/package.json index 437793d235..7650e93fe3 100644 --- a/packages/geom2/package.json +++ b/packages/geom2/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/geom2", "version": "0.0.1", "description": "TODO", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,30 +14,34 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc internal", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module geom2 api checks defmulti equiv hiccup hiccup-svg malloc math matrices transducers vectors3", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", - "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "doc": "typedoc --mode modules --out doc src", + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { "@thi.ng/api": "^4.2.4", "@thi.ng/checks": "^1.5.14", "@thi.ng/defmulti": "^0.7.0", + "@thi.ng/equiv": "^0.1.15", "@thi.ng/hiccup": "^2.7.2", "@thi.ng/hiccup-svg": "^2.0.10", "@thi.ng/malloc": "^0.2.1", "@thi.ng/math": "^0.2.2", "@thi.ng/matrices": "^0.0.1", + "@thi.ng/transducers": "^2.3.2", "@thi.ng/vectors3": "^0.0.1" }, "keywords": [ @@ -44,5 +50,13 @@ ], "publishConfig": { "access": "public" - } + }, + "browserslist": [ + "since 2018-07" + ], + "browser": { + "process": false, + "setTimeout": false + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/geom2/src/api.ts b/packages/geom2/src/api.ts index bad2a46a54..d331dcf99d 100644 --- a/packages/geom2/src/api.ts +++ b/packages/geom2/src/api.ts @@ -12,19 +12,22 @@ import { MultiFn2O } from "@thi.ng/defmulti"; import { equiv } from "@thi.ng/equiv"; -import { cossin } from "@thi.ng/math/angle"; -import { ReadonlyMat } from "@thi.ng/matrices/api"; -import { add } from "@thi.ng/vectors3/add"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { copy } from "@thi.ng/vectors3/copy"; -import { max } from "@thi.ng/vectors3/max"; -import { min } from "@thi.ng/vectors3/min"; -import { mixN } from "@thi.ng/vectors3/mixn"; -import { mul } from "@thi.ng/vectors3/mul"; -import { neg } from "@thi.ng/vectors3/neg"; -import { perpendicularLeft2 } from "@thi.ng/vectors3/perpendicular"; -import { rotateZ } from "@thi.ng/vectors3/rotate"; -import { sub } from "@thi.ng/vectors3/sub"; +import { cossin } from "@thi.ng/math"; +import { ReadonlyMat } from "@thi.ng/matrices"; +import { + add, + copy, + max, + min, + mixN, + mul, + neg, + perpendicularLeft2, + ReadonlyVec, + rotateZ, + sub, + Vec +} from "@thi.ng/vectors3"; import { subdivKernel3 } from "./internal/subdiv-curve"; import { warpPoints } from "./internal/warp"; diff --git a/packages/geom2/src/arc.ts b/packages/geom2/src/arc.ts index 24e6bf4491..53df122f67 100644 --- a/packages/geom2/src/arc.ts +++ b/packages/geom2/src/arc.ts @@ -1,37 +1,40 @@ -import { isNumber } from "@thi.ng/checks/is-number"; -import { isPlainObject } from "@thi.ng/checks/is-plain-object"; +import { isNumber, isPlainObject } from "@thi.ng/checks"; import { implementations } from "@thi.ng/defmulti"; -import { sincos } from "@thi.ng/math/angle"; import { EPS, + fit01, HALF_PI, + inRange, PI, + roundEps, + sincos, TAU -} from "@thi.ng/math/api"; -import { fit01 } from "@thi.ng/math/fit"; -import { inRange } from "@thi.ng/math/interval"; -import { roundEps } from "@thi.ng/math/prec"; -import { range } from "@thi.ng/transducers/iter/range"; -import { push } from "@thi.ng/transducers/rfn/push"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { filter } from "@thi.ng/transducers/xform/filter"; -import { map } from "@thi.ng/transducers/xform/map"; -import { abs2 } from "@thi.ng/vectors3/abs"; -import { add2 } from "@thi.ng/vectors3/add"; -import { angleBetween } from "@thi.ng/vectors3/angle-between"; +} from "@thi.ng/math"; import { + filter, + map, + push, + range, + transduce +} from "@thi.ng/transducers"; +import { + abs2, + add2, + angleBetween, + magSq2, MAX2, MIN2, + mulN2, ReadonlyVec, + sub2, Vec, X2 -} from "@thi.ng/vectors3/api"; -import { magSq2 } from "@thi.ng/vectors3/magsq"; -import { mulN2 } from "@thi.ng/vectors3/muln"; -import { sub2 } from "@thi.ng/vectors3/sub"; +} from "@thi.ng/vectors3"; import "./bezier"; import { bounds as _bounds } from "./internal/bounds"; import { Sampler } from "./internal/sampler"; +import { } from "@thi.ng/math"; +import { } from "@thi.ng/vectors3"; import { Arc2, asCubic, diff --git a/packages/geom2/src/bezier.ts b/packages/geom2/src/bezier.ts index 64df4bbf12..fd9b37c6eb 100644 --- a/packages/geom2/src/bezier.ts +++ b/packages/geom2/src/bezier.ts @@ -1,10 +1,17 @@ import { isNumber } from "@thi.ng/checks/is-number"; import { isPlainObject } from "@thi.ng/checks/is-plain-object"; import { implementations } from "@thi.ng/defmulti"; -import { clamp01 } from "@thi.ng/math/interval"; -import { mixCubic as _mixC, mixQuadratic as _mixQ } from "@thi.ng/math/mix"; -import { Vec } from "@thi.ng/vectors3/api"; -import { Mat } from "@thi.ng/matrices/api"; +import { clamp01, mixCubic as _mixC, mixQuadratic as _mixQ } from "@thi.ng/math"; +import { Mat } from "@thi.ng/matrices"; +import { + copy, + max, + min, + mixCubic, + mixN, + mixQuadratic, + Vec +} from "@thi.ng/vectors3"; import { asCubic, asPolyline, @@ -12,6 +19,7 @@ import { bounds, Cubic2, DEFAULT_SAMPLES, + flip, pointAt, Polyline2, Quadratic2, @@ -20,17 +28,10 @@ import { splitAt, transform, Type, - vertices, - flip + vertices } from "./api"; import { Sampler } from "./internal/sampler"; import { transformPoints } from "./internal/transform"; -import { mixCubic } from "@thi.ng/vectors3/mix-cubic"; -import { mixQuadratic } from "@thi.ng/vectors3/mix-quadratic"; -import { copy } from "@thi.ng/vectors3/copy"; -import { mixN } from "@thi.ng/vectors3/mixn"; -import { min } from "@thi.ng/vectors3/min"; -import { max } from "@thi.ng/vectors3/max"; export function cubic2(points: Vec[], attribs?: Attribs): Cubic2 { return new Cubic2(points, attribs); diff --git a/packages/geom2/src/circle.ts b/packages/geom2/src/circle.ts index a58e1bd4bf..506e767f8a 100644 --- a/packages/geom2/src/circle.ts +++ b/packages/geom2/src/circle.ts @@ -1,24 +1,27 @@ -import { isNumber } from "@thi.ng/checks/is-number"; +import { isNumber } from "@thi.ng/checks"; import { implementations } from "@thi.ng/defmulti"; -import { sign } from "@thi.ng/math/abs"; -import { cossin } from "@thi.ng/math/angle"; import { + cossin, EPS, HALF_PI, PI, + sign, TAU -} from "@thi.ng/math/api"; -import { add2 } from "@thi.ng/vectors3/add"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { cartesian2 } from "@thi.ng/vectors3/cartesian"; -import { copy } from "@thi.ng/vectors3/copy"; -import { dist } from "@thi.ng/vectors3/dist"; -import { distSq2 } from "@thi.ng/vectors3/distsq"; -import { mixN2 } from "@thi.ng/vectors3/mixn"; -import { mulN2 } from "@thi.ng/vectors3/muln"; -import { normalize } from "@thi.ng/vectors3/normalize"; -import { sub2 } from "@thi.ng/vectors3/sub"; -import { subN2 } from "@thi.ng/vectors3/subn"; +} from "@thi.ng/math"; +import { + add2, + cartesian2, + copy, + dist, + distSq2, + mixN2, + mulN2, + normalize, + ReadonlyVec, + sub2, + subN2, + Vec +} from "@thi.ng/vectors3"; import { arcLength, area, diff --git a/packages/geom2/src/container2.ts b/packages/geom2/src/container2.ts index 39a679d652..c21053754c 100644 --- a/packages/geom2/src/container2.ts +++ b/packages/geom2/src/container2.ts @@ -1,6 +1,6 @@ import { implementations } from "@thi.ng/defmulti"; -import { Mat } from "@thi.ng/matrices/api"; -import { MAX2, MIN2, Vec } from "@thi.ng/vectors3/api"; +import { Mat } from "@thi.ng/matrices"; +import { MAX2, MIN2, Vec } from "@thi.ng/vectors3"; import { Attribs, bounds, diff --git a/packages/geom2/src/ellipse.ts b/packages/geom2/src/ellipse.ts index 67b5117f22..af3f1103d7 100644 --- a/packages/geom2/src/ellipse.ts +++ b/packages/geom2/src/ellipse.ts @@ -1,13 +1,15 @@ -import { isNumber } from "@thi.ng/checks/is-number"; +import { isNumber } from "@thi.ng/checks"; import { implementations } from "@thi.ng/defmulti"; -import { cossin } from "@thi.ng/math/angle"; -import { PI, TAU } from "@thi.ng/math/api"; -import { add2 } from "@thi.ng/vectors3/add"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { copy } from "@thi.ng/vectors3/copy"; -import { madd2 } from "@thi.ng/vectors3/madd"; -import { mulN2 } from "@thi.ng/vectors3/muln"; -import { sub2 } from "@thi.ng/vectors3/sub"; +import { cossin, PI, TAU } from "@thi.ng/math"; +import { + add2, + copy, + madd2, + mulN2, + ReadonlyVec, + sub2, + Vec +} from "@thi.ng/vectors3"; import { arcLength, area, diff --git a/packages/geom2/src/internal/arc-length.ts b/packages/geom2/src/internal/arc-length.ts index a5536bf54e..5791bd7d6f 100644 --- a/packages/geom2/src/internal/arc-length.ts +++ b/packages/geom2/src/internal/arc-length.ts @@ -1,5 +1,4 @@ -import { ReadonlyVec } from "@thi.ng/vectors3/api"; -import { dist } from "@thi.ng/vectors3/dist"; +import { ReadonlyVec, dist } from "@thi.ng/vectors3"; export const arcLength = (pts: ReadonlyVec[], closed = false) => { const num = pts.length; diff --git a/packages/geom2/src/internal/arc.ts b/packages/geom2/src/internal/arc.ts index 5dff2c5d1a..3844ff219f 100644 --- a/packages/geom2/src/internal/arc.ts +++ b/packages/geom2/src/internal/arc.ts @@ -1,7 +1,5 @@ -import { atan2Abs, cossin } from "@thi.ng/math/angle"; -import { TAU } from "@thi.ng/math/api"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { madd } from "@thi.ng/vectors3/madd"; +import { atan2Abs, cossin, TAU } from "@thi.ng/math"; +import { ReadonlyVec, Vec, madd } from "@thi.ng/vectors3"; export const arcVertices = ( o: ReadonlyVec, diff --git a/packages/geom2/src/internal/barycentric.ts b/packages/geom2/src/internal/barycentric.ts index 76130a1f7d..e5505186f0 100644 --- a/packages/geom2/src/internal/barycentric.ts +++ b/packages/geom2/src/internal/barycentric.ts @@ -1,10 +1,13 @@ -import { eqDelta } from "@thi.ng/math/eqdelta"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { dot } from "@thi.ng/vectors3/dot"; -import { maddN } from "@thi.ng/vectors3/maddn"; -import { mulN } from "@thi.ng/vectors3/muln"; -import { zero } from "@thi.ng/vectors3/setn"; -import { sub } from "@thi.ng/vectors3/sub"; +import { eqDelta } from "@thi.ng/math"; +import { + dot, + maddN, + mulN, + ReadonlyVec, + sub, + Vec, + zero +} from "@thi.ng/vectors3"; export const toBarycentric = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, p: ReadonlyVec, out: Vec = []) => { diff --git a/packages/geom2/src/internal/bounds.ts b/packages/geom2/src/internal/bounds.ts index 17ce076de0..a5ba6451f1 100644 --- a/packages/geom2/src/internal/bounds.ts +++ b/packages/geom2/src/internal/bounds.ts @@ -1,8 +1,11 @@ -import { add } from "@thi.ng/vectors3/add"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { max } from "@thi.ng/vectors3/max"; -import { min } from "@thi.ng/vectors3/min"; -import { sub } from "@thi.ng/vectors3/sub"; +import { + add, + max, + min, + ReadonlyVec, + sub, + Vec +} from "@thi.ng/vectors3"; import { bounds as _bounds, IShape, union } from "../api"; export const bounds = diff --git a/packages/geom2/src/internal/centroid.ts b/packages/geom2/src/internal/centroid.ts index 34ee9bc271..c6552910bc 100644 --- a/packages/geom2/src/internal/centroid.ts +++ b/packages/geom2/src/internal/centroid.ts @@ -1,9 +1,12 @@ -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { cross2 } from "@thi.ng/vectors3/cross"; -import { empty } from "@thi.ng/vectors3/empty"; -import { add } from "@thi.ng/vectors3/add"; -import { divN } from "@thi.ng/vectors3/divn"; +import { illegalArgs } from "@thi.ng/errors"; +import { + add, + cross2, + divN, + empty, + ReadonlyVec, + Vec +} from "@thi.ng/vectors3"; export const centroid = (pts: ReadonlyVec[], c?: Vec) => { diff --git a/packages/geom2/src/internal/circumcenter.ts b/packages/geom2/src/internal/circumcenter.ts index f2217896f1..a96a1bef5d 100644 --- a/packages/geom2/src/internal/circumcenter.ts +++ b/packages/geom2/src/internal/circumcenter.ts @@ -1,5 +1,5 @@ -import { EPS } from "@thi.ng/math/api"; -import { ReadonlyVec } from "@thi.ng/vectors3/api"; +import { EPS } from "@thi.ng/math"; +import { ReadonlyVec } from "@thi.ng/vectors3"; export const circumCenter = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, eps = EPS) => { diff --git a/packages/geom2/src/internal/closest-point.ts b/packages/geom2/src/internal/closest-point.ts index c085aa6826..97b738b4c1 100644 --- a/packages/geom2/src/internal/closest-point.ts +++ b/packages/geom2/src/internal/closest-point.ts @@ -1,11 +1,14 @@ -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { distSq } from "@thi.ng/vectors3/distsq"; -import { dot } from "@thi.ng/vectors3/dot"; -import { empty } from "@thi.ng/vectors3/empty"; -import { magSq } from "@thi.ng/vectors3/magsq"; -import { mixN } from "@thi.ng/vectors3/mixn"; -import { set } from "@thi.ng/vectors3/set"; -import { sub } from "@thi.ng/vectors3/sub"; +import { + distSq, + dot, + empty, + magSq, + mixN, + ReadonlyVec, + set, + sub, + Vec +} from "@thi.ng/vectors3"; export const closestPoint = (p: ReadonlyVec, pts: Vec[]) => { diff --git a/packages/geom2/src/internal/corner.ts b/packages/geom2/src/internal/corner.ts index 9394756620..aa4d7c6de4 100644 --- a/packages/geom2/src/internal/corner.ts +++ b/packages/geom2/src/internal/corner.ts @@ -1,7 +1,5 @@ -import { sign } from "@thi.ng/math/abs"; -import { EPS } from "@thi.ng/math/api"; -import { ReadonlyVec } from "@thi.ng/vectors3/api"; -import { signedArea2 } from "@thi.ng/vectors3/signed-area"; +import { EPS, sign } from "@thi.ng/math"; +import { ReadonlyVec, signedArea2 } from "@thi.ng/vectors3"; export const classify = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, eps = EPS) => diff --git a/packages/geom2/src/internal/direction.ts b/packages/geom2/src/internal/direction.ts index 487391c27f..9c521ab5d0 100644 --- a/packages/geom2/src/internal/direction.ts +++ b/packages/geom2/src/internal/direction.ts @@ -1,7 +1,10 @@ -import { ReadonlyVec } from "@thi.ng/vectors3/api"; -import { normalize } from "@thi.ng/vectors3/normalize"; -import { perpendicularLeft2, perpendicularRight2 } from "@thi.ng/vectors3/perpendicular"; -import { sub } from "@thi.ng/vectors3/sub"; +import { + normalize, + perpendicularLeft2, + perpendicularRight2, + ReadonlyVec, + sub +} from "@thi.ng/vectors3"; export const direction = (a: ReadonlyVec, b: ReadonlyVec, n = 1) => diff --git "a/packages/geom2/src/internal/douglas\342\200\223peucker.ts" "b/packages/geom2/src/internal/douglas\342\200\223peucker.ts" index 2e3fcf7db3..4a2636ef6b 100644 --- "a/packages/geom2/src/internal/douglas\342\200\223peucker.ts" +++ "b/packages/geom2/src/internal/douglas\342\200\223peucker.ts" @@ -1,7 +1,6 @@ -import { EPS } from "@thi.ng/math/api"; -import { peek } from "@thi.ng/transducers/func/peek"; -import { Vec } from "@thi.ng/vectors3/api"; -import { eqDelta } from "@thi.ng/vectors3/eqdelta"; +import { EPS } from "@thi.ng/math"; +import { peek } from "@thi.ng/transducers"; +import { eqDelta, Vec } from "@thi.ng/vectors3"; import { farthestPointSegment } from "./closest-point"; // https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm diff --git a/packages/geom2/src/internal/edges.ts b/packages/geom2/src/internal/edges.ts index 188a55e420..014278115d 100644 --- a/packages/geom2/src/internal/edges.ts +++ b/packages/geom2/src/internal/edges.ts @@ -1,12 +1,12 @@ -import { wrap } from "@thi.ng/transducers/iter/wrap"; -import { partition } from "@thi.ng/transducers/xform/partition"; +import { partition, wrap } from "@thi.ng/transducers"; +import { Vec } from "@thi.ng/vectors3"; import { VecPair } from "../api"; -import { Vec } from "@thi.ng/vectors3/api"; -export const edges = (vertices: Iterable, closed = false) => - >partition( - 2, 1, - closed ? - wrap(vertices, 1, false, true) : - vertices - ); +export const edges = + (vertices: Iterable, closed = false) => + >partition( + 2, 1, + closed ? + wrap(vertices, 1, false, true) : + vertices + ); diff --git a/packages/geom2/src/internal/graham-scan.ts b/packages/geom2/src/internal/graham-scan.ts index 42252fb3ad..0298ddaf1d 100644 --- a/packages/geom2/src/internal/graham-scan.ts +++ b/packages/geom2/src/internal/graham-scan.ts @@ -1,6 +1,4 @@ -import { Vec } from "@thi.ng/vectors3/api"; -import { comparator2 } from "@thi.ng/vectors3/compare"; -import { signedArea2 } from "@thi.ng/vectors3/signed-area"; +import { comparator2, signedArea2, Vec } from "@thi.ng/vectors3"; /** * Returns array of points defining the 2D Convex Hull of `pts` using diff --git a/packages/geom2/src/internal/greiner-hormann.ts b/packages/geom2/src/internal/greiner-hormann.ts index b35e1d9600..c783bc5d1f 100644 --- a/packages/geom2/src/internal/greiner-hormann.ts +++ b/packages/geom2/src/internal/greiner-hormann.ts @@ -1,7 +1,7 @@ -import { ICopy } from "@thi.ng/api/api"; +import { ICopy } from "@thi.ng/api"; import { equivArrayLike } from "@thi.ng/equiv"; -import { mapcat } from "@thi.ng/transducers/xform/mapcat"; -import { Vec } from "@thi.ng/vectors3/api"; +import { mapcat } from "@thi.ng/transducers"; +import { Vec } from "@thi.ng/vectors3"; import { ClipMode, LineIntersectionType, VecPair } from "../api"; import { edges as _edges } from "./edges"; import { intersectLines2 } from "./line-intersection"; diff --git a/packages/geom2/src/internal/liang-barsky.ts b/packages/geom2/src/internal/liang-barsky.ts index 29bb3bee91..0b69ecf34f 100644 --- a/packages/geom2/src/internal/liang-barsky.ts +++ b/packages/geom2/src/internal/liang-barsky.ts @@ -1,5 +1,5 @@ -import { EPS } from "@thi.ng/math/api"; -import { Vec } from "@thi.ng/vectors3/api"; +import { EPS } from "@thi.ng/math"; +import { Vec } from "@thi.ng/vectors3"; // https://en.wikipedia.org/wiki/Liang%E2%80%93Barsky_algorithm // https://github.com/thi-ng/c-thing/blob/master/src/geom/clip/liangbarsky.c diff --git a/packages/geom2/src/internal/line-intersection.ts b/packages/geom2/src/internal/line-intersection.ts index 7e53562390..a6c9b38cd6 100644 --- a/packages/geom2/src/internal/line-intersection.ts +++ b/packages/geom2/src/internal/line-intersection.ts @@ -1,7 +1,5 @@ -import { EPS } from "@thi.ng/math/api"; -import { eqDelta } from "@thi.ng/math/eqdelta"; -import { ReadonlyVec } from "@thi.ng/vectors3/api"; -import { mixN2 } from "@thi.ng/vectors3/mixn"; +import { EPS, eqDelta } from "@thi.ng/math"; +import { mixN2, ReadonlyVec } from "@thi.ng/vectors3"; import { LineIntersection, LineIntersectionType } from "../api"; import { closestPointSegment } from "./closest-point"; diff --git a/packages/geom2/src/internal/offset.ts b/packages/geom2/src/internal/offset.ts index f2344a0760..f8a55dea0e 100644 --- a/packages/geom2/src/internal/offset.ts +++ b/packages/geom2/src/internal/offset.ts @@ -1,6 +1,4 @@ -import { add2 } from "@thi.ng/vectors3/add"; -import { Vec } from "@thi.ng/vectors3/api"; -import { sub2 } from "@thi.ng/vectors3/sub"; +import { add2, sub2, Vec } from "@thi.ng/vectors3"; import { ClipMode, VecPair } from "../api"; import { arcVertices } from "./arc"; import { normalL2 } from "./direction"; diff --git a/packages/geom2/src/internal/perimeter.ts b/packages/geom2/src/internal/perimeter.ts index 5d838313c3..e81d9bd169 100644 --- a/packages/geom2/src/internal/perimeter.ts +++ b/packages/geom2/src/internal/perimeter.ts @@ -1,5 +1,4 @@ -import { ReadonlyVec } from "@thi.ng/vectors3/api"; -import { dist } from "@thi.ng/vectors3/dist"; +import { dist, ReadonlyVec } from "@thi.ng/vectors3"; export const perimeter = (pts: ReadonlyVec[], closed = false) => { diff --git a/packages/geom2/src/internal/polygon.ts b/packages/geom2/src/internal/polygon.ts index 2f4ae24b29..ee50f225a3 100644 --- a/packages/geom2/src/internal/polygon.ts +++ b/packages/geom2/src/internal/polygon.ts @@ -1,5 +1,4 @@ -import { ReadonlyVec } from "@thi.ng/vectors3/api"; -import { cross2 } from "@thi.ng/vectors3/cross"; +import { cross2, ReadonlyVec } from "@thi.ng/vectors3"; export const polygonArea = (pts: ReadonlyVec[]) => { diff --git a/packages/geom2/src/internal/sampler.ts b/packages/geom2/src/internal/sampler.ts index 552db9fbe9..a054923558 100644 --- a/packages/geom2/src/internal/sampler.ts +++ b/packages/geom2/src/internal/sampler.ts @@ -1,10 +1,13 @@ -import { peek } from "@thi.ng/transducers/func/peek"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { copy } from "@thi.ng/vectors3/copy"; -import { dist } from "@thi.ng/vectors3/dist"; -import { mixN } from "@thi.ng/vectors3/mixn"; -import { normalize } from "@thi.ng/vectors3/normalize"; -import { sub } from "@thi.ng/vectors3/sub"; +import { peek } from "@thi.ng/transducers"; +import { + copy, + dist, + mixN, + normalize, + ReadonlyVec, + sub, + Vec +} from "@thi.ng/vectors3"; import { VecPair } from "../api"; export class Sampler { diff --git a/packages/geom2/src/internal/subdiv-curve.ts b/packages/geom2/src/internal/subdiv-curve.ts index 9515455c68..72893976c9 100644 --- a/packages/geom2/src/internal/subdiv-curve.ts +++ b/packages/geom2/src/internal/subdiv-curve.ts @@ -1,12 +1,19 @@ -import { comp } from "@thi.ng/transducers/func/comp"; -import { wrap } from "@thi.ng/transducers/iter/wrap"; -import { push } from "@thi.ng/transducers/rfn/push"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { indexed } from "@thi.ng/transducers/xform/indexed"; -import { mapcat } from "@thi.ng/transducers/xform/mapcat"; -import { partition } from "@thi.ng/transducers/xform/partition"; -import { addW2, addW3, addW5 } from "@thi.ng/vectors3/addw"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { + comp, + indexed, + mapcat, + partition, + push, + transduce, + wrap +} from "@thi.ng/transducers"; +import { + addW2, + addW3, + addW5, + ReadonlyVec, + Vec +} from "@thi.ng/vectors3"; import { SubdivKernel } from "../api"; export const subdivKernel2 = diff --git a/packages/geom2/src/internal/sutherland-hodgeman.ts b/packages/geom2/src/internal/sutherland-hodgeman.ts index 73d141a1aa..202ef7deae 100644 --- a/packages/geom2/src/internal/sutherland-hodgeman.ts +++ b/packages/geom2/src/internal/sutherland-hodgeman.ts @@ -1,4 +1,4 @@ -import { ReadonlyVec } from "@thi.ng/vectors3/api"; +import { ReadonlyVec } from "@thi.ng/vectors3"; import { classify } from "./corner"; import { intersectLines2 } from "./line-intersection"; diff --git a/packages/geom2/src/internal/transform.ts b/packages/geom2/src/internal/transform.ts index f43255be68..0f02d2dbe3 100644 --- a/packages/geom2/src/internal/transform.ts +++ b/packages/geom2/src/internal/transform.ts @@ -1,6 +1,5 @@ -import { Mat } from "@thi.ng/matrices/api"; -import { mulV } from "@thi.ng/matrices/mulv"; -import { ReadonlyVec } from "@thi.ng/vectors3/api"; +import { Mat, mulV } from "@thi.ng/matrices"; +import { ReadonlyVec } from "@thi.ng/vectors3"; export const transformPoints = (pts: ReadonlyVec[], mat: Mat) => pts.map((p) => mulV([], mat, p)); diff --git a/packages/geom2/src/internal/warp.ts b/packages/geom2/src/internal/warp.ts index 0363277a2e..30c9b9dfe3 100644 --- a/packages/geom2/src/internal/warp.ts +++ b/packages/geom2/src/internal/warp.ts @@ -1,4 +1,4 @@ -import { ReadonlyVec } from "@thi.ng/vectors3/api"; +import { ReadonlyVec } from "@thi.ng/vectors3"; import { IShape, mapPoint, unmapPoint } from "../api"; export const warpPoints = diff --git a/packages/geom2/src/line.ts b/packages/geom2/src/line.ts index f8a82aecfb..f33abed00b 100644 --- a/packages/geom2/src/line.ts +++ b/packages/geom2/src/line.ts @@ -1,9 +1,12 @@ import { implementations } from "@thi.ng/defmulti"; -import { Mat } from "@thi.ng/matrices/api"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { dist } from "@thi.ng/vectors3/dist"; -import { mixN } from "@thi.ng/vectors3/mixn"; -import { sub } from "@thi.ng/vectors3/sub"; +import { Mat } from "@thi.ng/matrices"; +import { + dist, + mixN, + ReadonlyVec, + sub, + Vec +} from "@thi.ng/vectors3"; import { arcLength, asCubic, diff --git a/packages/geom2/src/path.ts b/packages/geom2/src/path.ts index 61406d7bfa..da9c27997f 100644 --- a/packages/geom2/src/path.ts +++ b/packages/geom2/src/path.ts @@ -1,22 +1,28 @@ -import { isNumber } from "@thi.ng/checks/is-number"; +import { isNumber } from "@thi.ng/checks"; import { implementations } from "@thi.ng/defmulti"; -import { rad } from "@thi.ng/math/angle"; -import { eqDelta } from "@thi.ng/math/eqdelta"; -import { Mat } from "@thi.ng/matrices/api"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { ensureArray } from "@thi.ng/transducers/func/ensure-array"; -import { peek } from "@thi.ng/transducers/func/peek"; -import { iterator1 } from "@thi.ng/transducers/iterator"; -import { filter } from "@thi.ng/transducers/xform/filter"; -import { map } from "@thi.ng/transducers/xform/map"; -import { mapcat } from "@thi.ng/transducers/xform/mapcat"; -import { add2, add } from "@thi.ng/vectors3/add"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { maddN } from "@thi.ng/vectors3/maddn"; -import { mulV } from "@thi.ng/matrices/mulv"; -import { zeroes } from "@thi.ng/vectors3/setn"; -import { mulN2 } from "@thi.ng/vectors3/muln"; -import { set2 } from "@thi.ng/vectors3/set"; +import { eqDelta, rad } from "@thi.ng/math"; +import { Mat, mulV } from "@thi.ng/matrices"; +import { + comp, + ensureArray, + filter, + iterator1, + map, + mapcat, + peek +} from "@thi.ng/transducers"; +import { + add, + add2, + copy, + maddN, + mulN2, + ReadonlyVec, + set2, + sub2, + Vec, + zeroes +} from "@thi.ng/vectors3"; import { Arc2, asCubic, @@ -45,8 +51,6 @@ import { collBounds } from "./internal/bounds"; import "./polygon"; import "./polyline"; import { douglasPeucker2 } from "./internal/douglas–peucker"; -import { copy } from "@thi.ng/vectors3/copy"; -import { sub2 } from "@thi.ng/vectors3/sub"; const CMD_RE = /[achlmqstvz]/i; diff --git a/packages/geom2/src/polygon.ts b/packages/geom2/src/polygon.ts index 010ed29586..d436f146da 100644 --- a/packages/geom2/src/polygon.ts +++ b/packages/geom2/src/polygon.ts @@ -1,21 +1,26 @@ -import { isPlainObject } from "@thi.ng/checks/is-plain-object"; +import { isPlainObject } from "@thi.ng/checks"; import { implementations } from "@thi.ng/defmulti"; -import { TAU } from "@thi.ng/math/api"; -import { Mat } from "@thi.ng/matrices/api"; -import { Reducer } from "@thi.ng/transducers/api"; -import { cycle } from "@thi.ng/transducers/iter/cycle"; -import { normRange } from "@thi.ng/transducers/iter/norm-range"; -import { tuples } from "@thi.ng/transducers/iter/tuples"; -import { wrap } from "@thi.ng/transducers/iter/wrap"; -import { reduced } from "@thi.ng/transducers/reduced"; -import { push } from "@thi.ng/transducers/rfn/push"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { map } from "@thi.ng/transducers/xform/map"; -import { partition } from "@thi.ng/transducers/xform/partition"; -import { add2 } from "@thi.ng/vectors3/add"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { cartesian2 } from "@thi.ng/vectors3/cartesian"; -import { signedArea2 } from "@thi.ng/vectors3/signed-area"; +import { TAU } from "@thi.ng/math"; +import { Mat } from "@thi.ng/matrices"; +import { + cycle, + map, + normRange, + partition, + push, + reduced, + Reducer, + transduce, + tuples, + wrap +} from "@thi.ng/transducers"; +import { + add2, + cartesian2, + ReadonlyVec, + signedArea2, + Vec +} from "@thi.ng/vectors3"; import { arcLength, area, @@ -52,6 +57,7 @@ import { vertices } from "./api"; import "./container2"; +import { arcLength as _arcLength } from "./internal/arc-length"; import { centerOfWeight2 } from "./internal/centroid"; import { edges as _edges } from "./internal/edges"; import { booleanOp } from "./internal/greiner-hormann"; @@ -64,7 +70,6 @@ import { sutherlandHodgeman } from "./internal/sutherland-hodgeman"; import { transformPoints } from "./internal/transform"; import { tessellatePoints } from "./tessellate"; import { douglasPeucker2 } from "./internal/douglas–peucker"; -import { arcLength as _arcLength } from "./internal/arc-length"; export function polygon(points: Vec[], attribs?: Attribs): Polygon2 { return new Polygon2(points, attribs); diff --git a/packages/geom2/src/polyline.ts b/packages/geom2/src/polyline.ts index f18d2ebad1..63aaaf4a5b 100644 --- a/packages/geom2/src/polyline.ts +++ b/packages/geom2/src/polyline.ts @@ -1,9 +1,8 @@ -import { isPlainObject } from "@thi.ng/checks/is-plain-object"; +import { isPlainObject } from "@thi.ng/checks"; import { implementations } from "@thi.ng/defmulti"; -import { Mat } from "@thi.ng/matrices/api"; -import { map } from "@thi.ng/transducers/xform/map"; -import { add2 } from "@thi.ng/vectors3/add"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { Mat } from "@thi.ng/matrices"; +import { map } from "@thi.ng/transducers"; +import { add2, ReadonlyVec, Vec } from "@thi.ng/vectors3"; import { arcLength, asCubic, diff --git a/packages/geom2/src/quad.ts b/packages/geom2/src/quad.ts index 8e34f977e7..517cbda445 100644 --- a/packages/geom2/src/quad.ts +++ b/packages/geom2/src/quad.ts @@ -1,8 +1,11 @@ import { implementations } from "@thi.ng/defmulti"; -import { Mat } from "@thi.ng/matrices/api"; -import { add2 } from "@thi.ng/vectors3/add"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { mixBilinear2 } from "@thi.ng/vectors3/mix-bilinear"; +import { Mat } from "@thi.ng/matrices"; +import { + add2, + mixBilinear2, + ReadonlyVec, + Vec +} from "@thi.ng/vectors3"; import { arcLength, area, diff --git a/packages/geom2/src/ray.ts b/packages/geom2/src/ray.ts index 3f5f9eb4f0..8cd3b51df7 100644 --- a/packages/geom2/src/ray.ts +++ b/packages/geom2/src/ray.ts @@ -1,6 +1,5 @@ import { implementations } from "@thi.ng/defmulti"; -import { Vec } from "@thi.ng/vectors3/api"; -import { maddN } from "@thi.ng/vectors3/maddn"; +import { maddN, Vec } from "@thi.ng/vectors3"; import { pointAt, Ray, Type } from "./api"; export const ray = diff --git a/packages/geom2/src/rect.ts b/packages/geom2/src/rect.ts index 71e99817fe..f414352eab 100644 --- a/packages/geom2/src/rect.ts +++ b/packages/geom2/src/rect.ts @@ -1,12 +1,15 @@ import { implementations } from "@thi.ng/defmulti"; -import { Mat } from "@thi.ng/matrices/api"; -import { add2 } from "@thi.ng/vectors3/add"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { copy } from "@thi.ng/vectors3/copy"; -import { div2 } from "@thi.ng/vectors3/div"; -import { madd2 } from "@thi.ng/vectors3/madd"; -import { maddN2 } from "@thi.ng/vectors3/maddn"; -import { sub } from "@thi.ng/vectors3/sub"; +import { Mat } from "@thi.ng/matrices"; +import { + add2, + copy, + div2, + madd2, + maddN2, + ReadonlyVec, + sub, + Vec +} from "@thi.ng/vectors3"; import { arcLength, area, diff --git a/packages/geom2/src/sphere.ts b/packages/geom2/src/sphere.ts index 527a42c2f6..9ddbd5ee43 100644 --- a/packages/geom2/src/sphere.ts +++ b/packages/geom2/src/sphere.ts @@ -1,15 +1,17 @@ -import { Vec } from "@thi.ng/vectors3/api"; -import { dot3 } from "@thi.ng/vectors3/dot"; -import { maddN3 } from "@thi.ng/vectors3/maddn"; -import { magSq3 } from "@thi.ng/vectors3/magsq"; -import { sub3 } from "@thi.ng/vectors3/sub"; +import { + distSq3, + dot3, + maddN3, + magSq3, + sub3, + Vec +} from "@thi.ng/vectors3"; import { intersectShape, Ray, Sphere, Type, } from "./api"; -import { distSq3 } from "@thi.ng/vectors3/distsq"; export const sphere = (pos: Vec, r = 1) => new Sphere(pos, r); diff --git a/packages/geom2/src/svg.ts b/packages/geom2/src/svg.ts index 648eda46ef..d2297d0555 100644 --- a/packages/geom2/src/svg.ts +++ b/packages/geom2/src/svg.ts @@ -1,7 +1,5 @@ import { serialize } from "@thi.ng/hiccup"; -import { convertTree } from "@thi.ng/hiccup-svg/convert"; -import { ff } from "@thi.ng/hiccup-svg/format"; -import { svg } from "@thi.ng/hiccup-svg/svg"; +import { convertTree, ff, svg } from "@thi.ng/hiccup-svg"; import { Attribs, IShape, Rect2 } from "./api"; import { collBounds } from "./internal/bounds"; diff --git a/packages/geom2/src/tessellate.ts b/packages/geom2/src/tessellate.ts index 6815524d35..3da971eed4 100644 --- a/packages/geom2/src/tessellate.ts +++ b/packages/geom2/src/tessellate.ts @@ -1,20 +1,25 @@ -import { isFunction } from "@thi.ng/checks/is-function"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { range } from "@thi.ng/transducers/iter/range"; -import { repeat } from "@thi.ng/transducers/iter/repeat"; -import { tuples } from "@thi.ng/transducers/iter/tuples"; -import { wrap } from "@thi.ng/transducers/iter/wrap"; -import { reducer } from "@thi.ng/transducers/reduce"; -import { last } from "@thi.ng/transducers/rfn/last"; -import { push } from "@thi.ng/transducers/rfn/push"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { map } from "@thi.ng/transducers/xform/map"; -import { mapcat } from "@thi.ng/transducers/xform/mapcat"; -import { partition } from "@thi.ng/transducers/xform/partition"; -import { scan } from "@thi.ng/transducers/xform/scan"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { mixN } from "@thi.ng/vectors3/mixn"; -import { signedArea2 } from "@thi.ng/vectors3/signed-area"; +import { isFunction } from "@thi.ng/checks"; +import { + comp, + last, + map, + mapcat, + partition, + push, + range, + reducer, + repeat, + scan, + transduce, + tuples, + wrap +} from "@thi.ng/transducers"; +import { + mixN, + ReadonlyVec, + signedArea2, + Vec +} from "@thi.ng/vectors3"; import { Tessellator } from "./api"; import { centroid } from "./internal/centroid"; import { pointInTriangle2 } from "./internal/corner"; diff --git a/packages/geom2/src/triangle.ts b/packages/geom2/src/triangle.ts index d48ea690c4..09f86ee779 100644 --- a/packages/geom2/src/triangle.ts +++ b/packages/geom2/src/triangle.ts @@ -1,15 +1,18 @@ import { implementations } from "@thi.ng/defmulti"; -import { PI } from "@thi.ng/math/api"; -import { Mat } from "@thi.ng/matrices/api"; -import { add } from "@thi.ng/vectors3/add"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { divN } from "@thi.ng/vectors3/divn"; -import { maddN } from "@thi.ng/vectors3/maddn"; -import { mag } from "@thi.ng/vectors3/mag"; -import { normalize } from "@thi.ng/vectors3/normalize"; -import { perpendicularLeft2 } from "@thi.ng/vectors3/perpendicular"; -import { signedArea2 } from "@thi.ng/vectors3/signed-area"; -import { sub } from "@thi.ng/vectors3/sub"; +import { PI } from "@thi.ng/math"; +import { Mat } from "@thi.ng/matrices"; +import { + add, + divN, + maddN, + mag, + normalize, + perpendicularLeft2, + ReadonlyVec, + signedArea2, + sub, + Vec +} from "@thi.ng/vectors3"; import { arcLength, area, diff --git a/packages/geom2/test/circle.ts b/packages/geom2/test/circle.ts index 71c39c3476..5638b7393b 100644 --- a/packages/geom2/test/circle.ts +++ b/packages/geom2/test/circle.ts @@ -1,7 +1,6 @@ import { equiv } from "@thi.ng/equiv"; -import { HALF_PI, PI, TAU } from "@thi.ng/math/api"; -import { Vec } from "@thi.ng/vectors2/api"; -import { eqDeltaArray } from "@thi.ng/vectors2/internal/equiv"; +import { HALF_PI, PI, TAU } from "@thi.ng/math"; +import { eqDeltaArray, Vec } from "@thi.ng/vectors3"; import * as assert from "assert"; import { area, diff --git a/packages/geom2/test/tsconfig.json b/packages/geom2/test/tsconfig.json index bcf29ace54..2c9c12a650 100644 --- a/packages/geom2/test/tsconfig.json +++ b/packages/geom2/test/tsconfig.json @@ -1,10 +1,11 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "commonjs", }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/geom2/tsconfig.json b/packages/geom2/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/geom2/tsconfig.json +++ b/packages/geom2/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file From 5d25c1ae3812b986673966f19b42ceac2e5f31b7 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 10 Jan 2019 23:01:55 +0000 Subject: [PATCH 245/333] build(matrices): build: update package scripts, outputs, imports - enable multi-outputs (ES6, CJS, UMD) --- packages/matrices/package.json | 28 +++++++++++++------ packages/matrices/src/add.ts | 2 +- packages/matrices/src/addn.ts | 2 +- packages/matrices/src/alignment-quat.ts | 12 ++++---- packages/matrices/src/api.ts | 2 +- packages/matrices/src/column.ts | 8 ++++-- packages/matrices/src/concat.ts | 2 +- packages/matrices/src/conjugate.ts | 3 +- packages/matrices/src/determinant.ts | 2 +- packages/matrices/src/diag.ts | 3 +- packages/matrices/src/div.ts | 2 +- packages/matrices/src/divn.ts | 2 +- packages/matrices/src/frustum.ts | 4 +-- packages/matrices/src/identity.ts | 2 +- packages/matrices/src/index.ts | 1 + packages/matrices/src/internal/codegen.ts | 7 +++-- packages/matrices/src/invert.ts | 16 +++++++---- packages/matrices/src/lookat.ts | 14 ++++++---- packages/matrices/src/m33-m44.ts | 3 +- packages/matrices/src/m44-m33.ts | 2 +- packages/matrices/src/mixq.ts | 13 +++++---- packages/matrices/src/mul.ts | 2 +- packages/matrices/src/mulm.ts | 12 ++++++-- packages/matrices/src/muln.ts | 2 +- packages/matrices/src/mulq.ts | 3 +- packages/matrices/src/mulv.ts | 15 +++++++--- packages/matrices/src/ortho.ts | 2 +- packages/matrices/src/project.ts | 11 +++++--- packages/matrices/src/quat-axis-angle.ts | 5 ++-- packages/matrices/src/quat-euler.ts | 2 +- packages/matrices/src/quat-m33.ts | 3 +- packages/matrices/src/quat-m44.ts | 8 ++++-- packages/matrices/src/rotation-around-axis.ts | 3 +- packages/matrices/src/rotation.ts | 4 +-- packages/matrices/src/row.ts | 8 ++++-- packages/matrices/src/scale-center.ts | 3 +- packages/matrices/src/scale.ts | 10 +++++-- packages/matrices/src/set.ts | 9 ++++-- packages/matrices/src/sub.ts | 2 +- packages/matrices/src/subn.ts | 2 +- packages/matrices/src/trace.ts | 2 +- packages/matrices/src/translation.ts | 3 +- packages/matrices/src/transpose.ts | 2 +- packages/matrices/src/viewport.ts | 2 +- packages/matrices/test/tsconfig.json | 5 ++-- packages/matrices/tsconfig.json | 6 ++-- 46 files changed, 156 insertions(+), 100 deletions(-) diff --git a/packages/matrices/package.json b/packages/matrices/package.json index d0302e7181..855ec8ebc1 100644 --- a/packages/matrices/package.json +++ b/packages/matrices/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/matrices", "version": "0.0.1", "description": "Matrix & quaternion operations for 2D/3D geometry processing", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,19 +14,21 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module matrices api checks math vectors3", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", - "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "doc": "typedoc --mode modules --out doc src", + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -65,5 +69,13 @@ ], "publishConfig": { "access": "public" - } + }, + "browserslist": [ + "since 2018-07" + ], + "browser": { + "process": false, + "setTimeout": false + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/matrices/src/add.ts b/packages/matrices/src/add.ts index 3e8e6c23fa..22076ee8c1 100644 --- a/packages/matrices/src/add.ts +++ b/packages/matrices/src/add.ts @@ -1,4 +1,4 @@ -import { add as _add, add4 } from "@thi.ng/vectors3/add"; +import { add as _add, add4 } from "@thi.ng/vectors3"; import { MatOpMM, MultiMatOpMM } from "./api"; import { defMath } from "./internal/codegen"; diff --git a/packages/matrices/src/addn.ts b/packages/matrices/src/addn.ts index 32fc89d702..6ff41e2581 100644 --- a/packages/matrices/src/addn.ts +++ b/packages/matrices/src/addn.ts @@ -1,4 +1,4 @@ -import { addN as _addN, addN4 } from "@thi.ng/vectors3/addn"; +import { addN as _addN, addN4 } from "@thi.ng/vectors3"; import { MatOpMN, MultiMatOpMN } from "./api"; import { defMathN } from "./internal/codegen"; diff --git a/packages/matrices/src/alignment-quat.ts b/packages/matrices/src/alignment-quat.ts index 2f2a116b28..086f6edb18 100644 --- a/packages/matrices/src/alignment-quat.ts +++ b/packages/matrices/src/alignment-quat.ts @@ -1,9 +1,11 @@ -import { ReadonlyVec } from "@thi.ng/vectors3/api"; -import { normalize as _normalize } from "@thi.ng/vectors3/normalize"; -import { cross3 } from "@thi.ng/vectors3/cross"; +import { + cross3, + dot3, + mag, + normalize as _normalize, + ReadonlyVec +} from "@thi.ng/vectors3"; import { quatFromAxisAngle } from "./quat-axis-angle"; -import { dot3 } from "@thi.ng/vectors3/dot"; -import { mag } from "@thi.ng/vectors3/mag"; export const alignmentQuat = (from: ReadonlyVec, to: ReadonlyVec, normalize = true) => { diff --git a/packages/matrices/src/api.ts b/packages/matrices/src/api.ts index 6786b681d1..a769b7959c 100644 --- a/packages/matrices/src/api.ts +++ b/packages/matrices/src/api.ts @@ -1,4 +1,4 @@ -import { Vec, ReadonlyVec, IVector, MultiVecOp } from "@thi.ng/vectors3/api"; +import { Vec, ReadonlyVec, IVector, MultiVecOp } from "@thi.ng/vectors3"; export type Mat = Vec; export type ReadonlyMat = ReadonlyVec; diff --git a/packages/matrices/src/column.ts b/packages/matrices/src/column.ts index fcd815824c..a8614d341e 100644 --- a/packages/matrices/src/column.ts +++ b/packages/matrices/src/column.ts @@ -1,5 +1,9 @@ -import { vop } from "@thi.ng/vectors3/internal/vop"; -import { setS2, setS3, setS4 } from "@thi.ng/vectors3/sets"; +import { + setS2, + setS3, + setS4, + vop +} from "@thi.ng/vectors3"; import { MultiVecOpMN, VecOpMN } from "./api"; export const column: MultiVecOpMN = vop(1); diff --git a/packages/matrices/src/concat.ts b/packages/matrices/src/concat.ts index 9ba087a280..5c1d8dca9f 100644 --- a/packages/matrices/src/concat.ts +++ b/packages/matrices/src/concat.ts @@ -1,5 +1,5 @@ import { Mat, ReadonlyMat } from "./api"; -import { mulM } from "./mulM"; +import { mulM } from "./mulm"; export const concat = (out: Mat, a: ReadonlyMat, b: ReadonlyMat, ...xs: ReadonlyMat[]) => diff --git a/packages/matrices/src/conjugate.ts b/packages/matrices/src/conjugate.ts index 9ddda8e39d..cbbdacaa15 100644 --- a/packages/matrices/src/conjugate.ts +++ b/packages/matrices/src/conjugate.ts @@ -1,5 +1,4 @@ -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { setC4 } from "@thi.ng/vectors3/setc"; +import { ReadonlyVec, setC4, Vec } from "@thi.ng/vectors3"; export const conjugateQ = (out: Vec, a: ReadonlyVec) => diff --git a/packages/matrices/src/determinant.ts b/packages/matrices/src/determinant.ts index 72d66abd1c..3eda23b170 100644 --- a/packages/matrices/src/determinant.ts +++ b/packages/matrices/src/determinant.ts @@ -1,4 +1,4 @@ -import { dotC4, dotC6 } from "@thi.ng/vectors3/dotc"; +import { dotC4, dotC6 } from "@thi.ng/vectors3"; import { ReadonlyMat } from "./api"; const dp4 = dotC4; diff --git a/packages/matrices/src/diag.ts b/packages/matrices/src/diag.ts index a392ffd9fe..ef9667d1ef 100644 --- a/packages/matrices/src/diag.ts +++ b/packages/matrices/src/diag.ts @@ -1,5 +1,4 @@ -import { vop } from "@thi.ng/vectors3/internal/vop"; -import { setS2, setS3, setS4 } from "@thi.ng/vectors3/sets"; +import { vop, setS2, setS3, setS4 } from "@thi.ng/vectors3"; import { MultiVecOpM } from "./api"; export const diag: MultiVecOpM = vop(1); diff --git a/packages/matrices/src/div.ts b/packages/matrices/src/div.ts index 22a69bb051..43a9177d59 100644 --- a/packages/matrices/src/div.ts +++ b/packages/matrices/src/div.ts @@ -1,4 +1,4 @@ -import { div as _div, div4 } from "@thi.ng/vectors3/div"; +import { div as _div, div4 } from "@thi.ng/vectors3"; import { MatOpMM, MultiMatOpMM } from "./api"; import { defMath } from "./internal/codegen"; diff --git a/packages/matrices/src/divn.ts b/packages/matrices/src/divn.ts index deae8796cb..01e7eeef8b 100644 --- a/packages/matrices/src/divn.ts +++ b/packages/matrices/src/divn.ts @@ -1,4 +1,4 @@ -import { divN as _divN, divN4 } from "@thi.ng/vectors3/divn"; +import { divN as _divN, divN4 } from "@thi.ng/vectors3"; import { MatOpMN, MultiMatOpMN } from "./api"; import { defMathN } from "./internal/codegen"; diff --git a/packages/matrices/src/frustum.ts b/packages/matrices/src/frustum.ts index 60023cf340..ff22cfbef4 100644 --- a/packages/matrices/src/frustum.ts +++ b/packages/matrices/src/frustum.ts @@ -1,5 +1,5 @@ -import { DEG2RAD } from "@thi.ng/math/api"; -import { setC } from "@thi.ng/vectors3/setc"; +import { DEG2RAD } from "@thi.ng/math"; +import { setC } from "@thi.ng/vectors3"; import { Mat } from "./api"; export const frustum = ( diff --git a/packages/matrices/src/identity.ts b/packages/matrices/src/identity.ts index 02e6bb81c9..40dcb9c1bc 100644 --- a/packages/matrices/src/identity.ts +++ b/packages/matrices/src/identity.ts @@ -1,4 +1,4 @@ -import { vop } from "@thi.ng/vectors3/internal/vop"; +import { vop } from "@thi.ng/vectors3"; import { IDENT22, IDENT23, diff --git a/packages/matrices/src/index.ts b/packages/matrices/src/index.ts index 6f7c72b0f9..44d4d6cd64 100644 --- a/packages/matrices/src/index.ts +++ b/packages/matrices/src/index.ts @@ -1,4 +1,5 @@ export * from "./api"; +export * from "./internal/codegen"; export * from "./add"; export * from "./addn"; diff --git a/packages/matrices/src/internal/codegen.ts b/packages/matrices/src/internal/codegen.ts index dc1b1d3368..b94cf8e38d 100644 --- a/packages/matrices/src/internal/codegen.ts +++ b/packages/matrices/src/internal/codegen.ts @@ -2,9 +2,10 @@ import { ARGS_VN, ARGS_VV, compile, - DEFAULT_OUT -} from "@thi.ng/vectors3/internal/codegen"; -import { MATH, MATH_N } from "@thi.ng/vectors3/internal/templates"; + DEFAULT_OUT, + MATH, + MATH_N +} from "@thi.ng/vectors3"; import { MultiMatOpMM, MultiMatOpMN } from "../api"; const DEFAULT_SIZES = [6, 9, 16]; diff --git a/packages/matrices/src/invert.ts b/packages/matrices/src/invert.ts index aaadebf8fd..cc63a73097 100644 --- a/packages/matrices/src/invert.ts +++ b/packages/matrices/src/invert.ts @@ -1,8 +1,14 @@ -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { dotC4, dotC6 } from "@thi.ng/vectors3/dotc"; -import { vop } from "@thi.ng/vectors3/internal/vop"; -import { magSq4 } from "@thi.ng/vectors3/magsq"; -import { setC, setC4, setC6 } from "@thi.ng/vectors3/setc"; +import { + dotC4, + dotC6, + magSq4, + ReadonlyVec, + setC, + setC4, + setC6, + Vec, + vop +} from "@thi.ng/vectors3"; import { MatOpM, MultiMatOpM } from "./api"; import { det44FromCoeffs, detCoeffs44 } from "./determinant"; diff --git a/packages/matrices/src/lookat.ts b/packages/matrices/src/lookat.ts index 31c0dc0afb..559a976963 100644 --- a/packages/matrices/src/lookat.ts +++ b/packages/matrices/src/lookat.ts @@ -1,9 +1,11 @@ -import { ReadonlyVec } from "@thi.ng/vectors3/api"; -import { cross3 } from "@thi.ng/vectors3/cross"; -import { dot3 } from "@thi.ng/vectors3/dot"; -import { normalize } from "@thi.ng/vectors3/normalize"; -import { setC } from "@thi.ng/vectors3/setc"; -import { sub3 } from "@thi.ng/vectors3/sub"; +import { + cross3, + dot3, + normalize, + ReadonlyVec, + setC, + sub3 +} from "@thi.ng/vectors3"; import { Mat } from "./api"; export const lookAt = ( diff --git a/packages/matrices/src/m33-m44.ts b/packages/matrices/src/m33-m44.ts index 0862fa66b7..933a932fd2 100644 --- a/packages/matrices/src/m33-m44.ts +++ b/packages/matrices/src/m33-m44.ts @@ -1,5 +1,4 @@ -import { ZERO4 } from "@thi.ng/vectors3/api"; -import { setS3, setS4 } from "@thi.ng/vectors3/sets"; +import { setS3, setS4, ZERO4 } from "@thi.ng/vectors3"; import { MatOpM } from "./api"; export const mat33to44: MatOpM = diff --git a/packages/matrices/src/m44-m33.ts b/packages/matrices/src/m44-m33.ts index 35f63a376d..340782bcbe 100644 --- a/packages/matrices/src/m44-m33.ts +++ b/packages/matrices/src/m44-m33.ts @@ -1,4 +1,4 @@ -import { setS3 } from "@thi.ng/vectors3/sets"; +import { setS3 } from "@thi.ng/vectors3"; import { MatOpM } from "./api"; export const mat44to33: MatOpM = diff --git a/packages/matrices/src/mixq.ts b/packages/matrices/src/mixq.ts index 04832bf342..f85c8c707f 100644 --- a/packages/matrices/src/mixq.ts +++ b/packages/matrices/src/mixq.ts @@ -1,8 +1,11 @@ -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { dot4 } from "@thi.ng/vectors3/dot"; -import { maddN4 } from "@thi.ng/vectors3/maddn"; -import { mulN4 } from "@thi.ng/vectors3/muln"; -import { set4 } from "@thi.ng/vectors3/set"; +import { + dot4, + maddN4, + mulN4, + ReadonlyVec, + set4, + Vec +} from "@thi.ng/vectors3"; export const mixQ = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, t: number, eps = 1e-3) => { diff --git a/packages/matrices/src/mul.ts b/packages/matrices/src/mul.ts index fdb9ba6258..04364392fa 100644 --- a/packages/matrices/src/mul.ts +++ b/packages/matrices/src/mul.ts @@ -1,4 +1,4 @@ -import { mul as _mul, mul4 } from "@thi.ng/vectors3/mul"; +import { mul as _mul, mul4 } from "@thi.ng/vectors3"; import { MatOpMM, MultiMatOpMM } from "./api"; import { defMath } from "./internal/codegen"; diff --git a/packages/matrices/src/mulm.ts b/packages/matrices/src/mulm.ts index 3148c654e4..1537193cda 100644 --- a/packages/matrices/src/mulm.ts +++ b/packages/matrices/src/mulm.ts @@ -1,6 +1,12 @@ -import { dotS2, dotS3, dotS4 } from "@thi.ng/vectors3/dots"; -import { vop } from "@thi.ng/vectors3/internal/vop"; -import { setC, setC4, setC6 } from "@thi.ng/vectors3/setc"; +import { + dotS2, + dotS3, + dotS4, + setC, + setC4, + setC6, + vop +} from "@thi.ng/vectors3"; import { MultiMatOpMM } from "./api"; export const mulM: MultiMatOpMM = vop(1); diff --git a/packages/matrices/src/muln.ts b/packages/matrices/src/muln.ts index 23fe1d003d..be938739b6 100644 --- a/packages/matrices/src/muln.ts +++ b/packages/matrices/src/muln.ts @@ -1,4 +1,4 @@ -import { mulN as _mulN, mulN4 } from "@thi.ng/vectors3/muln"; +import { mulN as _mulN, mulN4 } from "@thi.ng/vectors3"; import { MatOpMN, MultiMatOpMN } from "./api"; import { defMathN } from "./internal/codegen"; diff --git a/packages/matrices/src/mulq.ts b/packages/matrices/src/mulq.ts index be70ef56bf..046807c949 100644 --- a/packages/matrices/src/mulq.ts +++ b/packages/matrices/src/mulq.ts @@ -1,5 +1,4 @@ -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { setC4 } from "@thi.ng/vectors3/setc"; +import { ReadonlyVec, setC4, Vec } from "@thi.ng/vectors3"; export const mulQ = (out: Vec, a: ReadonlyVec, b: ReadonlyVec) => { diff --git a/packages/matrices/src/mulv.ts b/packages/matrices/src/mulv.ts index 3172990963..6c9666f561 100644 --- a/packages/matrices/src/mulv.ts +++ b/packages/matrices/src/mulv.ts @@ -1,7 +1,14 @@ -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { dotS2, dotS3, dotS4 } from "@thi.ng/vectors3/dots"; -import { vop } from "@thi.ng/vectors3/internal/vop"; -import { setC2, setC3, setC4 } from "@thi.ng/vectors3/setc"; +import { + dotS2, + dotS3, + dotS4, + ReadonlyVec, + setC2, + setC3, + setC4, + Vec, + vop +} from "@thi.ng/vectors3"; import { MatOpMV, MultiMatOpMV } from "./api"; /** diff --git a/packages/matrices/src/ortho.ts b/packages/matrices/src/ortho.ts index 0710e2998f..c31739d5a9 100644 --- a/packages/matrices/src/ortho.ts +++ b/packages/matrices/src/ortho.ts @@ -1,4 +1,4 @@ -import { setC } from "@thi.ng/vectors3/setc"; +import { setC } from "@thi.ng/vectors3"; import { Mat } from "./api"; export const ortho = ( diff --git a/packages/matrices/src/project.ts b/packages/matrices/src/project.ts index c2967a4b0d..b2786f9c82 100644 --- a/packages/matrices/src/project.ts +++ b/packages/matrices/src/project.ts @@ -1,7 +1,10 @@ -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { divN3 } from "@thi.ng/vectors3/divn"; -import { dotC6 } from "@thi.ng/vectors3/dotc"; -import { fromHomogeneous4 } from "@thi.ng/vectors3/homogeneous"; +import { + divN3, + dotC6, + fromHomogeneous4, + ReadonlyVec, + Vec +} from "@thi.ng/vectors3"; import { ReadonlyMat } from "./api"; import { invert23, invert44 } from "./invert"; import { mulV23, mulV344, mulV44 } from "./mulv"; diff --git a/packages/matrices/src/quat-axis-angle.ts b/packages/matrices/src/quat-axis-angle.ts index 4dfab4d9e7..eea96ccb51 100644 --- a/packages/matrices/src/quat-axis-angle.ts +++ b/packages/matrices/src/quat-axis-angle.ts @@ -1,6 +1,5 @@ -import { EPS } from "@thi.ng/math/api"; -import { ReadonlyVec } from "@thi.ng/vectors3/api"; -import { normalize } from "@thi.ng/vectors3/normalize"; +import { EPS } from "@thi.ng/math"; +import { normalize, ReadonlyVec } from "@thi.ng/vectors3"; export const quatFromAxisAngle = (axis: ReadonlyVec, theta: number) => { diff --git a/packages/matrices/src/quat-euler.ts b/packages/matrices/src/quat-euler.ts index 36c35b9aa8..00004211af 100644 --- a/packages/matrices/src/quat-euler.ts +++ b/packages/matrices/src/quat-euler.ts @@ -1,4 +1,4 @@ -import { X3, Y3, Z3 } from "@thi.ng/vectors3/api"; +import { X3, Y3, Z3 } from "@thi.ng/vectors3"; import { mulQ } from "./mulq"; import { quatFromAxisAngle } from "./quat-axis-angle"; diff --git a/packages/matrices/src/quat-m33.ts b/packages/matrices/src/quat-m33.ts index 8857a1e6c5..ce1f2ec000 100644 --- a/packages/matrices/src/quat-m33.ts +++ b/packages/matrices/src/quat-m33.ts @@ -1,5 +1,4 @@ -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; -import { setC } from "@thi.ng/vectors3/setc"; +import { ReadonlyVec, setC, Vec } from "@thi.ng/vectors3"; export const quatToMat33 = (out: Vec, q: ReadonlyVec) => { diff --git a/packages/matrices/src/quat-m44.ts b/packages/matrices/src/quat-m44.ts index 53f5dff4d5..1597be737e 100644 --- a/packages/matrices/src/quat-m44.ts +++ b/packages/matrices/src/quat-m44.ts @@ -1,5 +1,9 @@ -import { ReadonlyVec, Vec, ZERO3 } from "@thi.ng/vectors3/api"; -import { setC } from "@thi.ng/vectors3/setc"; +import { + ReadonlyVec, + setC, + Vec, + ZERO3 +} from "@thi.ng/vectors3"; export const quatToMat44 = (out: Vec, a: ReadonlyVec, t: ReadonlyVec = ZERO3) => { diff --git a/packages/matrices/src/rotation-around-axis.ts b/packages/matrices/src/rotation-around-axis.ts index 308937d08f..25b99403cc 100644 --- a/packages/matrices/src/rotation-around-axis.ts +++ b/packages/matrices/src/rotation-around-axis.ts @@ -1,5 +1,4 @@ -import { ReadonlyVec } from "@thi.ng/vectors3/api"; -import { setC } from "@thi.ng/vectors3/setc"; +import { ReadonlyVec, setC } from "@thi.ng/vectors3"; import { Mat } from "./api"; import { mat33to44 } from "./m33-m44"; diff --git a/packages/matrices/src/rotation.ts b/packages/matrices/src/rotation.ts index bfc29c510e..41c2b5f056 100644 --- a/packages/matrices/src/rotation.ts +++ b/packages/matrices/src/rotation.ts @@ -1,5 +1,5 @@ -import { sincos } from "@thi.ng/math/angle"; -import { setC, setC4, setC6 } from "@thi.ng/vectors3/setc"; +import { sincos } from "@thi.ng/math"; +import { setC, setC4, setC6 } from "@thi.ng/vectors3"; import { Mat } from "./api"; export const rotation22 = diff --git a/packages/matrices/src/row.ts b/packages/matrices/src/row.ts index 2f3fcd4f8b..098f47ef63 100644 --- a/packages/matrices/src/row.ts +++ b/packages/matrices/src/row.ts @@ -1,5 +1,9 @@ -import { vop } from "@thi.ng/vectors3/internal/vop"; -import { setS2, setS3, setS4 } from "@thi.ng/vectors3/sets"; +import { + setS2, + setS3, + setS4, + vop +} from "@thi.ng/vectors3"; import { MultiVecOpMN } from "./api"; export const row: MultiVecOpMN = vop(1); diff --git a/packages/matrices/src/scale-center.ts b/packages/matrices/src/scale-center.ts index c34c8e3f88..950a1ca76b 100644 --- a/packages/matrices/src/scale-center.ts +++ b/packages/matrices/src/scale-center.ts @@ -1,5 +1,4 @@ -import { ReadonlyVec } from "@thi.ng/vectors3/api"; -import { neg } from "@thi.ng/vectors3/neg"; +import { neg, ReadonlyVec } from "@thi.ng/vectors3"; import { Mat } from "./api"; import { concat } from "./concat"; import { scale23, scale44 } from "./scale"; diff --git a/packages/matrices/src/scale.ts b/packages/matrices/src/scale.ts index 4d6cd20592..fb09068e14 100644 --- a/packages/matrices/src/scale.ts +++ b/packages/matrices/src/scale.ts @@ -1,6 +1,10 @@ -import { isNumber } from "@thi.ng/checks/is-number"; -import { ReadonlyVec } from "@thi.ng/vectors3/api"; -import { setC, setC4, setC6 } from "@thi.ng/vectors3/setc"; +import { isNumber } from "@thi.ng/checks"; +import { + ReadonlyVec, + setC, + setC4, + setC6 +} from "@thi.ng/vectors3"; import { Mat } from "./api"; export const scale22 = diff --git a/packages/matrices/src/set.ts b/packages/matrices/src/set.ts index 6ebc4708bf..cec967a5cf 100644 --- a/packages/matrices/src/set.ts +++ b/packages/matrices/src/set.ts @@ -1,6 +1,9 @@ -import { set as _set, set4 } from "@thi.ng/vectors3/set"; -import { compile } from "@thi.ng/vectors3/internal/codegen"; -import { SET } from "@thi.ng/vectors3/internal/templates"; +import { + compile, + set as _set, + SET, + set4 +} from "@thi.ng/vectors3"; import { MatOpM } from "./api"; const $ = (dim) => _set.add(dim, compile(dim, SET, "o,a")); diff --git a/packages/matrices/src/sub.ts b/packages/matrices/src/sub.ts index 0d15f69a19..2b496d02e8 100644 --- a/packages/matrices/src/sub.ts +++ b/packages/matrices/src/sub.ts @@ -1,4 +1,4 @@ -import { sub as _sub, sub4 } from "@thi.ng/vectors3/sub"; +import { sub as _sub, sub4 } from "@thi.ng/vectors3"; import { MatOpMM, MultiMatOpMM } from "./api"; import { defMath } from "./internal/codegen"; diff --git a/packages/matrices/src/subn.ts b/packages/matrices/src/subn.ts index c5d1bee338..a8338b1d09 100644 --- a/packages/matrices/src/subn.ts +++ b/packages/matrices/src/subn.ts @@ -1,4 +1,4 @@ -import { subN as _subN, subN4 } from "@thi.ng/vectors3/subn"; +import { subN as _subN, subN4 } from "@thi.ng/vectors3"; import { MatOpMN, MultiMatOpMN } from "./api"; import { defMathN } from "./internal/codegen"; diff --git a/packages/matrices/src/trace.ts b/packages/matrices/src/trace.ts index ea08e6e1a4..8ecd948769 100644 --- a/packages/matrices/src/trace.ts +++ b/packages/matrices/src/trace.ts @@ -1,4 +1,4 @@ -import { sum } from "@thi.ng/vectors3/sum"; +import { sum } from "@thi.ng/vectors3"; import { diag } from "./diag"; import { ReadonlyMat } from "./api"; diff --git a/packages/matrices/src/translation.ts b/packages/matrices/src/translation.ts index d57333a169..35d243edd9 100644 --- a/packages/matrices/src/translation.ts +++ b/packages/matrices/src/translation.ts @@ -1,6 +1,5 @@ -import { ReadonlyVec } from "@thi.ng/vectors3/api"; +import { ReadonlyVec, setC, setC6 } from "@thi.ng/vectors3"; import { Mat } from "./api"; -import { setC, setC6 } from "@thi.ng/vectors3/setc"; export const translation23 = (m: Mat, v: ReadonlyVec) => diff --git a/packages/matrices/src/transpose.ts b/packages/matrices/src/transpose.ts index 7c2a27a608..2d96219287 100644 --- a/packages/matrices/src/transpose.ts +++ b/packages/matrices/src/transpose.ts @@ -1,4 +1,4 @@ -import { setC, setC4 } from "@thi.ng/vectors3/setc"; +import { setC, setC4 } from "@thi.ng/vectors3"; import { MatOpM } from "./api"; export const transpose22: MatOpM = diff --git a/packages/matrices/src/viewport.ts b/packages/matrices/src/viewport.ts index 06c2570d85..2aaf77caee 100644 --- a/packages/matrices/src/viewport.ts +++ b/packages/matrices/src/viewport.ts @@ -1,5 +1,5 @@ import { Mat } from "./api"; -import { mulM23 } from "./mulM"; +import { mulM23 } from "./mulm"; import { scale23 } from "./scale"; import { translation23 } from "./translation"; diff --git a/packages/matrices/test/tsconfig.json b/packages/matrices/test/tsconfig.json index bcf29ace54..2c9c12a650 100644 --- a/packages/matrices/test/tsconfig.json +++ b/packages/matrices/test/tsconfig.json @@ -1,10 +1,11 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "commonjs", }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/matrices/tsconfig.json b/packages/matrices/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/matrices/tsconfig.json +++ b/packages/matrices/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file From 372c199cfebdec022e8cb3994c6633568fc88dc0 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 10 Jan 2019 23:02:54 +0000 Subject: [PATCH 246/333] build(vector-pools): build: update package scripts, outputs, imports - enable multi-outputs (ES6, CJS, UMD) --- packages/vector-pools/package.json | 36 ++++++++++++++++++------ packages/vector-pools/src/alist.ts | 2 +- packages/vector-pools/src/api.ts | 6 ++-- packages/vector-pools/src/array-list.ts | 2 +- packages/vector-pools/src/attrib-pool.ts | 19 +++++++------ packages/vector-pools/src/convert.ts | 2 +- packages/vector-pools/src/linked-list.ts | 2 +- packages/vector-pools/src/vec-pool.ts | 4 +-- packages/vector-pools/src/wrap.ts | 13 +++++---- packages/vector-pools/test/attribs.ts | 26 +++++++++++++++++ packages/vector-pools/test/tsconfig.json | 5 ++-- packages/vector-pools/tsconfig.json | 6 ++-- 12 files changed, 87 insertions(+), 36 deletions(-) create mode 100644 packages/vector-pools/test/attribs.ts diff --git a/packages/vector-pools/package.json b/packages/vector-pools/package.json index 0bf3674b94..43fc58712c 100644 --- a/packages/vector-pools/package.json +++ b/packages/vector-pools/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/vector-pools", "version": "0.0.1", "description": "TODO", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,19 +14,21 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module vectorPools api malloc vectors3", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", - "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "doc": "typedoc --mode modules --out doc src", + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -34,9 +38,23 @@ }, "keywords": [ "ES6", - "typescript" + "memory", + "memory mapped", + "pool", + "typedarray", + "typescript", + "webgl", + "wasm" ], "publishConfig": { "access": "public" - } + }, + "browserslist": [ + "since 2018-07" + ], + "browser": { + "process": false, + "setTimeout": false + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/vector-pools/src/alist.ts b/packages/vector-pools/src/alist.ts index 22c8e77177..773c41a237 100644 --- a/packages/vector-pools/src/alist.ts +++ b/packages/vector-pools/src/alist.ts @@ -1,4 +1,4 @@ -import { StridedVec, Vec } from "@thi.ng/vectors3/api"; +import { StridedVec, Vec } from "@thi.ng/vectors3"; import { VecFactory } from "./api"; import { wrap } from "./wrap"; diff --git a/packages/vector-pools/src/api.ts b/packages/vector-pools/src/api.ts index 433565bb4b..3216be17cb 100644 --- a/packages/vector-pools/src/api.ts +++ b/packages/vector-pools/src/api.ts @@ -1,6 +1,6 @@ -import { IRelease, TypedArray } from "@thi.ng/api/api"; -import { Type, MemPoolOpts } from "@thi.ng/malloc/api"; -import { StridedVec, Vec, ReadonlyVec } from "@thi.ng/vectors3/api"; +import { IRelease, TypedArray } from "@thi.ng/api"; +import { Type, MemPoolOpts } from "@thi.ng/malloc"; +import { StridedVec, Vec, ReadonlyVec } from "@thi.ng/vectors3"; export interface AttribSpec { type: GLType | Type; diff --git a/packages/vector-pools/src/array-list.ts b/packages/vector-pools/src/array-list.ts index 21997e14a3..e337a0a4b5 100644 --- a/packages/vector-pools/src/array-list.ts +++ b/packages/vector-pools/src/array-list.ts @@ -1,4 +1,4 @@ -import { StridedVec, Vec } from "@thi.ng/vectors3/api"; +import { StridedVec, Vec } from "@thi.ng/vectors3"; import { AVecList } from "./alist"; import { VecFactory } from "./api"; diff --git a/packages/vector-pools/src/attrib-pool.ts b/packages/vector-pools/src/attrib-pool.ts index 2ce68fa8e8..5b1960d790 100644 --- a/packages/vector-pools/src/attrib-pool.ts +++ b/packages/vector-pools/src/attrib-pool.ts @@ -1,12 +1,13 @@ -import { IObjectOf, IRelease, TypedArray } from "@thi.ng/api/api"; -import { assert } from "@thi.ng/api/assert"; -import { align } from "@thi.ng/binary/align"; -import { Pow2 } from "@thi.ng/binary/api"; -import { SIZEOF } from "@thi.ng/malloc/api"; -import { MemPool } from "@thi.ng/malloc/pool"; -import { wrap } from "@thi.ng/malloc/wrap"; -import { range } from "@thi.ng/transducers/iter/range"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3/api"; +import { + assert, + IObjectOf, + IRelease, + TypedArray +} from "@thi.ng/api"; +import { align, Pow2 } from "@thi.ng/binary"; +import { MemPool, SIZEOF, wrap } from "@thi.ng/malloc"; +import { range } from "@thi.ng/transducers"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3"; import { asNativeType } from "./convert"; import { AttribPoolOpts, diff --git a/packages/vector-pools/src/convert.ts b/packages/vector-pools/src/convert.ts index 1017824142..65e497132c 100644 --- a/packages/vector-pools/src/convert.ts +++ b/packages/vector-pools/src/convert.ts @@ -1,4 +1,4 @@ -import { Type } from "@thi.ng/malloc/api"; +import { Type } from "@thi.ng/malloc"; import { GL2TYPE, GLType, TYPE2GL } from "./api"; /** diff --git a/packages/vector-pools/src/linked-list.ts b/packages/vector-pools/src/linked-list.ts index cfd4fb758f..56b826742a 100644 --- a/packages/vector-pools/src/linked-list.ts +++ b/packages/vector-pools/src/linked-list.ts @@ -1,4 +1,4 @@ -import { StridedVec, Vec } from "@thi.ng/vectors3/api"; +import { StridedVec, Vec } from "@thi.ng/vectors3"; import { AVecList } from "./alist"; import { VecFactory } from "./api"; diff --git a/packages/vector-pools/src/vec-pool.ts b/packages/vector-pools/src/vec-pool.ts index 8d5199f61f..c8a2064e18 100644 --- a/packages/vector-pools/src/vec-pool.ts +++ b/packages/vector-pools/src/vec-pool.ts @@ -1,12 +1,12 @@ import { TypedArray } from "@thi.ng/api"; -import { isTypedArray } from "@thi.ng/checks/is-typedarray"; +import { isTypedArray } from "@thi.ng/checks"; import { MemPool, MemPoolOpts, MemPoolStats, Type } from "@thi.ng/malloc"; -import { IVector } from "@thi.ng/vectors3/api"; +import { IVector } from "@thi.ng/vectors3"; import { GLType, IVecPool } from "./api"; import { asNativeType } from "./convert"; import { wrap } from "./wrap"; diff --git a/packages/vector-pools/src/wrap.ts b/packages/vector-pools/src/wrap.ts index 0d2440b396..65ca5be087 100644 --- a/packages/vector-pools/src/wrap.ts +++ b/packages/vector-pools/src/wrap.ts @@ -1,8 +1,11 @@ -import { IVector, Vec } from "@thi.ng/vectors3/api"; -import { gvec } from "@thi.ng/vectors3/gvec"; -import { Vec2 } from "@thi.ng/vectors3/vec2"; -import { Vec3 } from "@thi.ng/vectors3/vec3"; -import { Vec4 } from "@thi.ng/vectors3/vec4"; +import { + gvec, + IVector, + Vec, + Vec2, + Vec3, + Vec4 +} from "@thi.ng/vectors3"; export const wrap = (buf: Vec, size: number, idx: number, stride: number): IVector => { diff --git a/packages/vector-pools/test/attribs.ts b/packages/vector-pools/test/attribs.ts new file mode 100644 index 0000000000..7a1d4ef7d9 --- /dev/null +++ b/packages/vector-pools/test/attribs.ts @@ -0,0 +1,26 @@ +import { AttribPool } from "../src/attrib-pool"; +import { Type } from "@thi.ng/malloc"; +// import * as assert from "assert"; + +describe("vector-pools", () => { + it("attribs", () => { + const pool = new AttribPool( + 0x100, + 8, + { + pos: { type: Type.F32, default: [0, 0], size: 2, byteOffset: 0 }, + id: { type: Type.U32, default: 0, size: 1, byteOffset: 8 }, + index: { type: Type.U16, default: 0, size: 1, byteOffset: 12 }, + col: { type: Type.I8, default: [0, 0, 0, 0], size: 4, byteOffset: 14 }, + } + ); + pool.setAttribValue("pos", 0, [1, 2]); + pool.setAttribValue("id", 0, 1); + pool.setAttribValue("index", 0, 10); + pool.setAttribValue("col", 0, [128, 129, 130, 131]); + pool.setAttribValue("pos", 1, [3, 4]); + pool.setAttribValue("id", 1, 2); + pool.setAttribValue("index", 1, 20); + pool.setAttribValue("col", 1, [255, 254, 253, 252]); + }); +}); diff --git a/packages/vector-pools/test/tsconfig.json b/packages/vector-pools/test/tsconfig.json index bcf29ace54..2c9c12a650 100644 --- a/packages/vector-pools/test/tsconfig.json +++ b/packages/vector-pools/test/tsconfig.json @@ -1,10 +1,11 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "commonjs", }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/vector-pools/tsconfig.json b/packages/vector-pools/tsconfig.json index bd6481a5a6..bcf03f18b4 100644 --- a/packages/vector-pools/tsconfig.json +++ b/packages/vector-pools/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "." + "outDir": ".", + "module": "es6", + "target": "es6" }, "include": [ "./src/**/*.ts" ] -} +} \ No newline at end of file From d4eddef2a33b404d2d779341f495ccf58eb08f47 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 10 Jan 2019 23:03:29 +0000 Subject: [PATCH 247/333] build(vectors2): build: update package scripts, outputs, imports - enable multi-outputs (ES6, CJS, UMD) --- packages/vectors2/package.json | 28 ++++++++++++++------ packages/vectors2/src/api.ts | 7 +++-- packages/vectors2/src/internal/codegen.ts | 31 +++++++++++++---------- packages/vectors2/src/internal/equiv.ts | 3 +-- packages/vectors2/src/internal/ops.ts | 2 +- packages/vectors2/src/mat23.ts | 5 ++-- packages/vectors2/src/mat33.ts | 7 +++-- packages/vectors2/src/mat44.ts | 9 +++---- packages/vectors2/src/nd.ts | 19 +++++++------- packages/vectors2/src/pool.ts | 2 +- packages/vectors2/src/vec2.ts | 13 +++++++--- packages/vectors2/src/vec3.ts | 11 +++++--- packages/vectors2/src/vec4.ts | 13 ++++++---- packages/vectors2/test/tsconfig.json | 5 ++-- packages/vectors2/tsconfig.json | 1 + 15 files changed, 90 insertions(+), 66 deletions(-) diff --git a/packages/vectors2/package.json b/packages/vectors2/package.json index 8aa0adc52f..89fd9ba20c 100644 --- a/packages/vectors2/package.json +++ b/packages/vectors2/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/vectors2", "version": "0.0.1", "description": "TODO", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,19 +14,21 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc internal", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module vectors2 api checks equiv errors malloc math random strings transducers", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", - "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "doc": "typedoc --mode modules --out doc src", + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -50,5 +54,13 @@ ], "browser": { "process": false - } + }, + "browserslist": [ + "since 2018-07" + ], + "browser": { + "process": false, + "setTimeout": false + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/vectors2/src/api.ts b/packages/vectors2/src/api.ts index cceb2c57f4..83e49ef8f8 100644 --- a/packages/vectors2/src/api.ts +++ b/packages/vectors2/src/api.ts @@ -7,10 +7,9 @@ import { IRelease, TypedArray } from "@thi.ng/api"; -import { implementsFunction } from "@thi.ng/checks/implements-function"; -import { Type } from "@thi.ng/malloc/api"; -import { atan2Abs } from "@thi.ng/math/angle"; -import { EPS } from "@thi.ng/math/api"; +import { implementsFunction } from "@thi.ng/checks"; +import { Type } from "@thi.ng/malloc"; +import { atan2Abs, EPS } from "@thi.ng/math"; import { genCommonDefaults } from "./internal/codegen"; import { eqDelta as _eqDelta } from "./internal/equiv"; import { vop } from "./internal/ops"; diff --git a/packages/vectors2/src/internal/codegen.ts b/packages/vectors2/src/internal/codegen.ts index b6932bca21..7d8ba102cc 100644 --- a/packages/vectors2/src/internal/codegen.ts +++ b/packages/vectors2/src/internal/codegen.ts @@ -1,17 +1,22 @@ -// import { FnAny } from "@thi.ng/api"; -import { sign as _sign } from "@thi.ng/math/abs"; -import { clamp as _clamp } from "@thi.ng/math/interval"; -import { fract as _fract, trunc as _trunc } from "@thi.ng/math/prec"; -import { smoothStep as _smoothStep, step as _step } from "@thi.ng/math/step"; +import { + clamp as _clamp, + fract as _fract, + sign as _sign, + smoothStep as _smoothStep, + step as _step, + trunc as _trunc +} from "@thi.ng/math"; import { SYSTEM } from "@thi.ng/random/system"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { range } from "@thi.ng/transducers/iter/range"; -import { tuples } from "@thi.ng/transducers/iter/tuples"; -import { push } from "@thi.ng/transducers/rfn/push"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { map } from "@thi.ng/transducers/xform/map"; -import { mapIndexed } from "@thi.ng/transducers/xform/map-indexed"; -import { take } from "@thi.ng/transducers/xform/take"; +import { + comp, + map, + mapIndexed, + push, + range, + take, + transduce, + tuples +} from "@thi.ng/transducers"; import { abs, add, diff --git a/packages/vectors2/src/internal/equiv.ts b/packages/vectors2/src/internal/equiv.ts index e27016bccb..69a85f4811 100644 --- a/packages/vectors2/src/internal/equiv.ts +++ b/packages/vectors2/src/internal/equiv.ts @@ -1,5 +1,4 @@ -import { EPS } from "@thi.ng/math/api"; -import { eqDelta as _eqDelta } from "@thi.ng/math/eqdelta"; +import { EPS, eqDelta as _eqDelta } from "@thi.ng/math"; import { ReadonlyVec } from "../api"; /** diff --git a/packages/vectors2/src/internal/ops.ts b/packages/vectors2/src/internal/ops.ts index 2dd6787a67..dd3b0231a6 100644 --- a/packages/vectors2/src/internal/ops.ts +++ b/packages/vectors2/src/internal/ops.ts @@ -1,4 +1,4 @@ -import { unsupported } from "@thi.ng/errors/unsupported"; +import { unsupported } from "@thi.ng/errors"; /** * Specialized / optimized version of `@thi.ng/defmulti` for vector diff --git a/packages/vectors2/src/mat23.ts b/packages/vectors2/src/mat23.ts index 44ff6440d7..33575f54d3 100644 --- a/packages/vectors2/src/mat23.ts +++ b/packages/vectors2/src/mat23.ts @@ -1,12 +1,11 @@ -import { isArrayLike } from "@thi.ng/checks/is-arraylike"; -import { isNumber } from "@thi.ng/checks/is-number"; +import { isArrayLike, isNumber } from "@thi.ng/checks"; import { IMatrix, Mat, ReadonlyMat, ReadonlyVec, Vec - } from "./api"; +} from "./api"; import { declareIndices } from "./internal/accessors"; import { iterator } from "./internal/iterator"; import { cross2, dot2 } from "./internal/matrix"; diff --git a/packages/vectors2/src/mat33.ts b/packages/vectors2/src/mat33.ts index 67a4532aac..6b1a42ee1b 100644 --- a/packages/vectors2/src/mat33.ts +++ b/packages/vectors2/src/mat33.ts @@ -1,12 +1,11 @@ -import { isArrayLike } from "@thi.ng/checks/is-arraylike"; -import { isNumber } from "@thi.ng/checks/is-number"; +import { isArrayLike, isNumber } from "@thi.ng/checks"; import { IMatrix, Mat, ReadonlyMat, ReadonlyVec, Vec - } from "./api"; +} from "./api"; import { declareIndices } from "./internal/accessors"; import { iterator } from "./internal/iterator"; import { @@ -14,7 +13,7 @@ import { set3, setS3, setS4 - } from "./internal/matrix"; +} from "./internal/matrix"; import { NDArray2 } from "./nd"; export const get33 = diff --git a/packages/vectors2/src/mat44.ts b/packages/vectors2/src/mat44.ts index d459841b8e..0762c890a5 100644 --- a/packages/vectors2/src/mat44.ts +++ b/packages/vectors2/src/mat44.ts @@ -1,6 +1,5 @@ -import { isArrayLike } from "@thi.ng/checks/is-arraylike"; -import { isNumber } from "@thi.ng/checks/is-number"; -import { DEG2RAD } from "@thi.ng/math/api"; +import { isArrayLike, isNumber } from "@thi.ng/checks"; +import { DEG2RAD } from "@thi.ng/math"; import { copy, IMatrix, @@ -9,7 +8,7 @@ import { ReadonlyMat, ReadonlyVec, Vec - } from "./api"; +} from "./api"; import { declareIndices } from "./internal/accessors"; import { iterator } from "./internal/iterator"; import { @@ -18,7 +17,7 @@ import { set3, setS3, setS4 - } from "./internal/matrix"; +} from "./internal/matrix"; import { Mat33 } from "./mat33"; import { NDArray2 } from "./nd"; import { cross3, sub3 } from "./vec3"; diff --git a/packages/vectors2/src/nd.ts b/packages/vectors2/src/nd.ts index 54254d92ab..2612b3a87d 100644 --- a/packages/vectors2/src/nd.ts +++ b/packages/vectors2/src/nd.ts @@ -1,14 +1,13 @@ -import { isArrayLike } from "@thi.ng/checks/is-arraylike"; -import { isIterable } from "@thi.ng/checks/is-iterable"; -import { isNumber } from "@thi.ng/checks/is-number"; +import { isArrayLike, isIterable, isNumber } from "@thi.ng/checks"; import { equiv, equivArrayLike } from "@thi.ng/equiv"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { unsupported } from "@thi.ng/errors/unsupported"; -import { EPS } from "@thi.ng/math/api"; -import { Stringer } from "@thi.ng/strings/api"; -import { floatFixedWidth } from "@thi.ng/strings/float"; -import { padLeft } from "@thi.ng/strings/pad-left"; -import { truncate } from "@thi.ng/strings/truncate"; +import { illegalArgs, unsupported } from "@thi.ng/errors"; +import { EPS } from "@thi.ng/math"; +import { + floatFixedWidth, + padLeft, + Stringer, + truncate +} from "@thi.ng/strings"; import { INDArray, NDVec } from "./api"; import { declareIndices } from "./internal/accessors"; import { eqDelta as _eqDelta } from "./internal/equiv"; diff --git a/packages/vectors2/src/pool.ts b/packages/vectors2/src/pool.ts index f509f30810..a9e2b350a8 100644 --- a/packages/vectors2/src/pool.ts +++ b/packages/vectors2/src/pool.ts @@ -1,5 +1,5 @@ import { NumericArray, TypedArray } from "@thi.ng/api"; -import { isTypedArray } from "@thi.ng/checks/is-typedarray"; +import { isTypedArray } from "@thi.ng/checks"; import { MemPool, MemPoolOpts, diff --git a/packages/vectors2/src/vec2.ts b/packages/vectors2/src/vec2.ts index 45a111f635..85db0c6c05 100644 --- a/packages/vectors2/src/vec2.ts +++ b/packages/vectors2/src/vec2.ts @@ -1,8 +1,13 @@ import { Comparator } from "@thi.ng/api"; -import { EPS, HALF_PI, PI } from "@thi.ng/math/api"; -import { eqDelta as _eqDelta } from "@thi.ng/math/eqdelta"; -import { max2id, min2id } from "@thi.ng/math/interval"; -import { mixBilinear } from "@thi.ng/math/mix"; +import { + EPS, + eqDelta as _eqDelta, + HALF_PI, + max2id, + min2id, + mixBilinear, + PI +} from "@thi.ng/math"; import { AVec } from "./avec"; import { declareIndices } from "./internal/accessors"; import { genCommon } from "./internal/codegen"; diff --git a/packages/vectors2/src/vec3.ts b/packages/vectors2/src/vec3.ts index 8a53084848..bb71eff717 100644 --- a/packages/vectors2/src/vec3.ts +++ b/packages/vectors2/src/vec3.ts @@ -1,8 +1,11 @@ import { Comparator } from "@thi.ng/api"; -import { EPS } from "@thi.ng/math/api"; -import { eqDelta as _eqDelta } from "@thi.ng/math/eqdelta"; -import { max3id, min3id } from "@thi.ng/math/interval"; -import { mixBilinear } from "@thi.ng/math/mix"; +import { + EPS, + eqDelta as _eqDelta, + max3id, + min3id, + mixBilinear +} from "@thi.ng/math"; import { AVec } from "./avec"; import { declareIndices } from "./internal/accessors"; import { genCommon } from "./internal/codegen"; diff --git a/packages/vectors2/src/vec4.ts b/packages/vectors2/src/vec4.ts index 9e509523a1..a1d9c6c97f 100644 --- a/packages/vectors2/src/vec4.ts +++ b/packages/vectors2/src/vec4.ts @@ -1,8 +1,11 @@ -import { Comparator } from "@thi.ng/api/api"; -import { EPS } from "@thi.ng/math/api"; -import { eqDelta as _eqDelta } from "@thi.ng/math/eqdelta"; -import { max4id, min4id } from "@thi.ng/math/interval"; -import { mixBilinear } from "@thi.ng/math/mix"; +import { Comparator } from "@thi.ng/api"; +import { + EPS, + eqDelta as _eqDelta, + max4id, + min4id, + mixBilinear +} from "@thi.ng/math"; import { AVec } from "./avec"; import { declareIndices } from "./internal/accessors"; import { genCommon } from "./internal/codegen"; diff --git a/packages/vectors2/test/tsconfig.json b/packages/vectors2/test/tsconfig.json index bcf29ace54..2c9c12a650 100644 --- a/packages/vectors2/test/tsconfig.json +++ b/packages/vectors2/test/tsconfig.json @@ -1,10 +1,11 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "commonjs", }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/vectors2/tsconfig.json b/packages/vectors2/tsconfig.json index 5a76bc343b..bcf03f18b4 100644 --- a/packages/vectors2/tsconfig.json +++ b/packages/vectors2/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6" }, "include": [ From a7ea1fc3fe5e381cb21deda6b93c05fd43e0da6a Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 10 Jan 2019 23:03:59 +0000 Subject: [PATCH 248/333] build(vectors): build: update package scripts, outputs, imports - enable multi-outputs (ES6, CJS, UMD) --- packages/vectors3/package.json | 28 ++++++++++++++++------- packages/vectors3/src/angle-between.ts | 2 +- packages/vectors3/src/api.ts | 2 +- packages/vectors3/src/bisect.ts | 2 +- packages/vectors3/src/cartesian.ts | 2 +- packages/vectors3/src/clamp.ts | 2 +- packages/vectors3/src/clampn.ts | 2 +- packages/vectors3/src/compare.ts | 2 +- packages/vectors3/src/copy.ts | 2 +- packages/vectors3/src/empty.ts | 2 +- packages/vectors3/src/eqdelta.ts | 7 +++--- packages/vectors3/src/fract.ts | 2 +- packages/vectors3/src/gvec.ts | 7 +++--- packages/vectors3/src/heading.ts | 2 +- packages/vectors3/src/index.ts | 4 ++++ packages/vectors3/src/internal/codegen.ts | 18 ++++++++------- packages/vectors3/src/internal/vop.ts | 2 +- packages/vectors3/src/jitter.ts | 3 +-- packages/vectors3/src/major.ts | 2 +- packages/vectors3/src/minor.ts | 2 +- packages/vectors3/src/mix-bilinear.ts | 2 +- packages/vectors3/src/normalize.ts | 2 +- packages/vectors3/src/random.ts | 3 +-- packages/vectors3/src/round.ts | 2 +- packages/vectors3/src/smoothstep.ts | 2 +- packages/vectors3/src/step.ts | 2 +- packages/vectors3/src/sum.ts | 3 +-- packages/vectors3/src/vec2.ts | 2 +- packages/vectors3/src/vec3.ts | 2 +- packages/vectors3/src/vec4.ts | 2 +- packages/vectors3/src/wrap.ts | 2 +- packages/vectors3/test/tsconfig.json | 5 ++-- packages/vectors3/tsconfig.json | 1 + 33 files changed, 70 insertions(+), 55 deletions(-) diff --git a/packages/vectors3/package.json b/packages/vectors3/package.json index d286972a19..ab171a0a03 100644 --- a/packages/vectors3/package.json +++ b/packages/vectors3/package.json @@ -2,7 +2,9 @@ "name": "@thi.ng/vectors3", "version": "0.0.1", "description": "Optimized 2d/3d/4d and arbitrary length vector operations", - "main": "./index.js", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", "typings": "./index.d.ts", "repository": { "type": "git", @@ -12,19 +14,21 @@ "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { - "build": "yarn run clean && tsc --declaration", - "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module vectors3 api checks equiv errors math random transducers", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", - "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn run build && yarn publish --access public", - "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + "doc": "typedoc --mode modules --out doc src", + "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", "nyc": "^13.1.0", - "typedoc": "^0.13.0", + "typedoc": "^0.14.0", "typescript": "^3.2.2" }, "dependencies": { @@ -84,5 +88,13 @@ ], "publishConfig": { "access": "public" - } + }, + "browserslist": [ + "since 2018-07" + ], + "browser": { + "process": false, + "setTimeout": false + }, + "sideEffects": false } \ No newline at end of file diff --git a/packages/vectors3/src/angle-between.ts b/packages/vectors3/src/angle-between.ts index 060f005e04..35d78caaa5 100644 --- a/packages/vectors3/src/angle-between.ts +++ b/packages/vectors3/src/angle-between.ts @@ -1,4 +1,4 @@ -import { absTheta } from "@thi.ng/math/angle"; +import { absTheta } from "@thi.ng/math"; import { ReadonlyVec } from "./api"; import { dot } from "./dot"; import { mag } from "./mag"; diff --git a/packages/vectors3/src/api.ts b/packages/vectors3/src/api.ts index 7c6b9956be..680362eb81 100644 --- a/packages/vectors3/src/api.ts +++ b/packages/vectors3/src/api.ts @@ -3,7 +3,7 @@ import { IEmpty, IEqualsDelta, ILength, -} from "@thi.ng/api/api"; +} from "@thi.ng/api"; export interface Vec extends Iterable, diff --git a/packages/vectors3/src/bisect.ts b/packages/vectors3/src/bisect.ts index f0f50fb068..667b7714d7 100644 --- a/packages/vectors3/src/bisect.ts +++ b/packages/vectors3/src/bisect.ts @@ -1,4 +1,4 @@ -import { HALF_PI, PI } from "@thi.ng/math/api"; +import { HALF_PI, PI } from "@thi.ng/math"; import { VecOpRoVV } from "./api"; import { headingXY } from "./heading"; diff --git a/packages/vectors3/src/cartesian.ts b/packages/vectors3/src/cartesian.ts index 77a98c95da..1f9787449d 100644 --- a/packages/vectors3/src/cartesian.ts +++ b/packages/vectors3/src/cartesian.ts @@ -1,4 +1,4 @@ -import { cossin } from "@thi.ng/math/angle"; +import { cossin } from "@thi.ng/math"; import { MultiVecOpVO, ReadonlyVec, diff --git a/packages/vectors3/src/clamp.ts b/packages/vectors3/src/clamp.ts index aa37e07294..e580d4358d 100644 --- a/packages/vectors3/src/clamp.ts +++ b/packages/vectors3/src/clamp.ts @@ -1,4 +1,4 @@ -import { clamp as _clamp, clamp01 as _clamp01, clamp11 as _clamp11 } from "@thi.ng/math/interval"; +import { clamp as _clamp, clamp01 as _clamp01, clamp11 as _clamp11 } from "@thi.ng/math"; import { MultiVecOpVVV, VecOpVVV } from "./api"; import { ARGS_VVV, defHofOp } from "./internal/codegen"; import { HOF_VVV } from "./internal/templates"; diff --git a/packages/vectors3/src/clampn.ts b/packages/vectors3/src/clampn.ts index 099c92b936..468453ea6c 100644 --- a/packages/vectors3/src/clampn.ts +++ b/packages/vectors3/src/clampn.ts @@ -1,4 +1,4 @@ -import { clamp as _clamp } from "@thi.ng/math/interval"; +import { clamp as _clamp } from "@thi.ng/math"; import { MultiVecOpVNN, VecOpVNN } from "./api"; import { defHofOp } from "./internal/codegen"; diff --git a/packages/vectors3/src/compare.ts b/packages/vectors3/src/compare.ts index a2b60b202e..9019864e42 100644 --- a/packages/vectors3/src/compare.ts +++ b/packages/vectors3/src/compare.ts @@ -1,4 +1,4 @@ -import { Comparator } from "@thi.ng/api/api"; +import { Comparator } from "@thi.ng/api"; import { ReadonlyVec } from "./api"; /** diff --git a/packages/vectors3/src/copy.ts b/packages/vectors3/src/copy.ts index 60fda83629..d03e0a7bbb 100644 --- a/packages/vectors3/src/copy.ts +++ b/packages/vectors3/src/copy.ts @@ -1,4 +1,4 @@ -import { implementsFunction } from "@thi.ng/checks/implements-function"; +import { implementsFunction } from "@thi.ng/checks"; import { ReadonlyVec, Vec } from "./api"; export const copy = diff --git a/packages/vectors3/src/empty.ts b/packages/vectors3/src/empty.ts index 3f79560bc9..1084914f82 100644 --- a/packages/vectors3/src/empty.ts +++ b/packages/vectors3/src/empty.ts @@ -1,4 +1,4 @@ -import { implementsFunction } from "@thi.ng/checks/implements-function"; +import { implementsFunction } from "@thi.ng/checks"; import { ReadonlyVec, Vec } from "./api"; import { zeroes } from "./setn"; diff --git a/packages/vectors3/src/eqdelta.ts b/packages/vectors3/src/eqdelta.ts index a0db5f3297..8387f8604e 100644 --- a/packages/vectors3/src/eqdelta.ts +++ b/packages/vectors3/src/eqdelta.ts @@ -1,9 +1,8 @@ -import { vop } from "./internal/vop"; +import { implementsFunction } from "@thi.ng/checks"; +import { EPS, eqDelta as _eq } from "@thi.ng/math"; import { MultiVecOpRoVVO, ReadonlyVec } from "./api"; -import { EPS } from "@thi.ng/math/api"; -import { eqDelta as _eq } from "@thi.ng/math/eqdelta"; -import { implementsFunction } from "@thi.ng/checks/implements-function"; import { compileHOF } from "./internal/codegen"; +import { vop } from "./internal/vop"; const $ = (dim) => eqDelta.add( diff --git a/packages/vectors3/src/fract.ts b/packages/vectors3/src/fract.ts index 11ee356b2c..fe7c8604a4 100644 --- a/packages/vectors3/src/fract.ts +++ b/packages/vectors3/src/fract.ts @@ -1,4 +1,4 @@ -import { fract as _fract } from "@thi.ng/math/prec"; +import { fract as _fract } from "@thi.ng/math"; import { MultiVecOpV, VecOpV } from "./api"; import { defHofOp } from "./internal/codegen"; diff --git a/packages/vectors3/src/gvec.ts b/packages/vectors3/src/gvec.ts index 80f2f902d0..99da073a48 100644 --- a/packages/vectors3/src/gvec.ts +++ b/packages/vectors3/src/gvec.ts @@ -1,7 +1,6 @@ -import { EPS } from "@thi.ng/math/api"; -import { memoize1 } from "@thi.ng/memoize/memoize1"; -import { range } from "@thi.ng/transducers/iter/range"; -import { map } from "@thi.ng/transducers/xform/map"; +import { EPS } from "@thi.ng/math"; +import { memoize1 } from "@thi.ng/memoize"; +import { map, range } from "@thi.ng/transducers"; import { IVector, Vec } from "./api"; import { eqDeltaS } from "./eqdelta"; import { values } from "./internal/vec-utils"; diff --git a/packages/vectors3/src/heading.ts b/packages/vectors3/src/heading.ts index 0b73157a26..f4f7d8bb45 100644 --- a/packages/vectors3/src/heading.ts +++ b/packages/vectors3/src/heading.ts @@ -1,4 +1,4 @@ -import { atan2Abs } from "@thi.ng/math/angle"; +import { atan2Abs } from "@thi.ng/math"; import { ReadonlyVec } from "./api"; export const headingXY = (a: ReadonlyVec) => atan2Abs(a[1], a[0]); diff --git a/packages/vectors3/src/index.ts b/packages/vectors3/src/index.ts index c4be876ab9..b20b9bdde3 100644 --- a/packages/vectors3/src/index.ts +++ b/packages/vectors3/src/index.ts @@ -1,5 +1,9 @@ export * from "./api"; +export * from "./internal/accessors"; +export * from "./internal/avec"; export * from "./internal/codegen"; +export * from "./internal/templates"; +export * from "./internal/vec-utils"; export * from "./internal/vop"; export * from "./vec2"; diff --git a/packages/vectors3/src/internal/codegen.ts b/packages/vectors3/src/internal/codegen.ts index 514362289c..64ea11edcc 100644 --- a/packages/vectors3/src/internal/codegen.ts +++ b/packages/vectors3/src/internal/codegen.ts @@ -1,11 +1,13 @@ -import { comp } from "@thi.ng/transducers/func/comp"; -import { range } from "@thi.ng/transducers/iter/range"; -import { tuples } from "@thi.ng/transducers/iter/tuples"; -import { str } from "@thi.ng/transducers/rfn/str"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { map } from "@thi.ng/transducers/xform/map"; -import { mapIndexed } from "@thi.ng/transducers/xform/map-indexed"; -import { take } from "@thi.ng/transducers/xform/take"; +import { + comp, + map, + mapIndexed, + range, + str, + take, + transduce, + tuples +} from "@thi.ng/transducers"; import { MultiVecOpVN, MultiVecOpVV, diff --git a/packages/vectors3/src/internal/vop.ts b/packages/vectors3/src/internal/vop.ts index 771acbf303..71b4f26750 100644 --- a/packages/vectors3/src/internal/vop.ts +++ b/packages/vectors3/src/internal/vop.ts @@ -1,4 +1,4 @@ -import { unsupported } from "@thi.ng/errors/unsupported"; +import { unsupported } from "@thi.ng/errors"; /** * Specialized / optimized version of `@thi.ng/defmulti` for vector diff --git a/packages/vectors3/src/jitter.ts b/packages/vectors3/src/jitter.ts index b3bbfc4f94..0b2ca7ce91 100644 --- a/packages/vectors3/src/jitter.ts +++ b/packages/vectors3/src/jitter.ts @@ -1,5 +1,4 @@ -import { IRandom } from "@thi.ng/random/api"; -import { SYSTEM } from "@thi.ng/random/system"; +import { IRandom, SYSTEM } from "@thi.ng/random"; import { add } from "./add"; import { ReadonlyVec, Vec } from "./api"; import { randNorm } from "./random"; diff --git a/packages/vectors3/src/major.ts b/packages/vectors3/src/major.ts index bc83e70b29..e3d3325add 100644 --- a/packages/vectors3/src/major.ts +++ b/packages/vectors3/src/major.ts @@ -1,4 +1,4 @@ -import { max2id, max3id, max4id } from "@thi.ng/math/interval"; +import { max2id, max3id, max4id } from "@thi.ng/math"; import { MultiVecOpRoV } from "./api"; import { vop } from "./internal/vop"; diff --git a/packages/vectors3/src/minor.ts b/packages/vectors3/src/minor.ts index dab5f09de8..381843c710 100644 --- a/packages/vectors3/src/minor.ts +++ b/packages/vectors3/src/minor.ts @@ -1,4 +1,4 @@ -import { min2id, min3id, min4id } from "@thi.ng/math/interval"; +import { min2id, min3id, min4id } from "@thi.ng/math"; import { MultiVecOpRoV } from "./api"; import { vop } from "./internal/vop"; diff --git a/packages/vectors3/src/mix-bilinear.ts b/packages/vectors3/src/mix-bilinear.ts index 446c8a2aba..72b8eb9707 100644 --- a/packages/vectors3/src/mix-bilinear.ts +++ b/packages/vectors3/src/mix-bilinear.ts @@ -1,4 +1,4 @@ -import { mixBilinear as _mix } from "@thi.ng/math/mix"; +import { mixBilinear as _mix } from "@thi.ng/math"; import { MultiVecOpVVVVNN, VecOpVVVVNN } from "./api"; import { defHofOp } from "./internal/codegen"; diff --git a/packages/vectors3/src/normalize.ts b/packages/vectors3/src/normalize.ts index 4f837684fd..b29fc9ade7 100644 --- a/packages/vectors3/src/normalize.ts +++ b/packages/vectors3/src/normalize.ts @@ -1,4 +1,4 @@ -import { EPS } from "@thi.ng/math/api"; +import { EPS } from "@thi.ng/math"; import { VecOpVO } from "./api"; import { mag } from "./mag"; import { mulN } from "./muln"; diff --git a/packages/vectors3/src/random.ts b/packages/vectors3/src/random.ts index 45a6a0d566..d66aaeac52 100644 --- a/packages/vectors3/src/random.ts +++ b/packages/vectors3/src/random.ts @@ -1,5 +1,4 @@ -import { IRandom } from "@thi.ng/random/api"; -import { SYSTEM } from "@thi.ng/random/system"; +import { IRandom, SYSTEM } from "@thi.ng/random"; import { MultiVecOpOOO, Vec, VecOpOOO } from "./api"; import { defHofOp } from "./internal/codegen"; import { normalize } from "./normalize"; diff --git a/packages/vectors3/src/round.ts b/packages/vectors3/src/round.ts index 502619937a..6fe0e04a29 100644 --- a/packages/vectors3/src/round.ts +++ b/packages/vectors3/src/round.ts @@ -1,4 +1,4 @@ -import { roundTo as _round } from "@thi.ng/math/prec"; +import { roundTo as _round } from "@thi.ng/math"; import { MultiVecOpVO, VecOpVO } from "./api"; import { defHofOp } from "./internal/codegen"; import { FN_N } from "./internal/templates"; diff --git a/packages/vectors3/src/smoothstep.ts b/packages/vectors3/src/smoothstep.ts index 9c40958728..c42e71970e 100644 --- a/packages/vectors3/src/smoothstep.ts +++ b/packages/vectors3/src/smoothstep.ts @@ -1,4 +1,4 @@ -import { smoothStep as _step } from "@thi.ng/math/step"; +import { smoothStep as _step } from "@thi.ng/math"; import { MultiVecOpV, VecOpV } from "./api"; import { DEFAULT_OUT, defHofOp } from "./internal/codegen"; import { HOF_VVV } from "./internal/templates"; diff --git a/packages/vectors3/src/step.ts b/packages/vectors3/src/step.ts index 08e84de9d2..84d05d127a 100644 --- a/packages/vectors3/src/step.ts +++ b/packages/vectors3/src/step.ts @@ -1,4 +1,4 @@ -import { step as _step } from "@thi.ng/math/step"; +import { step as _step } from "@thi.ng/math"; import { MultiVecOpV, VecOpV } from "./api"; import { DEFAULT_OUT, defHofOp } from "./internal/codegen"; import { FN2 } from "./internal/templates"; diff --git a/packages/vectors3/src/sum.ts b/packages/vectors3/src/sum.ts index ec12b5eeb3..33ebd10d7f 100644 --- a/packages/vectors3/src/sum.ts +++ b/packages/vectors3/src/sum.ts @@ -1,7 +1,6 @@ +import { add, reduce } from "@thi.ng/transducers"; import { MultiVecOpRoV } from "./api"; import { vop } from "./internal/vop"; -import { reduce } from "@thi.ng/transducers/reduce"; -import { add } from "@thi.ng/transducers/rfn/add"; /** * Returns component sum of vector `v`. diff --git a/packages/vectors3/src/vec2.ts b/packages/vectors3/src/vec2.ts index ce2b7033b6..c4273a4615 100644 --- a/packages/vectors3/src/vec2.ts +++ b/packages/vectors3/src/vec2.ts @@ -1,4 +1,4 @@ -import { EPS } from "@thi.ng/math/api"; +import { EPS } from "@thi.ng/math"; import { IVector, MAX2, diff --git a/packages/vectors3/src/vec3.ts b/packages/vectors3/src/vec3.ts index 76a768e52b..b800a053c3 100644 --- a/packages/vectors3/src/vec3.ts +++ b/packages/vectors3/src/vec3.ts @@ -1,4 +1,4 @@ -import { EPS } from "@thi.ng/math/api"; +import { EPS } from "@thi.ng/math"; import { IVector, MAX3, diff --git a/packages/vectors3/src/vec4.ts b/packages/vectors3/src/vec4.ts index d8b4532917..dc5e27059f 100644 --- a/packages/vectors3/src/vec4.ts +++ b/packages/vectors3/src/vec4.ts @@ -1,4 +1,4 @@ -import { EPS } from "@thi.ng/math/api"; +import { EPS } from "@thi.ng/math"; import { IVector, MAX4, diff --git a/packages/vectors3/src/wrap.ts b/packages/vectors3/src/wrap.ts index 81e0c6feb8..50cf460522 100644 --- a/packages/vectors3/src/wrap.ts +++ b/packages/vectors3/src/wrap.ts @@ -1,4 +1,4 @@ -import { wrap as _wrap } from "@thi.ng/math/interval"; +import { wrap as _wrap } from "@thi.ng/math"; import { MultiVecOpVVV, VecOpVVV } from "./api"; import { ARGS_VVV, defHofOp } from "./internal/codegen"; import { HOF_VVV } from "./internal/templates"; diff --git a/packages/vectors3/test/tsconfig.json b/packages/vectors3/test/tsconfig.json index bcf29ace54..2c9c12a650 100644 --- a/packages/vectors3/test/tsconfig.json +++ b/packages/vectors3/test/tsconfig.json @@ -1,10 +1,11 @@ { "extends": "../../../tsconfig.json", "compilerOptions": { - "outDir": "../build" + "outDir": "../build", + "module": "commonjs", }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} +} \ No newline at end of file diff --git a/packages/vectors3/tsconfig.json b/packages/vectors3/tsconfig.json index 5a76bc343b..bcf03f18b4 100644 --- a/packages/vectors3/tsconfig.json +++ b/packages/vectors3/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": ".", + "module": "es6", "target": "es6" }, "include": [ From 82f8ef27ff64feaeb4ac15a06c7543ce93fe2b3f Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 10 Jan 2019 23:04:53 +0000 Subject: [PATCH 249/333] revert(hiccup-svg): undo merge mistake in convert.ts --- packages/hiccup-svg/src/convert.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/hiccup-svg/src/convert.ts b/packages/hiccup-svg/src/convert.ts index e702dfed78..40020aa8be 100644 --- a/packages/hiccup-svg/src/convert.ts +++ b/packages/hiccup-svg/src/convert.ts @@ -1,7 +1,9 @@ -import { implementsFunction } from "@thi.ng/checks/implements-function"; -import { isArray } from "@thi.ng/checks/is-array"; -import { isArrayLike } from "@thi.ng/checks/is-arraylike"; -import { isString } from "@thi.ng/checks/is-string"; +import { + implementsFunction, + isArray, + isArrayLike, + isString +} from "@thi.ng/checks"; import { circle } from "./circle"; import { ff } from "./format"; import { linearGradient, radialGradient } from "./gradients"; @@ -154,7 +156,6 @@ const convertAttribs = default: res[id] = v; } - return path(segments, attribs); } } return res; From c9da5485e10b7f2b48b82040ee0b69bbb00f7306 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 11 Jan 2019 00:15:56 +0000 Subject: [PATCH 250/333] build(examples): update geom-tessel tsconfig --- examples/geom-tessel/tsconfig.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/geom-tessel/tsconfig.json b/examples/geom-tessel/tsconfig.json index 50a1cade93..440ebac19c 100644 --- a/examples/geom-tessel/tsconfig.json +++ b/examples/geom-tessel/tsconfig.json @@ -4,7 +4,9 @@ "outDir": ".", "module": "es6", "target": "es6", - "sourceMap": true + "sourceMap": true, + "noUnusedLocals": false, + "noUnusedParameters": false, }, "include": [ "./src/**/*.ts" From cdd8659aa7037141de9aab3c71f3325ce2466472 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 11 Jan 2019 14:11:21 +0000 Subject: [PATCH 251/333] refactor(defmulti): update imports, fix tests --- packages/defmulti/src/index.ts | 66 +++++++++++++++++++-------------- packages/defmulti/test/index.ts | 2 +- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/packages/defmulti/src/index.ts b/packages/defmulti/src/index.ts index 005cf5c053..79d447ee8e 100644 --- a/packages/defmulti/src/index.ts +++ b/packages/defmulti/src/index.ts @@ -1,9 +1,7 @@ -import { IObjectOf } from "@thi.ng/api/api"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { unsupported } from "@thi.ng/errors/unsupported"; -import { illegalArity } from "@thi.ng/errors/illegal-arity"; +import { IObjectOf } from "@thi.ng/api"; +import { illegalArgs, unsupported, illegalArity } from "@thi.ng/errors"; -export const DEFAULT: unique symbol = Symbol("DEFAULT"); +export const DEFAULT: unique symbol = Symbol(); export type DispatchFn = (...args) => PropertyKey; export type DispatchFn1 = (a: A, ...xs: any[]) => PropertyKey; @@ -262,7 +260,11 @@ export function defmulti(f: any, ancestors?: AncestorDefs): MultiFn { return fn; }; -const findImpl = (impls: IObjectOf>, rels: IObjectOf>, id: PropertyKey) => { +const findImpl = ( + impls: IObjectOf>, + rels: IObjectOf>, + id: PropertyKey +) => { const parents = rels[id]; if (!parents) return; for (let p of parents) { @@ -271,7 +273,11 @@ const findImpl = (impls: IObjectOf>, rels: IObjectOf>, id: PropertyKey) => { +const findAncestors = ( + acc: PropertyKey[], + rels: IObjectOf>, + id: PropertyKey +) => { const parents = rels[id]; if (parents) { for (let p of parents) { @@ -282,14 +288,15 @@ const findAncestors = (acc: PropertyKey[], rels: IObjectOf>, id return acc; }; -const makeRels = (spec: AncestorDefs) => { - const rels: IObjectOf> = {}; - for (let k in spec) { - const val = spec[k]; - rels[k] = val instanceof Set ? val : new Set(val); - } - return rels; -}; +const makeRels = + (spec: AncestorDefs) => { + const rels: IObjectOf> = {}; + for (let k in spec) { + const val = spec[k]; + rels[k] = val instanceof Set ? val : new Set(val); + } + return rels; + }; /** * Returns a multi-dispatch function which delegates to one of the @@ -337,7 +344,7 @@ export const defmultiN = ( fn.add(id, impls[id]); } return fn; -} +}; /** * Syntax-sugar intended for sets of multi-methods sharing same dispatch @@ -393,17 +400,20 @@ export const defmultiN = ( * @param type * @param impls */ -export const implementations = - (type: PropertyKey, rels: IObjectOf[]>, ...impls: (MultiFn | Implementation)[]) => { - (impls.length & 1) && illegalArgs("expected an even number of implementation items"); - if (rels) { - for (let parent in rels) { - for (let fn of rels[parent]) { - fn.isa(type, parent); - } +export const implementations = ( + type: PropertyKey, + rels: IObjectOf[]>, + ...impls: (MultiFn | Implementation)[] +) => { + (impls.length & 1) && illegalArgs("expected an even number of implementation items"); + if (rels) { + for (let parent in rels) { + for (let fn of rels[parent]) { + fn.isa(type, parent); } } - for (let i = 0; i < impls.length; i += 2) { - (>impls[i]).add(type, impls[i + 1]); - } - }; + } + for (let i = 0; i < impls.length; i += 2) { + (>impls[i]).add(type, impls[i + 1]); + } +}; diff --git a/packages/defmulti/test/index.ts b/packages/defmulti/test/index.ts index 7fe077f647..9656a9e5df 100644 --- a/packages/defmulti/test/index.ts +++ b/packages/defmulti/test/index.ts @@ -109,7 +109,7 @@ describe("defmulti", () => { implementations( "a", - + {}, foo, (x) => `foo: ${x.val}`, bar, (x) => `bar: ${x.val.toUpperCase()}` ) From c41b96fb3a036e43c77527b99bff2cfc3ec1c023 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 11 Jan 2019 14:19:10 +0000 Subject: [PATCH 252/333] refactor(geom): update imports, fix tests --- packages/geom2/package.json | 3 +- packages/geom2/src/bezier.ts | 3 +- packages/geom2/test/api.ts | 79 ++++++++++++++++++++---------------- packages/geom2/test/clip.ts | 2 +- 4 files changed, 47 insertions(+), 40 deletions(-) diff --git a/packages/geom2/package.json b/packages/geom2/package.json index 7650e93fe3..8f88a41c00 100644 --- a/packages/geom2/package.json +++ b/packages/geom2/package.json @@ -16,7 +16,7 @@ "scripts": { "build": "yarn clean && yarn build:es6 && yarn build:bundle", "build:es6": "tsc --declaration", - "build:bundle": "../../scripts/bundle-module geom2 api checks defmulti equiv hiccup hiccup-svg malloc math matrices transducers vectors3", + "build:bundle": "../../scripts/bundle-module geom2 api checks defmulti equiv errors hiccup hiccup-svg malloc math matrices transducers vectors3", "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", @@ -36,6 +36,7 @@ "@thi.ng/checks": "^1.5.14", "@thi.ng/defmulti": "^0.7.0", "@thi.ng/equiv": "^0.1.15", + "@thi.ng/errors": "^0.1.12", "@thi.ng/hiccup": "^2.7.2", "@thi.ng/hiccup-svg": "^2.0.10", "@thi.ng/malloc": "^0.2.1", diff --git a/packages/geom2/src/bezier.ts b/packages/geom2/src/bezier.ts index fd9b37c6eb..726c972db8 100644 --- a/packages/geom2/src/bezier.ts +++ b/packages/geom2/src/bezier.ts @@ -1,5 +1,4 @@ -import { isNumber } from "@thi.ng/checks/is-number"; -import { isPlainObject } from "@thi.ng/checks/is-plain-object"; +import { isNumber, isPlainObject } from "@thi.ng/checks"; import { implementations } from "@thi.ng/defmulti"; import { clamp01, mixCubic as _mixC, mixQuadratic as _mixQ } from "@thi.ng/math"; import { Mat } from "@thi.ng/matrices"; diff --git a/packages/geom2/test/api.ts b/packages/geom2/test/api.ts index 79e30ccc62..2a8bf7d623 100644 --- a/packages/geom2/test/api.ts +++ b/packages/geom2/test/api.ts @@ -56,12 +56,12 @@ describe("api", () => { it("area", () => checkImpls(area, [ _DEFAULT, - Type.CIRCLE2, - Type.ELLIPSE2, + Type.CIRCLE, + Type.ELLIPSE, Type.GROUP, Type.POLYGON2, Type.QUAD2, - Type.RECT2, + Type.RECT, Type.TRIANGLE2, ])); @@ -78,7 +78,7 @@ describe("api", () => { it("asPolygon", () => checkImpls(asPolygon, [ _DEFAULT, - Type.ELLIPSE2, + Type.ELLIPSE, Type.PATH2, Type.POLYGON2, ])); @@ -95,9 +95,9 @@ describe("api", () => { it("bounds", () => checkImpls(bounds, [ Type.ARC2, - Type.CIRCLE2, + Type.CIRCLE, Type.CUBIC2, - Type.ELLIPSE2, + Type.ELLIPSE, Type.GROUP, Type.LINE2, Type.PATH2, @@ -106,22 +106,22 @@ describe("api", () => { Type.POLYLINE2, Type.QUAD2, Type.QUADRATIC2, - Type.RECT2, + Type.RECT, Type.TRIANGLE2, ])); it("center", () => checkImpls(center, [ _DEFAULT, - Type.CIRCLE2, - Type.ELLIPSE2 + Type.CIRCLE, + Type.ELLIPSE ])); it("centroid", () => checkImpls(centroid, [ Type.ARC2, - Type.CIRCLE2, - Type.ELLIPSE2, + Type.CIRCLE, + Type.ELLIPSE, Type.GROUP, Type.LINE2, Type.PATH2, @@ -129,26 +129,26 @@ describe("api", () => { Type.POLYGON2, Type.POLYLINE2, Type.QUAD2, - Type.RECT2, + Type.RECT, Type.TRIANGLE2, ])); it("classifyPoint", () => checkImpls(classifyPoint, [ - Type.CIRCLE2, + Type.CIRCLE, Type.TRIANGLE2, ])); it("closestPoint", () => checkImpls(closestPoint, [ - Type.CIRCLE2, + Type.CIRCLE, ])); it("clipConvex", () => checkImpls(clipConvex, [ Type.POLYGON2, Type.QUAD2, - Type.RECT2, + Type.RECT, Type.TRIANGLE2, ])); @@ -176,7 +176,7 @@ describe("api", () => { Type.POLYGON2, Type.POLYLINE2, Type.QUAD2, - Type.RECT2, + Type.RECT, Type.TRIANGLE2, ])); @@ -207,6 +207,10 @@ describe("api", () => { it("intersectShape", () => checkImpls(intersectShape, [ + "rect-circle", + "rect-rect", + "sphere-ray", + "sphere-sphere" ])); it("intersectLine", () => @@ -216,7 +220,7 @@ describe("api", () => { it("mapPoint", () => checkImpls(mapPoint, [ - Type.RECT2 + Type.RECT ])); it("normalAt", () => @@ -234,33 +238,35 @@ describe("api", () => { it("perimeter", () => checkImpls(perimeter, [ - Type.CIRCLE2, - Type.ELLIPSE2, + Type.CIRCLE, + Type.ELLIPSE, Type.LINE2, Type.POLYGON2, Type.POLYLINE2, Type.QUAD2, - Type.RECT2, + Type.RECT, Type.TRIANGLE2, ])); it("pointAt", () => checkImpls(pointAt, [ Type.ARC2, - Type.CIRCLE2, + Type.CIRCLE, Type.CUBIC2, - Type.ELLIPSE2, + Type.ELLIPSE, + Type.LINE2, Type.POLYGON2, Type.QUADRATIC2, - Type.RECT2, + Type.RAY, + Type.RECT, ])); it("pointInside", () => checkImpls(pointInside, [ - Type.CIRCLE2, + Type.CIRCLE, Type.POLYGON2, Type.TRIANGLE2, - Type.RECT2, + Type.RECT, ])); it("resample", () => @@ -269,7 +275,7 @@ describe("api", () => { Type.POLYGON2, Type.POLYLINE2, Type.QUAD2, - Type.RECT2, + Type.RECT, Type.TRIANGLE2, ])); @@ -294,6 +300,7 @@ describe("api", () => { it("tangentAt", () => checkImpls(tangentAt, [ + Type.CIRCLE, Type.LINE2, Type.POLYGON2, Type.POLYLINE2, @@ -303,7 +310,7 @@ describe("api", () => { checkImpls(tessellate, [ Type.POLYGON2, Type.QUAD2, - Type.RECT2, + Type.RECT, Type.TRIANGLE2, ])); @@ -317,40 +324,40 @@ describe("api", () => { Type.POLYLINE2, Type.QUAD2, Type.QUADRATIC2, - Type.RECT2, + Type.RECT, Type.TRIANGLE2, ])); it("translate", () => checkImpls(translate, [ - Type.CIRCLE2, - Type.ELLIPSE2, + Type.CIRCLE, + Type.ELLIPSE, Type.PATH2, Type.POLYGON2, Type.POLYLINE2, Type.QUAD2, - Type.RECT2, + Type.RECT, Type.TRIANGLE2 ])); it("union", () => checkImpls(union, [ Type.POLYGON2, - Type.RECT2, + Type.RECT, ])); it("unmapPoint", () => checkImpls(unmapPoint, [ Type.QUAD2, - Type.RECT2, + Type.RECT, ])); it("vertices", () => checkImpls(vertices, [ Type.ARC2, - Type.CIRCLE2, + Type.CIRCLE, Type.CUBIC2, - Type.ELLIPSE2, + Type.ELLIPSE, Type.LINE2, Type.PATH2, Type.POINTS2, @@ -358,7 +365,7 @@ describe("api", () => { Type.POLYLINE2, Type.QUAD2, Type.QUADRATIC2, - Type.RECT2, + Type.RECT, Type.TRIANGLE2, ])); diff --git a/packages/geom2/test/clip.ts b/packages/geom2/test/clip.ts index 45917c6d08..154a231919 100644 --- a/packages/geom2/test/clip.ts +++ b/packages/geom2/test/clip.ts @@ -1,4 +1,4 @@ -import { translation23 } from "@thi.ng/matrices/translation"; +import { translation23 } from "@thi.ng/matrices"; import * as fs from "fs"; import * as g from "../src"; From f3a5e0ffbd03390d93b6db9bea68e4947cfff7f3 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 11 Jan 2019 14:19:43 +0000 Subject: [PATCH 253/333] refactor(malloc): update imports --- packages/malloc/src/api.ts | 2 +- packages/malloc/src/pool.ts | 6 +++--- packages/malloc/src/wrap.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/malloc/src/api.ts b/packages/malloc/src/api.ts index 5dd3de270d..261372617d 100644 --- a/packages/malloc/src/api.ts +++ b/packages/malloc/src/api.ts @@ -1,4 +1,4 @@ -import { IRelease, TypedArray } from "@thi.ng/api/api"; +import { IRelease, TypedArray } from "@thi.ng/api"; export const enum Type { U8, diff --git a/packages/malloc/src/pool.ts b/packages/malloc/src/pool.ts index 7d506abe88..14b866c33b 100644 --- a/packages/malloc/src/pool.ts +++ b/packages/malloc/src/pool.ts @@ -1,7 +1,7 @@ import { TypedArray } from "@thi.ng/api"; -import { align } from "@thi.ng/binary/align"; -import { isNumber } from "@thi.ng/checks/is-number"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { align } from "@thi.ng/binary"; +import { isNumber } from "@thi.ng/checks"; +import { illegalArgs } from "@thi.ng/errors"; import { IMemPool, MemBlock, diff --git a/packages/malloc/src/wrap.ts b/packages/malloc/src/wrap.ts index f0330275bb..d88b95fff6 100644 --- a/packages/malloc/src/wrap.ts +++ b/packages/malloc/src/wrap.ts @@ -1,5 +1,5 @@ +import { IObjectOf } from "@thi.ng/api"; import { BlockCtor, Type } from "./api"; -import { IObjectOf } from "@thi.ng/api/api"; const CTORS: IObjectOf = { [Type.U8]: (buf, addr, num) => new Uint8Array(buf, addr, num), From 048bdb1c60e78d77db752ab0790583fdacbc8482 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 11 Jan 2019 14:20:10 +0000 Subject: [PATCH 254/333] refactor(vectors2): update imports --- packages/vectors2/src/internal/codegen.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vectors2/src/internal/codegen.ts b/packages/vectors2/src/internal/codegen.ts index 7d8ba102cc..b1e00372e4 100644 --- a/packages/vectors2/src/internal/codegen.ts +++ b/packages/vectors2/src/internal/codegen.ts @@ -6,7 +6,7 @@ import { step as _step, trunc as _trunc } from "@thi.ng/math"; -import { SYSTEM } from "@thi.ng/random/system"; +import { SYSTEM } from "@thi.ng/random"; import { comp, map, From fcbc0c27a69cbebec9565ad092b380dc1ee290d7 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 11 Jan 2019 14:23:30 +0000 Subject: [PATCH 255/333] build: update bundle-module, strip comments, add source maps & dev deps --- package.json | 6 +- scripts/bundle-module | 49 ++++++--- yarn.lock | 249 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 283 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index af2dd4ae12..ee48779fd2 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "parcel-bundler": "^1.11.0", "rimraf": "^2.6.3", "rollup": "^1.0.2", + "rollup-plugin-cleanup": "^3.1.0", "terser": "^3.14.1", "tslint": "^5.12.0", "typescript": "^3.2.2", @@ -23,12 +24,13 @@ "scripts": { "bootstrap": "lerna bootstrap", "build": "yarn install && lerna -v && lerna bootstrap && lerna run build --sort", + "build:es6only": "lerna run clean && lerna run build:es6", "cover": "lerna run cover", "depgraph": "scripts/depgraph && git add assets/deps.png && git commit -m 'docs: update dep graph' && git push", "doc": "lerna run doc", "examples": "scripts/build-examples", "pub": "lerna publish --registry https://registry.npmjs.org/ && yarn doc && scripts/upload-docs", - "test": "yarn build && yarn test-only", - "test-only": "lerna run test" + "test": "yarn build && yarn test:only", + "test:only": "lerna run test" } } \ No newline at end of file diff --git a/scripts/bundle-module b/scripts/bundle-module index 1a804e8120..9815903682 100755 --- a/scripts/bundle-module +++ b/scripts/bundle-module @@ -1,6 +1,7 @@ #!/usr/bin/env node const fs = require("fs"); const rollup = require("rollup"); +const cleanup = require("rollup-plugin-cleanup"); const terser = require("terser"); const gz = require("gzip-size"); @@ -19,28 +20,36 @@ const deps = process.argv {} ); -const inOpts = { +const INPUT_OPTS = { external: Object.keys(deps), - input: "./index.js" + input: "./index.js", + plugins: [ + cleanup({ comments: "some" }) + ] }; -const terserOpts = { +const TERSER_OPTS = { compress: true, mangle: true, ecma: 6 }; const buildVersion = - async (dest, outOpts, write = true, compressed = false) => { - console.log(`bundling (${outOpts.format}): ${dest}`); - const bundle = await rollup.rollup(inOpts); - const bundleOut = (await bundle.generate(outOpts)).output[0].code; - const terserOut = terser.minify(bundleOut, terserOpts).code; - write && fs.writeFileSync(dest, compressed ? terserOut : bundleOut); + async (opts, write = true, compressed = false) => { + console.log(`bundling (${opts.format}): ${opts.file}`); + + const bundle = await rollup.rollup(INPUT_OPTS); + const bundleOut = (await bundle.generate(opts)).output[0]; + const bundleCode = bundleOut.code; + const terserOut = terser.minify(bundleCode, TERSER_OPTS).code; const gzSize = gz.sync(terserOut); + + write && fs.writeFileSync(opts.file, compressed ? terserOut : bundleCode); + opts.sourcemap && fs.writeFileSync(opts.file + ".map", bundleOut.map); + console.log(`\tsize: ${size(terserOut.length)} / gzipped: ${size(gzSize)}`); - return { raw: terserOut.length, gzip: gzSize }; + return { raw: bundleCode.length, min: terserOut.length, gzip: gzSize }; }; const build = @@ -50,26 +59,36 @@ const build = !fs.existsSync(".meta") && fs.mkdirSync(".meta"); const cjs = await buildVersion( - "lib/index.js", { - format: "cjs" + file: "lib/index.js", + format: "cjs", + // we don't use default exports, so safe to remove interop blocks + interop: false, + sourcemap: true, + sourcemapExcludeSources: true, } ); + // output disabled, just collect meta data const esm = await buildVersion( - "lib/index.es6.js", { - format: "esm" + file: "lib/index.es6.js", + format: "esm", + interop: false, }, false ); + // write minified version const umd = await buildVersion( - "lib/index.umd.js", { + file: "lib/index.umd.js", format: "umd", globals: deps, name: `thi.ng.${name}`, + interop: false, + sourcemap: true, + sourcemapExcludeSources: true, }, true, true diff --git a/yarn.lock b/yarn.lock index b05eff8d42..8a5586e836 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1670,12 +1670,19 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= + dependencies: + arr-flatten "^1.0.1" + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= -arr-flatten@^1.1.0: +arr-flatten@^1.0.1, arr-flatten@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== @@ -1712,6 +1719,11 @@ array-uniq@^1.0.1: resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= + array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" @@ -1944,6 +1956,15 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + braces@^2.3.0, braces@^2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" @@ -3477,6 +3498,11 @@ estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= +estree-walker@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.5.2.tgz#d3850be7529c9580d815600b53126515e146dd39" + integrity sha512-XpCnW/AE10ws/kDAs37cngSkvgIR8aN3G0MS85m7dUpuK2EREo9VJ00uvw6Dg/hXEpfsE1I1TvJOJr+Z+TL+ig== + esutils@^2.0.0, esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" @@ -3526,6 +3552,13 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= + dependencies: + is-posix-bracket "^0.1.0" + expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -3539,6 +3572,13 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= + dependencies: + fill-range "^2.1.0" + expand-tilde@^2.0.0, expand-tilde@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" @@ -3575,6 +3615,13 @@ external-editor@^3.0.0: iconv-lite "^0.4.24" tmp "^0.0.33" +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= + dependencies: + is-extglob "^1.0.0" + extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" @@ -3656,11 +3703,27 @@ file-loader@^3.0.1: loader-utils "^1.0.2" schema-utils "^1.0.0" +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= + filesize@^3.6.0: version "3.6.1" resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" integrity sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg== +fill-range@^2.1.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" + integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^3.0.0" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" @@ -3730,11 +3793,18 @@ flush-write-stream@^1.0.0: inherits "^2.0.1" readable-stream "^2.0.4" -for-in@^1.0.2: +for-in@^1.0.1, for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= + dependencies: + for-in "^1.0.1" + foreach@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" @@ -3962,6 +4032,21 @@ gitconfiglocal@^1.0.0: dependencies: ini "^1.3.2" +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= + dependencies: + is-glob "^2.0.0" + glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" @@ -4577,6 +4662,18 @@ is-directory@^0.3.1: resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= + dependencies: + is-primitive "^2.0.0" + is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -4589,6 +4686,11 @@ is-extendable@^1.0.1: dependencies: is-plain-object "^2.0.4" +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= + is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -4613,6 +4715,13 @@ is-fullwidth-code-point@^2.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= + dependencies: + is-extglob "^1.0.0" + is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" @@ -4627,6 +4736,13 @@ is-glob@^4.0.0: dependencies: is-extglob "^2.1.1" +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= + dependencies: + kind-of "^3.0.2" + is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -4634,6 +4750,11 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== + is-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" @@ -4651,6 +4772,16 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= + is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" @@ -4831,6 +4962,15 @@ js-beautify@^1.8.9: mkdirp "~0.5.0" nopt "~4.0.1" +js-cleanup@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/js-cleanup/-/js-cleanup-1.0.0.tgz#a3aad18a23a1752e9fa005f9128e65d601d2d634" + integrity sha512-gT33849UQki2Ek5NJM9eCH1ZEMjzMfyE881kmfv51hxO4K+TgH+qBIt9RZjczrV02wFqNDSVCk8pE9p78I3cIw== + dependencies: + magic-string "^0.25.1" + perf-regexes "^1.0.1" + skip-regex "^1.0.2" + js-levenshtein@^1.1.3: version "1.1.4" resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.4.tgz#3a56e3cbf589ca0081eb22cd9ba0b1290a16d26e" @@ -5269,6 +5409,13 @@ magic-string@^0.22.4: dependencies: vlq "^0.2.2" +magic-string@^0.25.1: + version "0.25.1" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.1.tgz#b1c248b399cd7485da0fe7385c2fc7011843266e" + integrity sha512-sCuTz6pYom8Rlt4ISPFn6wuFodbKMIHUMv4Qko9P17dpxb7s52KJTmRuZZqHdGmLCK9AOcDare039nRIcfdkEg== + dependencies: + sourcemap-codec "^1.4.1" + make-dir@^1.0.0, make-dir@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" @@ -5332,6 +5479,11 @@ math-expression-evaluator@^1.2.14: resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac" integrity sha1-3oGf282E3M2PrlnGrreWFbnSZqw= +math-random@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" + integrity sha1-izqsWIuKZuSXXjzepn97sylgH6w= + md5-hex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-2.0.0.tgz#d0588e9f1c74954492ecd24ac0ac6ce997d92e33" @@ -5432,6 +5584,25 @@ merge2@^1.2.3: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== +micromatch@^2.3.11: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -5786,7 +5957,7 @@ normalize-package-data@^2.0.0, normalize-package-data@^2.3.0, normalize-package- semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-path@^2.1.1: +normalize-path@^2.0.1, normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= @@ -5994,6 +6165,14 @@ object.getownpropertydescriptors@^2.0.3: define-properties "^1.1.2" es-abstract "^1.5.1" +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" @@ -6334,6 +6513,16 @@ parse-github-repo-url@^1.3.0: resolved "https://registry.yarnpkg.com/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz#9e7d8bb252a6cb6ba42595060b7bf6df3dbc1f50" integrity sha1-nn2LslKmy2ukJZUGC3v23z28H1A= +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + parse-json@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" @@ -6438,6 +6627,11 @@ pegjs@^0.11.0-dev.325: resolved "https://registry.yarnpkg.com/pegjs/-/pegjs-0.11.0-dev.325.tgz#5af06561c8b3f10ef57dcfcba89075a677af393a" integrity sha512-7YGSJyY9YHMS16zY14sVO6zF+SRGgIGVVtK4/SerLuOOyeWz/MFlE6RB5jJRBjODM5//OsfPrPBIpQDPEMh+/A== +perf-regexes@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/perf-regexes/-/perf-regexes-1.0.1.tgz#6da1d62f5a94bf9353a0451bccacf69068b75d0b" + integrity sha512-L7MXxUDtqr4PUaLFCDCXBfGV/6KLIuSEccizDI7JxT+c9x1G1v04BQ4+4oag84SHaCdrBgQAIs/Cqn+flwFPng== + performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" @@ -7049,6 +7243,11 @@ prepend-http@^1.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= + private@^0.1.6: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" @@ -7210,6 +7409,15 @@ quote-stream@^1.0.1, quote-stream@~1.0.2: minimist "^1.1.3" through2 "^2.0.0" +randomatic@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" + integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== + dependencies: + is-number "^4.0.0" + kind-of "^6.0.0" + math-random "^1.0.1" + randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: version "2.0.6" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" @@ -7428,6 +7636,13 @@ regenerator-transform@^0.13.3: dependencies: private "^0.1.6" +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== + dependencies: + is-equal-shallow "^0.1.3" + regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -7477,7 +7692,7 @@ repeat-element@^1.1.2: resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== -repeat-string@^1.6.1: +repeat-string@^1.5.2, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= @@ -7605,6 +7820,22 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" +rollup-plugin-cleanup@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-cleanup/-/rollup-plugin-cleanup-3.1.0.tgz#ba453828c9039fba76e276bb6c516e7dfd5d23d4" + integrity sha512-HA6PyX6tvN3rK6VgGemqPcDC62vYL9FawIng7IciaXbj/wJ4ydY13JmN+S+zIOtVaqpJhB3lTH24l2YVGJlC8A== + dependencies: + js-cleanup "^1.0.0" + rollup-pluginutils "^2.3.0" + +rollup-pluginutils@^2.3.0: + version "2.3.3" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.3.3.tgz#3aad9b1eb3e7fe8262820818840bf091e5ae6794" + integrity sha512-2XZwja7b6P5q4RZ5FhyX1+f46xi1Z3qBKigLRZ6VTZjwbN0K1IFGMlwm06Uu0Emcre2Z63l77nq/pzn+KxIEoA== + dependencies: + estree-walker "^0.5.2" + micromatch "^2.3.11" + rollup@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.0.2.tgz#df88abda5cfe96afaa07dbd540510f87e60d1baf" @@ -7819,6 +8050,11 @@ simple-swizzle@^0.2.2: dependencies: is-arrayish "^0.3.1" +skip-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/skip-regex/-/skip-regex-1.0.2.tgz#ac655d77e7c771ac2b9f37585fea37bff56ad65b" + integrity sha512-pEjMUbwJ5Pl/6Vn6FsamXHXItJXSRftcibixDmNCWbWhic0hzHrwkMZo0IZ7fMRH9KxcWDFSkzhccB4285PutA== + slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" @@ -7933,6 +8169,11 @@ source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= +sourcemap-codec@^1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.4.tgz#c63ea927c029dd6bd9a2b7fa03b3fec02ad56e9f" + integrity sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg== + spawn-wrap@^1.4.2: version "1.4.2" resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.4.2.tgz#cff58e73a8224617b6561abdc32586ea0c82248c" From 507218aa2787754cfd5d3726282e7b5598a65b5d Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 11 Jan 2019 14:23:53 +0000 Subject: [PATCH 256/333] minor(examples): update package-stats --- examples/package-stats/src/dep-chart.ts | 4 ++-- examples/package-stats/src/size-chart.ts | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/package-stats/src/dep-chart.ts b/examples/package-stats/src/dep-chart.ts index a8fc6c4903..5ae4a3fe42 100644 --- a/examples/package-stats/src/dep-chart.ts +++ b/examples/package-stats/src/dep-chart.ts @@ -83,8 +83,8 @@ fs.writeFileSync( }, mapIndexed((i, m) => [i, m[1]], packageDeps), group({ "font-size": "20px", "text-anchor": "middle" }, - text([592, 28], "@thi.ng/umbrella internal re-use"), - text([592, 56], "(transitive dependents)"), + text([552, 28], "@thi.ng/umbrella internal re-use"), + text([552, 56], "(transitive dependents)"), ) ] ) diff --git a/examples/package-stats/src/size-chart.ts b/examples/package-stats/src/size-chart.ts index 8e3e1bc9ee..89c115248f 100644 --- a/examples/package-stats/src/size-chart.ts +++ b/examples/package-stats/src/size-chart.ts @@ -27,6 +27,8 @@ const meta = transduce( fs.readdirSync(BASE_DIR) ); +console.log(meta.length); + const fileSizeChart = (stats, modType, type) => { @@ -68,8 +70,8 @@ const fileSizeChart = }, mapIndexed((i, m) => [i, get(m)], stats), group({ "font-size": "20px", "text-anchor": "middle" }, - text([592, 28], `@thi.ng/umbrella package sizes (${modType.toUpperCase()})`), - text([592, 56], `(minified + gzipped)`), + text([552, 28], `@thi.ng/umbrella package sizes (${modType.toUpperCase()})`), + text([552, 56], `(minified + gzipped)`), ) ] ) From d5ba06a4d8974d07bfcd386491547ec93eccdeec Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 11 Jan 2019 14:27:48 +0000 Subject: [PATCH 257/333] build: remove obsolete temp package vectors2 --- packages/vectors2/.npmignore | 11 - packages/vectors2/LICENSE | 201 ------- packages/vectors2/README.md | 40 -- packages/vectors2/package.json | 66 --- packages/vectors2/src/api.ts | 407 -------------- packages/vectors2/src/avec.ts | 32 -- packages/vectors2/src/index.ts | 12 - packages/vectors2/src/internal/accessors.ts | 29 - packages/vectors2/src/internal/codegen.ts | 390 ------------- packages/vectors2/src/internal/equiv.ts | 36 -- packages/vectors2/src/internal/iterator.ts | 7 - packages/vectors2/src/internal/matrix.ts | 36 -- packages/vectors2/src/internal/ops.ts | 18 - packages/vectors2/src/mat23.ts | 301 ---------- packages/vectors2/src/mat33.ts | 341 ------------ packages/vectors2/src/mat44.ts | 582 ------------------- packages/vectors2/src/nd.ts | 588 -------------------- packages/vectors2/src/pool.ts | 111 ---- packages/vectors2/src/quat.ts | 99 ---- packages/vectors2/src/vec2.ts | 318 ----------- packages/vectors2/src/vec3.ts | 355 ------------ packages/vectors2/src/vec4.ts | 292 ---------- packages/vectors2/test/index.ts | 6 - packages/vectors2/test/tsconfig.json | 11 - packages/vectors2/tsconfig.json | 11 - 25 files changed, 4300 deletions(-) delete mode 100644 packages/vectors2/.npmignore delete mode 100644 packages/vectors2/LICENSE delete mode 100644 packages/vectors2/README.md delete mode 100644 packages/vectors2/package.json delete mode 100644 packages/vectors2/src/api.ts delete mode 100644 packages/vectors2/src/avec.ts delete mode 100644 packages/vectors2/src/index.ts delete mode 100644 packages/vectors2/src/internal/accessors.ts delete mode 100644 packages/vectors2/src/internal/codegen.ts delete mode 100644 packages/vectors2/src/internal/equiv.ts delete mode 100644 packages/vectors2/src/internal/iterator.ts delete mode 100644 packages/vectors2/src/internal/matrix.ts delete mode 100644 packages/vectors2/src/internal/ops.ts delete mode 100644 packages/vectors2/src/mat23.ts delete mode 100644 packages/vectors2/src/mat33.ts delete mode 100644 packages/vectors2/src/mat44.ts delete mode 100644 packages/vectors2/src/nd.ts delete mode 100644 packages/vectors2/src/pool.ts delete mode 100644 packages/vectors2/src/quat.ts delete mode 100644 packages/vectors2/src/vec2.ts delete mode 100644 packages/vectors2/src/vec3.ts delete mode 100644 packages/vectors2/src/vec4.ts delete mode 100644 packages/vectors2/test/index.ts delete mode 100644 packages/vectors2/test/tsconfig.json delete mode 100644 packages/vectors2/tsconfig.json diff --git a/packages/vectors2/.npmignore b/packages/vectors2/.npmignore deleted file mode 100644 index ec83d74c9d..0000000000 --- a/packages/vectors2/.npmignore +++ /dev/null @@ -1,11 +0,0 @@ -build -coverage -dev -doc -export -src* -test -.nyc_output -tsconfig.json -*.tgz -*.html diff --git a/packages/vectors2/LICENSE b/packages/vectors2/LICENSE deleted file mode 100644 index 8dada3edaf..0000000000 --- a/packages/vectors2/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/packages/vectors2/README.md b/packages/vectors2/README.md deleted file mode 100644 index 42fad90a53..0000000000 --- a/packages/vectors2/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# @thi.ng/vectors2 - -[![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/vectors2.svg)](https://www.npmjs.com/package/@thi.ng/vectors2) -![npm downloads](https://img.shields.io/npm/dm/@thi.ng/vectors2.svg) -[![Twitter Follow](https://img.shields.io/twitter/follow/thing_umbrella.svg?style=flat-square&label=twitter)](https://twitter.com/thing_umbrella) - -This project is part of the -[@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo. - - - - - -## About - -TODO... - -## Installation - -```bash -yarn add @thi.ng/vectors2 -``` - -## Dependencies - -- TODO... - -## Usage examples - -```ts -import * as m from "@thi.ng/vectors2"; -``` - -## Authors - -- Karsten Schmidt - -## License - -© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/packages/vectors2/package.json b/packages/vectors2/package.json deleted file mode 100644 index 89fd9ba20c..0000000000 --- a/packages/vectors2/package.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "name": "@thi.ng/vectors2", - "version": "0.0.1", - "description": "TODO", - "module": "./index.js", - "main": "./lib/index.js", - "umd:main": "./lib/index.umd.js", - "typings": "./index.d.ts", - "repository": { - "type": "git", - "url": "https://github.com/thi-ng/umbrella.git" - }, - "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/vectors2", - "author": "Karsten Schmidt ", - "license": "Apache-2.0", - "scripts": { - "build": "yarn clean && yarn build:es6 && yarn build:bundle", - "build:es6": "tsc --declaration", - "build:bundle": "../../scripts/bundle-module vectors2 api checks equiv errors malloc math random strings transducers", - "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", - "cover": "yarn test && nyc report --reporter=lcov", - "doc": "typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public" - }, - "devDependencies": { - "@types/mocha": "^5.2.5", - "@types/node": "^10.12.15", - "mocha": "^5.2.0", - "nyc": "^13.1.0", - "typedoc": "^0.14.0", - "typescript": "^3.2.2" - }, - "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/equiv": "^0.1.15", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/malloc": "^0.2.1", - "@thi.ng/math": "^0.2.2", - "@thi.ng/random": "^0.1.1", - "@thi.ng/strings": "^0.7.1", - "@thi.ng/transducers": "^2.3.2" - }, - "keywords": [ - "ES6", - "typescript" - ], - "publishConfig": { - "access": "public" - }, - "browserslist": [ - "last 3 Chrome versions" - ], - "browser": { - "process": false - }, - "browserslist": [ - "since 2018-07" - ], - "browser": { - "process": false, - "setTimeout": false - }, - "sideEffects": false -} \ No newline at end of file diff --git a/packages/vectors2/src/api.ts b/packages/vectors2/src/api.ts deleted file mode 100644 index 83e49ef8f8..0000000000 --- a/packages/vectors2/src/api.ts +++ /dev/null @@ -1,407 +0,0 @@ -import { - ICopy, - IEmpty, - IEqualsDelta, - IEquiv, - ILength, - IRelease, - TypedArray -} from "@thi.ng/api"; -import { implementsFunction } from "@thi.ng/checks"; -import { Type } from "@thi.ng/malloc"; -import { atan2Abs, EPS } from "@thi.ng/math"; -import { genCommonDefaults } from "./internal/codegen"; -import { eqDelta as _eqDelta } from "./internal/equiv"; -import { vop } from "./internal/ops"; - -// suffix convention: -// V = vector arg -// N = numeric / scalar arg -// O = optional arg -// New = immutable op (w/ output vector) -// Ro = readonly op - -export type VecOpV = (a: Vec, ...xs: any[]) => T; -export type VecOpVO = (a: Vec, o?: O, ...xs: any[]) => T; -export type VecOpVV = (a: Vec, b: ReadonlyVec) => T; -export type VecOpVN = (a: Vec, n: number) => T; -export type VecOpVNN = (a: Vec, n: number, m: number) => T; -export type VecOpVVN = (a: Vec, b: ReadonlyVec, n: number) => T; -export type VecOpVVV = (a: Vec, b: ReadonlyVec, c: ReadonlyVec) => T; - -export type VecOpNewVN = (a: ReadonlyVec, n: number, o?: T) => T; -export type VecOpNewVV = (a: ReadonlyVec, b: ReadonlyVec, o?: T) => T; -export type VecOpNewVVN = (a: ReadonlyVec, b: ReadonlyVec, n: number, o?: T) => T; -export type VecOpNewVVV = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, o?: T) => T; -export type VecOpNewVVVN = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, n: number, o?: T) => T; -export type VecOpNewVVVVN = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, n: number, o?: T) => T; - -export type VecOpRoV = (a: ReadonlyVec, ...xs: any[]) => T; -export type VecOpRoVV = (a: ReadonlyVec, b: ReadonlyVec, ...xs: any[]) => T; -export type VecOpRoVVO = (a: ReadonlyVec, b: ReadonlyVec, o?: O, ...xs: any[]) => T; -export type VecOpRoVVV = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, ...xs: any[]) => T; - -export interface MultiVecOp { - add(dim: number, op: VOP): VOP; - default(op: VOP): VOP; -} - -export interface MultiVecOpV extends VecOpV, MultiVecOp> { } -export interface MultiVecOpVO extends VecOpVO, MultiVecOp> { } -export interface MultiVecOpVV extends VecOpVV, MultiVecOp> { } -export interface MultiVecOpVN extends VecOpVN, MultiVecOp> { } -export interface MultiVecOpVNN extends VecOpVNN, MultiVecOp> { } -export interface MultiVecOpVVN extends VecOpVVN, MultiVecOp> { } -export interface MultiVecOpVVV extends VecOpVVV, MultiVecOp> { } - -export interface MultiVecOpNewVV extends VecOpNewVV, MultiVecOp> { } -export interface MultiVecOpNewVN extends VecOpNewVN, MultiVecOp> { } -export interface MultiVecOpNewVVN extends VecOpNewVVN, MultiVecOp> { } -export interface MultiVecOpNewVVV extends VecOpNewVVV, MultiVecOp> { } -export interface MultiVecOpNewVVVN extends VecOpNewVVVN, MultiVecOp> { } -export interface MultiVecOpNewVVVVN extends VecOpNewVVVVN, MultiVecOp> { } - -export interface MultiVecOpRoV extends VecOpRoV, MultiVecOp> { } -export interface MultiVecOpRoVV extends VecOpRoVV, MultiVecOp> { } -export interface MultiVecOpRoVVO extends VecOpRoVVO, MultiVecOp> { } -export interface MultiVecOpRoVVV extends VecOpRoVVV, MultiVecOp> { } - -export interface Vec extends - Iterable, - ILength { - - [id: number]: number; -} - -export interface ReadonlyVec extends - Iterable, - ILength { - readonly [id: number]: number; -} - -export type Mat = Vec; -export type ReadonlyMat = ReadonlyVec; - -export interface IVector extends - Vec, - ICopy, - IEmpty, - IEqualsDelta { - - buf: Vec; - i: number; - s: number; -} - -export interface NDVec extends - Iterable, - ILength { - [id: number]: T; -} - -export interface INDArray extends - ICopy>, - IEquiv, - IEqualsDelta>, - Iterable { - - buf: NDVec; - i: number; - readonly shape: number[]; - readonly stride: number[]; - readonly length: number; - - get(...args: number[]): T; - - set(...args: [number, T] | [number, number, T] | [number, number, number, T]): void; - - lo(...args: number[]): INDArray; - - hi(...args: number[]): INDArray; - - step(...args: number[]): INDArray; - - pick(...args: number[]): INDArray; - - transpose(...args: number[]): INDArray; -} - -export interface IMatrix extends - Vec, - ICopy, - IEqualsDelta { - - mul(m: Readonly): T; - mulV(v: ReadonlyVec, out?: Vec): Vec; - - identity(): T; - invert(): T; -} - -export interface IVecPool extends IRelease { - - malloc(size: number, type?: Type): TypedArray; - - mallocWrapped(size: number, stride?: number, type?: Type): Vec; - - mallocArray(num: number, size: number, cstride?: number, estride?: number, type?: Type): Vec[]; - - free(vec: IVector | TypedArray): boolean; - - freeAll(); -} - -export type CommonOps = [ - // set - VecOpVV, - VecOpVN, - VecOpV, - // rand - VecOpVNN, - VecOpV, - VecOpV, - // math - VecOpVV, - VecOpVV, - VecOpVV, - VecOpVV, - VecOpNewVV, - VecOpNewVV, - VecOpNewVV, - VecOpNewVV, - VecOpVN, - VecOpVN, - VecOpVN, - VecOpVN, - VecOpNewVN, - VecOpNewVN, - VecOpNewVN, - VecOpNewVN, - // madd - VecOpVVV, - VecOpVVN, - VecOpNewVVV, - VecOpNewVVN, - // Math. - VecOpV, - VecOpV, - VecOpV, - VecOpV, - VecOpV, - VecOpV, - VecOpV, - VecOpV, - VecOpV, - VecOpV, - VecOpV, - VecOpV, - VecOpV, - VecOpV, - VecOpV, - VecOpV, - VecOpVN, - // minmax - VecOpVV, - VecOpVV, - VecOpVVV, - // step - VecOpVV, - VecOpVVV, - // mix - VecOpVVV, - VecOpVVN, - VecOpNewVVV, - VecOpNewVVN -]; - -export type Vec2Coord = 0 | 1; -export type Vec3Coord = 0 | 1 | 2; -export type Vec4Coord = 0 | 1 | 2 | 3; - -export const set: MultiVecOpVV = vop(); -export const setN: MultiVecOpVN = vop(); -export const setS: MultiVecOpV = vop(); - -export const copy: MultiVecOpRoV = vop(); -copy.default((v) => - implementsFunction(v, "copy") ? - (v).copy() : - [...v] -); - -export const empty: MultiVecOpRoV = vop(); -empty.default((v) => - implementsFunction(v, "empty") ? - (v).empty() : - zeroes(v.length) -); - -export const zero = (a: Vec) => setN(a, 0); -export const one = (a: Vec) => setN(a, 1); - -export const zeroes = (n: number) => new Array(n).fill(0); -export const ones = (n: number) => new Array(n).fill(1); - -export const eqDelta: MultiVecOpRoVVO = vop(); -eqDelta.default((v1, v2, eps = EPS) => { - if (implementsFunction(v1, "eqDelta")) { - return (v1).eqDelta(v2, eps); - } - if (implementsFunction(v2, "eqDelta")) { - return (v2).eqDelta(v1, eps); - } - return _eqDelta(v1, v2, v1.length, eps); -}); - -export const rand: MultiVecOpVNN = vop(); -export const rand01: MultiVecOpV = vop(); -export const rand11: MultiVecOpV = vop(); - -export const add: MultiVecOpVV = vop(); -export const sub: MultiVecOpVV = vop(); -export const mul: MultiVecOpVV = vop(); -export const div: MultiVecOpVV = vop(); - -export const addNew: MultiVecOpNewVV = vop(); -export const subNew: MultiVecOpNewVV = vop(); -export const mulNew: MultiVecOpNewVV = vop(); -export const divNew: MultiVecOpNewVV = vop(); - -export const addN: MultiVecOpVN = vop(); -export const subN: MultiVecOpVN = vop(); -export const mulN: MultiVecOpVN = vop(); -export const divN: MultiVecOpVN = vop(); - -export const addNewN: MultiVecOpNewVN = vop(); -export const subNewN: MultiVecOpNewVN = vop(); -export const mulNewN: MultiVecOpNewVN = vop(); -export const divNewN: MultiVecOpNewVN = vop(); - -export const neg: MultiVecOpV = vop(); -neg.default((v) => mulN(v, -1)); - -export const madd: MultiVecOpVVV = vop(); -export const maddN: MultiVecOpVVN = vop(); -export const maddNew: MultiVecOpNewVVV = vop(); -export const maddNewN: MultiVecOpNewVVN = vop(); - -export const dot: MultiVecOpRoVV = vop(); -dot.default((a, b) => { - let res = 0; - for (let i = a.length; --i >= 0;) { - res += a[i] * b[i]; - } - return res; -}); - -export const magSq: MultiVecOpRoV = vop(); -magSq.default((v) => dot(v, v)); - -export const mag: MultiVecOpRoV = vop(); -mag.default((a) => Math.sqrt(magSq(a, a))); - -export const normalize: MultiVecOpVO = vop(); -normalize.default((v, n: number) => { - let m = mag(v); - return m >= EPS ? mulN(v, n / m) : v; -}); - -export const limit: MultiVecOpV = vop(); -limit.default((v, n: number) => { - let m = mag(v); - return m > n ? mulN(v, n / m) : v; -}); - -export const distSq: MultiVecOpRoVV = vop(); -export const dist: MultiVecOpRoVV = vop(); -dist.default((a, b) => Math.sqrt(distSq(a, b))); - -export const distManhattan: MultiVecOpRoVV = vop(); -export const distChebyshev: MultiVecOpRoVV = vop(); - -export const abs: MultiVecOpV = vop(); -export const sign: MultiVecOpV = vop(); -export const sin: MultiVecOpV = vop(); -export const cos: MultiVecOpV = vop(); -export const tan: MultiVecOpV = vop(); -export const asin: MultiVecOpV = vop(); -export const acos: MultiVecOpV = vop(); -export const atan: MultiVecOpV = vop(); -export const sqrt: MultiVecOpV = vop(); -export const floor: MultiVecOpV = vop(); -export const ceil: MultiVecOpV = vop(); -export const fract: MultiVecOpV = vop(); -export const trunc: MultiVecOpV = vop(); -export const log: MultiVecOpV = vop(); -export const exp: MultiVecOpV = vop(); -export const pow: MultiVecOpVV = vop(); -export const powN: MultiVecOpVN = vop(); - -export const min: MultiVecOpVV = vop(); -export const max: MultiVecOpVV = vop(); -export const clamp: MultiVecOpVVV = vop(); -clamp.default((a, b, c) => min(max(a, b), c)); - -export const minor: MultiVecOpV = vop(); -export const major: MultiVecOpV = vop(); - -export const mix: MultiVecOpVVV = vop(); -export const mixN: MultiVecOpVVN = vop(); -export const mixNew: MultiVecOpNewVVV = vop(); -export const mixNewN: MultiVecOpNewVVN = vop(); - -export const step: MultiVecOpVV = vop(); -export const smoothStep: MultiVecOpVVV = vop(); - -const _rotate = (u: number, v: number): VecOpVN => - (a: Vec, theta: number) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - const x = a[u]; - const y = a[v]; - a[u] = x * c - y * s; - a[v] = x * s + y * c; - return a; - }; - -export const rotateX = _rotate(1, 2); -export const rotateY = _rotate(2, 0); -export const rotateZ = _rotate(0, 1); - -export const polar: MultiVecOpV = vop(); -export const cartesian: MultiVecOpVO = vop(); - -export const reflect: VecOpVV = - (a, b) => maddN(a, b, -2 * dot(a, b)); - -export const refract: VecOpVVN = - (a, n, eta) => { - const d = dot(a, n); - const k = 1 - eta * eta * (1 - d * d); - return k < 0 ? - zero(a) : - maddN(mulN(a, eta), n, -(eta * d + Math.sqrt(k))); - }; - -export const headingXY = (a: ReadonlyVec) => atan2Abs(a[1], a[0]); -export const headingXZ = (a: ReadonlyVec) => atan2Abs(a[2], a[0]); -export const headingYZ = (a: ReadonlyVec) => atan2Abs(a[2], a[1]); - -export const angleRatio = - (a: ReadonlyVec, b: ReadonlyVec) => - dot(a, b) / (mag(a) * mag(b)); - -export const angleBetween: MultiVecOpRoVVO = vop(); - -const mi = -Infinity; -const mx = Infinity; -export const MIN4 = Object.freeze([mi, mi, mi, mi]); -export const MAX4 = Object.freeze([mx, mx, mx, mx]); -export const ONE4 = Object.freeze([1, 1, 1, 1]); -export const ZERO4 = Object.freeze([0, 0, 0, 0]); -export const X4 = Object.freeze([1, 0, 0, 0]); -export const Y4 = Object.freeze([0, 1, 0, 0]); -export const Z4 = Object.freeze([0, 0, 1, 0]); -export const W4 = Object.freeze([0, 0, 0, 1]); - -genCommonDefaults(); diff --git a/packages/vectors2/src/avec.ts b/packages/vectors2/src/avec.ts deleted file mode 100644 index e9a4ac24a0..0000000000 --- a/packages/vectors2/src/avec.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Vec } from "./api"; - -export abstract class AVec { - - buf: Vec; - i: number; - s: number; - - constructor(buf: Vec, i = 0, s = 1) { - this.buf = buf; - this.i = i; - this.s = s; - } - - abstract get length(): number; - - get dim() { - return 1; - } - - get offset() { - return this.i; - } - - get shape() { - return [this.length]; - } - - get stride() { - return [this.s]; - } -} diff --git a/packages/vectors2/src/index.ts b/packages/vectors2/src/index.ts deleted file mode 100644 index 2423847675..0000000000 --- a/packages/vectors2/src/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -export * from "./api"; -export * from "./pool"; - -export * from "./vec2"; -export * from "./vec3"; -export * from "./vec4"; - -export * from "./nd"; -export * from "./mat23"; -export * from "./mat33"; -export * from "./mat44"; -export * from "./quat"; diff --git a/packages/vectors2/src/internal/accessors.ts b/packages/vectors2/src/internal/accessors.ts deleted file mode 100644 index 95510fdcc3..0000000000 --- a/packages/vectors2/src/internal/accessors.ts +++ /dev/null @@ -1,29 +0,0 @@ -export const declareIndices = ( - proto: any, - props: string[], - strided = true, - defNumeric = true) => { - - const get = (i: number) => - strided ? - function () { return this.buf[this.i + i * this.s]; } : - function () { return this.buf[this.i + i]; }; - - const set = (i: number) => - strided ? - function (n: number) { this.buf[this.i + i * this.s] = n; } : - function (n: number) { this.buf[this.i + i] = n; }; - - props.forEach((id, i) => { - defNumeric && Object.defineProperty(proto, i, { - get: get(i), - set: set(i), - enumerable: true, - }); - Object.defineProperty(proto, id, { - get: get(i), - set: set(i), - enumerable: true, - }); - }); -}; diff --git a/packages/vectors2/src/internal/codegen.ts b/packages/vectors2/src/internal/codegen.ts deleted file mode 100644 index b1e00372e4..0000000000 --- a/packages/vectors2/src/internal/codegen.ts +++ /dev/null @@ -1,390 +0,0 @@ -import { - clamp as _clamp, - fract as _fract, - sign as _sign, - smoothStep as _smoothStep, - step as _step, - trunc as _trunc -} from "@thi.ng/math"; -import { SYSTEM } from "@thi.ng/random"; -import { - comp, - map, - mapIndexed, - push, - range, - take, - transduce, - tuples -} from "@thi.ng/transducers"; -import { - abs, - add, - addN, - addNew, - addNewN, - ceil, - cos, - div, - divN, - divNew, - divNewN, - exp, - floor, - fract, - madd, - maddN, - max, - min, - mix, - mixN, - mixNew, - mixNewN, - mul, - mulN, - mulNew, - mulNewN, - pow, - powN, - set, - setN, - sign, - sin, - smoothStep, - sqrt, - step, - sub, - subN, - subNew, - subNewN, - trunc, - Vec, - VecOpV, - VecOpVV, - VecOpVN, - VecOpNewVV, - VecOpNewVN, - rand01, - rand11, - log, - setS, - rand, - clamp, - maddNew, - maddNewN, - asin, - acos, - tan, - atan, - CommonOps, -} from "../api"; - -export type Template = (syms: string[], i?: number) => string; - -export const indices = (sym: string) => map((i) => `${sym}[${i}]`, range()); - -/** - * Takes a vector size `dim`, a code template function and an array of - * symbol names participating in the template. For each symbol, creates - * iterator of index lookups (e.g. `a[0]`), forms them into tuples and - * passes them to template to generate code. If the optional `ret` arg - * is not `null` (default `"a"`), appends a `return` statement to the - * result array, using `ret` as return value. Returns array of source - * code lines. - * - * The optional `pre` and `post` strings can be used to wrap the - * generated code. `post` will be injected **before** the generated - * return statement (if not suppressed). - * - * @param dim - * @param tpl - * @param syms - * @param ret - * @param pre - * @param post - */ -export const assemble = ( - dim: number, - tpl: Template, - syms: string, - ret = "a", - pre?: string, - post?: string) => { - - const src = transduce( - comp(take(dim), mapIndexed((i, x: string[]) => tpl(x, i))), - push(), - pre ? [pre] : [], - tuples.apply(null, [...map(indices, syms.split(","))]) - ); - post && src.push(post); - ret !== null && src.push(`return ${ret};`); - return src; -}; - -export const assembleG = ( - tpl: Template, - syms: string, - ret = "a", - pre?: string, - post?: string) => [ - pre, - "for(let i=a.length;--i>=0;) {", - tpl(syms.split(",").map((x) => `${x}[i]`)), - "}", - post, - ret !== null ? `return ${ret};` : "" - ]; - -export const compile = ( - dim: number, - tpl: Template, - args: string, - syms = args, - ret = "a", - pre?: string, - post?: string) => - - new Function(args, assemble(dim, tpl, syms, ret, pre, post).join("")); - -export const compileHOF = ( - dim: number, - fns: any[], - tpl: Template, - hofArgs: string, - args: string, - syms = args, - ret = "a", - pre?: string, - post?: string) => { - - return new Function( - hofArgs, - `return (${args})=>{${assemble(dim, tpl, syms, ret, pre, post).join("\n")}}` - )(...fns); -}; - -export const compileG = ( - tpl: Template, - args: string, - syms = args, - ret = "a", - pre?: string, - post?: string) => - - new Function(args, assembleG(tpl, syms, ret, pre, post).join("")); - -export const compileGHOF = ( - fns: any[], - tpl: Template, - hofArgs: string, - args: string, - syms = args, - ret = "a", - pre?: string, - post?: string) => { - - return new Function( - hofArgs, - `return (${args})=>{${assembleG(tpl, syms, ret, pre, post).join("\n")}}` - )(...fns); -}; - -const tplFnV = (fn) => ([a]) => `${a}=${fn}(${a});`; -const tplHofV = ([a]) => `${a}=fn(${a});`; -const tplVV = (op) => ([a, b]) => `${a}${op}=${b};` -const tplFnVV = (fn) => ([a, b]) => `${a}=${fn}(${a},${b});` -const tplVN = (op) => ([a]) => `${a}${op}=n;` -const tplNewVV = (op) => ([a, b, o]) => `${o}=${a}${op}${b};` -const tplNewVN = (op) => ([a, o]) => `${o}=${a}${op}n;`; -const tplRand01 = ([a]) => `${a}=rnd.float();` -const tplRand11 = ([a]) => `${a}=rnd.norm();` -const tplRand = ([a]) => `${a}=rnd.minmax(n,m);` -const tplMadd = ([a, b, c]) => `${a}+=${b}*${c};` -const tplMaddN = ([a, b]) => `${a}+=${b}*n;`; -const tplMaddNew = ([a, b, c, o]) => `${o}=${a}+${b}*${c};` -const tplMaddNewN = ([a, b, o]) => `${o}=${a}+${b}*n;`; -const tplPowN = ([a]) => `${a}=Math.pow(${a},n);`; -const tplClamp = ([a, b, c]) => `${a}=fn(${a},${b},${c});`; -const tplStep = ([a, e]) => `${a}=fn(${e},${a});`; -const tplSmoothStep = ([a, e1, e2]) => `${a}=fn(${e1},${e2},${a});`; -const tplMix = ([a, b, c]) => `${a}+=(${b}-${a})*${c};`; -const tplMixN = ([a, b]) => `${a}+=(${b}-${a})*n;`; -const tplMixNew = ([a, b, c, o]) => `${o}=${a}+(${b}-${a})*${c};`; -const tplMixNewN = ([a, b, o]) => `${o}=${a}+(${b}-${a})*n;`; - -export const genOpFnV = (dim: number, fn: string): VecOpV => - compile(dim, tplFnV(fn), "a"); - -export const genOpHofV = (dim: number, fn) => - compileHOF(dim, [fn], tplHofV, "fn", "a"); - -export const genOpVV = (dim: number, op: string): VecOpVV => - compile(dim, tplVV(op), "a,b"); - -export const genOpFnVV = (dim: number, fn: string): VecOpVV => - compile(dim, tplFnVV(fn), "a,b"); - -export const genOpVN = (dim: number, op: string): VecOpVN => - compile(dim, tplVN(op), "a,n", "a"); - -export const genOpNewVV = (dim: number, op: string): VecOpNewVV => - compile(dim, tplNewVV(op), "a,b,o=[]", "a,b,o", "o"); - -export const genOpNewVN = (dim: number, op: string): VecOpNewVN => - compile(dim, tplNewVN(op), "a,n,o=[]", "a,o", "o"); - -export const genCommon = (dim: number): CommonOps => [ - set.add(dim, genOpVV(dim, "")), - setN.add(dim, genOpVN(dim, "")), - setS.add(dim, compile(dim, ([a], i) => `${a}=xs[${i}];`, "a,...xs", "a")), - - rand01.add(dim, compileHOF(dim, [SYSTEM], tplRand01, "_rnd", "a,rnd=_rnd", "a")), - rand11.add(dim, compileHOF(dim, [SYSTEM], tplRand11, "_rnd", "a,rnd=_rnd", "a")), - rand.add(dim, compileHOF(dim, [SYSTEM], tplRand, "_rnd", "a,n,m,rnd=_rnd", "a")), - - add.add(dim, genOpVV(dim, "+")), - sub.add(dim, genOpVV(dim, "-")), - mul.add(dim, genOpVV(dim, "*")), - div.add(dim, genOpVV(dim, "/")), - - addNew.add(dim, genOpNewVV(dim, "+")), - subNew.add(dim, genOpNewVV(dim, "-")), - mulNew.add(dim, genOpNewVV(dim, "*")), - divNew.add(dim, genOpNewVV(dim, "/")), - - addN.add(dim, genOpVN(dim, "+")), - subN.add(dim, genOpVN(dim, "-")), - mulN.add(dim, genOpVN(dim, "*")), - divN.add(dim, genOpVN(dim, "/")), - - addNewN.add(dim, genOpNewVN(dim, "+")), - subNewN.add(dim, genOpNewVN(dim, "-")), - mulNewN.add(dim, genOpNewVN(dim, "*")), - divNewN.add(dim, genOpNewVN(dim, "/")), - - madd.add(dim, compile(dim, tplMadd, "a,b,c")), - maddN.add(dim, compile(dim, tplMaddN, "a,b,n", "a,b")), - maddNew.add(dim, compile(dim, tplMaddNew, "a,b,c,o=[]", "a,b,c,o", "o")), - maddNewN.add(dim, compile(dim, tplMaddNewN, "a,b,n,o=[]", "a,b,o", "o")), - - abs.add(dim, genOpFnV(dim, "Math.abs")), - sign.add(dim, genOpHofV(dim, _sign)), - sin.add(dim, genOpFnV(dim, "Math.sin")), - cos.add(dim, genOpFnV(dim, "Math.cos")), - tan.add(dim, genOpFnV(dim, "Math.tan")), - asin.add(dim, genOpFnV(dim, "Math.asin")), - acos.add(dim, genOpFnV(dim, "Math.acos")), - atan.add(dim, genOpFnV(dim, "Math.atan")), - floor.add(dim, genOpFnV(dim, "Math.floor")), - ceil.add(dim, genOpFnV(dim, "Math.ceil")), - trunc.add(dim, genOpFnV(dim, "Math.trunc")), - fract.add(dim, genOpHofV(dim, _fract)), - sqrt.add(dim, genOpFnV(dim, "Math.sqrt")), - log.add(dim, genOpFnVV(dim, "Math.log")), - exp.add(dim, genOpFnVV(dim, "Math.exp")), - pow.add(dim, genOpFnVV(dim, "Math.pow")), - powN.add(dim, compile(dim, tplPowN, "a,n", "a")), - - min.add(dim, genOpFnVV(dim, "Math.min")), - max.add(dim, genOpFnVV(dim, "Math.max")), - clamp.add(dim, compileHOF(dim, [_clamp], tplClamp, "fn", "a,b,c")), - - step.add(dim, compileHOF(dim, [_step], tplStep, "fn", "a,e")), - smoothStep.add(dim, compileHOF(dim, [_smoothStep], tplSmoothStep, "fn", "a,e1,e2")), - - mix.add(dim, compile(dim, tplMix, "a,b,c")), - mixN.add(dim, compile(dim, tplMixN, "a,b,n", "a,b")), - mixNew.add(dim, compile(dim, tplMixNew, "a,b,c,o=[]", "a,b,c,o", "o")), - mixNewN.add(dim, compile(dim, tplMixNewN, "a,b,n,o=[]", "a,b,o", "o")), -]; - -export const genGOpFnV = (fn: string): VecOpV => - compileG(tplFnV(fn), "a"); - -export const genGOpHofV = (fn) => - compileGHOF([fn], tplHofV, "fn", "a"); - -export const genGOpVV = (op: string): VecOpVV => - compileG(tplVV(op), "a,b"); - -export const genGOpFnVV = (fn: string): VecOpVV => - compileG(tplFnVV(fn), "a,b"); - -export const genGOpVN = (op: string): VecOpVN => - compileG(tplVN(op), "a,n", "a"); - -export const genGOpNewVV = (op: string): VecOpNewVV => - compileG(tplNewVV(op), "a,b,o=[]", "a,b,o", "o"); - -export const genGOpNewVN = (op: string): VecOpNewVN => - compileG(tplNewVN(op), "a,n,o=[]", "a,o", "o"); - -export const genCommonDefaults = (): CommonOps => [ - set.default(genGOpVV("")), - setN.default(genGOpVN("")), - setS.default(compileG(([a]) => `${a}=xs[i];`, "a,...xs", "a")), - - // rand01.default(compileG(tplRand01, "a")), - // rand11.default(compileG(tplRand11, "a")), - // rand.default(compileG(tplRand, "a,n,m", "a")), - - rand01.default(compileGHOF([SYSTEM], tplRand01, "_rnd", "a,rnd=_rnd", "a")), - rand11.default(compileGHOF([SYSTEM], tplRand11, "_rnd", "a,rnd=_rnd", "a")), - rand.default(compileGHOF([SYSTEM], tplRand, "_rnd", "a,n,m,rnd=_rnd", "a")), - - add.default(genGOpVV("+")), - sub.default(genGOpVV("-")), - mul.default(genGOpVV("*")), - div.default(genGOpVV("/")), - - addNew.default(genGOpNewVV("+")), - subNew.default(genGOpNewVV("-")), - mulNew.default(genGOpNewVV("*")), - divNew.default(genGOpNewVV("/")), - - addN.default(genGOpVN("+")), - subN.default(genGOpVN("-")), - mulN.default(genGOpVN("*")), - divN.default(genGOpVN("/")), - - addNewN.default(genGOpNewVN("+")), - subNewN.default(genGOpNewVN("-")), - mulNewN.default(genGOpNewVN("*")), - divNewN.default(genGOpNewVN("/")), - - madd.default(compileG(tplMadd, "a,b,c")), - maddN.default(compileG(tplMaddN, "a,b,n", "a,b")), - maddNew.default(compileG(tplMaddNew, "a,b,c,o=[]", "a,b,c,o", "o")), - maddNewN.default(compileG(tplMaddNewN, "a,b,n,o=[]", "a,b,o", "o")), - - abs.default(genGOpFnV("Math.abs")), - sign.default(genGOpHofV(_sign)), - sin.default(genGOpFnV("Math.sin")), - cos.default(genGOpFnV("Math.cos")), - tan.default(genGOpFnV("Math.tan")), - asin.default(genGOpFnV("Math.asin")), - acos.default(genGOpFnV("Math.acos")), - atan.default(genGOpFnV("Math.atan")), - floor.default(genGOpFnV("Math.floor")), - ceil.default(genGOpFnV("Math.ceil")), - trunc.default(genGOpFnV("Math.trunc")), - fract.default(genGOpHofV(_fract)), - sqrt.default(genGOpFnV("Math.sqrt")), - log.default(genGOpFnVV("Math.log")), - exp.default(genGOpFnVV("Math.exp")), - pow.default(genGOpFnVV("Math.pow")), - powN.default(compileG(tplPowN, "a,n", "a")), - - min.default(genGOpFnVV("Math.min")), - max.default(genGOpFnVV("Math.max")), - clamp.default(compileGHOF([_clamp], tplClamp, "fn", "a,b,c")), - - step.default(compileGHOF([_step], tplStep, "fn", "a,e")), - smoothStep.default(compileGHOF([_smoothStep], tplSmoothStep, "fn", "a,e1,e2")), - - mix.default(compileG(tplMix, "a,b,c")), - mixN.default(compileG(tplMixN, "a,b,n", "a,b")), - mixNew.default(compileG(tplMixNew, "a,b,c,o=[]", "a,b,c,o", "o")), - mixNewN.default(compileG(tplMixNewN, "a,b,n,o=[]", "a,b,o", "o")), -]; \ No newline at end of file diff --git a/packages/vectors2/src/internal/equiv.ts b/packages/vectors2/src/internal/equiv.ts deleted file mode 100644 index 69a85f4811..0000000000 --- a/packages/vectors2/src/internal/equiv.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { EPS, eqDelta as _eqDelta } from "@thi.ng/math"; -import { ReadonlyVec } from "../api"; - -/** - * Similar to `equiv()`, but takes tolerance `eps` into account for - * equality checks. - * - * @param a first vector - * @param b second vector - * @param n number of elements - * @param eps tolerance - * @param ia start index a - * @param ib start index b - * @param sa stride a - * @param sb stride b - */ -export const eqDelta = (a: ReadonlyVec, b: ReadonlyVec, n: number, eps = EPS, ia = 0, ib = 0, sa = 1, sb = 1) => { - for (; n > 0; n-- , ia += sa, ib += sb) { - if (!_eqDelta(a[ia], b[ib], eps)) { - return false; - } - } - return true; -}; - -export const eqDeltaArray = (a: ReadonlyVec[], b: ReadonlyVec[], eps = EPS) => { - if (a.length !== b.length) { - return false; - } - for (let i = a.length; --i >= 0;) { - if (!eqDelta(a[i], b[i], a[i].length, eps)) { - return false; - } - } - return true; -}; diff --git a/packages/vectors2/src/internal/iterator.ts b/packages/vectors2/src/internal/iterator.ts deleted file mode 100644 index 64db8e8b04..0000000000 --- a/packages/vectors2/src/internal/iterator.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Vec } from "../api"; - -export function* iterator(buf: Vec, n: number, i = 0, s = 1) { - for (; n > 0; n-- , i += s) { - yield buf[i]; - } -} diff --git a/packages/vectors2/src/internal/matrix.ts b/packages/vectors2/src/internal/matrix.ts deleted file mode 100644 index 29de9e0f38..0000000000 --- a/packages/vectors2/src/internal/matrix.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { ReadonlyVec, Vec } from "../api"; - -export const dot2 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - a[ia] * b[ib] + a[ia + sa] * b[ib + sb]; - -export const dot3 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - a[ia] * b[ib] + - a[ia + sa] * b[ib + sb] + - a[ia + 2 * sa] * b[ib + 2 * sb]; - -export const dot4 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - a[ia] * b[ib] + - a[ia + sa] * b[ib + sb] + - a[ia + 2 * sa] * b[ib + 2 * sb] + - a[ia + 3 * sa] * b[ib + 3 * sb]; - -export const set3 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => ( - a[ia] = b[ib], - a[ia + sa] = b[ib + sb], - a[ia + 2 * sa] = b[ib + 2 * sb], - a -); - -export const setS3 = (a: Vec, x: number, y: number, z: number, ia = 0, sa = 1) => - (a[ia] = x, a[ia + sa] = y, a[ia + 2 * sa] = z, a); - -export const setS4 = (a: Vec, x: number, y: number, z: number, w: number, ia = 0, sa = 1) => ( - a[ia] = x, - a[ia + sa] = y, - a[ia + 2 * sa] = z, - a[ia + 3 * sa] = w, - a -); - -export const cross2 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - a[ia] * b[ib + sb] - a[ia + sa] * b[ib]; diff --git a/packages/vectors2/src/internal/ops.ts b/packages/vectors2/src/internal/ops.ts deleted file mode 100644 index dd3b0231a6..0000000000 --- a/packages/vectors2/src/internal/ops.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { unsupported } from "@thi.ng/errors"; - -/** - * Specialized / optimized version of `@thi.ng/defmulti` for vector - * operations. Uses hardcoded logic to dispatch on length (vector size) - * of first argument. - */ -export const vop = () => { - const impls = new Array(5); - let fallback; - const fn = (...args: any[]) => { - const g = impls[args[0].length] || fallback; - return g ? g(...args) : unsupported(`no impl for vec size ${args[0].length}`); - }; - fn.add = (dim: number, fn) => (impls[dim] = fn); - fn.default = (fn) => (fallback = fn); - return fn; -}; diff --git a/packages/vectors2/src/mat23.ts b/packages/vectors2/src/mat23.ts deleted file mode 100644 index 33575f54d3..0000000000 --- a/packages/vectors2/src/mat23.ts +++ /dev/null @@ -1,301 +0,0 @@ -import { isArrayLike, isNumber } from "@thi.ng/checks"; -import { - IMatrix, - Mat, - ReadonlyMat, - ReadonlyVec, - Vec -} from "./api"; -import { declareIndices } from "./internal/accessors"; -import { iterator } from "./internal/iterator"; -import { cross2, dot2 } from "./internal/matrix"; -import { NDArray2 } from "./nd"; -import { setS2 } from "./vec2"; - -export const get23 = - (a: Mat, i = 0) => - (a).slice(i, i + 6); - -export const set23 = - (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => ( - a[ia] = b[ib], - a[ia + 1] = b[ib + 1], - a[ia + 2] = b[ib + 2], - a[ia + 3] = b[ib + 3], - a[ia + 4] = b[ib + 4], - a[ia + 5] = b[ib + 5], - a - ); - -/** - * ``` - * m00 m10 m20 - * m01 m11 m21 - * ``` - * - * @param m - * @param m00 - * @param m01 - * @param m10 - * @param m11 - * @param m20 - * @param m21 - * @param i - */ -export const setS23 = ( - m: Mat, - m00: number, m01: number, - m10: number, m11: number, - m20: number, m21: number, - i = 0) => ( - m[i] = m00, - m[i + 1] = m01, - m[i + 2] = m10, - m[i + 3] = m11, - m[i + 4] = m20, - m[i + 5] = m21, - m - ); - -export const identity23 = - (m?: Mat, i = 0) => - setS23(m || [], 1, 0, 0, 1, 0, 0, i); - -export const rotation23 = - (m: Mat, theta: number, i = 0) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS23(m || [], c, s, -s, c, 0, 0, i); - }; - -export const rotationAroundPoint23 = - (m: Mat, p: ReadonlyVec, theta: number, im = 0) => - concat23( - translationV23(m || [], p, im), im, - rotation23([], theta), - translationS23([], -p[0], -p[1]) - ); - -export const scaleV23 = - (m: Mat, v: Vec, i = 0) => - scaleS23(m, v[0], v[1], i); - -export const scaleN23 = - (m: Mat, n: number, i = 0) => - scaleS23(m, n, n, i); - -export const scaleS23 = - (m: Mat, sx: number, sy: number, i = 0) => - setS23(m || [], sx, 0, 0, sy, 0, 0, i); - -export const scaleWithCenter23 = - (m: Mat, p: ReadonlyVec, sx: number, sy: number, im = 0) => - concat23( - translationV23(m || [], p, im), im, - scaleS23([], sx, sy), - translationS23([], -p[0], -p[1]) - ); - -export const translationV23 = - (m: Mat, v: ReadonlyVec, i = 0) => - translationS23(m, v[0], v[1], i); - -export const translationS23 = - (m: Mat, x: number, y: number, i = 0) => - setS23(m || [], 1, 0, 0, 1, x, y, i); - -export const shearX23 = - (m: Mat, x: number, i = 0) => - setS23(m || [], 1, 0, x, 1, 0, 0, i); - -export const shearY23 = - (m: Mat, y: number, i = 0) => - setS23(m || [], 1, y, 0, 1, 0, 0, i); - -export const skewX23 = - (m: Mat, theta: number, i = 0) => - shearX23(m, Math.tan(theta), i); - -export const skewY23 = - (m: Mat, theta: number, i = 0) => - shearY23(m, Math.tan(theta), i); - -export const mul23 = - (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => - setS23( - a, - dot2(a, b, ia, ib, 2), - dot2(a, b, ia + 1, ib, 2), - dot2(a, b, ia, ib + 2, 2), - dot2(a, b, ia + 1, ib + 2, 2), - dot2(a, b, ia, ib + 4, 2) + a[ia + 4], - dot2(a, b, ia + 1, ib + 4, 2) + a[ia + 5], - ia - ); - -export const concat23 = - (a: Mat, ia: number, ...xs: (ReadonlyMat | [ReadonlyMat, number])[]) => - xs.reduce( - (acc: Mat, x) => isArrayLike(x[0]) ? - mul23(acc, x[0], ia, x[1]) : - mul23(acc, x, ia), - a - ); - -export const mulV23 = - (v: ReadonlyVec, m: ReadonlyMat, out: Vec = [], im = 0) => - setS2( - out, - dot2(m, v, im, 0, 2) + m[im + 4], - dot2(m, v, im + 1, 0, 2) + m[im + 5], - ); - -export const det23 = - (m: ReadonlyMat, i = 0) => - cross2(m, m, i, i + 1, 2, 2); - -export const invert23 = - (m: Mat, i = 0) => { - const m00 = m[i]; - const m01 = m[i + 1]; - const m10 = m[i + 2]; - const m11 = m[i + 3]; - const m20 = m[i + 4]; - const m21 = m[i + 5]; - let det = m00 * m11 - m01 * m10; - if (!det) { - return; - } - det = 1.0 / det; - return setS23( - m, - m11 * det, - -m01 * det, - -m10 * det, - m00 * det, - (m10 * m21 - m11 * m20) * det, - (m01 * m20 - m00 * m21) * det, - i - ); - } - -export class Mat23 extends NDArray2 implements - IMatrix { - - static identity() { - return new Mat23(identity23()); - } - - static rotation(theta: number) { - return new Mat23(rotation23([], theta)); - } - - static rotationAroundPoint(p: ReadonlyVec, theta: number) { - return new Mat23(rotationAroundPoint23([], p, theta)); - } - - static scale(v: ReadonlyVec): Mat23; - static scale(n: number): Mat23; - static scale(x: number, y: number): Mat23; - static scale(x: any, y = x) { - return new Mat23( - isNumber(x) ? - scaleS23([], x, y) : - scaleV23([], x) - ); - } - - static scaleWithCenter(p: ReadonlyVec, sx: number, sy = sx) { - return new Mat23(scaleWithCenter23([], p, sx, sy)); - } - - static translation(v: ReadonlyVec): Mat23; - static translation(x: number, y: number): Mat23; - static translation(x: any, y?: any) { - return new Mat23( - isNumber(x) ? - translationS23([], x, y) : - translationV23([], x) - ); - } - - static skewX(x: number) { - return new Mat23(skewX23([], x)); - } - - static skewY(y: number) { - return new Mat23(skewY23([], y)); - } - - static shearX(theta: number) { - return new Mat23(shearX23([], theta)); - } - - static shearY(theta: number) { - return new Mat23(shearY23([], theta)); - } - - static concat(m: Readonly, ...xs: Readonly[]) { - return new Mat23(concat23.apply(null, [ - get23(m.buf, m.i), 0, - ...<[ReadonlyMat, number][]>xs.map((x) => [x.buf, x.i])]) - ); - } - - [id: number]: number; - - constructor(buf?: Mat, i = 0) { - super(buf || [0, 0, 0, 0, 0, 0], [2, 3], [1, 2], i); - } - - [Symbol.iterator]() { - return iterator(this.buf, 6, this.i); - } - - get length() { - return 6; - } - - copy() { - return new Mat23([...this]); - } - - identity() { - identity23(this.buf, this.i); - return this; - } - - setM(m: Readonly) { - set23(this.buf, m.buf, this.i, m.i); - return this; - } - - setS(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number) { - setS23(this.buf, m00, m01, m10, m11, m20, m21, this.i); - return this; - } - - mul(m: Readonly) { - mul23(this.buf, m.buf, this.i, m.i); - return this; - } - - mulV(v: ReadonlyVec, out?: Vec) { - return mulV23(v, this.buf, out, this.i); - } - - determinant() { - return det23(this.buf, this.i); - } - - invert() { - invert23(this.buf, this.i); - return this; - } -} - -declareIndices( - Mat23.prototype, - ["m00", "m01", "m10", "m11", "m20", "m21"], - false -); diff --git a/packages/vectors2/src/mat33.ts b/packages/vectors2/src/mat33.ts deleted file mode 100644 index 6b1a42ee1b..0000000000 --- a/packages/vectors2/src/mat33.ts +++ /dev/null @@ -1,341 +0,0 @@ -import { isArrayLike, isNumber } from "@thi.ng/checks"; -import { - IMatrix, - Mat, - ReadonlyMat, - ReadonlyVec, - Vec -} from "./api"; -import { declareIndices } from "./internal/accessors"; -import { iterator } from "./internal/iterator"; -import { - dot3, - set3, - setS3, - setS4 -} from "./internal/matrix"; -import { NDArray2 } from "./nd"; - -export const get33 = - (a: Mat, i = 0) => - (a).slice(i, i + 9); - -export const set33 = - (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => ( - a[ia] = b[ib], - a[ia + 1] = b[ib + 1], - a[ia + 2] = b[ib + 2], - a[ia + 3] = b[ib + 3], - a[ia + 4] = b[ib + 4], - a[ia + 5] = b[ib + 5], - a[ia + 6] = b[ib + 6], - a[ia + 7] = b[ib + 7], - a[ia + 8] = b[ib + 8], - a - ); - -/** - * ``` - * m00 m10 m20 - * m01 m11 m21 - * m02 m12 m22 - * ``` - * - * @param m - * @param m00 - * @param m01 - * @param m02 - * @param m10 - * @param m11 - * @param m12 - * @param m20 - * @param m21 - * @param m22 - * @param i - */ -export const setS33 = ( - m: Mat, - m00: number, m01: number, m02: number, - m10: number, m11: number, m12: number, - m20: number, m21: number, m22: number, - i = 0) => ( - m[i] = m00, - m[i + 1] = m01, - m[i + 2] = m02, - m[i + 3] = m10, - m[i + 4] = m11, - m[i + 5] = m12, - m[i + 6] = m20, - m[i + 7] = m21, - m[i + 8] = m22, - m - ); - -export const identity33 = - (m?: Mat, i = 0) => - setS33(m || [], - 1, 0, 0, - 0, 1, 0, - 0, 0, 1, - i - ); - -export const rotationX33 = - (m: Mat, theta: number, i = 0) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS33(m || [], - 1, 0, 0, - 0, c, s, - 0, -s, c, - i - ); - }; - -export const rotationY33 = - (m: Mat, theta: number, i = 0) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS33(m || [], - c, 0, -s, - 0, 1, 0, - s, 0, c, - i - ); - }; - -export const rotationZ33 = - (m: Mat, theta: number, i = 0) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS33(m || [], - c, s, 0, - -s, c, 0, - 0, 0, 1, - i - ); - }; - -export const scaleV33 = - (m: Mat, v: ReadonlyVec, i = 0) => - scaleS33(m, v[0], v[1], v[2], i); - -export const scaleN33 = - (m: Mat, n: number, i = 0) => - scaleS33(m, n, n, n, i); - -export const scaleS33 = - (m: Mat, sx: number, sy: number, sz: number, i = 0) => - setS33(m || [], - sx, 0, 0, - 0, sy, 0, - 0, 0, sz, - i - ); - -export const mul33 = - (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => - setS33( - a, - dot3(a, b, ia, ib, 3), - dot3(a, b, ia + 1, ib, 3), - dot3(a, b, ia + 2, ib, 3), - dot3(a, b, ia, ib + 3, 3), - dot3(a, b, ia + 1, ib + 3, 3), - dot3(a, b, ia + 2, ib + 3, 3), - dot3(a, b, ia, ib + 6, 3), - dot3(a, b, ia + 1, ib + 6, 3), - dot3(a, b, ia + 2, ib + 6, 3), - ia - ); - -export const concat33 = - (a: Mat, ia: number, ...xs: (ReadonlyMat | [ReadonlyMat, number])[]) => - xs.reduce( - (acc: Mat, x) => isArrayLike(x[0]) ? - mul33(acc, x[0], ia, x[1]) : - mul33(acc, x, ia), - a - ); - -export const mulV33 = - (v: Vec, m: ReadonlyMat, out: Vec = [], im = 0) => - setS3( - out, - dot3(m, v, im, 0, 3), - dot3(m, v, im + 1, 0, 3), - dot3(m, v, im + 2, 0, 3), - ); - -export const det33 = - (m: ReadonlyMat, i = 0) => { - const m00 = m[i]; - const m01 = m[i + 1]; - const m02 = m[i + 2]; - const m10 = m[i + 3]; - const m11 = m[i + 4]; - const m12 = m[i + 5]; - const m20 = m[i + 6]; - const m21 = m[i + 7]; - const m22 = m[i + 8]; - const d01 = m22 * m11 - m12 * m21; - const d11 = -m22 * m10 + m12 * m20; - const d21 = m21 * m10 - m11 * m20; - return m00 * d01 + m01 * d11 + m02 * d21; - }; - -export const invert33 = - (m: Mat, i = 0) => { - const m00 = m[i]; - const m01 = m[i + 1]; - const m02 = m[i + 2]; - const m10 = m[i + 3]; - const m11 = m[i + 4]; - const m12 = m[i + 5]; - const m20 = m[i + 6]; - const m21 = m[i + 7]; - const m22 = m[i + 8]; - const d01 = m22 * m11 - m12 * m21; - const d11 = -m22 * m10 + m12 * m20; - const d21 = m21 * m10 - m11 * m20; - let det = m00 * d01 + m01 * d11 + m02 * d21; - if (!det) { - return; - } - det = 1.0 / det; - return setS33( - m, - d01 * det, - (-m22 * m01 + m02 * m21) * det, - (m12 * m01 - m02 * m11) * det, - d11 * det, - (m22 * m00 - m02 * m20) * det, - (-m12 * m00 + m02 * m10) * det, - d21 * det, - (-m21 * m00 + m01 * m20) * det, - (m11 * m00 - m01 * m10) * det, - i - ); - } - -export const transpose33 = - (m: Mat, i = 0) => - setS33( - m, - m[i], m[i + 3], m[i + 6], - m[i + 1], m[i + 4], m[i + 7], - m[i + 2], m[i + 5], m[i + 8], - i - ); - -export const mat33to44 = - (m44: Mat, m33: ReadonlyMat, ia = 0, ib = 0) => ( - set3(m44, m33, ia, ib), - set3(m44, m33, ia + 4, ib + 3), - set3(m44, m33, ia + 8, ib + 6), - setS3(m44, 0, 0, 0, ia + 12), - setS4(m44, 0, 0, 0, 1, ia + 3, 4), - m44 - ); - -export class Mat33 extends NDArray2 implements - IMatrix { - - static identity() { - return new Mat33(identity33()); - } - - static rotationX(theta: number) { - return new Mat33(rotationX33([], theta)); - } - - static rotationY(theta: number) { - return new Mat33(rotationY33([], theta)); - } - - static rotationZ(theta: number) { - return new Mat33(rotationZ33([], theta)); - } - - static scale(v: ReadonlyVec): Mat33; - static scale(n: number): Mat33; - static scale(x: number, y: number, z: number): Mat33; - static scale(x: any, y = x, z = x) { - return new Mat33( - isNumber(x) ? - scaleS33([], x, y, z) : - scaleV33([], x) - ); - } - - static concat(m: Readonly, ...xs: Readonly[]) { - return new Mat33(concat33.apply(null, [ - get33(m.buf, m.i), 0, - ...<[ReadonlyMat, number][]>xs.map((x) => [x.buf, x.i])]) - ); - } - - [id: number]: number; - - constructor(buf?: Mat, i = 0) { - super(buf || [0, 0, 0, 0, 0, 0, 0, 0, 0], [3, 3], [1, 3], i); - } - - [Symbol.iterator]() { - return iterator(this.buf, 9, this.i); - } - - get length() { - return 9; - } - - copy() { - return new Mat33([...this]); - } - - identity() { - identity33(this.buf, this.i); - return this; - } - - setM(m: Readonly) { - set33(this.buf, m.buf, this.i, m.i); - return this; - } - - setS(m00: number, m01: number, m02: number, - m10: number, m11: number, m12: number, - m20: number, m21: number, m22: number) { - setS33(this.buf, m00, m01, m02, m10, m11, m12, m20, m21, m22, this.i); - return this; - } - - mul(m: Readonly) { - mul33(this.buf, m.buf, this.i, m.i); - return this; - } - - mulV(v: ReadonlyVec, out?: Vec) { - return mulV33(v, this.buf, out, this.i); - } - - determinant() { - return det33(this.buf, this.i); - } - - invert() { - invert33(this.buf, this.i); - return this; - } - - transpose() { - transpose33(this.buf, this.i); - return this; - } -} - -declareIndices( - Mat33.prototype, - ["m00", "m01", "m02", "m10", "m11", "m12", "m20", "m21", "m22"], - false -); \ No newline at end of file diff --git a/packages/vectors2/src/mat44.ts b/packages/vectors2/src/mat44.ts deleted file mode 100644 index 0762c890a5..0000000000 --- a/packages/vectors2/src/mat44.ts +++ /dev/null @@ -1,582 +0,0 @@ -import { isArrayLike, isNumber } from "@thi.ng/checks"; -import { DEG2RAD } from "@thi.ng/math"; -import { - copy, - IMatrix, - Mat, - normalize, - ReadonlyMat, - ReadonlyVec, - Vec -} from "./api"; -import { declareIndices } from "./internal/accessors"; -import { iterator } from "./internal/iterator"; -import { - dot3, - dot4, - set3, - setS3, - setS4 -} from "./internal/matrix"; -import { Mat33 } from "./mat33"; -import { NDArray2 } from "./nd"; -import { cross3, sub3 } from "./vec3"; - -export const get44 = - (a: Mat, i = 0) => - (a).slice(i, i + 16); - -export const set44 = - (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => { - for (let i = 0; i < 16; i++) { - a[ia + i] = b[ib + i]; - } - return a; - }; - -/** - * ``` - * m00 m10 m20 m30 - * m01 m11 m21 m31 - * m02 m12 m22 m32 - * m03 m13 m23 m33 - * ``` - */ -export const setS44 = ( - m: Mat, - m00: number, m01: number, m02: number, m03: number, - m10: number, m11: number, m12: number, m13: number, - m20: number, m21: number, m22: number, m23: number, - m30: number, m31: number, m32: number, m33: number, - i = 0) => ( - m[i] = m00, - m[i + 1] = m01, - m[i + 2] = m02, - m[i + 3] = m03, - m[i + 4] = m10, - m[i + 5] = m11, - m[i + 6] = m12, - m[i + 7] = m13, - m[i + 8] = m20, - m[i + 9] = m21, - m[i + 10] = m22, - m[i + 11] = m23, - m[i + 12] = m30, - m[i + 13] = m31, - m[i + 14] = m32, - m[i + 15] = m33, - m - ); - -export const identity44 = - (m?: Mat, i = 0) => - setS44(m || [], - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1, - i - ); - -export const rotationX44 = - (m: Mat, theta: number, i = 0) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS44(m || [], - 1, 0, 0, 0, - 0, c, s, 0, - 0, -s, c, 0, - 0, 0, 0, 1, - i - ); - }; - -export const rotationY44 = - (m: Mat, theta: number, i = 0) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS44(m || [], - c, 0, -s, 0, - 0, 1, 0, 0, - s, 0, c, 0, - 0, 0, 0, 1, - i - ); - }; - -export const rotationZ44 = - (m: Mat, theta: number, i = 0) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS44(m || [], - c, s, 0, 0, - -s, c, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1, - i - ); - }; - -export const scaleV44 = - (m: Mat, v: ReadonlyVec, i = 0) => - scaleS44(m, v[0], v[1], v[2], i); - -export const scaleN44 = - (m: Mat, n: number, i = 0) => - scaleS44(m, n, n, n, i); - -export const scaleS44 = - (m: Mat, sx: number, sy: number, sz: number, i = 0) => - setS44(m || [], - sx, 0, 0, 0, - 0, sy, 0, 0, - 0, 0, sz, 0, - 0, 0, 0, 1, - i - ); - -export const scaleWithCenter44 = - (m: Mat, p: ReadonlyVec, sx: number, sy: number, sz: number, im = 0) => - concat44( - translationV44(m || [], p, im), im, - scaleS44([], sx, sy, sz), - translationS44([], -p[0], -p[1], -p[2]) - ); - -export const translationV44 = - (m: Mat, v: ReadonlyVec, i = 0) => - translationS44(m, v[0], v[1], v[2], i); - -export const translationS44 = - (m: Mat, x: number, y: number, z: number, i = 0) => - setS44(m || [], - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - x, y, z, 1, - i - ); - -export const frustum = - (m: Mat, left: number, right: number, bottom: number, top: number, near: number, far: number, i = 0) => { - const dx = 1 / (right - left); - const dy = 1 / (top - bottom); - const dz = 1 / (far - near); - return setS44(m || [], - near * 2 * dx, 0, 0, 0, - 0, near * 2 * dy, 0, 0, - (right + left) * dx, (top + bottom) * dy, -(far + near) * dz, -1, - 0, 0, -(far * near * 2) * dz, 0, - i - ); - }; - -export const frustumBounds = - (fovy: number, aspect: number, near: number, far: number) => { - const top = near * Math.tan(fovy * DEG2RAD / 2); - const right = top * aspect; - return { - left: -right, - right, - bottom: -top, - top, - near, - far - }; - }; - -export const perspective = - (m: Mat, fov: number, aspect: number, near: number, far: number, i = 0) => { - const f = frustumBounds(fov, aspect, near, far); - return frustum(m || [], f.left, f.right, f.bottom, f.top, f.near, f.far, i); - }; - -export const ortho = - (m: Mat, left: number, right: number, bottom: number, top: number, near: number, far: number, i = 0) => { - const dx = 1 / (right - left); - const dy = 1 / (top - bottom); - const dz = 1 / (far - near); - return setS44(m || [], - 2 * dx, 0, 0, 0, - 0, 2 * dy, 0, 0, - 0, 0, -2 * dz, 0, - -(left + right) * dx, -(top + bottom) * dy, -(far + near) * dz, 1, - i - ); - }; - -export const lookAt = - (m: Mat, eye: ReadonlyVec, target: ReadonlyVec, up: ReadonlyVec, im = 0) => { - const z = normalize(sub3(copy(eye), target)); - const x = normalize(cross3(copy(up), z)); - const y = normalize(cross3(z, x)); - return setS44(m || [], - x[0], y[0], z[0], 0, - x[1], y[1], z[1], 0, - x[2], y[2], z[2], 0, - -dot3(eye, x), -dot3(eye, y), -dot3(eye, z), 1, - im - ); - } - -export const mul44 = - (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => - setS44( - a, - dot4(a, b, ia, ib, 4), - dot4(a, b, ia + 1, ib, 4), - dot4(a, b, ia + 2, ib, 4), - dot4(a, b, ia + 3, ib, 4), - dot4(a, b, ia, ib + 4, 4), - dot4(a, b, ia + 1, ib + 4, 4), - dot4(a, b, ia + 2, ib + 4, 4), - dot4(a, b, ia + 3, ib + 4, 4), - dot4(a, b, ia, ib + 8, 4), - dot4(a, b, ia + 1, ib + 8, 4), - dot4(a, b, ia + 2, ib + 8, 4), - dot4(a, b, ia + 3, ib + 8, 4), - dot4(a, b, ia, ib + 12, 4), - dot4(a, b, ia + 1, ib + 12, 4), - dot4(a, b, ia + 2, ib + 12, 4), - dot4(a, b, ia + 3, ib + 12, 4), - ia - ); - -export const concat44 = - (a: Mat, ia: number, ...xs: (ReadonlyMat | [ReadonlyMat, number])[]) => - xs.reduce( - (acc: Mat, x) => isArrayLike(x[0]) ? - mul44(acc, x[0], ia, x[1]) : - mul44(acc, x, ia), - a - ); - -export const mulV344 = - (v: Vec, m: ReadonlyMat, im = 0) => - setS3( - v, - dot3(m, v, im, 0, 4) + m[12], - dot3(m, v, im + 1, 0, 4) + m[13], - dot3(m, v, im + 2, 0, 4) + m[14], - ); - -export const mulV44 = - (v: ReadonlyVec, m: ReadonlyMat, out: Vec = [], im = 0) => - setS4( - out, - dot4(m, v, im, 0, 4), - dot4(m, v, im + 1, 0, 4), - dot4(m, v, im + 2, 0, 4), - dot4(m, v, im + 3, 0, 4), - ); - -const detCoeffs44 = - (m: ReadonlyMat, i = 0) => { - const m00 = m[i]; - const m01 = m[i + 1]; - const m02 = m[i + 2]; - const m03 = m[i + 3]; - const m10 = m[i + 4]; - const m11 = m[i + 5]; - const m12 = m[i + 6]; - const m13 = m[i + 7]; - const m20 = m[i + 8]; - const m21 = m[i + 9]; - const m22 = m[i + 10]; - const m23 = m[i + 11]; - const m30 = m[i + 12]; - const m31 = m[i + 13]; - const m32 = m[i + 14]; - const m33 = m[i + 15]; - return [ - m00 * m11 - m01 * m10, - m00 * m12 - m02 * m10, - m00 * m13 - m03 * m10, - m01 * m12 - m02 * m11, - m01 * m13 - m03 * m11, - m02 * m13 - m03 * m12, - m20 * m31 - m21 * m30, - m20 * m32 - m22 * m30, - m20 * m33 - m23 * m30, - m21 * m32 - m22 * m31, - m21 * m33 - m23 * m31, - m22 * m33 - m23 * m32, - ]; - }; - -export const det44 = - (m: ReadonlyMat, i = 0) => { - const d = detCoeffs44(m, i); - return d[0] * d[11] - d[1] * d[10] + d[2] * d[9] + - d[3] * d[8] - d[4] * d[7] + d[5] * d[6]; - }; - -export const invert44 = - (m: Mat, i = 0) => { - const m00 = m[i]; - const m01 = m[i + 1]; - const m02 = m[i + 2]; - const m03 = m[i + 3]; - const m10 = m[i + 4]; - const m11 = m[i + 5]; - const m12 = m[i + 6]; - const m13 = m[i + 7]; - const m20 = m[i + 8]; - const m21 = m[i + 9]; - const m22 = m[i + 10]; - const m23 = m[i + 11]; - const m30 = m[i + 12]; - const m31 = m[i + 13]; - const m32 = m[i + 14]; - const m33 = m[i + 15]; - const d = detCoeffs44(m, i); - const d00 = d[0]; - const d01 = d[1]; - const d02 = d[2]; - const d03 = d[3]; - const d04 = d[4]; - const d05 = d[5]; - const d06 = d[6]; - const d07 = d[7]; - const d08 = d[8]; - const d09 = d[9]; - const d10 = d[10]; - const d11 = d[11]; - let det = (d00 * d11 - d01 * d10 + d02 * d09 + d03 * d08 - d04 * d07 + d05 * d06); - if (!det) { - return; - } - det = 1.0 / det; - return setS44( - m, - (m11 * d11 - m12 * d10 + m13 * d09) * det, - (-m01 * d11 + m02 * d10 - m03 * d09) * det, - (m31 * d05 - m32 * d04 + m33 * d03) * det, - (-m21 * d05 + m22 * d04 - m23 * d03) * det, - (-m10 * d11 + m12 * d08 - m13 * d07) * det, - (m00 * d11 - m02 * d08 + m03 * d07) * det, - (-m30 * d05 + m32 * d02 - m33 * d01) * det, - (m20 * d05 - m22 * d02 + m23 * d01) * det, - (m10 * d10 - m11 * d08 + m13 * d06) * det, - (-m00 * d10 + m01 * d08 - m03 * d06) * det, - (m30 * d04 - m31 * d02 + m33 * d00) * det, - (-m20 * d04 + m21 * d02 - m23 * d00) * det, - (-m10 * d09 + m11 * d07 - m12 * d06) * det, - (m00 * d09 - m01 * d07 + m02 * d06) * det, - (-m30 * d03 + m31 * d01 - m32 * d00) * det, - (m20 * d03 - m21 * d01 + m22 * d00) * det, - i - ); - } - -export const transpose44 = - (m: Mat, i = 0) => - setS44( - m, - m[i], m[i + 4], m[i + 8], m[i + 12], - m[i + 1], m[i + 5], m[i + 9], m[i + 13], - m[i + 2], m[i + 6], m[i + 10], m[i + 14], - m[i + 3], m[i + 7], m[i + 11], m[i + 15], - i - ); - -export const normal44 = - (a: Mat, b: ReadonlyMat, ia = 0, ib = 0): Mat => { - const m00 = b[ib]; - const m01 = b[ib + 1]; - const m02 = b[ib + 2]; - const m10 = b[ib + 4]; - const m11 = b[ib + 5]; - const m12 = b[ib + 6]; - const m20 = b[ib + 8]; - const m21 = b[ib + 9]; - const m22 = b[ib + 10]; - const d01 = m22 * m11 - m12 * m21; - const d11 = -m22 * m10 + m12 * m20; - const d21 = m21 * m10 - m11 * m20; - let det = m00 * d01 + m01 * d11 + m02 * d21; - if (!det) { - return; - } - det = 1.0 / det; - a[ia] = d01 * det; - a[ia + 1] = d11 * det; - a[ia + 2] = d21 * det; - a[ia + 3] = (-m22 * m01 + m02 * m21) * det; - a[ia + 4] = (m22 * m00 - m02 * m20) * det; - a[ia + 5] = (-m21 * m00 + m01 * m20) * det; - a[ia + 6] = (m12 * m01 - m02 * m11) * det; - a[ia + 7] = (-m12 * m00 + m02 * m10) * det; - a[ia + 8] = (m11 * m00 - m01 * m10) * det; - return a; - }; - -export const mat44to33 = - (m33: Mat, m44: ReadonlyMat, ia = 0, ib = 0) => ( - set3(m33, m44, ia, ib), - set3(m33, m44, ia + 3, ib + 4), - set3(m33, m44, ia + 6, ib + 8), - m33 - ); - -export class Mat44 extends NDArray2 implements - IMatrix { - - static identity() { - return new Mat44(identity44()); - } - - static rotationX(theta: number) { - return new Mat44(rotationX44([], theta)); - } - - static rotationY(theta: number) { - return new Mat44(rotationY44([], theta)); - } - - static rotationZ(theta: number) { - return new Mat44(rotationZ44([], theta)); - } - - static scale(v: ReadonlyVec): Mat44; - static scale(n: number): Mat44; - static scale(x: number, y: number, z: number): Mat44; - static scale(x: any, y = x, z = x) { - return new Mat44( - isNumber(x) ? - scaleS44([], x, y, z) : - scaleV44([], x) - ); - } - - static scaleWithCenter(p: ReadonlyVec, sx: number, sy = sx, sz = sy) { - return new Mat44(scaleWithCenter44([], p, sx, sy, sz)); - } - - static translation(v: ReadonlyVec): Mat44; - static translation(x: number, y: number, z: number): Mat44; - static translation(x: any, y?: any, z?: any) { - return new Mat44( - isNumber(x) ? - translationS44([], x, y, z) : - translationV44([], x) - ); - } - - static perspective(fov: number, aspect: number, near: number, far: number) { - return new Mat44(perspective([], fov, aspect, near, far)); - } - - static ortho(left: number, right: number, bottom: number, top: number, near: number, far: number) { - return new Mat44(ortho([], left, right, bottom, top, near, far)); - } - - static frustum(left: number, right: number, bottom: number, top: number, near: number, far: number) { - return new Mat44(frustum([], left, right, bottom, top, near, far)); - } - - static lookAt(eye: ReadonlyVec, target: ReadonlyVec, up: ReadonlyVec) { - return new Mat44(lookAt([], eye, target, up)); - } - - static concat(m: Readonly, ...xs: Readonly[]) { - return new Mat44(concat44.apply(null, [ - get44(m.buf, m.i), 0, - ...<[ReadonlyMat, number][]>xs.map((x) => [x.buf, x.i])]) - ); - } - - [id: number]: number; - - constructor(buf?: Mat, i = 0) { - super(buf || (new Array(16).fill(0)), [4, 4], [1, 4], i); - } - - [Symbol.iterator]() { - return iterator(this.buf, 16, this.i); - } - - get length() { - return 16; - } - - copy() { - return new Mat44([...this]); - } - - identity() { - identity44(this.buf, this.i); - return this; - } - - setM(m: Readonly) { - set44(this.buf, m.buf, this.i, m.i); - return this; - } - - setS(m00: number, m01: number, m02: number, m03: number, - m10: number, m11: number, m12: number, m13: number, - m20: number, m21: number, m22: number, m23: number, - m30: number, m31: number, m32: number, m33: number) { - setS44( - this.buf, - m00, m01, m02, m03, - m10, m11, m12, m13, - m20, m21, m22, m23, - m30, m31, m32, m33, - this.i - ); - return this; - } - - mul(m: Readonly) { - mul44(this.buf, m.buf, this.i, m.i); - return this; - } - - mulV3(v: Vec) { - mulV344(v, this.buf, this.i); - return v; - } - - mulV(v: ReadonlyVec, out?: Vec) { - return mulV44(v, this.buf, out, this.i); - } - - determinant() { - return det44(this.buf, this.i); - } - - invert() { - invert44(this.buf, this.i); - return this; - } - - transpose() { - transpose44(this.buf, this.i); - return this; - } - - normalMat(m?: Mat33) { - !m && (m = new Mat33([])); - normal44(m.buf, this.buf, m.i, this.i); - return m; - } - - toMat33(m?: Mat33) { - !m && (m = new Mat33([])); - mat44to33(m.buf, this.buf, m.i, this.i); - return m; - } -} - -declareIndices( - Mat44.prototype, - [ - "m00", "m01", "m02", "m03", - "m10", "m11", "m12", "m13", - "m20", "m21", "m22", "m23", - "m30", "m31", "m32", "m33" - ], - false -); diff --git a/packages/vectors2/src/nd.ts b/packages/vectors2/src/nd.ts deleted file mode 100644 index 2612b3a87d..0000000000 --- a/packages/vectors2/src/nd.ts +++ /dev/null @@ -1,588 +0,0 @@ -import { isArrayLike, isIterable, isNumber } from "@thi.ng/checks"; -import { equiv, equivArrayLike } from "@thi.ng/equiv"; -import { illegalArgs, unsupported } from "@thi.ng/errors"; -import { EPS } from "@thi.ng/math"; -import { - floatFixedWidth, - padLeft, - Stringer, - truncate -} from "@thi.ng/strings"; -import { INDArray, NDVec } from "./api"; -import { declareIndices } from "./internal/accessors"; -import { eqDelta as _eqDelta } from "./internal/equiv"; -import { iterator } from "./internal/iterator"; - -export class NDArray1 implements - INDArray { - - static mapBuffer(buf: NDVec, num: number, size: number, start = 0, cstride = 1, estride = size) { - const res: NDArray1[] = []; - while (--num >= 0) { - res.push(new NDArray1(buf, [size], [cstride], start)); - start += estride; - } - return res; - } - - static intoBuffer(buf: NDVec, src: Iterable>, start: number, cstride: number, estride: number) { - for (let v of src) { - let i = start; - for (let x of v) { - buf[i] = x; - i += cstride; - } - start += estride; - } - return buf; - } - - buf: NDVec; - i: number; - s: number; - readonly length: number; - - x: number; - y: number; - z: number; - w: number; - [id: number]: number; - - constructor(buf: NDVec, shape: number[], strides: number[], offset = 0) { - this.buf = buf; - this.i = offset; - this.s = strides[0]; - this.length = shape[0]; - } - - [Symbol.iterator](): IterableIterator { - return iterator(this.buf, this.length, this.i, this.s); - } - - get dim() { - return 1; - } - - get offset() { - return this.i; - } - - get order() { - return [0]; - } - - get shape() { - return [this.length]; - } - - get stride() { - return [this.s]; - } - - copy() { - return new NDArray1( - [...this], - [this.shape[0]], - [1], - this.i - ); - } - - equiv(o: any) { - return this === o || - (isArrayLike(o) && - isIterable(o) && - this.length === o.length && - equivArrayLike([...this], [...o])); - } - - eqDelta(o: NDArray1, eps = EPS) { - return this === o || - _eqDelta([...this], [...o], this.length, eps); - } - - index(x: number) { - return this.i + x * this.s; - } - - get(x: number) { - return this.buf[this.i + x * this.s]; - } - - set(x: number, v: T) { - this.buf[this.i + x * this.s] = v; - return this; - } - - hi(x: number) { - return new NDArray1( - this.buf, - [x != null && x >= 0 ? x : this.shape[0]], - this.stride, - this.i - ); - } - - lo(x: number) { - const s = this.shape; - const t = this.stride; - let o = this.i; - return new NDArray1( - this.buf, - [x != null && x >= 0 ? (o += t[0] * x, s[0] - x) : s[0]], - t, o - ); - } - - step(x: number) { - const s = this.shape.slice(); - const t = this.stride.slice(); - return new NDArray1(this.buf, s, t, step(x, 0, s, t, this.i)); - } - - pick(x: number) { - return x != null && x >= 0 ? - new NDArray1(this.buf, [1], [1], this.i + x * this.s) : - undefined - } - - transpose() { - return this.copy() - } - - toJSON() { - return { - buf: [...this], - shape: this.shape, - stride: [1], - }; - } - - toString() { - const res = []; - for (let x of this) { - res.push(format(x)); - } - return res.join(" "); - } -} - -declareIndices(NDArray1.prototype, ["x", "y", "z", "w"]); - -export class NDArray2 implements - INDArray { - - buf: NDVec; - i: number; - shape: number[]; - stride: number[]; - - protected _n: number; - - constructor(buf: NDVec, shape: number[], stride: number[], offset = 0) { - this.buf = buf; - this.i = offset; - this.shape = shape; - this.stride = stride; - } - - *[Symbol.iterator]() { - const buf = this.buf; - const [sx, sy] = this.shape; - const [tx, ty] = this.stride; - for (let i = this.i, x = 0; x < sx; x++ , i += tx) { - for (let y = 0; y < sy; y++) { - yield buf[i + y * ty]; - } - } - } - - get length() { - return this._n || (this._n = this.shape.reduce((acc, x) => acc * x, 1)); - } - - get dim() { - return 2; - } - - get offset() { - return this.i; - } - - get order() { - return Math.abs(this.stride[1]) > Math.abs(this.stride[0]) ? - [1, 0] : - [0, 1]; - } - - copy() { - return new NDArray2( - [...this.buf], - [...this.shape], - shapeToStride(this.shape), - this.i - ); - } - - equiv(o: any) { - return this === o || - (o instanceof NDArray2 && - equiv(this.shape, o.shape) && - equivArrayLike([...this], [...o])); - } - - eqDelta(o: NDArray2, eps = EPS) { - return this === o || - (equiv(this.shape, o.shape) && - _eqDelta([...this], [...o], this.length, eps)); - } - - index(x: number, y: number) { - const t = this.stride; - return this.i + x * t[0] + y * t[1]; - } - - get(x: number, y: number) { - const t = this.stride; - return this.buf[this.i + x * t[0] + y * t[1]]; - } - - set(x: number, y: number, v: T) { - const t = this.stride; - this.buf[this.i + x * t[0] + y * t[1]] = v; - return this; - } - - hi(x?: number, y?: number) { - const s = this.shape; - return new NDArray2( - this.buf, - [ - x != null && x >= 0 ? x : s[0], - y != null && y >= 0 ? y : s[1], - ], - this.stride, - this.i - ); - } - - lo(x?: number, y?: number) { - const s = this.shape; - const t = this.stride; - let o = this.i; - return new NDArray2( - this.buf, - [ - x != null && x >= 0 ? (o += t[0] * x, s[0] - x) : s[0], - y != null && y >= 0 ? (o += t[1] * y, s[1] - y) : s[1] - ], - t, o - ); - } - - step(x?: number, y?: number) { - const s = this.shape.slice(); - const t = this.stride.slice(); - return new NDArray2( - this.buf, s, t, - step(y, 1, s, t, step(x, 0, s, t, this.i)) - ); - } - - pick(x?: number, y?: number) { - const s = []; - const t = []; - return ndarray(this.buf, s, t, - pick(y, 1, s, t, this.shape, this.stride, - pick(x, 0, s, t, this.shape, this.stride, this.i)) - ); - } - - transpose(x: number, y: number) { - const s = this.shape; - const t = this.stride; - return new NDArray2(this.buf, [s[x], s[y]], [t[x], t[y]], this.i); - } - - toJSON() { - return { - buf: [...this], - shape: this.shape, - stride: shapeToStride(this.shape), - }; - } - - toString() { - const res = []; - for (let i = 0; i < this.shape[0]; i++) { - res.push(this.pick(i).toString()); - } - return res.join("\n"); - } -} - -export class NDArray3 implements - INDArray { - - buf: NDVec; - i: number; - shape: number[]; - stride: number[]; - - protected _n: number; - - constructor(buf: NDVec, shape: number[], stride: number[], offset = 0) { - this.buf = buf; - this.shape = shape; - this.stride = stride; - this.i = offset; - } - - *[Symbol.iterator]() { - const buf = this.buf; - const [sx, sy, sz] = this.shape; - const [tx, ty, tz] = this.stride; - for (let i = this.i, x = sx; --x >= 0; i += tx) { - for (let j = i, y = sy; --y >= 0; j += ty) { - for (let z = 0; z < sz; z++) { - yield buf[j + z * tz]; - } - } - } - } - - get length() { - return this._n || (this._n = this.shape.reduce((acc, x) => acc * x, 1)); - } - - get dim() { - return 3; - } - - get offset() { - return this.i; - } - - get order() { - return strideOrder(this.stride); - } - - index(x: number, y: number, z: number) { - const t = this.stride; - return this.i + x * t[0] + y * t[1] + z * t[2]; - } - - get(x: number, y: number, z: number) { - const t = this.stride; - return this.buf[this.i + x * t[0] + y * t[1] + z * t[2]]; - } - - set(x: number, y: number, z: number, v: T) { - const t = this.stride; - this.buf[this.i + x * t[0] + y * t[1] + z * t[2]] = v; - } - - copy() { - return new NDArray2( - [...this.buf], - [...this.shape], - shapeToStride(this.shape), - this.i - ); - } - - equiv(o: any) { - return this === o || - (o instanceof NDArray3 && - equiv(this.shape, o.shape) && - equivArrayLike([...this], [...o])); - } - - eqDelta(o: NDArray3, eps = EPS) { - return this === o || - (equiv(this.shape, o.shape) && - _eqDelta([...this], [...o], this.length, eps)); - } - - hi(x?: number, y?: number, z?: number) { - const s = this.shape; - return new NDArray3( - this.buf, - [ - x != null && x >= 0 ? x : s[0], - y != null && y >= 0 ? y : s[1], - z != null && z >= 0 ? z : s[2], - ], - this.stride, - this.i - ); - } - - lo(x?: number, y?: number, z?: number) { - const s = this.shape; - const t = this.stride; - let o = this.i; - return new NDArray3( - this.buf, - [ - x != null && x >= 0 ? (o += t[0] * x, s[0] - x) : s[0], - y != null && y >= 0 ? (o += t[1] * y, s[1] - y) : s[1], - z != null && z >= 0 ? (o += t[2] * z, s[2] - y) : s[2], - ], - t, o - ); - } - - step(x?: number, y?: number, z?: number) { - const s = this.shape.slice(); - const t = this.stride.slice(); - return new NDArray3( - this.buf, s, t, - step(z, 2, s, t, - step(y, 1, s, t, - step(x, 0, s, t, this.i))) - ); - } - - pick(x?: number, y?: number, z?: number) { - const s = []; - const t = []; - const ss = this.shape; - const st = this.stride; - return ndarray( - this.buf, s, t, - pick(z, 2, s, t, ss, st, - pick(y, 1, s, t, ss, st, - pick(x, 0, s, t, ss, st, this.i))) - ); - } - - transpose(x: number, y: number, z: number) { - const s = this.shape; - const t = this.stride; - return new NDArray3(this.buf, [s[x], s[y], s[z]], [t[x], t[y], t[z]], this.i); - } - - toJSON() { - return { - buf: [...this], - shape: this.shape, - stride: shapeToStride(this.shape), - }; - } - - toString() { - const res = []; - for (let i = 0; i < this.shape[0]; i++) { - res.push(`--- ${i}: ---`, this.pick(i).toString()); - } - return res.join("\n"); - } -} - -export const ndarray = ( - buf?: NDVec, - shape?: number[], - strides?: number[], - offset?: number): INDArray => { - - if (!(buf || shape)) { - illegalArgs("data or shape must be provided"); - } - buf = buf || new Array(shape.reduce((a, b) => a * b, 1)).fill(0); - !shape && (shape = [buf.length]); - !strides && (strides = shapeToStride(shape)); - if (offset === undefined) { - offset = 0; - for (let i = 0; i < shape.length; i++) { - if (strides[i] < 0) { - offset -= (shape[i] - 1) * strides[i]; - } - } - } - switch (shape.length) { - case 0: - return new NDArray1(buf, [1], [1], offset); - case 1: - return new NDArray1(buf, shape, strides, offset); - case 2: - return new NDArray2(buf, shape, strides, offset); - case 3: - return new NDArray3(buf, shape, strides, offset); - default: - unsupported(`unsupported dimension: ${shape.length}`); - } -} - -const shapeToStride = - (shape: number[]) => { - const n = shape.length; - const stride = new Array(n); - for (let i = n, s = 1; --i >= 0; s *= shape[i]) { - stride[i] = s; - } - return stride; - }; - -const strideOrder = - (strides: number[]) => - strides - .map((x, i) => [x, i]) - .sort((a, b) => Math.abs(b[0]) - Math.abs(a[0])) - .map((x) => x[1]); - -const step = ( - x: number, - i: number, - shape: number[], - strides: number[], - o: number) => { - - if (x) { - if (x < 0) { - o += strides[i] * (shape[i] - 1); - shape[i] = Math.ceil(-shape[i] / x); - } else { - shape[i] = Math.ceil(shape[i] / x); - } - strides[i] *= x; - } - return o; -}; - -const pick = ( - x: number, - i: number, - ds: number[], - dt: number[], - ss: number[], - st: number[], - o: number) => { - - if (x != null && x >= 0) { - o += st[i] * x; - } else { - ds.push(ss[i]); - dt.push(st[i]); - } - return o; -}; - -let formatNumber: Stringer; -let pad: Stringer; -let trunc: Stringer; - -const format = - (x: any) => - isNumber(x) ? - formatNumber(x) : - trunc(pad(x.toString())); - -export const setFormat = - (width: number, prec: number) => { - formatNumber = floatFixedWidth(width, prec); - pad = padLeft(width); - trunc = truncate(width); - }; - -setFormat(9, 4); diff --git a/packages/vectors2/src/pool.ts b/packages/vectors2/src/pool.ts deleted file mode 100644 index a9e2b350a8..0000000000 --- a/packages/vectors2/src/pool.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { NumericArray, TypedArray } from "@thi.ng/api"; -import { isTypedArray } from "@thi.ng/checks"; -import { - MemPool, - MemPoolOpts, - MemPoolStats, - Type -} from "@thi.ng/malloc"; -import { IVecPool, IVector, Vec } from "./api"; -import { NDArray1 } from "./nd"; -import { Vec2 } from "./vec2"; -import { Vec3 } from "./vec3"; -import { Vec4 } from "./vec4"; - -const F64 = Type.F64; - -export class VecPool implements - IVecPool { - - pool: MemPool; - - constructor(pool: MemPool); - constructor(buf: number | ArrayBuffer, opts?: Partial); - constructor(pool: any, opts?: Partial) { - this.pool = !(pool instanceof MemPool) ? - new MemPool(pool, opts) : - pool; - } - - stats(): MemPoolStats { - return this.pool.stats(); - } - - malloc(size: number, type: Type = F64): TypedArray { - return this.pool.callocAs(type, size); - } - - mallocWrapped(size: number, stride = 1, type: Type = F64): Vec { - const buf = this.pool.callocAs(type, size * stride); - return wrapped(buf, size, 0, stride); - - } - - /** - * Intended to provide individual vector views of a larger - * underlying buffer. Attempts to allocate a single block of - * sufficient memory to hold `num` vectors of `size` elements and if - * successful returns array of vectors mapping the buffer with given - * stride lengths (both component and element strides can be - * provided). - * - * *Note:* Since all result vectors share the same continuous memory - * block, freeing any of them from the pool will invalidate all of - * them. - * - * Also see: - * - `Vec2.mapBuffer()` - * - `Vec3.mapBuffer()` - * - `Vec4.mapBuffer()` - * - `NDArray1.mapBuffer()` - * - * @param num - * @param size - * @param cstride - * @param estride - * @param type - */ - mallocArray(num: number, size: number, cstride = 1, estride = size, type: Type = F64): Vec[] { - const buf = this.malloc(Math.max(cstride, estride, size) * num, type); - if (!buf) return; - const res: Vec[] = []; - for (let i = 0; i < num; i += estride) { - res.push(wrapped(buf, size, i, cstride)); - } - return res; - } - - free(vec: IVector | TypedArray) { - const buf = (vec).buf; - if (buf) { - return isTypedArray(buf) ? - this.pool.free(buf) : - false; - } - return this.pool.free(vec); - } - - freeAll() { - this.pool.freeAll(); - } - - release() { - const res = this.pool.release(); - res && delete this.pool; - return res; - } -} - -const wrapped = - (buf: NumericArray, size: number, idx: number, stride: number) => { - switch (size) { - case 2: - return new Vec2(buf, idx, stride); - case 3: - return new Vec3(buf, idx, stride); - case 4: - return new Vec4(buf, idx, stride); - default: - return new NDArray1(buf, [size], [stride], idx); - } - }; diff --git a/packages/vectors2/src/quat.ts b/packages/vectors2/src/quat.ts deleted file mode 100644 index 6ef91e8a50..0000000000 --- a/packages/vectors2/src/quat.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { - dot, - magSq, - ReadonlyVec, - Vec -} from "./api"; -import { maddN4, mulN4, Vec4 } from "./vec4"; - -export const mulQ = - (a: Vec, b: ReadonlyVec) => { - const [ax, ay, az, aw] = a; - const [bx, by, bz, bw] = b; - a[0] = ax * bw + aw * bx + ay * bz - az * by; - a[1] = ay * bw + aw * by + az * bx - ax * bz; - a[2] = az * bw + aw * bz + ax * by - ay * bx; - a[3] = aw * bw - ax * bx - ay * by - az * bz; - return a; - }; - -export const mulVQ = - (p: Vec, q: ReadonlyVec) => { - const [px, py, pz] = p; - const [qx, qy, qz, qw] = q; - const ix = qw * px + qy * pz - qz * py; - const iy = qw * py + qz * px - qx * pz; - const iz = qw * pz + qx * py - qy * px; - const iw = -qx * px - qy * py - qz * pz; - p[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy; - p[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz; - p[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx; - return p; - }; - -export const conjugateQ = - (a: Vec) => (a[0] *= -1, a[1] *= -1, a[2] *= -1, a); - -export const invertQ = - (a: Vec) => { - let d = magSq(a); - d = d > 0 ? -1 / d : 0; - a[0] *= d; - a[1] *= d; - a[2] *= d; - a[3] *= -d; - return a; - }; - -export const mixQ = - (a: Vec, b: ReadonlyVec, t: number, eps = 1e-3) => { - const d = dot(a, b); - if (Math.abs(d) < 1.0) { - const theta = Math.acos(d); - const stheta = Math.sqrt(1 - d * d); - let u, v; - if (Math.abs(stheta) < eps) { - u = v = 0.5; - } else { - u = Math.sin(theta * (1 - t)) / stheta; - v = Math.sin(theta * t) / stheta; - } - return maddN4(mulN4(a, u), b, v); - } - }; - -export class Quat extends Vec4 { - - static fromAxisAngle(axis: ReadonlyVec, theta: number) { - return quatFromAxisAngle(axis, theta); - } - - mulQ(q: Quat) { - mulQ(this, q); - return this; - } - - mulV(p: Vec) { - return mulVQ(p, this); - } - - mixQ(q: Quat, t: number) { - mixQ(this, q, t); - return this; - } -} - -export const quat = - (x = 0, y = 0, z = 0, w = 1) => new Quat([x, y, z, w]); - -export const quatFromAxisAngle = - (axis: ReadonlyVec, theta: number) => { - theta /= 2; - const s = Math.sin(theta); - return new Quat([ - s * axis[0], - s * axis[1], - s * axis[2], - Math.cos(theta) - ]); - }; diff --git a/packages/vectors2/src/vec2.ts b/packages/vectors2/src/vec2.ts deleted file mode 100644 index 85db0c6c05..0000000000 --- a/packages/vectors2/src/vec2.ts +++ /dev/null @@ -1,318 +0,0 @@ -import { Comparator } from "@thi.ng/api"; -import { - EPS, - eqDelta as _eqDelta, - HALF_PI, - max2id, - min2id, - mixBilinear, - PI -} from "@thi.ng/math"; -import { AVec } from "./avec"; -import { declareIndices } from "./internal/accessors"; -import { genCommon } from "./internal/codegen"; -import { - magSq, - dot, - Vec, - IVector, - minor, - major, - polar, - mag, - cartesian, - distSq, - distManhattan, - distChebyshev, - headingXY, - angleBetween, - angleRatio, - eqDelta, - Vec2Coord, - VecOpRoVV, - VecOpVVN, - VecOpV, - X4, - Y4, - Z4, - MIN4, - MAX4, - ZERO4, - ONE4, - ReadonlyVec, - dist, -} from "./api"; - -export class Vec2 extends AVec implements - IVector { - - /** - * Returns array of memory mapped `Vec2` instances using given - * backing array and stride settings: The `cstride` is the step size - * between individual XY vector components. `estride` is the step - * size between successive vectors. This arrangement allows for - * different storage approaches, incl. SOA, AOS, striped / - * interleaved etc. - * - * @param buf backing array - * @param n num vectors - * @param start start index - * @param cstride component stride - * @param estride element stride - */ - static mapBuffer(buf: Vec, n: number = buf.length >> 1, start = 0, cstride = 1, estride = 2) { - const res: Vec2[] = []; - while (--n >= 0) { - res.push(new Vec2(buf, start, cstride)); - start += estride; - } - return res; - } - - /** - * Merges given `src` iterable of `Vec2`s into single array `buf`. - * Vectors will be arranged according to given component and element - * strides, starting at `start` index. It's the user's - * responsibility to ensure the target buffer has sufficient - * capacity to hold the input vectors. See `Vec2.mapBuffer` for the - * inverse operation. Returns `buf`. - * - * @param buf - * @param src - * @param start - * @param cstride - * @param estride - */ - static intoBuffer(buf: Vec, src: Iterable>, start = 0, cstride = 1, estride = 2) { - for (let v of src) { - buf[start] = v[0]; - buf[start + cstride] = v[1]; - start += estride; - } - return buf; - } - - static readonly X_AXIS = new Vec2(X4); - static readonly Y_AXIS = new Vec2(Y4); - static readonly Z_AXIS = new Vec2(Z4); - static readonly MIN = new Vec2(MIN4); - static readonly MAX = new Vec2(MAX4); - static readonly ZERO = new Vec2(ZERO4); - static readonly ONE = new Vec2(ONE4); - - x: number; - y: number; - [id: number]: number; - - constructor(buf?: Vec, i = 0, s = 1) { - super(buf || [0, 0], i, s); - } - - *[Symbol.iterator]() { - yield this.x; - yield this.y; - } - - get length() { - return 2; - } - - copy() { - return new Vec2([this.x, this.y]); - } - - empty() { - return new Vec2(); - } - - eqDelta(v: ReadonlyVec, eps = EPS) { - return eqDelta(this, v, eps); - } - - toJSON() { - return [this.x, this.y]; - } - - toString() { - return `[${this.x}, ${this.y}]`; - } -} - -declareIndices(Vec2.prototype, ["x", "y"]); - -export const [ - set2, - setN2, - setS2, - rand2_01, - rand2_11, - rand2, - add2, - sub2, - mul2, - div2, - addNew2, - subNew2, - mulNew2, - divNew2, - addN2, - subN2, - mulN2, - divN2, - addNewN2, - subNewN2, - mulNewN2, - divNewN2, - madd2, - maddN2, - maddNew2, - maddNewN2, - abs2, - sign2, - sin2, - cos2, - tan2, - asin2, - acos2, - atan2, - floor2, - ceil2, - trunc2, - fract2, - sqrt2, - log2, - exp2, - pow2, - powN2, - min2, - max2, - clamp2, - step2, - smoothStep2, - mix2, - mixN2, - mixNew2, - mixNewN2, -] = genCommon(2); - -const abs = Math.abs; -const pow = Math.pow; -const sqrt = Math.sqrt; - -eqDelta.add(2, (a, b, eps = EPS) => - b.length === 2 && - _eqDelta(a[0], b[0], eps) && - _eqDelta(a[1], b[1], eps) -); - -dot.add(2, (a, b) => a[0] * b[0] + a[1] * b[1]); -magSq.add(2, (a) => a[0] * a[0] + a[1] * a[1]); - -const distsq2 = - (a: ReadonlyVec, b: ReadonlyVec) => - pow(a[0] - b[0], 2) + - pow(a[1] - b[1], 2); - -distSq.add(2, distsq2); -dist.add(2, (a, b) => sqrt(distsq2(a, b))); - -distManhattan.add(2, (a, b) => abs(a[0] - b[0]) + abs(a[1] - b[1])); -distChebyshev.add(2, (a, b) => Math.max(abs(a[0] - b[0]), abs(a[1] - b[1]))); - -minor.add(2, (a) => min2id(abs(a[0]), abs(a[1]))); -major.add(2, (a) => max2id(abs(a[0]), abs(a[1]))); - -polar.add(2, (a) => { - const x = a[0]; - a[0] = mag(a); - a[1] = Math.atan2(a[1], x); - return a; -}); - -cartesian.add(2, (a, b = Vec2.ZERO) => { - const r = a[0]; - const t = a[1]; - a[0] = r * Math.cos(t) + b[0]; - a[1] = r * Math.sin(t) + b[1]; - return a; -}); - -angleBetween.add(2, (a, b, normalize) => - normalize ? - (a[0] * b[1] < a[1] * b[0] ? -1 : 1) * - Math.acos(angleRatio(a, b)) : - Math.acos(dot(a, b)) -); - -export const vec2 = - (x = 0, y = 0) => new Vec2([x, y]); - -export const vec2n = - (n: number) => new Vec2([n, n]); - -export const asVec2 = - (x: Vec) => - x instanceof Vec2 ? - x : - new Vec2(x.length === 2 ? x : [x[0] || 0, x[1] || 0]); - -export const swizzle2 = (a: Vec, b: ReadonlyVec, x: number, y: number) => - (a[0] = b[x] || 0, a[1] = b[y] || 0, a); - -export const comparator2 = - (o1: Vec2Coord, o2: Vec2Coord): Comparator => - (a, b): number => { - const ax = a[o1]; - const ay = a[o2]; - const bx = b[o1]; - const by = b[o2]; - return ax === bx ? - ay === by ? - 0 : - ay < by ? -2 : 2 : - ax < bx ? -1 : 1; - }; - -export const perpendicularLeft2: VecOpV = (a) => { - const x = a[0]; - a[0] = -a[1]; - a[1] = x; - return a; -}; - -export const perpendicularRight2: VecOpV = (a) => { - const x = -a[0]; - a[0] = a[1]; - a[1] = x; - return a; -}; - -export const rotateAroundPoint2: VecOpVVN = (a, b, theta) => { - const x = a[0] - b[0]; - const y = a[1] - b[1]; - const s = Math.sin(theta); - const c = Math.cos(theta); - a[0] = x * c - y * s + b[0]; - a[1] = x * s + y * c + b[1]; - return a; -}; - -export const cross2: VecOpRoVV = - (a, b) => a[0] * b[1] - a[1] * b[0]; - -export const bisect2: VecOpRoVV = (a, b) => { - const theta = (headingXY(a) + headingXY(b)) / 2; - return theta <= HALF_PI ? theta : PI - theta; -}; - -export const mixBilinear2 = ( - a: ReadonlyVec, - b: ReadonlyVec, - c: ReadonlyVec, - d: ReadonlyVec, - u: number, v: number, - out: Vec = []) => ( - out[0] = mixBilinear(a[0], b[0], c[0], d[0], u, v), - out[1] = mixBilinear(a[1], b[1], c[1], d[1], u, v), - out - ); diff --git a/packages/vectors2/src/vec3.ts b/packages/vectors2/src/vec3.ts deleted file mode 100644 index bb71eff717..0000000000 --- a/packages/vectors2/src/vec3.ts +++ /dev/null @@ -1,355 +0,0 @@ -import { Comparator } from "@thi.ng/api"; -import { - EPS, - eqDelta as _eqDelta, - max3id, - min3id, - mixBilinear -} from "@thi.ng/math"; -import { AVec } from "./avec"; -import { declareIndices } from "./internal/accessors"; -import { genCommon } from "./internal/codegen"; -import { - magSq, - dot, - Vec, - IVector, - minor, - major, - polar, - cartesian, - distSq, - distManhattan, - distChebyshev, - angleBetween, - angleRatio, - eqDelta, - VecOpVVN, - subNew, - VecOpRoVVV, - VecOpVV, - Vec3Coord, - X4, - Y4, - Z4, - MIN4, - MAX4, - ZERO4, - ONE4, - ReadonlyVec, - dist, -} from "./api"; - -export class Vec3 extends AVec implements - IVector { - - /** - * Returns array of memory mapped `Vec3` instances using given - * backing array and stride settings: The `cstride` is the step size - * between individual XYZ vector components. `estride` is the step - * size between successive vectors. This arrangement allows for - * different storage approaches, incl. SOA, AOS, striped / - * interleaved etc. - * - * @param buf backing array - * @param n num vectors - * @param start start index - * @param cstride component stride - * @param estride element stride - */ - static mapBuffer(buf: Vec, n: number = (buf.length / 3) | 0, start = 0, cstride = 1, estride = 3) { - const res: Vec3[] = []; - while (--n >= 0) { - res.push(new Vec3(buf, start, cstride)); - start += estride; - } - return res; - } - - /** - * Merges given `src` iterable of `Vec3`s into single array `buf`. - * Vectors will be arranged according to given component and element - * strides, starting at `start` index. It's the user's - * responsibility to ensure the target buffer has sufficient - * capacity to hold the input vectors. See `Vec3.mapBuffer` for the - * inverse operation. Returns `buf`. - * - * @param buf - * @param src - * @param start - * @param cstride - * @param estride - */ - static intoBuffer(buf: Vec, src: Iterable>, start = 0, cstride = 1, estride = 3) { - for (let v of src) { - buf[start] = v[0]; - buf[start + cstride] = v[1]; - buf[start + 2 * cstride] = v[2]; - start += estride; - } - return buf; - } - - static readonly X_AXIS = new Vec3(X4); - static readonly Y_AXIS = new Vec3(Y4); - static readonly Z_AXIS = new Vec3(Z4); - static readonly MIN = new Vec3(MIN4); - static readonly MAX = new Vec3(MAX4); - static readonly ZERO = new Vec3(ZERO4); - static readonly ONE = new Vec3(ONE4); - - x: number; - y: number; - z: number; - [id: number]: number; - - constructor(buf?: Vec, i = 0, s = 1) { - super(buf || [0, 0, 0], i, s); - } - - *[Symbol.iterator]() { - yield this.x; - yield this.y; - yield this.z; - } - - get length() { - return 3; - } - - copy() { - return new Vec3([this.x, this.y, this.z]); - } - - empty() { - return new Vec3(); - } - - eqDelta(v: ReadonlyVec, eps = EPS) { - return eqDelta(this, v, eps); - } - - toJSON() { - return [this.x, this.y, this.z]; - } - - toString() { - return `[${this.x}, ${this.y}, ${this.z}]`; - } -} - -declareIndices(Vec3.prototype, ["x", "y", "z"]); - -export const [ - set3, - setN3, - setS3, - rand3_01, - rand3_11, - rand3, - add3, - sub3, - mul3, - div3, - addNew3, - subNew3, - mulNew3, - divNew3, - addN3, - subN3, - mulN3, - divN3, - addNewN3, - subNewN3, - mulNewN3, - divNewN3, - madd3, - maddN3, - maddNew3, - maddNewN3, - abs3, - sign3, - sin3, - cos3, - tan3, - asin3, - acos3, - atan3, - floor3, - ceil3, - trunc3, - fract3, - sqrt3, - log3, - exp3, - pow3, - powN3, - min3, - max3, - clamp3, - step3, - smoothStep3, - mix3, - mixN3, - mixNew3, - mixNewN3, -] = genCommon(3); - -const abs = Math.abs; -const pow = Math.pow; -const sqrt = Math.sqrt; - -eqDelta.add(3, (a, b, eps = EPS) => - b.length == 3 && - _eqDelta(a[0], b[0], eps) && - _eqDelta(a[1], b[1], eps) && - _eqDelta(a[2], b[2], eps) -); - -dot.add(3, (a, b) => a[0] * b[0] + a[1] * b[1] + a[2] * b[2]); - -magSq.add(3, (a) => a[0] * a[0] + a[1] * a[1] + a[2] * a[2]); - -const distsq3 = - (a: ReadonlyVec, b: ReadonlyVec) => - pow(a[0] - b[0], 2) + - pow(a[1] - b[1], 2) + - pow(a[2] - b[2], 2); - -distSq.add(3, distsq3); -dist.add(3, (a, b) => sqrt(distsq3(a, b))); - -distManhattan.add(3, (a, b) => - abs(a[0] - b[0]) + - abs(a[1] - b[1]) + - abs(a[2] - b[2]) -); - -distChebyshev.add(3, (a, b) => - Math.max( - abs(a[0] - b[0]), - abs(a[1] - b[1]), - abs(a[2] - b[2]) - ) -); - -minor.add(3, (a) => min3id(abs(a[0]), abs(a[1]), abs(a[2]))); - -major.add(3, (a) => max3id(abs(a[0]), abs(a[1]), abs(a[2]))); - -polar.add(3, (a) => { - const x = a[0]; - const y = a[1]; - const z = a[2]; - const r = sqrt(x * x + y * y + z * z); - a[0] = r; - a[1] = Math.asin(z / r); - a[2] = Math.atan2(y, x); - return a; -}); - -cartesian.add(3, (a, b = Vec3.ZERO) => { - const r = a[0]; - const theta = a[1]; - const phi = a[2]; - const ct = Math.cos(theta); - - a[0] = r * ct * Math.cos(phi) + b[0]; - a[1] = r * ct * Math.sin(phi) + b[1]; - a[2] = r * Math.sin(theta) + b[2]; - return a; -}); - -angleBetween.add(3, (a, b, normalize) => - normalize ? - (a[0] * b[1] < a[1] * b[0] ? -1 : 1) * - Math.acos(angleRatio(a, b)) : - Math.acos(dot(a, b)) -); - -export const vec3 = - (x = 0, y = 0, z = 0) => new Vec3([x, y, z]); - -export const vec3n = - (n: number) => new Vec3([n, n, n]); - -export const asVec3 = - (x: Vec) => - x instanceof Vec3 ? - x : - new Vec3(x.length === 3 ? x : [x[0] || 0, x[1] || 0, x[2] || 0]); - -export const swizzle3 = - (a: Vec, b: ReadonlyVec, x: number, y: number, z: number) => - (a[0] = b[x] || 0, a[1] = b[y] || 0, a[2] = b[z] || 0, a); - -export const comparator3 = - (o1: Vec3Coord, o2: Vec3Coord, o3: Vec3Coord): Comparator => - (a, b): number => { - const ax = a[o1]; - const ay = a[o2]; - const az = a[o3]; - const bx = b[o1]; - const by = b[o2]; - const bz = b[o3]; - return ax === bx ? - ay === by ? - az === bz ? - 0 : - az < bz ? -3 : 3 : - ay < by ? -2 : 2 : - ax < bx ? -1 : 1; - }; - -export const rotateAroundAxis3: VecOpVVN = - (v, axis, theta) => { - const x = v[0]; - const y = v[1]; - const z = v[2]; - const ax = axis[0]; - const ay = axis[1]; - const az = axis[2]; - const ux = ax * x; - const uy = ax * y; - const uz = ax * z; - const vx = ay * x; - const vy = ay * y; - const vz = ay * z; - const wx = az * x; - const wy = az * y; - const wz = az * z; - const uvw = ux + vy + wz; - const s = Math.sin(theta); - const c = Math.cos(theta); - - v[0] = (ax * uvw + (x * (ay * ay + az * az) - ax * (vy + wz)) * c + (-wy + vz) * s); - v[1] = (ay * uvw + (y * (ax * ax + az * az) - ay * (ux + wz)) * c + (wx - uz) * s); - v[2] = (az * uvw + (z * (ax * ax + ay * ay) - az * (ux + vy)) * c + (-vx + uy) * s); - return v; - }; - -export const cross3: VecOpVV = - (a, b) => { - const x = a[1] * b[2] - a[2] * b[1]; - const y = a[2] * b[0] - a[0] * b[2]; - a[2] = a[0] * b[1] - a[1] * b[0]; - a[1] = y; - a[0] = x; - return a; - }; - -export const orthoNormal3: VecOpRoVVV = (a: Vec, b: Vec, c: Vec) => - cross3(subNew(c, a), subNew(b, a)); - -export const mixBilinear3 = ( - a: ReadonlyVec, - b: ReadonlyVec, - c: ReadonlyVec, - d: ReadonlyVec, - u: number, v: number, - out: Vec = []) => ( - out[0] = mixBilinear(a[0], b[0], c[0], d[0], u, v), - out[1] = mixBilinear(a[1], b[1], c[1], d[1], u, v), - out[2] = mixBilinear(a[2], b[2], c[2], d[2], u, v), - out - ); diff --git a/packages/vectors2/src/vec4.ts b/packages/vectors2/src/vec4.ts deleted file mode 100644 index a1d9c6c97f..0000000000 --- a/packages/vectors2/src/vec4.ts +++ /dev/null @@ -1,292 +0,0 @@ -import { Comparator } from "@thi.ng/api"; -import { - EPS, - eqDelta as _eqDelta, - max4id, - min4id, - mixBilinear -} from "@thi.ng/math"; -import { AVec } from "./avec"; -import { declareIndices } from "./internal/accessors"; -import { genCommon } from "./internal/codegen"; -import { - magSq, - dot, - Vec, - IVector, - minor, - major, - distSq, - distManhattan, - distChebyshev, - eqDelta, - Vec4Coord, - X4, - Y4, - Z4, - MIN4, - MAX4, - ZERO4, - ONE4, - ReadonlyVec, - dist, -} from "./api"; - -export class Vec4 extends AVec implements - IVector { - - /** - * Returns array of memory mapped `Vec4` instances using given - * backing array and stride settings: The `cstride` is the step size - * between individual XYZ vector components. `estride` is the step - * size between successive vectors. This arrangement allows for - * different storage approaches, incl. SOA, AOS, striped / - * interleaved etc. - * - * @param buf backing array - * @param n num vectors - * @param start start index - * @param cstride component stride - * @param estride element stride - */ - static mapBuffer(buf: Vec, n: number = buf.length >> 2, start = 0, cstride = 1, estride = 4) { - const res: Vec4[] = []; - while (--n >= 0) { - res.push(new Vec4(buf, start, cstride)); - start += estride; - } - return res; - } - - /** - * Merges given `src` iterable of `Vec4`s into single array `buf`. - * Vectors will be arranged according to given component and element - * strides, starting at `start` index. It's the user's - * responsibility to ensure the target buffer has sufficient - * capacity to hold the input vectors. See `Vec4.mapBuffer` for the - * inverse operation. Returns `buf`. - * - * @param buf - * @param src - * @param start - * @param cstride - * @param estride - */ - static intoBuffer(buf: Vec, src: Iterable>, start = 0, cstride = 1, estride = 3) { - for (let v of src) { - buf[start] = v[0]; - buf[start + cstride] = v[1]; - buf[start + 2 * cstride] = v[2]; - buf[start + 3 * cstride] = v[3]; - start += estride; - } - return buf; - } - - static readonly X_AXIS = new Vec4(X4); - static readonly Y_AXIS = new Vec4(Y4); - static readonly Z_AXIS = new Vec4(Z4); - static readonly MIN = new Vec4(MIN4); - static readonly MAX = new Vec4(MAX4); - static readonly ZERO = new Vec4(ZERO4); - static readonly ONE = new Vec4(ONE4); - - x: number; - y: number; - z: number; - w: number; - [id: number]: number; - - constructor(buf?: Vec, i = 0, s = 1) { - super(buf || [0, 0, 0, 0], i, s); - } - - *[Symbol.iterator]() { - yield this.x; - yield this.y; - yield this.z; - yield this.w; - } - - get length() { - return 4; - } - - copy() { - return new Vec4([this.x, this.y, this.z, this.w]); - } - - empty() { - return new Vec4(); - } - - eqDelta(v: ReadonlyVec, eps = EPS) { - return eqDelta(this, v, eps); - } - - toJSON() { - return [this.x, this.y, this.z, this.w]; - } - - toString() { - return `[${this.x}, ${this.y}, ${this.z}, ${this.w}]`; - } -} - -declareIndices(Vec4.prototype, ["x", "y", "z", "w"]); - -export const [ - set4, - setN4, - setS4, - rand4_01, - rand4_11, - rand4, - add4, - sub4, - mul4, - div4, - addNew4, - subNew4, - mulNew4, - divNew4, - addN4, - subN4, - mulN4, - divN4, - addNewN4, - subNewN4, - mulNewN4, - divNewN4, - madd4, - maddN4, - maddNew4, - maddNewN4, - abs4, - sign4, - sin4, - cos4, - tan4, - asin4, - acos4, - atan4, - floor4, - ceil4, - trunc4, - fract4, - sqrt4, - log4, - exp4, - pow4, - powN4, - min4, - max4, - clamp4, - step4, - smoothStep4, - mix4, - mixN4, - mixNew4, - mixNewN4, -] = genCommon(4); - -const abs = Math.abs; -const pow = Math.pow; -const sqrt = Math.sqrt; - -eqDelta.add(4, (a, b, eps = EPS) => - b.length == 4 && - _eqDelta(a[0], b[0], eps) && - _eqDelta(a[1], b[1], eps) && - _eqDelta(a[2], b[2], eps) && - _eqDelta(a[3], b[3], eps) -); - -dot.add(4, (a, b) => a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]); - -magSq.add(4, (a) => a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3]); - -const distsq4 = - (a: ReadonlyVec, b: ReadonlyVec) => - pow(a[0] - b[0], 2) + - pow(a[1] - b[1], 2) + - pow(a[2] - b[2], 2) + - pow(a[3] - b[3], 2); - -distSq.add(4, distsq4); -dist.add(4, (a, b) => sqrt(distsq4(a, b))); - -distManhattan.add(4, (a, b) => - abs(a[0] - b[0]) + - abs(a[1] - b[1]) + - abs(a[2] - b[2]) + - abs(a[3] - b[3]) -); - -distChebyshev.add(4, (a, b) => - Math.max( - abs(a[0] - b[0]), - abs(a[1] - b[1]), - abs(a[2] - b[2]), - abs(a[3] - b[3]) - ) -); - -minor.add(4, (a) => min4id(abs(a[0]), abs(a[1]), abs(a[2]), abs(a[3]))); - -major.add(4, (a) => max4id(abs(a[0]), abs(a[1]), abs(a[2]), abs(a[3]))); - -export const vec4 = - (x = 0, y = 0, z = 0, w = 0) => new Vec4([x, y, z, w]); - -export const vec4n = - (n: number) => new Vec4([n, n, n, n]); - -export const asVec4 = - (x: Vec) => - x instanceof Vec4 ? - x : - new Vec4(x.length !== 4 ? - [x[0] || 0, x[1] || 0, x[2] || 0, x[3] || 0] : - x); - -export const swizzle4 = - (a: Vec, b: ReadonlyVec, x: number, y: number, z: number, w: number) => - (a[0] = b[x] || 0, a[1] = b[y] || 0, a[2] = b[z] || 0, a[3] = b[w] || 0, a); - -export const comparator4 = - (o1: Vec4Coord, o2: Vec4Coord, o3: Vec4Coord, o4: Vec4Coord): Comparator => - (a, b): number => { - - const ax = a[o1]; - const ay = a[o2]; - const az = a[o3]; - const aw = b[o4]; - const bx = b[o1]; - const by = b[o2]; - const bz = b[o3]; - const bw = b[o4]; - return ax === bx ? - ay === by ? - az === bz ? - aw === bw ? - 0 : - aw < bw ? -4 : 4 : - az < bz ? -3 : 3 : - ay < by ? -2 : 2 : - ax < bx ? -1 : 1; - }; - -export const mixBilinear4 = ( - a: ReadonlyVec, - b: ReadonlyVec, - c: ReadonlyVec, - d: ReadonlyVec, - u: number, v: number, - out: Vec = []) => ( - out[0] = mixBilinear(a[0], b[0], c[0], d[0], u, v), - out[1] = mixBilinear(a[1], b[1], c[1], d[1], u, v), - out[2] = mixBilinear(a[2], b[2], c[2], d[2], u, v), - out[3] = mixBilinear(a[3], b[3], c[3], d[3], u, v), - out - ); diff --git a/packages/vectors2/test/index.ts b/packages/vectors2/test/index.ts deleted file mode 100644 index cea49f3372..0000000000 --- a/packages/vectors2/test/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -// import * as assert from "assert"; -// import * as v from "../src/index"; - -describe("vectors2", () => { - it("tests pending"); -}); diff --git a/packages/vectors2/test/tsconfig.json b/packages/vectors2/test/tsconfig.json deleted file mode 100644 index 2c9c12a650..0000000000 --- a/packages/vectors2/test/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "../../../tsconfig.json", - "compilerOptions": { - "outDir": "../build", - "module": "commonjs", - }, - "include": [ - "./**/*.ts", - "../src/**/*.ts" - ] -} \ No newline at end of file diff --git a/packages/vectors2/tsconfig.json b/packages/vectors2/tsconfig.json deleted file mode 100644 index bcf03f18b4..0000000000 --- a/packages/vectors2/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": ".", - "module": "es6", - "target": "es6" - }, - "include": [ - "./src/**/*.ts" - ] -} \ No newline at end of file From 61e406384d0089c6b52666b74ca3e6df0bc10032 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 14 Jan 2019 16:49:04 +0000 Subject: [PATCH 258/333] feat(vectors): add addm/addmN, subm/submN --- packages/vectors3/README.md | 4 ++++ packages/vectors3/src/addm.ts | 11 +++++++++++ packages/vectors3/src/addmn.ts | 9 +++++++++ packages/vectors3/src/index.ts | 4 ++++ packages/vectors3/src/internal/templates.ts | 4 ++++ packages/vectors3/src/madd.ts | 2 ++ packages/vectors3/src/subm.ts | 11 +++++++++++ packages/vectors3/src/submn.ts | 9 +++++++++ 8 files changed, 54 insertions(+) create mode 100644 packages/vectors3/src/addm.ts create mode 100644 packages/vectors3/src/addmn.ts create mode 100644 packages/vectors3/src/subm.ts create mode 100644 packages/vectors3/src/submn.ts diff --git a/packages/vectors3/README.md b/packages/vectors3/README.md index 226c0885cd..c96ab1d918 100644 --- a/packages/vectors3/README.md +++ b/packages/vectors3/README.md @@ -246,9 +246,13 @@ Functions for memory mapped, strided vectors (without requiring wrappers): ### Multiply-add +- `addm` / `addm2` / `addm3` / `addm4` +- `addmN` / `addmN2` / `addmN3` / `addmN4` - `addW2` / `addW3` / `addW4` / `addW5` - `madd` / `madd2` / `madd3` / `madd4` - `maddN` / `maddN2` / `maddN3` / `maddN4` +- `subm` / `subm2` / `subm3` / `subm4` +- `submN` / `submN2` / `submN3` / `submN4` ### Constraints diff --git a/packages/vectors3/src/addm.ts b/packages/vectors3/src/addm.ts new file mode 100644 index 0000000000..620d94594c --- /dev/null +++ b/packages/vectors3/src/addm.ts @@ -0,0 +1,11 @@ +import { MultiVecOpVVV, VecOpVVV } from "./api"; +import { ARGS_VVV, defOp } from "./internal/codegen"; +import { ADDM } from "./internal/templates"; + +/** + * Returns `out = (a + b) * c`. + * + * @see madd + */ +export const [addm, addm2, addm3, addm4] = + defOp(ADDM, ARGS_VVV); diff --git a/packages/vectors3/src/addmn.ts b/packages/vectors3/src/addmn.ts new file mode 100644 index 0000000000..ebfefbbadc --- /dev/null +++ b/packages/vectors3/src/addmn.ts @@ -0,0 +1,9 @@ +import { MultiVecOpVVN, VecOpVVN } from "./api"; +import { ARGS_VVN, defOp } from "./internal/codegen"; +import { ADDM_N } from "./internal/templates"; + +/** + * Returns `out = (a + b) * n`. + */ +export const [addmN, addmN2, addmN3, addmN4] = + defOp(ADDM_N, ARGS_VVN); diff --git a/packages/vectors3/src/index.ts b/packages/vectors3/src/index.ts index b20b9bdde3..b7bcb04093 100644 --- a/packages/vectors3/src/index.ts +++ b/packages/vectors3/src/index.ts @@ -14,6 +14,8 @@ export * from "./abs"; export * from "./acos"; export * from "./addw"; export * from "./add"; +export * from "./addm"; +export * from "./addmn"; export * from "./addn"; export * from "./adds"; export * from "./angle-between"; @@ -99,6 +101,8 @@ export * from "./sqrt"; export * from "./step"; export * from "./smoothstep"; export * from "./sub"; +export * from "./subm"; +export * from "./submn"; export * from "./subn"; export * from "./subs"; export * from "./sum"; diff --git a/packages/vectors3/src/internal/templates.ts b/packages/vectors3/src/internal/templates.ts index 760ab87e4a..a8acfdd1e3 100644 --- a/packages/vectors3/src/internal/templates.ts +++ b/packages/vectors3/src/internal/templates.ts @@ -11,7 +11,11 @@ export const SET_N = ([a]) => `${a}=n;` export const HOF_VVV = ([o, a, b, c]) => `${o}=op(${a},${b},${c});`; +export const ADDM = ([o, a, b, c]) => `${o}=(${a}+${b})*${c};`; +export const ADDM_N = ([o, a, b]) => `${o}=(${a}+${b})*n;`; export const MADD = ([o, a, b, c]) => `${o}=${a}+${b}*${c};`; export const MADD_N = ([o, a, b]) => `${o}=${a}+${b}*n;`; export const MIX = ([o, a, b, c]) => `${o}=${a}+(${b}-${a})*${c};`; export const MIX_N = ([o, a, b]) => `${o}=${a}+(${b}-${a})*n;` +export const SUBM = ([o, a, b, c]) => `${o}=(${a}-${b})*${c};`; +export const SUBM_N = ([o, a, b]) => `${o}=(${a}-${b})*n;`; diff --git a/packages/vectors3/src/madd.ts b/packages/vectors3/src/madd.ts index b69f4d3d46..5c577ca5f4 100644 --- a/packages/vectors3/src/madd.ts +++ b/packages/vectors3/src/madd.ts @@ -4,6 +4,8 @@ import { MADD } from "./internal/templates"; /** * Returns `out = a + b * c`. + * + * @see addm */ export const [madd, madd2, madd3, madd4] = defOp(MADD, ARGS_VVV); diff --git a/packages/vectors3/src/subm.ts b/packages/vectors3/src/subm.ts new file mode 100644 index 0000000000..01938e147c --- /dev/null +++ b/packages/vectors3/src/subm.ts @@ -0,0 +1,11 @@ +import { MultiVecOpVVV, VecOpVVV } from "./api"; +import { ARGS_VVV, defOp } from "./internal/codegen"; +import { SUBM } from "./internal/templates"; + +/** + * Returns `out = (a + b) * c`. + * + * @see madd + */ +export const [subm, subm2, subm3, subm4] = + defOp(SUBM, ARGS_VVV); diff --git a/packages/vectors3/src/submn.ts b/packages/vectors3/src/submn.ts new file mode 100644 index 0000000000..3863046a6f --- /dev/null +++ b/packages/vectors3/src/submn.ts @@ -0,0 +1,9 @@ +import { MultiVecOpVVN, VecOpVVN } from "./api"; +import { ARGS_VVN, defOp } from "./internal/codegen"; +import { SUBM_N } from "./internal/templates"; + +/** + * Returns `out = (a - b) * n`. + */ +export const [submN, submN2, submN3, submN4] = + defOp(SUBM_N, ARGS_VVN); From 18aeb49c026fb75b35ab7a1d52e7f5d4f5bc5105 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 15 Jan 2019 02:56:07 +0000 Subject: [PATCH 259/333] build(vectors): add memoize dep --- packages/vectors3/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/vectors3/package.json b/packages/vectors3/package.json index ab171a0a03..ce6ea74895 100644 --- a/packages/vectors3/package.json +++ b/packages/vectors3/package.json @@ -16,7 +16,7 @@ "scripts": { "build": "yarn clean && yarn build:es6 && yarn build:bundle", "build:es6": "tsc --declaration", - "build:bundle": "../../scripts/bundle-module vectors3 api checks equiv errors math random transducers", + "build:bundle": "../../scripts/bundle-module vectors3 api checks equiv errors math memoize random transducers", "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", @@ -37,6 +37,7 @@ "@thi.ng/equiv": "^0.1.15", "@thi.ng/errors": "^0.1.12", "@thi.ng/math": "^0.2.2", + "@thi.ng/memoize": "^0.2.6", "@thi.ng/random": "^0.1.1", "@thi.ng/transducers": "^2.3.2" }, From c12ad1ccf87ad2055bb6842c67528ee2150ff95e Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 15 Jan 2019 02:56:34 +0000 Subject: [PATCH 260/333] test(vectors): update eqDelta tests --- packages/vectors/test/gvec.ts | 2 +- packages/vectors/test/vec2.ts | 2 +- packages/vectors/test/vec3.ts | 4 ++-- packages/vectors/test/vec4.ts | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/vectors/test/gvec.ts b/packages/vectors/test/gvec.ts index 6fb251cc3d..79120ab66c 100644 --- a/packages/vectors/test/gvec.ts +++ b/packages/vectors/test/gvec.ts @@ -68,7 +68,7 @@ describe("gvec", () => { it("eqdelta", () => { assert(v.eqDelta([0, 1.001, 0, 1.999, 0, 3.0099, 0, 3.991], [1, 2, 3, 4], 4, 0.01, 1, 0, 2, 1)); - assert(!v.eqDelta([0, 1.001, 0, 1.999, 0, 3.02, 0, 4], [1, 2, 3, 4], 4, 0.01, 1, 0, 2, 1)); + assert(!v.eqDelta([0, 1.001, 0, 1.999, 0, 3.04, 0, 4], [1, 2, 3, 4], 4, 0.01, 1, 0, 2, 1)); }); it("iterator", () => { diff --git a/packages/vectors/test/vec2.ts b/packages/vectors/test/vec2.ts index 79839c71ea..31e4df35b7 100644 --- a/packages/vectors/test/vec2.ts +++ b/packages/vectors/test/vec2.ts @@ -68,7 +68,7 @@ describe("vec2", () => { it("eqdelta", () => { assert(v.eqDelta2([0, 1.001, 0, 1.999, 0], [1, 2], 0.01, 1, 0, 2, 1)); - assert(!v.eqDelta2([0, 1.001, 0, 1.989, 0], [1, 2], 0.01, 1, 0, 2, 1)); + assert(!v.eqDelta2([0, 1.001, 0, 1.979, 0], [1, 2], 0.01, 1, 0, 2, 1)); }); it("iterator", () => { diff --git a/packages/vectors/test/vec3.ts b/packages/vectors/test/vec3.ts index 7e5f3df709..5929f74745 100644 --- a/packages/vectors/test/vec3.ts +++ b/packages/vectors/test/vec3.ts @@ -68,9 +68,9 @@ describe("vec3", () => { it("eqdelta", () => { assert(v.eqDelta3([0, 1.001, 0, 1.999, 0, 3.0099], [1, 2, 3], 0.01, 1, 0, 2, 1)); - assert(!v.eqDelta3([0, 1.001, 0, 1.999, 0, 3.02], [1, 2, 3], 0.01, 1, 0, 2, 1)); + assert(!v.eqDelta3([0, 1.001, 0, 1.999, 0, 3.04], [1, 2, 3], 0.01, 1, 0, 2, 1)); assert(new v.Vec3([0, 1.001, 0, 1.999, 0, 3.0099], 1, 2).eqDelta(v.vec3(1, 2, 3), 0.01)); - assert(!new v.Vec3([0, 1.001, 0, 1.999, 0, 3.02], 1, 2).eqDelta(v.vec3(1, 2, 3), 0.01)); + assert(!new v.Vec3([0, 1.001, 0, 1.999, 0, 3.04], 1, 2).eqDelta(v.vec3(1, 2, 3), 0.01)); }); it("iterator", () => { diff --git a/packages/vectors/test/vec4.ts b/packages/vectors/test/vec4.ts index c2b8931ab3..8843955fcf 100644 --- a/packages/vectors/test/vec4.ts +++ b/packages/vectors/test/vec4.ts @@ -68,7 +68,7 @@ describe("vec4", () => { it("eqdelta", () => { assert(v.eqDelta4([0, 1.001, 0, 1.999, 0, 3.0099, 0, 3.991], [1, 2, 3, 4], 0.01, 1, 0, 2, 1)); - assert(!v.eqDelta4([0, 1.001, 0, 1.999, 0, 3.02, 0, 4], [1, 2, 3, 4], 0.01, 1, 0, 2, 1)); + assert(!v.eqDelta4([0, 1.001, 0, 1.999, 0, 3.04, 0, 4], [1, 2, 3, 4], 0.01, 1, 0, 2, 1)); }); it("iterator", () => { From d14c94b2c341deb0a18e924e3999f95c7918b30f Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 15 Jan 2019 02:57:41 +0000 Subject: [PATCH 261/333] build: disable minification for UMD outputs --- scripts/bundle-module | 4 +--- scripts/depgraph | 2 ++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/bundle-module b/scripts/bundle-module index 9815903682..0f8ed33b64 100755 --- a/scripts/bundle-module +++ b/scripts/bundle-module @@ -89,9 +89,7 @@ const build = interop: false, sourcemap: true, sourcemapExcludeSources: true, - }, - true, - true + } ); fs.writeFileSync(".meta/size.json", JSON.stringify({ esm, cjs, umd })); diff --git a/scripts/depgraph b/scripts/depgraph index 350c789485..9a35a2720c 100755 --- a/scripts/depgraph +++ b/scripts/depgraph @@ -53,5 +53,7 @@ tx.run( ([p, d]) => g.addDependency(p, d), packages); +// console.log(g.transitiveDependencies("@thi.ng/geom3")); + console.log("topo order:", g.sort().map((x) => x.replace("@thi.ng/", "")).join(" ")); console.log("done"); \ No newline at end of file From a39811c6c0497f6b62972115a1b80538eb63c1bb Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 15 Jan 2019 02:59:45 +0000 Subject: [PATCH 262/333] feat(hiccup-svg): add ellipse shape type, update convert() --- packages/hiccup-svg/package.json | 2 +- packages/hiccup-svg/src/convert.ts | 3 +++ packages/hiccup-svg/src/ellipse.ts | 12 ++++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 packages/hiccup-svg/src/ellipse.ts diff --git a/packages/hiccup-svg/package.json b/packages/hiccup-svg/package.json index 1c83318a92..92088159b3 100644 --- a/packages/hiccup-svg/package.json +++ b/packages/hiccup-svg/package.json @@ -16,7 +16,7 @@ "scripts": { "build": "yarn clean && yarn build:es6 && yarn build:bundle", "build:es6": "tsc --declaration", - "build:bundle": "../../scripts/bundle-module hiccup-svg checks hiccup", + "build:bundle": "../../scripts/bundle-module hiccupSvg checks hiccup", "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", diff --git a/packages/hiccup-svg/src/convert.ts b/packages/hiccup-svg/src/convert.ts index 094cca3aa9..a84e01e090 100644 --- a/packages/hiccup-svg/src/convert.ts +++ b/packages/hiccup-svg/src/convert.ts @@ -1,6 +1,7 @@ import { isArray, isArrayLike } from "@thi.ng/checks"; import { PathSegment } from "./api"; import { circle } from "./circle"; +import { ellipse } from "./ellipse"; import { ff } from "./format"; import { linearGradient, radialGradient } from "./gradients"; import { image } from "./image"; @@ -82,6 +83,8 @@ export const convertTree = ); case "circle": return circle(tree[2], tree[3], attribs); + case "ellipse": + return ellipse(tree[2], tree[3][0], tree[3][1], attribs); case "rect": { const r = tree[5] || 0; return roundedRect(tree[2], tree[3], tree[4], r, r, attribs); diff --git a/packages/hiccup-svg/src/ellipse.ts b/packages/hiccup-svg/src/ellipse.ts new file mode 100644 index 0000000000..c5f6ec9668 --- /dev/null +++ b/packages/hiccup-svg/src/ellipse.ts @@ -0,0 +1,12 @@ +import { Vec2Like } from "./api"; +import { ff } from "./format"; + +export const ellipse = + (p: Vec2Like, rx: number, ry: number, attribs?: any): any[] => + ["ellipse", { + cx: ff(p[0]), + cy: ff(p[1]), + rx: ff(rx), + ry: ff(ry), + ...attribs + }]; From 50180096458d3380577d0707027fbf97a59675f2 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 15 Jan 2019 03:01:40 +0000 Subject: [PATCH 263/333] feat(math): update eqDelta w/ adaptive eps, rename old => eqDeltaFixed --- packages/math/src/eqdelta.ts | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/packages/math/src/eqdelta.ts b/packages/math/src/eqdelta.ts index 54c38e437b..f4b4641927 100644 --- a/packages/math/src/eqdelta.ts +++ b/packages/math/src/eqdelta.ts @@ -1,14 +1,33 @@ import { EPS } from "./api"; +const abs = Math.abs; +const max = Math.max; + /** - * Checks if `|a - b| <= ε`. + * Checks if `|a - b| <= ε` and adapts given epsilon value to the given + * arguments: + * + * ε is factored with the largest absolute value of `a` or `b` (but + * never lesser than the given `eps` value): + * + * `ε = ε * max(1, |a|, |b|)` * * @param a left value * @param b right value - * @param eps epsilon / tolerance + * @param eps epsilon / tolerance, default `1e-6` */ export const eqDelta = - (a: number, b: number, eps = EPS) => { - const d = a - b; - return (d < 0 ? -d : d) <= eps; - }; + (a: number, b: number, eps = EPS) => + abs(a - b) <= eps * max(1, abs(a), abs(b)); + +/** + * Similar to `eqDelta()`, but used given `eps` as is. + * + * @param a left value + * @param b right value + * @param eps epsilon / tolerance, default `1e-6` + */ +export const eqDeltaFixed = + (a: number, b: number, eps = EPS) => + abs(a - b) <= eps; + From c0e3a0bcf79877913864d69b2efa5c79d6e8ed68 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 15 Jan 2019 03:06:29 +0000 Subject: [PATCH 264/333] feat(geom): add temp geom3 package (another refactored version of geom2) --- packages/geom3/.npmignore | 12 + packages/geom3/LICENSE | 201 +++++++ packages/geom3/README.md | 52 ++ packages/geom3/package.json | 55 ++ packages/geom3/src/api.ts | 493 ++++++++++++++++++ packages/geom3/src/ctors/circle.ts | 27 + packages/geom3/src/ctors/cubic.ts | 14 + packages/geom3/src/ctors/ellipse.ts | 10 + packages/geom3/src/ctors/group.ts | 5 + packages/geom3/src/ctors/line.ts | 10 + packages/geom3/src/ctors/points.ts | 5 + packages/geom3/src/ctors/polygon.ts | 26 + packages/geom3/src/ctors/polyline.ts | 6 + packages/geom3/src/ctors/quad.ts | 10 + packages/geom3/src/ctors/quadratic.ts | 14 + packages/geom3/src/ctors/rect.ts | 14 + packages/geom3/src/ctors/triangle.ts | 25 + packages/geom3/src/index.ts | 57 ++ packages/geom3/src/internal/args.ts | 49 ++ packages/geom3/src/internal/bounds.ts | 23 + packages/geom3/src/internal/centroid.ts | 19 + packages/geom3/src/internal/circumcenter.ts | 43 ++ packages/geom3/src/internal/closest-point.ts | 116 +++++ packages/geom3/src/internal/coll-bounds.ts | 24 + packages/geom3/src/internal/copy-points.ts | 4 + packages/geom3/src/internal/corner.ts | 30 ++ packages/geom3/src/internal/direction.ts | 19 + packages/geom3/src/internal/dispatch.ts | 5 + .../internal/douglas\342\200\223peucker.ts" | 42 ++ packages/geom3/src/internal/graham-scan.ts | 87 ++++ packages/geom3/src/internal/liang-barsky.ts | 58 +++ .../geom3/src/internal/line-intersection.ts | 48 ++ .../geom3/src/internal/poly-arc-length.ts | 15 + packages/geom3/src/internal/poly-area.ts | 16 + packages/geom3/src/internal/poly-centroid.ts | 18 + .../geom3/src/internal/poly-point-inside.ts | 20 + packages/geom3/src/internal/sampler.ts | 139 +++++ packages/geom3/src/internal/subdiv-curve.ts | 64 +++ .../geom3/src/internal/sutherland-hodgeman.ts | 44 ++ .../geom3/src/internal/transform-points.ts | 10 + .../geom3/src/internal/translate-points.ts | 5 + packages/geom3/src/internal/union-bounds.ts | 25 + packages/geom3/src/ops/arc-length.ts | 79 +++ packages/geom3/src/ops/area.ts | 96 ++++ packages/geom3/src/ops/as-polygon.ts | 27 + packages/geom3/src/ops/as-svg.ts | 27 + packages/geom3/src/ops/bounds.ts | 66 +++ packages/geom3/src/ops/center.ts | 42 ++ packages/geom3/src/ops/centroid.ts | 64 +++ packages/geom3/src/ops/classify-point.ts | 15 + packages/geom3/src/ops/closest-point.ts | 21 + packages/geom3/src/ops/convex-hull.ts | 34 ++ packages/geom3/src/ops/fit-into-bounds.ts | 57 ++ packages/geom3/src/ops/map-point.ts | 21 + packages/geom3/src/ops/point-at.ts | 59 +++ packages/geom3/src/ops/point-inside.ts | 40 ++ packages/geom3/src/ops/resample.ts | 35 ++ packages/geom3/src/ops/simplify.ts | 29 ++ packages/geom3/src/ops/subdiv-curve.ts | 87 ++++ packages/geom3/src/ops/tangent-at.ts | 43 ++ packages/geom3/src/ops/transform.ts | 58 +++ packages/geom3/src/ops/translate.ts | 101 ++++ packages/geom3/src/ops/union.ts | 18 + packages/geom3/src/ops/unmap-point.ts | 47 ++ packages/geom3/src/ops/vertices.ts | 94 ++++ packages/geom3/test/index.ts | 6 + packages/geom3/test/tsconfig.json | 11 + packages/geom3/tsconfig.json | 12 + 68 files changed, 3148 insertions(+) create mode 100644 packages/geom3/.npmignore create mode 100644 packages/geom3/LICENSE create mode 100644 packages/geom3/README.md create mode 100644 packages/geom3/package.json create mode 100644 packages/geom3/src/api.ts create mode 100644 packages/geom3/src/ctors/circle.ts create mode 100644 packages/geom3/src/ctors/cubic.ts create mode 100644 packages/geom3/src/ctors/ellipse.ts create mode 100644 packages/geom3/src/ctors/group.ts create mode 100644 packages/geom3/src/ctors/line.ts create mode 100644 packages/geom3/src/ctors/points.ts create mode 100644 packages/geom3/src/ctors/polygon.ts create mode 100644 packages/geom3/src/ctors/polyline.ts create mode 100644 packages/geom3/src/ctors/quad.ts create mode 100644 packages/geom3/src/ctors/quadratic.ts create mode 100644 packages/geom3/src/ctors/rect.ts create mode 100644 packages/geom3/src/ctors/triangle.ts create mode 100644 packages/geom3/src/index.ts create mode 100644 packages/geom3/src/internal/args.ts create mode 100644 packages/geom3/src/internal/bounds.ts create mode 100644 packages/geom3/src/internal/centroid.ts create mode 100644 packages/geom3/src/internal/circumcenter.ts create mode 100644 packages/geom3/src/internal/closest-point.ts create mode 100644 packages/geom3/src/internal/coll-bounds.ts create mode 100644 packages/geom3/src/internal/copy-points.ts create mode 100644 packages/geom3/src/internal/corner.ts create mode 100644 packages/geom3/src/internal/direction.ts create mode 100644 packages/geom3/src/internal/dispatch.ts create mode 100644 "packages/geom3/src/internal/douglas\342\200\223peucker.ts" create mode 100644 packages/geom3/src/internal/graham-scan.ts create mode 100644 packages/geom3/src/internal/liang-barsky.ts create mode 100644 packages/geom3/src/internal/line-intersection.ts create mode 100644 packages/geom3/src/internal/poly-arc-length.ts create mode 100644 packages/geom3/src/internal/poly-area.ts create mode 100644 packages/geom3/src/internal/poly-centroid.ts create mode 100644 packages/geom3/src/internal/poly-point-inside.ts create mode 100644 packages/geom3/src/internal/sampler.ts create mode 100644 packages/geom3/src/internal/subdiv-curve.ts create mode 100644 packages/geom3/src/internal/sutherland-hodgeman.ts create mode 100644 packages/geom3/src/internal/transform-points.ts create mode 100644 packages/geom3/src/internal/translate-points.ts create mode 100644 packages/geom3/src/internal/union-bounds.ts create mode 100644 packages/geom3/src/ops/arc-length.ts create mode 100644 packages/geom3/src/ops/area.ts create mode 100644 packages/geom3/src/ops/as-polygon.ts create mode 100644 packages/geom3/src/ops/as-svg.ts create mode 100644 packages/geom3/src/ops/bounds.ts create mode 100644 packages/geom3/src/ops/center.ts create mode 100644 packages/geom3/src/ops/centroid.ts create mode 100644 packages/geom3/src/ops/classify-point.ts create mode 100644 packages/geom3/src/ops/closest-point.ts create mode 100644 packages/geom3/src/ops/convex-hull.ts create mode 100644 packages/geom3/src/ops/fit-into-bounds.ts create mode 100644 packages/geom3/src/ops/map-point.ts create mode 100644 packages/geom3/src/ops/point-at.ts create mode 100644 packages/geom3/src/ops/point-inside.ts create mode 100644 packages/geom3/src/ops/resample.ts create mode 100644 packages/geom3/src/ops/simplify.ts create mode 100644 packages/geom3/src/ops/subdiv-curve.ts create mode 100644 packages/geom3/src/ops/tangent-at.ts create mode 100644 packages/geom3/src/ops/transform.ts create mode 100644 packages/geom3/src/ops/translate.ts create mode 100644 packages/geom3/src/ops/union.ts create mode 100644 packages/geom3/src/ops/unmap-point.ts create mode 100644 packages/geom3/src/ops/vertices.ts create mode 100644 packages/geom3/test/index.ts create mode 100644 packages/geom3/test/tsconfig.json create mode 100644 packages/geom3/tsconfig.json diff --git a/packages/geom3/.npmignore b/packages/geom3/.npmignore new file mode 100644 index 0000000000..74ea62d1fa --- /dev/null +++ b/packages/geom3/.npmignore @@ -0,0 +1,12 @@ +.meta +.nyc_output +*.html +*.tgz +build +coverage +dev +doc +export +src* +test +tsconfig.json diff --git a/packages/geom3/LICENSE b/packages/geom3/LICENSE new file mode 100644 index 0000000000..8dada3edaf --- /dev/null +++ b/packages/geom3/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/geom3/README.md b/packages/geom3/README.md new file mode 100644 index 0000000000..5333c8241a --- /dev/null +++ b/packages/geom3/README.md @@ -0,0 +1,52 @@ +# @thi.ng/geom3 + +[![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/geom3.svg)](https://www.npmjs.com/package/@thi.ng/geom3) +![npm downloads](https://img.shields.io/npm/dm/@thi.ng/geom3.svg) +[![Twitter Follow](https://img.shields.io/twitter/follow/thing_umbrella.svg?style=flat-square&label=twitter)](https://twitter.com/thing_umbrella) + +This project is part of the +[@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo. + + + +- [About](#about) +- [Installation](#installation) +- [Dependencies](#dependencies) +- [Usage examples](#usage-examples) +- [Authors](#authors) +- [License](#license) + + + +## About + +Temporary WIP refactoring of +[@thi.ng/geom](https://github.com/thi-ng/umbrella/tree/master/packages/geom), +based on multi-methods +([@thi.ng/defmulti](https://github.com/thi-ng/umbrella/tree/master/packages/defmulti)). + +[up-to-date feature matrix spreadsheet](https://docs.google.com/spreadsheets/d/1GxJm-zOQaGECui2MJUmy3gQPTF-T6BJ6vhNlUnPsmDs/edit?usp=sharing) + +## Installation + +```bash +yarn add @thi.ng/geom3 +``` + +## Dependencies + +- TODO... + +## Usage examples + +```ts +import * as g from "@thi.ng/geom3"; +``` + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/packages/geom3/package.json b/packages/geom3/package.json new file mode 100644 index 0000000000..bbc4ffebcc --- /dev/null +++ b/packages/geom3/package.json @@ -0,0 +1,55 @@ +{ + "name": "@thi.ng/geom3", + "version": "0.0.1", + "description": "TODO", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", + "typings": "./index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/thi-ng/umbrella.git" + }, + "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/geom3", + "author": "Karsten Schmidt ", + "license": "Apache-2.0", + "scripts": { + "build": "yarn clean && yarn build:es6 && yarn build:bundle", + "build:es6": "tsc --declaration", + "build:bundle": "../../scripts/bundle-module geom3 api checks defmulti equiv errors hiccup hiccup-svg math matrices transducers vectors3", + "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", + "cover": "yarn test && nyc report --reporter=lcov", + "doc": "node_modules/.bin/typedoc --mode modules --out doc src", + "pub": "yarn build && yarn publish --access public" + }, + "devDependencies": { + "@types/mocha": "^5.2.5", + "@types/node": "^10.12.15", + "mocha": "^5.2.0", + "nyc": "^13.1.0", + "typedoc": "^0.14.0", + "typescript": "^3.2.2" + }, + "dependencies": { + "@thi.ng/api": "^4.2.4", + "@thi.ng/checks": "^1.5.14", + "@thi.ng/defmulti": "^0.7.0", + "@thi.ng/equiv": "^0.1.15", + "@thi.ng/errors": "^0.1.12", + "@thi.ng/hiccup": "^2.7.2", + "@thi.ng/hiccup-svg": "^2.0.10", + "@thi.ng/math": "^0.2.2", + "@thi.ng/matrices": "^0.0.1", + "@thi.ng/transducers": "^2.3.2", + "@thi.ng/vectors3": "^0.0.1" + }, + "keywords": [ + "ES6", + "typescript" + ], + "publishConfig": { + "access": "public" + }, + "sideEffects": false +} \ No newline at end of file diff --git a/packages/geom3/src/api.ts b/packages/geom3/src/api.ts new file mode 100644 index 0000000000..7166fa2728 --- /dev/null +++ b/packages/geom3/src/api.ts @@ -0,0 +1,493 @@ +import { ICopy, IObjectOf, IToHiccup } from "@thi.ng/api"; +import { isNumber } from "@thi.ng/checks"; +import { equiv } from "@thi.ng/equiv"; +import { + copy, + maddN, + ReadonlyVec, + Vec +} from "@thi.ng/vectors3"; +import { copyPoints } from "./internal/copy-points"; + +export const enum Type { + AABB = 1, + ARC, + CIRCLE, + CUBIC, + CUBIC3, + ELLIPSE, + GROUP, + LINE, + LINE3, + PATH, + POINTS, + POINTS3, + POLYGON, + POLYGON3, + POLYLINE, + POLYLINE3, + QUAD, + QUAD3, + QUADRATIC, + QUADRATIC3, + RECT, + SPHERE, + TRIANGLE, + TRIANGLE3, + RAY, + RAY3, +} + +export const enum LineIntersectionType { + PARALLEL = 1, + COINCIDENT, + COINCIDENT_NO_INTERSECT, + INTERSECT, + INTERSECT_OUTSIDE, +} + +export const DEFAULT_SAMPLES = 20; + +export type Attribs = IObjectOf; + +export type VecPair = [Vec, Vec]; + +export interface IShape extends + ICopy { + + readonly type: number | string; + attribs?: Attribs; +} + +export interface AABBLike extends IShape { + pos: Vec; + size: Vec; +} + +export interface PCLike extends IShape { + points: Vec[]; +} + +export interface PCLikeConstructor { + new(pts: Vec[], attribs: Attribs): PCLike; +} + +export interface HiccupShape extends IShape, IToHiccup { } + +export interface IHiccupPathSegment { + toHiccupPathSegments(): any[]; +} + +export interface LineIntersection { + type: LineIntersectionType; + isec?: Vec; + det?: number; + alpha?: number; + beta?: number; +} + +export interface SamplingOpts { + /** + * Number of points to sample & return. Defaults to the implementing + * type's `DEFAULT_RES` if neither this nor `theta` option is given + * (see `ArcSamplingOpts`). + */ + num: number; + /** + * Approximate desired distance between sampled result points. If + * given, takes priority over the `num` option, but the latter MIGHT + * be used as part of the sampling process (implementation + * specific). Note: For circles this value is interpreted as arc + * length, not cartesian distance (error will be proportional to the + * given value relative to the circle's radius). + */ + dist: number; + /** + * Currently only used by these types: + * + * - Arc2 + * - Circle2 + * + * Defines the target angle between sampled points. If greater than + * the actual range of the arc, only the two end points will be + * returned at most. This option is used to derive a `num` value and + * takes priority if `num` is given as well. + * + * This option is useful to adapt the sampling based on angular + * resolution, rather than a fixed number of samples. + */ + theta: number; + /** + * If `true`, the shape's end point will be included in the result + * array. The default setting for open geometries is `true`, for + * closed ones `false`. This option has no influence on any internal + * resolution calculation. + * + * For open geometry this option is useful to when re-sampling paths + * of consecutive segments, where the end points of each segment + * coincide with the start points of the next segment. For all but + * the last segment, this option should be `false` and so can be + * used to avoid duplicate vertices in the concatenated result. + * + * When sampling closed shapes, enabling this option will include an + * extra point (start), i.e. if the `num` option was given, results + * in `num+1` points. + */ + last: boolean; +} + +export interface SubdivKernel { + fn: (pts: ReadonlyVec[], i: number, nump: number) => Vec[]; + iter?: (pts: ReadonlyVec[]) => Iterable; + size: number; +} + +export abstract class APC implements + PCLike { + + points: Vec[]; + attribs: Attribs; + + constructor(points: Vec[], attribs?: Attribs) { + this.points = points; + this.attribs = attribs; + } + + abstract get type(): number | string; + + *[Symbol.iterator]() { + yield* this.points; + } + + abstract copy(): IShape; +} + +export class AABB implements + IShape { + + pos: Vec; + size: Vec; + attribs: Attribs; + + constructor(pos: Vec = [0, 0, 0], size: Vec = [1, 1, 1], attribs?: Attribs) { + this.pos = pos; + this.size = size; + this.attribs = attribs; + } + + get type() { + return Type.AABB; + } + + copy() { + return new AABB(copy(this.pos), copy(this.size), { ...this.attribs }); + } +} + +export class Circle implements + HiccupShape { + + pos: Vec; + r: number; + attribs: Attribs; + + constructor(pos: Vec = [0, 0], r = 1, attribs?: Attribs) { + this.pos = pos; + this.r = r; + this.attribs = attribs; + } + + get type() { + return Type.CIRCLE; + } + + copy() { + return new Circle(copy(this.pos), this.r, { ...this.attribs }); + } + + toHiccup() { + return ["circle", this.attribs, this.pos, this.r]; + } +} + +export class Cubic extends APC implements + IHiccupPathSegment { + + get type() { + return Type.CUBIC; + } + + copy() { + return new Cubic(copyPoints(this.points), { ...this.attribs }); + } + + toHiccup() { + return ["path", this.attribs, + [ + ["M", this.points[0]], + ...this.toHiccupPathSegments() + ] + ]; + } + + toHiccupPathSegments() { + const pts = this.points; + return [["C", pts[1], pts[2], pts[3]]]; + } +} + +export class Ellipse implements + HiccupShape { + + pos: Vec; + r: Vec; + attribs: Attribs; + + constructor(pos: Vec = [0, 0], r: number | Vec = [1, 1], attribs?: Attribs) { + this.pos = pos; + this.r = isNumber(r) ? [r, r] : r; + this.attribs = attribs; + } + + get type() { + return Type.ELLIPSE; + } + + copy() { + return new Ellipse(copy(this.pos), copy(this.r), { ...this.attribs }); + } + + toHiccup() { + return ["ellipse", this.attribs, this.pos, this.r]; + } +} + +export class Group implements + HiccupShape { + + children: HiccupShape[]; + attribs: Attribs; + + constructor(children: HiccupShape[], attribs?: Attribs) { + this.children = children; + this.attribs = attribs; + } + + get type() { + return Type.GROUP; + } + + *[Symbol.iterator]() { + yield* this.children; + } + + copy() { + return new Group( + this.children.map((c) => c.copy()), + { ...this.attribs } + ); + } + + equiv(o: any) { + return o instanceof Group && + equiv(this.children, o.children); + } + + toHiccup() { + return ["g", this.attribs, ...this.children.map((x) => x.toHiccup())]; + } +} + +export class Line extends APC { + + get type() { + return Type.LINE; + } + + copy() { + return new Line(copyPoints(this.points), { ...this.attribs }); + } + + toHiccup() { + return ["line", this.attribs, this.points[0], this.points[1]]; + } +} + +export class Points extends APC { + + get type() { + return Type.POINTS; + } + + copy() { + return new Points(copyPoints(this.points), { ...this.attribs }); + } + + toHiccup() { + return ["points", this.attribs, this.points]; + } +} + +export class Polygon extends APC { + + get type() { + return Type.POLYGON; + } + + copy() { + return new Polygon(copyPoints(this.points), { ...this.attribs }); + } + + toHiccup() { + return ["polygon", this.attribs, this.points]; + } +} + +export class Polyline extends APC { + + get type() { + return Type.POLYLINE; + } + + copy() { + return new Polyline(copyPoints(this.points), { ...this.attribs }); + } + + toHiccup() { + return ["polyline", { ...this.attribs, fill: "none" }, this.points]; + } +} + +export class Quad extends APC { + + get type() { + return Type.QUAD; + } + + copy() { + return new Quad(copyPoints(this.points), { ...this.attribs }); + } + + toHiccup() { + return ["polygon", this.attribs, this.points]; + } +} + +export class Quadratic extends APC implements + IHiccupPathSegment { + + get type() { + return Type.QUADRATIC; + } + + copy() { + return new Quadratic(copyPoints(this.points), { ...this.attribs }); + } + + toHiccup() { + return ["path", this.attribs, + [ + ["M", this.points[0]], + ...this.toHiccupPathSegments() + ] + ]; + } + + toHiccupPathSegments() { + const pts = this.points; + return [["Q", pts[1], pts[2]]]; + } +} + +export class Ray implements + HiccupShape { + + pos: Vec; + dir: Vec; + attribs: Attribs; + + constructor(pos: Vec, dir: Vec, attribs?: Attribs) { + this.pos = pos; + this.dir = dir; + this.attribs = attribs; + } + + get type() { + return Type.RAY; + } + + copy() { + return new Ray(copy(this.pos), copy(this.dir), { ...this.attribs }); + } + + toHiccup() { + return ["line", this.attribs, this.pos, maddN([], this.pos, this.dir, 1e6)]; + } +} + +export class Rect implements + HiccupShape { + + pos: Vec; + size: Vec; + attribs: Attribs; + + constructor(pos: Vec = [0, 0], size: number | Vec = [1, 1], attribs?: Attribs) { + this.pos = pos; + this.size = isNumber(size) ? [size, size] : size; + this.attribs = attribs; + } + + get type() { + return Type.RECT; + } + + copy() { + return new Rect(copy(this.pos), copy(this.size), { ...this.attribs }); + } + + toHiccup() { + return ["rect", this.attribs, this.pos, this.size]; + } +} + +export class Sphere implements + IShape { + + pos: Vec; + r: number; + attribs: Attribs; + + constructor(pos: Vec = [0, 0, 0], r = 1, attribs?: Attribs) { + this.pos = pos; + this.r = r; + this.attribs = attribs; + } + + get type() { + return Type.SPHERE; + } + + copy() { + return new Sphere(copy(this.pos), this.r, { ...this.attribs }); + } + + toHiccup() { + return ["sphere", this.attribs, this.pos, this.r]; + } +} + +export class Triangle extends APC { + + get type() { + return Type.TRIANGLE; + } + + copy() { + return new Triangle(copyPoints(this.points), { ...this.attribs }); + } + + toHiccup() { + return ["polygon", this.attribs, this.points]; + } +} diff --git a/packages/geom3/src/ctors/circle.ts b/packages/geom3/src/ctors/circle.ts new file mode 100644 index 0000000000..d3482ed808 --- /dev/null +++ b/packages/geom3/src/ctors/circle.ts @@ -0,0 +1,27 @@ +import { + dist, + mixN2, + ReadonlyVec, + Vec +} from "@thi.ng/vectors3"; +import { Attribs, Circle } from "../api"; +import { argsVN } from "../internal/args"; +import { circumCenter } from "../internal/circumcenter"; + +export function circle(pos: Vec, r: number, attribs?: Attribs): Circle; +export function circle(pos: Vec, attribs?: Attribs): Circle; +export function circle(r: number, attribs?: Attribs): Circle; +export function circle(attribs?: Attribs): Circle; +export function circle(...args: any[]) { + return new Circle(...argsVN(args)); +} + +export const circleFrom2Points = + (a: ReadonlyVec, b: ReadonlyVec, attribs?: Attribs) => + new Circle(mixN2([], a, b, 0.5), dist(a, b) / 2, attribs); + +export const circleFrom3Points = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, attribs?: Attribs) => { + const o = circumCenter(a, b, c); + return o ? new Circle(o, dist(a, o), attribs) : undefined; + }; diff --git a/packages/geom3/src/ctors/cubic.ts b/packages/geom3/src/ctors/cubic.ts new file mode 100644 index 0000000000..b601032d1b --- /dev/null +++ b/packages/geom3/src/ctors/cubic.ts @@ -0,0 +1,14 @@ +import { mixN, Vec } from "@thi.ng/vectors3"; +import { Attribs, Cubic } from "../api"; +import { argAttribs } from "../internal/args"; + +export function cubic(a: Vec, b: Vec, c: Vec, d: Vec, attribs?: Attribs): Cubic; +export function cubic(pts: Vec[], attribs?: Attribs): Cubic; +export function cubic(...args: any[]) { + const attr = argAttribs(args); + return new Cubic(args.length === 1 ? args[0] : args, attr); +} + +export const cubicFromLine = + (a: Vec, b: Vec, attribs?: Attribs) => + new Cubic([a, mixN([], a, b, 1 / 3), mixN([], b, a, 1 / 3), b], attribs); diff --git a/packages/geom3/src/ctors/ellipse.ts b/packages/geom3/src/ctors/ellipse.ts new file mode 100644 index 0000000000..f8f87f477a --- /dev/null +++ b/packages/geom3/src/ctors/ellipse.ts @@ -0,0 +1,10 @@ +import { Vec } from "@thi.ng/vectors3"; +import { Attribs, Ellipse } from "../api"; +import { argsVV } from "../internal/args"; + +export function ellipse(pos: Vec, r: number | Vec, attribs?: Attribs): Ellipse; +export function ellipse(r: number | Vec, attribs?: Attribs): Ellipse; +export function ellipse(attribs?: Attribs): Ellipse; +export function ellipse(...args: any[]) { + return new Ellipse(...argsVV(args)); +} diff --git a/packages/geom3/src/ctors/group.ts b/packages/geom3/src/ctors/group.ts new file mode 100644 index 0000000000..7a32a0749a --- /dev/null +++ b/packages/geom3/src/ctors/group.ts @@ -0,0 +1,5 @@ +import { HiccupShape, Attribs, Group } from "../api"; + +export const group = + (children: HiccupShape[], attribs?: Attribs) => + new Group(children, attribs); diff --git a/packages/geom3/src/ctors/line.ts b/packages/geom3/src/ctors/line.ts new file mode 100644 index 0000000000..981fb1c5dd --- /dev/null +++ b/packages/geom3/src/ctors/line.ts @@ -0,0 +1,10 @@ +import { Vec } from "@thi.ng/vectors3"; +import { Attribs, Line } from "../api"; +import { argAttribs } from "../internal/args"; + +export function line(a: Vec, b: Vec, attribs?: Attribs): Line; +export function line(pts: Vec[], attribs?: Attribs): Line; +export function line(...args: any[]) { + const attr = argAttribs(args); + return new Line(args.length === 1 ? args[0] : args, attr); +} diff --git a/packages/geom3/src/ctors/points.ts b/packages/geom3/src/ctors/points.ts new file mode 100644 index 0000000000..009deeab40 --- /dev/null +++ b/packages/geom3/src/ctors/points.ts @@ -0,0 +1,5 @@ +import { Attribs, Points } from "../api"; +import { Vec } from "@thi.ng/vectors3"; + +export const points = (pts?: Vec[], attribs?: Attribs) => + new Points(pts, attribs); diff --git a/packages/geom3/src/ctors/polygon.ts b/packages/geom3/src/ctors/polygon.ts new file mode 100644 index 0000000000..8576ddffc3 --- /dev/null +++ b/packages/geom3/src/ctors/polygon.ts @@ -0,0 +1,26 @@ +import { TAU } from "@thi.ng/math"; +import { + cycle, + map, + normRange, + push, + transduce, + tuples +} from "@thi.ng/transducers"; +import { cartesian2, Vec } from "@thi.ng/vectors3"; +import { Attribs, Polygon } from "../api"; + +export const polygon = + (pts: Vec[], attribs?: Attribs) => + new Polygon(pts, attribs); + +export const star = + (r: number, n: number, profile: number[], attribs?: Attribs) => + new Polygon( + transduce( + map(([i, p]) => cartesian2(null, [r * p, i * TAU])), + push(), + tuples(normRange(n * profile.length, false), cycle(profile)) + ), + attribs + ); diff --git a/packages/geom3/src/ctors/polyline.ts b/packages/geom3/src/ctors/polyline.ts new file mode 100644 index 0000000000..0634359ee4 --- /dev/null +++ b/packages/geom3/src/ctors/polyline.ts @@ -0,0 +1,6 @@ +import { Vec } from "@thi.ng/vectors3"; +import { Attribs, Polyline } from "../api"; + +export const polyline = + (pts: Vec[], attribs?: Attribs) => + new Polyline(pts, attribs); diff --git a/packages/geom3/src/ctors/quad.ts b/packages/geom3/src/ctors/quad.ts new file mode 100644 index 0000000000..8b9c3aacf0 --- /dev/null +++ b/packages/geom3/src/ctors/quad.ts @@ -0,0 +1,10 @@ +import { Vec } from "@thi.ng/vectors3"; +import { Attribs, Quad } from "../api"; +import { argAttribs } from "../internal/args"; + +export function quad(a: Vec, b: Vec, c: Vec, d: Vec, attribs?: Attribs): Quad; +export function quad(pts: Vec[], attribs?: Attribs): Quad; +export function quad(...args: any[]) { + const attr = argAttribs(args); + return new Quad(args.length === 1 ? args[0] : args, attr); +} diff --git a/packages/geom3/src/ctors/quadratic.ts b/packages/geom3/src/ctors/quadratic.ts new file mode 100644 index 0000000000..1a3c3ff1d3 --- /dev/null +++ b/packages/geom3/src/ctors/quadratic.ts @@ -0,0 +1,14 @@ +import { mixN, Vec } from "@thi.ng/vectors3"; +import { Attribs, Quadratic } from "../api"; +import { argAttribs } from "../internal/args"; + +export function quadratic(a: Vec, b: Vec, c: Vec, attribs?: Attribs): Quadratic; +export function quadratic(pts: Vec[], attribs?: Attribs): Quadratic; +export function quadratic(...args: any[]) { + const attr = argAttribs(args); + return new Quadratic(args.length === 1 ? args[0] : args, attr); +} + +export const quadraticFromLine = + (a: Vec, b: Vec, attribs?: Attribs) => + new Quadratic([a, mixN([], a, b, 0.5), b], attribs) diff --git a/packages/geom3/src/ctors/rect.ts b/packages/geom3/src/ctors/rect.ts new file mode 100644 index 0000000000..789a985316 --- /dev/null +++ b/packages/geom3/src/ctors/rect.ts @@ -0,0 +1,14 @@ +import { sub2, Vec } from "@thi.ng/vectors3"; +import { Attribs, Rect } from "../api"; +import { argsVV } from "../internal/args"; + +export function rect(pos: Vec, size: number | Vec, attribs?: Attribs): Rect; +export function rect(size: number | Vec, attribs?: Attribs): Rect; +export function rect(attribs?: Attribs): Rect; +export function rect(...args: any[]) { + return new Rect(...argsVV(args)); +} + +export const rectFromMinMax = + (min: Vec, max: Vec, attribs?: Attribs) => + new Rect(min, sub2([], max, min), attribs); diff --git a/packages/geom3/src/ctors/triangle.ts b/packages/geom3/src/ctors/triangle.ts new file mode 100644 index 0000000000..55cc9b0e9c --- /dev/null +++ b/packages/geom3/src/ctors/triangle.ts @@ -0,0 +1,25 @@ +import { THIRD_PI } from "@thi.ng/math"; +import { + maddN2, + mag, + normalize, + perpendicularLeft2, + sub2, + Vec +} from "@thi.ng/vectors3"; +import { Attribs, Triangle } from "../api"; +import { argAttribs } from "../internal/args"; + +export function triangle(a: Vec, b: Vec, c: Vec, attribs?: Attribs): Triangle; +export function triangle(pts: Vec[], attribs?: Attribs): Triangle; +export function triangle(...args: any[]) { + const attr = argAttribs(args); + return new Triangle(args.length === 1 ? args[0] : args, attr); +} + +export const equilateralTriangle = + (a: Vec, b: Vec, attribs?: Attribs) => { + const dir = sub2([], b, a); + const c = normalize(null, perpendicularLeft2([], dir), mag(dir) * Math.sin(THIRD_PI)); + return new Triangle([a, b, maddN2(null, c, dir, 0.5)], attribs); + }; diff --git a/packages/geom3/src/index.ts b/packages/geom3/src/index.ts new file mode 100644 index 0000000000..3d396f40e5 --- /dev/null +++ b/packages/geom3/src/index.ts @@ -0,0 +1,57 @@ +export * from "./api"; + +export * from "./ctors/circle"; +export * from "./ctors/cubic"; +export * from "./ctors/ellipse"; +export * from "./ctors/group"; +export * from "./ctors/line"; +export * from "./ctors/polygon"; +export * from "./ctors/polyline"; +export * from "./ctors/quad"; +export * from "./ctors/quadratic"; +export * from "./ctors/rect"; +export * from "./ctors/triangle"; + +export * from "./ops/arc-length"; +export * from "./ops/area"; +export * from "./ops/as-polygon"; +export * from "./ops/as-svg"; +export * from "./ops/bounds"; +export * from "./ops/center"; +export * from "./ops/centroid"; +export * from "./ops/classify-point"; +export * from "./ops/closest-point"; +export * from "./ops/convex-hull"; +export * from "./ops/fit-into-bounds"; +export * from "./ops/map-point"; +export * from "./ops/point-at"; +export * from "./ops/point-inside"; +export * from "./ops/resample"; +export * from "./ops/simplify"; +export * from "./ops/subdiv-curve"; +export * from "./ops/tangent-at"; +export * from "./ops/transform"; +export * from "./ops/translate"; +export * from "./ops/union"; +export * from "./ops/unmap-point"; +export * from "./ops/vertices"; + +export * from "./internal/bounds"; +export * from "./internal/centroid"; +export * from "./internal/circumcenter"; +export * from "./internal/closest-point"; +export * from "./internal/copy-points"; +export * from "./internal/corner"; +export * from "./internal/douglas–peucker"; +export * from "./internal/graham-scan"; +export * from "./internal/liang-barsky"; +export * from "./internal/line-intersection"; +export * from "./internal/poly-arc-length"; +export * from "./internal/poly-area"; +export * from "./internal/poly-centroid"; +export * from "./internal/poly-point-inside"; +export * from "./internal/sampler"; +export * from "./internal/subdiv-curve"; +export * from "./internal/sutherland-hodgeman"; +export * from "./internal/transform-points"; +export * from "./internal/union-bounds"; diff --git a/packages/geom3/src/internal/args.ts b/packages/geom3/src/internal/args.ts new file mode 100644 index 0000000000..7bf1bba99f --- /dev/null +++ b/packages/geom3/src/internal/args.ts @@ -0,0 +1,49 @@ +import { isNumber, isPlainObject } from "@thi.ng/checks"; +import { peek } from "@thi.ng/transducers"; + +/** + * Takes an array of arguments, checks if last element is a plain object + * and if so, removes it from array and returns it. Else returns + * `undefined`. + * + * @param args + */ +export const argAttribs = + (args: any[]) => + isPlainObject(peek(args)) ? + args.pop() : + undefined; + +/** + * Args parser for functions expecting up to 2 vector args and optional + * attribs object. Returns 3-tuple of re-structured args. + * + * @param args + */ +export const argsVV = + (args: any[]) => { + const attr = argAttribs(args); + return args.length ? + args.length === 2 ? + [args[0], args[1], attr] : + [undefined, args[0], attr] : + [undefined, undefined, attr]; + }; + +/** + * Args parser for functions expecting a vector, numeric and/or optional + * attribs object. Returns 3-tuple of re-structured args. + * + * @param args + */ +export const argsVN = + (args: any[]) => { + const attr = argAttribs(args); + return args.length ? + args.length === 2 ? + [args[0], args[1], attr] : + isNumber(args[0]) ? + [undefined, args[0], attr] : + [args[0], undefined, attr] : + [undefined, undefined, attr]; + }; diff --git a/packages/geom3/src/internal/bounds.ts b/packages/geom3/src/internal/bounds.ts new file mode 100644 index 0000000000..7dcd3ddf64 --- /dev/null +++ b/packages/geom3/src/internal/bounds.ts @@ -0,0 +1,23 @@ +import { max, min, Vec } from "@thi.ng/vectors3"; + +/** + * Computes the nD bounds of given vectors. `vmin` should be initialized + * to `+Infinity` and `vmax` to `-Infinity` (e.g. use copies of `MIN*` / + * `MAX*` constants defined in thi.ng/vectors3). + * + * Returns 2-tuple of modified `[vmin, vmax]`. + * + * @param pts + * @param vmin + * @param vmax + */ +export const boundsRaw = + (pts: ReadonlyArray, vmin: Vec, vmax: Vec): [Vec, Vec] => { + + for (let i = pts.length; --i >= 0;) { + const p = pts[i]; + min(null, vmin, p); + max(null, vmax, p); + } + return [vmin, vmax]; + }; diff --git a/packages/geom3/src/internal/centroid.ts b/packages/geom3/src/internal/centroid.ts new file mode 100644 index 0000000000..cffe402581 --- /dev/null +++ b/packages/geom3/src/internal/centroid.ts @@ -0,0 +1,19 @@ +import { illegalArgs } from "@thi.ng/errors"; +import { + add, + divN, + empty, + ReadonlyVec, + Vec +} from "@thi.ng/vectors3"; + +export const centroidRaw = + (pts: ReadonlyVec[], out?: Vec) => { + const num = pts.length; + !num && illegalArgs("no points available"); + !out && (out = empty(pts[0])); + for (let i = num; --i >= 0;) { + add(out, out, pts[i]); + } + return divN(null, out, num); + }; diff --git a/packages/geom3/src/internal/circumcenter.ts b/packages/geom3/src/internal/circumcenter.ts new file mode 100644 index 0000000000..a5ccca08c7 --- /dev/null +++ b/packages/geom3/src/internal/circumcenter.ts @@ -0,0 +1,43 @@ +import { EPS } from "@thi.ng/math"; +import { ReadonlyVec } from "@thi.ng/vectors3"; + +export const circumCenter = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, eps = EPS) => { + + const deltaAB = Math.abs(a[1] - b[1]); + const deltaBC = Math.abs(b[1] - c[1]); + + if (deltaAB < eps && deltaBC < eps) return; + + const ax = a[0], ay = a[1]; + const bx = b[0], by = b[1]; + const cx = c[0], cy = c[1]; + let m1, m2, mx1, mx2, my1, my2, xc, yc; + + if (deltaAB < eps) { + m2 = -(cx - bx) / (cy - by); + mx2 = (bx + cx) / 2; + my2 = (by + cy) / 2; + xc = (bx + ax) / 2; + yc = m2 * (xc - mx2) + my2; + } else if (deltaBC < eps) { + m1 = -(bx - ax) / (by - ay); + mx1 = (ax + bx) / 2; + my1 = (ay + by) / 2; + xc = (cx + bx) / 2; + yc = m1 * (xc - mx1) + my1; + } else { + m1 = -(bx - ax) / (by - ay); + m2 = -(cx - bx) / (cy - by); + mx1 = (ax + bx) / 2; + my1 = (ay + by) / 2; + mx2 = (bx + cx) / 2; + my2 = (by + cy) / 2; + xc = (m1 * mx1 - m2 * mx2 + my2 - my1) / (m1 - m2); + yc = deltaAB > deltaBC ? + m1 * (xc - mx1) + my1 : + m2 * (xc - mx2) + my2; + } + + return [xc, yc]; + }; diff --git a/packages/geom3/src/internal/closest-point.ts b/packages/geom3/src/internal/closest-point.ts new file mode 100644 index 0000000000..e4c4fd8ffd --- /dev/null +++ b/packages/geom3/src/internal/closest-point.ts @@ -0,0 +1,116 @@ +import { + distSq, + dot, + empty, + magSq, + mixN, + ReadonlyVec, + set, + sub, + Vec +} from "@thi.ng/vectors3"; + +export const closestPointRaw = + (p: ReadonlyVec, pts: Vec[]) => { + + let minD = Infinity; + let closest: Vec; + for (let i = pts.length; --i >= 0;) { + const d = distSq(pts[i], p); + if (d < minD) { + minD = d; + closest = pts[i]; + } + } + return closest; + }; + +export const closestCoeff = + (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec) => { + + const d = sub([], b, a); + const l = magSq(d); + return l > 1e-6 ? + dot(sub([], p, a), d) / l : + undefined; + }; + +/** + * Returns closest point to `p` on segment `a` -> `b`. By default, if + * the result point lies outside the segment, returns a copy of the + * closest end point. However, if `insideOnly` is true, only returns the + * closest point if it actually is inside the segment (incl. end + * points). + * + * @param p + * @param a + * @param b + * @param out + */ +export const closestPointSegment = + (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, out?: Vec, insideOnly = false) => { + + const t = closestCoeff(p, a, b); + if (t !== undefined && (!insideOnly || t >= 0 && t <= 1)) { + out = out || empty(p); + return t <= 0.0 ? + set(out, a) : + t >= 1.0 ? + set(out, b) : + mixN(out, a, b, t); + } + }; + +export const closestPointPolyline = + (p: ReadonlyVec, pts: ReadonlyArray, closed = false) => { + + const closest = empty(pts[0]); + const tmp = empty(closest); + const n = pts.length - 1; + let minD = Infinity, i, j; + if (closed) { + i = n; + j = 0; + } else { + i = 0; + j = 1; + } + for (; j <= n; i = j, j++) { + if (closestPointSegment(p, pts[i], pts[j], tmp)) { + const d = distSq(p, tmp); + if (d < minD) { + minD = d; + set(closest, tmp); + } + } + } + return closest; + }; + +/** + * Returns the index of the start point containing the segment in the + * polyline array `points` farthest away from `p` with regards to the + * line segment `a` to `b`. `points` is only checked between indices + * `from` and `to` (not including the latter). + * + * @param a + * @param b + * @param points + * @param from + * @param to + */ +export const farthestPointSegment = + (a: Vec, b: Vec, points: Vec[], from = 0, to = points.length) => { + let maxD = -1; + let maxIdx; + const tmp = empty(a); + for (let i = from; i < to; i++) { + const p = points[i]; + const d = distSq(p, closestPointSegment(p, a, b, tmp) || a); + if (d > maxD) { + maxD = d; + maxIdx = i; + } + } + return [maxIdx, Math.sqrt(maxD)]; + }; diff --git a/packages/geom3/src/internal/coll-bounds.ts b/packages/geom3/src/internal/coll-bounds.ts new file mode 100644 index 0000000000..48b4d9590e --- /dev/null +++ b/packages/geom3/src/internal/coll-bounds.ts @@ -0,0 +1,24 @@ +import { Fn } from "@thi.ng/api"; +import { AABBLike, IShape } from "../api"; +import { unionBounds } from "./union-bounds"; + +/** + * Computes the total bounds for the given shape collection, which + * should either contain only 2D or 3D types. No mixed dimensions are + * allowed! Currently the `bounds` function must be passed in as arg to + * avoid circular module dependencies. + * + * @param shapes + * @param bounds + */ +export const collBounds = + (shapes: IShape[], bounds: Fn) => { + let n = shapes.length - 1; + if (n < 0) return; + let { pos, size } = bounds(shapes[n]); + for (; --n >= 0;) { + const b = bounds(shapes[n]); + [pos, size] = unionBounds(pos, size, b.pos, b.size); + } + return [pos, size]; + }; diff --git a/packages/geom3/src/internal/copy-points.ts b/packages/geom3/src/internal/copy-points.ts new file mode 100644 index 0000000000..4be333836f --- /dev/null +++ b/packages/geom3/src/internal/copy-points.ts @@ -0,0 +1,4 @@ +import { copy, ReadonlyVec } from "@thi.ng/vectors3"; + +export const copyPoints = + (pts: ReadonlyVec[]) => pts.map((p) => copy(p)); diff --git a/packages/geom3/src/internal/corner.ts b/packages/geom3/src/internal/corner.ts new file mode 100644 index 0000000000..aa4d7c6de4 --- /dev/null +++ b/packages/geom3/src/internal/corner.ts @@ -0,0 +1,30 @@ +import { EPS, sign } from "@thi.ng/math"; +import { ReadonlyVec, signedArea2 } from "@thi.ng/vectors3"; + +export const classify = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, eps = EPS) => + sign(signedArea2(a, b, c), eps); + +export const clockwise2 = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => + signedArea2(a, b, c) < 0; + +export const classifyPointInTriangle2 = + (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => { + const s = clockwise2(a, b, c) ? 1 : -1; + return sign( + Math.min( + s * signedArea2(a, c, p), + s * signedArea2(b, a, p), + s * signedArea2(c, b, p) + ) + ); + }; + +export const pointInTriangle2 = + (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => { + const s = clockwise2(a, b, c) ? 1 : -1; + return s * signedArea2(a, c, p) >= 0 && + s * signedArea2(b, a, p) >= 0 && + s * signedArea2(c, b, p) >= 0; + }; diff --git a/packages/geom3/src/internal/direction.ts b/packages/geom3/src/internal/direction.ts new file mode 100644 index 0000000000..9c521ab5d0 --- /dev/null +++ b/packages/geom3/src/internal/direction.ts @@ -0,0 +1,19 @@ +import { + normalize, + perpendicularLeft2, + perpendicularRight2, + ReadonlyVec, + sub +} from "@thi.ng/vectors3"; + +export const direction = + (a: ReadonlyVec, b: ReadonlyVec, n = 1) => + normalize(null, sub([], b, a), n); + +export const normalL2 = + (a: ReadonlyVec, b: ReadonlyVec, n = 1) => + perpendicularLeft2(null, direction(a, b, n)); + +export const normalR2 = + (a: ReadonlyVec, b: ReadonlyVec, n = 1) => + perpendicularRight2(null, direction(a, b, n)); diff --git a/packages/geom3/src/internal/dispatch.ts b/packages/geom3/src/internal/dispatch.ts new file mode 100644 index 0000000000..09f4da1a3d --- /dev/null +++ b/packages/geom3/src/internal/dispatch.ts @@ -0,0 +1,5 @@ +import { IShape } from "../api"; + +export const dispatch = (x: IShape) => x.type; + +export const dispatch2 = (a: IShape, b: IShape) => a.type + "-" + b.type; diff --git "a/packages/geom3/src/internal/douglas\342\200\223peucker.ts" "b/packages/geom3/src/internal/douglas\342\200\223peucker.ts" new file mode 100644 index 0000000000..4a2636ef6b --- /dev/null +++ "b/packages/geom3/src/internal/douglas\342\200\223peucker.ts" @@ -0,0 +1,42 @@ +import { EPS } from "@thi.ng/math"; +import { peek } from "@thi.ng/transducers"; +import { eqDelta, Vec } from "@thi.ng/vectors3"; +import { farthestPointSegment } from "./closest-point"; + +// https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm + +export const douglasPeucker2 = + (pts: Vec[], eps = 0, closed = false) => { + + let num = pts.length; + const visited: boolean[] = []; + if (num <= 2) return pts.slice(); + if (closed && !eqDelta(pts[0], peek(pts), EPS)) { + pts = pts.slice(); + pts.push(pts[0]); + num++; + } + + const $ = (from: number, to: number) => { + visited[from] = visited[to] = true; + if (to <= from + 1) { + return; + } + const [maxIdx, maxD] = farthestPointSegment(pts[from], pts[to], pts, from + 1, to); + if (maxD <= eps) { + return; + } + $(from, maxIdx); + $(maxIdx, to); + }; + + $(0, num - 1); + + const res: Vec[] = []; + for (let i = 0, n = closed ? num - 1 : num; i < n; i++) { + if (visited[i]) { + res.push(pts[i]); + } + } + return res; + }; diff --git a/packages/geom3/src/internal/graham-scan.ts b/packages/geom3/src/internal/graham-scan.ts new file mode 100644 index 0000000000..76ede164c0 --- /dev/null +++ b/packages/geom3/src/internal/graham-scan.ts @@ -0,0 +1,87 @@ +import { EPS } from "@thi.ng/math"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3"; + +/** + * Returns array of points defining the 2D Convex Hull of `pts` using + * the Graham Scan method. + * + * https://en.wikipedia.org/wiki/Graham_scan + * + * @param pts + */ +export const grahamScan2 = + (pts: ReadonlyVec[], eps = EPS) => { + const num = pts.length; + if (num <= 3) return pts.slice(); + let h = 1, i, p, q, r, rx, ry; + // find min YX index + const min = findMin(pts); + [rx, ry] = pts[min]; + const sorted = []; + // compute & sort by polar ordering relative to min + for (i = 0; i < num; i++) { + p = pts[i]; + sorted[i] = { p, t: Math.atan2(p[1] - ry, p[0] - rx) }; + } + sorted.sort( + (a, b) => + a.t !== b.t ? + a.t - b.t : + a.p[0] - b.p[0] + ); + const hull: Vec[] = [sorted[0].p]; + for (i = 1; i < num; i++) { + p = hull[h - 2]; + q = hull[h - 1]; + r = sorted[i].p; + rx = r[0]; + ry = r[1]; + while ((h > 1 && notCCW(p[0], p[1], q[0], q[1], rx, ry, eps)) || + (h === 1 && q[0] === rx && q[1] === ry)) { + h--; + q = p; + p = hull[h - 2]; + } + hull[h++] = r; + } + hull.length = h; + return hull; + }; + +/** + * Returns true, if triangle defined by ABC is NOT counter clockwise, + * i.e. clockwise or colinear. + * + * @see thi.ng/vectors3/signedArea2 + * + * @param ax + * @param ay + * @param bx + * @param by + * @param cx + * @param cy + */ +const notCCW = (ax: number, ay: number, bx: number, by: number, cx: number, cy: number, eps: number) => + (by - ay) * (cx - ax) >= (bx - ax) * (cy - ay) - eps; + +/** + * Returns index of point with lowest YX coords. + * + * @param pts + */ +const findMin = + (pts: ReadonlyVec[]) => { + let n = pts.length - 1; + let minID = n; + let min = pts[n][1]; + let p, y; + for (; --n >= 0;) { + p = pts[n]; + y = p[1]; + if (y < min || (y === min && p[0] < pts[minID][0])) { + min = y; + minID = n; + } + } + return minID; + }; diff --git a/packages/geom3/src/internal/liang-barsky.ts b/packages/geom3/src/internal/liang-barsky.ts new file mode 100644 index 0000000000..0b69ecf34f --- /dev/null +++ b/packages/geom3/src/internal/liang-barsky.ts @@ -0,0 +1,58 @@ +import { EPS } from "@thi.ng/math"; +import { Vec } from "@thi.ng/vectors3"; + +// https://en.wikipedia.org/wiki/Liang%E2%80%93Barsky_algorithm +// https://github.com/thi-ng/c-thing/blob/master/src/geom/clip/liangbarsky.c + +export const liangBarsky2 = ( + la: Vec, + lb: Vec, + tl: Vec, + br: Vec, + ca: Vec = [], + cb: Vec = [] +): [Vec, Vec, number, number] => { + const lax = la[0]; + const lay = la[1]; + const dx = lb[0] - lax; + const dy = lb[1] - lay; + let a = 0; + let b = 1; + + const clip = (p: number, q: number) => { + if (q < 0 && Math.abs(p) < EPS) { + return 0; + } + const r = q / p; + if (p < 0) { + if (r > b) { + return false; + } else if (r > a) { + a = r; + } + } else if (p > 0) { + if (r < a) { + return false; + } else if (r < b) { + b = r; + } + } + return true; + }; + + if (!( + clip(-dx, -(tl[0] - lax)) && + clip(dx, br[0] - lax) && + clip(-dy, -(tl[1] - lay)) && + clip(dy, br[1] - lay) + )) { + return; + } + + ca[0] = a * dx + lax; + ca[1] = a * dy + lay; + cb[0] = b * dx + lax; + cb[1] = b * dy + lay; + + return [ca, cb, a, b]; +}; diff --git a/packages/geom3/src/internal/line-intersection.ts b/packages/geom3/src/internal/line-intersection.ts new file mode 100644 index 0000000000..a6c9b38cd6 --- /dev/null +++ b/packages/geom3/src/internal/line-intersection.ts @@ -0,0 +1,48 @@ +import { EPS, eqDelta } from "@thi.ng/math"; +import { mixN2, ReadonlyVec } from "@thi.ng/vectors3"; +import { LineIntersection, LineIntersectionType } from "../api"; +import { closestPointSegment } from "./closest-point"; + +export const intersectLines2 = ( + a: ReadonlyVec, + b: ReadonlyVec, + c: ReadonlyVec, + d: ReadonlyVec, + eps = EPS +): LineIntersection => { + + const bax = b[0] - a[0]; + const bay = b[1] - a[1]; + const dcx = d[0] - c[0]; + const dcy = d[1] - c[1]; + const acx = a[0] - c[0]; + const acy = a[1] - c[1]; + const det = dcy * bax - dcx * bay; + let alpha = dcx * acy - dcy * acx; + let beta = bax * acy - bay * acx; + if (eqDelta(det, 0, eps)) { + if (eqDelta(alpha, 0, eps) && eqDelta(beta, 0, eps)) { + let isec = closestPointSegment(c, a, b, undefined, true) || + closestPointSegment(d, a, b, undefined, true); + return { + isec, + type: isec ? + LineIntersectionType.COINCIDENT : + LineIntersectionType.COINCIDENT_NO_INTERSECT, + }; + } + return { type: LineIntersectionType.PARALLEL }; + } + alpha /= det; + beta /= det; + const ieps = 1 - eps; + return { + type: (eps < alpha && alpha < ieps) && (eps < beta && beta < ieps) ? + LineIntersectionType.INTERSECT : + LineIntersectionType.INTERSECT_OUTSIDE, + isec: mixN2([], a, b, alpha), + alpha, + beta, + det, + }; +}; diff --git a/packages/geom3/src/internal/poly-arc-length.ts b/packages/geom3/src/internal/poly-arc-length.ts new file mode 100644 index 0000000000..bbf27764d3 --- /dev/null +++ b/packages/geom3/src/internal/poly-arc-length.ts @@ -0,0 +1,15 @@ +import { ReadonlyVec, dist } from "@thi.ng/vectors3"; + +export const polyArcLength = + (pts: ReadonlyVec[], num = pts.length, closed = false) => { + if (num < 2) return 0; + let res = 0; + let p = pts[0]; + let q = pts[1]; + for (let i = 1; i < num; p = q, q = pts[++i]) { + res += dist(p, q); + } + return closed ? + res + dist(p, pts[0]) : + res; + }; diff --git a/packages/geom3/src/internal/poly-area.ts b/packages/geom3/src/internal/poly-area.ts new file mode 100644 index 0000000000..ed09f0e527 --- /dev/null +++ b/packages/geom3/src/internal/poly-area.ts @@ -0,0 +1,16 @@ +import { cross2, ReadonlyVec } from "@thi.ng/vectors3"; + +/** + * Interprets given points as closed 2D polygon and computes signed + * area. + * + * @param pts + */ +export const polyArea = + (pts: ReadonlyVec[]) => { + let res = 0; + for (let n = pts.length - 1, i = n, j = 0; n >= 0; i = j, j++ , n--) { + res += cross2(pts[i], pts[j]); + } + return res / 2; + }; diff --git a/packages/geom3/src/internal/poly-centroid.ts b/packages/geom3/src/internal/poly-centroid.ts new file mode 100644 index 0000000000..fc7800e277 --- /dev/null +++ b/packages/geom3/src/internal/poly-centroid.ts @@ -0,0 +1,18 @@ +import { cross2, ReadonlyVec, Vec } from "@thi.ng/vectors3"; + +export const polyCentroid = + (pts: ReadonlyVec[], c: Vec = []) => { + let area = 0; + let x = 0; + let y = 0; + for (let n = pts.length - 1, i = pts[n], j = pts[0], k = 0; k <= n; i = j, j = pts[++k]) { + const z = cross2(i, j); + area += z; + x += (i[0] + j[0]) * z; + y += (i[1] + j[1]) * z; + } + area = 1 / (area * 3); + c[0] = x * area; + c[1] = y * area; + return c; + }; diff --git a/packages/geom3/src/internal/poly-point-inside.ts b/packages/geom3/src/internal/poly-point-inside.ts new file mode 100644 index 0000000000..9d53190907 --- /dev/null +++ b/packages/geom3/src/internal/poly-point-inside.ts @@ -0,0 +1,20 @@ +import { ReadonlyVec } from "@thi.ng/vectors3"; + +export const polyPointInside = + (pts: ReadonlyVec[], { 0: px, 1: py }: ReadonlyVec) => { + let inside = 0; + for (let n = pts.length - 1, i = n, j = 0; j <= n; i = j, j++) { + inside = polyPointInsidePair(pts[i], pts[j], px, py, inside); + } + return inside; + }; + +export const polyPointInsidePair = + (a: ReadonlyVec, b: ReadonlyVec, px: number, py: number, inside: number) => { + if (((a[1] < py && b[1] >= py) || + (b[1] < py && a[1] >= py)) && + (a[0] <= px || b[0] <= px)) { + inside ^= (((a[0] + (py - a[1]) / (b[1] - a[1]) * (b[0] - a[0])) < px) ? 1 : 0); + } + return inside; + }; diff --git a/packages/geom3/src/internal/sampler.ts b/packages/geom3/src/internal/sampler.ts new file mode 100644 index 0000000000..8c61f4e2bb --- /dev/null +++ b/packages/geom3/src/internal/sampler.ts @@ -0,0 +1,139 @@ +import { isPlainObject } from "@thi.ng/checks"; +import { peek } from "@thi.ng/transducers"; +import { + copy, + dist, + mixN, + normalize, + ReadonlyVec, + sub, + Vec +} from "@thi.ng/vectors3"; +import { DEFAULT_SAMPLES, SamplingOpts, VecPair } from "../api"; +import { copyPoints } from "./copy-points"; + +export const resamplePoints = + (pts: ReadonlyVec[], opts: number | Partial, closed = false, copy = false) => { + if (opts !== undefined) { + const sampler = new Sampler(pts, false); + return isPlainObject(opts) ? + closed ? + opts.dist ? + sampler.sampleUniform(opts.dist, opts.last) : + sampler.sampleFixedNum(opts.num, opts.last) : + opts.dist ? + sampler.sampleUniform(opts.dist, opts.last !== false) : + sampler.sampleFixedNum(opts.num, opts.last !== false) : + sampler.sampleFixedNum(opts || DEFAULT_SAMPLES, !closed); + } + return copy ? + copyPoints(pts) : + pts; + }; + +export class Sampler { + + points: ReadonlyVec[]; + index: number[]; + + constructor(points: ReadonlyVec[], closed = false) { + if (closed) { + this.points = points.slice(); + this.points.push(points[0]); + } else { + this.points = points; + } + this.buildIndex(); + } + + pointAt(t: number) { + const pts = this.points; + const n = pts.length - 1; + if (n < 0) { + return; + } + if (n === 0 || t <= 0) { + return pts[0]; + } + if (t >= 1) { + return pts[n]; + } + const idx = this.index; + const t0 = t * idx[n]; + for (let i = 1; i <= n; i++) { + if (idx[i] >= t0) { + return mixN([], pts[i - 1], pts[i], (t0 - idx[i - 1]) / (idx[i] - idx[i - 1])); + } + } + } + + segmentAt(t: number): VecPair { + let i = this.indexAt(t); + if (i === undefined) { + return; + } + i = Math.max(1, i); + return [this.points[i - 1], this.points[i]]; + } + + tangentAt(t: number, n = 1) { + const seg = this.segmentAt(t); + return seg ? + normalize(null, sub([], seg[1], seg[0]), n) : + undefined; + } + + indexAt(t: number) { + const pts = this.points; + const n = pts.length - 1; + if (n < 0) { + return; + } + if (n === 0 || t <= 0) { + return 0; + } + if (t >= 1) { + return n; + } + const idx = this.index; + const t0 = t * idx[n]; + for (let i = 1; i <= n; i++) { + if (idx[i] >= t0) { + return i; + } + } + } + + sampleUniform(dist: number, includeLast = false, result: Vec[] = []) { + const index = this.index; + const pts = this.points; + const total = peek(index); + const delta = dist / total; + const n = index.length; + for (let t = 0, i = 1; t < 1; t += delta) { + const ct = t * total; + while (ct >= index[i] && i < n) { i++; } + if (i >= n) break; + const p = index[i - 1]; + result.push(mixN([], pts[i - 1], pts[i], (ct - p) / (index[i] - p))); + } + if (includeLast) { + result.push(copy(peek(pts))); + } + return result; + } + + sampleFixedNum(num: number, includeLast = false, result?: Vec[]) { + return this.sampleUniform(peek(this.index) / num, includeLast, result); + } + + protected buildIndex() { + const idx: number[] = [0]; + const pts = this.points; + const n = pts.length; + for (let i = 0, j = 1; j < n; i = j, j++) { + idx[j] = idx[i] + dist(pts[i], pts[j]); + } + this.index = idx; + } +} diff --git a/packages/geom3/src/internal/subdiv-curve.ts b/packages/geom3/src/internal/subdiv-curve.ts new file mode 100644 index 0000000000..c7c669a2c6 --- /dev/null +++ b/packages/geom3/src/internal/subdiv-curve.ts @@ -0,0 +1,64 @@ +import { + comp, + indexed, + mapcat, + partition, + push, + transduce +} from "@thi.ng/transducers"; +import { + addW2, + addW3, + addW5, + ReadonlyVec, + Vec +} from "@thi.ng/vectors3"; +import { SubdivKernel } from "../api"; + +export const subdivKernel2 = + ([ua, ub]: number[], [va, vb]: number[]) => + ([a, b]: ReadonlyVec[]) => [ + addW2([], a, b, ua, ub), + addW2([], a, b, va, vb), + ]; + +export const subdivKernel3 = + ([ua, ub, uc]: number[], [va, vb, vc]: number[]) => + ([a, b, c]: ReadonlyVec[]) => [ + addW3([], a, b, c, ua, ub, uc), + addW3([], a, b, c, va, vb, vc), + ]; + +export const subdivKernel5 = + ([ua, ub, uc, ud, ue]: number[], [va, vb, vc, vd, ve]: number[]) => + ([a, b, c, d, e]: ReadonlyVec[]) => [ + addW5([], a, b, c, d, e, ua, ub, uc, ud, ue), + addW5([], a, b, c, d, e, va, vb, vc, vd, ve), + ]; + +/** + * http://algorithmicbotany.org/papers/subgpu.sig2003.pdf + * + * @param kernel subdivision scheme + * @param pts source points + * @param recurse number of iterations + */ +export const subdivCurvePoints = ( + pts: ReadonlyVec[], + { fn, iter, size }: SubdivKernel, + recurse = 1) => { + + while (--recurse >= 0) { + const nump = pts.length; + pts = transduce( + comp( + partition(size, 1), + indexed(), + mapcat(([i, pts]) => fn(pts, i, nump)) + ), + push(), + iter ? iter(pts) : pts + ); + } + return pts; +}; diff --git a/packages/geom3/src/internal/sutherland-hodgeman.ts b/packages/geom3/src/internal/sutherland-hodgeman.ts new file mode 100644 index 0000000000..202ef7deae --- /dev/null +++ b/packages/geom3/src/internal/sutherland-hodgeman.ts @@ -0,0 +1,44 @@ +import { ReadonlyVec } from "@thi.ng/vectors3"; +import { classify } from "./corner"; +import { intersectLines2 } from "./line-intersection"; + +/** + * Extended version of Sutherland-Hodgeman convex polygon clipping + * supporting any convex boundary (not only rects). Returns new array of + * clipped vertices. + * + * https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm + * + * @param pts subject poly vertices + * @param bounds clipping boundary vertices + * @param bc pre-computed boundary centroid + * @param eps edge classification tolerance + */ +export const sutherlandHodgeman = + (pts: ReadonlyVec[], bounds: ReadonlyVec[], bc: ReadonlyVec, eps = 1e-4) => { + for (let ne = bounds.length, j = ne - 1, i = 0; i < ne; j = i, i++) { + const clipped = []; + const ca = bounds[j]; + const cb = bounds[i]; + const sign = classify(ca, cb, bc, eps); + for (let np = pts.length, k = np - 1, l = 0; l < np; k = l, l++) { + const p = pts[k]; + const q = pts[l]; + const cqsign = classify(ca, cb, q, eps); + if (classify(ca, cb, p, eps) === sign) { + clipped.push( + cqsign !== sign ? + intersectLines2(ca, cb, p, q).isec : + q + ); + } else if (cqsign === sign) { + clipped.push(intersectLines2(ca, cb, p, q).isec, q); + } + } + if (clipped.length < 2) { + return []; + } + pts = clipped; + } + return pts; + }; diff --git a/packages/geom3/src/internal/transform-points.ts b/packages/geom3/src/internal/transform-points.ts new file mode 100644 index 0000000000..5a093f95e3 --- /dev/null +++ b/packages/geom3/src/internal/transform-points.ts @@ -0,0 +1,10 @@ +import { mulV, ReadonlyMat } from "@thi.ng/matrices"; +import { ReadonlyVec } from "@thi.ng/vectors3"; + +export const transformPoints = + (pts: ReadonlyVec[], mat: ReadonlyMat) => + (pts.forEach((p) => mulV(null, mat, p)), pts); + +export const transformedPoints = + (pts: ReadonlyVec[], mat: ReadonlyMat) => + pts.map((p) => mulV([], mat, p)); diff --git a/packages/geom3/src/internal/translate-points.ts b/packages/geom3/src/internal/translate-points.ts new file mode 100644 index 0000000000..760bab4290 --- /dev/null +++ b/packages/geom3/src/internal/translate-points.ts @@ -0,0 +1,5 @@ +import { add, ReadonlyVec } from "@thi.ng/vectors3"; + +export const translatedPoints = + (pts: ReadonlyVec[], delta: ReadonlyVec) => + pts.map((x) => add([], x, delta)); diff --git a/packages/geom3/src/internal/union-bounds.ts b/packages/geom3/src/internal/union-bounds.ts new file mode 100644 index 0000000000..523430c51b --- /dev/null +++ b/packages/geom3/src/internal/union-bounds.ts @@ -0,0 +1,25 @@ +import { + add, + max, + min, + ReadonlyVec, + sub, + Vec +} from "@thi.ng/vectors3"; + +/** + * Takes the position and size vectors of 2 `AABBLike`s and returns + * 2-tuple of `[pos,size]` of their union bounds. + * + * @param apos + * @param asize + * @param bpos + * @param bsize + */ +export const unionBounds = + (apos: ReadonlyVec, asize: ReadonlyVec, bpos: ReadonlyVec, bsize: ReadonlyVec): [Vec, Vec] => { + const p = add([], apos, asize); + const q = add([], bpos, bsize); + const pos = min([], apos, bpos); + return [pos, sub(null, max(null, p, q), pos)]; + }; diff --git a/packages/geom3/src/ops/arc-length.ts b/packages/geom3/src/ops/arc-length.ts new file mode 100644 index 0000000000..57d1a5ac65 --- /dev/null +++ b/packages/geom3/src/ops/arc-length.ts @@ -0,0 +1,79 @@ +import { defmulti, MultiFn1 } from "@thi.ng/defmulti"; +import { PI, TAU } from "@thi.ng/math"; +import { dist } from "@thi.ng/vectors3"; +import { + Circle, + Ellipse, + Group, + IShape, + Line, + Polygon, + Rect, + Type, + Triangle +} from "../api"; +import { dispatch } from "../internal/dispatch"; +import { polyArcLength } from "../internal/poly-arc-length"; + +/** + * Returns the arc length / perimeter / circumference of the given + * shape. For groups calls `arcLength()` for each child and returns the + * sum of results. + * + * Implemented for: + * + * - Circle + * - Ellipse + * - Group + * - Line + * - Polygon + * - Polyline + * - Quad + * - Rect + * - Triangle + * + */ +export const arcLength: MultiFn1 = defmulti(dispatch); + +arcLength.addAll({ + + [Type.CIRCLE]: + ($: Circle) => + TAU * $.r, + + [Type.ELLIPSE]: + ({ r: [a, b] }: Ellipse) => + // Ramanujan approximation + // https://www.mathsisfun.com/geometry/ellipse-perimeter.html + PI * ((3 * (a + b)) - Math.sqrt((3 * a + b) * (3 * b + a))), + + [Type.GROUP]: + ({ children }: Group) => + children.reduce((sum, $) => sum + arcLength($), 0), + + [Type.LINE]: + ({ points }: Line) => + dist(points[0], points[1]), + + [Type.POLYGON]: + ({ points }: Polygon) => + polyArcLength(points, points.length, true), + + [Type.POLYLINE]: + ({ points }: Polygon) => + polyArcLength(points, points.length), + + [Type.RECT]: + ({ size }: Rect) => + 2 * (size[0] + size[1]), + + [Type.TRIANGLE]: + ({ points }: Triangle) => + dist(points[0], points[1]) + + dist(points[1], points[2]) + + dist(points[2], points[0]), + +}); + +arcLength.isa(Type.QUAD, Type.POLYGON); +arcLength.isa(Type.TRIANGLE, Type.POLYGON); diff --git a/packages/geom3/src/ops/area.ts b/packages/geom3/src/ops/area.ts new file mode 100644 index 0000000000..e3eaed3ff2 --- /dev/null +++ b/packages/geom3/src/ops/area.ts @@ -0,0 +1,96 @@ +import { defmulti, MultiFn1O } from "@thi.ng/defmulti"; +import { PI } from "@thi.ng/math"; +import { signedArea2, Vec } from "@thi.ng/vectors3"; +import { + AABB, + Circle, + Ellipse, + Group, + IShape, + Polygon, + Rect, + Triangle, + Type +} from "../api"; +import { dispatch } from "../internal/dispatch"; +import { polyArea } from "../internal/poly-area"; + +/** + * Returns the possibly signed (by default) surface area of given + * `shape`. For groups calls `area()` for each child and returns sum of + * unsigned areas. + * + * In general, for polygons and triangles, the sign of the result can be + * used as indication of the shapes orientation (clockwise / + * counterclockwise). + * + * For curves, lines, point clouds and rays the function returns 0. + * + * Implemented for: + * + * - AABB + * - Circle + * - Cubic + * - Ellipse + * - Group + * - Line + * - Points + * - Polygon + * - Polyline + * - Quad + * - Quadratic + * - Ray + * - Rect + * - Triangle + * + * @param shape + * @param signed true, if signed area + */ +export const area: MultiFn1O = defmulti(dispatch); + +area.addAll({ + + [Type.AABB]: + ({ size: [w, h, d] }: AABB) => + 2 * ((w * h) + (w * d) + (h * d)), + + [Type.CIRCLE]: + ($: Circle) => + PI * $.r * $.r, + + [Type.ELLIPSE]: + ($: Ellipse) => + PI * $.r[0] * $.r[1], + + [Type.GROUP]: + ({ children }: Group) => + children.reduce((sum, $) => sum + area($, false), 0), + + [Type.POINTS]: + () => 0, + + [Type.POLYGON]: + ($: Polygon, signed = true) => { + const area = polyArea($.points); + return signed ? area : Math.abs(area); + }, + + [Type.RECT]: + ($: Rect) => + $.size[0] * $.size[1], + + [Type.TRIANGLE]: + ($: Triangle, signed = true) => { + const area = 0.5 * signedArea2(...<[Vec, Vec, Vec]>$.points); + return signed ? area : Math.abs(area); + }, + +}); + +area.isa(Type.ARC, Type.POINTS); +area.isa(Type.CUBIC, Type.POINTS); +area.isa(Type.LINE, Type.POINTS); +area.isa(Type.POLYLINE, Type.POINTS); +area.isa(Type.QUAD, Type.POLYGON); +area.isa(Type.QUADRATIC, Type.POINTS); +area.isa(Type.RAY, Type.POINTS); diff --git a/packages/geom3/src/ops/as-polygon.ts b/packages/geom3/src/ops/as-polygon.ts new file mode 100644 index 0000000000..b43dfc9fdd --- /dev/null +++ b/packages/geom3/src/ops/as-polygon.ts @@ -0,0 +1,27 @@ +import { defmulti, MultiFn1O } from "@thi.ng/defmulti"; +import { + IShape, + Polygon, + SamplingOpts, + Type +} from "../api"; +import { dispatch } from "../internal/dispatch"; +import { vertices } from "./vertices"; + +export const asPolygon: MultiFn1O, Polygon> = defmulti(dispatch); + +asPolygon.addAll({ + + [Type.POINTS]: + ($, opts) => new Polygon(vertices($, opts), { ...$.attribs }), + +}); + +asPolygon.isa(Type.CIRCLE, Type.POINTS); +asPolygon.isa(Type.ELLIPSE, Type.POINTS); +asPolygon.isa(Type.LINE, Type.POINTS); +asPolygon.isa(Type.POLYGON, Type.POINTS); +asPolygon.isa(Type.POLYLINE, Type.POINTS); +asPolygon.isa(Type.QUAD, Type.POINTS); +asPolygon.isa(Type.RECT, Type.POINTS); +asPolygon.isa(Type.TRIANGLE, Type.POINTS); diff --git a/packages/geom3/src/ops/as-svg.ts b/packages/geom3/src/ops/as-svg.ts new file mode 100644 index 0000000000..1dd4f0755c --- /dev/null +++ b/packages/geom3/src/ops/as-svg.ts @@ -0,0 +1,27 @@ +import { serialize } from "@thi.ng/hiccup"; +import { convertTree, ff, svg } from "@thi.ng/hiccup-svg"; +import { Attribs, IShape } from "../api"; +import { bounds } from "./bounds"; +import { collBounds } from "../internal/coll-bounds"; + +export const asSvg = + (...args: any[]) => + args + .map((x) => serialize(convertTree(x))) + .join(""); + +export const svgDoc = + (attribs: Attribs, ...xs: IShape[]) => { + if (xs.length > 0) { + if (!attribs || !attribs.viewBox) { + const [pos, size] = collBounds(xs, bounds); + attribs = { + width: ff(size[0]), + height: ff(size[1]), + viewBox: `${ff(pos[0])} ${ff(pos[1])} ${ff(size[0])} ${ff(size[1])}`, + ...attribs + }; + } + } + return svg(attribs, ...xs); + }; diff --git a/packages/geom3/src/ops/bounds.ts b/packages/geom3/src/ops/bounds.ts new file mode 100644 index 0000000000..4261822ff4 --- /dev/null +++ b/packages/geom3/src/ops/bounds.ts @@ -0,0 +1,66 @@ +import { defmulti } from "@thi.ng/defmulti"; +import { + copy, + MAX2, + MIN2, + mul2, + mulN2, + sub2, + subN2 +} from "@thi.ng/vectors3"; +import { + AABBLike, + Circle, + Ellipse, + Group, + IShape, + Line, + PCLike, + Rect, + Type +} from "../api"; +import { rectFromMinMax } from "../ctors/rect"; +import { boundsRaw } from "../internal/bounds"; +import { collBounds } from "../internal/coll-bounds"; +import { dispatch } from "../internal/dispatch"; + +export const bounds = defmulti(dispatch); + +bounds.addAll({ + + [Type.CIRCLE]: + ($: Circle) => + new Rect( + subN2([], $.pos, $.r), + mulN2(null, [2, 2], $.r) + ), + + [Type.ELLIPSE]: + ($: Ellipse) => + new Rect( + sub2([], $.pos, $.r), + mul2(null, [2, 2], $.r) + ), + + [Type.GROUP]: + ($: Group) => + new Rect(...collBounds($.children, bounds)), + + [Type.LINE]: + ({ points }: Line) => + rectFromMinMax(points[0], points[1]), + + [Type.POINTS]: + ($: PCLike) => + rectFromMinMax(...boundsRaw($.points, copy(MAX2), copy(MIN2))), + + [Type.RECT]: + ($: IShape) => $.copy(), + +}); + +bounds.isa(Type.AABB, Type.RECT); +bounds.isa(Type.POLYGON, Type.POINTS); +bounds.isa(Type.POLYLINE, Type.POINTS); +bounds.isa(Type.TRIANGLE, Type.POINTS); +bounds.isa(Type.QUAD, Type.POINTS); diff --git a/packages/geom3/src/ops/center.ts b/packages/geom3/src/ops/center.ts new file mode 100644 index 0000000000..0f10ce0352 --- /dev/null +++ b/packages/geom3/src/ops/center.ts @@ -0,0 +1,42 @@ +import { DEFAULT, defmulti, MultiFn1O } from "@thi.ng/defmulti"; +import { + copy, + ReadonlyVec, + submN, + ZERO2, + ZERO3 +} from "@thi.ng/vectors3"; +import { + Circle, + Ellipse, + IShape, + Sphere, + Type +} from "../api"; +import { dispatch } from "../internal/dispatch"; +import { centroid } from "./centroid"; +import { translate } from "./translate"; + +export const center: MultiFn1O = defmulti(dispatch); + +center.add( + DEFAULT, + ($, origin = ZERO3) => + translate($, submN(null, centroid($), origin, -1)) +); + +center.addAll({ + + [Type.CIRCLE]: + ($: Circle, origin = ZERO2) => + new Circle(copy(origin), $.r, { ...$.attribs }), + + [Type.ELLIPSE]: + ($: Ellipse, origin = ZERO2) => + new Ellipse(copy(origin), copy($.r), { ...$.attribs }), + + [Type.SPHERE]: + ($: Sphere, origin = ZERO3) => + new Sphere(copy(origin), $.r, { ...$.attribs }), + +}); diff --git a/packages/geom3/src/ops/centroid.ts b/packages/geom3/src/ops/centroid.ts new file mode 100644 index 0000000000..e96c184005 --- /dev/null +++ b/packages/geom3/src/ops/centroid.ts @@ -0,0 +1,64 @@ +import { defmulti, MultiFn1O } from "@thi.ng/defmulti"; +import { + add, + divN, + maddN, + mixN, + set, + Vec +} from "@thi.ng/vectors3"; +import { + AABBLike, + Circle, + Group, + IShape, + Line, + PCLike, + Polygon, + Triangle, + Type +} from "../api"; +import { centroidRaw } from "../internal/centroid"; +import { dispatch } from "../internal/dispatch"; +import { polyCentroid } from "../internal/poly-centroid"; +import { bounds } from "./bounds"; + +export const centroid: MultiFn1O = defmulti(dispatch); + +centroid.addAll({ + + [Type.CIRCLE]: + ($: Circle, out?) => + set(out || [], $.pos), + + [Type.GROUP]: + ($: Group) => + centroid(bounds($)), + + [Type.LINE]: + ({ points }: Line, out?) => + mixN(out || [], points[0], points[1], 0.5), + + [Type.POINTS]: + ($: PCLike, out?) => + centroidRaw($.points, out), + + [Type.POLYGON]: + ($: Polygon, out?) => polyCentroid($.points, out), + + [Type.RECT]: + ($: AABBLike, out?) => maddN(out || [], $.pos, $.size, 0.5), + + [Type.TRIANGLE]: + ({ points }: Triangle, out?) => + divN(null, add(null, add(out || [], points[0], points[1]), points[2]), 3) + +}); + +centroid.isa(Type.AABB, Type.RECT); +centroid.isa(Type.ELLIPSE, Type.CIRCLE); +centroid.isa(Type.LINE3, Type.LINE); +centroid.isa(Type.POLYLINE, Type.POINTS); +centroid.isa(Type.QUAD, Type.POLYGON); +centroid.isa(Type.SPHERE, Type.CIRCLE); +centroid.isa(Type.TRIANGLE3, Type.TRIANGLE); diff --git a/packages/geom3/src/ops/classify-point.ts b/packages/geom3/src/ops/classify-point.ts new file mode 100644 index 0000000000..e369dbfe9c --- /dev/null +++ b/packages/geom3/src/ops/classify-point.ts @@ -0,0 +1,15 @@ +import { defmulti } from "@thi.ng/defmulti"; +import { EPS, sign } from "@thi.ng/math"; +import { dist, ReadonlyVec } from "@thi.ng/vectors3"; +import { Circle, IShape, Type } from "../api"; +import { dispatch } from "../internal/dispatch"; + +export const classifyPoint = defmulti(dispatch); + +classifyPoint.addAll({ + + [Type.CIRCLE]: + ($: Circle, p: ReadonlyVec, eps = EPS) => + sign($.r - dist($.pos, p), eps), + +}); diff --git a/packages/geom3/src/ops/closest-point.ts b/packages/geom3/src/ops/closest-point.ts new file mode 100644 index 0000000000..9d74912009 --- /dev/null +++ b/packages/geom3/src/ops/closest-point.ts @@ -0,0 +1,21 @@ +import { defmulti } from "@thi.ng/defmulti"; +import { + add2, + normalize, + ReadonlyVec, + sub2, + Vec +} from "@thi.ng/vectors3"; +import { Circle, IShape, Type } from "../api"; +import { dispatch } from "../internal/dispatch"; + +export const closestPoint = defmulti(dispatch); + +closestPoint.addAll({ + + [Type.CIRCLE]: + ($: Circle, p) => + add2(null, normalize(null, sub2([], p, $.pos), $.r), $.pos), + +}); + diff --git a/packages/geom3/src/ops/convex-hull.ts b/packages/geom3/src/ops/convex-hull.ts new file mode 100644 index 0000000000..c8a16791c8 --- /dev/null +++ b/packages/geom3/src/ops/convex-hull.ts @@ -0,0 +1,34 @@ +import { defmulti } from "@thi.ng/defmulti"; +import { + IShape, + PCLike, + Polygon, + Type +} from "../api"; +import { dispatch } from "../internal/dispatch"; +import { grahamScan2 } from "../internal/graham-scan"; +import { vertices } from "./vertices"; + +export const convexHull = defmulti(dispatch); + +convexHull.addAll({ + + [Type.GROUP]: + ($) => + new Polygon(vertices($), { ...$.attribs }), + + [Type.POINTS]: + ($: PCLike) => + new Polygon(grahamScan2($.points), { ...$.attribs }), + + [Type.TRIANGLE]: + ($) => $.copy(), + +}); + +convexHull.isa(Type.CIRCLE, Type.TRIANGLE); +convexHull.isa(Type.ELLIPSE, Type.TRIANGLE); +convexHull.isa(Type.POLYGON, Type.POINTS); +convexHull.isa(Type.POLYLINE, Type.POINTS); +convexHull.isa(Type.QUAD, Type.POINTS); +convexHull.isa(Type.RECT, Type.TRIANGLE); diff --git a/packages/geom3/src/ops/fit-into-bounds.ts b/packages/geom3/src/ops/fit-into-bounds.ts new file mode 100644 index 0000000000..68e2668dfc --- /dev/null +++ b/packages/geom3/src/ops/fit-into-bounds.ts @@ -0,0 +1,57 @@ +import { + concat, + ReadonlyMat, + scale23, + translation23 +} from "@thi.ng/matrices"; +import { div2, neg, ReadonlyVec } from "@thi.ng/vectors3"; +import { IShape, Rect } from "../api"; +import { bounds } from "./bounds"; +import { center } from "./center"; +import { centroid } from "./centroid"; +import { collBounds } from "../internal/coll-bounds"; +import { mapPoint } from "./map-point"; +import { transform } from "./transform"; +import { unmapPoint } from "./unmap-point"; + +const translateScale2 = + (shape: IShape, c1: ReadonlyVec, c2: ReadonlyVec, smat: ReadonlyMat) => + transform( + shape, + concat( + translation23([], c1), + smat, + translation23([], c2) + ) + ); + +export const fitIntoBounds2 = + (shape: IShape, dest: Rect) => { + const src = bounds(shape); + const tscale = div2([], dest.size, src.size); + const scale = Math.min(tscale[0], tscale[1]); + return translateScale2( + shape, + centroid(dest), + neg(null, centroid(src)), + scale23([], scale) + ); + }; + +export const fitAllIntoBounds2 = + (shapes: IShape[], dest: Rect) => { + const src = new Rect(...collBounds(shapes, bounds)); + const [w, h] = div2([], dest.size, src.size); + const s = w > 0 && h > 0 ? Math.min(w, h) : w > 0 ? w : h; + const smat = scale23([], s); + const b = center(transform(src, smat), centroid(dest)); + const c1 = []; + const c2 = []; + const res: IShape[] = []; + for (let i = shapes.length; --i >= 0;) { + const s = shapes[i]; + unmapPoint(b, mapPoint(src, centroid(s, c1)), c2); + res.push(translateScale2(s, c2, neg(null, c1), smat)); + } + return res; + }; diff --git a/packages/geom3/src/ops/map-point.ts b/packages/geom3/src/ops/map-point.ts new file mode 100644 index 0000000000..60ea6bc072 --- /dev/null +++ b/packages/geom3/src/ops/map-point.ts @@ -0,0 +1,21 @@ +import { defmulti, MultiFn2O } from "@thi.ng/defmulti"; +import { + ReadonlyVec, + Vec, + sub, + div +} from "@thi.ng/vectors3"; +import { IShape, Rect, Type } from "../api"; +import { dispatch } from "../internal/dispatch"; + +export const mapPoint: MultiFn2O = defmulti(dispatch); + +mapPoint.addAll({ + + [Type.RECT]: + ($: Rect, p: ReadonlyVec, out: Vec = []) => + div(null, sub(out, p, $.pos), $.size), + +}); + +mapPoint.isa(Type.AABB, Type.RECT); diff --git a/packages/geom3/src/ops/point-at.ts b/packages/geom3/src/ops/point-at.ts new file mode 100644 index 0000000000..24a61b2bb0 --- /dev/null +++ b/packages/geom3/src/ops/point-at.ts @@ -0,0 +1,59 @@ +import { defmulti } from "@thi.ng/defmulti"; +import { cossin, TAU } from "@thi.ng/math"; +import { + cartesian2, + madd2, + maddN, + mixN2, + Vec +} from "@thi.ng/vectors3"; +import { + Circle, + Ellipse, + IShape, + Line, + Polygon, + Ray, + Rect, + Type +} from "../api"; +import { dispatch } from "../internal/dispatch"; +import { Sampler } from "../internal/sampler"; +import { vertices } from "./vertices"; + +export const pointAt = defmulti(dispatch); + +pointAt.addAll({ + + [Type.CIRCLE]: + ($: Circle, t) => + cartesian2(null, [$.r, TAU * t], $.pos), + + [Type.ELLIPSE]: + ($: Ellipse, t) => + madd2([], $.pos, cossin(TAU * t), $.r), + + [Type.LINE]: + ({ points }: Line, t) => + mixN2([], points[0], points[1], t), + + [Type.POLYGON]: + ($: Polygon, t) => + new Sampler($.points, true).pointAt(t), + + [Type.POLYLINE]: + ($: Polygon, t) => + new Sampler($.points).pointAt(t), + + [Type.RAY]: + ($: Ray, t) => + maddN([], $.pos, $.dir, t), + + [Type.RECT]: + ($: Rect, t) => + new Sampler(vertices($), true).pointAt(t), + +}); + +pointAt.isa(Type.QUAD, Type.POLYGON); +pointAt.isa(Type.TRIANGLE, Type.POLYGON); diff --git a/packages/geom3/src/ops/point-inside.ts b/packages/geom3/src/ops/point-inside.ts new file mode 100644 index 0000000000..7f9065b0e1 --- /dev/null +++ b/packages/geom3/src/ops/point-inside.ts @@ -0,0 +1,40 @@ +import { defmulti } from "@thi.ng/defmulti"; +import { distSq, ReadonlyVec } from "@thi.ng/vectors3"; +import { + Circle, + IShape, + Rect, + Type, + Polygon, + AABB +} from "../api"; +import { dispatch } from "../internal/dispatch"; +import { polyPointInside } from "../internal/poly-point-inside"; + +export const pointInside = defmulti(dispatch); + +pointInside.addAll({ + + [Type.AABB]: + ({ pos, size }: AABB, [x, y, z]: ReadonlyVec) => + x >= pos[0] && x <= pos[0] + size[0] && + y >= pos[1] && y <= pos[1] + size[1] && + z >= pos[2] && z <= pos[2] + size[2], + + [Type.CIRCLE]: + ($: Circle, p) => + distSq($.pos, p) <= $.r * $.r, + + [Type.POLYGON]: + ($: Polygon, p) => + polyPointInside($.points, p) > 0, + + [Type.RECT]: + ({ pos, size }: Rect, [x, y]: ReadonlyVec) => + x >= pos[0] && x <= pos[0] + size[0] && + y >= pos[1] && y <= pos[1] + size[1], + +}); + +pointInside.isa(Type.SPHERE, Type.CIRCLE); +pointInside.isa(Type.QUAD, Type.POLYGON); diff --git a/packages/geom3/src/ops/resample.ts b/packages/geom3/src/ops/resample.ts new file mode 100644 index 0000000000..16d4d56e2b --- /dev/null +++ b/packages/geom3/src/ops/resample.ts @@ -0,0 +1,35 @@ +import { defmulti } from "@thi.ng/defmulti"; +import { + IShape, + PCLike, + Polygon, + Polyline, + SamplingOpts, + Type +} from "../api"; +import { dispatch } from "../internal/dispatch"; +import { resamplePoints } from "../internal/sampler"; +import { asPolygon } from "./as-polygon"; + +export const resample = defmulti, IShape>(dispatch); + +resample.addAll({ + + [Type.CIRCLE]: + ($, opts) => asPolygon($, opts), + + [Type.POLYGON]: + ($: PCLike, opts) => + new Polygon(resamplePoints($.points, opts, true, true), { ...$.attribs }), + + [Type.POLYLINE]: + ($: PCLike, opts) => + new Polyline(resamplePoints($.points, opts, false, true), { ...$.attribs }), + +}); + +resample.isa(Type.ELLIPSE, Type.CIRCLE); +resample.isa(Type.LINE, Type.POLYLINE); +resample.isa(Type.QUAD, Type.POLYGON); +resample.isa(Type.TRIANGLE, Type.POLYGON); +resample.isa(Type.RECT, Type.CIRCLE); diff --git a/packages/geom3/src/ops/simplify.ts b/packages/geom3/src/ops/simplify.ts new file mode 100644 index 0000000000..c36391efbd --- /dev/null +++ b/packages/geom3/src/ops/simplify.ts @@ -0,0 +1,29 @@ +import { defmulti } from "@thi.ng/defmulti"; +import { + IShape, + Polygon, + Polyline, + Type +} from "../api"; +import { dispatch } from "../internal/dispatch"; +import { douglasPeucker2 } from "../internal/douglas–peucker"; + +export const simplify = defmulti(dispatch); + +simplify.addAll({ + + [Type.POLYGON]: + (poly: Polygon, eps = 0.1) => + new Polygon( + douglasPeucker2(poly.points, eps, true), + { ...poly.attribs } + ), + + [Type.POLYLINE]: + (poly: Polyline, eps = 0.1) => + new Polyline( + douglasPeucker2(poly.points, eps), + { ...poly.attribs } + ), + +}); diff --git a/packages/geom3/src/ops/subdiv-curve.ts b/packages/geom3/src/ops/subdiv-curve.ts new file mode 100644 index 0000000000..593ca0a08c --- /dev/null +++ b/packages/geom3/src/ops/subdiv-curve.ts @@ -0,0 +1,87 @@ +import { defmulti, MultiFn2O } from "@thi.ng/defmulti"; +import { wrap } from "@thi.ng/transducers"; +import { mixN, ReadonlyVec } from "@thi.ng/vectors3"; +import { + IShape, + Polygon, + Polyline, + SubdivKernel, + Type +} from "../api"; +import { dispatch } from "../internal/dispatch"; +import { subdivCurvePoints, subdivKernel3 } from "../internal/subdiv-curve"; + +const CHAIKIN_FIRST = subdivKernel3([1 / 2, 1 / 2, 0], [0, 3 / 4, 1 / 4]); +const CHAIKIN_MAIN = subdivKernel3([1 / 4, 3 / 4, 0], [0, 3 / 4, 1 / 4]); +const CHAIKIN_LAST = subdivKernel3([1 / 4, 3 / 4, 0], [0, 1 / 2, 1 / 2]); +const CUBIC_MAIN = subdivKernel3([1 / 8, 3 / 4, 1 / 8], [0, 1 / 2, 1 / 2]); + +const MIDP = ([a, b]: ReadonlyVec[]) => [a, mixN([], a, b, 0.5)]; +const THIRDS = ([a, b]: ReadonlyVec[]) => [a, mixN([], a, b, 1 / 3), mixN([], a, b, 2 / 3)]; + +const wrap2 = (pts: ReadonlyVec[]) => wrap(pts, 1, false, true); +const wrap3 = (pts: ReadonlyVec[]) => wrap(pts, 1, true, true); + +export const SUBDIV_MID_OPEN: SubdivKernel = { + fn: (pts, i, n) => i < n - 2 ? MIDP(pts) : [...MIDP(pts), pts[1]], + size: 2 +}; + +export const SUBDIV_MID_CLOSED: SubdivKernel = { + fn: MIDP, + iter: wrap2, + size: 2 +}; + +export const SUBDIV_THIRDS_OPEN: SubdivKernel = { + fn: (pts, i, n) => i < n - 2 ? THIRDS(pts) : [...THIRDS(pts), pts[1]], + size: 2 +}; + +export const SUBDIV_THIRDS_CLOSED: SubdivKernel = { + fn: THIRDS, + iter: wrap2, + size: 2 +}; + +export const SUBDIV_CHAIKIN_OPEN: SubdivKernel = { + fn: (pts, i, n) => + i == 0 ? + [pts[0], ...CHAIKIN_FIRST(pts)] : + i === n - 3 ? + [...CHAIKIN_LAST(pts), pts[2]] : + CHAIKIN_MAIN(pts), + size: 3 +}; + +export const SUBDIV_CHAIKIN_CLOSED: SubdivKernel = { + fn: CHAIKIN_MAIN, + iter: wrap3, + size: 3 +}; + +export const SUBDIV_CUBIC_CLOSED: SubdivKernel = { + fn: CUBIC_MAIN, + iter: wrap3, + size: 3 +}; + +export const subdivCurve: MultiFn2O = defmulti(dispatch); + +subdivCurve.addAll({ + + [Type.POLYGON]: + (poly: Polygon, kernel, iter = 1) => + new Polygon( + subdivCurvePoints(poly.points, kernel, iter), + { ...poly.attribs } + ), + + [Type.POLYLINE]: + (line: Polyline, kernel, iter = 1) => + new Polyline( + subdivCurvePoints(line.points, kernel, iter), + { ...line.attribs } + ), + +}); diff --git a/packages/geom3/src/ops/tangent-at.ts b/packages/geom3/src/ops/tangent-at.ts new file mode 100644 index 0000000000..bfe6ec07b4 --- /dev/null +++ b/packages/geom3/src/ops/tangent-at.ts @@ -0,0 +1,43 @@ +import { defmulti } from "@thi.ng/defmulti"; +import { cossin, HALF_PI, TAU } from "@thi.ng/math"; +import { Vec } from "@thi.ng/vectors3"; +import { + IShape, + Line, + PCLike, + Rect, + Type +} from "../api"; +import { direction } from "../internal/direction"; +import { dispatch } from "../internal/dispatch"; +import { Sampler } from "../internal/sampler"; +import { vertices } from "./vertices"; + +export const tangentAt = defmulti(dispatch); + +tangentAt.addAll({ + + [Type.CIRCLE]: + (_, t) => + cossin(TAU * t + HALF_PI), + + [Type.LINE]: + ({ points }: Line) => + direction(points[0], points[1]), + + [Type.POLYGON]: + ($: PCLike, t) => + new Sampler($.points, true).tangentAt(t), + + [Type.POLYLINE]: + ($: PCLike, t) => + new Sampler($.points).tangentAt(t), + + [Type.RECT]: + ($: Rect, t) => + new Sampler(vertices($), true).tangentAt(t), + +}); + +tangentAt.isa(Type.QUAD, Type.POLYGON); +tangentAt.isa(Type.TRIANGLE, Type.POLYGON); diff --git a/packages/geom3/src/ops/transform.ts b/packages/geom3/src/ops/transform.ts new file mode 100644 index 0000000000..d20d245761 --- /dev/null +++ b/packages/geom3/src/ops/transform.ts @@ -0,0 +1,58 @@ +import { defmulti } from "@thi.ng/defmulti"; +import { ReadonlyMat } from "@thi.ng/matrices"; +import { + Group, + HiccupShape, + IShape, + Line, + PCLike, + PCLikeConstructor, + Points, + Polygon, + Polyline, + Quad, + Triangle, + Type +} from "../api"; +import { dispatch } from "../internal/dispatch"; +import { transformedPoints, transformPoints } from "../internal/transform-points"; +import { vertices } from "./vertices"; + +const tx = (ctor: PCLikeConstructor) => + ($: PCLike, mat: ReadonlyMat) => + new ctor(transformedPoints($.points, mat), { ...$.attribs }); + +export const transform = defmulti(dispatch); + +transform.addAll({ + + [Type.CIRCLE]: + ($, mat) => + new Polygon( + transformPoints(vertices($), mat), + { ...$.attribs } + ), + + [Type.GROUP]: + ($: Group, mat) => + new Group( + $.children.map((x) => transform(x, mat)), + { ...$.attribs } + ), + + [Type.LINE]: tx(Line), + + [Type.POINTS]: tx(Points), + + [Type.POLYGON]: tx(Polygon), + + [Type.POLYLINE]: tx(Polyline), + + [Type.QUAD]: tx(Quad), + + [Type.TRIANGLE]: tx(Triangle), + +}); + +transform.isa(Type.ELLIPSE, Type.CIRCLE); +transform.isa(Type.RECT, Type.CIRCLE); diff --git a/packages/geom3/src/ops/translate.ts b/packages/geom3/src/ops/translate.ts new file mode 100644 index 0000000000..a3d95c8790 --- /dev/null +++ b/packages/geom3/src/ops/translate.ts @@ -0,0 +1,101 @@ +import { defmulti } from "@thi.ng/defmulti"; +import { + add2, + add3, + ReadonlyVec, + set2, + set3 +} from "@thi.ng/vectors3"; +import { + AABB, + Circle, + Ellipse, + Group, + HiccupShape, + IShape, + Line, + PCLike, + PCLikeConstructor, + Points, + Polygon, + Polyline, + Quad, + Ray, + Rect, + Sphere, + Triangle, + Type +} from "../api"; +import { dispatch } from "../internal/dispatch"; +import { translatedPoints } from "../internal/translate-points"; + +const tx = (ctor: PCLikeConstructor) => + ($: PCLike, mat: ReadonlyVec) => + new ctor(translatedPoints($.points, mat), { ...$.attribs }); + +export const translate = defmulti(dispatch); + +translate.addAll({ + + [Type.AABB]: + ($: Rect, delta) => + new AABB( + add3([], $.pos, delta), set3([], $.size), + { ...$.attribs } + ), + + [Type.CIRCLE]: + ($: Circle, delta) => + new Circle( + add2([], $.pos, delta), $.r, + { ...$.attribs } + ), + + [Type.ELLIPSE]: + ($: Ellipse, delta) => + new Ellipse( + add2([], $.pos, delta), set2([], $.r), + { ...$.attribs } + ), + + [Type.GROUP]: + ($: Group, delta) => + new Group( + $.children.map((s) => translate(s, delta)), + { ...$.attribs } + ), + + [Type.LINE]: tx(Line), + + [Type.POINTS]: tx(Points), + + [Type.POLYGON]: tx(Polygon), + + [Type.POLYLINE]: tx(Polyline), + + [Type.QUAD]: tx(Quad), + + [Type.RAY]: + ($: Ray, delta) => + new Ray( + add2([], $.pos, delta), $.dir, + { ...$.attribs } + ), + + [Type.RECT]: + ($: Rect, delta) => + new Rect( + add2([], $.pos, delta), set2([], $.size), + { ...$.attribs } + ), + + [Type.SPHERE]: + ($: Sphere, delta) => + new Sphere( + add3([], $.pos, delta), $.r, + { ...$.attribs } + ), + + [Type.TRIANGLE]: tx(Triangle), + +}); diff --git a/packages/geom3/src/ops/union.ts b/packages/geom3/src/ops/union.ts new file mode 100644 index 0000000000..0f5e407ff6 --- /dev/null +++ b/packages/geom3/src/ops/union.ts @@ -0,0 +1,18 @@ +import { defmulti } from "@thi.ng/defmulti"; +import { dispatch } from "../internal/dispatch"; +import { IShape, Type, Rect, AABB } from "../api"; +import { unionBounds } from "../internal/union-bounds"; + +export const union = defmulti(dispatch); + +union.addAll({ + + [Type.AABB]: + (a: AABB, b: AABB) => + [new AABB(...unionBounds(a.pos, a.size, b.pos, b.size))], + + [Type.RECT]: + (a: Rect, b: Rect) => + [new Rect(...unionBounds(a.pos, a.size, b.pos, b.size))], + +}); diff --git a/packages/geom3/src/ops/unmap-point.ts b/packages/geom3/src/ops/unmap-point.ts new file mode 100644 index 0000000000..e2f134315a --- /dev/null +++ b/packages/geom3/src/ops/unmap-point.ts @@ -0,0 +1,47 @@ +import { defmulti, MultiFn2O } from "@thi.ng/defmulti"; +import { + madd, + mixBilinear, + ReadonlyVec, + Vec +} from "@thi.ng/vectors3"; +import { + IShape, + Quad, + Rect, + Type +} from "../api"; +import { dispatch } from "../internal/dispatch"; + +/** + * Projects given point `uv` (normalized coords) into the target space + * defined by `shape` and writes result to `out` (or returns new + * vector). See `mapPoint` for reverse operation. Both functions + * together can be used to warp points from one shape into another. + * + * Currently only implemented for these shape types: + * + * - AABB + * - Quad + * - Rect + * + * @param shape + * @param uv + * @param out + */ +export const unmapPoint: MultiFn2O = defmulti(dispatch); + +unmapPoint.addAll({ + + [Type.QUAD]: + ({ points }: Quad, uv, out = []) => + mixBilinear(out, points[0], points[1], points[3], points[2], uv[0], uv[1]), + + [Type.RECT]: + ($: Rect, uv: ReadonlyVec, out = []) => + madd(out, $.pos, $.size, uv), + +}); + +unmapPoint.isa(Type.AABB, Type.RECT); +unmapPoint.isa(Type.QUAD3, Type.QUAD); diff --git a/packages/geom3/src/ops/vertices.ts b/packages/geom3/src/ops/vertices.ts new file mode 100644 index 0000000000..a76d0a6b23 --- /dev/null +++ b/packages/geom3/src/ops/vertices.ts @@ -0,0 +1,94 @@ +import { isNumber } from "@thi.ng/checks"; +import { defmulti, MultiFn1O } from "@thi.ng/defmulti"; +import { TAU, cossin } from "@thi.ng/math"; +import { + add2, + cartesian2, + copy, + Vec, + madd2 +} from "@thi.ng/vectors3"; +import { + Circle, + DEFAULT_SAMPLES, + IShape, + Polygon, + Polyline, + Rect, + SamplingOpts, + Type, + Ellipse, + Group +} from "../api"; +import { dispatch } from "../internal/dispatch"; +import { resamplePoints } from "../internal/sampler"; + +export const vertices: MultiFn1O, Vec[]> = defmulti(dispatch); + +vertices.addAll({ + + [Type.CIRCLE]: + ($: Circle, opts = DEFAULT_SAMPLES) => { + const pos = $.pos; + const r = $.r; + let [num, last] = circleOpts(opts); + const delta = TAU / num; + last && num++; + const buf: Vec[] = new Array(num); + for (let i = 0; i < num; i++) { + buf[i] = cartesian2(null, [r, i * delta], pos); + } + return buf; + }, + + [Type.ELLIPSE]: + ($: Ellipse, opts = DEFAULT_SAMPLES) => { + const buf: Vec[] = []; + const pos = $.pos; + const r = $.r; + let [num, last] = circleOpts(opts); + const delta = TAU / num; + last && num++; + for (let i = 0; i < num; i++) { + buf[i] = madd2([], pos, cossin(i * delta), r); + } + return buf; + }, + + [Type.GROUP]: + ({ children }: Group) => + children.reduce((acc, $) => acc.concat(vertices($)), []), + + [Type.POLYGON]: + ($: Polygon, opts?) => + resamplePoints($.points, opts, true), + + [Type.POLYLINE]: + ($: Polyline, opts?) => + resamplePoints($.points, opts), + + [Type.RECT]: + ($: Rect, opts) => { + const p = $.pos; + const q = add2([], p, $.size); + const verts = [copy(p), [q[0], p[1]], q, [p[0], q[1]]]; + return opts != null ? + vertices(new Polygon(verts), opts) : + verts; + } +}); + +vertices.isa(Type.LINE, Type.POLYLINE); +vertices.isa(Type.QUAD, Type.POLYGON); +vertices.isa(Type.TRIANGLE, Type.POLYGON); + +const circleOpts = + (opts: number | Partial): [number, boolean] => + isNumber(opts) ? + [opts, false] : + [ + opts.theta ? + Math.floor(TAU / opts.theta) : + opts.num || DEFAULT_SAMPLES, + opts.last === true + ]; diff --git a/packages/geom3/test/index.ts b/packages/geom3/test/index.ts new file mode 100644 index 0000000000..b3cc7672bc --- /dev/null +++ b/packages/geom3/test/index.ts @@ -0,0 +1,6 @@ +// import * as assert from "assert"; +// import * as g from "../src/index"; + +describe("geom3", () => { + it("tests pending"); +}); diff --git a/packages/geom3/test/tsconfig.json b/packages/geom3/test/tsconfig.json new file mode 100644 index 0000000000..f6e63560dd --- /dev/null +++ b/packages/geom3/test/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "../build", + "module": "commonjs" + }, + "include": [ + "./**/*.ts", + "../src/**/*.ts" + ] +} diff --git a/packages/geom3/tsconfig.json b/packages/geom3/tsconfig.json new file mode 100644 index 0000000000..faed4e5fe7 --- /dev/null +++ b/packages/geom3/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": ".", + "module": "es6", + "target": "es6", + "preserveConstEnums": false + }, + "include": [ + "./src/**/*.ts" + ] +} \ No newline at end of file From d118464bf47e85e11254f7781abd4dcbc1cf2bce Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 15 Jan 2019 10:12:42 +0000 Subject: [PATCH 265/333] test(vectors): update tests (due to math eqDelta change in eps handling) --- packages/vectors/test/gvec.ts | 2 +- packages/vectors/test/vec2.ts | 2 +- packages/vectors/test/vec3.ts | 4 ++-- packages/vectors/test/vec4.ts | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/vectors/test/gvec.ts b/packages/vectors/test/gvec.ts index 6fb251cc3d..79120ab66c 100644 --- a/packages/vectors/test/gvec.ts +++ b/packages/vectors/test/gvec.ts @@ -68,7 +68,7 @@ describe("gvec", () => { it("eqdelta", () => { assert(v.eqDelta([0, 1.001, 0, 1.999, 0, 3.0099, 0, 3.991], [1, 2, 3, 4], 4, 0.01, 1, 0, 2, 1)); - assert(!v.eqDelta([0, 1.001, 0, 1.999, 0, 3.02, 0, 4], [1, 2, 3, 4], 4, 0.01, 1, 0, 2, 1)); + assert(!v.eqDelta([0, 1.001, 0, 1.999, 0, 3.04, 0, 4], [1, 2, 3, 4], 4, 0.01, 1, 0, 2, 1)); }); it("iterator", () => { diff --git a/packages/vectors/test/vec2.ts b/packages/vectors/test/vec2.ts index 79839c71ea..31e4df35b7 100644 --- a/packages/vectors/test/vec2.ts +++ b/packages/vectors/test/vec2.ts @@ -68,7 +68,7 @@ describe("vec2", () => { it("eqdelta", () => { assert(v.eqDelta2([0, 1.001, 0, 1.999, 0], [1, 2], 0.01, 1, 0, 2, 1)); - assert(!v.eqDelta2([0, 1.001, 0, 1.989, 0], [1, 2], 0.01, 1, 0, 2, 1)); + assert(!v.eqDelta2([0, 1.001, 0, 1.979, 0], [1, 2], 0.01, 1, 0, 2, 1)); }); it("iterator", () => { diff --git a/packages/vectors/test/vec3.ts b/packages/vectors/test/vec3.ts index 7e5f3df709..5929f74745 100644 --- a/packages/vectors/test/vec3.ts +++ b/packages/vectors/test/vec3.ts @@ -68,9 +68,9 @@ describe("vec3", () => { it("eqdelta", () => { assert(v.eqDelta3([0, 1.001, 0, 1.999, 0, 3.0099], [1, 2, 3], 0.01, 1, 0, 2, 1)); - assert(!v.eqDelta3([0, 1.001, 0, 1.999, 0, 3.02], [1, 2, 3], 0.01, 1, 0, 2, 1)); + assert(!v.eqDelta3([0, 1.001, 0, 1.999, 0, 3.04], [1, 2, 3], 0.01, 1, 0, 2, 1)); assert(new v.Vec3([0, 1.001, 0, 1.999, 0, 3.0099], 1, 2).eqDelta(v.vec3(1, 2, 3), 0.01)); - assert(!new v.Vec3([0, 1.001, 0, 1.999, 0, 3.02], 1, 2).eqDelta(v.vec3(1, 2, 3), 0.01)); + assert(!new v.Vec3([0, 1.001, 0, 1.999, 0, 3.04], 1, 2).eqDelta(v.vec3(1, 2, 3), 0.01)); }); it("iterator", () => { diff --git a/packages/vectors/test/vec4.ts b/packages/vectors/test/vec4.ts index c2b8931ab3..8843955fcf 100644 --- a/packages/vectors/test/vec4.ts +++ b/packages/vectors/test/vec4.ts @@ -68,7 +68,7 @@ describe("vec4", () => { it("eqdelta", () => { assert(v.eqDelta4([0, 1.001, 0, 1.999, 0, 3.0099, 0, 3.991], [1, 2, 3, 4], 0.01, 1, 0, 2, 1)); - assert(!v.eqDelta4([0, 1.001, 0, 1.999, 0, 3.02, 0, 4], [1, 2, 3, 4], 0.01, 1, 0, 2, 1)); + assert(!v.eqDelta4([0, 1.001, 0, 1.999, 0, 3.04, 0, 4], [1, 2, 3, 4], 0.01, 1, 0, 2, 1)); }); it("iterator", () => { From 9eb6f2d2dfd925c60e66267eef902c65dd5162b0 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 15 Jan 2019 11:13:03 +0000 Subject: [PATCH 266/333] build: update rollup dev dep --- package.json | 2 +- yarn.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index ee48779fd2..1dc905d799 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "nyc": "^13.1.0", "parcel-bundler": "^1.11.0", "rimraf": "^2.6.3", - "rollup": "^1.0.2", + "rollup": "^1.1.0", "rollup-plugin-cleanup": "^3.1.0", "terser": "^3.14.1", "tslint": "^5.12.0", diff --git a/yarn.lock b/yarn.lock index 8a5586e836..c2c91e123c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1542,7 +1542,7 @@ acorn@^5.0.0, acorn@^5.6.2: resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== -acorn@^6.0.4: +acorn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.5.tgz#81730c0815f3f3b34d8efa95cb7430965f4d887a" integrity sha512-i33Zgp3XWtmZBMNvCr4azvOFeWVw1Rk6p3hfi3LUDvIFraOMywb1kAtrbi+med14m4Xfpqm3zRZMT+c0FNE7kg== @@ -7836,14 +7836,14 @@ rollup-pluginutils@^2.3.0: estree-walker "^0.5.2" micromatch "^2.3.11" -rollup@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.0.2.tgz#df88abda5cfe96afaa07dbd540510f87e60d1baf" - integrity sha512-FkkSrWUVo1WliS+/GIgEmKQPILubgVdBRTWampfdhkasxx7sM2nfwSfKiX3paIBVnN0HG3DvkTy13RfjkyBX9w== +rollup@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.1.0.tgz#461a7534b55be48aa4a6e6810a1543a5769e75d1" + integrity sha512-NK03gkkOz0CchHBMGomcNqa6U3jLNzHuWK9SI0+1FV475JA6cQxVtjlDcQoKKDNIQ3IwYumIlgoKYDEWUyFBwQ== dependencies: "@types/estree" "0.0.39" "@types/node" "*" - acorn "^6.0.4" + acorn "^6.0.5" run-async@^2.2.0: version "2.3.0" From b70e84d730d1efa349a56dfcee11bac0240f283f Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 15 Jan 2019 11:24:49 +0000 Subject: [PATCH 267/333] build: update .npmignore files (add .meta) --- packages/api/.npmignore | 1 + packages/associative/.npmignore | 1 + packages/atom/.npmignore | 1 + packages/bench/.npmignore | 1 + packages/binary/.npmignore | 9 ++++++--- packages/bitstream/.npmignore | 1 + packages/cache/.npmignore | 1 + packages/checks/.npmignore | 1 + packages/compare/.npmignore | 1 + packages/compose/.npmignore | 1 + packages/csp/.npmignore | 1 + packages/dcons/.npmignore | 1 + packages/defmulti/.npmignore | 1 + packages/dgraph/.npmignore | 1 + packages/diff/.npmignore | 1 + packages/dlogic/.npmignore | 1 + packages/dot/.npmignore | 1 + packages/dsp/.npmignore | 1 + packages/equiv/.npmignore | 1 + packages/errors/.npmignore | 1 + packages/fsm/.npmignore | 1 + packages/geom-accel/.npmignore | 1 + packages/geom/.npmignore | 1 + packages/hdom-canvas/.npmignore | 1 + packages/hdom-components/.npmignore | 1 + packages/hdom-mock/.npmignore | 1 + packages/hdom/.npmignore | 1 + packages/heaps/.npmignore | 1 + packages/hiccup-carbon-icons/.npmignore | 1 + packages/hiccup-css/.npmignore | 1 + packages/hiccup-markdown/.npmignore | 1 + packages/hiccup-svg/.npmignore | 1 + packages/hiccup/.npmignore | 1 + packages/iges/.npmignore | 1 + packages/interceptors/.npmignore | 1 + packages/intervals/.npmignore | 1 + packages/iterators/.npmignore | 1 + packages/malloc/.npmignore | 1 + packages/math/.npmignore | 1 + packages/memoize/.npmignore | 1 + packages/morton/.npmignore | 1 + packages/paths/.npmignore | 1 + packages/pointfree-lang/.npmignore | 1 + packages/pointfree/.npmignore | 1 + packages/random/.npmignore | 1 + packages/range-coder/.npmignore | 1 + packages/resolve-map/.npmignore | 1 + packages/rle-pack/.npmignore | 1 + packages/router/.npmignore | 1 + packages/rstream-csp/.npmignore | 1 + packages/rstream-dot/.npmignore | 1 + packages/rstream-gestures/.npmignore | 1 + packages/rstream-graph/.npmignore | 1 + packages/rstream-log/.npmignore | 1 + packages/rstream-query/.npmignore | 1 + packages/rstream/.npmignore | 1 + packages/sax/.npmignore | 1 + packages/strings/.npmignore | 1 + packages/transducers-fsm/.npmignore | 1 + packages/transducers-hdom/.npmignore | 1 + packages/transducers-stats/.npmignore | 1 + packages/transducers/.npmignore | 1 + packages/unionstruct/.npmignore | 1 + packages/vectors/.npmignore | 1 + 64 files changed, 69 insertions(+), 3 deletions(-) diff --git a/packages/api/.npmignore b/packages/api/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/api/.npmignore +++ b/packages/api/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/associative/.npmignore b/packages/associative/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/associative/.npmignore +++ b/packages/associative/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/atom/.npmignore b/packages/atom/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/atom/.npmignore +++ b/packages/atom/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/bench/.npmignore b/packages/bench/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/bench/.npmignore +++ b/packages/bench/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/binary/.npmignore b/packages/binary/.npmignore index d703bda97a..67d0c55714 100644 --- a/packages/binary/.npmignore +++ b/packages/binary/.npmignore @@ -1,10 +1,13 @@ +.cache +.meta +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/bitstream/.npmignore b/packages/bitstream/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/bitstream/.npmignore +++ b/packages/bitstream/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/cache/.npmignore b/packages/cache/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/cache/.npmignore +++ b/packages/cache/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/checks/.npmignore b/packages/checks/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/checks/.npmignore +++ b/packages/checks/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/compare/.npmignore b/packages/compare/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/compare/.npmignore +++ b/packages/compare/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/compose/.npmignore b/packages/compose/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/compose/.npmignore +++ b/packages/compose/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/csp/.npmignore b/packages/csp/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/csp/.npmignore +++ b/packages/csp/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/dcons/.npmignore b/packages/dcons/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/dcons/.npmignore +++ b/packages/dcons/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/defmulti/.npmignore b/packages/defmulti/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/defmulti/.npmignore +++ b/packages/defmulti/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/dgraph/.npmignore b/packages/dgraph/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/dgraph/.npmignore +++ b/packages/dgraph/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/diff/.npmignore b/packages/diff/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/diff/.npmignore +++ b/packages/diff/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/dlogic/.npmignore b/packages/dlogic/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/dlogic/.npmignore +++ b/packages/dlogic/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/dot/.npmignore b/packages/dot/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/dot/.npmignore +++ b/packages/dot/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/dsp/.npmignore b/packages/dsp/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/dsp/.npmignore +++ b/packages/dsp/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/equiv/.npmignore b/packages/equiv/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/equiv/.npmignore +++ b/packages/equiv/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/errors/.npmignore b/packages/errors/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/errors/.npmignore +++ b/packages/errors/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/fsm/.npmignore b/packages/fsm/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/fsm/.npmignore +++ b/packages/fsm/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/geom-accel/.npmignore b/packages/geom-accel/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/geom-accel/.npmignore +++ b/packages/geom-accel/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/geom/.npmignore b/packages/geom/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/geom/.npmignore +++ b/packages/geom/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/hdom-canvas/.npmignore b/packages/hdom-canvas/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/hdom-canvas/.npmignore +++ b/packages/hdom-canvas/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/hdom-components/.npmignore b/packages/hdom-components/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/hdom-components/.npmignore +++ b/packages/hdom-components/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/hdom-mock/.npmignore b/packages/hdom-mock/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/hdom-mock/.npmignore +++ b/packages/hdom-mock/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/hdom/.npmignore b/packages/hdom/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/hdom/.npmignore +++ b/packages/hdom/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/heaps/.npmignore b/packages/heaps/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/heaps/.npmignore +++ b/packages/heaps/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/hiccup-carbon-icons/.npmignore b/packages/hiccup-carbon-icons/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/hiccup-carbon-icons/.npmignore +++ b/packages/hiccup-carbon-icons/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/hiccup-css/.npmignore b/packages/hiccup-css/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/hiccup-css/.npmignore +++ b/packages/hiccup-css/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/hiccup-markdown/.npmignore b/packages/hiccup-markdown/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/hiccup-markdown/.npmignore +++ b/packages/hiccup-markdown/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/hiccup-svg/.npmignore b/packages/hiccup-svg/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/hiccup-svg/.npmignore +++ b/packages/hiccup-svg/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/hiccup/.npmignore b/packages/hiccup/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/hiccup/.npmignore +++ b/packages/hiccup/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/iges/.npmignore b/packages/iges/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/iges/.npmignore +++ b/packages/iges/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/interceptors/.npmignore b/packages/interceptors/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/interceptors/.npmignore +++ b/packages/interceptors/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/intervals/.npmignore b/packages/intervals/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/intervals/.npmignore +++ b/packages/intervals/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/iterators/.npmignore b/packages/iterators/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/iterators/.npmignore +++ b/packages/iterators/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/malloc/.npmignore b/packages/malloc/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/malloc/.npmignore +++ b/packages/malloc/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/math/.npmignore b/packages/math/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/math/.npmignore +++ b/packages/math/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/memoize/.npmignore b/packages/memoize/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/memoize/.npmignore +++ b/packages/memoize/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/morton/.npmignore b/packages/morton/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/morton/.npmignore +++ b/packages/morton/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/paths/.npmignore b/packages/paths/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/paths/.npmignore +++ b/packages/paths/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/pointfree-lang/.npmignore b/packages/pointfree-lang/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/pointfree-lang/.npmignore +++ b/packages/pointfree-lang/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/pointfree/.npmignore b/packages/pointfree/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/pointfree/.npmignore +++ b/packages/pointfree/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/random/.npmignore b/packages/random/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/random/.npmignore +++ b/packages/random/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/range-coder/.npmignore b/packages/range-coder/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/range-coder/.npmignore +++ b/packages/range-coder/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/resolve-map/.npmignore b/packages/resolve-map/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/resolve-map/.npmignore +++ b/packages/resolve-map/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/rle-pack/.npmignore b/packages/rle-pack/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/rle-pack/.npmignore +++ b/packages/rle-pack/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/router/.npmignore b/packages/router/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/router/.npmignore +++ b/packages/router/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/rstream-csp/.npmignore b/packages/rstream-csp/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/rstream-csp/.npmignore +++ b/packages/rstream-csp/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/rstream-dot/.npmignore b/packages/rstream-dot/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/rstream-dot/.npmignore +++ b/packages/rstream-dot/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/rstream-gestures/.npmignore b/packages/rstream-gestures/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/rstream-gestures/.npmignore +++ b/packages/rstream-gestures/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/rstream-graph/.npmignore b/packages/rstream-graph/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/rstream-graph/.npmignore +++ b/packages/rstream-graph/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/rstream-log/.npmignore b/packages/rstream-log/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/rstream-log/.npmignore +++ b/packages/rstream-log/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/rstream-query/.npmignore b/packages/rstream-query/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/rstream-query/.npmignore +++ b/packages/rstream-query/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/rstream/.npmignore b/packages/rstream/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/rstream/.npmignore +++ b/packages/rstream/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/sax/.npmignore b/packages/sax/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/sax/.npmignore +++ b/packages/sax/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/strings/.npmignore b/packages/strings/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/strings/.npmignore +++ b/packages/strings/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/transducers-fsm/.npmignore b/packages/transducers-fsm/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/transducers-fsm/.npmignore +++ b/packages/transducers-fsm/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/transducers-hdom/.npmignore b/packages/transducers-hdom/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/transducers-hdom/.npmignore +++ b/packages/transducers-hdom/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/transducers-stats/.npmignore b/packages/transducers-stats/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/transducers-stats/.npmignore +++ b/packages/transducers-stats/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/transducers/.npmignore b/packages/transducers/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/transducers/.npmignore +++ b/packages/transducers/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/unionstruct/.npmignore b/packages/unionstruct/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/unionstruct/.npmignore +++ b/packages/unionstruct/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html diff --git a/packages/vectors/.npmignore b/packages/vectors/.npmignore index 756c6f6ea9..67d0c55714 100644 --- a/packages/vectors/.npmignore +++ b/packages/vectors/.npmignore @@ -1,4 +1,5 @@ .cache +.meta .nyc_output *.gz *.html From b63d2589004a82d03358d4ac4c100f97da31fb98 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 15 Jan 2019 11:48:14 +0000 Subject: [PATCH 268/333] docs(transducers): update cat() docstring --- packages/transducers/src/xform/cat.ts | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/packages/transducers/src/xform/cat.ts b/packages/transducers/src/xform/cat.ts index 225bfa82c6..4c58d6f0bc 100644 --- a/packages/transducers/src/xform/cat.ts +++ b/packages/transducers/src/xform/cat.ts @@ -3,17 +3,33 @@ import { compR } from "../func/compr"; import { isReduced, unreduced, ensureReduced } from "../reduced"; /** - * Transducer to concatenate iterable values. If, during processing, the - * transducer is given a wrapped `reduced()` input iterable, it will - * still be processed as normal, but then immediately triggers early - * termination by wrapping its own result in `reduced()`. This behavior - * allows a `mapcat()` user functions to benefit from `reduced` results. + * Transducer to concatenate iterable values. Iterates over each input + * and emits individual values down stream, therefore removing one level + * of nesting from the input. If, during processing, the transducer is + * given a wrapped `reduced()` input iterable, it will still be + * processed as normal, but then immediately triggers early termination + * by wrapping its own result in `reduced()`. E.g. this behavior allows + * a `mapcat()` user functions to benefit from `reduced` results. * * ``` + * [...iterator(comp(map((x) => [x, x]), cat()), [1, 2, 3, 4])] + * // [ 1, 1, 2, 2, 3, 3, 4, 4 ] + * + * [...iterator( + * comp( + * mapIndexed((i, x) => [[i], [x, x]]), + * cat(), + * cat() + * ), + * "abc" + * )] + * // [ 0, 'a', 'a', 1, 'b', 'b', 2, 'c', 'c' ] + * * [...mapcat((x)=>(x > 1 ? reduced([x, x]) : [x, x]), [1, 2, 3, 4])] * // [ 1, 1, 2, 2 ] * ``` * + * @see thi.ng/transducers/iter/concat * @see thi.ng/transducers/xform/mapcat */ export const cat = From 89dafa45f62fa61b4aa2ec70fab33c13959fcd7a Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 15 Jan 2019 11:49:53 +0000 Subject: [PATCH 269/333] build: update bundle-module script, disable minification in UMD outputs --- scripts/bundle-module | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/bundle-module b/scripts/bundle-module index 9815903682..0f8ed33b64 100755 --- a/scripts/bundle-module +++ b/scripts/bundle-module @@ -89,9 +89,7 @@ const build = interop: false, sourcemap: true, sourcemapExcludeSources: true, - }, - true, - true + } ); fs.writeFileSync(".meta/size.json", JSON.stringify({ esm, cjs, umd })); From e04eb29439fd051d43e43604f793a109380f8584 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 11 Jan 2019 14:11:21 +0000 Subject: [PATCH 270/333] refactor(defmulti): update imports, fix tests (cherry picked from cdd8659a) --- packages/defmulti/src/index.ts | 182 ++++++++++++++++++++++++++++++-- packages/defmulti/test/index.ts | 21 +++- 2 files changed, 191 insertions(+), 12 deletions(-) diff --git a/packages/defmulti/src/index.ts b/packages/defmulti/src/index.ts index d7e1ed664e..79d447ee8e 100644 --- a/packages/defmulti/src/index.ts +++ b/packages/defmulti/src/index.ts @@ -1,27 +1,43 @@ import { IObjectOf } from "@thi.ng/api"; -import { illegalArity, unsupported } from "@thi.ng/errors"; +import { illegalArgs, unsupported, illegalArity } from "@thi.ng/errors"; export const DEFAULT: unique symbol = Symbol(); export type DispatchFn = (...args) => PropertyKey; export type DispatchFn1 = (a: A, ...xs: any[]) => PropertyKey; +export type DispatchFn1O = (a: A, b?: B, ...xs: any[]) => PropertyKey; export type DispatchFn2 = (a: A, b: B, ...xs: any[]) => PropertyKey; +export type DispatchFn2O = (a: A, b: B, c?: C, ...xs: any[]) => PropertyKey; export type DispatchFn3 = (a: A, b: B, c: C, ...xs: any[]) => PropertyKey; +export type DispatchFn3O = (a: A, b: B, c: C, d?: D, ...xs: any[]) => PropertyKey; export type DispatchFn4 = (a: A, b: B, c: C, d: D, ...xs: any[]) => PropertyKey; +export type DispatchFn4O = (a: A, b: B, c: C, d: D, e?: E, ...xs: any[]) => PropertyKey; export type DispatchFn5 = (a: A, b: B, c: C, d: D, e: E, ...xs: any[]) => PropertyKey; +export type DispatchFn5O = (a: A, b: B, c: C, d: D, e: E, f?: F, ...xs: any[]) => PropertyKey; export type DispatchFn6 = (a: A, b: B, c: C, d: D, e: E, f: F, ...xs: any[]) => PropertyKey; +export type DispatchFn6O = (a: A, b: B, c: C, d: D, e: E, f: F, g?: G, ...xs: any[]) => PropertyKey; export type DispatchFn7 = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, ...xs: any[]) => PropertyKey; +export type DispatchFn7O = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h?: H, ...xs: any[]) => PropertyKey; export type DispatchFn8 = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, ...xs: any[]) => PropertyKey; +export type DispatchFn8O = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i?: I, ...xs: any[]) => PropertyKey; export type Implementation = (...args: any[]) => T; export type Implementation1 = (a: A, ...xs: any[]) => T; +export type Implementation1O = (a: A, b?: B, ...xs: any[]) => T; export type Implementation2 = (a: A, b: B, ...xs: any[]) => T; +export type Implementation2O = (a: A, b: B, c?: C, ...xs: any[]) => T; export type Implementation3 = (a: A, b: B, c: C, ...xs: any[]) => T; +export type Implementation3O = (a: A, b: B, c: C, d?: D, ...xs: any[]) => T; export type Implementation4 = (a: A, b: B, c: C, d: D, ...xs: any[]) => T; +export type Implementation4O = (a: A, b: B, c: C, d: D, e?: E, ...xs: any[]) => T; export type Implementation5 = (a: A, b: B, c: C, d: D, e: E, ...xs: any[]) => T; +export type Implementation5O = (a: A, b: B, c: C, d: D, e: E, f?: F, ...xs: any[]) => T; export type Implementation6 = (a: A, b: B, c: C, d: D, e: E, f: F, ...xs: any[]) => T; +export type Implementation6O = (a: A, b: B, c: C, d: D, e: E, f: F, g?: G, ...xs: any[]) => T; export type Implementation7 = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, ...xs: any[]) => T; +export type Implementation7O = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h?: H, ...xs: any[]) => T; export type Implementation8 = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, ...xs: any[]) => T; +export type Implementation8O = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i?: I, ...xs: any[]) => T; export interface MultiFnBase { /** @@ -49,6 +65,17 @@ export interface MultiFnBase { * @param id */ remove(id: PropertyKey): boolean; + /** + * Returns true, if the function is callable (has a valid + * implementation) for given arguments. + * + * @param args + */ + callable(...args: any[]): boolean; + /** + * Returns a set of all registered dispatch values. + */ + impls(): Set; /** * Updates dispatch hierarchy by declaring dispatch value `id` to * delegate to `parent`'s implementation. I.e. in terms of dispatch @@ -87,34 +114,66 @@ export interface MultiFn1 extends Implementation1, MultiFnBase> { } +export interface MultiFn1O extends + Implementation1O, + MultiFnBase> { } + export interface MultiFn2 extends Implementation2, MultiFnBase> { } +export interface MultiFn2O extends + Implementation2O, + MultiFnBase> { } + export interface MultiFn3 extends Implementation3, MultiFnBase> { } +export interface MultiFn3O extends + Implementation3O, + MultiFnBase> { } + export interface MultiFn4 extends Implementation4, MultiFnBase> { } +export interface MultiFn4O extends + Implementation4O, + MultiFnBase> { } + export interface MultiFn5 extends Implementation5, MultiFnBase> { } +export interface MultiFn5O extends + Implementation5O, + MultiFnBase> { } + export interface MultiFn6 extends Implementation6, MultiFnBase> { } +export interface MultiFn6O extends + Implementation6O, + MultiFnBase> { } + export interface MultiFn7 extends Implementation7, MultiFnBase> { } +export interface MultiFn7O extends + Implementation7O, + MultiFnBase> { } + export interface MultiFn8 extends Implementation8, MultiFnBase> { } +export interface MultiFn8O extends + Implementation8O, + MultiFnBase> { } + export type AncestorDefs = IObjectOf>; /** @@ -139,12 +198,20 @@ export type AncestorDefs = IObjectOf>; export function defmulti(f: DispatchFn, rels?: AncestorDefs): MultiFn; export function defmulti(f: DispatchFn1, rels?: AncestorDefs): MultiFn1; export function defmulti(f: DispatchFn2, rels?: AncestorDefs): MultiFn2; +export function defmulti(f: DispatchFn1O, rels?: AncestorDefs): MultiFn1O; export function defmulti(f: DispatchFn3, rels?: AncestorDefs): MultiFn3; +export function defmulti(f: DispatchFn2O, rels?: AncestorDefs): MultiFn2O; export function defmulti(f: DispatchFn4, rels?: AncestorDefs): MultiFn4; +export function defmulti(f: DispatchFn3O, rels?: AncestorDefs): MultiFn3O; export function defmulti(f: DispatchFn5, rels?: AncestorDefs): MultiFn5; +export function defmulti(f: DispatchFn4O, rels?: AncestorDefs): MultiFn4O; export function defmulti(f: DispatchFn6, rels?: AncestorDefs): MultiFn6; +export function defmulti(f: DispatchFn5O, rels?: AncestorDefs): MultiFn5O; export function defmulti(f: DispatchFn7, rels?: AncestorDefs): MultiFn7; +export function defmulti(f: DispatchFn6O, rels?: AncestorDefs): MultiFn6O; export function defmulti(f: DispatchFn8, rels?: AncestorDefs): MultiFn8; +export function defmulti(f: DispatchFn7O, rels?: AncestorDefs): MultiFn7O; +export function defmulti(f: DispatchFn8O, rels?: AncestorDefs): MultiFn8O; export function defmulti(f: any, ancestors?: AncestorDefs): MultiFn { const impls: IObjectOf> = {}; const rels: IObjectOf> = ancestors ? makeRels(ancestors) : {}; @@ -170,18 +237,34 @@ export function defmulti(f: any, ancestors?: AncestorDefs): MultiFn { delete impls[id]; return true; }; + fn.callable = (...args: any[]) => { + const id = f(...args); + return !!(impls[id] || findImpl(impls, rels, id) || impls[DEFAULT]); + }; fn.isa = (id: PropertyKey, parent: PropertyKey) => { let val = rels[id]; !val && (rels[id] = val = new Set()); val.add(parent); }; + fn.impls = () => { + const res = new Set(Object.keys(impls)); + for (let id in rels) { + findImpl(impls, rels, id) && res.add(id); + } + impls[DEFAULT] && res.add(DEFAULT); + return res; + }; fn.rels = () => rels; fn.parents = (id: PropertyKey) => rels[id]; fn.ancestors = (id: PropertyKey) => new Set(findAncestors([], rels, id)); return fn; }; -const findImpl = (impls: IObjectOf>, rels: IObjectOf>, id: PropertyKey) => { +const findImpl = ( + impls: IObjectOf>, + rels: IObjectOf>, + id: PropertyKey +) => { const parents = rels[id]; if (!parents) return; for (let p of parents) { @@ -190,7 +273,11 @@ const findImpl = (impls: IObjectOf>, rels: IObjectOf>, id: PropertyKey) => { +const findAncestors = ( + acc: PropertyKey[], + rels: IObjectOf>, + id: PropertyKey +) => { const parents = rels[id]; if (parents) { for (let p of parents) { @@ -201,14 +288,15 @@ const findAncestors = (acc: PropertyKey[], rels: IObjectOf>, id return acc; }; -const makeRels = (spec: AncestorDefs) => { - const rels: IObjectOf> = {}; - for (let k in spec) { - const val = spec[k]; - rels[k] = val instanceof Set ? val : new Set(val); - } - return rels; -}; +const makeRels = + (spec: AncestorDefs) => { + const rels: IObjectOf> = {}; + for (let k in spec) { + const val = spec[k]; + rels[k] = val instanceof Set ? val : new Set(val); + } + return rels; + }; /** * Returns a multi-dispatch function which delegates to one of the @@ -257,3 +345,75 @@ export const defmultiN = ( } return fn; }; + +/** + * Syntax-sugar intended for sets of multi-methods sharing same dispatch + * values / logic. Takes a dispatch value, an object of "is-a" + * relationships and a number of multi-methods, each with an + * implementation for the given dispatch value. + * + * The relations object has dispatch values (parents) as keys and arrays + * of multi-methods as their values. For each multi-method associates + * the given `type` with the related parent dispatch value to delegate + * to its implementation. + * + * The remaining implementations are associated with their related + * multi-method and the given `type` dispatch value. + * + * ``` + * foo = defmulti((x) => x.id); + * bar = defmulti((x) => x.id); + * bax = defmulti((x) => x.id); + * baz = defmulti((x) => x.id); + * + * // define impls for dispatch value `a` + * implementations( + * "a", + * + * // delegate bax & baz impls to dispatch val `b` + * { + * b: [bax, baz] + * }, + * + * // concrete multi-fn impls + * foo, + * (x) => `foo: ${x.val}`, + * + * bar, + * (x) => `bar: ${x.val.toUpperCase()}` + * ); + * + * // add parent impls + * bax.add("b", (x) => `bax: ${x.id}`); + * baz.add("c", (x) => `baz: ${x.id}`); + * // use "c" impl for "b" + * baz.isa("b", "c"); + * + * foo({ id: "a", val: "alice" }); // "foo: alice" + * bar({ id: "a", val: "alice" }); // "bar: ALICE" + * bax({ id: "a", val: "alice" }); // "bax: a" + * baz({ id: "a", val: "alice" }); // "baz: a" + * + * baz.impls(); // Set { "c", "a", "b" } + * ``` + * + * @param type + * @param impls + */ +export const implementations = ( + type: PropertyKey, + rels: IObjectOf[]>, + ...impls: (MultiFn | Implementation)[] +) => { + (impls.length & 1) && illegalArgs("expected an even number of implementation items"); + if (rels) { + for (let parent in rels) { + for (let fn of rels[parent]) { + fn.isa(type, parent); + } + } + } + for (let i = 0; i < impls.length; i += 2) { + (>impls[i]).add(type, impls[i + 1]); + } +}; diff --git a/packages/defmulti/test/index.ts b/packages/defmulti/test/index.ts index 41e17b28ef..9656a9e5df 100644 --- a/packages/defmulti/test/index.ts +++ b/packages/defmulti/test/index.ts @@ -1,5 +1,5 @@ import * as assert from "assert"; -import { DEFAULT, defmulti, defmultiN } from "../src/index"; +import { DEFAULT, defmulti, defmultiN, implementations } from "../src/index"; describe("defmulti", () => { it("flatten", () => { @@ -81,9 +81,13 @@ describe("defmulti", () => { }, "foo rels"); assert.equal(foo(23), "odd"); assert.equal(foo(42), "number"); + assert(foo.callable(23)); + assert(foo.callable(42)); + assert(!foo.callable(66)); assert.throws(() => foo(66), "no default"); foo.add(DEFAULT, (x) => -x); assert.equal(foo(66), -66); + assert.deepEqual(foo.impls(), new Set([DEFAULT, "odd", "even", "number", "23", "42"])); const bar = defmulti((x) => x, { 23: ["odd"], @@ -98,4 +102,19 @@ describe("defmulti", () => { "even": new Set(["number"]), }, "bar rels"); }); + + it("implementations", () => { + const foo = defmulti((x) => x.id); + const bar = defmulti((x) => x.id); + + implementations( + "a", + {}, + foo, (x) => `foo: ${x.val}`, + bar, (x) => `bar: ${x.val.toUpperCase()}` + ) + + assert.equal(foo({ id: "a", val: "alice" }), "foo: alice"); + assert.equal(bar({ id: "a", val: "alice" }), "bar: ALICE"); + }); }); From c8d8a37e446e07da7bf2e3552a27b1132159c269 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 15 Jan 2019 12:16:44 +0000 Subject: [PATCH 271/333] refactor(malloc): add/extract types to api.ts (cherry picked from commit e3727ce937824b1ed889fac6d66e488d4684a53e) --- packages/malloc/src/api.ts | 51 ++++++++++++++++++++++++++++++++++++ packages/malloc/src/index.ts | 44 ++++++++++--------------------- 2 files changed, 65 insertions(+), 30 deletions(-) create mode 100644 packages/malloc/src/api.ts diff --git a/packages/malloc/src/api.ts b/packages/malloc/src/api.ts new file mode 100644 index 0000000000..2ecfd0692f --- /dev/null +++ b/packages/malloc/src/api.ts @@ -0,0 +1,51 @@ +import { IRelease, TypedArray } from "@thi.ng/api/api"; + +export const enum Type { + U8, + U8C, + I8, + U16, + I16, + U32, + I32, + F32, + F64 +}; + +export interface MemBlock { + addr: number; + size: number; + next: MemBlock; +} + +export interface MemPoolOpts { + start: number; + end: number; + compact: boolean; + split: boolean; + minSplit: number; +} + +export interface MemPoolStats { + free: { count: number, size: number }; + used: { count: number, size: number }; + top: number; + available: number; + total: number; +} + +export interface IMemPool extends IRelease { + malloc(size: number): number; + + calloc(size: number): number; + + mallocAs(type: Type, num: number): TypedArray; + + callocAs(type: Type, num: number): TypedArray; + + free(ptr: number | TypedArray): boolean; + + freeAll(); + + stats(): MemPoolStats; +} diff --git a/packages/malloc/src/index.ts b/packages/malloc/src/index.ts index 067f6e8cf3..b31143079b 100644 --- a/packages/malloc/src/index.ts +++ b/packages/malloc/src/index.ts @@ -1,19 +1,16 @@ -import { IObjectOf, IRelease, TypedArray } from "@thi.ng/api"; -import { align } from "@thi.ng/binary"; -import { isNumber } from "@thi.ng/checks"; -import { illegalArgs } from "@thi.ng/errors"; +import { IObjectOf, TypedArray } from "@thi.ng/api"; +import { align } from "@thi.ng/binary/align"; +import { isNumber } from "@thi.ng/checks/is-number"; +import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; +import { + IMemPool, + MemBlock, + MemPoolOpts, + Type, + MemPoolStats +} from "./api"; -export const enum Type { - U8, - U8C, - I8, - U16, - I16, - U32, - I32, - F32, - F64 -}; +export * from "./api"; type BlockCtor = (buf: ArrayBuffer, addr: number, num: number) => TypedArray; @@ -41,21 +38,8 @@ const SIZEOF = { [Type.F64]: 8, }; -export interface MemBlock { - addr: number; - size: number; - next: MemBlock; -} - -export interface MemPoolOpts { - start: number; - end: number; - compact: boolean; - split: boolean; - minSplit: number; -} export class MemPool implements - IRelease { + IMemPool { buf: ArrayBuffer; protected top: number; @@ -89,7 +73,7 @@ export class MemPool implements this._used = null; } - stats() { + stats(): MemPoolStats { const listStats = (block: MemBlock) => { let count = 0; let size = 0; From 1cfefdabe078b1683fba40be17bb3649f0ecb14b Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 15 Jan 2019 12:19:28 +0000 Subject: [PATCH 272/333] refactor(malloc): update imports (cherry picked from commit f3a5e0ffbd03390d93b6db9bea68e4947cfff7f3) --- packages/malloc/src/api.ts | 32 ++++- packages/malloc/src/index.ts | 272 +---------------------------------- packages/malloc/src/pool.ts | 246 +++++++++++++++++++++++++++++++ packages/malloc/src/wrap.ts | 18 +++ 4 files changed, 297 insertions(+), 271 deletions(-) create mode 100644 packages/malloc/src/pool.ts create mode 100644 packages/malloc/src/wrap.ts diff --git a/packages/malloc/src/api.ts b/packages/malloc/src/api.ts index 2ecfd0692f..261372617d 100644 --- a/packages/malloc/src/api.ts +++ b/packages/malloc/src/api.ts @@ -1,4 +1,4 @@ -import { IRelease, TypedArray } from "@thi.ng/api/api"; +import { IRelease, TypedArray } from "@thi.ng/api"; export const enum Type { U8, @@ -12,6 +12,18 @@ export const enum Type { F64 }; +export const SIZEOF = { + [Type.U8]: 1, + [Type.U8C]: 1, + [Type.I8]: 1, + [Type.U16]: 2, + [Type.I16]: 2, + [Type.U32]: 4, + [Type.I32]: 4, + [Type.F32]: 4, + [Type.F64]: 8, +}; + export interface MemBlock { addr: number; size: number; @@ -27,10 +39,25 @@ export interface MemPoolOpts { } export interface MemPoolStats { + /** + * Free block stats. + */ free: { count: number, size: number }; + /** + * Used block stats. + */ used: { count: number, size: number }; + /** + * Current top address. + */ top: number; + /** + * Bytes available + */ available: number; + /** + * Total pool size. + */ total: number; } @@ -49,3 +76,6 @@ export interface IMemPool extends IRelease { stats(): MemPoolStats; } + +export type BlockCtor = + (buf: ArrayBuffer, addr: number, num: number) => TypedArray; diff --git a/packages/malloc/src/index.ts b/packages/malloc/src/index.ts index b31143079b..3d894796d0 100644 --- a/packages/malloc/src/index.ts +++ b/packages/malloc/src/index.ts @@ -1,271 +1,3 @@ -import { IObjectOf, TypedArray } from "@thi.ng/api"; -import { align } from "@thi.ng/binary/align"; -import { isNumber } from "@thi.ng/checks/is-number"; -import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; -import { - IMemPool, - MemBlock, - MemPoolOpts, - Type, - MemPoolStats -} from "./api"; - export * from "./api"; - -type BlockCtor = (buf: ArrayBuffer, addr: number, num: number) => TypedArray; - -const CTORS: IObjectOf = { - [Type.U8]: (buf, addr, num) => new Uint8Array(buf, addr, num), - [Type.U8C]: (buf, addr, num) => new Uint8ClampedArray(buf, addr, num), - [Type.I8]: (buf, addr, num) => new Int8Array(buf, addr, num), - [Type.U16]: (buf, addr, num) => new Uint16Array(buf, addr, num), - [Type.I16]: (buf, addr, num) => new Int16Array(buf, addr, num), - [Type.U32]: (buf, addr, num) => new Uint32Array(buf, addr, num), - [Type.I32]: (buf, addr, num) => new Int32Array(buf, addr, num), - [Type.F32]: (buf, addr, num) => new Float32Array(buf, addr, num), - [Type.F64]: (buf, addr, num) => new Float64Array(buf, addr, num), -}; - -const SIZEOF = { - [Type.U8]: 1, - [Type.U8C]: 1, - [Type.I8]: 1, - [Type.U16]: 2, - [Type.I16]: 2, - [Type.U32]: 4, - [Type.I32]: 4, - [Type.F32]: 4, - [Type.F64]: 8, -}; - -export class MemPool implements - IMemPool { - - buf: ArrayBuffer; - protected top: number; - protected start: number; - protected end: number; - protected doCompact: boolean; - protected doSplit: boolean; - protected minSplit: number; - protected _free: MemBlock; - protected _used: MemBlock; - - protected u8: Uint8Array; - - constructor(buf: number | ArrayBuffer, opts: Partial = {}) { - this.buf = isNumber(buf) ? new ArrayBuffer(buf) : buf; - this.u8 = new Uint8Array(this.buf); - this.start = opts.start != null ? - align(Math.max(opts.start, 8), 8) : - 8; - this.end = opts.end != null ? - Math.min(opts.end, this.buf.byteLength) : - this.buf.byteLength; - if (this.start >= this.end) { - illegalArgs(`invalid address range (0x${this.start.toString(16)} - 0x${this.end.toString(16)})`); - } - this.top = this.start; - this.doCompact = opts.compact !== false; - this.doSplit = opts.split !== false; - this.minSplit = opts.minSplit || 16; - this._free = null; - this._used = null; - } - - stats(): MemPoolStats { - const listStats = (block: MemBlock) => { - let count = 0; - let size = 0; - while (block) { - count++; - size += block.size; - block = block.next; - } - return { count, size }; - }; - return { - free: listStats(this._free), - used: listStats(this._used), - top: this.top, - available: this.end - this.top, - total: this.buf.byteLength - }; - } - - callocAs(type: Type, num: number): TypedArray { - const block = this.mallocAs(type, num); - block && block.fill(0); - return block; - } - - mallocAs(type: Type, num: number): TypedArray { - const addr = this.malloc(num * SIZEOF[type]); - return addr ? - CTORS[type](this.buf, addr, num) : - null; - } - - calloc(size: number): number { - const addr = this.malloc(size); - addr && this.u8.fill(0, addr, align(addr + size, 8)); - return addr; - } - - malloc(size: number): number { - if (size <= 0) { - return 0; - } - size = align(size, 8); - let top = this.top; - const end = this.end; - let block = this._free; - let prev = null; - while (block) { - const isTop = block.addr + block.size >= top; - if (isTop || block.size >= size) { - if (isTop && this.doCompact && block.addr + size > end) { - return 0; - } - if (prev) { - prev.next = block.next; - } else { - this._free = block.next; - } - block.next = this._used; - this._used = block; - if (isTop) { - block.size = size; - this.top = block.addr + size; - } else if (this.doSplit) { - const excess = block.size - size; - if (excess >= this.minSplit) { - block.size = size; - this.insert({ - addr: block.addr + size, - size: excess, - next: null - }); - this.doCompact && this.compact(); - } - } - return block.addr; - } - prev = block; - block = block.next; - } - const addr = align(top, 8); - top = addr + size; - if (top <= end) { - block = { - addr, - size, - next: this._used - }; - this._used = block; - this.top = top; - return addr; - } - return 0; - } - - free(ptr: number | TypedArray) { - let addr: number; - if (!isNumber(ptr)) { - if (ptr.buffer !== this.buf) { - return false; - } - addr = ptr.byteOffset; - } else { - addr = ptr; - } - let block = this._used; - let prev: MemBlock = null; - while (block) { - if (block.addr === addr) { - if (prev) { - prev.next = block.next; - } else { - this._used = block.next; - } - this.insert(block); - this.doCompact && this.compact(); - return true; - } - prev = block; - block = block.next; - } - return false; - } - - freeAll() { - this._free = null; - this._used = null; - this.top = this.start; - } - - release() { - delete this._free; - delete this._used; - delete this.u8; - delete this.buf; - delete this.top; - delete this.start; - delete this.end; - return true; - } - - protected compact() { - let block = this._free; - let prev: MemBlock; - let scan: MemBlock; - let res = false; - while (block) { - prev = block; - scan = block.next; - while (scan && prev.addr + prev.size === scan.addr) { - // console.log("merge:", scan.addr, scan.size); - prev = scan; - scan = scan.next; - } - if (prev !== block) { - const newSize = prev.addr - block.addr + prev.size; - // console.log("merged size:", newSize); - block.size = newSize; - const next = prev.next; - let tmp = block.next; - while (tmp !== prev.next) { - // console.log("release:", tmp.addr); - const tn = tmp.next; - tmp.next = null; - tmp = tn; - } - block.next = next; - res = true; - } - block = block.next; - } - return res; - } - - protected insert(block: MemBlock) { - let ptr = this._free; - if (!this.doCompact) { - block.next = ptr; - this._free = block; - return; - } - let prev: MemBlock = null; - while (ptr) { - if (block.addr <= ptr.addr) break; - prev = ptr; - ptr = ptr.next; - } - if (prev) { - prev.next = block; - } else { - this._free = block; - } - block.next = ptr; - } -} +export * from "./pool"; +export * from "./wrap"; diff --git a/packages/malloc/src/pool.ts b/packages/malloc/src/pool.ts new file mode 100644 index 0000000000..14b866c33b --- /dev/null +++ b/packages/malloc/src/pool.ts @@ -0,0 +1,246 @@ +import { TypedArray } from "@thi.ng/api"; +import { align } from "@thi.ng/binary"; +import { isNumber } from "@thi.ng/checks"; +import { illegalArgs } from "@thi.ng/errors"; +import { + IMemPool, + MemBlock, + MemPoolOpts, + MemPoolStats, + SIZEOF, + Type, +} from "./api"; +import { wrap } from "./wrap"; + +export class MemPool implements + IMemPool { + + buf: ArrayBuffer; + protected top: number; + protected start: number; + protected end: number; + protected doCompact: boolean; + protected doSplit: boolean; + protected minSplit: number; + protected _free: MemBlock; + protected _used: MemBlock; + + protected u8: Uint8Array; + + constructor(buf: number | ArrayBuffer, opts: Partial = {}) { + this.buf = isNumber(buf) ? new ArrayBuffer(buf) : buf; + this.u8 = new Uint8Array(this.buf); + this.start = opts.start != null ? + align(Math.max(opts.start, 8), 8) : + 8; + this.end = opts.end != null ? + Math.min(opts.end, this.buf.byteLength) : + this.buf.byteLength; + if (this.start >= this.end) { + illegalArgs(`invalid address range (0x${this.start.toString(16)} - 0x${this.end.toString(16)})`); + } + this.top = this.start; + this.doCompact = opts.compact !== false; + this.doSplit = opts.split !== false; + this.minSplit = opts.minSplit || 16; + this._free = null; + this._used = null; + } + + stats(): MemPoolStats { + const listStats = (block: MemBlock) => { + let count = 0; + let size = 0; + while (block) { + count++; + size += block.size; + block = block.next; + } + return { count, size }; + }; + const free = listStats(this._free); + return { + free, + used: listStats(this._used), + top: this.top, + available: this.end - this.top + free.size, + total: this.buf.byteLength + }; + } + + callocAs(type: Type, num: number): TypedArray { + const block = this.mallocAs(type, num); + block && block.fill(0); + return block; + } + + mallocAs(type: Type, num: number): TypedArray { + const addr = this.malloc(num * SIZEOF[type]); + return addr ? + wrap(type, this.buf, addr, num) : + null; + } + + calloc(size: number): number { + const addr = this.malloc(size); + addr && this.u8.fill(0, addr, align(addr + size, 8)); + return addr; + } + + malloc(size: number): number { + if (size <= 0) { + return 0; + } + size = align(size, 8); + let top = this.top; + const end = this.end; + let block = this._free; + let prev = null; + while (block) { + const isTop = block.addr + block.size >= top; + if (isTop || block.size >= size) { + if (isTop && this.doCompact && block.addr + size > end) { + return 0; + } + if (prev) { + prev.next = block.next; + } else { + this._free = block.next; + } + block.next = this._used; + this._used = block; + if (isTop) { + block.size = size; + this.top = block.addr + size; + } else if (this.doSplit) { + const excess = block.size - size; + if (excess >= this.minSplit) { + block.size = size; + this.insert({ + addr: block.addr + size, + size: excess, + next: null + }); + this.doCompact && this.compact(); + } + } + return block.addr; + } + prev = block; + block = block.next; + } + const addr = align(top, 8); + top = addr + size; + if (top <= end) { + block = { + addr, + size, + next: this._used + }; + this._used = block; + this.top = top; + return addr; + } + return 0; + } + + free(ptr: number | TypedArray) { + let addr: number; + if (!isNumber(ptr)) { + if (ptr.buffer !== this.buf) { + return false; + } + addr = ptr.byteOffset; + } else { + addr = ptr; + } + let block = this._used; + let prev: MemBlock = null; + while (block) { + if (block.addr === addr) { + if (prev) { + prev.next = block.next; + } else { + this._used = block.next; + } + this.insert(block); + this.doCompact && this.compact(); + return true; + } + prev = block; + block = block.next; + } + return false; + } + + freeAll() { + this._free = null; + this._used = null; + this.top = this.start; + } + + release() { + delete this._free; + delete this._used; + delete this.u8; + delete this.buf; + delete this.top; + delete this.start; + delete this.end; + return true; + } + + protected compact() { + let block = this._free; + let prev: MemBlock; + let scan: MemBlock; + let res = false; + while (block) { + prev = block; + scan = block.next; + while (scan && prev.addr + prev.size === scan.addr) { + // console.log("merge:", scan.addr, scan.size); + prev = scan; + scan = scan.next; + } + if (prev !== block) { + const newSize = prev.addr - block.addr + prev.size; + // console.log("merged size:", newSize); + block.size = newSize; + const next = prev.next; + let tmp = block.next; + while (tmp !== prev.next) { + // console.log("release:", tmp.addr); + const tn = tmp.next; + tmp.next = null; + tmp = tn; + } + block.next = next; + res = true; + } + block = block.next; + } + return res; + } + + protected insert(block: MemBlock) { + let ptr = this._free; + if (!this.doCompact) { + block.next = ptr; + this._free = block; + return; + } + let prev: MemBlock = null; + while (ptr) { + if (block.addr <= ptr.addr) break; + prev = ptr; + ptr = ptr.next; + } + if (prev) { + prev.next = block; + } else { + this._free = block; + } + block.next = ptr; + } +} diff --git a/packages/malloc/src/wrap.ts b/packages/malloc/src/wrap.ts new file mode 100644 index 0000000000..d88b95fff6 --- /dev/null +++ b/packages/malloc/src/wrap.ts @@ -0,0 +1,18 @@ +import { IObjectOf } from "@thi.ng/api"; +import { BlockCtor, Type } from "./api"; + +const CTORS: IObjectOf = { + [Type.U8]: (buf, addr, num) => new Uint8Array(buf, addr, num), + [Type.U8C]: (buf, addr, num) => new Uint8ClampedArray(buf, addr, num), + [Type.I8]: (buf, addr, num) => new Int8Array(buf, addr, num), + [Type.U16]: (buf, addr, num) => new Uint16Array(buf, addr, num), + [Type.I16]: (buf, addr, num) => new Int16Array(buf, addr, num), + [Type.U32]: (buf, addr, num) => new Uint32Array(buf, addr, num), + [Type.I32]: (buf, addr, num) => new Int32Array(buf, addr, num), + [Type.F32]: (buf, addr, num) => new Float32Array(buf, addr, num), + [Type.F64]: (buf, addr, num) => new Float64Array(buf, addr, num), +}; + +export const wrap = + (type: Type, buf: ArrayBuffer, addr: number, num: number) => + CTORS[type](buf, addr, num); \ No newline at end of file From a75f192057f1d81c02254101da74ae237ee91a97 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 15 Jan 2019 13:02:43 +0000 Subject: [PATCH 273/333] docs: update/fix various readmes --- packages/bitstream/README.md | 6 +++--- packages/checks/README.md | 2 +- packages/dot/README.md | 4 ++-- packages/dsp/README.md | 2 +- packages/fsm/README.md | 32 ++++++++++++++++++++++++++------ packages/hdom/README.md | 14 +++++++------- packages/iterators/README.md | 2 +- packages/random/README.md | 4 ++-- packages/router/README.md | 6 +++--- packages/strings/README.md | 5 +++-- packages/transducers/README.md | 11 +---------- 11 files changed, 50 insertions(+), 38 deletions(-) diff --git a/packages/bitstream/README.md b/packages/bitstream/README.md index cbe4f7ed85..e9bed5d37a 100644 --- a/packages/bitstream/README.md +++ b/packages/bitstream/README.md @@ -25,7 +25,7 @@ yarn add @thi.ng/bitstream ## API ```ts -import * as bits from "@thi.ng/bitstream"; +import { BitInputStream, BitOutputStream } from "@thi.ng/bitstream"; ``` ### BitOutputStream @@ -47,7 +47,7 @@ but JS can only represent integers (w/o loss of precision) up to technically the max. supported word width is 64 bits. ```ts -out = new bits.BitOutputStream(); +out = new BitOutputStream(); // write 3-bit number (only the lowest 3 bits are used, here 0x05) out.write(0xf5, 3); // write 7-bit number @@ -109,7 +109,7 @@ out.reader().seek(10).readWords(4, 16).map(x=>x.toString(16)); src = new Uint8Array([0xf1,0xe2,0xd3,0xc4,0xb5,0xa6,0x97,0x88]); // create stream from bit 36 -input = new bits.BitInputStream(src, 36); +input = new BitInputStream(src, 36); input.read(12).toString(16); // 5a6 input.read(4) diff --git a/packages/checks/README.md b/packages/checks/README.md index 14ec1889da..32b333be31 100644 --- a/packages/checks/README.md +++ b/packages/checks/README.md @@ -29,7 +29,7 @@ None import * as checks from "@thi.ng/checks"; // individual import -import { isFunction } from "@thi.ng/checks/is-function"; +import { isFunction } from "@thi.ng/checks"; ``` ## Authors diff --git a/packages/dot/README.md b/packages/dot/README.md index 6da2d1195a..23fdb3f747 100644 --- a/packages/dot/README.md +++ b/packages/dot/README.md @@ -40,7 +40,7 @@ The source code of this example is also available in [/test/example.ts](https://github.com/thi-ng/umbrella/tree/master/packages/dot/test/example.ts). ```ts -import * as dot from "@thi.ng/dot"; +import { serializeGraph } from "@thi.ng/dot"; // node type style presets const terminal = { @@ -57,7 +57,7 @@ const operator = { outs: { "out": "out" } }; -dot.serializeGraph({ +serializeGraph({ directed: true, // default // graph attributes attribs: { diff --git a/packages/dsp/README.md b/packages/dsp/README.md index efb553fcda..020e7bc419 100644 --- a/packages/dsp/README.md +++ b/packages/dsp/README.md @@ -47,7 +47,7 @@ yarn add @thi.ng/dsp import * as dsp from "@thi.ng/dsp"; import { take } from "@thi.ng/transducers"; -[...take(20, new dsp.Oscillator(dsp.mix(dsp.sin,dsp.rect), 1/20)] +[...take(20, new dsp.Oscillator(dsp.mix(dsp.sin, dsp.rect), 1/20)] // [ 0.5, // 0.6545084971874737, // 0.7938926261462366, diff --git a/packages/fsm/README.md b/packages/fsm/README.md index db34868138..4f347df284 100644 --- a/packages/fsm/README.md +++ b/packages/fsm/README.md @@ -54,6 +54,14 @@ yarn add @thi.ng/fsm ## Usage examples +Checkout the minimal Markdown parser example: + +[Source code](https://github.com/thi-ng/umbrella/tree/master/examples/markdown) | +[Live demo](https://demo.thi.ng/umbrella/markdown/) + +The parser itself is defined here: +[@thi.ng/hiccup-markdown](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup-markdown/src/parse.ts) + ```ts import * as fsm from "@thi.ng/fsm"; ``` @@ -70,12 +78,26 @@ also support optional user callbacks, which are executed when a match was made and are responsible for state transitions, state update and production of any result values. +- [`alts()`](https://github.com/thi-ng/umbrella/tree/master/packages/fsm/src/alts.ts) +- [`always()`](https://github.com/thi-ng/umbrella/tree/master/packages/fsm/src/always.ts) +- [`lit()`](https://github.com/thi-ng/umbrella/tree/master/packages/fsm/src/lit.ts) +- [`never()`](https://github.com/thi-ng/umbrella/tree/master/packages/fsm/src/never.ts) +- [`not()`](https://github.com/thi-ng/umbrella/tree/master/packages/fsm/src/not.ts) +- [`repeat()`](https://github.com/thi-ng/umbrella/tree/master/packages/fsm/src/repeat.ts) +- [`seq()`](https://github.com/thi-ng/umbrella/tree/master/packages/fsm/src/seq.ts) +- [`str()`](https://github.com/thi-ng/umbrella/tree/master/packages/fsm/src/str.ts) +- [`until()`](https://github.com/thi-ng/umbrella/tree/master/packages/fsm/src/until.ts) + +See docs strings in `/src` folder for now. + ### FSM transducer -The `fsm()` function returns a Finite-state machine transducer w/ -support for single lookahead value. It takes an object of `states` and -their matchers, an arbitrary context object which will be uses as state -container for the various matchers and an `initial` state ID. +The +[`fsm()`](https://github.com/thi-ng/umbrella/tree/master/packages/fsm/src/fsm.ts) +function is a Finite-state machine transducer w/ support for single +lookahead value. It takes an object of `states` and their matchers, an +arbitrary context object which will be uses as state container for the +various matchers and an `initial` state ID. The returned transducer consumes inputs of type `T` and produces results of type `R`. The results are produced by callbacks of the given state @@ -83,8 +105,6 @@ matchers. For each input consumed, the callbacks can produce any number of result values. If a callback returns a result wrapped w/ `reduced()`, the FSM causes early termination of the overall transducer pipeline. -See docs strings in `/src` folder for now. - ## Authors - Karsten Schmidt diff --git a/packages/hdom/README.md b/packages/hdom/README.md index c5f73505c9..5b1e185052 100644 --- a/packages/hdom/README.md +++ b/packages/hdom/README.md @@ -100,7 +100,7 @@ Benefits: [standalone example](https://github.com/thi-ng/umbrella/tree/master/examples/hdom-basics) ```ts -import * as hdom from "@thi.ng/hdom"; +import { start, renderOnce } from "@thi.ng/hdom"; // stateless component w/ params // the first arg is an auto-injected context object @@ -120,10 +120,10 @@ const app = () => { }; // start RAF update & diff loop -hdom.start(app(), { root: document.body }); +start(app(), { root: document.body }); // alternatively create DOM tree only once -hdom.renderOnce(app(), { root: document.body }); +renderOnce(app(), { root: document.body }); ``` Alternatively, use the same component for browser or server side HTML @@ -151,8 +151,8 @@ diffing via RAF). ```ts import { fromInterval, stream, sync } from "@thi.ng/rstream"; -import { updateDOM } from "@thi.ng/rstream/transducers-hdom"; -import * as tx from "@thi.ng/rstream/transducers"; +import { updateDOM } from "@thi.ng/transducers-hdom"; +import { map, scan } from "@thi.ng/transducers"; // root component function const app = ({ ticks, clicks }) => @@ -164,7 +164,7 @@ const app = ({ ticks, clicks }) => ]; // transformed stream to count clicks -const clickStream = stream().transform(tx.scan(tx.count(-1))); +const clickStream = stream().transform(scan(tx.count(-1))); // seed clickStream.next(0); @@ -179,7 +179,7 @@ sync({ }, }).transform( // transform tuple into hdom component - tx.map(app), + map(app), // apply hdom tree to real DOM updateDOM({ root: document.body }) ); diff --git a/packages/iterators/README.md b/packages/iterators/README.md index c027d8c14a..dc2896e8e5 100644 --- a/packages/iterators/README.md +++ b/packages/iterators/README.md @@ -29,7 +29,7 @@ case*, whereas function names are in *Camel case*. // import all import * as ti from "@thi.ng/iterators"; // single function (ES6 / TS) -import { partitionBy } from "@thi.ng/iterators/partition-by"; +import { partitionBy } from "@thi.ng/iterators"; ``` ## Dependencies diff --git a/packages/random/README.md b/packages/random/README.md index 66e404c459..866ea00c82 100644 --- a/packages/random/README.md +++ b/packages/random/README.md @@ -43,9 +43,9 @@ yarn add @thi.ng/random ## Usage examples ```ts -import * as r from "@thi.ng/random"; +import { Smush32 } from "@thi.ng/random"; -const rnd = new r.Smush32(0xdecafbad); +const rnd = new Smush32(0xdecafbad); // the following methods are available for all generators diff --git a/packages/router/README.md b/packages/router/README.md index 7b35f79fe6..9827a64cd7 100644 --- a/packages/router/README.md +++ b/packages/router/README.md @@ -56,7 +56,7 @@ A complete, full commented demo app is here: [Live demo](https://demo.thi.ng/umbrella/router-basics/) ```ts -import * as r from "@thi.ng/router"; +import { HTMLRouter, EV_ROUTE_CHANGED } from "@thi.ng/router"; // router configuration const config = { @@ -139,8 +139,8 @@ const config = { // `HTMLRouter` ONLY works in browser environments // for non-browser use cases use `BasicRouter` -const router = new r.HTMLRouter(config); -router.addListener(r.EV_ROUTE_CHANGED, console.log); +const router = new HTMLRouter(config); +router.addListener(EV_ROUTE_CHANGED, console.log); router.start(); ``` diff --git a/packages/strings/README.md b/packages/strings/README.md index bf6def08b2..3cfbd5a5e7 100644 --- a/packages/strings/README.md +++ b/packages/strings/README.md @@ -20,8 +20,9 @@ This project is part of the ## About -Various higher-order, but low-level string formatting & utility -functions, some memoized. WIP / Alpha. Please sources for now. +Various higher-order, configurable string formatting & utility +functions, some memoized. WIP / Alpha. Please sources / docstrings for +now. ## Installation diff --git a/packages/transducers/README.md b/packages/transducers/README.md index 98958bbda3..87a4da4462 100644 --- a/packages/transducers/README.md +++ b/packages/transducers/README.md @@ -110,16 +110,7 @@ purposes full module re-exports are defined. import * as tx from "@thi.ng/transducers"; // selective / single function imports -import { transduce } from "@thi.ng/transducers/transduce"; - -// all transducers are under the /xform import path -import { map } from "@thi.ng/transducers/xform/map"; - -// all reducers are under the /rfn import path -import { push } from "@thi.ng/transducers/rfn/push"; - -// all iterators are under the /iter import path -import { range } from "@thi.ng/transducers/iter/range"; +import { transduce } from "@thi.ng/transducers"; ``` ### Basic usage patterns From 66e45ccdfb9cca9ad84f088f48d1b8aba2059616 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 15 Jan 2019 15:07:49 +0000 Subject: [PATCH 274/333] build: update .npmignore files --- packages/color/.npmignore | 10 ++++++---- packages/geom2/.npmignore | 10 ++++++---- packages/geom3/.npmignore | 3 ++- packages/matrices/.npmignore | 10 ++++++---- packages/vector-pools/.npmignore | 10 ++++++---- packages/vectors3/.npmignore | 10 ++++++---- 6 files changed, 32 insertions(+), 21 deletions(-) diff --git a/packages/color/.npmignore b/packages/color/.npmignore index ec83d74c9d..67d0c55714 100644 --- a/packages/color/.npmignore +++ b/packages/color/.npmignore @@ -1,11 +1,13 @@ +.cache +.meta +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc -export src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/geom2/.npmignore b/packages/geom2/.npmignore index ec83d74c9d..67d0c55714 100644 --- a/packages/geom2/.npmignore +++ b/packages/geom2/.npmignore @@ -1,11 +1,13 @@ +.cache +.meta +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc -export src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/geom3/.npmignore b/packages/geom3/.npmignore index 74ea62d1fa..67d0c55714 100644 --- a/packages/geom3/.npmignore +++ b/packages/geom3/.npmignore @@ -1,12 +1,13 @@ +.cache .meta .nyc_output +*.gz *.html *.tgz build coverage dev doc -export src* test tsconfig.json diff --git a/packages/matrices/.npmignore b/packages/matrices/.npmignore index ec83d74c9d..67d0c55714 100644 --- a/packages/matrices/.npmignore +++ b/packages/matrices/.npmignore @@ -1,11 +1,13 @@ +.cache +.meta +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc -export src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/vector-pools/.npmignore b/packages/vector-pools/.npmignore index ec83d74c9d..67d0c55714 100644 --- a/packages/vector-pools/.npmignore +++ b/packages/vector-pools/.npmignore @@ -1,11 +1,13 @@ +.cache +.meta +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc -export src* test -.nyc_output tsconfig.json -*.tgz -*.html diff --git a/packages/vectors3/.npmignore b/packages/vectors3/.npmignore index ec83d74c9d..67d0c55714 100644 --- a/packages/vectors3/.npmignore +++ b/packages/vectors3/.npmignore @@ -1,11 +1,13 @@ +.cache +.meta +.nyc_output +*.gz +*.html +*.tgz build coverage dev doc -export src* test -.nyc_output tsconfig.json -*.tgz -*.html From 446a183275445e29b73b83c633545ad532df3394 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 16 Jan 2019 02:12:17 +0000 Subject: [PATCH 275/333] fix(vectors): minor update opt arg in VecOp* --- packages/vectors3/src/api.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/vectors3/src/api.ts b/packages/vectors3/src/api.ts index 680362eb81..3f7f631d9a 100644 --- a/packages/vectors3/src/api.ts +++ b/packages/vectors3/src/api.ts @@ -58,11 +58,11 @@ export type VecOpVVVVNN = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: Readonly export type VecOpVO = (out: Vec, a: ReadonlyVec, b?: T) => Vec; export type VecOpOO = (out: Vec, a?: A, b?: B) => Vec; export type VecOpOOO = (out: Vec, a?: A, b?: B, c?: C) => Vec; -export type VecOpNNO = (out: Vec, a: number, b: number, c: T) => Vec; +export type VecOpNNO = (out: Vec, a: number, b: number, c?: T) => Vec; export type VecOpRoV = (a: ReadonlyVec) => T; export type VecOpRoVV = (a: ReadonlyVec, b: ReadonlyVec) => T; -export type VecOpRoVVO = (a: ReadonlyVec, b: ReadonlyVec, c: O) => T; +export type VecOpRoVVO = (a: ReadonlyVec, b: ReadonlyVec, c?: O) => T; export type VecOpSV = (out: Vec, a: ReadonlyVec, io?: number, ia?: number, so?: number, sa?: number) => Vec; export type VecOpSVV = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, io?: number, ia?: number, ib?: number, so?: number, sa?: number, sb?: number) => Vec; From 18437026afa739a2b8e1da8966e8229d08c637ae Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 16 Jan 2019 02:12:38 +0000 Subject: [PATCH 276/333] perf(vectors): update copy() --- packages/vectors3/src/copy.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/vectors3/src/copy.ts b/packages/vectors3/src/copy.ts index d03e0a7bbb..08a6ef21c2 100644 --- a/packages/vectors3/src/copy.ts +++ b/packages/vectors3/src/copy.ts @@ -1,8 +1,9 @@ import { implementsFunction } from "@thi.ng/checks"; import { ReadonlyVec, Vec } from "./api"; +import { set } from "./set"; export const copy = (v: ReadonlyVec): Vec => implementsFunction(v, "copy") ? (v).copy() : - [...v]; + set([], v); From fea8fbe3e8e551f8a2f857f01a212cb7599dc673 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 16 Jan 2019 02:14:35 +0000 Subject: [PATCH 277/333] feat(geom): re-add arc, cubic, quadratic ops, splitAt & other ops --- packages/geom3/src/api.ts | 109 +++++++++++++++-- packages/geom3/src/ctors/cubic.ts | 81 ++++++++++++- packages/geom3/src/index.ts | 2 + packages/geom3/src/internal/bounds.ts | 3 +- packages/geom3/src/internal/copy-points.ts | 4 +- packages/geom3/src/internal/sampler.ts | 24 +++- packages/geom3/src/internal/splines.ts | 128 ++++++++++++++++++++ packages/geom3/src/internal/split-line.ts | 8 ++ packages/geom3/src/internal/union-bounds.ts | 6 +- packages/geom3/src/ops/area.ts | 6 +- packages/geom3/src/ops/as-cubic.ts | 27 +++++ packages/geom3/src/ops/bounds.ts | 57 ++++++++- packages/geom3/src/ops/center.ts | 14 ++- packages/geom3/src/ops/centroid.ts | 1 + packages/geom3/src/ops/split-at.ts | 53 ++++++++ packages/geom3/src/ops/vertices.ts | 16 +-- 16 files changed, 497 insertions(+), 42 deletions(-) create mode 100644 packages/geom3/src/internal/splines.ts create mode 100644 packages/geom3/src/internal/split-line.ts create mode 100644 packages/geom3/src/ops/as-cubic.ts create mode 100644 packages/geom3/src/ops/split-at.ts diff --git a/packages/geom3/src/api.ts b/packages/geom3/src/api.ts index 7166fa2728..cf8bdd16a3 100644 --- a/packages/geom3/src/api.ts +++ b/packages/geom3/src/api.ts @@ -1,10 +1,14 @@ import { ICopy, IObjectOf, IToHiccup } from "@thi.ng/api"; import { isNumber } from "@thi.ng/checks"; import { equiv } from "@thi.ng/equiv"; +import { cossin } from "@thi.ng/math"; import { - copy, - maddN, + add2, + maddN2, + mul2, ReadonlyVec, + rotateZ, + set, Vec } from "@thi.ng/vectors3"; import { copyPoints } from "./internal/copy-points"; @@ -180,7 +184,94 @@ export class AABB implements } copy() { - return new AABB(copy(this.pos), copy(this.size), { ...this.attribs }); + return new AABB(set([], this.pos), set([], this.size), { ...this.attribs }); + } +} + +export class Arc implements + HiccupShape, + IHiccupPathSegment { + + pos: Vec; + r: Vec; + start: number; + end: number; + axis: number; + xl: boolean; + cw: boolean; + attribs: Attribs; + + constructor( + pos: Vec, + r: Vec, + axis: number, + start: number, + end: number, + xl = false, + cw = false, + attribs?: Attribs) { + + this.pos = pos; + this.r = r; + this.axis = axis; + this.start = start; + this.end = end; + this.xl = xl; + this.cw = cw; + this.attribs = attribs; + } + + get type() { + return Type.ARC; + } + + copy() { + return new Arc( + set([], this.pos), + set([], this.r), + this.axis, + this.start, + this.end, + this.xl, + this.cw, + { ...this.attribs } + ); + } + + equiv(o: any) { + return o instanceof Arc && + equiv(this.pos, o.pos) && + equiv(this.r, o.r) && + this.start === o.start && + this.end === o.end && + this.axis === o.axis && + this.xl === o.xl && + this.cw && o.cw; + } + + pointAtTheta(theta: number, out: Vec = []) { + return add2(null, rotateZ(null, mul2(out, cossin(theta), this.r), this.axis), this.pos); + } + + toHiccup() { + return ["path", this.attribs, [ + ["M", this.pointAtTheta(this.start)], + ...this.toHiccupPathSegments() + ]]; + } + + toHiccupPathSegments() { + return [ + [ + "A", + this.r[0], + this.r[1], + this.axis, + this.xl, + this.cw, + this.pointAtTheta(this.end) + ] + ]; } } @@ -202,7 +293,7 @@ export class Circle implements } copy() { - return new Circle(copy(this.pos), this.r, { ...this.attribs }); + return new Circle(set([], this.pos), this.r, { ...this.attribs }); } toHiccup() { @@ -254,7 +345,7 @@ export class Ellipse implements } copy() { - return new Ellipse(copy(this.pos), copy(this.r), { ...this.attribs }); + return new Ellipse(set([], this.pos), set([], this.r), { ...this.attribs }); } toHiccup() { @@ -417,11 +508,11 @@ export class Ray implements } copy() { - return new Ray(copy(this.pos), copy(this.dir), { ...this.attribs }); + return new Ray(set([], this.pos), set([], this.dir), { ...this.attribs }); } toHiccup() { - return ["line", this.attribs, this.pos, maddN([], this.pos, this.dir, 1e6)]; + return ["line", this.attribs, this.pos, maddN2([], this.pos, this.dir, 1e6)]; } } @@ -443,7 +534,7 @@ export class Rect implements } copy() { - return new Rect(copy(this.pos), copy(this.size), { ...this.attribs }); + return new Rect(set([], this.pos), set([], this.size), { ...this.attribs }); } toHiccup() { @@ -469,7 +560,7 @@ export class Sphere implements } copy() { - return new Sphere(copy(this.pos), this.r, { ...this.attribs }); + return new Sphere(set([], this.pos), this.r, { ...this.attribs }); } toHiccup() { diff --git a/packages/geom3/src/ctors/cubic.ts b/packages/geom3/src/ctors/cubic.ts index b601032d1b..53314eaba9 100644 --- a/packages/geom3/src/ctors/cubic.ts +++ b/packages/geom3/src/ctors/cubic.ts @@ -1,5 +1,17 @@ -import { mixN, Vec } from "@thi.ng/vectors3"; -import { Attribs, Cubic } from "../api"; +import { + EPS, + HALF_PI, + roundEps, + sincos +} from "@thi.ng/math"; +import { + add2, + magSq2, + mixN2, + set2, + Vec +} from "@thi.ng/vectors3"; +import { Arc, Attribs, Cubic } from "../api"; import { argAttribs } from "../internal/args"; export function cubic(a: Vec, b: Vec, c: Vec, d: Vec, attribs?: Attribs): Cubic; @@ -9,6 +21,69 @@ export function cubic(...args: any[]) { return new Cubic(args.length === 1 ? args[0] : args, attr); } +export const cubicFromArc = + (arc: Arc) => { + const p = arc.pointAtTheta(arc.start); + const q = arc.pointAtTheta(arc.end); + const [rx, ry] = arc.r; + const [sphi, cphi] = sincos(arc.axis); + const dx = cphi * (p[0] - q[0]) / 2 + sphi * (p[1] - q[1]) / 2; + const dy = -sphi * (p[0] - q[0]) / 2 + cphi * (p[1] - q[1]) / 2; + if ((dx === 0 && dy === 0) || magSq2(arc.r) < EPS) { + return [cubicFromLine(p, q, { ...arc.attribs })]; + } + + const mapP = (x: number, y: number) => { + x *= rx; + y *= ry; + return add2( + null, + [ + cphi * x - sphi * y, + sphi * x + cphi * y + ], + arc.pos + ); + }; + + const res: Cubic[] = []; + const delta = arc.end - arc.start; + const n = Math.max(roundEps(Math.abs(delta) / HALF_PI), 1); + // https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/svg/svg_path_parser.cc#L253 + const d = delta / n; + const t = 8 / 6 * Math.tan(0.25 * d); + if (!isFinite(t)) { + return [cubicFromLine(p, q, { ...arc.attribs })]; + } + for (let i = n, theta = arc.start; i > 0; i-- , theta += d) { + const [s1, c1] = sincos(theta); + const [s2, c2] = sincos(theta + d); + const curve = new Cubic( + [ + mapP(c1, s1), + mapP(c1 - s1 * t, s1 + c1 * t), + mapP(c2 + s2 * t, s2 - c2 * t), + mapP(c2, s2), + ], + { ...arc.attribs } + ); + res.push(curve); + } + return res; + }; + export const cubicFromLine = (a: Vec, b: Vec, attribs?: Attribs) => - new Cubic([a, mixN([], a, b, 1 / 3), mixN([], b, a, 1 / 3), b], attribs); + new Cubic([a, mixN2([], a, b, 1 / 3), mixN2([], b, a, 1 / 3), b], attribs); + +export const cubicFromQuadratic = + (a: Vec, b: Vec, c: Vec, attribs?: Attribs) => + new Cubic( + [ + set2([], a), + mixN2([], a, b, 2 / 3), + mixN2([], c, b, 2 / 3), + set2([], c) + ], + attribs + ); diff --git a/packages/geom3/src/index.ts b/packages/geom3/src/index.ts index 3d396f40e5..9f61a12b00 100644 --- a/packages/geom3/src/index.ts +++ b/packages/geom3/src/index.ts @@ -14,6 +14,7 @@ export * from "./ctors/triangle"; export * from "./ops/arc-length"; export * from "./ops/area"; +export * from "./ops/as-cubic"; export * from "./ops/as-polygon"; export * from "./ops/as-svg"; export * from "./ops/bounds"; @@ -28,6 +29,7 @@ export * from "./ops/point-at"; export * from "./ops/point-inside"; export * from "./ops/resample"; export * from "./ops/simplify"; +export * from "./ops/split-at"; export * from "./ops/subdiv-curve"; export * from "./ops/tangent-at"; export * from "./ops/transform"; diff --git a/packages/geom3/src/internal/bounds.ts b/packages/geom3/src/internal/bounds.ts index 7dcd3ddf64..b161def12c 100644 --- a/packages/geom3/src/internal/bounds.ts +++ b/packages/geom3/src/internal/bounds.ts @@ -1,4 +1,5 @@ import { max, min, Vec } from "@thi.ng/vectors3"; +import { VecPair } from "../api"; /** * Computes the nD bounds of given vectors. `vmin` should be initialized @@ -12,7 +13,7 @@ import { max, min, Vec } from "@thi.ng/vectors3"; * @param vmax */ export const boundsRaw = - (pts: ReadonlyArray, vmin: Vec, vmax: Vec): [Vec, Vec] => { + (pts: ReadonlyArray, vmin: Vec, vmax: Vec): VecPair => { for (let i = pts.length; --i >= 0;) { const p = pts[i]; diff --git a/packages/geom3/src/internal/copy-points.ts b/packages/geom3/src/internal/copy-points.ts index 4be333836f..6fab8e9922 100644 --- a/packages/geom3/src/internal/copy-points.ts +++ b/packages/geom3/src/internal/copy-points.ts @@ -1,4 +1,4 @@ -import { copy, ReadonlyVec } from "@thi.ng/vectors3"; +import { ReadonlyVec, set } from "@thi.ng/vectors3"; export const copyPoints = - (pts: ReadonlyVec[]) => pts.map((p) => copy(p)); + (pts: ReadonlyVec[]) => pts.map((p) => set([], p)); diff --git a/packages/geom3/src/internal/sampler.ts b/packages/geom3/src/internal/sampler.ts index 8c61f4e2bb..91be1b6fc8 100644 --- a/packages/geom3/src/internal/sampler.ts +++ b/packages/geom3/src/internal/sampler.ts @@ -1,13 +1,14 @@ import { isPlainObject } from "@thi.ng/checks"; import { peek } from "@thi.ng/transducers"; import { - copy, dist, mixN, normalize, ReadonlyVec, sub, - Vec + Vec, + eqDelta, + set } from "@thi.ng/vectors3"; import { DEFAULT_SAMPLES, SamplingOpts, VecPair } from "../api"; import { copyPoints } from "./copy-points"; @@ -83,6 +84,23 @@ export class Sampler { undefined; } + splitAt(t: number) { + if (t <= 0 || t >= 1) { + return [this.points]; + } + const p = this.pointAt(t); + const i = Math.max(1, this.indexAt(t)); + const head = this.points.slice(0, i); + const tail = this.points.slice(i); + if (!eqDelta(head[i - 1], p)) { + head.push(p); + } + if (!eqDelta(tail[0], p)) { + tail.unshift(p); + } + return [head, tail]; + } + indexAt(t: number) { const pts = this.points; const n = pts.length - 1; @@ -118,7 +136,7 @@ export class Sampler { result.push(mixN([], pts[i - 1], pts[i], (ct - p) / (index[i] - p))); } if (includeLast) { - result.push(copy(peek(pts))); + result.push(set([], peek(pts))); } return result; } diff --git a/packages/geom3/src/internal/splines.ts b/packages/geom3/src/internal/splines.ts new file mode 100644 index 0000000000..52f69c7e25 --- /dev/null +++ b/packages/geom3/src/internal/splines.ts @@ -0,0 +1,128 @@ +import { clamp01, mixCubic } from "@thi.ng/math"; +import { + max2, + max3, + min2, + min3, + mixN, + ReadonlyVec, + set +} from "@thi.ng/vectors3"; +import { VecPair } from "../api"; + +const cubicAxisBounds = + (pa: number, pb: number, pc: number, pd: number) => { + let a = 3 * pd - 9 * pc + 9 * pb - 3 * pa; + let b = 6 * pa - 12 * pb + 6 * pc; + let c = 3 * pb - 3 * pa; + let disc = b * b - 4 * a * c; + let l = pa; + let h = pa; + + const bounds = (t: number) => { + if (t > 0 && t < 1) { + const x = mixCubic(pa, pb, pc, pd, t); + x < l && (l = x); + x > h && (h = x); + } + }; + + pd < l && (l = pd); + pd > h && (h = pd); + if (disc >= 0) { + disc = Math.sqrt(disc); + a *= 2; + bounds((-b + disc) / a); + bounds((-b - disc) / a); + } + return [l, h]; + }; + +export const cubicBounds2 = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec): VecPair => { + const x = cubicAxisBounds(a[0], b[0], c[0], d[0]); + const y = cubicAxisBounds(a[1], b[1], c[1], d[1]); + return [[x[0], y[0]], [x[1], y[1]]]; + }; + +export const cubicBounds3 = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec): VecPair => { + const x = cubicAxisBounds(a[0], b[0], c[0], d[0]); + const y = cubicAxisBounds(a[1], b[1], c[1], d[1]); + const z = cubicAxisBounds(a[2], b[2], c[2], d[2]); + return [[x[0], y[0], z[0]], [x[1], y[1], z[1]]]; + }; + +const solveQuadratic = + (a: number, b: number, c: number) => { + const t = clamp01((a - b) / (a - 2.0 * b + c)); + const s = 1 - t; + return s * s * a + 2.0 * s * t * b + t * t * c; + }; + +export const quadraticBounds2 = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec): VecPair => { + const mi = min2([], a, c); + const ma = max2([], a, c); + if (b[0] < mi[0] || b[0] > ma[0] || b[1] < mi[1] || b[1] > ma[1]) { + const q = [ + solveQuadratic(a[0], b[0], c[0]), + solveQuadratic(a[1], b[1], c[1]), + ]; + min2(null, mi, q); + max2(null, ma, q); + } + return [mi, ma]; + }; + +export const quadraticBounds3 = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec): VecPair => { + const mi = min3([], a, c); + const ma = max3([], a, c); + if (b[0] < mi[0] || b[0] > ma[0] || + b[1] < mi[1] || b[1] > ma[1] || + b[2] < mi[2] || b[2] > ma[2]) { + const q = [ + solveQuadratic(a[0], b[0], c[0]), + solveQuadratic(a[1], b[1], c[1]), + solveQuadratic(a[2], b[2], c[2]), + ]; + min3(null, mi, q); + max3(null, ma, q); + } + return [mi, ma]; + }; + +export const splitCubic = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, t: number) => { + if (t <= 0 || t >= 1) { + const p = t <= 0 ? a : d; + const c1 = [set([], p), set([], p), set([], p), set([], p)]; + const c2 = [set([], a), set([], b), set([], c), set([], d)]; + return t <= 0 ? [c1, c2] : [c2, c1]; + } + const ab = mixN([], a, b, t); + const bc = mixN([], b, c, t); + const cd = mixN([], c, d, t); + const abc = mixN([], ab, bc, t); + const bcd = mixN([], bc, cd, t); + const p = mixN([], abc, bcd, t); + return [ + [set([], a), ab, abc, set([], p)], + [p, bcd, cd, set([], d)] + ]; + }; + +export const splitQuadratic = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, t: number) => { + if (t <= 0 || t >= 1) { + const p = t <= 0 ? a : c; + const c1 = [set([], p), set([], p), set([], p)]; + const c2 = [set([], a), set([], b), set([], c)]; + return t <= 0 ? [c1, c2] : [c2, c1]; + } + const ab = mixN([], a, b, t); + const bc = mixN([], b, c, t); + const p = mixN([], ab, bc, t); + return [[set([], a), ab, p], [p, bc, set([], c)]]; + }; diff --git a/packages/geom3/src/internal/split-line.ts b/packages/geom3/src/internal/split-line.ts new file mode 100644 index 0000000000..af7d645778 --- /dev/null +++ b/packages/geom3/src/internal/split-line.ts @@ -0,0 +1,8 @@ +import { mixN, set, Vec } from "@thi.ng/vectors3"; +import { VecPair } from "../api"; + +export const splitLine = + (a: Vec, b: Vec, t: number): [VecPair, VecPair] => { + const p = mixN([], a, b, t); + return [[a, p], [set([], p), b]]; + }; diff --git a/packages/geom3/src/internal/union-bounds.ts b/packages/geom3/src/internal/union-bounds.ts index 523430c51b..d396dcd0d3 100644 --- a/packages/geom3/src/internal/union-bounds.ts +++ b/packages/geom3/src/internal/union-bounds.ts @@ -3,9 +3,9 @@ import { max, min, ReadonlyVec, - sub, - Vec + sub } from "@thi.ng/vectors3"; +import { VecPair } from "../api"; /** * Takes the position and size vectors of 2 `AABBLike`s and returns @@ -17,7 +17,7 @@ import { * @param bsize */ export const unionBounds = - (apos: ReadonlyVec, asize: ReadonlyVec, bpos: ReadonlyVec, bsize: ReadonlyVec): [Vec, Vec] => { + (apos: ReadonlyVec, asize: ReadonlyVec, bpos: ReadonlyVec, bsize: ReadonlyVec): VecPair => { const p = add([], apos, asize); const q = add([], bpos, bsize); const pos = min([], apos, bpos); diff --git a/packages/geom3/src/ops/area.ts b/packages/geom3/src/ops/area.ts index e3eaed3ff2..b6859829b8 100644 --- a/packages/geom3/src/ops/area.ts +++ b/packages/geom3/src/ops/area.ts @@ -16,7 +16,7 @@ import { dispatch } from "../internal/dispatch"; import { polyArea } from "../internal/poly-area"; /** - * Returns the possibly signed (by default) surface area of given + * Returns the possibly signed (unsigned by default) surface area of given * `shape`. For groups calls `area()` for each child and returns sum of * unsigned areas. * @@ -70,7 +70,7 @@ area.addAll({ () => 0, [Type.POLYGON]: - ($: Polygon, signed = true) => { + ($: Polygon, signed?) => { const area = polyArea($.points); return signed ? area : Math.abs(area); }, @@ -80,7 +80,7 @@ area.addAll({ $.size[0] * $.size[1], [Type.TRIANGLE]: - ($: Triangle, signed = true) => { + ($: Triangle, signed?) => { const area = 0.5 * signedArea2(...<[Vec, Vec, Vec]>$.points); return signed ? area : Math.abs(area); }, diff --git a/packages/geom3/src/ops/as-cubic.ts b/packages/geom3/src/ops/as-cubic.ts new file mode 100644 index 0000000000..9c83c46ff4 --- /dev/null +++ b/packages/geom3/src/ops/as-cubic.ts @@ -0,0 +1,27 @@ +import { defmulti } from "@thi.ng/defmulti"; +import { + Cubic, + IShape, + Line, + Quadratic, + Type +} from "../api"; +import { cubicFromLine, cubicFromQuadratic } from "../ctors/cubic"; +import { dispatch } from "../internal/dispatch"; + +export const asCubic = defmulti(dispatch); + +asCubic.addAll({ + + [Type.CUBIC]: + ($: Cubic) => [$], + + [Type.LINE]: + ({ attribs, points }: Line) => + [cubicFromLine(points[0], points[1], { ...attribs })], + + [Type.QUADRATIC]: + ({ attribs, points }: Quadratic) => + [cubicFromQuadratic(points[0], points[1], points[2], { ...attribs })], + +}); diff --git a/packages/geom3/src/ops/bounds.ts b/packages/geom3/src/ops/bounds.ts index 4261822ff4..aa9561b89c 100644 --- a/packages/geom3/src/ops/bounds.ts +++ b/packages/geom3/src/ops/bounds.ts @@ -1,21 +1,35 @@ import { defmulti } from "@thi.ng/defmulti"; +import { HALF_PI, inRange, PI } from "@thi.ng/math"; import { - copy, + filter, + map, + push, + range, + transduce +} from "@thi.ng/transducers"; +import { + max, MAX2, + min, MIN2, mul2, mulN2, + set2, sub2, - subN2 + subN2, + Vec } from "@thi.ng/vectors3"; import { AABBLike, + Arc, Circle, + Cubic, Ellipse, Group, IShape, Line, PCLike, + Quadratic, Rect, Type } from "../api"; @@ -23,11 +37,30 @@ import { rectFromMinMax } from "../ctors/rect"; import { boundsRaw } from "../internal/bounds"; import { collBounds } from "../internal/coll-bounds"; import { dispatch } from "../internal/dispatch"; +import { cubicBounds2, quadraticBounds2 } from "../internal/splines"; export const bounds = defmulti(dispatch); bounds.addAll({ + [Type.ARC]: + (arc: Arc) => { + const pts = transduce( + map(arc.pointAtTheta.bind(arc)), + push(), + [ + arc.start, + arc.end, + // multiples of HALF_PI in arc range + ...filter( + (t: number) => inRange(t, arc.start, arc.end), + range(-3 * PI, 3.01 * PI, HALF_PI) + ) + ] + ); + return rectFromMinMax(...boundsRaw(pts, set2([], MAX2), set2([], MIN2))); + }, + [Type.CIRCLE]: ($: Circle) => new Rect( @@ -35,6 +68,12 @@ bounds.addAll({ mulN2(null, [2, 2], $.r) ), + [Type.CUBIC]: + ({ points }: Cubic) => + rectFromMinMax( + ...cubicBounds2(points[0], points[1], points[2], points[3]) + ), + [Type.ELLIPSE]: ($: Ellipse) => new Rect( @@ -47,12 +86,18 @@ bounds.addAll({ new Rect(...collBounds($.children, bounds)), [Type.LINE]: - ({ points }: Line) => - rectFromMinMax(points[0], points[1]), + ({ points: [a, b] }: Line) => + rectFromMinMax(min([], a, b), max([], a, b)), [Type.POINTS]: ($: PCLike) => - rectFromMinMax(...boundsRaw($.points, copy(MAX2), copy(MIN2))), + rectFromMinMax(...boundsRaw($.points, set2([], MAX2), set2([], MIN2))), + + [Type.QUADRATIC]: + ({ points }: Quadratic) => + rectFromMinMax( + ...quadraticBounds2(points[0], points[1], points[2]) + ), [Type.RECT]: ($: IShape) => $.copy(), @@ -62,5 +107,5 @@ bounds.addAll({ bounds.isa(Type.AABB, Type.RECT); bounds.isa(Type.POLYGON, Type.POINTS); bounds.isa(Type.POLYLINE, Type.POINTS); -bounds.isa(Type.TRIANGLE, Type.POINTS); bounds.isa(Type.QUAD, Type.POINTS); +bounds.isa(Type.TRIANGLE, Type.POINTS); diff --git a/packages/geom3/src/ops/center.ts b/packages/geom3/src/ops/center.ts index 0f10ce0352..8c5884736e 100644 --- a/packages/geom3/src/ops/center.ts +++ b/packages/geom3/src/ops/center.ts @@ -1,12 +1,14 @@ import { DEFAULT, defmulti, MultiFn1O } from "@thi.ng/defmulti"; import { - copy, ReadonlyVec, + set2, + set3, submN, ZERO2, ZERO3 } from "@thi.ng/vectors3"; import { + Arc, Circle, Ellipse, IShape, @@ -27,16 +29,20 @@ center.add( center.addAll({ + [Type.ARC]: + ($: Arc, origin = ZERO2) => + new Arc(set2([], origin), set2([], $.r), $.axis, $.start, $.end, $.xl, $.cw, { ...$.attribs }), + [Type.CIRCLE]: ($: Circle, origin = ZERO2) => - new Circle(copy(origin), $.r, { ...$.attribs }), + new Circle(set2([], origin), $.r, { ...$.attribs }), [Type.ELLIPSE]: ($: Ellipse, origin = ZERO2) => - new Ellipse(copy(origin), copy($.r), { ...$.attribs }), + new Ellipse(set2([], origin), set2([], $.r), { ...$.attribs }), [Type.SPHERE]: ($: Sphere, origin = ZERO3) => - new Sphere(copy(origin), $.r, { ...$.attribs }), + new Sphere(set3([], origin), $.r, { ...$.attribs }), }); diff --git a/packages/geom3/src/ops/centroid.ts b/packages/geom3/src/ops/centroid.ts index e96c184005..eb5625704c 100644 --- a/packages/geom3/src/ops/centroid.ts +++ b/packages/geom3/src/ops/centroid.ts @@ -55,6 +55,7 @@ centroid.addAll({ }); +centroid.isa(Type.ARC, Type.CIRCLE); centroid.isa(Type.AABB, Type.RECT); centroid.isa(Type.ELLIPSE, Type.CIRCLE); centroid.isa(Type.LINE3, Type.LINE); diff --git a/packages/geom3/src/ops/split-at.ts b/packages/geom3/src/ops/split-at.ts new file mode 100644 index 0000000000..37f89e8a5e --- /dev/null +++ b/packages/geom3/src/ops/split-at.ts @@ -0,0 +1,53 @@ +import { defmulti } from "@thi.ng/defmulti"; +import { fit01 } from "@thi.ng/math"; +import { set } from "@thi.ng/vectors3"; +import { + Arc, + Cubic, + IShape, + Line, + Polyline, + Quadratic, + Type +} from "../api"; +import { copyPoints } from "../internal/copy-points"; +import { dispatch } from "../internal/dispatch"; +import { Sampler } from "../internal/sampler"; +import { splitCubic, splitQuadratic } from "../internal/splines"; +import { splitLine } from "../internal/split-line"; + +export const splitAt = defmulti(dispatch); + +splitAt.addAll({ + + [Type.ARC]: + ($: Arc, t: number) => { + const theta = fit01(t, $.start, $.end); + return [ + new Arc(set([], $.pos), set([], $.r), $.axis, $.start, theta, $.xl, $.cw, { ...$.attribs }), + new Arc(set([], $.pos), set([], $.r), $.axis, theta, $.end, $.xl, $.cw, { ...$.attribs }), + ]; + }, + + [Type.CUBIC]: + ({ attribs, points }: Cubic, t: number) => + splitCubic(points[0], points[1], points[2], points[3], t) + .map((pts) => new Cubic(pts, { ...attribs })), + + [Type.LINE]: + ({ attribs, points }: Line, t) => + splitLine(points[0], points[1], t) + .map((pts) => new Line(pts, { ...attribs })), + + [Type.POLYLINE]: + ($: Polyline, t) => + new Sampler($.points) + .splitAt(t) + .map((pts) => new Polyline(copyPoints(pts), { ...$.attribs })), + + [Type.QUADRATIC]: + ({ attribs, points }: Quadratic, t: number) => + splitQuadratic(points[0], points[1], points[2], t) + .map((pts) => new Quadratic(pts, { ...attribs })), + +}); diff --git a/packages/geom3/src/ops/vertices.ts b/packages/geom3/src/ops/vertices.ts index a76d0a6b23..08ff2c673b 100644 --- a/packages/geom3/src/ops/vertices.ts +++ b/packages/geom3/src/ops/vertices.ts @@ -1,24 +1,24 @@ import { isNumber } from "@thi.ng/checks"; import { defmulti, MultiFn1O } from "@thi.ng/defmulti"; -import { TAU, cossin } from "@thi.ng/math"; +import { cossin, TAU } from "@thi.ng/math"; import { add2, cartesian2, - copy, - Vec, - madd2 + madd2, + set2, + Vec } from "@thi.ng/vectors3"; import { Circle, DEFAULT_SAMPLES, + Ellipse, + Group, IShape, Polygon, Polyline, Rect, SamplingOpts, - Type, - Ellipse, - Group + Type } from "../api"; import { dispatch } from "../internal/dispatch"; import { resamplePoints } from "../internal/sampler"; @@ -71,7 +71,7 @@ vertices.addAll({ ($: Rect, opts) => { const p = $.pos; const q = add2([], p, $.size); - const verts = [copy(p), [q[0], p[1]], q, [p[0], q[1]]]; + const verts = [set2([], p), [q[0], p[1]], q, [p[0], q[1]]]; return opts != null ? vertices(new Polygon(verts), opts) : verts; From 4effc0ec96fa2ae0290c96979d5182ad839aba15 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 16 Jan 2019 02:51:17 +0000 Subject: [PATCH 278/333] feat(examples): add hdom-inner-html demo #67 --- examples/hdom-inner-html/.gitignore | 5 +++ examples/hdom-inner-html/README.md | 13 ++++++++ examples/hdom-inner-html/index.html | 16 +++++++++ examples/hdom-inner-html/package.json | 27 ++++++++++++++++ examples/hdom-inner-html/src/index.ts | 45 ++++++++++++++++++++++++++ examples/hdom-inner-html/tsconfig.json | 11 +++++++ 6 files changed, 117 insertions(+) create mode 100644 examples/hdom-inner-html/.gitignore create mode 100644 examples/hdom-inner-html/README.md create mode 100644 examples/hdom-inner-html/index.html create mode 100644 examples/hdom-inner-html/package.json create mode 100644 examples/hdom-inner-html/src/index.ts create mode 100644 examples/hdom-inner-html/tsconfig.json diff --git a/examples/hdom-inner-html/.gitignore b/examples/hdom-inner-html/.gitignore new file mode 100644 index 0000000000..0c5abcab62 --- /dev/null +++ b/examples/hdom-inner-html/.gitignore @@ -0,0 +1,5 @@ +.cache +out +node_modules +yarn.lock +*.js diff --git a/examples/hdom-inner-html/README.md b/examples/hdom-inner-html/README.md new file mode 100644 index 0000000000..a1373d097c --- /dev/null +++ b/examples/hdom-inner-html/README.md @@ -0,0 +1,13 @@ +# hdom-inner-html + +[Live demo](http://demo.thi.ng/umbrella/hdom-inner-html/) + +Please refer to the [example build instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) on the wiki. + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/examples/hdom-inner-html/index.html b/examples/hdom-inner-html/index.html new file mode 100644 index 0000000000..9551c2e5d6 --- /dev/null +++ b/examples/hdom-inner-html/index.html @@ -0,0 +1,16 @@ + + + + + + + hdom-inner-html + + + + +
+ + + diff --git a/examples/hdom-inner-html/package.json b/examples/hdom-inner-html/package.json new file mode 100644 index 0000000000..dc0296cb0c --- /dev/null +++ b/examples/hdom-inner-html/package.json @@ -0,0 +1,27 @@ +{ + "name": "hdom-inner-html", + "version": "0.0.1", + "repository": "https://github.com/thi-ng/umbrella", + "author": "Karsten Schmidt ", + "license": "Apache-2.0", + "scripts": { + "clean": "rimraf .cache build out", + "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --detailed-report", + "start": "parcel index.html -p 8080 --open" + }, + "devDependencies": { + "parcel-bundler": "^1.11.0", + "rimraf": "^2.6.3", + "terser": "^3.14.1", + "typescript": "^3.2.2" + }, + "dependencies": { + "@thi.ng/hdom": "latest" + }, + "browserslist": [ + "last 3 Chrome versions" + ], + "browser": { + "process": false + } +} \ No newline at end of file diff --git a/examples/hdom-inner-html/src/index.ts b/examples/hdom-inner-html/src/index.ts new file mode 100644 index 0000000000..8b74afbaeb --- /dev/null +++ b/examples/hdom-inner-html/src/index.ts @@ -0,0 +1,45 @@ +import { start } from "@thi.ng/hdom"; + +/** + * HOF component for rendering HTML strings by setting `innerHTML`. The + * returned component takes a single HTML string as arg and updates each + * time the given string has changed. + */ +const innerHtmlWrapper = + () => ({ + init(el, _, html) { + this.el = el; + this.prev = html; + el.innerHTML = html; + }, + render(_, body) { + if (this.el && this.prev != body) { + this.el.innerHTML = body; + this.prev = body; + } + return ["div"]; + } + }); + +/** + * Root component. + */ +const app = () => { + // instantiate HTML wrapper + const wrapper = innerHtmlWrapper(); + return () => + [wrapper, + new Date().getSeconds() & 1 ? + `
Time now:
` : + `
${new Date().toLocaleTimeString()}
` + ]; +}; + +// kick off +const cancel = start(app()); + +// HMR handling +if (process.env.NODE_ENV !== "production") { + const hot = (module).hot; + hot && hot.dispose(cancel); +} diff --git a/examples/hdom-inner-html/tsconfig.json b/examples/hdom-inner-html/tsconfig.json new file mode 100644 index 0000000000..bbf112cc18 --- /dev/null +++ b/examples/hdom-inner-html/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": ".", + "target": "es6", + "sourceMap": true + }, + "include": [ + "./src/**/*.ts" + ] +} From 2cc682a68430be73e0399b629ccd27a78dd3e221 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 16 Jan 2019 03:01:42 +0000 Subject: [PATCH 279/333] fix(examples): add release() lifecycle method (hdom-inner-html) --- examples/hdom-inner-html/src/index.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/examples/hdom-inner-html/src/index.ts b/examples/hdom-inner-html/src/index.ts index 8b74afbaeb..8da0aba198 100644 --- a/examples/hdom-inner-html/src/index.ts +++ b/examples/hdom-inner-html/src/index.ts @@ -18,6 +18,11 @@ const innerHtmlWrapper = this.prev = body; } return ["div"]; + }, + release() { + this.el.innerHTML = ""; + delete this.prev; + delete this.el; } }); From c3762e97b90b6e2fee6b0da57b7ee07bd842c27a Mon Sep 17 00:00:00 2001 From: evilive Date: Wed, 16 Jan 2019 13:32:55 +0200 Subject: [PATCH 280/333] fix(cache): TLRU: expected behavior on getSet() --- packages/cache/src/tlru.ts | 8 ++++++++ packages/cache/test/tlru.ts | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/packages/cache/src/tlru.ts b/packages/cache/src/tlru.ts index 4d0e2f71b9..c89824810f 100644 --- a/packages/cache/src/tlru.ts +++ b/packages/cache/src/tlru.ts @@ -78,6 +78,14 @@ export class TLRUCache extends LRUCache { return value; } + getSet(key: K, retrieve: () => Promise, ttl = this.opts.ttl): Promise { + const e = this.get(key); + if (e) { + return Promise.resolve(e); + } + return retrieve().then((v) => this.set(key, v, ttl)); + } + prune() { const now = Date.now(); let cell = this.items.head; diff --git a/packages/cache/test/tlru.ts b/packages/cache/test/tlru.ts index f3734f8f49..708439da18 100644 --- a/packages/cache/test/tlru.ts +++ b/packages/cache/test/tlru.ts @@ -50,4 +50,18 @@ describe("TLRU", () => { }, 20); }); + it("getSet ttl", (done) => { + setTimeout(() => { + c.getSet("a", () => Promise.resolve(10)).then(v => { + assert.equal(v, 10); + assert(!c.has("b")); + assert(!c.has("c")); + assert.deepEqual([...evicts], [["a", 1], ["b", 2], ["c", 3]]); + assert.deepEqual([...c.keys()], ["a"]); + assert.deepEqual([...c.values()], [10]); + done(); + }).catch(done) + }, 20) + }); + }); From e81d8c31740577cf8ba4a62ea27d6eb06d12f804 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 16 Jan 2019 14:20:17 +0000 Subject: [PATCH 281/333] feat(vectors): update/split angleBetween for 2d/3d --- packages/vectors3/src/angle-between.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/vectors3/src/angle-between.ts b/packages/vectors3/src/angle-between.ts index 35d78caaa5..2cbc44ce41 100644 --- a/packages/vectors3/src/angle-between.ts +++ b/packages/vectors3/src/angle-between.ts @@ -1,16 +1,18 @@ -import { absTheta } from "@thi.ng/math"; import { ReadonlyVec } from "./api"; import { dot } from "./dot"; import { mag } from "./mag"; +import { cross2 } from "./cross"; export const angleRatio = (a: ReadonlyVec, b: ReadonlyVec) => dot(a, b) / (mag(a) * mag(b)); -export const angleBetween = +export const angleBetween2 = + (a: ReadonlyVec, b: ReadonlyVec) => + Math.atan2(cross2(a, b), dot(a, b)); + +export const angleBetween3 = (a: ReadonlyVec, b: ReadonlyVec, normalize = true) => - absTheta( - normalize ? - Math.acos(angleRatio(a, b)) : - Math.acos(dot(a, b)) - ); + normalize ? + Math.acos(angleRatio(a, b)) : + Math.acos(dot(a, b)); From 61cfb0f1a867cc8645be9a2706d1f006a9ebe0f6 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 16 Jan 2019 16:58:27 +0000 Subject: [PATCH 282/333] feat(geom): add path builder, path & arc op impls --- packages/geom3/src/api.ts | 138 +++++++++++++--- packages/geom3/src/ctors/arc.ts | 69 ++++++++ packages/geom3/src/ctors/group.ts | 4 +- packages/geom3/src/ctors/path.ts | 245 ++++++++++++++++++++++++++++ packages/geom3/src/index.ts | 2 + packages/geom3/src/ops/area.ts | 7 +- packages/geom3/src/ops/as-cubic.ts | 65 ++++++++ packages/geom3/src/ops/bounds.ts | 19 +++ packages/geom3/src/ops/point-at.ts | 7 +- packages/geom3/src/ops/simplify.ts | 39 +++++ packages/geom3/src/ops/transform.ts | 4 +- packages/geom3/src/ops/translate.ts | 32 +++- packages/geom3/src/ops/vertices.ts | 70 ++++++-- 13 files changed, 657 insertions(+), 44 deletions(-) create mode 100644 packages/geom3/src/ctors/arc.ts create mode 100644 packages/geom3/src/ctors/path.ts diff --git a/packages/geom3/src/api.ts b/packages/geom3/src/api.ts index cf8bdd16a3..f785d6fd20 100644 --- a/packages/geom3/src/api.ts +++ b/packages/geom3/src/api.ts @@ -1,6 +1,7 @@ import { ICopy, IObjectOf, IToHiccup } from "@thi.ng/api"; import { isNumber } from "@thi.ng/checks"; import { equiv } from "@thi.ng/equiv"; +import { illegalState } from "@thi.ng/errors"; import { cossin } from "@thi.ng/math"; import { add2, @@ -13,6 +14,16 @@ import { } from "@thi.ng/vectors3"; import { copyPoints } from "./internal/copy-points"; +export const enum SegmentType { + MOVE, + LINE, + POLYLINE, + ARC, + CUBIC, + QUADRATIC, + CLOSE, +} + export const enum Type { AABB = 1, ARC, @@ -68,15 +79,7 @@ export interface AABBLike extends IShape { size: Vec; } -export interface PCLike extends IShape { - points: Vec[]; -} - -export interface PCLikeConstructor { - new(pts: Vec[], attribs: Attribs): PCLike; -} - -export interface HiccupShape extends IShape, IToHiccup { } +export interface IHiccupShape extends IShape, IToHiccup { } export interface IHiccupPathSegment { toHiccupPathSegments(): any[]; @@ -90,6 +93,20 @@ export interface LineIntersection { beta?: number; } +export interface PathSegment { + type: SegmentType; + point?: Vec; + geo?: IShape & IHiccupPathSegment; +} + +export interface PCLike extends IShape { + points: Vec[]; +} + +export interface PCLikeConstructor { + new(pts: Vec[], attribs: Attribs): PCLike; +} + export interface SamplingOpts { /** * Number of points to sample & return. Defaults to the implementing @@ -109,8 +126,8 @@ export interface SamplingOpts { /** * Currently only used by these types: * - * - Arc2 - * - Circle2 + * - Arc + * - Circle * * Defines the target angle between sampled points. If greater than * the actual range of the arc, only the two end points will be @@ -189,7 +206,7 @@ export class AABB implements } export class Arc implements - HiccupShape, + IHiccupShape, IHiccupPathSegment { pos: Vec; @@ -276,7 +293,7 @@ export class Arc implements } export class Circle implements - HiccupShape { + IHiccupShape { pos: Vec; r: number; @@ -328,7 +345,7 @@ export class Cubic extends APC implements } export class Ellipse implements - HiccupShape { + IHiccupShape { pos: Vec; r: Vec; @@ -354,12 +371,12 @@ export class Ellipse implements } export class Group implements - HiccupShape { + IHiccupShape { - children: HiccupShape[]; + children: IHiccupShape[]; attribs: Attribs; - constructor(children: HiccupShape[], attribs?: Attribs) { + constructor(children: IHiccupShape[], attribs?: Attribs) { this.children = children; this.attribs = attribs; } @@ -374,7 +391,7 @@ export class Group implements copy() { return new Group( - this.children.map((c) => c.copy()), + this.children.map((c) => c.copy()), { ...this.attribs } ); } @@ -389,7 +406,9 @@ export class Group implements } } -export class Line extends APC { +export class Line extends APC implements + IHiccupShape, + IHiccupPathSegment { get type() { return Type.LINE; @@ -402,6 +421,71 @@ export class Line extends APC { toHiccup() { return ["line", this.attribs, this.points[0], this.points[1]]; } + + toHiccupPathSegments() { + const [a, b] = this.points; + return [ + a[0] === b[0] ? + ["V", b[1]] : + a[1] === b[1] ? + ["H", b[0]] : + ["L", b] + ]; + } +} + +export class Path implements + IHiccupShape { + + segments: PathSegment[]; + closed: boolean; + attribs: Attribs; + + constructor(segments?: PathSegment[], attribs?: Attribs) { + this.segments = segments || []; + this.attribs = attribs; + this.closed = false; + } + + get type() { + return Type.PATH; + } + + *[Symbol.iterator]() { + yield* this.segments; + } + + copy() { + const p = new Path([...this.segments], { ...this.attribs }); + p.closed = this.closed; + return p; + } + + equiv(o: any) { + return o instanceof Path && + equiv(this.segments, o.segments); + } + + add(s: PathSegment) { + if (this.closed) illegalState("path already closed"); + this.segments.push(s); + } + + toHiccup() { + let dest: any[] = []; + const segments = this.segments; + const n = segments.length; + if (n > 1) { + dest.push(["M", segments[0].point]); + for (let i = 1; i < n; i++) { + dest = dest.concat(segments[i].geo.toHiccupPathSegments()); + } + if (this.closed) { + dest.push(["Z"]); + } + } + return ["path", this.attribs || {}, dest]; + } } export class Points extends APC { @@ -434,7 +518,9 @@ export class Polygon extends APC { } } -export class Polyline extends APC { +export class Polyline extends APC implements + IHiccupShape, + IHiccupPathSegment { get type() { return Type.POLYLINE; @@ -447,6 +533,14 @@ export class Polyline extends APC { toHiccup() { return ["polyline", { ...this.attribs, fill: "none" }, this.points]; } + + toHiccupPathSegments() { + const res: any[] = []; + for (let pts = this.points, n = pts.length, i = 1; i < n; i++) { + res.push(["L", pts[i]]); + } + return res; + } } export class Quad extends APC { @@ -491,7 +585,7 @@ export class Quadratic extends APC implements } export class Ray implements - HiccupShape { + IHiccupShape { pos: Vec; dir: Vec; @@ -517,7 +611,7 @@ export class Ray implements } export class Rect implements - HiccupShape { + IHiccupShape { pos: Vec; size: Vec; diff --git a/packages/geom3/src/ctors/arc.ts b/packages/geom3/src/ctors/arc.ts new file mode 100644 index 0000000000..0834d2a032 --- /dev/null +++ b/packages/geom3/src/ctors/arc.ts @@ -0,0 +1,69 @@ +import { isNumber } from "@thi.ng/checks"; +import { TAU } from "@thi.ng/math"; +import { + abs2, + angleBetween2, + mulN2, + ReadonlyVec, + submN2, + Vec, + X2 +} from "@thi.ng/vectors3"; +import { Arc } from "../api"; + +export const arc = ( + pos: Vec, + r: number | Vec, + axis: number, + start: number, + end: number, + xl = false, + clockwise = false +) => new Arc(pos, isNumber(r) ? [r, r] : r, axis, start, end, xl, clockwise); + +export const arcFrom2Points = ( + a: ReadonlyVec, + b: ReadonlyVec, + radii: ReadonlyVec, + axisTheta = 0, + large = false, + clockwise = false +) => { + + const r = abs2([], radii); + const co = Math.cos(axisTheta); + const si = Math.sin(axisTheta); + const m = submN2([], a, b, 0.5); + // const m = mulN2(null, sub2([], a, b), 0.5); + const px = co * m[0] + si * m[1]; + const py = -si * m[0] + co * m[1]; + const px2 = px * px; + const py2 = py * py; + + const l = px2 / (r[0] * r[0]) + py2 / (r[1] * r[1]); + l > 1 && mulN2(null, r, Math.sqrt(l)); + + const rx2 = r[0] * r[0]; + const ry2 = r[1] * r[1]; + const rxpy = rx2 * py2; + const rypx = ry2 * px2; + const rad = ((large === clockwise) ? -1 : 1) * + Math.sqrt(Math.max(0, rx2 * ry2 - rxpy - rypx) / (rxpy + rypx)); + + const tx = rad * r[0] / r[1] * py; + const ty = -rad * r[1] / r[0] * px; + const c = [co * tx - si * ty + (a[0] + b[0]) / 2, si * tx + co * ty + (a[1] + b[1]) / 2]; + const d1 = [(px - tx) / r[0], (py - ty) / r[1]]; + const d2 = [(-px - tx) / r[0], (-py - ty) / r[1]]; + + const theta = angleBetween2(X2, d1); + let delta = angleBetween2(d1, d2); + + if (clockwise && delta < 0) { + delta += TAU; + } else if (!clockwise && delta > 0) { + delta -= TAU; + } + + return new Arc(c, r, axisTheta, theta, theta + delta, large, clockwise); +}; diff --git a/packages/geom3/src/ctors/group.ts b/packages/geom3/src/ctors/group.ts index 7a32a0749a..97c9a9eabc 100644 --- a/packages/geom3/src/ctors/group.ts +++ b/packages/geom3/src/ctors/group.ts @@ -1,5 +1,5 @@ -import { HiccupShape, Attribs, Group } from "../api"; +import { IHiccupShape, Attribs, Group } from "../api"; export const group = - (children: HiccupShape[], attribs?: Attribs) => + (children: IHiccupShape[], attribs?: Attribs) => new Group(children, attribs); diff --git a/packages/geom3/src/ctors/path.ts b/packages/geom3/src/ctors/path.ts new file mode 100644 index 0000000000..2a8d88c219 --- /dev/null +++ b/packages/geom3/src/ctors/path.ts @@ -0,0 +1,245 @@ +import { isNumber } from "@thi.ng/checks"; +import { eqDelta } from "@thi.ng/math"; +import { map, mapcat, peek } from "@thi.ng/transducers"; +import { + add2, + copy, + maddN2, + mulN2, + set2, + sub2, + Vec, + zeroes +} from "@thi.ng/vectors3"; +import { + Attribs, + Cubic, + Line, + Path, + PathSegment, + Quadratic, + SegmentType +} from "../api"; +import { asCubic } from "../ops/as-cubic"; +import { arcFrom2Points } from "./arc"; + +export const path = + (segments: PathSegment[], attribs?: Attribs) => + new Path(segments, attribs); + +export const normalizedPath = + (path: Path) => + new Path( + [...mapcat((s) => + s.geo ? + map( + (c) => ({ type: SegmentType.CUBIC, geo: c }), + asCubic(s.geo) + ) : + [{ ...s }], + path.segments + )], + path.attribs + ); + +export const roundedRect = + (pos: Vec, size: Vec, r: number | Vec) => { + r = isNumber(r) ? [r, r] : r; + const b = new PathBuilder(); + const [w, h] = maddN2([], size, r, -2); + b.moveTo([pos[0] + r[0], pos[1]]); + b.hlineTo(w, true); + b.arcTo(r, r, 0, false, true, true); + b.vlineTo(h, true); + b.arcTo([-r[0], r[1]], r, 0, false, true, true); + b.hlineTo(-w, true); + b.arcTo([-r[0], -r[1]], r, 0, false, true, true); + b.vlineTo(-h, true); + b.arcTo([r[0], -r[1]], r, 0, false, true, true); + return b.curr; + }; + +export class PathBuilder { + + paths: Path[]; + curr: Path; + protected currP: Vec; + protected bezierP: Vec; + protected startP: Vec; + + constructor() { + this.paths = []; + this.newPath(); + } + + *[Symbol.iterator]() { + yield* this.paths; + } + + newPath() { + this.curr = new Path(); + this.paths.push(this.curr); + this.currP = zeroes(2); + this.bezierP = zeroes(2); + this.startP = zeroes(2); + } + + moveTo(p: Vec, relative = false): PathBuilder { + if (this.curr.segments.length > 0) { + this.curr = new Path(); + this.paths.push(this.curr); + } + p = this.updateCurrent(p, relative); + set2(this.startP, p); + set2(this.bezierP, p); + this.curr.add({ + point: p, + type: SegmentType.MOVE, + }); + return this; + } + + lineTo(p: Vec, relative = false): PathBuilder { + this.curr.add({ + geo: new Line([ + copy(this.currP), + this.updateCurrent(p, relative) + ]), + type: SegmentType.LINE, + }); + set2(this.bezierP, this.currP); + return this; + } + + hlineTo(x: number, relative = false): PathBuilder { + const prev = copy(this.currP); + this.currP[0] = relative ? this.currP[0] + x : x; + set2(this.bezierP, this.currP); + this.curr.add({ + geo: new Line([prev, copy(this.currP)]), + type: SegmentType.LINE, + }); + return this; + } + + vlineTo(y: number, relative = false): PathBuilder { + const prev = copy(this.currP); + this.currP[1] = relative ? this.currP[1] + y : y; + set2(this.bezierP, this.currP); + this.curr.add({ + geo: new Line([prev, copy(this.currP)]), + type: SegmentType.LINE, + }); + return this; + } + + // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#Cubic_B%C3%A9zier_Curve + cubicTo(cp1: Vec, cp2: Vec, p: Vec, relative = false) { + const c2 = this.absPoint(cp2, relative); + set2(this.bezierP, c2); + this.curr.add({ + geo: new Cubic([ + copy(this.currP), + this.absPoint(cp1, relative), + c2, + this.updateCurrent(p, relative), + ]), + type: SegmentType.CUBIC, + }); + return this; + } + + // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#Quadratic_B%C3%A9zier_Curve + quadraticTo(cp: Vec, p: Vec, relative = false) { + const c1 = this.absPoint(cp, relative); + set2(this.bezierP, c1); + this.curr.add({ + geo: new Quadratic([ + copy(this.currP), + c1, + this.updateCurrent(p, relative), + ]), + type: SegmentType.QUADRATIC, + }); + return this; + } + + cubicChainTo(cp2: Vec, p: Vec, relative = false) { + const prevMode = peek(this.curr.segments).type; + const c1 = copy(this.currP); + if (prevMode === SegmentType.CUBIC) { + add2(null, sub2([], c1, this.bezierP), c1); + } + const c2 = this.absPoint(cp2, relative); + set2(this.bezierP, c2); + this.curr.add({ + geo: new Cubic([ + copy(this.currP), + c1, + c2, + this.updateCurrent(p, relative), + ]), + type: SegmentType.CUBIC, + }); + return this; + } + + quadraticChainTo(p: Vec, relative = false) { + const prevMode = peek(this.curr.segments).type; + const c1 = copy(this.currP); + if (prevMode === SegmentType.QUADRATIC) { + sub2(null, mulN2(null, c1, 2), this.bezierP); + } + set2(this.bezierP, c1); + this.curr.add({ + geo: new Quadratic([ + copy(this.currP), + c1, + this.updateCurrent(p, relative), + ]), + type: SegmentType.CUBIC, + }); + return this; + } + + arcTo(p: Vec, r: Vec, xaxis: number, xl: boolean, clockwise: boolean, relative = false) { + if (eqDelta(r[0], 0) || eqDelta(r[1], 0)) { + return this.lineTo(p, relative); + } + const prev = copy(this.currP); + this.curr.add({ + geo: arcFrom2Points( + prev, + this.updateCurrent(p, relative), + r, + xaxis, + xl, + clockwise + ), + type: SegmentType.ARC, + }); + set2(this.bezierP, this.currP); + return this; + } + + closePath() { + this.curr.add({ + geo: new Line([copy(this.currP), copy(this.startP)]), + type: SegmentType.LINE, + }); + this.curr.closed = true; + return this; + } + + protected updateCurrent(p: Vec, relative: boolean) { + p = copy(relative ? add2(null, this.currP, p) : set2(this.currP, p)); + return p; + } + + protected absPoint(p: Vec, relative: boolean) { + return relative ? add2(null, p, this.currP) : p; + } +} + +export const pathBuilder = + () => new PathBuilder(); diff --git a/packages/geom3/src/index.ts b/packages/geom3/src/index.ts index 9f61a12b00..3e08dc0e39 100644 --- a/packages/geom3/src/index.ts +++ b/packages/geom3/src/index.ts @@ -1,10 +1,12 @@ export * from "./api"; +export * from "./ctors/arc"; export * from "./ctors/circle"; export * from "./ctors/cubic"; export * from "./ctors/ellipse"; export * from "./ctors/group"; export * from "./ctors/line"; +export * from "./ctors/path"; export * from "./ctors/polygon"; export * from "./ctors/polyline"; export * from "./ctors/quad"; diff --git a/packages/geom3/src/ops/area.ts b/packages/geom3/src/ops/area.ts index b6859829b8..4488a574fc 100644 --- a/packages/geom3/src/ops/area.ts +++ b/packages/geom3/src/ops/area.ts @@ -10,7 +10,8 @@ import { Polygon, Rect, Triangle, - Type + Type, + Arc } from "../api"; import { dispatch } from "../internal/dispatch"; import { polyArea } from "../internal/poly-area"; @@ -54,6 +55,10 @@ area.addAll({ ({ size: [w, h, d] }: AABB) => 2 * ((w * h) + (w * d) + (h * d)), + [Type.ARC]: + // http://cut-the-knot.org/Generalization/Cavalieri2.shtml + ($: Arc) => 0.5 * Math.abs($.start - $.end) * $.r[0] * $.r[1], + [Type.CIRCLE]: ($: Circle) => PI * $.r * $.r, diff --git a/packages/geom3/src/ops/as-cubic.ts b/packages/geom3/src/ops/as-cubic.ts index 9c83c46ff4..a22a452a5e 100644 --- a/packages/geom3/src/ops/as-cubic.ts +++ b/packages/geom3/src/ops/as-cubic.ts @@ -1,8 +1,18 @@ import { defmulti } from "@thi.ng/defmulti"; import { + EPS, + HALF_PI, + roundEps, + sincos +} from "@thi.ng/math"; +import { mapcat } from "@thi.ng/transducers"; +import { add2, magSq2 } from "@thi.ng/vectors3"; +import { + Arc, Cubic, IShape, Line, + Path, Quadratic, Type } from "../api"; @@ -13,6 +23,57 @@ export const asCubic = defmulti(dispatch); asCubic.addAll({ + [Type.ARC]: + ($: Arc) => { + const p = $.pointAtTheta($.start); + const q = $.pointAtTheta($.end); + const [rx, ry] = $.r; + const [sphi, cphi] = sincos($.axis); + const dx = cphi * (p[0] - q[0]) / 2 + sphi * (p[1] - q[1]) / 2; + const dy = -sphi * (p[0] - q[0]) / 2 + cphi * (p[1] - q[1]) / 2; + if ((dx === 0 && dy === 0) || magSq2($.r) < EPS) { + return [cubicFromLine(p, q, { ...$.attribs })]; + } + + const mapP = (x: number, y: number) => { + x *= rx; + y *= ry; + return add2( + null, + [ + cphi * x - sphi * y, + sphi * x + cphi * y + ], + $.pos + ); + }; + + const res: Cubic[] = []; + const delta = $.end - $.start; + const n = Math.max(roundEps(Math.abs(delta) / HALF_PI, 1e-3), 1); + // https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/svg/svg_path_parser.cc#L253 + const d = delta / n; + const t = 8 / 6 * Math.tan(0.25 * d); + if (!isFinite(t)) { + return [cubicFromLine(p, q)]; + } + for (let i = n, theta = $.start; i > 0; i-- , theta += d) { + const [s1, c1] = sincos(theta); + const [s2, c2] = sincos(theta + d); + const curve = new Cubic( + [ + mapP(c1, s1), + mapP(c1 - s1 * t, s1 + c1 * t), + mapP(c2 + s2 * t, s2 - c2 * t), + mapP(c2, s2), + ], + { ...$.attribs } + ); + res.push(curve); + } + return res; + }, + [Type.CUBIC]: ($: Cubic) => [$], @@ -20,6 +81,10 @@ asCubic.addAll({ ({ attribs, points }: Line) => [cubicFromLine(points[0], points[1], { ...attribs })], + [Type.PATH]: + ($: Path) => + [...mapcat((s) => s.geo ? asCubic(s.geo) : null, $.segments)], + [Type.QUADRATIC]: ({ attribs, points }: Quadratic) => [cubicFromQuadratic(points[0], points[1], points[2], { ...attribs })], diff --git a/packages/geom3/src/ops/bounds.ts b/packages/geom3/src/ops/bounds.ts index aa9561b89c..4bee677add 100644 --- a/packages/geom3/src/ops/bounds.ts +++ b/packages/geom3/src/ops/bounds.ts @@ -1,7 +1,9 @@ import { defmulti } from "@thi.ng/defmulti"; import { HALF_PI, inRange, PI } from "@thi.ng/math"; import { + comp, filter, + iterator1, map, push, range, @@ -28,6 +30,8 @@ import { Group, IShape, Line, + Path, + PathSegment, PCLike, Quadratic, Rect, @@ -89,6 +93,21 @@ bounds.addAll({ ({ points: [a, b] }: Line) => rectFromMinMax(min([], a, b), max([], a, b)), + [Type.PATH]: + (path: Path) => + new Rect( + ...collBounds( + [...iterator1( + comp( + map((s: PathSegment) => s.geo), + filter((s) => !!s), + ), + path.segments) + ], + bounds + ) + ), + [Type.POINTS]: ($: PCLike) => rectFromMinMax(...boundsRaw($.points, set2([], MAX2), set2([], MIN2))), diff --git a/packages/geom3/src/ops/point-at.ts b/packages/geom3/src/ops/point-at.ts index 24a61b2bb0..800c6e48b8 100644 --- a/packages/geom3/src/ops/point-at.ts +++ b/packages/geom3/src/ops/point-at.ts @@ -1,5 +1,5 @@ import { defmulti } from "@thi.ng/defmulti"; -import { cossin, TAU } from "@thi.ng/math"; +import { cossin, fit01, TAU } from "@thi.ng/math"; import { cartesian2, madd2, @@ -8,6 +8,7 @@ import { Vec } from "@thi.ng/vectors3"; import { + Arc, Circle, Ellipse, IShape, @@ -25,6 +26,10 @@ export const pointAt = defmulti(dispatch); pointAt.addAll({ + [Type.ARC]: + ($: Arc, t: number) => + $.pointAtTheta(fit01(t, $.start, $.end)), + [Type.CIRCLE]: ($: Circle, t) => cartesian2(null, [$.r, TAU * t], $.pos), diff --git a/packages/geom3/src/ops/simplify.ts b/packages/geom3/src/ops/simplify.ts index c36391efbd..0bb2fbc7bc 100644 --- a/packages/geom3/src/ops/simplify.ts +++ b/packages/geom3/src/ops/simplify.ts @@ -1,17 +1,56 @@ import { defmulti } from "@thi.ng/defmulti"; +import { peek } from "@thi.ng/transducers"; +import { Vec } from "@thi.ng/vectors3"; import { IShape, + Path, + PathSegment, Polygon, Polyline, + SegmentType, Type } from "../api"; import { dispatch } from "../internal/dispatch"; +import { vertices } from "./vertices"; import { douglasPeucker2 } from "../internal/douglas–peucker"; export const simplify = defmulti(dispatch); simplify.addAll({ + [Type.PATH]: + (path: Path, eps = 0.1) => { + const res: PathSegment[] = []; + const orig = path.segments; + const n = orig.length; + let points: Vec[]; + let lastP: Vec; + for (let i = 0; i < n; i++) { + const s = orig[i]; + if (s.type === SegmentType.LINE || s.type === SegmentType.POLYLINE) { + points = (points || []).concat(vertices(s.geo)); + lastP = peek(points); + } else if (points) { + points.push(lastP); + res.push({ + geo: new Polyline(douglasPeucker2(points, eps)), + type: SegmentType.POLYLINE, + }); + points = null; + } else { + res.push({ ...s }); + } + } + if (points) { + points.push(lastP); + res.push({ + geo: new Polyline(points), + type: SegmentType.POLYLINE, + }); + } + return new Path(res, { ...path.attribs }); + }, + [Type.POLYGON]: (poly: Polygon, eps = 0.1) => new Polygon( diff --git a/packages/geom3/src/ops/transform.ts b/packages/geom3/src/ops/transform.ts index d20d245761..f2c1dda00f 100644 --- a/packages/geom3/src/ops/transform.ts +++ b/packages/geom3/src/ops/transform.ts @@ -2,7 +2,7 @@ import { defmulti } from "@thi.ng/defmulti"; import { ReadonlyMat } from "@thi.ng/matrices"; import { Group, - HiccupShape, + IHiccupShape, IShape, Line, PCLike, @@ -36,7 +36,7 @@ transform.addAll({ [Type.GROUP]: ($: Group, mat) => new Group( - $.children.map((x) => transform(x, mat)), + $.children.map((x) => transform(x, mat)), { ...$.attribs } ), diff --git a/packages/geom3/src/ops/translate.ts b/packages/geom3/src/ops/translate.ts index a3d95c8790..107dfe6a73 100644 --- a/packages/geom3/src/ops/translate.ts +++ b/packages/geom3/src/ops/translate.ts @@ -8,12 +8,14 @@ import { } from "@thi.ng/vectors3"; import { AABB, + Arc, Circle, Ellipse, Group, - HiccupShape, + IHiccupShape, IShape, Line, + Path, PCLike, PCLikeConstructor, Points, @@ -38,12 +40,19 @@ export const translate = defmulti(dispatch); translate.addAll({ [Type.AABB]: - ($: Rect, delta) => + ($: AABB, delta) => new AABB( add3([], $.pos, delta), set3([], $.size), { ...$.attribs } ), + [Type.ARC]: + ($: Arc, delta) => { + const a = $.copy(); + add2(null, a.pos, delta); + return a; + }, + [Type.CIRCLE]: ($: Circle, delta) => new Circle( @@ -61,12 +70,29 @@ translate.addAll({ [Type.GROUP]: ($: Group, delta) => new Group( - $.children.map((s) => translate(s, delta)), + $.children.map((s) => translate(s, delta)), { ...$.attribs } ), [Type.LINE]: tx(Line), + [Type.PATH]: + ($: Path, delta: ReadonlyVec) => + new Path( + $.segments.map((s) => + s.geo ? + { + type: s.type, + geo: translate(s.geo, delta) + } : + { + type: s.type, + point: add2([], s.point, delta) + } + ), + { ...$.attribs } + ), + [Type.POINTS]: tx(Points), [Type.POLYGON]: tx(Polygon), diff --git a/packages/geom3/src/ops/vertices.ts b/packages/geom3/src/ops/vertices.ts index 08ff2c673b..915e7ee097 100644 --- a/packages/geom3/src/ops/vertices.ts +++ b/packages/geom3/src/ops/vertices.ts @@ -1,19 +1,14 @@ -import { isNumber } from "@thi.ng/checks"; +import { isNumber, isPlainObject } from "@thi.ng/checks"; import { defmulti, MultiFn1O } from "@thi.ng/defmulti"; import { cossin, TAU } from "@thi.ng/math"; import { - add2, - cartesian2, - madd2, - set2, - Vec -} from "@thi.ng/vectors3"; -import { + Arc, Circle, DEFAULT_SAMPLES, Ellipse, Group, IShape, + Path, Polygon, Polyline, Rect, @@ -21,17 +16,47 @@ import { Type } from "../api"; import { dispatch } from "../internal/dispatch"; -import { resamplePoints } from "../internal/sampler"; +import { resamplePoints, Sampler } from "../internal/sampler"; +import { + add2, + cartesian2, + madd2, + set2, + Vec, +} from "@thi.ng/vectors3"; export const vertices: MultiFn1O, Vec[]> = defmulti(dispatch); vertices.addAll({ + [Type.ARC]: + (arc: Arc, opts?: number | Partial): Vec[] => { + if (isPlainObject(opts) && (opts).dist !== undefined) { + return new Sampler(vertices(arc, (opts).num || DEFAULT_SAMPLES)) + .sampleUniform((opts).dist, (opts).last !== false); + } + opts = isNumber(opts) ? + { num: opts, last: true } : + { num: DEFAULT_SAMPLES, ...opts }; + const start = arc.start; + let delta = arc.end - start; + let num = opts.theta ? + Math.round(delta / opts.theta) : + opts.num; + delta /= num; + opts.last !== false && num++; + const pts: Vec[] = new Array(num); + for (let i = 0, j = 0; i < num; i++ , j += 2) { + pts[i] = arc.pointAtTheta(start + i * delta); + } + return pts; + }, + [Type.CIRCLE]: ($: Circle, opts = DEFAULT_SAMPLES) => { const pos = $.pos; const r = $.r; - let [num, last] = circleOpts(opts); + let [num, last] = circleOpts(opts, r); const delta = TAU / num; last && num++; const buf: Vec[] = new Array(num); @@ -46,7 +71,7 @@ vertices.addAll({ const buf: Vec[] = []; const pos = $.pos; const r = $.r; - let [num, last] = circleOpts(opts); + let [num, last] = circleOpts(opts, Math.max($.r[0], $.r[1])); const delta = TAU / num; last && num++; for (let i = 0; i < num; i++) { @@ -59,6 +84,23 @@ vertices.addAll({ ({ children }: Group) => children.reduce((acc, $) => acc.concat(vertices($)), []), + [Type.PATH]: + (path: Path, opts?: number | Partial) => { + const _opts = isNumber(opts) ? + { num: opts } : + opts; + let verts: Vec[] = []; + for (let segs = path.segments, n = segs.length - 1, i = 0; i <= n; i++) { + const s = segs[i]; + if (s.geo) { + verts = verts.concat( + vertices(s.geo, { ..._opts, last: i === n && !path.closed }) + ); + } + } + return verts; + }, + [Type.POLYGON]: ($: Polygon, opts?) => resamplePoints($.points, opts, true), @@ -83,12 +125,14 @@ vertices.isa(Type.QUAD, Type.POLYGON); vertices.isa(Type.TRIANGLE, Type.POLYGON); const circleOpts = - (opts: number | Partial): [number, boolean] => + (opts: number | Partial, r: number): [number, boolean] => isNumber(opts) ? [opts, false] : [ opts.theta ? Math.floor(TAU / opts.theta) : - opts.num || DEFAULT_SAMPLES, + opts.dist ? + Math.floor(TAU / (opts.dist / r)) : + opts.num || DEFAULT_SAMPLES, opts.last === true ]; From d09cc795254bf62b87861b66b8419b7547062417 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 17 Jan 2019 02:49:19 +0000 Subject: [PATCH 283/333] feat(geom): add clipConvex, scatter, warpPoints --- packages/geom3/package.json | 3 ++- packages/geom3/src/api.ts | 30 ++++++++++++++++++++----- packages/geom3/src/index.ts | 5 +++++ packages/geom3/src/ops/as-polygon.ts | 1 + packages/geom3/src/ops/clip-convex.ts | 31 ++++++++++++++++++++++++++ packages/geom3/src/ops/scatter.ts | 22 ++++++++++++++++++ packages/geom3/src/ops/warp-points.ts | 13 +++++++++++ packages/geom3/src/ops/with-attribs.ts | 7 ++++++ 8 files changed, 105 insertions(+), 7 deletions(-) create mode 100644 packages/geom3/src/ops/clip-convex.ts create mode 100644 packages/geom3/src/ops/scatter.ts create mode 100644 packages/geom3/src/ops/warp-points.ts create mode 100644 packages/geom3/src/ops/with-attribs.ts diff --git a/packages/geom3/package.json b/packages/geom3/package.json index bbc4ffebcc..9dda804af2 100644 --- a/packages/geom3/package.json +++ b/packages/geom3/package.json @@ -16,7 +16,7 @@ "scripts": { "build": "yarn clean && yarn build:es6 && yarn build:bundle", "build:es6": "tsc --declaration", - "build:bundle": "../../scripts/bundle-module geom3 api checks defmulti equiv errors hiccup hiccup-svg math matrices transducers vectors3", + "build:bundle": "../../scripts/bundle-module geom3 api checks defmulti equiv errors hiccup hiccup-svg math matrices random transducers vectors3", "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", @@ -41,6 +41,7 @@ "@thi.ng/hiccup-svg": "^2.0.10", "@thi.ng/math": "^0.2.2", "@thi.ng/matrices": "^0.0.1", + "@thi.ng/random": "^0.1.1", "@thi.ng/transducers": "^2.3.2", "@thi.ng/vectors3": "^0.0.1" }, diff --git a/packages/geom3/src/api.ts b/packages/geom3/src/api.ts index f785d6fd20..74185add69 100644 --- a/packages/geom3/src/api.ts +++ b/packages/geom3/src/api.ts @@ -5,6 +5,7 @@ import { illegalState } from "@thi.ng/errors"; import { cossin } from "@thi.ng/math"; import { add2, + add3, maddN2, mul2, ReadonlyVec, @@ -77,6 +78,8 @@ export interface IShape extends export interface AABBLike extends IShape { pos: Vec; size: Vec; + + max(): Vec; } export interface IHiccupShape extends IShape, IToHiccup { } @@ -184,7 +187,7 @@ export abstract class APC implements } export class AABB implements - IShape { + AABBLike { pos: Vec; size: Vec; @@ -203,8 +206,13 @@ export class AABB implements copy() { return new AABB(set([], this.pos), set([], this.size), { ...this.attribs }); } + + max() { + return add3([], this.pos, this.size); + } } + export class Arc implements IHiccupShape, IHiccupPathSegment { @@ -488,7 +496,8 @@ export class Path implements } } -export class Points extends APC { +export class Points extends APC implements + IHiccupShape { get type() { return Type.POINTS; @@ -503,7 +512,8 @@ export class Points extends APC { } } -export class Polygon extends APC { +export class Polygon extends APC implements + IHiccupShape { get type() { return Type.POLYGON; @@ -543,7 +553,8 @@ export class Polyline extends APC implements } } -export class Quad extends APC { +export class Quad extends APC implements + IHiccupShape { get type() { return Type.QUAD; @@ -559,6 +570,7 @@ export class Quad extends APC { } export class Quadratic extends APC implements + IHiccupShape, IHiccupPathSegment { get type() { @@ -611,6 +623,7 @@ export class Ray implements } export class Rect implements + AABBLike, IHiccupShape { pos: Vec; @@ -631,13 +644,17 @@ export class Rect implements return new Rect(set([], this.pos), set([], this.size), { ...this.attribs }); } + max() { + return add2([], this.pos, this.size); + } + toHiccup() { return ["rect", this.attribs, this.pos, this.size]; } } export class Sphere implements - IShape { + IHiccupShape { pos: Vec; r: number; @@ -662,7 +679,8 @@ export class Sphere implements } } -export class Triangle extends APC { +export class Triangle extends APC implements + IHiccupShape { get type() { return Type.TRIANGLE; diff --git a/packages/geom3/src/index.ts b/packages/geom3/src/index.ts index 3e08dc0e39..9161fa5fd0 100644 --- a/packages/geom3/src/index.ts +++ b/packages/geom3/src/index.ts @@ -7,6 +7,7 @@ export * from "./ctors/ellipse"; export * from "./ctors/group"; export * from "./ctors/line"; export * from "./ctors/path"; +export * from "./ctors/points"; export * from "./ctors/polygon"; export * from "./ctors/polyline"; export * from "./ctors/quad"; @@ -23,6 +24,7 @@ export * from "./ops/bounds"; export * from "./ops/center"; export * from "./ops/centroid"; export * from "./ops/classify-point"; +export * from "./ops/clip-convex"; export * from "./ops/closest-point"; export * from "./ops/convex-hull"; export * from "./ops/fit-into-bounds"; @@ -30,6 +32,7 @@ export * from "./ops/map-point"; export * from "./ops/point-at"; export * from "./ops/point-inside"; export * from "./ops/resample"; +export * from "./ops/scatter"; export * from "./ops/simplify"; export * from "./ops/split-at"; export * from "./ops/subdiv-curve"; @@ -39,6 +42,8 @@ export * from "./ops/translate"; export * from "./ops/union"; export * from "./ops/unmap-point"; export * from "./ops/vertices"; +export * from "./ops/warp-points"; +export * from "./ops/with-attribs"; export * from "./internal/bounds"; export * from "./internal/centroid"; diff --git a/packages/geom3/src/ops/as-polygon.ts b/packages/geom3/src/ops/as-polygon.ts index b43dfc9fdd..5a82145e28 100644 --- a/packages/geom3/src/ops/as-polygon.ts +++ b/packages/geom3/src/ops/as-polygon.ts @@ -20,6 +20,7 @@ asPolygon.addAll({ asPolygon.isa(Type.CIRCLE, Type.POINTS); asPolygon.isa(Type.ELLIPSE, Type.POINTS); asPolygon.isa(Type.LINE, Type.POINTS); +asPolygon.isa(Type.PATH, Type.POINTS); asPolygon.isa(Type.POLYGON, Type.POINTS); asPolygon.isa(Type.POLYLINE, Type.POINTS); asPolygon.isa(Type.QUAD, Type.POINTS); diff --git a/packages/geom3/src/ops/clip-convex.ts b/packages/geom3/src/ops/clip-convex.ts new file mode 100644 index 0000000000..cc4da93295 --- /dev/null +++ b/packages/geom3/src/ops/clip-convex.ts @@ -0,0 +1,31 @@ +import { defmulti } from "@thi.ng/defmulti"; +import { IShape, Polygon, Type } from "../api"; +import { dispatch } from "../internal/dispatch"; +import { sutherlandHodgeman } from "../internal/sutherland-hodgeman"; +import { vertices } from "./vertices"; +import { centroid } from "./centroid"; + +export const clipConvex = defmulti(dispatch); + +clipConvex.addAll({ + + [Type.POLYGON]: + ($: Polygon, boundary: IShape) => + new Polygon( + sutherlandHodgeman($.points, vertices(boundary), centroid(boundary)), + { ...$.attribs } + ), + + [Type.RECT]: + ($, boundary: IShape) => + new Polygon( + sutherlandHodgeman(vertices($), vertices(boundary), centroid(boundary)), + { ...$.attribs } + ) +}); + +clipConvex.isa(Type.CIRCLE, Type.RECT); +clipConvex.isa(Type.ELLIPSE, Type.RECT); +clipConvex.isa(Type.PATH, Type.RECT); +clipConvex.isa(Type.QUAD, Type.POLYGON); +clipConvex.isa(Type.TRIANGLE, Type.POLYGON); diff --git a/packages/geom3/src/ops/scatter.ts b/packages/geom3/src/ops/scatter.ts new file mode 100644 index 0000000000..72d9f79d66 --- /dev/null +++ b/packages/geom3/src/ops/scatter.ts @@ -0,0 +1,22 @@ +import { IShape } from "../api"; +import { Vec, randMinMax } from "@thi.ng/vectors3"; +import { SYSTEM } from "@thi.ng/random"; +import { bounds } from "./bounds"; +import { pointInside } from "./point-inside"; + +export const scatter = + (shape: IShape, num: number, rnd = SYSTEM, out: Vec[] = []) => { + const b = bounds(shape); + const mi = b.pos; + const mx = b.max(); + for (; --num >= 0;) { + while (true) { + const p = randMinMax([], mi, mx, rnd); + if (pointInside(shape, p)) { + out.push(p); + break; + } + } + } + return out; + }; diff --git a/packages/geom3/src/ops/warp-points.ts b/packages/geom3/src/ops/warp-points.ts new file mode 100644 index 0000000000..414c5bd3a4 --- /dev/null +++ b/packages/geom3/src/ops/warp-points.ts @@ -0,0 +1,13 @@ +import { ReadonlyVec, Vec } from "@thi.ng/vectors3"; +import { IShape } from "../api"; +import { mapPoint } from "./map-point"; +import { unmapPoint } from "./unmap-point"; + +export const warpPoints = + (pts: ReadonlyVec[], dest: IShape, src: IShape) => { + const res: Vec[] = []; + for (let n = pts.length, i = 0; i < n; i++) { + res.push(unmapPoint(dest, mapPoint(src, pts[i]))); + } + return res; + }; diff --git a/packages/geom3/src/ops/with-attribs.ts b/packages/geom3/src/ops/with-attribs.ts new file mode 100644 index 0000000000..b1000a4c23 --- /dev/null +++ b/packages/geom3/src/ops/with-attribs.ts @@ -0,0 +1,7 @@ +import { Attribs, IShape } from "../api"; + +export const withAttribs = + (shape: IShape, attribs: Attribs, replace = true) => { + shape.attribs = replace ? attribs : { ...shape.attribs, ...attribs }; + return shape; + }; From 5f873009bcdb54971fb12a5f5a0b2f6c56a795ca Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 17 Jan 2019 02:50:30 +0000 Subject: [PATCH 284/333] feat(vectors): add randMinMax --- packages/vectors3/src/random.ts | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/vectors3/src/random.ts b/packages/vectors3/src/random.ts index d66aaeac52..dac711b784 100644 --- a/packages/vectors3/src/random.ts +++ b/packages/vectors3/src/random.ts @@ -1,5 +1,10 @@ import { IRandom, SYSTEM } from "@thi.ng/random"; -import { MultiVecOpOOO, Vec, VecOpOOO } from "./api"; +import { + MultiVecOpOOO, + ReadonlyVec, + Vec, + VecOpOOO +} from "./api"; import { defHofOp } from "./internal/codegen"; import { normalize } from "./normalize"; @@ -36,3 +41,20 @@ export const randNorm = v = random(v, -1, 1, rnd); return normalize(v, v, n); }; + +/** + * Sets `out` to random vector with each component in the semi-open + * interval defined by [min,max). + * + * @param out + * @param min + * @param max + * @param rnd + */ +export const [randMinMax, randMinMax2, randMinMax3, randMinMax4] = + defHofOp, VecOpOOO>( + SYSTEM, + ([o, a, b]) => `${o}=rnd.minmax(${a},${b});`, + "o,a,b,rnd=op", + "o,a,b" + ); \ No newline at end of file From 9f91cfa1e5957cd1bab30c7cd46f099df082f8da Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 17 Jan 2019 02:53:41 +0000 Subject: [PATCH 285/333] fix(api): update assert(), re-export mixin() --- packages/api/src/assert.ts | 20 +++++++++++--------- packages/api/src/index.ts | 1 + 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/packages/api/src/assert.ts b/packages/api/src/assert.ts index 0dd2a212d0..43143364f2 100644 --- a/packages/api/src/assert.ts +++ b/packages/api/src/assert.ts @@ -4,12 +4,14 @@ * is only enabled if `NODE_ENV != "production"` or if * `UMBRELLA_ASSERTS = 1`. */ -export const assert = - (process.env.NODE_ENV !== "production" || - process.env.UMBRELLA_ASSERTS === "1") ? - (test: boolean | (() => boolean), msg = "assertion failed") => { - if ((typeof test === "function" && !test()) || !test) { - throw new Error(msg); - } - } : - () => { }; +export const assert = ( + typeof process === "undefined" || + process.env.NODE_ENV !== "production" || + process.env.UMBRELLA_ASSERTS === "1" +) ? + (test: boolean | (() => boolean), msg = "assertion failed") => { + if ((typeof test === "function" && !test()) || !test) { + throw new Error(msg); + } + } : + () => { }; diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts index c40c252e8d..a88afb5ccf 100644 --- a/packages/api/src/index.ts +++ b/packages/api/src/index.ts @@ -1,6 +1,7 @@ export * from "./api"; export * from "./assert"; +export * from "./mixin"; export * from "./decorators/configurable"; export * from "./decorators/deprecated"; From f1f428a25a40d8cfcd706b8abfce74feb530a7ba Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 17 Jan 2019 03:36:37 +0000 Subject: [PATCH 286/333] feat(geom): re-add tessellators --- packages/geom3/src/api.ts | 2 + packages/geom3/src/index.ts | 1 + packages/geom3/src/ops/tessellate.ts | 179 +++++++++++++++++++++++++++ 3 files changed, 182 insertions(+) create mode 100644 packages/geom3/src/ops/tessellate.ts diff --git a/packages/geom3/src/api.ts b/packages/geom3/src/api.ts index 74185add69..61e97c0553 100644 --- a/packages/geom3/src/api.ts +++ b/packages/geom3/src/api.ts @@ -66,6 +66,8 @@ export const DEFAULT_SAMPLES = 20; export type Attribs = IObjectOf; +export type Tessellator = (points: Vec[]) => Vec[][]; + export type VecPair = [Vec, Vec]; export interface IShape extends diff --git a/packages/geom3/src/index.ts b/packages/geom3/src/index.ts index 9161fa5fd0..7587f2ed86 100644 --- a/packages/geom3/src/index.ts +++ b/packages/geom3/src/index.ts @@ -37,6 +37,7 @@ export * from "./ops/simplify"; export * from "./ops/split-at"; export * from "./ops/subdiv-curve"; export * from "./ops/tangent-at"; +export * from "./ops/tessellate"; export * from "./ops/transform"; export * from "./ops/translate"; export * from "./ops/union"; diff --git a/packages/geom3/src/ops/tessellate.ts b/packages/geom3/src/ops/tessellate.ts new file mode 100644 index 0000000000..112453f584 --- /dev/null +++ b/packages/geom3/src/ops/tessellate.ts @@ -0,0 +1,179 @@ +import { isFunction } from "@thi.ng/checks"; +import { + comp, + last, + map, + mapcat, + partition, + push, + range, + reducer, + repeat, + scan, + transduce, + tuples, + wrap +} from "@thi.ng/transducers"; +import { + mixN, + ReadonlyVec, + signedArea2, + Vec +} from "@thi.ng/vectors3"; +import { Tessellator } from "../api"; +import { centroidRaw } from "../internal/centroid"; +import { pointInTriangle2 } from "../internal/corner"; +import { polyArea } from "../internal/poly-area"; + +const snip = ( + points: ReadonlyVec[], + u: number, + v: number, + w: number, + n: number, + ids: number[] +) => { + const a = points[ids[u]]; + const b = points[ids[v]]; + const c = points[ids[w]]; + if (signedArea2(a, b, c) > 0) { + for (let i = 0; i < n; i++) { + if (i !== u && i !== v && i !== w) { + if (pointInTriangle2(points[ids[i]], a, b, c)) { + return; + } + } + } + return [a, b, c]; + } +}; + +export const earCut = + (points: ReadonlyVec[]) => { + const tris: Vec[][] = []; + let n = points.length; + const ids = [ + ...(polyArea(points) > 0 ? + range(n) : + range(n - 1, -1, -1)) + ]; + let count = 2 * n - 1; + let v = n - 1, u, w, t; + while (count > 0 && n > 2) { + u = n <= v ? 0 : v; + v = u + 1; + v = n <= v ? 0 : v; + w = v + 1; + w = n <= w ? 0 : w; + t = snip(points, u, v, w, n, ids); + if (t !== undefined) { + tris.push(t); + ids.splice(v, 1); + n--; + count = 2 * n; + } else { + count--; + } + } + return tris; + }; + +export const triFan = + (points: ReadonlyVec[]) => { + const c = centroidRaw(points); + return transduce( + comp( + partition(2, 1), + map(([a, b]) => [a, b, c]) + ), + push(), + wrap(points, 1, false, true) + ); + }; + +export const quadFan = + (points: ReadonlyVec[]) => { + const p = centroidRaw(points); + return transduce( + comp( + partition(3, 1), + map(([a, b, c]) => [mixN([], a, b, 0.5), b, mixN([], b, c, 0.5), p]) + ), + push(), + wrap(points, 1, true, true) + ); + }; + +export const edgeSplit = + (points: ReadonlyVec[]) => { + const c = centroidRaw(points); + return transduce( + comp( + partition(2, 1), + mapcat(([a, b]) => { + const m = mixN([], a, b, 0.5); + return [[a, m, c], [m, b, c]]; + })), + push(), + wrap(points, 1, false, true) + ); + }; + +export const rimTris = + (points: ReadonlyVec[]) => { + const edgeCentroids = transduce( + comp( + partition(2, 1), + map((e) => mixN([], e[0], e[1], 0.5)) + ), + push(), + wrap(points, 1, false, true) + ); + return transduce( + comp( + partition(2, 1), + map((t) => [t[0][0], t[1][1], t[1][0]]) + ), + push(), + [edgeCentroids], + wrap([...tuples(edgeCentroids, points)], 1, true, false) + ); + }; + +export const inset = + (inset = 0.5, keepInterior = false) => + (points: ReadonlyVec[]) => { + const c = centroidRaw(points); + const inner = points.map((p) => mixN([], p, c, inset)); + return transduce( + comp( + partition(2, 1), + map(([[a, b], [c, d]]) => [a, b, d, c]) + ), + push(), + keepInterior ? [inner] : [], + wrap([...tuples(points, inner)], 1, false, true) + ); + }; + +export function tessellatePoints(points: ReadonlyVec[], tessFn: Tessellator, iter?: number): Vec[][]; +export function tessellatePoints(points: ReadonlyVec[], tessFns: Iterable): Vec[][]; +export function tessellatePoints(...args): Vec[][] { + return transduce( + scan( + reducer( + () => [args[0]], + (acc: Vec[][], fn: Tessellator) => + transduce( + mapcat(fn), + push(), + acc + ) + ) + ), + last(), + isFunction(args[1]) ? + repeat(args[1], args[2] || 1) : + args[1] + ); +} From 66267e221f2bd8b7cbbe27de2616e8ce1546d5b3 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 18 Jan 2019 01:27:02 +0000 Subject: [PATCH 287/333] feat(geom): add intersection checks & intersects() multi-fn --- packages/geom3/src/api.ts | 12 ++-- packages/geom3/src/ctors/ray.ts | 6 ++ packages/geom3/src/index.ts | 11 ++- .../geom3/src/internal/line-intersection.ts | 48 ------------- .../geom3/src/internal/sutherland-hodgeman.ts | 6 +- packages/geom3/src/isec/circle-circle.ts | 28 ++++++++ packages/geom3/src/isec/line-line.ts | 56 +++++++++++++++ packages/geom3/src/isec/ray-circle.ts | 22 ++++++ packages/geom3/src/isec/ray-line.ts | 17 +++++ packages/geom3/src/isec/ray-poly.ts | 56 +++++++++++++++ packages/geom3/src/isec/rect-circle.ts | 34 +++++++++ packages/geom3/src/isec/rect-rect.ts | 6 ++ packages/geom3/src/ops/intersects.ts | 70 +++++++++++++++++++ 13 files changed, 316 insertions(+), 56 deletions(-) create mode 100644 packages/geom3/src/ctors/ray.ts delete mode 100644 packages/geom3/src/internal/line-intersection.ts create mode 100644 packages/geom3/src/isec/circle-circle.ts create mode 100644 packages/geom3/src/isec/line-line.ts create mode 100644 packages/geom3/src/isec/ray-circle.ts create mode 100644 packages/geom3/src/isec/ray-line.ts create mode 100644 packages/geom3/src/isec/ray-poly.ts create mode 100644 packages/geom3/src/isec/rect-circle.ts create mode 100644 packages/geom3/src/isec/rect-rect.ts create mode 100644 packages/geom3/src/ops/intersects.ts diff --git a/packages/geom3/src/api.ts b/packages/geom3/src/api.ts index 61e97c0553..57f07cbd59 100644 --- a/packages/geom3/src/api.ts +++ b/packages/geom3/src/api.ts @@ -54,8 +54,9 @@ export const enum Type { RAY3, } -export const enum LineIntersectionType { - PARALLEL = 1, +export const enum IntersectionType { + NONE, + PARALLEL, COINCIDENT, COINCIDENT_NO_INTERSECT, INTERSECT, @@ -90,8 +91,11 @@ export interface IHiccupPathSegment { toHiccupPathSegments(): any[]; } -export interface LineIntersection { - type: LineIntersectionType; +export interface IntersectionResult { + type: IntersectionType; +} + +export interface LineIntersection extends IntersectionResult { isec?: Vec; det?: number; alpha?: number; diff --git a/packages/geom3/src/ctors/ray.ts b/packages/geom3/src/ctors/ray.ts new file mode 100644 index 0000000000..ce19dcc41b --- /dev/null +++ b/packages/geom3/src/ctors/ray.ts @@ -0,0 +1,6 @@ +import { normalize as _norm, Vec } from "@thi.ng/vectors3"; +import { Attribs, Ray } from "../api"; + +export const ray = + (pos: Vec, dir: Vec, attribs?: Attribs, normalize = true) => + new Ray(pos, normalize ? _norm(null, dir) : dir, attribs); diff --git a/packages/geom3/src/index.ts b/packages/geom3/src/index.ts index 7587f2ed86..6d5847c980 100644 --- a/packages/geom3/src/index.ts +++ b/packages/geom3/src/index.ts @@ -12,6 +12,7 @@ export * from "./ctors/polygon"; export * from "./ctors/polyline"; export * from "./ctors/quad"; export * from "./ctors/quadratic"; +export * from "./ctors/ray"; export * from "./ctors/rect"; export * from "./ctors/triangle"; @@ -28,6 +29,7 @@ export * from "./ops/clip-convex"; export * from "./ops/closest-point"; export * from "./ops/convex-hull"; export * from "./ops/fit-into-bounds"; +export * from "./ops/intersects"; export * from "./ops/map-point"; export * from "./ops/point-at"; export * from "./ops/point-inside"; @@ -55,7 +57,6 @@ export * from "./internal/corner"; export * from "./internal/douglas–peucker"; export * from "./internal/graham-scan"; export * from "./internal/liang-barsky"; -export * from "./internal/line-intersection"; export * from "./internal/poly-arc-length"; export * from "./internal/poly-area"; export * from "./internal/poly-centroid"; @@ -65,3 +66,11 @@ export * from "./internal/subdiv-curve"; export * from "./internal/sutherland-hodgeman"; export * from "./internal/transform-points"; export * from "./internal/union-bounds"; + +export * from "./isec/circle-circle"; +export * from "./isec/line-line"; +export * from "./isec/ray-circle"; +export * from "./isec/ray-line"; +export * from "./isec/ray-poly"; +export * from "./isec/rect-circle"; +export * from "./isec/rect-rect"; diff --git a/packages/geom3/src/internal/line-intersection.ts b/packages/geom3/src/internal/line-intersection.ts deleted file mode 100644 index a6c9b38cd6..0000000000 --- a/packages/geom3/src/internal/line-intersection.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { EPS, eqDelta } from "@thi.ng/math"; -import { mixN2, ReadonlyVec } from "@thi.ng/vectors3"; -import { LineIntersection, LineIntersectionType } from "../api"; -import { closestPointSegment } from "./closest-point"; - -export const intersectLines2 = ( - a: ReadonlyVec, - b: ReadonlyVec, - c: ReadonlyVec, - d: ReadonlyVec, - eps = EPS -): LineIntersection => { - - const bax = b[0] - a[0]; - const bay = b[1] - a[1]; - const dcx = d[0] - c[0]; - const dcy = d[1] - c[1]; - const acx = a[0] - c[0]; - const acy = a[1] - c[1]; - const det = dcy * bax - dcx * bay; - let alpha = dcx * acy - dcy * acx; - let beta = bax * acy - bay * acx; - if (eqDelta(det, 0, eps)) { - if (eqDelta(alpha, 0, eps) && eqDelta(beta, 0, eps)) { - let isec = closestPointSegment(c, a, b, undefined, true) || - closestPointSegment(d, a, b, undefined, true); - return { - isec, - type: isec ? - LineIntersectionType.COINCIDENT : - LineIntersectionType.COINCIDENT_NO_INTERSECT, - }; - } - return { type: LineIntersectionType.PARALLEL }; - } - alpha /= det; - beta /= det; - const ieps = 1 - eps; - return { - type: (eps < alpha && alpha < ieps) && (eps < beta && beta < ieps) ? - LineIntersectionType.INTERSECT : - LineIntersectionType.INTERSECT_OUTSIDE, - isec: mixN2([], a, b, alpha), - alpha, - beta, - det, - }; -}; diff --git a/packages/geom3/src/internal/sutherland-hodgeman.ts b/packages/geom3/src/internal/sutherland-hodgeman.ts index 202ef7deae..7975bfec6c 100644 --- a/packages/geom3/src/internal/sutherland-hodgeman.ts +++ b/packages/geom3/src/internal/sutherland-hodgeman.ts @@ -1,6 +1,6 @@ import { ReadonlyVec } from "@thi.ng/vectors3"; import { classify } from "./corner"; -import { intersectLines2 } from "./line-intersection"; +import { intersectLineLine } from "../isec/line-line"; /** * Extended version of Sutherland-Hodgeman convex polygon clipping @@ -28,11 +28,11 @@ export const sutherlandHodgeman = if (classify(ca, cb, p, eps) === sign) { clipped.push( cqsign !== sign ? - intersectLines2(ca, cb, p, q).isec : + intersectLineLine(ca, cb, p, q).isec : q ); } else if (cqsign === sign) { - clipped.push(intersectLines2(ca, cb, p, q).isec, q); + clipped.push(intersectLineLine(ca, cb, p, q).isec, q); } } if (clipped.length < 2) { diff --git a/packages/geom3/src/isec/circle-circle.ts b/packages/geom3/src/isec/circle-circle.ts new file mode 100644 index 0000000000..3057af4433 --- /dev/null +++ b/packages/geom3/src/isec/circle-circle.ts @@ -0,0 +1,28 @@ +import { ReadonlyVec, distSq, mag, sub, maddN, perpendicularLeft2, mulN, add } from "@thi.ng/vectors3"; +import { eqDeltaFixed } from "@thi.ng/math"; +import { IntersectionType } from "../api"; + +export const intersectCircleCircle = + (a: ReadonlyVec, b: ReadonlyVec, ar: number, br: number) => { + const delta = sub([], b, a); + const d = mag(delta); + if (eqDeltaFixed(d, 0)) { + return { type: IntersectionType.COINCIDENT }; + } + if (d <= ar + br && d >= Math.abs(ar - br)) { + ar *= ar; + const alpha = (ar - br * br + d * d) / (2 * d); + const h = Math.sqrt(ar - alpha * alpha); + const p = maddN([], a, delta, alpha / d); + const t = mulN(null, perpendicularLeft2(null, delta), h / d); + return { + type: IntersectionType.INTERSECT, + isec: [add([], p, t), sub([], p, t)] + }; + } + return { type: IntersectionType.NONE }; + }; + +export const testCircleCircle = + (a: ReadonlyVec, b: ReadonlyVec, ar: number, br: number) => + distSq(a, b) <= Math.pow(ar + br, 2); diff --git a/packages/geom3/src/isec/line-line.ts b/packages/geom3/src/isec/line-line.ts new file mode 100644 index 0000000000..d9dd2b3c6e --- /dev/null +++ b/packages/geom3/src/isec/line-line.ts @@ -0,0 +1,56 @@ +import { EPS, eqDeltaFixed } from "@thi.ng/math"; +import { mixN2, ReadonlyVec } from "@thi.ng/vectors3"; +import { IntersectionType, LineIntersection } from "../api"; +import { closestPointSegment } from "../internal/closest-point"; + +export const intersectLineLine = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, eps = EPS): LineIntersection => { + + const bax = b[0] - a[0]; + const bay = b[1] - a[1]; + const dcx = d[0] - c[0]; + const dcy = d[1] - c[1]; + const acx = a[0] - c[0]; + const acy = a[1] - c[1]; + const det = dcy * bax - dcx * bay; + let alpha = dcx * acy - dcy * acx; + let beta = bax * acy - bay * acx; + if (eqDeltaFixed(det, 0, eps)) { + if (eqDeltaFixed(alpha, 0, eps) && eqDeltaFixed(beta, 0, eps)) { + let isec = closestPointSegment(c, a, b, undefined, true) || + closestPointSegment(d, a, b, undefined, true); + return { + type: isec ? + IntersectionType.COINCIDENT : + IntersectionType.COINCIDENT_NO_INTERSECT, + isec, + }; + } + return { type: IntersectionType.PARALLEL }; + } + alpha /= det; + beta /= det; + const ieps = 1 - eps; + return { + type: (eps < alpha && alpha < ieps) && (eps < beta && beta < ieps) ? + IntersectionType.INTERSECT : + IntersectionType.INTERSECT_OUTSIDE, + isec: mixN2([], a, b, alpha), + alpha, + beta, + det, + }; + }; + +/** + * 2D only. Returns true if line `a`,`b` is parallel (or coincident) to + * line `c`,`d`. + * + * @param a + * @param b + * @param c + * @param d + */ +export const isParallelLine = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec) => + eqDeltaFixed((d[1] - c[1]) * (b[0] - a[0]) - (d[0] - c[0]) * (b[1] - a[1]), 0); diff --git a/packages/geom3/src/isec/ray-circle.ts b/packages/geom3/src/isec/ray-circle.ts new file mode 100644 index 0000000000..cb34004ed2 --- /dev/null +++ b/packages/geom3/src/isec/ray-circle.ts @@ -0,0 +1,22 @@ +import { sub, dot, magSq, maddN, ReadonlyVec } from "@thi.ng/vectors3"; + +export const intersectRayCircle = + (rpos: ReadonlyVec, dir: ReadonlyVec, spos: ReadonlyVec, r: number) => { + const delta = sub([], spos, rpos); + const w = dot(delta, dir); + let d = r * r + w * w - magSq(delta); + if (d >= 0) { + d = Math.sqrt(d); + const a = w + d; + const b = w - d; + return a >= 0 ? + b >= 0 ? + a > b ? + [maddN(delta, rpos, dir, b), maddN([], rpos, dir, a)] : + [maddN(delta, rpos, dir, a), maddN([], rpos, dir, b)] : + [maddN(delta, rpos, dir, a)] : + b >= 0 ? + [maddN(delta, rpos, dir, b)] : + undefined; + } + }; diff --git a/packages/geom3/src/isec/ray-line.ts b/packages/geom3/src/isec/ray-line.ts new file mode 100644 index 0000000000..ce8ae58dd8 --- /dev/null +++ b/packages/geom3/src/isec/ray-line.ts @@ -0,0 +1,17 @@ +import { eqDeltaFixed } from "@thi.ng/math"; +import { ReadonlyVec } from "@thi.ng/vectors3"; + +export const intersectRayLine = + (rpos: ReadonlyVec, dir: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec) => { + const bax = b[0] - a[0]; + const bay = b[1] - a[1]; + const d = dir[0] * bay - dir[1] * bax; + if (eqDeltaFixed(d, 0)) return; + const arx = a[0] - rpos[0]; + const ary = a[1] - rpos[1]; + const t = (bay * arx - bax * ary) / d; + const s = (dir[1] * arx - dir[0] * ary) / d; + return t >= 0 && s >= 0 && s <= 1 ? + t : + undefined; + }; diff --git a/packages/geom3/src/isec/ray-poly.ts b/packages/geom3/src/isec/ray-poly.ts new file mode 100644 index 0000000000..4604f129ed --- /dev/null +++ b/packages/geom3/src/isec/ray-poly.ts @@ -0,0 +1,56 @@ +import { maddN2, ReadonlyVec } from "@thi.ng/vectors3"; +import { IntersectionType } from "../api"; +import { intersectRayLine } from "./ray-line"; + +export const intersectRayPolyline = + (rpos: ReadonlyVec, dir: ReadonlyVec, pts: ReadonlyVec[], closed = false) => { + const n = pts.length - 1; + let minD = Infinity; + let cross = 0; + let i, j; + if (closed) { + i = pts[n]; + j = pts[0]; + } else { + i = pts[0]; + j = pts[1]; + } + for (let k = 0; k <= n; i = j, j = pts[++k]) { + const d = intersectRayLine(rpos, dir, i, j); + if (d !== undefined) { + cross++; + if (d < minD) minD = d; + } + } + return cross > 0 ? + { + type: IntersectionType.INTERSECT, + isec: maddN2([], rpos, dir, minD), + dist: minD, + inside: !(cross & 1) + } : + { + type: IntersectionType.NONE + }; + }; + +export const intersectRayPolylineAll = + (rpos: ReadonlyVec, dir: ReadonlyVec, pts: ReadonlyVec[], closed = false) => { + const n = pts.length - 1; + let i, j; + if (closed) { + i = pts[n]; + j = pts[0]; + } else { + i = pts[0]; + j = pts[1]; + } + const res = []; + for (let k = 0; k <= n; i = j, j = pts[++k]) { + const d = intersectRayLine(rpos, dir, i, j); + if (d !== undefined) { + res.push([d, maddN2([], rpos, dir, d)]); + } + } + return res.sort((a, b) => a[0] - b[0]); + }; diff --git a/packages/geom3/src/isec/rect-circle.ts b/packages/geom3/src/isec/rect-circle.ts new file mode 100644 index 0000000000..eb7a9eecc5 --- /dev/null +++ b/packages/geom3/src/isec/rect-circle.ts @@ -0,0 +1,34 @@ +export const intersectRectCircle = ( + rx: number, + ry: number, + w: number, + h: number, + cx: number, + cy: number, + r: number +) => + (rcAxis(cx, rx, w) + rcAxis(cy, ry, h)) <= r * r; + +export const intersectAABBSphere = ( + rx: number, + ry: number, + rz: number, + w: number, + h: number, + d: number, + cx: number, + cy: number, + cz: number, + r: number +) => ( + rcAxis(cx, rx, w) + + rcAxis(cy, ry, h) + + rcAxis(cz, rz, d) +) <= r * r; + +const rcAxis = (a: number, b: number, c: number) => + a < b ? + Math.pow(a - b, 2) : + a > b + c ? + Math.pow(a - b - c, 2) : + 0; diff --git a/packages/geom3/src/isec/rect-rect.ts b/packages/geom3/src/isec/rect-rect.ts new file mode 100644 index 0000000000..123898d054 --- /dev/null +++ b/packages/geom3/src/isec/rect-rect.ts @@ -0,0 +1,6 @@ +export const testRectRect = + (ax: number, ay: number, aw: number, ah: number, bx: number, by: number, bw: number, bh: number) => + !((ax > bx + bw) || + (bx > ax + aw) || + (ay > by + bh) || + (by > ay + ah)); diff --git a/packages/geom3/src/ops/intersects.ts b/packages/geom3/src/ops/intersects.ts new file mode 100644 index 0000000000..3ac9ed634a --- /dev/null +++ b/packages/geom3/src/ops/intersects.ts @@ -0,0 +1,70 @@ +import { defmulti, MultiFn2O } from "@thi.ng/defmulti"; +import { + Circle, + IntersectionResult, + IntersectionType, + IShape, + Line, + PCLike, + Ray, + Rect, + Sphere, + Type +} from "../api"; +import { dispatch2 } from "../internal/dispatch"; +import { intersectCircleCircle } from "../isec/circle-circle"; +import { intersectLineLine } from "../isec/line-line"; +import { intersectRayCircle } from "../isec/ray-circle"; +import { intersectRayPolyline } from "../isec/ray-poly"; +import { intersectRectCircle } from "../isec/rect-circle"; +import { testRectRect } from "../isec/rect-rect"; + +export const intersects: MultiFn2O = defmulti(dispatch2); + +intersects.addAll({ + + [`${Type.CIRCLE}-${Type.CIRCLE}`]: + (a: Sphere, b: Sphere) => + intersectCircleCircle(a.pos, b.pos, a.r, b.r), + + [`${Type.LINE}-${Type.LINE}`]: + ({ points: a }: Line, { points: b }: Line) => + intersectLineLine(a[0], a[1], b[0], b[1]), + + [`${Type.RAY}-${Type.CIRCLE}`]: + (ray: Ray, sphere: Sphere) => { + const isec = intersectRayCircle(ray.pos, ray.dir, sphere.pos, sphere.r); + return isec ? + { type: IntersectionType.INTERSECT, isec } : + { type: IntersectionType.NONE }; + }, + + [`${Type.RAY}-${Type.POLYGON}`]: + (ray: Ray, poly: PCLike) => + intersectRayPolyline(ray.pos, ray.dir, poly.points, true), + + [`${Type.RAY}-${Type.POLYLINE}`]: + (ray: Ray, poly: PCLike) => + intersectRayPolyline(ray.pos, ray.dir, poly.points, false), + + [`${Type.RECT}-${Type.CIRCLE}`]: + ({ pos: rp, size }: Rect, { pos: cp, r }: Circle) => ({ + type: intersectRectCircle(rp[0], rp[1], size[0], size[1], cp[0], cp[1], r) ? + IntersectionType.INTERSECT : + IntersectionType.NONE + }), + + [`${Type.RECT}-${Type.RECT}`]: + ({ pos: ap, size: as }: Rect, + { pos: bp, size: bs }: Rect) => ({ + type: testRectRect(ap[0], ap[1], as[0], as[1], bp[0], bp[1], bs[0], bs[1]) ? + IntersectionType.INTERSECT : + IntersectionType.NONE + }), + +}); + +intersects.isa(`${Type.RAY}-${Type.SPHERE}`, `${Type.RAY}-${Type.CIRCLE}`); +intersects.isa(`${Type.RAY}-${Type.QUAD}`, `${Type.RAY}-${Type.POLYGON}`); +intersects.isa(`${Type.RAY}-${Type.TRIANGLE}`, `${Type.RAY}-${Type.POLYGON}`); +intersects.isa(`${Type.SPHERE}-${Type.SPHERE}`, `${Type.CIRCLE}-${Type.CIRCLE}`); From 3c9a7b0f4464386c01eed0998adcd1fa7026c7a7 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 18 Jan 2019 02:49:35 +0000 Subject: [PATCH 288/333] feat(geom): re-add pathFromSvg() --- packages/geom3/src/ctors/path.ts | 145 ++++++++++++++++++++++++++++++- 1 file changed, 144 insertions(+), 1 deletion(-) diff --git a/packages/geom3/src/ctors/path.ts b/packages/geom3/src/ctors/path.ts index 2a8d88c219..e455f4bbef 100644 --- a/packages/geom3/src/ctors/path.ts +++ b/packages/geom3/src/ctors/path.ts @@ -1,5 +1,5 @@ import { isNumber } from "@thi.ng/checks"; -import { eqDelta } from "@thi.ng/math"; +import { eqDelta, rad } from "@thi.ng/math"; import { map, mapcat, peek } from "@thi.ng/transducers"; import { add2, @@ -243,3 +243,146 @@ export class PathBuilder { export const pathBuilder = () => new PathBuilder(); + +const CMD_RE = /[achlmqstvz]/i; + +export const pathFromSvg = (svg: string) => { + const b = new PathBuilder(); + try { + let cmd: string; + for (let n = svg.length, i = 0; i < n;) { + i = skipWS(svg, i); + const c = svg.charAt(i); + if (CMD_RE.test(c)) { + cmd = c; + i++; + } + let p, pa, pb, t1, t2, t3; + switch (cmd.toLowerCase()) { + case "m": + [p, i] = readPoint(svg, i); + b.moveTo(p, cmd === "m"); + break; + case "l": + [p, i] = readPoint(svg, i); + b.lineTo(p, cmd === "l"); + break; + case "h": + [p, i] = readFloat(svg, i); + b.hlineTo(p, cmd === "h"); + break; + case "v": + [p, i] = readFloat(svg, i); + b.vlineTo(p, cmd === "v"); + break; + case "q": + [pa, i] = readPoint(svg, i); + [p, i] = readPoint(svg, i); + // console.log("quadratic", pa.toString(), p.toString()); + b.quadraticTo(pa, p, cmd === "q"); + break; + case "c": + [pa, i] = readPoint(svg, i); + [pb, i] = readPoint(svg, i); + [p, i] = readPoint(svg, i); + // console.log("cubic", pa.toString(), pb.toString(), p.toString()); + b.cubicTo(pa, pb, p, cmd === "c"); + break; + case "s": + [pa, i] = readPoint(svg, i); + [p, i] = readPoint(svg, i); + // console.log("cubicChain", pa.toString(), p.toString()); + b.cubicChainTo(pa, p, cmd === "s"); + break; + case "t": + [p, i] = readPoint(svg, i); + // console.log("quadraticChain", p.toString()); + b.quadraticChainTo(p, cmd === "t"); + break; + case "a": { + [pa, i] = readPoint(svg, i); + [t1, i] = readFloat(svg, i); + [t2, i] = readFloat(svg, i); + [t3, i] = readFloat(svg, i); + [pb, i] = readPoint(svg, i); + // console.log("arc", pa.toString(), rad(t1), t2, t3, pb.toString()); + b.arcTo(pb, pa, rad(t1), !!t2, !!t3, cmd === "a"); + break; + } + case "z": + b.closePath(); + break; + default: + throw new Error(`unsupported segment type: ${c} @ pos ${i}`); + } + } + return b.paths; + } catch (e) { + throw e instanceof Error ? e : new Error(`illegal char '${svg.charAt(e)}' @ ${e}`); + } +}; + +const readPoint = + (src: string, index: number): [Vec, number] => { + let x, y; + [x, index] = readFloat(src, index); + index = skipWS(src, index); + [y, index] = readFloat(src, index); + return [[x, y], index]; + }; + +const isWS = + (c: string) => c === " " || c === "\n" || c === "\r" || c === "\t"; + +const skipWS = + (src: string, i: number) => { + const n = src.length; + while (i < n && isWS(src.charAt(i))) i++; + return i; + }; + +const readFloat = + (src: string, index: number) => { + index = skipWS(src, index); + let signOk = true; + let dotOk = true; + let expOk = false; + let commaOk = false; + let i = index; + for (let n = src.length; i < n; i++) { + const c = src.charAt(i); + // console.log("float", src.substring(index, i + 1)); + if ("0" <= c && c <= "9") { + expOk = true; + commaOk = true; + signOk = false; + continue; + } + if (c === "-" || c === "+") { + if (!signOk) break; + signOk = false; + continue; + } + if (c === ".") { + if (!dotOk) break; + dotOk = false; + continue; + } + if (c === "e") { + if (!expOk) throw i; + expOk = false; + dotOk = false; + signOk = true; + continue; + } + if (c === ",") { + if (!commaOk) throw i; + i++; + } + break; + } + if (i === index) { + throw new Error(`expected coordinate @ pos: ${i}`); + } + return [parseFloat(src.substring(index, i)), i]; + }; From f5a53ca0f6db15acf429c48b5ff4f7af9b8ddd80 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 18 Jan 2019 02:50:43 +0000 Subject: [PATCH 289/333] feat(geom): re-add vertices() impls for Cubic/Quadratic --- packages/geom3/src/ops/vertices.ts | 74 ++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 10 deletions(-) diff --git a/packages/geom3/src/ops/vertices.ts b/packages/geom3/src/ops/vertices.ts index 915e7ee097..a748b63e7c 100644 --- a/packages/geom3/src/ops/vertices.ts +++ b/packages/geom3/src/ops/vertices.ts @@ -1,9 +1,19 @@ import { isNumber, isPlainObject } from "@thi.ng/checks"; import { defmulti, MultiFn1O } from "@thi.ng/defmulti"; import { cossin, TAU } from "@thi.ng/math"; +import { + add2, + cartesian2, + madd2, + mixCubic, + mixQuadratic, + set2, + Vec +} from "@thi.ng/vectors3"; import { Arc, Circle, + Cubic, DEFAULT_SAMPLES, Ellipse, Group, @@ -11,19 +21,13 @@ import { Path, Polygon, Polyline, + Quadratic, Rect, SamplingOpts, Type } from "../api"; import { dispatch } from "../internal/dispatch"; import { resamplePoints, Sampler } from "../internal/sampler"; -import { - add2, - cartesian2, - madd2, - set2, - Vec, -} from "@thi.ng/vectors3"; export const vertices: MultiFn1O, Vec[]> = defmulti(dispatch); @@ -66,6 +70,31 @@ vertices.addAll({ return buf; }, + [Type.CUBIC]: + ($: Cubic, opts?: number | Partial) => { + if (isPlainObject(opts) && (opts).dist !== undefined) { + return new Sampler(vertices($, (opts).num || DEFAULT_SAMPLES)) + .sampleUniform((opts).dist, (opts).last !== false); + } + opts = isNumber(opts) ? + { + num: opts, + last: true + } : + { + num: DEFAULT_SAMPLES, + ...opts + }; + const res: Vec[] = []; + const [a, b, c, d] = $.points; + const delta = 1 / opts.num; + for (let t = 0; t < opts.num; t++) { + res.push(mixCubic([], a, b, c, d, t * delta)); + } + opts.last && res.push([d[0], d[1]]); + return res; + }, + [Type.ELLIPSE]: ($: Ellipse, opts = DEFAULT_SAMPLES) => { const buf: Vec[] = []; @@ -85,16 +114,16 @@ vertices.addAll({ children.reduce((acc, $) => acc.concat(vertices($)), []), [Type.PATH]: - (path: Path, opts?: number | Partial) => { + ($: Path, opts?: number | Partial) => { const _opts = isNumber(opts) ? { num: opts } : opts; let verts: Vec[] = []; - for (let segs = path.segments, n = segs.length - 1, i = 0; i <= n; i++) { + for (let segs = $.segments, n = segs.length - 1, i = 0; i <= n; i++) { const s = segs[i]; if (s.geo) { verts = verts.concat( - vertices(s.geo, { ..._opts, last: i === n && !path.closed }) + vertices(s.geo, { ..._opts, last: i === n && !$.closed }) ); } } @@ -109,6 +138,31 @@ vertices.addAll({ ($: Polyline, opts?) => resamplePoints($.points, opts), + [Type.QUADRATIC]: + ($: Quadratic, opts?: number | Partial) => { + if (isPlainObject(opts) && (opts).dist !== undefined) { + return new Sampler(vertices($, (opts).num || DEFAULT_SAMPLES)) + .sampleUniform((opts).dist, (opts).last !== false); + } + opts = isNumber(opts) ? + { + num: opts, + last: true + } : + { + num: DEFAULT_SAMPLES, + ...opts + }; + const res: Vec[] = []; + const delta = 1 / opts.num; + const [a, b, c] = $.points; + for (let t = 0; t < opts.num; t++) { + res.push(mixQuadratic([], a, b, c, t * delta)); + } + opts.last && res.push([c[0], c[1]]); + return res; + }, + [Type.RECT]: ($: Rect, opts) => { const p = $.pos; From e834597c5667ee738f85843012ffa958b0cfcd59 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 18 Jan 2019 14:28:59 +0000 Subject: [PATCH 290/333] feat(geom): add/update edges(), pointInside() & classifyPoint() impls --- packages/geom3/src/index.ts | 4 +++ packages/geom3/src/internal/clockwise.ts | 5 +++ packages/geom3/src/internal/corner.ts | 28 ++------------- packages/geom3/src/internal/edges.ts | 12 +++++++ packages/geom3/src/internal/point-in-array.ts | 12 +++++++ .../geom3/src/internal/sutherland-hodgeman.ts | 8 ++--- .../src/internal/triangle-point-inside.ts | 24 +++++++++++++ packages/geom3/src/ops/classify-point.ts | 11 ++++-- packages/geom3/src/ops/edges.ts | 35 +++++++++++++++++++ packages/geom3/src/ops/point-inside.ts | 19 +++++++--- packages/geom3/src/ops/tessellate.ts | 2 +- 11 files changed, 122 insertions(+), 38 deletions(-) create mode 100644 packages/geom3/src/internal/clockwise.ts create mode 100644 packages/geom3/src/internal/edges.ts create mode 100644 packages/geom3/src/internal/point-in-array.ts create mode 100644 packages/geom3/src/internal/triangle-point-inside.ts create mode 100644 packages/geom3/src/ops/edges.ts diff --git a/packages/geom3/src/index.ts b/packages/geom3/src/index.ts index 6d5847c980..806b9cab50 100644 --- a/packages/geom3/src/index.ts +++ b/packages/geom3/src/index.ts @@ -28,6 +28,7 @@ export * from "./ops/classify-point"; export * from "./ops/clip-convex"; export * from "./ops/closest-point"; export * from "./ops/convex-hull"; +export * from "./ops/edges"; export * from "./ops/fit-into-bounds"; export * from "./ops/intersects"; export * from "./ops/map-point"; @@ -51,10 +52,12 @@ export * from "./ops/with-attribs"; export * from "./internal/bounds"; export * from "./internal/centroid"; export * from "./internal/circumcenter"; +export * from "./internal/clockwise"; export * from "./internal/closest-point"; export * from "./internal/copy-points"; export * from "./internal/corner"; export * from "./internal/douglas–peucker"; +export * from "./internal/edges"; export * from "./internal/graham-scan"; export * from "./internal/liang-barsky"; export * from "./internal/poly-arc-length"; @@ -65,6 +68,7 @@ export * from "./internal/sampler"; export * from "./internal/subdiv-curve"; export * from "./internal/sutherland-hodgeman"; export * from "./internal/transform-points"; +export * from "./internal/triangle-point-inside"; export * from "./internal/union-bounds"; export * from "./isec/circle-circle"; diff --git a/packages/geom3/src/internal/clockwise.ts b/packages/geom3/src/internal/clockwise.ts new file mode 100644 index 0000000000..13dbf51623 --- /dev/null +++ b/packages/geom3/src/internal/clockwise.ts @@ -0,0 +1,5 @@ +import { ReadonlyVec, signedArea2 } from "@thi.ng/vectors3"; + +export const clockwise2 = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => + signedArea2(a, b, c) < 0; diff --git a/packages/geom3/src/internal/corner.ts b/packages/geom3/src/internal/corner.ts index aa4d7c6de4..88f2660317 100644 --- a/packages/geom3/src/internal/corner.ts +++ b/packages/geom3/src/internal/corner.ts @@ -1,30 +1,6 @@ import { EPS, sign } from "@thi.ng/math"; import { ReadonlyVec, signedArea2 } from "@thi.ng/vectors3"; -export const classify = +export const corner = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, eps = EPS) => - sign(signedArea2(a, b, c), eps); - -export const clockwise2 = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => - signedArea2(a, b, c) < 0; - -export const classifyPointInTriangle2 = - (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => { - const s = clockwise2(a, b, c) ? 1 : -1; - return sign( - Math.min( - s * signedArea2(a, c, p), - s * signedArea2(b, a, p), - s * signedArea2(c, b, p) - ) - ); - }; - -export const pointInTriangle2 = - (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => { - const s = clockwise2(a, b, c) ? 1 : -1; - return s * signedArea2(a, c, p) >= 0 && - s * signedArea2(b, a, p) >= 0 && - s * signedArea2(c, b, p) >= 0; - }; + sign(signedArea2(a, b, c), eps); \ No newline at end of file diff --git a/packages/geom3/src/internal/edges.ts b/packages/geom3/src/internal/edges.ts new file mode 100644 index 0000000000..b8b21d2b92 --- /dev/null +++ b/packages/geom3/src/internal/edges.ts @@ -0,0 +1,12 @@ +import { partition, wrap } from "@thi.ng/transducers"; +import { ReadonlyVec } from "@thi.ng/vectors3"; +import { VecPair } from "../api"; + +export const edgeIterator = + (vertices: Iterable, closed = false) => + >partition( + 2, 1, + closed ? + wrap(vertices, 1, false, true) : + vertices + ); diff --git a/packages/geom3/src/internal/point-in-array.ts b/packages/geom3/src/internal/point-in-array.ts new file mode 100644 index 0000000000..08caa22f43 --- /dev/null +++ b/packages/geom3/src/internal/point-in-array.ts @@ -0,0 +1,12 @@ +import { EPS } from "@thi.ng/math"; +import { eqDelta, ReadonlyVec } from "@thi.ng/vectors3"; + +export const pointInArray = + (points: ReadonlyVec[], p: ReadonlyVec, eps = EPS) => { + for (let i = points.length; --i >= 0;) { + if (eqDelta(p, points[i], eps)) { + return true; + } + } + return false; + }; diff --git a/packages/geom3/src/internal/sutherland-hodgeman.ts b/packages/geom3/src/internal/sutherland-hodgeman.ts index 7975bfec6c..967481a32e 100644 --- a/packages/geom3/src/internal/sutherland-hodgeman.ts +++ b/packages/geom3/src/internal/sutherland-hodgeman.ts @@ -1,5 +1,5 @@ import { ReadonlyVec } from "@thi.ng/vectors3"; -import { classify } from "./corner"; +import { corner } from "./corner"; import { intersectLineLine } from "../isec/line-line"; /** @@ -20,12 +20,12 @@ export const sutherlandHodgeman = const clipped = []; const ca = bounds[j]; const cb = bounds[i]; - const sign = classify(ca, cb, bc, eps); + const sign = corner(ca, cb, bc, eps); for (let np = pts.length, k = np - 1, l = 0; l < np; k = l, l++) { const p = pts[k]; const q = pts[l]; - const cqsign = classify(ca, cb, q, eps); - if (classify(ca, cb, p, eps) === sign) { + const cqsign = corner(ca, cb, q, eps); + if (corner(ca, cb, p, eps) === sign) { clipped.push( cqsign !== sign ? intersectLineLine(ca, cb, p, q).isec : diff --git a/packages/geom3/src/internal/triangle-point-inside.ts b/packages/geom3/src/internal/triangle-point-inside.ts new file mode 100644 index 0000000000..1047c3c290 --- /dev/null +++ b/packages/geom3/src/internal/triangle-point-inside.ts @@ -0,0 +1,24 @@ +import { EPS, sign } from "@thi.ng/math"; +import { ReadonlyVec, signedArea2 } from "@thi.ng/vectors3"; +import { clockwise2 } from "./clockwise"; + +export const classifyPointInTriangle2 = + (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, eps = EPS) => { + const s = clockwise2(a, b, c) ? 1 : -1; + return sign( + Math.min( + s * signedArea2(a, c, p), + s * signedArea2(b, a, p), + s * signedArea2(c, b, p) + ), + eps + ); + }; + +export const pointInTriangle2 = + (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => { + const s = clockwise2(a, b, c) ? 1 : -1; + return s * signedArea2(a, c, p) >= 0 && + s * signedArea2(b, a, p) >= 0 && + s * signedArea2(c, b, p) >= 0; + }; diff --git a/packages/geom3/src/ops/classify-point.ts b/packages/geom3/src/ops/classify-point.ts index e369dbfe9c..c75ada83e1 100644 --- a/packages/geom3/src/ops/classify-point.ts +++ b/packages/geom3/src/ops/classify-point.ts @@ -1,10 +1,11 @@ -import { defmulti } from "@thi.ng/defmulti"; +import { defmulti, MultiFn2O } from "@thi.ng/defmulti"; import { EPS, sign } from "@thi.ng/math"; import { dist, ReadonlyVec } from "@thi.ng/vectors3"; -import { Circle, IShape, Type } from "../api"; +import { Circle, IShape, Type, Triangle } from "../api"; import { dispatch } from "../internal/dispatch"; +import { classifyPointInTriangle2 } from "../internal/triangle-point-inside"; -export const classifyPoint = defmulti(dispatch); +export const classifyPoint: MultiFn2O = defmulti(dispatch); classifyPoint.addAll({ @@ -12,4 +13,8 @@ classifyPoint.addAll({ ($: Circle, p: ReadonlyVec, eps = EPS) => sign($.r - dist($.pos, p), eps), + [Type.TRIANGLE]: + ({ points }: Triangle, p: ReadonlyVec, eps = EPS) => + classifyPointInTriangle2(p, points[0], points[1], points[2], eps), + }); diff --git a/packages/geom3/src/ops/edges.ts b/packages/geom3/src/ops/edges.ts new file mode 100644 index 0000000000..9d3f1220ef --- /dev/null +++ b/packages/geom3/src/ops/edges.ts @@ -0,0 +1,35 @@ +import { defmulti, MultiFn1O } from "@thi.ng/defmulti"; +import { + IShape, + Polygon, + Polyline, + SamplingOpts, + Type, + VecPair, + Rect +} from "../api"; +import { dispatch } from "../internal/dispatch"; +import { edgeIterator } from "../internal/edges"; +import { vertices } from "./vertices"; + +export const edges: MultiFn1O, Iterable> = defmulti(dispatch); + +edges.addAll({ + + [Type.POLYGON]: + ($: Polygon) => + edgeIterator($.points, true), + + [Type.POLYLINE]: + ($: Polyline) => + edgeIterator($.points), + + [Type.RECT]: + ($: Rect) => + edgeIterator(vertices($), true), + +}); + +edges.isa(Type.LINE, Type.POLYLINE); +edges.isa(Type.QUAD, Type.POLYGON); +edges.isa(Type.TRIANGLE, Type.POLYGON); diff --git a/packages/geom3/src/ops/point-inside.ts b/packages/geom3/src/ops/point-inside.ts index 7f9065b0e1..9522738e51 100644 --- a/packages/geom3/src/ops/point-inside.ts +++ b/packages/geom3/src/ops/point-inside.ts @@ -1,15 +1,19 @@ import { defmulti } from "@thi.ng/defmulti"; -import { distSq, ReadonlyVec } from "@thi.ng/vectors3"; +import { distSq, ReadonlyVec, Vec } from "@thi.ng/vectors3"; import { + AABB, Circle, IShape, - Rect, - Type, + Points, Polygon, - AABB + Rect, + Triangle, + Type } from "../api"; import { dispatch } from "../internal/dispatch"; +import { pointInArray } from "../internal/point-in-array"; import { polyPointInside } from "../internal/poly-point-inside"; +import { pointInTriangle2 } from "../internal/triangle-point-inside"; export const pointInside = defmulti(dispatch); @@ -25,6 +29,10 @@ pointInside.addAll({ ($: Circle, p) => distSq($.pos, p) <= $.r * $.r, + [Type.POINTS]: + ({ points }: Points, p) => + pointInArray(points, p), + [Type.POLYGON]: ($: Polygon, p) => polyPointInside($.points, p) > 0, @@ -34,6 +42,9 @@ pointInside.addAll({ x >= pos[0] && x <= pos[0] + size[0] && y >= pos[1] && y <= pos[1] + size[1], + [Type.TRIANGLE]: + (tri: Triangle, p: ReadonlyVec) => + pointInTriangle2(p, ...<[Vec, Vec, Vec]>tri.points), }); pointInside.isa(Type.SPHERE, Type.CIRCLE); diff --git a/packages/geom3/src/ops/tessellate.ts b/packages/geom3/src/ops/tessellate.ts index 112453f584..07b1a2f797 100644 --- a/packages/geom3/src/ops/tessellate.ts +++ b/packages/geom3/src/ops/tessellate.ts @@ -22,7 +22,7 @@ import { } from "@thi.ng/vectors3"; import { Tessellator } from "../api"; import { centroidRaw } from "../internal/centroid"; -import { pointInTriangle2 } from "../internal/corner"; +import { pointInTriangle2 } from "../internal/triangle-point-inside"; import { polyArea } from "../internal/poly-area"; const snip = ( From cd59f6640466c678399ca29ed37adbc7b908a638 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 18 Jan 2019 18:12:27 +0000 Subject: [PATCH 291/333] perf(geom): use squared dist for classifyPoint() (circle) --- packages/geom3/src/ops/classify-point.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/geom3/src/ops/classify-point.ts b/packages/geom3/src/ops/classify-point.ts index c75ada83e1..d35efcae38 100644 --- a/packages/geom3/src/ops/classify-point.ts +++ b/packages/geom3/src/ops/classify-point.ts @@ -1,6 +1,6 @@ import { defmulti, MultiFn2O } from "@thi.ng/defmulti"; import { EPS, sign } from "@thi.ng/math"; -import { dist, ReadonlyVec } from "@thi.ng/vectors3"; +import { ReadonlyVec, distSq } from "@thi.ng/vectors3"; import { Circle, IShape, Type, Triangle } from "../api"; import { dispatch } from "../internal/dispatch"; import { classifyPointInTriangle2 } from "../internal/triangle-point-inside"; @@ -11,7 +11,7 @@ classifyPoint.addAll({ [Type.CIRCLE]: ($: Circle, p: ReadonlyVec, eps = EPS) => - sign($.r - dist($.pos, p), eps), + sign($.r * $.r - distSq($.pos, p), eps), [Type.TRIANGLE]: ({ points }: Triangle, p: ReadonlyVec, eps = EPS) => From d763621c9864a199ecaae1e193463819c24c52aa Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 18 Jan 2019 18:13:00 +0000 Subject: [PATCH 292/333] feat(geom): add clippedLine(), minor update liangBarsky() --- packages/geom3/src/ctors/line.ts | 18 +++++++++++++- packages/geom3/src/internal/liang-barsky.ts | 27 +++++++++++++++++---- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/packages/geom3/src/ctors/line.ts b/packages/geom3/src/ctors/line.ts index 981fb1c5dd..842fae4f04 100644 --- a/packages/geom3/src/ctors/line.ts +++ b/packages/geom3/src/ctors/line.ts @@ -1,6 +1,12 @@ import { Vec } from "@thi.ng/vectors3"; -import { Attribs, Line } from "../api"; +import { + Attribs, + Line, + Rect, + VecPair +} from "../api"; import { argAttribs } from "../internal/args"; +import { liangBarsky } from "../internal/liang-barsky"; export function line(a: Vec, b: Vec, attribs?: Attribs): Line; export function line(pts: Vec[], attribs?: Attribs): Line; @@ -8,3 +14,13 @@ export function line(...args: any[]) { const attr = argAttribs(args); return new Line(args.length === 1 ? args[0] : args, attr); } + +export const clippedLine = + (l: Line, bounds: VecPair | Rect) => { + const res = bounds instanceof Rect ? + liangBarsky(l.points[0], l.points[1], bounds.pos, bounds.max()) : + liangBarsky(l.points[0], l.points[1], bounds[0], bounds[1]); + if (res) { + return new Line([res[0], res[1]], { ...l.attribs }); + } + }; diff --git a/packages/geom3/src/internal/liang-barsky.ts b/packages/geom3/src/internal/liang-barsky.ts index 0b69ecf34f..f30ffcc3da 100644 --- a/packages/geom3/src/internal/liang-barsky.ts +++ b/packages/geom3/src/internal/liang-barsky.ts @@ -1,10 +1,27 @@ import { EPS } from "@thi.ng/math"; import { Vec } from "@thi.ng/vectors3"; -// https://en.wikipedia.org/wiki/Liang%E2%80%93Barsky_algorithm -// https://github.com/thi-ng/c-thing/blob/master/src/geom/clip/liangbarsky.c - -export const liangBarsky2 = ( +/** + * Performs Liang-Barsky clipping with given line endpoints `la`, `lb` + * and clipping rect defined by top-left `tr` and bottom-right `br` + * points. The optional `ca` and `cb` vectors can be given to store the + * result (clipped points). If omitted creates new vectors. Returns a + * tuple of `[ca, cb, a, b]`, where the latter two values represent the + * normalized distances of the clipped points relative to original given + * line segment. Returns `undefined` iff the line lies completely + * outside the rect. + * + * https://en.wikipedia.org/wiki/Liang%E2%80%93Barsky_algorithm + * https://github.com/thi-ng/c-thing/blob/master/src/geom/clip/liangbarsky.c + * + * @param la + * @param lb + * @param tl + * @param br + * @param ca + * @param cb + */ +export const liangBarsky = ( la: Vec, lb: Vec, tl: Vec, @@ -30,7 +47,7 @@ export const liangBarsky2 = ( } else if (r > a) { a = r; } - } else if (p > 0) { + } else { if (r < a) { return false; } else if (r < b) { From 627e20d490a75a54edf32b4b7ff255293415fe52 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 18 Jan 2019 18:13:32 +0000 Subject: [PATCH 293/333] feat(geom): add transform() impls for Cubic/Quadratic --- packages/geom3/src/ops/transform.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/geom3/src/ops/transform.ts b/packages/geom3/src/ops/transform.ts index f2c1dda00f..605a7df89a 100644 --- a/packages/geom3/src/ops/transform.ts +++ b/packages/geom3/src/ops/transform.ts @@ -12,7 +12,9 @@ import { Polyline, Quad, Triangle, - Type + Type, + Cubic, + Quadratic } from "../api"; import { dispatch } from "../internal/dispatch"; import { transformedPoints, transformPoints } from "../internal/transform-points"; @@ -33,6 +35,8 @@ transform.addAll({ { ...$.attribs } ), + [Type.CUBIC]: tx(Cubic), + [Type.GROUP]: ($: Group, mat) => new Group( @@ -50,6 +54,8 @@ transform.addAll({ [Type.QUAD]: tx(Quad), + [Type.QUADRATIC]: tx(Quadratic), + [Type.TRIANGLE]: tx(Triangle), }); From eaf1a1b01be7e4df43836da3ebc43f983ebff4e6 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 18 Jan 2019 18:15:10 +0000 Subject: [PATCH 294/333] feat(geom): add closestPoint() impls for splines, line, polygons, polyline --- packages/geom3/src/internal/closest-point.ts | 105 ++++++++++++++++++- packages/geom3/src/ops/closest-point.ts | 55 +++++++++- 2 files changed, 151 insertions(+), 9 deletions(-) diff --git a/packages/geom3/src/internal/closest-point.ts b/packages/geom3/src/internal/closest-point.ts index e4c4fd8ffd..15bab6f4e6 100644 --- a/packages/geom3/src/internal/closest-point.ts +++ b/packages/geom3/src/internal/closest-point.ts @@ -1,16 +1,20 @@ +import { Fn } from "@thi.ng/api"; +import { partial } from "@thi.ng/compose"; import { distSq, dot, empty, magSq, + mixCubic, mixN, + mixQuadratic, ReadonlyVec, set, sub, Vec } from "@thi.ng/vectors3"; -export const closestPointRaw = +export const closestPointArray = (p: ReadonlyVec, pts: Vec[]) => { let minD = Infinity; @@ -53,9 +57,9 @@ export const closestPointSegment = const t = closestCoeff(p, a, b); if (t !== undefined && (!insideOnly || t >= 0 && t <= 1)) { out = out || empty(p); - return t <= 0.0 ? + return t <= 0 ? set(out, a) : - t >= 1.0 ? + t >= 1 ? set(out, b) : mixN(out, a, b, t); } @@ -63,7 +67,6 @@ export const closestPointSegment = export const closestPointPolyline = (p: ReadonlyVec, pts: ReadonlyArray, closed = false) => { - const closest = empty(pts[0]); const tmp = empty(closest); const n = pts.length - 1; @@ -100,7 +103,7 @@ export const closestPointPolyline = * @param to */ export const farthestPointSegment = - (a: Vec, b: Vec, points: Vec[], from = 0, to = points.length) => { + (a: ReadonlyVec, b: ReadonlyVec, points: ReadonlyVec[], from = 0, to = points.length) => { let maxD = -1; let maxIdx; const tmp = empty(a); @@ -114,3 +117,95 @@ export const farthestPointSegment = } return [maxIdx, Math.sqrt(maxD)]; }; + +/** + * Performs recursive search for closest point to `p` on cubic curve + * defined by control points `a`,`b`,`c`,`d`. The `res` and `recur` + * params are used to control the recursion behavior. See `closestT`. + * + * @param p + * @param a + * @param b + * @param c + * @param d + * @param res + * @param iter + */ +export const closestPointCubic = ( + p: ReadonlyVec, + a: ReadonlyVec, + b: ReadonlyVec, + c: ReadonlyVec, + d: ReadonlyVec, + res = 8, + iter = 4 +) => { + const fn = partial(mixCubic, [], a, b, c, d); + return fn(closestT(fn, p, res, iter, 0, 1)); +}; + +/** + * Performs recursive search for closest point to `p` on quadratic curve + * defined by control points `a`,`b`,`c`. The `res` and `recur` params + * are used to control the recursion behavior. See `closestT`. + * + * @param p + * @param a + * @param b + * @param c + * @param res + * @param iter + */ +export const closestPointQuadratic = ( + p: ReadonlyVec, + a: ReadonlyVec, + b: ReadonlyVec, + c: ReadonlyVec, + res = 8, + iter = 4 +) => { + const fn = partial(mixQuadratic, [], a, b, c); + return fn(closestT(fn, p, res, iter, 0, 1)); +}; + +/** + * Recursively evaluates function `fn` for `res` uniformly spaced values + * `t` in the closed interval `[start,end]` to compute points on a curve + * and returns the `t` producing the minimum distance to query point + * `p`. At each level of recursion the search interval is increasingly + * centered around the currently best `t`. + * + * @param fn + * @param p + * @param res + * @param iter + * @param start + * @param end + */ +const closestT = ( + fn: Fn, + p: ReadonlyVec, + res: number, + iter: number, + start: number, + end: number +) => { + if (iter <= 0) return (start + end) / 2; + const delta = (end - start) / res; + let minT = start; + let minD = Infinity; + for (let i = 0; i <= res; i++) { + const t = start + i * delta; + const q = fn(t); + const d = distSq(p, q); + if (d < minD) { + minD = d; + minT = t; + } + } + return closestT( + fn, p, res, iter - 1, + Math.max(minT - delta, 0), + Math.min(minT + delta, 1) + ); +}; diff --git a/packages/geom3/src/ops/closest-point.ts b/packages/geom3/src/ops/closest-point.ts index 9d74912009..93d160ac5c 100644 --- a/packages/geom3/src/ops/closest-point.ts +++ b/packages/geom3/src/ops/closest-point.ts @@ -1,13 +1,29 @@ import { defmulti } from "@thi.ng/defmulti"; import { - add2, + add, normalize, ReadonlyVec, - sub2, + sub, Vec } from "@thi.ng/vectors3"; -import { Circle, IShape, Type } from "../api"; +import { + Circle, + Cubic, + IShape, + Line, + PCLike, + Quadratic, + Type +} from "../api"; +import { + closestPointArray, + closestPointCubic, + closestPointPolyline, + closestPointQuadratic, + closestPointSegment +} from "../internal/closest-point"; import { dispatch } from "../internal/dispatch"; +import { vertices } from "./vertices"; export const closestPoint = defmulti(dispatch); @@ -15,7 +31,38 @@ closestPoint.addAll({ [Type.CIRCLE]: ($: Circle, p) => - add2(null, normalize(null, sub2([], p, $.pos), $.r), $.pos), + add(null, normalize(null, sub([], p, $.pos), $.r), $.pos), + + [Type.CUBIC]: + ({ points }: Cubic, p) => + closestPointCubic(p, points[0], points[1], points[2], points[3]), + + [Type.LINE]: + ({ points }: Line, p) => + closestPointSegment(p, points[0], points[1]), + + [Type.POLYGON]: + ($: PCLike, p) => + closestPointArray(p, $.points), + + [Type.POLYGON]: + ($: PCLike, p) => + closestPointPolyline(p, $.points, true), + + [Type.POLYLINE]: + ($: PCLike, p) => + closestPointPolyline(p, $.points), + + [Type.QUADRATIC]: + ({ points }: Quadratic, p) => + closestPointQuadratic(p, points[0], points[1], points[2]), + + [Type.RECT]: + ($, p) => + closestPointPolyline(p, vertices($), true), }); +closestPoint.isa(Type.QUAD, Type.POLYGON); +closestPoint.isa(Type.SPHERE, Type.CIRCLE); +closestPoint.isa(Type.TRIANGLE, Type.POLYGON); \ No newline at end of file From ebc9a981cff06b0963ad1995fa4079c066f13a30 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 18 Jan 2019 18:15:46 +0000 Subject: [PATCH 295/333] feat(geom): add pointAt() impls for Cubic/Quadratic --- packages/geom3/src/ops/point-at.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/geom3/src/ops/point-at.ts b/packages/geom3/src/ops/point-at.ts index 800c6e48b8..1cf22cbd1b 100644 --- a/packages/geom3/src/ops/point-at.ts +++ b/packages/geom3/src/ops/point-at.ts @@ -4,16 +4,20 @@ import { cartesian2, madd2, maddN, + mixCubic, mixN2, + mixQuadratic, Vec } from "@thi.ng/vectors3"; import { Arc, Circle, + Cubic, Ellipse, IShape, Line, Polygon, + Quadratic, Ray, Rect, Type @@ -34,6 +38,10 @@ pointAt.addAll({ ($: Circle, t) => cartesian2(null, [$.r, TAU * t], $.pos), + [Type.CUBIC]: + ({ points }: Cubic, t) => + mixCubic([], points[0], points[1], points[2], points[3], t), + [Type.ELLIPSE]: ($: Ellipse, t) => madd2([], $.pos, cossin(TAU * t), $.r), @@ -50,6 +58,10 @@ pointAt.addAll({ ($: Polygon, t) => new Sampler($.points).pointAt(t), + [Type.QUADRATIC]: + ({ points }: Quadratic, t) => + mixQuadratic([], points[0], points[1], points[2], t), + [Type.RAY]: ($: Ray, t) => maddN([], $.pos, $.dir, t), From 56f6037294a76e19ea1d7334ff2fd6f608b3c77b Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 18 Jan 2019 18:16:21 +0000 Subject: [PATCH 296/333] feat(geom): add flip() impls --- packages/geom3/src/ops/flip.ts | 59 ++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 packages/geom3/src/ops/flip.ts diff --git a/packages/geom3/src/ops/flip.ts b/packages/geom3/src/ops/flip.ts new file mode 100644 index 0000000000..9731cc3338 --- /dev/null +++ b/packages/geom3/src/ops/flip.ts @@ -0,0 +1,59 @@ +import { DEFAULT, defmulti } from "@thi.ng/defmulti"; +import { neg } from "@thi.ng/vectors3"; +import { + Arc, + Group, + IShape, + Path, + PCLike, + Ray, + Type +} from "../api"; +import { dispatch } from "../internal/dispatch"; + +export const flip = defmulti(dispatch); +flip.add(DEFAULT, ($) => $); + +flip.addAll({ + + [Type.ARC]: + ($: Arc) => { + const t = $.start; + $.start = $.end; + $.end = t; + $.cw = !$.cw; + return $; + }, + + [Type.GROUP]: + ($: Group) => { + $.children.forEach(flip); + return $; + }, + + [Type.PATH]: + ($: Path) => { + // TODO + return $; + }, + + [Type.POINTS]: + ($: PCLike) => { + $.points.reverse(); + return $; + }, + + [Type.RAY]: + ($: Ray) => { + $.dir = neg(null, $.dir); + return $; + } +}); + +flip.isa(Type.CUBIC, Type.POINTS); +flip.isa(Type.LINE, Type.POINTS); +flip.isa(Type.POLYGON, Type.POINTS); +flip.isa(Type.POLYLINE, Type.POINTS); +flip.isa(Type.QUAD, Type.POINTS); +flip.isa(Type.QUADRATIC, Type.POINTS); +flip.isa(Type.TRIANGLE, Type.POINTS); From 9a4570bf44ccf01eb61080eede30cea8b0e4827e Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 18 Jan 2019 18:16:53 +0000 Subject: [PATCH 297/333] minor(geom): minor updates --- packages/geom3/src/api.ts | 3 +-- packages/geom3/src/index.ts | 1 + packages/geom3/src/ops/simplify.ts | 4 +++- packages/geom3/src/ops/vertices.ts | 4 ++++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/geom3/src/api.ts b/packages/geom3/src/api.ts index 57f07cbd59..998cbe65f6 100644 --- a/packages/geom3/src/api.ts +++ b/packages/geom3/src/api.ts @@ -184,12 +184,11 @@ export abstract class APC implements } abstract get type(): number | string; + abstract copy(): IShape; *[Symbol.iterator]() { yield* this.points; } - - abstract copy(): IShape; } export class AABB implements diff --git a/packages/geom3/src/index.ts b/packages/geom3/src/index.ts index 806b9cab50..0382eb61b5 100644 --- a/packages/geom3/src/index.ts +++ b/packages/geom3/src/index.ts @@ -30,6 +30,7 @@ export * from "./ops/closest-point"; export * from "./ops/convex-hull"; export * from "./ops/edges"; export * from "./ops/fit-into-bounds"; +export * from "./ops/flip"; export * from "./ops/intersects"; export * from "./ops/map-point"; export * from "./ops/point-at"; diff --git a/packages/geom3/src/ops/simplify.ts b/packages/geom3/src/ops/simplify.ts index 0bb2fbc7bc..1e1d06d5e5 100644 --- a/packages/geom3/src/ops/simplify.ts +++ b/packages/geom3/src/ops/simplify.ts @@ -28,7 +28,9 @@ simplify.addAll({ for (let i = 0; i < n; i++) { const s = orig[i]; if (s.type === SegmentType.LINE || s.type === SegmentType.POLYLINE) { - points = (points || []).concat(vertices(s.geo)); + points = points ? + points.concat(vertices(s.geo)) : + vertices(s.geo); lastP = peek(points); } else if (points) { points.push(lastP); diff --git a/packages/geom3/src/ops/vertices.ts b/packages/geom3/src/ops/vertices.ts index a748b63e7c..94562b30c9 100644 --- a/packages/geom3/src/ops/vertices.ts +++ b/packages/geom3/src/ops/vertices.ts @@ -19,6 +19,7 @@ import { Group, IShape, Path, + Points, Polygon, Polyline, Quadratic, @@ -130,6 +131,9 @@ vertices.addAll({ return verts; }, + [Type.POINTS]: + ($: Points) => $.points, + [Type.POLYGON]: ($: Polygon, opts?) => resamplePoints($.points, opts, true), From 9623b4e9e2fa3610acb6826a5425949bb2910761 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 18 Jan 2019 18:17:14 +0000 Subject: [PATCH 298/333] build(geom): add @thi.ng/compose dependency --- packages/geom3/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/geom3/package.json b/packages/geom3/package.json index 9dda804af2..356cbbf7df 100644 --- a/packages/geom3/package.json +++ b/packages/geom3/package.json @@ -16,7 +16,7 @@ "scripts": { "build": "yarn clean && yarn build:es6 && yarn build:bundle", "build:es6": "tsc --declaration", - "build:bundle": "../../scripts/bundle-module geom3 api checks defmulti equiv errors hiccup hiccup-svg math matrices random transducers vectors3", + "build:bundle": "../../scripts/bundle-module geom3 api checks compose defmulti equiv errors hiccup hiccup-svg math matrices random transducers vectors3", "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", @@ -34,6 +34,7 @@ "dependencies": { "@thi.ng/api": "^4.2.4", "@thi.ng/checks": "^1.5.14", + "@thi.ng/compose": "^0.3.0", "@thi.ng/defmulti": "^0.7.0", "@thi.ng/equiv": "^0.1.15", "@thi.ng/errors": "^0.1.12", From 0451f8f67b7ea9aefd563cef99a8014603c62619 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 18 Jan 2019 18:26:51 +0000 Subject: [PATCH 299/333] docs: update main readme --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7ce484c56c..37c5b93bfd 100644 --- a/README.md +++ b/README.md @@ -143,7 +143,8 @@ packages) in the [examples](./examples) directory. ### Experimental packages (WIP / unreleased) -- [@thi.ng/geom2](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/geom2) +- [@thi.ng/color](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/color) +- [@thi.ng/geom3](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/geom3) - [@thi.ng/matrices](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/matrices) - [@thi.ng/vector-pools](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vector-pools) - [@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3) From 1d754eb94bad3ee9959b5c6cc073f10dbf229835 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 18 Jan 2019 23:43:21 +0000 Subject: [PATCH 300/333] feat(geom): add splitNearPoint(), Sampler.closestT(), internal restructure --- packages/geom3/src/index.ts | 3 + packages/geom3/src/internal/bounds.ts | 115 ++++++++++++++++ packages/geom3/src/internal/closest-point.ts | 32 ++--- packages/geom3/src/internal/coll-bounds.ts | 24 ---- packages/geom3/src/internal/corner.ts | 10 +- .../internal/douglas\342\200\223peucker.ts" | 2 +- .../geom3/src/internal/poly-point-inside.ts | 2 +- packages/geom3/src/internal/sampler.ts | 29 +++- packages/geom3/src/internal/splines.ts | 128 ------------------ packages/geom3/src/internal/split-line.ts | 8 -- packages/geom3/src/internal/split.ts | 81 +++++++++++ packages/geom3/src/ops/as-svg.ts | 2 +- packages/geom3/src/ops/bounds.ts | 9 +- packages/geom3/src/ops/fit-into-bounds.ts | 2 +- packages/geom3/src/ops/simplify.ts | 8 +- packages/geom3/src/ops/split-at.ts | 3 +- packages/geom3/src/ops/split-near.ts | 26 ++++ 17 files changed, 293 insertions(+), 191 deletions(-) delete mode 100644 packages/geom3/src/internal/coll-bounds.ts delete mode 100644 packages/geom3/src/internal/splines.ts delete mode 100644 packages/geom3/src/internal/split-line.ts create mode 100644 packages/geom3/src/internal/split.ts create mode 100644 packages/geom3/src/ops/split-near.ts diff --git a/packages/geom3/src/index.ts b/packages/geom3/src/index.ts index 0382eb61b5..fa5cc2156d 100644 --- a/packages/geom3/src/index.ts +++ b/packages/geom3/src/index.ts @@ -39,6 +39,7 @@ export * from "./ops/resample"; export * from "./ops/scatter"; export * from "./ops/simplify"; export * from "./ops/split-at"; +export * from "./ops/split-near"; export * from "./ops/subdiv-curve"; export * from "./ops/tangent-at"; export * from "./ops/tessellate"; @@ -66,8 +67,10 @@ export * from "./internal/poly-area"; export * from "./internal/poly-centroid"; export * from "./internal/poly-point-inside"; export * from "./internal/sampler"; +export * from "./internal/split"; export * from "./internal/subdiv-curve"; export * from "./internal/sutherland-hodgeman"; +export * from "./internal/tessellate"; export * from "./internal/transform-points"; export * from "./internal/triangle-point-inside"; export * from "./internal/union-bounds"; diff --git a/packages/geom3/src/internal/bounds.ts b/packages/geom3/src/internal/bounds.ts index b161def12c..fa3e198284 100644 --- a/packages/geom3/src/internal/bounds.ts +++ b/packages/geom3/src/internal/bounds.ts @@ -1,5 +1,16 @@ +import { Fn } from "@thi.ng/api"; +import { clamp01, mixCubic as _mixCubic } from "@thi.ng/math"; import { max, min, Vec } from "@thi.ng/vectors3"; +import { + max2, + max3, + min2, + min3, + ReadonlyVec +} from "@thi.ng/vectors3"; import { VecPair } from "../api"; +import { AABBLike, IShape } from "../api"; +import { unionBounds } from "./union-bounds"; /** * Computes the nD bounds of given vectors. `vmin` should be initialized @@ -22,3 +33,107 @@ export const boundsRaw = } return [vmin, vmax]; }; + +/** + * Computes the total bounds for the given shape collection, which + * should either contain only 2D or 3D types. No mixed dimensions are + * allowed! Currently the `bounds` function must be passed in as arg to + * avoid circular module dependencies. + * + * @param shapes + * @param bounds + */ +export const collBounds = + (shapes: IShape[], bounds: Fn) => { + let n = shapes.length - 1; + if (n < 0) return; + let { pos, size } = bounds(shapes[n]); + for (; --n >= 0;) { + const b = bounds(shapes[n]); + [pos, size] = unionBounds(pos, size, b.pos, b.size); + } + return [pos, size]; + }; + +const cubicAxisBounds = + (pa: number, pb: number, pc: number, pd: number) => { + let a = 3 * pd - 9 * pc + 9 * pb - 3 * pa; + let b = 6 * pa - 12 * pb + 6 * pc; + let c = 3 * pb - 3 * pa; + let disc = b * b - 4 * a * c; + let l = pa; + let h = pa; + + const bounds = (t: number) => { + if (t > 0 && t < 1) { + const x = _mixCubic(pa, pb, pc, pd, t); + x < l && (l = x); + x > h && (h = x); + } + }; + + pd < l && (l = pd); + pd > h && (h = pd); + if (disc >= 0) { + disc = Math.sqrt(disc); + a *= 2; + bounds((-b + disc) / a); + bounds((-b - disc) / a); + } + return [l, h]; + }; + +export const cubicBounds2 = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec): VecPair => { + const x = cubicAxisBounds(a[0], b[0], c[0], d[0]); + const y = cubicAxisBounds(a[1], b[1], c[1], d[1]); + return [[x[0], y[0]], [x[1], y[1]]]; + }; + +export const cubicBounds3 = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec): VecPair => { + const x = cubicAxisBounds(a[0], b[0], c[0], d[0]); + const y = cubicAxisBounds(a[1], b[1], c[1], d[1]); + const z = cubicAxisBounds(a[2], b[2], c[2], d[2]); + return [[x[0], y[0], z[0]], [x[1], y[1], z[1]]]; + }; + +const solveQuadratic = + (a: number, b: number, c: number) => { + const t = clamp01((a - b) / (a - 2.0 * b + c)); + const s = 1 - t; + return s * s * a + 2.0 * s * t * b + t * t * c; + }; + +export const quadraticBounds2 = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec): VecPair => { + const mi = min2([], a, c); + const ma = max2([], a, c); + if (b[0] < mi[0] || b[0] > ma[0] || b[1] < mi[1] || b[1] > ma[1]) { + const q = [ + solveQuadratic(a[0], b[0], c[0]), + solveQuadratic(a[1], b[1], c[1]), + ]; + min2(null, mi, q); + max2(null, ma, q); + } + return [mi, ma]; + }; + +export const quadraticBounds3 = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec): VecPair => { + const mi = min3([], a, c); + const ma = max3([], a, c); + if (b[0] < mi[0] || b[0] > ma[0] || + b[1] < mi[1] || b[1] > ma[1] || + b[2] < mi[2] || b[2] > ma[2]) { + const q = [ + solveQuadratic(a[0], b[0], c[0]), + solveQuadratic(a[1], b[1], c[1]), + solveQuadratic(a[2], b[2], c[2]), + ]; + min3(null, mi, q); + max3(null, ma, q); + } + return [mi, ma]; + }; diff --git a/packages/geom3/src/internal/closest-point.ts b/packages/geom3/src/internal/closest-point.ts index 15bab6f4e6..110771bf98 100644 --- a/packages/geom3/src/internal/closest-point.ts +++ b/packages/geom3/src/internal/closest-point.ts @@ -137,11 +137,11 @@ export const closestPointCubic = ( b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, - res = 8, - iter = 4 + res?: number, + iter?: number ) => { const fn = partial(mixCubic, [], a, b, c, d); - return fn(closestT(fn, p, res, iter, 0, 1)); + return fn(findClosestT(fn, p, res, iter, 0, 1)); }; /** @@ -161,19 +161,19 @@ export const closestPointQuadratic = ( a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, - res = 8, - iter = 4 + res?: number, + iter?: number ) => { const fn = partial(mixQuadratic, [], a, b, c); - return fn(closestT(fn, p, res, iter, 0, 1)); + return fn(findClosestT(fn, p, res, iter, 0, 1)); }; /** * Recursively evaluates function `fn` for `res` uniformly spaced values - * `t` in the closed interval `[start,end]` to compute points on a curve - * and returns the `t` producing the minimum distance to query point - * `p`. At each level of recursion the search interval is increasingly - * centered around the currently best `t`. + * `t` in the closed interval `[start,end]` to compute points and + * returns the `t` of the point producing the minimum distance to query + * point `p`. At each level of recursion the search interval is + * increasingly narrowed / centered around the currently best `t`. * * @param fn * @param p @@ -182,13 +182,13 @@ export const closestPointQuadratic = ( * @param start * @param end */ -const closestT = ( +export const findClosestT = ( fn: Fn, p: ReadonlyVec, - res: number, - iter: number, - start: number, - end: number + res = 8, + iter = 4, + start = 0, + end = 1 ) => { if (iter <= 0) return (start + end) / 2; const delta = (end - start) / res; @@ -203,7 +203,7 @@ const closestT = ( minT = t; } } - return closestT( + return findClosestT( fn, p, res, iter - 1, Math.max(minT - delta, 0), Math.min(minT + delta, 1) diff --git a/packages/geom3/src/internal/coll-bounds.ts b/packages/geom3/src/internal/coll-bounds.ts deleted file mode 100644 index 48b4d9590e..0000000000 --- a/packages/geom3/src/internal/coll-bounds.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Fn } from "@thi.ng/api"; -import { AABBLike, IShape } from "../api"; -import { unionBounds } from "./union-bounds"; - -/** - * Computes the total bounds for the given shape collection, which - * should either contain only 2D or 3D types. No mixed dimensions are - * allowed! Currently the `bounds` function must be passed in as arg to - * avoid circular module dependencies. - * - * @param shapes - * @param bounds - */ -export const collBounds = - (shapes: IShape[], bounds: Fn) => { - let n = shapes.length - 1; - if (n < 0) return; - let { pos, size } = bounds(shapes[n]); - for (; --n >= 0;) { - const b = bounds(shapes[n]); - [pos, size] = unionBounds(pos, size, b.pos, b.size); - } - return [pos, size]; - }; diff --git a/packages/geom3/src/internal/corner.ts b/packages/geom3/src/internal/corner.ts index 88f2660317..cfea7cf3d1 100644 --- a/packages/geom3/src/internal/corner.ts +++ b/packages/geom3/src/internal/corner.ts @@ -1,6 +1,14 @@ import { EPS, sign } from "@thi.ng/math"; import { ReadonlyVec, signedArea2 } from "@thi.ng/vectors3"; +/** + * Syntax sugar for `sign(signedArea2(a,b,c))`. + * + * @param a + * @param b + * @param c + * @param eps + */ export const corner = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, eps = EPS) => - sign(signedArea2(a, b, c), eps); \ No newline at end of file + sign(signedArea2(a, b, c), eps); diff --git "a/packages/geom3/src/internal/douglas\342\200\223peucker.ts" "b/packages/geom3/src/internal/douglas\342\200\223peucker.ts" index 4a2636ef6b..3051fc747d 100644 --- "a/packages/geom3/src/internal/douglas\342\200\223peucker.ts" +++ "b/packages/geom3/src/internal/douglas\342\200\223peucker.ts" @@ -5,7 +5,7 @@ import { farthestPointSegment } from "./closest-point"; // https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm -export const douglasPeucker2 = +export const douglasPeucker = (pts: Vec[], eps = 0, closed = false) => { let num = pts.length; diff --git a/packages/geom3/src/internal/poly-point-inside.ts b/packages/geom3/src/internal/poly-point-inside.ts index 9d53190907..d8c0f96f07 100644 --- a/packages/geom3/src/internal/poly-point-inside.ts +++ b/packages/geom3/src/internal/poly-point-inside.ts @@ -9,7 +9,7 @@ export const polyPointInside = return inside; }; -export const polyPointInsidePair = +const polyPointInsidePair = (a: ReadonlyVec, b: ReadonlyVec, px: number, py: number, inside: number) => { if (((a[1] < py && b[1] >= py) || (b[1] < py && a[1] >= py)) && diff --git a/packages/geom3/src/internal/sampler.ts b/packages/geom3/src/internal/sampler.ts index 91be1b6fc8..a7b2fe0220 100644 --- a/packages/geom3/src/internal/sampler.ts +++ b/packages/geom3/src/internal/sampler.ts @@ -8,10 +8,13 @@ import { sub, Vec, eqDelta, - set + set, + distSq } from "@thi.ng/vectors3"; import { DEFAULT_SAMPLES, SamplingOpts, VecPair } from "../api"; import { copyPoints } from "./copy-points"; +import { closestPointSegment, closestCoeff } from "./closest-point"; +import { fit01 } from "@thi.ng/math"; export const resamplePoints = (pts: ReadonlyVec[], opts: number | Partial, closed = false, copy = false) => { @@ -68,6 +71,30 @@ export class Sampler { } } + closestT(p: ReadonlyVec) { + const pts = this.points; + const idx = this.index; + const tmp = []; + const closest = []; + let minD = Infinity; + let minI; + for (let i = 0; i < this.index.length - 1; i++) { + if (closestPointSegment(p, pts[i], pts[i + 1], tmp)) { + const d = distSq(p, tmp); + if (d < minD) { + minD = d; + minI = i; + set(closest, tmp); + } + } + } + return fit01( + closestCoeff(p, pts[minI], pts[minI + 1]), + idx[minI], + idx[minI + 1] + ) / peek(idx); + } + segmentAt(t: number): VecPair { let i = this.indexAt(t); if (i === undefined) { diff --git a/packages/geom3/src/internal/splines.ts b/packages/geom3/src/internal/splines.ts deleted file mode 100644 index 52f69c7e25..0000000000 --- a/packages/geom3/src/internal/splines.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { clamp01, mixCubic } from "@thi.ng/math"; -import { - max2, - max3, - min2, - min3, - mixN, - ReadonlyVec, - set -} from "@thi.ng/vectors3"; -import { VecPair } from "../api"; - -const cubicAxisBounds = - (pa: number, pb: number, pc: number, pd: number) => { - let a = 3 * pd - 9 * pc + 9 * pb - 3 * pa; - let b = 6 * pa - 12 * pb + 6 * pc; - let c = 3 * pb - 3 * pa; - let disc = b * b - 4 * a * c; - let l = pa; - let h = pa; - - const bounds = (t: number) => { - if (t > 0 && t < 1) { - const x = mixCubic(pa, pb, pc, pd, t); - x < l && (l = x); - x > h && (h = x); - } - }; - - pd < l && (l = pd); - pd > h && (h = pd); - if (disc >= 0) { - disc = Math.sqrt(disc); - a *= 2; - bounds((-b + disc) / a); - bounds((-b - disc) / a); - } - return [l, h]; - }; - -export const cubicBounds2 = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec): VecPair => { - const x = cubicAxisBounds(a[0], b[0], c[0], d[0]); - const y = cubicAxisBounds(a[1], b[1], c[1], d[1]); - return [[x[0], y[0]], [x[1], y[1]]]; - }; - -export const cubicBounds3 = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec): VecPair => { - const x = cubicAxisBounds(a[0], b[0], c[0], d[0]); - const y = cubicAxisBounds(a[1], b[1], c[1], d[1]); - const z = cubicAxisBounds(a[2], b[2], c[2], d[2]); - return [[x[0], y[0], z[0]], [x[1], y[1], z[1]]]; - }; - -const solveQuadratic = - (a: number, b: number, c: number) => { - const t = clamp01((a - b) / (a - 2.0 * b + c)); - const s = 1 - t; - return s * s * a + 2.0 * s * t * b + t * t * c; - }; - -export const quadraticBounds2 = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec): VecPair => { - const mi = min2([], a, c); - const ma = max2([], a, c); - if (b[0] < mi[0] || b[0] > ma[0] || b[1] < mi[1] || b[1] > ma[1]) { - const q = [ - solveQuadratic(a[0], b[0], c[0]), - solveQuadratic(a[1], b[1], c[1]), - ]; - min2(null, mi, q); - max2(null, ma, q); - } - return [mi, ma]; - }; - -export const quadraticBounds3 = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec): VecPair => { - const mi = min3([], a, c); - const ma = max3([], a, c); - if (b[0] < mi[0] || b[0] > ma[0] || - b[1] < mi[1] || b[1] > ma[1] || - b[2] < mi[2] || b[2] > ma[2]) { - const q = [ - solveQuadratic(a[0], b[0], c[0]), - solveQuadratic(a[1], b[1], c[1]), - solveQuadratic(a[2], b[2], c[2]), - ]; - min3(null, mi, q); - max3(null, ma, q); - } - return [mi, ma]; - }; - -export const splitCubic = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, t: number) => { - if (t <= 0 || t >= 1) { - const p = t <= 0 ? a : d; - const c1 = [set([], p), set([], p), set([], p), set([], p)]; - const c2 = [set([], a), set([], b), set([], c), set([], d)]; - return t <= 0 ? [c1, c2] : [c2, c1]; - } - const ab = mixN([], a, b, t); - const bc = mixN([], b, c, t); - const cd = mixN([], c, d, t); - const abc = mixN([], ab, bc, t); - const bcd = mixN([], bc, cd, t); - const p = mixN([], abc, bcd, t); - return [ - [set([], a), ab, abc, set([], p)], - [p, bcd, cd, set([], d)] - ]; - }; - -export const splitQuadratic = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, t: number) => { - if (t <= 0 || t >= 1) { - const p = t <= 0 ? a : c; - const c1 = [set([], p), set([], p), set([], p)]; - const c2 = [set([], a), set([], b), set([], c)]; - return t <= 0 ? [c1, c2] : [c2, c1]; - } - const ab = mixN([], a, b, t); - const bc = mixN([], b, c, t); - const p = mixN([], ab, bc, t); - return [[set([], a), ab, p], [p, bc, set([], c)]]; - }; diff --git a/packages/geom3/src/internal/split-line.ts b/packages/geom3/src/internal/split-line.ts deleted file mode 100644 index af7d645778..0000000000 --- a/packages/geom3/src/internal/split-line.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { mixN, set, Vec } from "@thi.ng/vectors3"; -import { VecPair } from "../api"; - -export const splitLine = - (a: Vec, b: Vec, t: number): [VecPair, VecPair] => { - const p = mixN([], a, b, t); - return [[a, p], [set([], p), b]]; - }; diff --git a/packages/geom3/src/internal/split.ts b/packages/geom3/src/internal/split.ts new file mode 100644 index 0000000000..f8bc9940df --- /dev/null +++ b/packages/geom3/src/internal/split.ts @@ -0,0 +1,81 @@ +import { mixN, set, Vec, ReadonlyVec, mixCubic, mixQuadratic } from "@thi.ng/vectors3"; +import { VecPair } from "../api"; +import { partial } from "@thi.ng/compose"; +import { findClosestT } from "./closest-point"; + +export const splitLine = + (a: Vec, b: Vec, t: number): [VecPair, VecPair] => { + const p = mixN([], a, b, t); + return [[a, p], [set([], p), b]]; + }; + +export const splitCubic = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, t: number) => { + if (t <= 0 || t >= 1) { + const p = t <= 0 ? a : d; + const c1 = [set([], p), set([], p), set([], p), set([], p)]; + const c2 = [set([], a), set([], b), set([], c), set([], d)]; + return t <= 0 ? [c1, c2] : [c2, c1]; + } + const ab = mixN([], a, b, t); + const bc = mixN([], b, c, t); + const cd = mixN([], c, d, t); + const abc = mixN([], ab, bc, t); + const bcd = mixN([], bc, cd, t); + const p = mixN([], abc, bcd, t); + return [ + [set([], a), ab, abc, set([], p)], + [p, bcd, cd, set([], d)] + ]; + }; + +export const splitQuadratic = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, t: number) => { + if (t <= 0 || t >= 1) { + const p = t <= 0 ? a : c; + const c1 = [set([], p), set([], p), set([], p)]; + const c2 = [set([], a), set([], b), set([], c)]; + return t <= 0 ? [c1, c2] : [c2, c1]; + } + const ab = mixN([], a, b, t); + const bc = mixN([], b, c, t); + const p = mixN([], ab, bc, t); + return [[set([], a), ab, p], [p, bc, set([], c)]]; + }; + +export const splitCubicNear = ( + p: ReadonlyVec, + a: ReadonlyVec, + b: ReadonlyVec, + c: ReadonlyVec, + d: ReadonlyVec, + res?: number, + iter?: number +) => + splitCubic( + a, b, c, d, + findClosestT( + partial(mixCubic, [], a, b, c, d), + p, + res, + iter + ) + ); + +export const splitQuadraticNear = ( + p: ReadonlyVec, + a: ReadonlyVec, + b: ReadonlyVec, + c: ReadonlyVec, + res?: number, + iter?: number +) => + splitQuadratic( + a, b, c, + findClosestT( + partial(mixQuadratic, [], a, b, c), + p, + res, + iter + ) + ); diff --git a/packages/geom3/src/ops/as-svg.ts b/packages/geom3/src/ops/as-svg.ts index 1dd4f0755c..8b3322bbb0 100644 --- a/packages/geom3/src/ops/as-svg.ts +++ b/packages/geom3/src/ops/as-svg.ts @@ -2,7 +2,7 @@ import { serialize } from "@thi.ng/hiccup"; import { convertTree, ff, svg } from "@thi.ng/hiccup-svg"; import { Attribs, IShape } from "../api"; import { bounds } from "./bounds"; -import { collBounds } from "../internal/coll-bounds"; +import { collBounds } from "../internal/bounds"; export const asSvg = (...args: any[]) => diff --git a/packages/geom3/src/ops/bounds.ts b/packages/geom3/src/ops/bounds.ts index 4bee677add..f6a1072daf 100644 --- a/packages/geom3/src/ops/bounds.ts +++ b/packages/geom3/src/ops/bounds.ts @@ -38,10 +38,13 @@ import { Type } from "../api"; import { rectFromMinMax } from "../ctors/rect"; -import { boundsRaw } from "../internal/bounds"; -import { collBounds } from "../internal/coll-bounds"; +import { + boundsRaw, + collBounds, + cubicBounds2, + quadraticBounds2 +} from "../internal/bounds"; import { dispatch } from "../internal/dispatch"; -import { cubicBounds2, quadraticBounds2 } from "../internal/splines"; export const bounds = defmulti(dispatch); diff --git a/packages/geom3/src/ops/fit-into-bounds.ts b/packages/geom3/src/ops/fit-into-bounds.ts index 68e2668dfc..0b55168cee 100644 --- a/packages/geom3/src/ops/fit-into-bounds.ts +++ b/packages/geom3/src/ops/fit-into-bounds.ts @@ -6,10 +6,10 @@ import { } from "@thi.ng/matrices"; import { div2, neg, ReadonlyVec } from "@thi.ng/vectors3"; import { IShape, Rect } from "../api"; +import { collBounds } from "../internal/bounds"; import { bounds } from "./bounds"; import { center } from "./center"; import { centroid } from "./centroid"; -import { collBounds } from "../internal/coll-bounds"; import { mapPoint } from "./map-point"; import { transform } from "./transform"; import { unmapPoint } from "./unmap-point"; diff --git a/packages/geom3/src/ops/simplify.ts b/packages/geom3/src/ops/simplify.ts index 1e1d06d5e5..26f5ee69a8 100644 --- a/packages/geom3/src/ops/simplify.ts +++ b/packages/geom3/src/ops/simplify.ts @@ -12,7 +12,7 @@ import { } from "../api"; import { dispatch } from "../internal/dispatch"; import { vertices } from "./vertices"; -import { douglasPeucker2 } from "../internal/douglas–peucker"; +import { douglasPeucker } from "../internal/douglas–peucker"; export const simplify = defmulti(dispatch); @@ -35,7 +35,7 @@ simplify.addAll({ } else if (points) { points.push(lastP); res.push({ - geo: new Polyline(douglasPeucker2(points, eps)), + geo: new Polyline(douglasPeucker(points, eps)), type: SegmentType.POLYLINE, }); points = null; @@ -56,14 +56,14 @@ simplify.addAll({ [Type.POLYGON]: (poly: Polygon, eps = 0.1) => new Polygon( - douglasPeucker2(poly.points, eps, true), + douglasPeucker(poly.points, eps, true), { ...poly.attribs } ), [Type.POLYLINE]: (poly: Polyline, eps = 0.1) => new Polyline( - douglasPeucker2(poly.points, eps), + douglasPeucker(poly.points, eps), { ...poly.attribs } ), diff --git a/packages/geom3/src/ops/split-at.ts b/packages/geom3/src/ops/split-at.ts index 37f89e8a5e..a950cdce4f 100644 --- a/packages/geom3/src/ops/split-at.ts +++ b/packages/geom3/src/ops/split-at.ts @@ -13,8 +13,7 @@ import { import { copyPoints } from "../internal/copy-points"; import { dispatch } from "../internal/dispatch"; import { Sampler } from "../internal/sampler"; -import { splitCubic, splitQuadratic } from "../internal/splines"; -import { splitLine } from "../internal/split-line"; +import { splitCubic, splitLine, splitQuadratic } from "../internal/split"; export const splitAt = defmulti(dispatch); diff --git a/packages/geom3/src/ops/split-near.ts b/packages/geom3/src/ops/split-near.ts new file mode 100644 index 0000000000..10a11cd309 --- /dev/null +++ b/packages/geom3/src/ops/split-near.ts @@ -0,0 +1,26 @@ +import { defmulti } from "@thi.ng/defmulti"; +import { ReadonlyVec } from "@thi.ng/vectors3"; +import { + Cubic, + IShape, + Quadratic, + Type +} from "../api"; +import { dispatch } from "../internal/dispatch"; +import { splitCubicNear, splitQuadraticNear } from "../internal/split"; + +export const splitNearPoint = defmulti(dispatch); + +splitNearPoint.addAll({ + + [Type.CUBIC]: + ({ points, attribs }: Cubic, p) => + splitCubicNear(p, points[0], points[1], points[2], points[3]) + .map((pts) => new Cubic(pts, { ...attribs })), + + [Type.QUADRATIC]: + ({ points, attribs }: Quadratic, p) => + splitQuadraticNear(p, points[0], points[1], points[2]) + .map((pts) => new Quadratic(pts, { ...attribs })), + +}); From 499e14b3552299c96e56c3ccc8ae9cff4582f817 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 18 Jan 2019 23:44:05 +0000 Subject: [PATCH 301/333] refactor(geom): add tessellate() multi-fn, move/rename tessellators --- packages/geom3/src/internal/tessellate.ts | 179 +++++++++++++++++++++ packages/geom3/src/ops/tessellate.ts | 185 +--------------------- 2 files changed, 187 insertions(+), 177 deletions(-) create mode 100644 packages/geom3/src/internal/tessellate.ts diff --git a/packages/geom3/src/internal/tessellate.ts b/packages/geom3/src/internal/tessellate.ts new file mode 100644 index 0000000000..50055afe98 --- /dev/null +++ b/packages/geom3/src/internal/tessellate.ts @@ -0,0 +1,179 @@ +import { isFunction } from "@thi.ng/checks"; +import { + comp, + last, + map, + mapcat, + partition, + push, + range, + reducer, + repeat, + scan, + transduce, + tuples, + wrap +} from "@thi.ng/transducers"; +import { + mixN, + ReadonlyVec, + signedArea2, + Vec +} from "@thi.ng/vectors3"; +import { Tessellator } from "../api"; +import { centroidRaw } from "../internal/centroid"; +import { pointInTriangle2 } from "../internal/triangle-point-inside"; +import { polyArea } from "../internal/poly-area"; + +const snip = ( + points: ReadonlyVec[], + u: number, + v: number, + w: number, + n: number, + ids: number[] +) => { + const a = points[ids[u]]; + const b = points[ids[v]]; + const c = points[ids[w]]; + if (signedArea2(a, b, c) > 0) { + for (let i = 0; i < n; i++) { + if (i !== u && i !== v && i !== w) { + if (pointInTriangle2(points[ids[i]], a, b, c)) { + return; + } + } + } + return [a, b, c]; + } +}; + +export const tesselEarCut = + (points: ReadonlyVec[]) => { + const tris: Vec[][] = []; + let n = points.length; + const ids = [ + ...(polyArea(points) > 0 ? + range(n) : + range(n - 1, -1, -1)) + ]; + let count = 2 * n - 1; + let v = n - 1, u, w, t; + while (count > 0 && n > 2) { + u = n <= v ? 0 : v; + v = u + 1; + v = n <= v ? 0 : v; + w = v + 1; + w = n <= w ? 0 : w; + t = snip(points, u, v, w, n, ids); + if (t !== undefined) { + tris.push(t); + ids.splice(v, 1); + n--; + count = 2 * n; + } else { + count--; + } + } + return tris; + }; + +export const tesselTriFan = + (points: ReadonlyVec[]) => { + const c = centroidRaw(points); + return transduce( + comp( + partition(2, 1), + map(([a, b]) => [a, b, c]) + ), + push(), + wrap(points, 1, false, true) + ); + }; + +export const tesselQuadFan = + (points: ReadonlyVec[]) => { + const p = centroidRaw(points); + return transduce( + comp( + partition(3, 1), + map(([a, b, c]) => [mixN([], a, b, 0.5), b, mixN([], b, c, 0.5), p]) + ), + push(), + wrap(points, 1, true, true) + ); + }; + +export const tesselEdgeSplit = + (points: ReadonlyVec[]) => { + const c = centroidRaw(points); + return transduce( + comp( + partition(2, 1), + mapcat(([a, b]) => { + const m = mixN([], a, b, 0.5); + return [[a, m, c], [m, b, c]]; + })), + push(), + wrap(points, 1, false, true) + ); + }; + +export const tesselRimTris = + (points: ReadonlyVec[]) => { + const edgeCentroids = transduce( + comp( + partition(2, 1), + map((e) => mixN([], e[0], e[1], 0.5)) + ), + push(), + wrap(points, 1, false, true) + ); + return transduce( + comp( + partition(2, 1), + map((t) => [t[0][0], t[1][1], t[1][0]]) + ), + push(), + [edgeCentroids], + wrap([...tuples(edgeCentroids, points)], 1, true, false) + ); + }; + +export const tesselInset = + (inset = 0.5, keepInterior = false) => + (points: ReadonlyVec[]) => { + const c = centroidRaw(points); + const inner = points.map((p) => mixN([], p, c, inset)); + return transduce( + comp( + partition(2, 1), + map(([[a, b], [c, d]]) => [a, b, d, c]) + ), + push(), + keepInterior ? [inner] : [], + wrap([...tuples(points, inner)], 1, false, true) + ); + }; + +export function tessellatePoints(points: ReadonlyVec[], tessFn: Tessellator, iter?: number): Vec[][]; +export function tessellatePoints(points: ReadonlyVec[], tessFns: Iterable): Vec[][]; +export function tessellatePoints(...args): Vec[][] { + return transduce( + scan( + reducer( + () => [args[0]], + (acc: Vec[][], fn: Tessellator) => + transduce( + mapcat(fn), + push(), + acc + ) + ) + ), + last(), + isFunction(args[1]) ? + repeat(args[1], args[2] || 1) : + args[1] + ); +} diff --git a/packages/geom3/src/ops/tessellate.ts b/packages/geom3/src/ops/tessellate.ts index 07b1a2f797..d87ac7a27c 100644 --- a/packages/geom3/src/ops/tessellate.ts +++ b/packages/geom3/src/ops/tessellate.ts @@ -1,179 +1,10 @@ -import { isFunction } from "@thi.ng/checks"; -import { - comp, - last, - map, - mapcat, - partition, - push, - range, - reducer, - repeat, - scan, - transduce, - tuples, - wrap -} from "@thi.ng/transducers"; -import { - mixN, - ReadonlyVec, - signedArea2, - Vec -} from "@thi.ng/vectors3"; -import { Tessellator } from "../api"; -import { centroidRaw } from "../internal/centroid"; -import { pointInTriangle2 } from "../internal/triangle-point-inside"; -import { polyArea } from "../internal/poly-area"; +import { DEFAULT, defmulti } from "@thi.ng/defmulti"; +import { Vec } from "@thi.ng/vectors3"; +import { IShape, Tessellator } from "../api"; +import { dispatch } from "../internal/dispatch"; +import { tessellatePoints } from "../internal/tessellate"; +import { vertices } from "./vertices"; -const snip = ( - points: ReadonlyVec[], - u: number, - v: number, - w: number, - n: number, - ids: number[] -) => { - const a = points[ids[u]]; - const b = points[ids[v]]; - const c = points[ids[w]]; - if (signedArea2(a, b, c) > 0) { - for (let i = 0; i < n; i++) { - if (i !== u && i !== v && i !== w) { - if (pointInTriangle2(points[ids[i]], a, b, c)) { - return; - } - } - } - return [a, b, c]; - } -}; +export const tessellate = defmulti(dispatch); -export const earCut = - (points: ReadonlyVec[]) => { - const tris: Vec[][] = []; - let n = points.length; - const ids = [ - ...(polyArea(points) > 0 ? - range(n) : - range(n - 1, -1, -1)) - ]; - let count = 2 * n - 1; - let v = n - 1, u, w, t; - while (count > 0 && n > 2) { - u = n <= v ? 0 : v; - v = u + 1; - v = n <= v ? 0 : v; - w = v + 1; - w = n <= w ? 0 : w; - t = snip(points, u, v, w, n, ids); - if (t !== undefined) { - tris.push(t); - ids.splice(v, 1); - n--; - count = 2 * n; - } else { - count--; - } - } - return tris; - }; - -export const triFan = - (points: ReadonlyVec[]) => { - const c = centroidRaw(points); - return transduce( - comp( - partition(2, 1), - map(([a, b]) => [a, b, c]) - ), - push(), - wrap(points, 1, false, true) - ); - }; - -export const quadFan = - (points: ReadonlyVec[]) => { - const p = centroidRaw(points); - return transduce( - comp( - partition(3, 1), - map(([a, b, c]) => [mixN([], a, b, 0.5), b, mixN([], b, c, 0.5), p]) - ), - push(), - wrap(points, 1, true, true) - ); - }; - -export const edgeSplit = - (points: ReadonlyVec[]) => { - const c = centroidRaw(points); - return transduce( - comp( - partition(2, 1), - mapcat(([a, b]) => { - const m = mixN([], a, b, 0.5); - return [[a, m, c], [m, b, c]]; - })), - push(), - wrap(points, 1, false, true) - ); - }; - -export const rimTris = - (points: ReadonlyVec[]) => { - const edgeCentroids = transduce( - comp( - partition(2, 1), - map((e) => mixN([], e[0], e[1], 0.5)) - ), - push(), - wrap(points, 1, false, true) - ); - return transduce( - comp( - partition(2, 1), - map((t) => [t[0][0], t[1][1], t[1][0]]) - ), - push(), - [edgeCentroids], - wrap([...tuples(edgeCentroids, points)], 1, true, false) - ); - }; - -export const inset = - (inset = 0.5, keepInterior = false) => - (points: ReadonlyVec[]) => { - const c = centroidRaw(points); - const inner = points.map((p) => mixN([], p, c, inset)); - return transduce( - comp( - partition(2, 1), - map(([[a, b], [c, d]]) => [a, b, d, c]) - ), - push(), - keepInterior ? [inner] : [], - wrap([...tuples(points, inner)], 1, false, true) - ); - }; - -export function tessellatePoints(points: ReadonlyVec[], tessFn: Tessellator, iter?: number): Vec[][]; -export function tessellatePoints(points: ReadonlyVec[], tessFns: Iterable): Vec[][]; -export function tessellatePoints(...args): Vec[][] { - return transduce( - scan( - reducer( - () => [args[0]], - (acc: Vec[][], fn: Tessellator) => - transduce( - mapcat(fn), - push(), - acc - ) - ) - ), - last(), - isFunction(args[1]) ? - repeat(args[1], args[2] || 1) : - args[1] - ); -} +tessellate.add(DEFAULT, ($, fns) => tessellatePoints(vertices($), fns)); From 910529dd898a2cbd32a8f1d8ae6684d119142230 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 19 Jan 2019 17:05:59 +0000 Subject: [PATCH 302/333] feat(geom): add splitNearPoint() for line & polyline, update Sampler --- packages/geom3/src/internal/sampler.ts | 4 +++ packages/geom3/src/ops/split-near.ts | 38 +++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/packages/geom3/src/internal/sampler.ts b/packages/geom3/src/internal/sampler.ts index a7b2fe0220..ef377963f0 100644 --- a/packages/geom3/src/internal/sampler.ts +++ b/packages/geom3/src/internal/sampler.ts @@ -128,6 +128,10 @@ export class Sampler { return [head, tail]; } + splitNear(p: ReadonlyVec) { + return this.splitAt(this.closestT(p)); + } + indexAt(t: number) { const pts = this.points; const n = pts.length - 1; diff --git a/packages/geom3/src/ops/split-near.ts b/packages/geom3/src/ops/split-near.ts index 10a11cd309..6fbaeac2e2 100644 --- a/packages/geom3/src/ops/split-near.ts +++ b/packages/geom3/src/ops/split-near.ts @@ -1,14 +1,37 @@ import { defmulti } from "@thi.ng/defmulti"; +import { clamp01 } from "@thi.ng/math"; import { ReadonlyVec } from "@thi.ng/vectors3"; import { Cubic, IShape, + Line, + Polyline, Quadratic, Type } from "../api"; +import { closestCoeff } from "../internal/closest-point"; +import { copyPoints } from "../internal/copy-points"; import { dispatch } from "../internal/dispatch"; -import { splitCubicNear, splitQuadraticNear } from "../internal/split"; +import { Sampler } from "../internal/sampler"; +import { splitCubicNear, splitLine, splitQuadraticNear } from "../internal/split"; +/** + * Similar to `splitAt`, but instead of taking a normalized parametric + * split position, splits the given curve at the closest point to `p`. + * Returns tuple of split shapes of same type as `shape`. + * + * Implemented for: + * + * - Cubic + * - Line + * - Polyline + * - Quadratic + * + * @see splitAt + * + * @param shape + * @param p + */ export const splitNearPoint = defmulti(dispatch); splitNearPoint.addAll({ @@ -18,6 +41,19 @@ splitNearPoint.addAll({ splitCubicNear(p, points[0], points[1], points[2], points[3]) .map((pts) => new Cubic(pts, { ...attribs })), + [Type.LINE]: + ($: Line, p) => { + const t = closestCoeff(p, $.points[0], $.points[1]) || 0; + return splitLine($.points[0], $.points[1], clamp01(t)) + .map((pts) => new Line(pts, { ...$.attribs })); + }, + + [Type.POLYLINE]: + ($: Polyline, p) => + new Sampler($.points) + .splitNear(p) + .map((pts) => new Polyline(copyPoints(pts), { ...$.attribs })), + [Type.QUADRATIC]: ({ points, attribs }: Quadratic, p) => splitQuadraticNear(p, points[0], points[1], points[2]) From 62ec49fe4a7ecf9b43277bf82d4d29968da53b4f Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 19 Jan 2019 17:12:13 +0000 Subject: [PATCH 303/333] fix(geom): update arcFrom2Points() --- packages/geom3/src/ctors/arc.ts | 99 +++++++++++++++++++++------------ 1 file changed, 63 insertions(+), 36 deletions(-) diff --git a/packages/geom3/src/ctors/arc.ts b/packages/geom3/src/ctors/arc.ts index 0834d2a032..4846f8cce6 100644 --- a/packages/geom3/src/ctors/arc.ts +++ b/packages/geom3/src/ctors/arc.ts @@ -1,10 +1,15 @@ import { isNumber } from "@thi.ng/checks"; -import { TAU } from "@thi.ng/math"; +import { EPS, TAU } from "@thi.ng/math"; import { abs2, angleBetween2, + div2, + eqDelta2, mulN2, + neg, + powN2, ReadonlyVec, + sub2, submN2, Vec, X2 @@ -21,49 +26,71 @@ export const arc = ( clockwise = false ) => new Arc(pos, isNumber(r) ? [r, r] : r, axis, start, end, xl, clockwise); +/** + * https://svgwg.org/svg2-draft/implnote.html#ArcConversionEndpointToCenter + * + * Returns undefined if `a` & `b` are equal or any `radii` component is + * zero. + * + * @param a start point + * @param b end point + * @param radii ellipse radii + * @param axisTheta in radians + * @param xl large arc flag + * @param cw clockwise flag + */ export const arcFrom2Points = ( a: ReadonlyVec, b: ReadonlyVec, radii: ReadonlyVec, axisTheta = 0, - large = false, - clockwise = false + xl = false, + cw = false ) => { const r = abs2([], radii); - const co = Math.cos(axisTheta); - const si = Math.sin(axisTheta); - const m = submN2([], a, b, 0.5); - // const m = mulN2(null, sub2([], a, b), 0.5); - const px = co * m[0] + si * m[1]; - const py = -si * m[0] + co * m[1]; - const px2 = px * px; - const py2 = py * py; - - const l = px2 / (r[0] * r[0]) + py2 / (r[1] * r[1]); - l > 1 && mulN2(null, r, Math.sqrt(l)); - - const rx2 = r[0] * r[0]; - const ry2 = r[1] * r[1]; - const rxpy = rx2 * py2; - const rypx = ry2 * px2; - const rad = ((large === clockwise) ? -1 : 1) * - Math.sqrt(Math.max(0, rx2 * ry2 - rxpy - rypx) / (rxpy + rypx)); - - const tx = rad * r[0] / r[1] * py; - const ty = -rad * r[1] / r[0] * px; - const c = [co * tx - si * ty + (a[0] + b[0]) / 2, si * tx + co * ty + (a[1] + b[1]) / 2]; - const d1 = [(px - tx) / r[0], (py - ty) / r[1]]; - const d2 = [(-px - tx) / r[0], (-py - ty) / r[1]]; - - const theta = angleBetween2(X2, d1); - let delta = angleBetween2(d1, d2); - - if (clockwise && delta < 0) { - delta += TAU; - } else if (!clockwise && delta > 0) { - delta -= TAU; + if (eqDelta2(a, b) || r[0] < EPS || r[1] < EPS) { + return; + } + axisTheta %= TAU; + const d = submN2([], a, b, 0.5); + const c = Math.cos(axisTheta); + const s = Math.sin(axisTheta); + // transformed point + const tp = [ + c * d[0] + s * d[1], + -s * d[0] + c * d[1] + ]; + const [tx2, ty2] = powN2([], tp, 2); + // ensure radii + const rc = tx2 / (r[0] * r[0]) + ty2 / (r[1] * r[1]); + rc > 1 && mulN2(r, r, Math.sqrt(rc)); + const [rx, ry] = r; + const rx2 = rx * rx; + const ry2 = ry * ry; + // transformed center + const radicant = Math.max(0, (rx2 * ry2 - rx2 * ty2 - ry2 * tx2) / (rx2 * ty2 + ry2 * tx2)); + const coeff = (xl !== cw ? 1 : -1) * Math.sqrt(radicant); + const tc = [ + coeff * ((rx * tp[1]) / ry), + coeff * (-(ry * tp[0]) / rx) + ]; + // actual center + const center = [ + c * tc[0] - s * tc[1] + (a[0] + b[0]) / 2, + s * tc[0] + c * tc[1] + (a[1] + b[1]) / 2 + ]; + // transformed end points & angles + const ta = div2(null, sub2([], tp, tc), r); + const tb = div2(null, sub2(null, neg([], tp), tc), r); + const start = angleBetween2(X2, ta); + let sweep = angleBetween2(ta, tb); + if (!cw && sweep > 0) { + sweep -= TAU; + } else if (cw && sweep < 0) { + sweep += TAU; } + sweep %= TAU; - return new Arc(c, r, axisTheta, theta, theta + delta, large, clockwise); + return new Arc(center, r, axisTheta, start, start + sweep, xl, cw); }; From 0e5e7768d8a9d172ef74cef19bdfb6474e1b89ae Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 19 Jan 2019 17:14:22 +0000 Subject: [PATCH 304/333] feat(geom): add arcPointAt() helper, refactor Arc, minor other updates --- packages/geom3/src/api.ts | 14 +++++++----- packages/geom3/src/ctors/cubic.ts | 1 + packages/geom3/src/index.ts | 1 + packages/geom3/src/internal/arc-point.ts | 28 ++++++++++++++++++++++++ packages/geom3/src/ops/vertices.ts | 2 +- 5 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 packages/geom3/src/internal/arc-point.ts diff --git a/packages/geom3/src/api.ts b/packages/geom3/src/api.ts index 998cbe65f6..70df05131a 100644 --- a/packages/geom3/src/api.ts +++ b/packages/geom3/src/api.ts @@ -2,17 +2,15 @@ import { ICopy, IObjectOf, IToHiccup } from "@thi.ng/api"; import { isNumber } from "@thi.ng/checks"; import { equiv } from "@thi.ng/equiv"; import { illegalState } from "@thi.ng/errors"; -import { cossin } from "@thi.ng/math"; import { add2, add3, maddN2, - mul2, ReadonlyVec, - rotateZ, set, Vec } from "@thi.ng/vectors3"; +import { arcPointAt, arcPointAtTheta } from "./internal/arc-point"; import { copyPoints } from "./internal/copy-points"; export const enum SegmentType { @@ -279,13 +277,17 @@ export class Arc implements this.cw && o.cw; } + pointAt(t: number, out: Vec = []) { + return arcPointAt(this.pos, this.r, this.axis, this.start, this.end, t, out); + } + pointAtTheta(theta: number, out: Vec = []) { - return add2(null, rotateZ(null, mul2(out, cossin(theta), this.r), this.axis), this.pos); + return arcPointAtTheta(this.pos, this.r, this.axis, theta, out); } toHiccup() { return ["path", this.attribs, [ - ["M", this.pointAtTheta(this.start)], + ["M", this.pointAt(0)], ...this.toHiccupPathSegments() ]]; } @@ -299,7 +301,7 @@ export class Arc implements this.axis, this.xl, this.cw, - this.pointAtTheta(this.end) + this.pointAt(1) ] ]; } diff --git a/packages/geom3/src/ctors/cubic.ts b/packages/geom3/src/ctors/cubic.ts index 53314eaba9..e7041f2443 100644 --- a/packages/geom3/src/ctors/cubic.ts +++ b/packages/geom3/src/ctors/cubic.ts @@ -33,6 +33,7 @@ export const cubicFromArc = return [cubicFromLine(p, q, { ...arc.attribs })]; } + // TODO use mat23 const mapP = (x: number, y: number) => { x *= rx; y *= ry; diff --git a/packages/geom3/src/index.ts b/packages/geom3/src/index.ts index fa5cc2156d..bd89097857 100644 --- a/packages/geom3/src/index.ts +++ b/packages/geom3/src/index.ts @@ -51,6 +51,7 @@ export * from "./ops/vertices"; export * from "./ops/warp-points"; export * from "./ops/with-attribs"; +export * from "./internal/arc-point"; export * from "./internal/bounds"; export * from "./internal/centroid"; export * from "./internal/circumcenter"; diff --git a/packages/geom3/src/internal/arc-point.ts b/packages/geom3/src/internal/arc-point.ts new file mode 100644 index 0000000000..63a7df49e2 --- /dev/null +++ b/packages/geom3/src/internal/arc-point.ts @@ -0,0 +1,28 @@ +import { cossin, fit01 } from "@thi.ng/math"; +import { + add2, + mul2, + ReadonlyVec, + rotateZ, + Vec +} from "@thi.ng/vectors3"; + +export const arcPointAt = ( + pos: ReadonlyVec, + r: ReadonlyVec, + axis: number, + start: number, + end: number, + t: number, + out: Vec = [] +) => + arcPointAtTheta(pos, r, axis, fit01(t, start, end), out); + +export const arcPointAtTheta = ( + pos: ReadonlyVec, + r: ReadonlyVec, + axis: number, + theta: number, + out: Vec = [] +) => + add2(null, rotateZ(null, mul2(out, cossin(theta), r), axis), pos); diff --git a/packages/geom3/src/ops/vertices.ts b/packages/geom3/src/ops/vertices.ts index 94562b30c9..967b54dec0 100644 --- a/packages/geom3/src/ops/vertices.ts +++ b/packages/geom3/src/ops/vertices.ts @@ -51,7 +51,7 @@ vertices.addAll({ delta /= num; opts.last !== false && num++; const pts: Vec[] = new Array(num); - for (let i = 0, j = 0; i < num; i++ , j += 2) { + for (let i = 0; i < num; i++) { pts[i] = arc.pointAtTheta(start + i * delta); } return pts; From 63b3a5d931866562db4ac15925a9010a2a552056 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 19 Jan 2019 17:15:34 +0000 Subject: [PATCH 305/333] feat(geom): update closestPoint(), add support for Arc --- packages/geom3/src/internal/closest-point.ts | 39 +++++++++++----- packages/geom3/src/ops/closest-point.ts | 47 +++++++++++--------- 2 files changed, 55 insertions(+), 31 deletions(-) diff --git a/packages/geom3/src/internal/closest-point.ts b/packages/geom3/src/internal/closest-point.ts index 110771bf98..55b6e149ff 100644 --- a/packages/geom3/src/internal/closest-point.ts +++ b/packages/geom3/src/internal/closest-point.ts @@ -1,5 +1,6 @@ import { Fn } from "@thi.ng/api"; import { partial } from "@thi.ng/compose"; +import { fit01 } from "@thi.ng/math"; import { distSq, dot, @@ -13,6 +14,7 @@ import { sub, Vec } from "@thi.ng/vectors3"; +import { arcPointAtTheta } from "./arc-point"; export const closestPointArray = (p: ReadonlyVec, pts: Vec[]) => { @@ -66,9 +68,8 @@ export const closestPointSegment = }; export const closestPointPolyline = - (p: ReadonlyVec, pts: ReadonlyArray, closed = false) => { - const closest = empty(pts[0]); - const tmp = empty(closest); + (p: ReadonlyVec, pts: ReadonlyArray, closed = false, out: Vec = []) => { + const tmp = []; const n = pts.length - 1; let minD = Infinity, i, j; if (closed) { @@ -83,11 +84,11 @@ export const closestPointPolyline = const d = distSq(p, tmp); if (d < minD) { minD = d; - set(closest, tmp); + set(out, tmp); } } } - return closest; + return out; }; /** @@ -118,6 +119,21 @@ export const farthestPointSegment = return [maxIdx, Math.sqrt(maxD)]; }; +export const closestPointArc = ( + p: ReadonlyVec, + o: ReadonlyVec, + r: ReadonlyVec, + axis: number, + start: number, + end: number, + out: Vec = [], + res?: number, + iter?: number +) => { + const fn = (t: number) => arcPointAtTheta(o, r, axis, fit01(t, start, end), out); + return fn(findClosestT(fn, p, res, iter)); +}; + /** * Performs recursive search for closest point to `p` on cubic curve * defined by control points `a`,`b`,`c`,`d`. The `res` and `recur` @@ -137,11 +153,12 @@ export const closestPointCubic = ( b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, + out: Vec = [], res?: number, iter?: number ) => { - const fn = partial(mixCubic, [], a, b, c, d); - return fn(findClosestT(fn, p, res, iter, 0, 1)); + const fn = partial(mixCubic, out, a, b, c, d); + return fn(findClosestT(fn, p, res, iter)); }; /** @@ -161,11 +178,12 @@ export const closestPointQuadratic = ( a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, + out: Vec = [], res?: number, iter?: number ) => { - const fn = partial(mixQuadratic, [], a, b, c); - return fn(findClosestT(fn, p, res, iter, 0, 1)); + const fn = partial(mixQuadratic, out, a, b, c); + return fn(findClosestT(fn, p, res, iter)); }; /** @@ -196,8 +214,7 @@ export const findClosestT = ( let minD = Infinity; for (let i = 0; i <= res; i++) { const t = start + i * delta; - const q = fn(t); - const d = distSq(p, q); + const d = distSq(p, fn(t)); if (d < minD) { minD = d; minT = t; diff --git a/packages/geom3/src/ops/closest-point.ts b/packages/geom3/src/ops/closest-point.ts index 93d160ac5c..ea75b47d0d 100644 --- a/packages/geom3/src/ops/closest-point.ts +++ b/packages/geom3/src/ops/closest-point.ts @@ -1,12 +1,14 @@ -import { defmulti } from "@thi.ng/defmulti"; +import { defmulti, MultiFn2O } from "@thi.ng/defmulti"; import { add, normalize, ReadonlyVec, + set, sub, Vec } from "@thi.ng/vectors3"; import { + Arc, Circle, Cubic, IShape, @@ -16,6 +18,7 @@ import { Type } from "../api"; import { + closestPointArc, closestPointArray, closestPointCubic, closestPointPolyline, @@ -25,44 +28,48 @@ import { import { dispatch } from "../internal/dispatch"; import { vertices } from "./vertices"; -export const closestPoint = defmulti(dispatch); +export const closestPoint: MultiFn2O = defmulti(dispatch); closestPoint.addAll({ + [Type.ARC]: + ($: Arc, p, out = []) => + closestPointArc(p, $.pos, $.r, $.axis, $.start, $.end, out), + [Type.CIRCLE]: - ($: Circle, p) => - add(null, normalize(null, sub([], p, $.pos), $.r), $.pos), + ($: Circle, p, out = []) => + add(null, normalize(null, sub(out, p, $.pos), $.r), $.pos), [Type.CUBIC]: - ({ points }: Cubic, p) => - closestPointCubic(p, points[0], points[1], points[2], points[3]), + ({ points }: Cubic, p, out = []) => + closestPointCubic(p, points[0], points[1], points[2], points[3], out), [Type.LINE]: - ({ points }: Line, p) => - closestPointSegment(p, points[0], points[1]), + ({ points }: Line, p, out = []) => + closestPointSegment(p, points[0], points[1], out), - [Type.POLYGON]: - ($: PCLike, p) => - closestPointArray(p, $.points), + [Type.POINTS]: + ($: PCLike, p, out) => + set(out, closestPointArray(p, $.points)), [Type.POLYGON]: - ($: PCLike, p) => - closestPointPolyline(p, $.points, true), + ($: PCLike, p, out = []) => + closestPointPolyline(p, $.points, true, out), [Type.POLYLINE]: - ($: PCLike, p) => - closestPointPolyline(p, $.points), + ($: PCLike, p, out = []) => + closestPointPolyline(p, $.points, false, out), [Type.QUADRATIC]: - ({ points }: Quadratic, p) => - closestPointQuadratic(p, points[0], points[1], points[2]), + ({ points }: Quadratic, p, out = []) => + closestPointQuadratic(p, points[0], points[1], points[2], out), [Type.RECT]: - ($, p) => - closestPointPolyline(p, vertices($), true), + ($, p, out = []) => + closestPointPolyline(p, vertices($), true, out), }); closestPoint.isa(Type.QUAD, Type.POLYGON); closestPoint.isa(Type.SPHERE, Type.CIRCLE); -closestPoint.isa(Type.TRIANGLE, Type.POLYGON); \ No newline at end of file +closestPoint.isa(Type.TRIANGLE, Type.POLYGON); From 370f92808f8545ab021dc71715d8bcaf04fc6858 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 19 Jan 2019 17:16:21 +0000 Subject: [PATCH 306/333] fix(hiccup-svg): convert path arc segment axis theta to degrees --- packages/hiccup-svg/src/path.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/hiccup-svg/src/path.ts b/packages/hiccup-svg/src/path.ts index d39ec6e58e..e47588cba5 100644 --- a/packages/hiccup-svg/src/path.ts +++ b/packages/hiccup-svg/src/path.ts @@ -1,6 +1,8 @@ import { PathSegment } from "./api"; import { ff, fpoint, fpoints } from "./format"; +const DEG = 180 / Math.PI; + export const path = (segments: PathSegment[], attribs?: any): any[] => { let res = []; @@ -14,7 +16,7 @@ export const path = // ry ff(seg[2]), // x-axis (theta) - ff(seg[3]), + ff(seg[3] * DEG), // xl seg[4] ? 1 : 0, // clockwise From 46bb8730469384c28010770ae0f01d277cc717be Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 19 Jan 2019 18:31:09 +0000 Subject: [PATCH 307/333] build: remove obsolete geom2 package --- packages/geom2/.npmignore | 13 - packages/geom2/LICENSE | 201 ---- packages/geom2/README.md | 40 - packages/geom2/package.json | 63 -- packages/geom2/src/api.ts | 874 ------------------ packages/geom2/src/arc.ts | 203 ---- packages/geom2/src/bezier.ts | 260 ------ packages/geom2/src/circle.ts | 149 --- packages/geom2/src/container2.ts | 58 -- packages/geom2/src/ellipse.ts | 113 --- packages/geom2/src/group.ts | 30 - packages/geom2/src/index.ts | 19 - packages/geom2/src/internal/arc-length.ts | 14 - packages/geom2/src/internal/arc.ts | 24 - packages/geom2/src/internal/barycentric.ts | 39 - packages/geom2/src/internal/bounds.ts | 39 - packages/geom2/src/internal/centroid.ts | 37 - packages/geom2/src/internal/circumcenter.ts | 43 - packages/geom2/src/internal/closest-point.ts | 116 --- packages/geom2/src/internal/corner.ts | 30 - packages/geom2/src/internal/direction.ts | 19 - .../internal/douglas\342\200\223peucker.ts" | 42 - packages/geom2/src/internal/edges.ts | 12 - packages/geom2/src/internal/graham-scan.ts | 37 - .../geom2/src/internal/greiner-hormann.ts | 305 ------ packages/geom2/src/internal/liang-barsky.ts | 58 -- .../geom2/src/internal/line-intersection.ts | 48 - packages/geom2/src/internal/offset.ts | 52 -- packages/geom2/src/internal/perimeter.ts | 15 - packages/geom2/src/internal/polygon.ts | 20 - packages/geom2/src/internal/sampler.ts | 118 --- packages/geom2/src/internal/subdiv-curve.ts | 69 -- .../geom2/src/internal/sutherland-hodgeman.ts | 44 - packages/geom2/src/internal/transform.ts | 5 - packages/geom2/src/internal/warp.ts | 6 - packages/geom2/src/line.ts | 109 --- packages/geom2/src/path.ts | 538 ----------- packages/geom2/src/polygon.ts | 250 ----- packages/geom2/src/polyline.ts | 131 --- packages/geom2/src/quad.ts | 79 -- packages/geom2/src/ray.ts | 15 - packages/geom2/src/rect.ts | 175 ---- packages/geom2/src/sphere.ts | 61 -- packages/geom2/src/svg.ts | 24 - packages/geom2/src/tessellate.ts | 166 ---- packages/geom2/src/triangle.ts | 103 --- packages/geom2/test/api.ts | 381 -------- packages/geom2/test/circle.ts | 52 -- packages/geom2/test/clip.ts | 39 - packages/geom2/test/tsconfig.json | 11 - packages/geom2/tsconfig.json | 11 - 51 files changed, 5360 deletions(-) delete mode 100644 packages/geom2/.npmignore delete mode 100644 packages/geom2/LICENSE delete mode 100644 packages/geom2/README.md delete mode 100644 packages/geom2/package.json delete mode 100644 packages/geom2/src/api.ts delete mode 100644 packages/geom2/src/arc.ts delete mode 100644 packages/geom2/src/bezier.ts delete mode 100644 packages/geom2/src/circle.ts delete mode 100644 packages/geom2/src/container2.ts delete mode 100644 packages/geom2/src/ellipse.ts delete mode 100644 packages/geom2/src/group.ts delete mode 100644 packages/geom2/src/index.ts delete mode 100644 packages/geom2/src/internal/arc-length.ts delete mode 100644 packages/geom2/src/internal/arc.ts delete mode 100644 packages/geom2/src/internal/barycentric.ts delete mode 100644 packages/geom2/src/internal/bounds.ts delete mode 100644 packages/geom2/src/internal/centroid.ts delete mode 100644 packages/geom2/src/internal/circumcenter.ts delete mode 100644 packages/geom2/src/internal/closest-point.ts delete mode 100644 packages/geom2/src/internal/corner.ts delete mode 100644 packages/geom2/src/internal/direction.ts delete mode 100644 "packages/geom2/src/internal/douglas\342\200\223peucker.ts" delete mode 100644 packages/geom2/src/internal/edges.ts delete mode 100644 packages/geom2/src/internal/graham-scan.ts delete mode 100644 packages/geom2/src/internal/greiner-hormann.ts delete mode 100644 packages/geom2/src/internal/liang-barsky.ts delete mode 100644 packages/geom2/src/internal/line-intersection.ts delete mode 100644 packages/geom2/src/internal/offset.ts delete mode 100644 packages/geom2/src/internal/perimeter.ts delete mode 100644 packages/geom2/src/internal/polygon.ts delete mode 100644 packages/geom2/src/internal/sampler.ts delete mode 100644 packages/geom2/src/internal/subdiv-curve.ts delete mode 100644 packages/geom2/src/internal/sutherland-hodgeman.ts delete mode 100644 packages/geom2/src/internal/transform.ts delete mode 100644 packages/geom2/src/internal/warp.ts delete mode 100644 packages/geom2/src/line.ts delete mode 100644 packages/geom2/src/path.ts delete mode 100644 packages/geom2/src/polygon.ts delete mode 100644 packages/geom2/src/polyline.ts delete mode 100644 packages/geom2/src/quad.ts delete mode 100644 packages/geom2/src/ray.ts delete mode 100644 packages/geom2/src/rect.ts delete mode 100644 packages/geom2/src/sphere.ts delete mode 100644 packages/geom2/src/svg.ts delete mode 100644 packages/geom2/src/tessellate.ts delete mode 100644 packages/geom2/src/triangle.ts delete mode 100644 packages/geom2/test/api.ts delete mode 100644 packages/geom2/test/circle.ts delete mode 100644 packages/geom2/test/clip.ts delete mode 100644 packages/geom2/test/tsconfig.json delete mode 100644 packages/geom2/tsconfig.json diff --git a/packages/geom2/.npmignore b/packages/geom2/.npmignore deleted file mode 100644 index 67d0c55714..0000000000 --- a/packages/geom2/.npmignore +++ /dev/null @@ -1,13 +0,0 @@ -.cache -.meta -.nyc_output -*.gz -*.html -*.tgz -build -coverage -dev -doc -src* -test -tsconfig.json diff --git a/packages/geom2/LICENSE b/packages/geom2/LICENSE deleted file mode 100644 index 8dada3edaf..0000000000 --- a/packages/geom2/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/packages/geom2/README.md b/packages/geom2/README.md deleted file mode 100644 index 6ab103f4d7..0000000000 --- a/packages/geom2/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# @thi.ng/geom2 - -[![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/geom2.svg)](https://www.npmjs.com/package/@thi.ng/geom2) -![npm downloads](https://img.shields.io/npm/dm/@thi.ng/geom2.svg) -[![Twitter Follow](https://img.shields.io/twitter/follow/thing_umbrella.svg?style=flat-square&label=twitter)](https://twitter.com/thing_umbrella) - -This project is part of the -[@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo. - - - - - -## About - -TODO... - -## Installation - -```bash -yarn add @thi.ng/geom2 -``` - -## Dependencies - -- TODO... - -## Usage examples - -```ts -import * as g from "@thi.ng/geom2"; -``` - -## Authors - -- Karsten Schmidt - -## License - -© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/packages/geom2/package.json b/packages/geom2/package.json deleted file mode 100644 index 8f88a41c00..0000000000 --- a/packages/geom2/package.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "name": "@thi.ng/geom2", - "version": "0.0.1", - "description": "TODO", - "module": "./index.js", - "main": "./lib/index.js", - "umd:main": "./lib/index.umd.js", - "typings": "./index.d.ts", - "repository": { - "type": "git", - "url": "https://github.com/thi-ng/umbrella.git" - }, - "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/geom2", - "author": "Karsten Schmidt ", - "license": "Apache-2.0", - "scripts": { - "build": "yarn clean && yarn build:es6 && yarn build:bundle", - "build:es6": "tsc --declaration", - "build:bundle": "../../scripts/bundle-module geom2 api checks defmulti equiv errors hiccup hiccup-svg malloc math matrices transducers vectors3", - "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", - "cover": "yarn test && nyc report --reporter=lcov", - "doc": "typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public" - }, - "devDependencies": { - "@types/mocha": "^5.2.5", - "@types/node": "^10.12.15", - "mocha": "^5.2.0", - "nyc": "^13.1.0", - "typedoc": "^0.14.0", - "typescript": "^3.2.2" - }, - "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/defmulti": "^0.7.0", - "@thi.ng/equiv": "^0.1.15", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/hiccup": "^2.7.2", - "@thi.ng/hiccup-svg": "^2.0.10", - "@thi.ng/malloc": "^0.2.1", - "@thi.ng/math": "^0.2.2", - "@thi.ng/matrices": "^0.0.1", - "@thi.ng/transducers": "^2.3.2", - "@thi.ng/vectors3": "^0.0.1" - }, - "keywords": [ - "ES6", - "typescript" - ], - "publishConfig": { - "access": "public" - }, - "browserslist": [ - "since 2018-07" - ], - "browser": { - "process": false, - "setTimeout": false - }, - "sideEffects": false -} \ No newline at end of file diff --git a/packages/geom2/src/api.ts b/packages/geom2/src/api.ts deleted file mode 100644 index d331dcf99d..0000000000 --- a/packages/geom2/src/api.ts +++ /dev/null @@ -1,874 +0,0 @@ -import { - ICopy, - IEquiv, - IObjectOf, - IToHiccup -} from "@thi.ng/api"; -import { - DEFAULT, - defmulti, - MultiFn1, - MultiFn1O, - MultiFn2O -} from "@thi.ng/defmulti"; -import { equiv } from "@thi.ng/equiv"; -import { cossin } from "@thi.ng/math"; -import { ReadonlyMat } from "@thi.ng/matrices"; -import { - add, - copy, - max, - min, - mixN, - mul, - neg, - perpendicularLeft2, - ReadonlyVec, - rotateZ, - sub, - Vec -} from "@thi.ng/vectors3"; -import { subdivKernel3 } from "./internal/subdiv-curve"; -import { warpPoints } from "./internal/warp"; - -export const enum Type { - AABB = "aabb", - ARC2 = "arc", - CIRCLE = "circle", - CUBIC2 = "cubic", - ELLIPSE = "ellipse", - GROUP = "g", - LINE2 = "line", - LINE3 = "line3", - PATH2 = "path", - POINTS2 = "points", - POINTS3 = "points3", - POLYGON2 = "polygon", - POLYGON3 = "poly3", - POLYLINE2 = "polyline", - QUAD2 = "quad2", - QUAD3 = "quad3", - QUADRATIC2 = "quadratic", - RECT = "rect", - SPHERE = "sphere", - TRIANGLE2 = "triangle", - RAY = "ray" -} - -export const enum ClipMode { - /** - * Shape union (A | B) - */ - UNION = 0, - /** - * Shape difference (B - A) - */ - DIFF_B = 1, - /** - * Shape difference (A - B) - */ - DIFF_A = 2, - /** - * Shape intersection (A & B) - */ - INTERSECTION = 3, -} - -export enum Convexity { - COLINEAR = 0, - CONVEX, - CONCAVE, -} - -export const enum LineIntersectionType { - PARALLEL = 1, - COINCIDENT, - COINCIDENT_NO_INTERSECT, - INTERSECT, - INTERSECT_OUTSIDE, -} - -export const enum SegmentType { - MOVE, - LINE, - POLYLINE, - ARC, - CUBIC, - QUADRATIC, - CLOSE, -} - -export const DEFAULT_SAMPLES = 20; - -const CHAIKIN_FIRST = subdivKernel3([1 / 2, 1 / 2, 0], [0, 3 / 4, 1 / 4]); -const CHAIKIN_MAIN = subdivKernel3([1 / 4, 3 / 4, 0], [0, 3 / 4, 1 / 4]); -const CHAIKIN_LAST = subdivKernel3([1 / 4, 3 / 4, 0], [0, 1 / 2, 1 / 2]); -const CUBIC_MAIN = subdivKernel3([1 / 8, 3 / 4, 1 / 8], [0, 1 / 2, 1 / 2]); - -export const CHAIKIN_CLOSED: SubdivKernel = { - fn: CHAIKIN_MAIN, - size: 3 -}; - -export const CHAIKIN_OPEN: SubdivKernel = { - fn: (pts, i, n) => - i == 0 ? - [pts[0], ...CHAIKIN_FIRST(pts)] : - i === n - 3 ? - [...CHAIKIN_LAST(pts), pts[2]] : - CHAIKIN_MAIN(pts), - size: 3 -}; - -export const CUBIC_CLOSED: SubdivKernel = { - fn: CUBIC_MAIN, - size: 3 -}; - -export interface IShape extends - ICopy, - IEquiv, - IToHiccup { - - readonly type: string; - attribs?: IObjectOf; -} - -export interface IHiccupPathSegment { - toHiccupPathSegments(): any[]; -} - -export interface AABBLike extends IShape { - pos: Vec; - size: Vec; -} - -export interface LineIntersection { - type: LineIntersectionType; - isec?: Vec; - det?: number; - alpha?: number; - beta?: number; -} - -export interface PathSegment { - type: SegmentType; - point?: Vec; - geo?: IShape & IHiccupPathSegment; -} - -export interface SamplingOpts { - /** - * Number of points to sample & return. Defaults to the implementing - * type's `DEFAULT_RES` if neither this nor `theta` option is given - * (see `ArcSamplingOpts`). - */ - num: number; - /** - * Approximate desired distance between sampled result points. If - * given, takes priority over the `num` option, but the latter MIGHT - * be used as part of the sampling process (implementation - * specific). Note: For circles this value is interpreted as arc - * length, not cartesian distance (error will be proportional to the - * given value relative to the circle's radius). - */ - dist: number; - /** - * Currently only used by these types: - * - * - Arc2 - * - Circle2 - * - * Defines the target angle between sampled points. If greater than - * the actual range of the arc, only the two end points will be - * returned at most. This option is used to derive a `num` value and - * takes priority if `num` is given as well. - * - * This option is useful to adapt the sampling based on angular - * resolution, rather than a fixed number of samples. - */ - theta: number; - /** - * If `true`, the shape's end point will be included in the result - * array. The default setting for open geometries is `true`, for - * closed ones `false`. This option has no influence on any internal - * resolution calculation. - * - * For open geometry this option is useful to when re-sampling paths - * of consecutive segments, where the end points of each segment - * coincide with the start points of the next segment. For all but - * the last segment, this option should be `false` and so can be - * used to avoid duplicate vertices in the concatenated result. - * - * When sampling closed shapes, enabling this option will include an - * extra point (start), i.e. if the `num` option was given, results - * in `num+1` points. - */ - last: boolean; -} - -export interface SubdivKernel { - fn: (pts: ReadonlyVec[], i: number, nump: number) => Vec[]; - size: number; -} - -export type Attribs = IObjectOf; - -export type Tessellator = (points: Vec[]) => Vec[][]; - -export type VecPair = [Vec, Vec]; - -const dispatch = (x: IShape) => x.type; -const dispatch2 = (a: IShape, b: IShape) => a.type + "-" + b.type; - -export const arcLength: MultiFn1 = defmulti(dispatch); - -export const area: MultiFn1O = defmulti(dispatch); -area.add(DEFAULT, () => 0); - -export const asCubic = defmulti>(dispatch); - -export const asPolygon: MultiFn1O = defmulti(dispatch); -asPolygon.add(DEFAULT, (x, opts) => - new Polygon2(vertices(x, opts), { ...x.attribs }) -); - -export const asPolyline: MultiFn1O = defmulti(dispatch); -asPolyline.add(DEFAULT, (x, opts) => - new Polyline2(vertices(x, opts), { ...x.attribs }) -); - -export const bounds = defmulti(dispatch); - -export const center: MultiFn1O = defmulti(dispatch); -center.add(DEFAULT, (x, origin?) => { - const delta = neg(null, centroid(x)); - return translate(x, origin ? add(null, delta, origin) : delta); -}); - -export const centroid: MultiFn1O = defmulti(dispatch); - -export const classifyPoint: MultiFn2O = defmulti(dispatch); - -export const closestPoint = defmulti(dispatch); - -export const clipConvex = defmulti(dispatch); - -export const convexHull = defmulti(dispatch); - -export const depth = defmulti(dispatch); -depth.add(DEFAULT, (x) => bounds(x).size[2] || 0); - -export const difference = defmulti(dispatch); - -export const edges: MultiFn1O, Iterable> = defmulti(dispatch); - -export const extrude = defmulti(dispatch); - -export const flip = defmulti(dispatch); - -export const height = defmulti(dispatch); -height.add(DEFAULT, (x) => bounds(x).size[1]); - -export const intersection = defmulti(dispatch); - -// TODO define isec result -export const intersectShape = defmulti(dispatch2); - -export const intersectLine = defmulti(dispatch); - -export const isEmpty = defmulti(dispatch); - -export const mapPoint: MultiFn2O = defmulti(dispatch); - -export const normalAt: MultiFn2O = defmulti(dispatch); -normalAt.add(DEFAULT, (shape, t, n = 1) => perpendicularLeft2(null, tangentAt(shape, t, n))); - -export const offset: MultiFn2O = defmulti(dispatch); - -export const perimeter = defmulti(dispatch); - -export const pointAt = defmulti(dispatch); - -export const pointInside = defmulti(dispatch); - -export const resample: MultiFn1O, IShape> = defmulti(dispatch); - -/** - * Returns new shape of same type with a shallow copy of the original - * geometry (vertex list) simplified using Douglas-Peucker algorithm. - * - * @param shape - * @param eps simplification threshold (default: 0.1) - */ -export const simplify: MultiFn1O = defmulti(dispatch); - -export const splitAt = defmulti(dispatch); - -export const subdivide: MultiFn2O = defmulti(dispatch); - -export const tangentAt: MultiFn2O = defmulti(dispatch); - -export const tessellate = defmulti, Vec[][]>(dispatch); - -export const transform = defmulti(dispatch); - -export const translate = defmulti(dispatch); - -export const union = defmulti(dispatch); - -export const unmapPoint: MultiFn2O = defmulti(dispatch); - -export const vertices: MultiFn1O, Vec[]> = defmulti(dispatch); - -export const warp = defmulti(dispatch); -warp.add(DEFAULT, (src: IShape, dest: IShape) => - new Polygon2( - warpPoints(vertices(src), bounds(src), dest), - { ...src.attribs } - ) -); - -export const width = defmulti(dispatch); -width.add(DEFAULT, (x) => bounds(x).size[0]); - -export const withAttribs = defmulti(dispatch); -withAttribs.add(DEFAULT, (x, attribs) => { - x = x.copy(); - Object.assign(x.attribs, attribs); - return x; -}); - -export class PointContainer implements - IShape { - - readonly type: string; - points: Vec[]; - attribs: Attribs; - - constructor(type: string, points: Vec[], attribs?: Attribs) { - this.type = type; - this.points = points; - this.attribs = attribs; - } - - *[Symbol.iterator]() { - yield* this.points; - } - - copy() { - return new PointContainer(this.type, this._copy(), this.attribs); - } - - equiv(o: any) { - return o instanceof PointContainer && - this.type === o.type && - equiv(this.points, o.points); - } - - flip() { - this.points.reverse(); - return this; - } - - toHiccup() { - return [this.type, this.attribs, this.points]; - } - - protected _copy() { - return this.points.map((p) => copy(p)); - } -} - -export class Arc2 implements - IHiccupPathSegment, - IShape { - - pos: Vec; - r: Vec; - axis: number; - start: number; - end: number; - xl: boolean; - clockwise: boolean; - attribs: Attribs; - - constructor( - pos: Vec, - r: Vec, - axis: number, - start: number, - end: number, - xl = false, - clockwise = false, - attribs?: Attribs) { - - this.pos = pos; - this.r = r; - this.axis = axis; - this.start = start; - this.end = end; - this.xl = xl; - this.clockwise = clockwise; - this.attribs = attribs; - } - - get type() { - return Type.ARC2; - } - - copy() { - return new Arc2( - copy(this.pos), - copy(this.r), - this.axis, - this.start, - this.end, - this.xl, - this.clockwise, - { ...this.attribs } - ); - } - - equiv(o: any) { - return o instanceof Arc2 && - equiv(this.pos, o.pos) && - equiv(this.r, o.r) && - this.start === o.start && - this.end === o.end && - this.axis === o.axis && - this.xl === o.xl && - this.clockwise && o.clockwise; - } - - pointAtTheta(theta: number, pos: Vec = []) { - return add(null, rotateZ(null, mul(pos, cossin(theta), this.r), this.axis), this.pos); - } - - toHiccup() { - return ["path", this.attribs, [ - ["M", this.pointAtTheta(this.start)], - ...this.toHiccupPathSegments() - ]]; - } - - toHiccupPathSegments() { - return [["A", - this.r[0], - this.r[1], - this.axis, - this.xl, - this.clockwise, - this.pointAtTheta(this.end) - ]]; - } -} - -export class Circle2 implements - IShape { - - pos: Vec; - r: number; - attribs: Attribs; - - constructor(pos: Vec, r: number, attribs?: Attribs) { - this.pos = pos; - this.r = r; - this.attribs = attribs; - } - - get type() { - return Type.CIRCLE; - } - - copy() { - return new Circle2(copy(this.pos), this.r, { ...this.attribs }); - } - - equiv(o: any) { - return o instanceof Circle2 && - equiv(this.pos, o.pos) && - this.r === o.r; - } - - toHiccup() { - return [this.type, this.attribs, this.pos, this.r]; - } -} - -export class Cubic2 extends PointContainer implements - IHiccupPathSegment { - - static fromLine(a: Vec, b: Vec, attribs?: Attribs) { - return new Cubic2([a, mixN([], a, b, 1 / 3), mixN([], b, a, 1 / 3), b], attribs); - } - - constructor(points: Vec[], attribs?: Attribs) { - super(Type.CUBIC2, points, attribs); - } - - copy() { - return new Cubic2(this._copy(), { ...this.attribs }); - } - - toHiccup() { - return ["path", this.attribs, - [ - ["M", this.points[0]], - ...this.toHiccupPathSegments() - ] - ]; - } - - toHiccupPathSegments() { - const pts = this.points; - return [["C", pts[1], pts[2], pts[3]]]; - } -} - -export class Ellipse2 implements - IShape { - - pos: Vec; - r: Vec; - attribs: Attribs; - - constructor(pos: Vec, r: Vec, attribs?: Attribs) { - this.pos = pos; - this.r = r; - this.attribs = attribs; - } - - get type() { - return Type.ELLIPSE; - } - - copy() { - return new Ellipse2(copy(this.pos), copy(this.r), { ...this.attribs }); - } - - equiv(o: any) { - return o instanceof Ellipse2 && - equiv(this.pos, o.pos) && - equiv(this.r, o.r); - } - - toHiccup() { - return [this.type, this.attribs, this.pos, this.r]; - } -} - -export class Group2 implements - IShape { - - children: IShape[]; - attribs: Attribs; - - constructor(attribs?: Attribs, ...children: IShape[]) { - this.attribs = attribs; - this.children = children; - } - - get type() { - return Type.GROUP; - } - - *[Symbol.iterator]() { - yield* this.children; - } - - copy() { - return new Group2( - { ...this.attribs }, - ...this.children.map((c) => c.copy()) - ); - } - - equiv(o: any) { - return o instanceof Group2 && - equiv(this.children, o.children); - } - - toHiccup() { - return [ - this.type, - this.attribs, - ...this.children.map((x) => x.toHiccup()) - ]; - } -} - -export class Line2 extends PointContainer implements - IHiccupPathSegment { - - constructor(points: Vec[], attribs?: Attribs) { - super(Type.LINE2, points, attribs); - } - - get a() { - return this.points[0]; - } - - get b() { - return this.points[1]; - } - - copy() { - return new Line2(this._copy(), { ...this.attribs }); - } - - toHiccupPathSegments() { - const [a, b] = this.points; - return [ - a[0] === b[0] ? - ["V", b[1]] : - a[1] === b[1] ? - ["H", b[0]] : - ["L", b] - ]; - } -} - -export class Path2 implements IShape { - - segments: PathSegment[]; - closed: boolean; - attribs: Attribs; - - constructor(segments?: PathSegment[], attribs?: Attribs) { - this.segments = segments || []; - this.attribs = attribs; - this.closed = false; - } - - get type() { - return Type.PATH2; - } - - *[Symbol.iterator]() { - yield* this.segments; - } - - copy() { - const p = new Path2([...this.segments], { ...this.attribs }); - p.closed = this.closed; - return p; - } - - equiv(o: any) { - return o instanceof Path2 && - equiv(this.segments, o.segments); - } - - add(s: PathSegment) { - this.segments.push(s); - } - - toHiccup() { - const dest: any[] = []; - const res: any[] = ["path", this.attribs || {}, dest]; - const src = this.segments; - const n = src.length; - if (n > 1) { - dest.push(["M", src[0].point]); - for (let i = 1; i < n; i++) { - dest.push(...src[i].geo.toHiccupPathSegments()); - } - if (this.closed) { - dest.push(["Z"]); - } - } - return res; - } -} - -export class Polygon2 extends PointContainer { - - constructor(points: Vec[], attribs?: Attribs) { - super(Type.POLYGON2, points, attribs); - } - - copy() { - return new Polygon2(this._copy(), { ...this.attribs }); - } -} - -export class Polyline2 extends PointContainer implements - IHiccupPathSegment { - - constructor(points: Vec[], attribs?: Attribs) { - super(Type.POLYLINE2, points, attribs); - } - - copy() { - return new Polyline2(this._copy(), { ...this.attribs }); - } - - toHiccupPathSegments() { - const res: any[] = []; - for (let pts = this.points, n = pts.length, i = 1; i < n; i++) { - res.push(["L", pts[i]]); - } - return res; - } -} - -export class Quad2 extends PointContainer { - - constructor(points: Vec[], attribs?: Attribs) { - super(Type.QUAD2, points, attribs); - } - - copy() { - return new Quad2(this._copy(), { ...this.attribs }); - } - - toHiccup() { - return [Type.POLYGON2, this.attribs, this.points]; - } -} - -export class Quadratic2 extends PointContainer implements - IHiccupPathSegment { - - static fromLine(a: Vec, b: Vec, attribs?: Attribs) { - return new Quadratic2([a, mixN([], a, b, 0.5), b], attribs); - } - - constructor(points: Vec[], attribs?: Attribs) { - super(Type.QUADRATIC2, points, attribs); - } - - copy() { - return new Quadratic2(this._copy(), { ...this.attribs }); - } - - toHiccup() { - return ["path", this.attribs, - [ - ["M", this.points[0]], - ...this.toHiccupPathSegments() - ] - ]; - } - - toHiccupPathSegments() { - const pts = this.points; - return [["Q", pts[1], pts[2]]]; - } -} - -export class Ray implements IShape { - - pos: Vec; - dir: Vec; - - constructor(pos: Vec, dir: Vec) { - this.pos = pos; - this.dir = dir; - } - - get type() { - return Type.RAY; - } - - copy() { - return new Ray(copy(this.pos), copy(this.dir)); - } - - equiv(o: any) { - return o instanceof Ray && - equiv(this.pos, o.pos) && - equiv(this.dir, o.dir); - } - - toHiccup() { - return ""; - } -} - -export class Rect2 implements - AABBLike, - IShape { - - static fromMinMax(mi: Vec, mx: Vec, attribs?: Attribs) { - const _mi = min([], mi, mx); - const _mx = max([], mx, mi); - return new Rect2(_mi, sub(null, _mx, _mi), attribs); - } - - pos: Vec; - size: Vec; - attribs: Attribs; - - constructor(pos: Vec, size: Vec, attribs?: Attribs) { - this.pos = pos; - this.size = size; - this.attribs = attribs; - } - - get type() { - return Type.RECT; - } - - copy() { - return new Rect2(copy(this.pos), copy(this.size), { ...this.attribs }); - } - - equiv(o: any) { - return o instanceof Rect2 && - equiv(this.pos, o.pos) && - equiv(this.size, o.size); - } - - toHiccup() { - return [this.type, this.attribs, this.pos, this.size]; - } -} - -export class Sphere implements - IShape { - - pos: Vec; - r: number; - attribs: Attribs; - - constructor(pos: Vec, r: number, attribs?: Attribs) { - this.pos = pos; - this.r = r; - this.attribs = attribs; - } - - get type() { - return Type.SPHERE; - } - - copy() { - return new Sphere(copy(this.pos), this.r, { ...this.attribs }); - } - - equiv(o: any) { - return o instanceof Sphere && - equiv(this.pos, o.pos) && - this.r === o.r; - } - - toHiccup() { - return ""; - } -} - -export class Triangle2 extends PointContainer { - - constructor(points: Vec[], attribs?: Attribs) { - super(Type.TRIANGLE2, points, attribs); - } - - copy() { - return new Triangle2(this._copy(), { ...this.attribs }); - } - - toHiccup() { - return [Type.POLYGON2, this.attribs, this.points]; - } -} diff --git a/packages/geom2/src/arc.ts b/packages/geom2/src/arc.ts deleted file mode 100644 index 53df122f67..0000000000 --- a/packages/geom2/src/arc.ts +++ /dev/null @@ -1,203 +0,0 @@ -import { isNumber, isPlainObject } from "@thi.ng/checks"; -import { implementations } from "@thi.ng/defmulti"; -import { - EPS, - fit01, - HALF_PI, - inRange, - PI, - roundEps, - sincos, - TAU -} from "@thi.ng/math"; -import { - filter, - map, - push, - range, - transduce -} from "@thi.ng/transducers"; -import { - abs2, - add2, - angleBetween, - magSq2, - MAX2, - MIN2, - mulN2, - ReadonlyVec, - sub2, - Vec, - X2 -} from "@thi.ng/vectors3"; -import "./bezier"; -import { bounds as _bounds } from "./internal/bounds"; -import { Sampler } from "./internal/sampler"; -import { } from "@thi.ng/math"; -import { } from "@thi.ng/vectors3"; -import { - Arc2, - asCubic, - Attribs, - bounds, - centroid, - Cubic2, - DEFAULT_SAMPLES, - pointAt, - Rect2, - SamplingOpts, - Type, - vertices, -} from "./api"; - -export function arc(pos: Vec, r: Vec, axis: number, start: number, end: number, xl: boolean, clockwise: boolean, attribs?: Attribs): Arc2 { - return new Arc2(pos, r, axis, start, end, xl, clockwise, attribs); -} - -export function arcFrom2Points( - a: ReadonlyVec, - b: ReadonlyVec, - radii: ReadonlyVec, - axisTheta = 0, - large = false, - clockwise = true) { - - const r = abs2([], radii); - const co = Math.cos(axisTheta); - const si = Math.sin(axisTheta); - const m = mulN2(null, sub2([], a, b), 0.5); - const px = co * m[0] + si * m[1]; - const py = -si * m[0] + co * m[1]; - const px2 = px * px; - const py2 = py * py; - - const l = px2 / (r[0] * r[0]) + py2 / (r[1] * r[1]); - l > 1 && mulN2(null, r, Math.sqrt(l)); - - const rx2 = r[0] * r[0]; - const ry2 = r[1] * r[1]; - const rxpy = rx2 * py2; - const rypx = ry2 * px2; - const rad = ((large === clockwise) ? -1 : 1) * - Math.sqrt(Math.max(0, rx2 * ry2 - rxpy - rypx) / (rxpy + rypx)); - - const tc = [rad * r[0] / r[1] * py, rad * -r[1] / r[0] * px]; - const c = [co * tc[0] - si * tc[1] + (a[0] + b[0]) / 2, si * tc[0] + co * tc[1] + (a[1] + b[1]) / 2]; - const d1 = [(px - tc[0]) / r[0], (py - tc[1]) / r[1]]; - const d2 = [(-px - tc[0]) / r[0], (-py - tc[1]) / r[1]]; - - const theta = angleBetween(X2, d1, true); - let delta = angleBetween(d1, d2, true); - - if (clockwise && delta < 0) { - delta += TAU; - } else if (!clockwise && delta > 0) { - delta -= TAU; - } - - return new Arc2(c, r, axisTheta, theta, theta + delta, large, clockwise); -}; - -implementations( - Type.ARC2, - - null, - - asCubic, - (arc: Arc2) => { - const p = arc.pointAtTheta(arc.start); - const q = arc.pointAtTheta(arc.end); - const [rx, ry] = arc.r; - const [sphi, cphi] = sincos(arc.axis); - const dx = cphi * (p[0] - q[0]) / 2 + sphi * (p[1] - q[1]) / 2; - const dy = -sphi * (p[0] - q[0]) / 2 + cphi * (p[1] - q[1]) / 2; - if ((dx === 0 && dy === 0) || magSq2(arc.r) < EPS) { - return [Cubic2.fromLine(p, q, { ...arc.attribs })]; - } - - const mapP = (x: number, y: number) => { - x *= rx; - y *= ry; - return add2( - null, - [ - cphi * x - sphi * y, - sphi * x + cphi * y - ], - arc.pos - ); - }; - - const res: Cubic2[] = []; - const delta = arc.end - arc.start; - const n = Math.max(roundEps(Math.abs(delta) / HALF_PI), 1); - // https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/svg/svg_path_parser.cc#L253 - const d = delta / n; - const t = 8 / 6 * Math.tan(0.25 * d); - if (!isFinite(t)) { - return [Cubic2.fromLine(p, q)]; - } - for (let i = n, theta = arc.start; i > 0; i-- , theta += d) { - const [s1, c1] = sincos(theta); - const [s2, c2] = sincos(theta + d); - const curve = new Cubic2( - [ - mapP(c1, s1), - mapP(c1 - s1 * t, s1 + c1 * t), - mapP(c2 + s2 * t, s2 - c2 * t), - mapP(c2, s2), - ], - { ...arc.attribs } - ); - res.push(curve); - } - return res; - }, - - bounds, - (arc: Arc2) => { - const pts = transduce( - map(arc.pointAtTheta.bind(arc)), - push(), - [ - arc.start, - arc.end, - // multiples of HALF_PI in arc range - ...filter( - (t: number) => inRange(t, arc.start, arc.end), - range(-3 * PI, 3.01 * PI, HALF_PI) - ) - ] - ); - return Rect2.fromMinMax(..._bounds(pts, [...MAX2], [...MIN2])); - }, - - centroid, - (arc: Arc2) => arc.pos, - - pointAt, - (arc: Arc2, t: number) => arc.pointAtTheta(fit01(t, arc.start, arc.end)), - - vertices, - (arc: Arc2, opts?: number | Partial): Vec[] => { - if (isPlainObject(opts) && (opts).dist !== undefined) { - return new Sampler(vertices(arc, (opts).num || DEFAULT_SAMPLES)) - .sampleUniform((opts).dist, (opts).last !== false); - } - opts = isNumber(opts) ? - { num: opts, last: true } : - { num: DEFAULT_SAMPLES, ...opts }; - const start = arc.start; - let delta = arc.end - start; - let num = opts.theta ? - Math.round(delta / opts.theta) : - opts.num; - delta /= num; - opts.last !== false && num++; - const pts: Vec[] = new Array(num); - for (let i = 0, j = 0; i < num; i++ , j += 2) { - pts[i] = arc.pointAtTheta(start + i * delta); - } - return pts; - } -); diff --git a/packages/geom2/src/bezier.ts b/packages/geom2/src/bezier.ts deleted file mode 100644 index 726c972db8..0000000000 --- a/packages/geom2/src/bezier.ts +++ /dev/null @@ -1,260 +0,0 @@ -import { isNumber, isPlainObject } from "@thi.ng/checks"; -import { implementations } from "@thi.ng/defmulti"; -import { clamp01, mixCubic as _mixC, mixQuadratic as _mixQ } from "@thi.ng/math"; -import { Mat } from "@thi.ng/matrices"; -import { - copy, - max, - min, - mixCubic, - mixN, - mixQuadratic, - Vec -} from "@thi.ng/vectors3"; -import { - asCubic, - asPolyline, - Attribs, - bounds, - Cubic2, - DEFAULT_SAMPLES, - flip, - pointAt, - Polyline2, - Quadratic2, - Rect2, - SamplingOpts, - splitAt, - transform, - Type, - vertices -} from "./api"; -import { Sampler } from "./internal/sampler"; -import { transformPoints } from "./internal/transform"; - -export function cubic2(points: Vec[], attribs?: Attribs): Cubic2 { - return new Cubic2(points, attribs); -} - -export function quadratic2(points: Vec[], attribs?: Attribs): Quadratic2 { - return new Quadratic2(points, attribs); -} - -const cubicAxisBounds = (pa: number, pb: number, pc: number, pd: number) => { - let a = 3 * pd - 9 * pc + 9 * pb - 3 * pa; - let b = 6 * pa - 12 * pb + 6 * pc; - let c = 3 * pb - 3 * pa; - let disc = b * b - 4 * a * c; - let l = pa; - let h = pa; - - const bounds = (t: number) => { - if (t > 0 && t < 1) { - const x = _mixC(pa, pb, pc, pd, t); - x < l && (l = x); - x > h && (h = x); - } - }; - - pd < l && (l = pd); - pd > h && (h = pd); - if (disc >= 0) { - disc = Math.sqrt(disc); - a *= 2; - bounds((-b + disc) / a); - bounds((-b - disc) / a); - } - return [l, h]; -}; - -implementations( - Type.CUBIC2, - - { - [Type.POINTS2]: [ - flip, - ] - }, - - asCubic, - (curve: Cubic2) => [curve], - - asPolyline, - (curve: Cubic2, opts?: number | Partial) => - new Polyline2(vertices(curve, opts), { ...curve.attribs }), - - bounds, - (curve: Cubic2) => { - const [a, b, c, d] = curve.points; - const x = cubicAxisBounds(a[0], b[0], c[0], d[0]); - const y = cubicAxisBounds(a[1], b[1], c[1], d[1]); - return Rect2.fromMinMax([x[0], y[0]], [x[1], y[1]]); - }, - - pointAt, - (curve: Cubic2, t: number) => { - const pts = curve.points; - return mixCubic([], pts[0], pts[1], pts[2], pts[3], t); - }, - - splitAt, - (curve: Cubic2, t: number) => { - const [a, b, c, d] = curve.points; - if (t <= 0 || t >= 1) { - const p = t <= 0 ? a : d; - const c1 = new Cubic2([copy(p), copy(p), copy(p), copy(p)]); - const c2 = new Cubic2([copy(a), copy(b), copy(c), copy(d)]); - return t <= 0 ? [c1, c2] : [c2, c1]; - } - const ab = mixN([], a, b, t); - const bc = mixN([], b, c, t); - const cd = mixN([], c, d, t); - const abc = mixN([], ab, bc, t); - const bcd = mixN([], bc, cd, t); - const p = mixN([], abc, bcd, t); - return [ - new Cubic2([[a[0], a[1]], [ab[0], ab[1]], [abc[0], abc[1]], [p[0], p[1]]]), - new Cubic2([[p[0], p[1]], [bcd[0], bcd[1]], [cd[0], cd[1]], [d[0], d[1]]]) - ]; - }, - - transform, - (curve: Cubic2, mat: Mat) => - new Cubic2( - transformPoints(curve.points, mat), - { ...curve.attribs } - ), - - vertices, - (curve: Cubic2, opts?: number | Partial) => { - if (isPlainObject(opts) && (opts).dist !== undefined) { - return new Sampler(vertices(curve, (opts).num || DEFAULT_SAMPLES)) - .sampleUniform((opts).dist, (opts).last !== false); - } - opts = isNumber(opts) ? - { - num: opts, - last: true - } : - { - num: DEFAULT_SAMPLES, - ...opts - }; - const res: Vec[] = []; - const [a, b, c, d] = curve.points; - const delta = 1 / opts.num; - for (let t = 0; t < opts.num; t++) { - res.push(mixCubic([], a, b, c, d, t * delta)); - } - opts.last && res.push([d[0], d[1]]); - return res; - } -); - -implementations( - Type.QUADRATIC2, - - { - [Type.POINTS2]: [ - flip, - ] - }, - - asCubic, - (curve: Quadratic2) => { - const [a, b, c] = curve.points; - return [ - new Cubic2( - [ - copy(a), - mixN([], a, b, 2 / 3), - mixN([], c, b, 2 / 3), - copy(c) - ], - { ...curve.attribs } - ) - ]; - }, - - asPolyline, - (curve: Quadratic2, opts?: number | Partial) => - new Polyline2(vertices(curve, opts), { ...curve.attribs }), - - bounds, - (curve: Quadratic2) => { - const [a, b, c] = curve.points; - const mi = min([], a, c); - const ma = max([], a, c); - const solve = (a, b, c) => { - const t = clamp01((a - b) / (a - 2.0 * b + c)); - const s = 1 - t; - return s * s * a + 2.0 * s * t * b + t * t * c; - }; - if (b[0] < mi[0] || b[0] > ma[0] || b[1] < mi[1] || b[1] > ma[1]) { - const q = [ - solve(a[0], b[0], c[0]), - solve(a[1], b[1], c[1]), - ]; - min(null, mi, q); - max(null, ma, q); - } - return Rect2.fromMinMax(mi, ma); - }, - - pointAt, - (curve: Quadratic2, t: number) => { - const pts = curve.points; - return mixQuadratic([], pts[0], pts[1], pts[2], t); - }, - - splitAt, - (curve: Quadratic2, t: number) => { - const [a, b, c] = curve.points; - if (t <= 0 || t >= 1) { - const p = t <= 0 ? a : c; - const c1 = new Quadratic2([copy(p), copy(p), copy(p), copy(p)]); - const c2 = new Quadratic2([copy(a), copy(b), copy(c)]); - return t <= 0 ? [c1, c2] : [c2, c1]; - } - const ab = mixN([], a, b, t); - const bc = mixN([], b, c, t); - const p = mixN([], ab, bc, t); - return [ - new Quadratic2([copy(a), ab, p]), - new Quadratic2([p, bc, copy(c)]) - ]; - }, - - transform, - (curve: Quadratic2, mat: Mat) => - new Quadratic2( - transformPoints(curve.points, mat), - { ...curve.attribs } - ), - - vertices, - (curve: Quadratic2, opts?: number | Partial) => { - if (isPlainObject(opts) && (opts).dist !== undefined) { - return new Sampler(vertices(curve, (opts).num || DEFAULT_SAMPLES)) - .sampleUniform((opts).dist, (opts).last !== false); - } - opts = isNumber(opts) ? - { - num: opts, - last: true - } : - { - num: DEFAULT_SAMPLES, - ...opts - }; - const res: Vec[] = []; - const delta = 1 / opts.num; - const [a, b, c] = curve.points; - for (let t = 0; t < opts.num; t++) { - res.push(mixQuadratic([], a, b, c, t * delta)); - } - opts.last && res.push([c[0], c[1]]); - return res; - } - -); diff --git a/packages/geom2/src/circle.ts b/packages/geom2/src/circle.ts deleted file mode 100644 index 506e767f8a..0000000000 --- a/packages/geom2/src/circle.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { isNumber } from "@thi.ng/checks"; -import { implementations } from "@thi.ng/defmulti"; -import { - cossin, - EPS, - HALF_PI, - PI, - sign, - TAU -} from "@thi.ng/math"; -import { - add2, - cartesian2, - copy, - dist, - distSq2, - mixN2, - mulN2, - normalize, - ReadonlyVec, - sub2, - subN2, - Vec -} from "@thi.ng/vectors3"; -import { - arcLength, - area, - Attribs, - bounds, - center, - centroid, - Circle2, - classifyPoint, - closestPoint, - DEFAULT_SAMPLES, - perimeter, - pointAt, - pointInside, - Rect2, - SamplingOpts, - tangentAt, - translate, - Type, - vertices -} from "./api"; -import { circumCenter } from "./internal/circumcenter"; -import "./polygon"; - -export function circle(pos: Vec, r = 1, attribs?: Attribs): Circle2 { - return new Circle2(pos, r, attribs); -} - -export const circleFrom2Points = - (a: ReadonlyVec, b: ReadonlyVec, attribs?: Attribs) => - new Circle2(mixN2([], a, b, 0.5), dist(a, b) / 2, attribs); - -export const circleFrom3Points = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, attribs?: Attribs) => { - const o = circumCenter(a, b, c); - if (o) { - return new Circle2(o, dist(a, o), attribs); - } - }; - -implementations( - Type.CIRCLE, - - null, - - arcLength, - (circle: Circle2) => - TAU * circle.r, - - area, - (circle: Circle2) => - PI * circle.r * circle.r, - - bounds, - (circle: Circle2) => - new Rect2( - subN2([], circle.pos, circle.r), - mulN2(null, [2, 2], circle.r) - ), - - centroid, - (circle: Circle2) => copy(circle.pos), - - center, - (circle: Circle2, origin?: ReadonlyVec) => - new Circle2( - origin ? origin : [0, 0], - circle.r, - { ...circle.attribs } - ), - - classifyPoint, - (circle: Circle2, p: ReadonlyVec, eps = EPS) => - sign(circle.r - dist(circle.pos, p), eps), - - closestPoint, - (circle: Circle2, p: ReadonlyVec) => - add2(null, normalize(null, sub2([], p, circle.pos), circle.r), circle.pos), - - perimeter, - (circle: Circle2) => TAU * circle.r, - - pointAt, - (circle: Circle2, t: number) => - cartesian2(null, [circle.r, TAU * t], circle.pos), - - pointInside, - (circle: Circle2, p: ReadonlyVec) => - distSq2(circle.pos, p) <= circle.r * circle.r, - - tangentAt, - (_: Circle2, t: number) => - cossin(TAU * t + HALF_PI), - - translate, - (circle: Circle2, delta: ReadonlyVec) => - new Circle2( - add2([], circle.pos, delta), - circle.r, - { ...circle.attribs } - ), - - vertices, - (circle: Circle2, opts: number | Partial = DEFAULT_SAMPLES) => { - const buf: Vec[] = []; - const pos = circle.pos; - const r = circle.r; - let [num, last] = isNumber(opts) ? - [opts, false] : - [ - opts.theta ? - Math.floor(TAU / opts.theta) : - opts.dist ? - Math.floor(TAU / (opts.dist / r)) : - opts.num || DEFAULT_SAMPLES, - opts.last === true - ]; - const delta = TAU / num; - last && num++; - for (let i = 0; i < num; i++) { - buf[i] = cartesian2(null, [r, i * delta], pos); - } - return buf; - } -); diff --git a/packages/geom2/src/container2.ts b/packages/geom2/src/container2.ts deleted file mode 100644 index c21053754c..0000000000 --- a/packages/geom2/src/container2.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { implementations } from "@thi.ng/defmulti"; -import { Mat } from "@thi.ng/matrices"; -import { MAX2, MIN2, Vec } from "@thi.ng/vectors3"; -import { - Attribs, - bounds, - centroid, - convexHull, - flip, - PointContainer, - Polygon2, - Rect2, - transform, - Type, - vertices -} from "./api"; -import { bounds as _bounds } from "./internal/bounds"; -import { centroid as _centroid } from "./internal/centroid"; -import { grahamScan2 } from "./internal/graham-scan"; -import { transformPoints } from "./internal/transform"; - -export function points(points: Vec[], attribs?: Attribs) { - return new PointContainer(Type.POINTS2, points, attribs); -} - -implementations( - Type.POINTS2, - - null, - - bounds, - (pc: PointContainer) => - Rect2.fromMinMax(..._bounds(pc.points, [...MAX2], [...MIN2])), - - centroid, - (pc: PointContainer) => - _centroid(pc.points), - - convexHull, - (pc: PointContainer) => - new Polygon2(grahamScan2(pc.points), { ...pc.attribs }), - - flip, - (pc: PointContainer) => - pc.flip(), - - transform, - (pc: PointContainer, mat: Mat) => - new PointContainer( - pc.type, - transformPoints(pc.points, mat), - { ...pc.attribs } - ), - - vertices, - (pc: PointContainer) => - pc.points -); diff --git a/packages/geom2/src/ellipse.ts b/packages/geom2/src/ellipse.ts deleted file mode 100644 index af3f1103d7..0000000000 --- a/packages/geom2/src/ellipse.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { isNumber } from "@thi.ng/checks"; -import { implementations } from "@thi.ng/defmulti"; -import { cossin, PI, TAU } from "@thi.ng/math"; -import { - add2, - copy, - madd2, - mulN2, - ReadonlyVec, - sub2, - Vec -} from "@thi.ng/vectors3"; -import { - arcLength, - area, - asPolygon, - Attribs, - bounds, - center, - centroid, - DEFAULT_SAMPLES, - Ellipse2, - perimeter, - pointAt, - Polygon2, - Rect2, - SamplingOpts, - translate, - Type, - vertices -} from "./api"; -import "./polygon"; - -export function ellipse(pos: Vec, r = [1, 1], attribs?: Attribs): Ellipse2 { - return new Ellipse2(pos, r, attribs); -} - -implementations( - Type.ELLIPSE, - - null, - - arcLength, - (ellipse: Ellipse2) => { - const [a, b] = ellipse.r; - // Ramanujan approximation - // https://www.mathsisfun.com/geometry/ellipse-perimeter.html - return PI * ((3 * (a + b)) - Math.sqrt((3 * a + b) * (3 * b + a))); - }, - - area, - (ellipse: Ellipse2) => - PI * ellipse.r[0] * ellipse.r[1], - - asPolygon, - (ellipse: Ellipse2, opts) => - new Polygon2(vertices(ellipse, opts), { ...ellipse.attribs }), - - bounds, - (ellipse: Ellipse2) => - new Rect2(sub2([], ellipse.pos, ellipse.r), mulN2([], ellipse.r, 2)), - - centroid, - (ellipse: Ellipse2) => copy(ellipse.pos), - - center, - (ellipse: Ellipse2, origin?: ReadonlyVec) => - new Ellipse2( - origin ? origin : [0, 0], - copy(ellipse.r), - { ...ellipse.attribs } - ), - - perimeter, - (ellipse: Ellipse2) => { - const a = ellipse.r[0]; - const b = ellipse.r[1]; - return PI * (3 * (a + b) - Math.sqrt((3 * a + b) * (3 * b + a))); - }, - - pointAt, - (ellipse: Ellipse2, t: number) => - madd2([], ellipse.pos, cossin(t * TAU), ellipse.r), - - translate, - (ellipse: Ellipse2, delta: ReadonlyVec) => - new Ellipse2( - add2([], ellipse.pos, delta), - ellipse.r, - { ...ellipse.attribs } - ), - - vertices, - (ellipse: Ellipse2, opts: number | Partial = DEFAULT_SAMPLES) => { - const buf: Vec[] = []; - const pos = ellipse.pos; - const r = ellipse.r; - let [num, last] = isNumber(opts) ? - [opts, false] : - [ - opts.theta ? - Math.floor(TAU / opts.theta) : - opts.num || DEFAULT_SAMPLES, - opts.last === true - ]; - const delta = TAU / num; - last && num++; - for (let i = 0; i < num; i++) { - buf[i] = madd2([], pos, cossin(i * delta), r); - } - return buf; - } -); diff --git a/packages/geom2/src/group.ts b/packages/geom2/src/group.ts deleted file mode 100644 index a292df94d3..0000000000 --- a/packages/geom2/src/group.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { implementations } from "@thi.ng/defmulti"; -import { - area, - Attribs, - bounds, - centroid, - Group2, - IShape, - Type -} from "./api"; -import { collBounds } from "./internal/bounds"; - -export function group(attribs?: Attribs, ...children: IShape[]) { - return new Group2(attribs, ...children); -} - -implementations( - Type.GROUP, - - null, - - area, - (g: Group2) => area(bounds(g)), - - bounds, - (g: Group2) => collBounds(g.children), - - centroid, - (g: Group2) => centroid(bounds(g)), -); diff --git a/packages/geom2/src/index.ts b/packages/geom2/src/index.ts deleted file mode 100644 index 700c65e00f..0000000000 --- a/packages/geom2/src/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -export * from "./api"; -export * from "./arc"; -export * from "./bezier"; -export * from "./circle"; -export * from "./container2"; -export * from "./ellipse"; -export * from "./group"; -export * from "./line"; -export * from "./path"; -export * from "./polygon"; -export * from "./polyline"; -export * from "./quad"; -export * from "./ray"; -export * from "./rect"; -export * from "./sphere"; -export * from "./triangle"; - -export * from "./svg"; -export * from "./tessellate"; diff --git a/packages/geom2/src/internal/arc-length.ts b/packages/geom2/src/internal/arc-length.ts deleted file mode 100644 index 5791bd7d6f..0000000000 --- a/packages/geom2/src/internal/arc-length.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { ReadonlyVec, dist } from "@thi.ng/vectors3"; - -export const arcLength = (pts: ReadonlyVec[], closed = false) => { - const num = pts.length; - if (num < 2) return 0; - let res = 0; - let p = pts[0]; - let q = pts[1]; - for (let i = 1; i < num; i++ , p = q, q = pts[i]) { - res += dist(p, q); - } - closed && (res += dist(p, pts[0])); - return res; -}; diff --git a/packages/geom2/src/internal/arc.ts b/packages/geom2/src/internal/arc.ts deleted file mode 100644 index 3844ff219f..0000000000 --- a/packages/geom2/src/internal/arc.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { atan2Abs, cossin, TAU } from "@thi.ng/math"; -import { ReadonlyVec, Vec, madd } from "@thi.ng/vectors3"; - -export const arcVertices = ( - o: ReadonlyVec, - a: ReadonlyVec, - b: ReadonlyVec, - r: ReadonlyVec, - verts: Vec[] = [], - outwards = false, - res = 8) => { - - const ta = atan2Abs(a[1] - o[1], a[0] - o[0]); - const tb = atan2Abs(b[1] - o[1], b[0] - o[0]); - const theta = ta > tb ? ta - tb : ta + TAU - tb; - const ts = (outwards ? -theta : TAU - theta) / res; - verts.push(a); - for (let i = 1; i < res; i++) { - const p = cossin(ta + ts * i); - verts.push(madd(p, o, p, r)); - } - verts.push(b); - return verts; -}; diff --git a/packages/geom2/src/internal/barycentric.ts b/packages/geom2/src/internal/barycentric.ts deleted file mode 100644 index e5505186f0..0000000000 --- a/packages/geom2/src/internal/barycentric.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { eqDelta } from "@thi.ng/math"; -import { - dot, - maddN, - mulN, - ReadonlyVec, - sub, - Vec, - zero -} from "@thi.ng/vectors3"; - -export const toBarycentric = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, p: ReadonlyVec, out: Vec = []) => { - - const u = sub([], b, a); - const v = sub([], c, a); - const w = sub([], p, a); - const d00 = dot(u, u); - const d01 = dot(u, v); - const d11 = dot(v, v); - const d20 = dot(w, u); - const d21 = dot(w, v); - const denom = d00 * d11 - d01 * d01; - - if (eqDelta(denom, 0)) { - return zero(out); - } - - const s = (d11 * d20 - d01 * d21) / denom; - const t = (d00 * d21 - d01 * d20) / denom; - out[0] = 1 - s - t; - out[1] = s; - out[2] = t; - return out; - }; - -export const fromBarycentric = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, p: ReadonlyVec, out: Vec) => - maddN(null, maddN(null, mulN(out, a, p[0]), b, p[1]), c, p[2]); diff --git a/packages/geom2/src/internal/bounds.ts b/packages/geom2/src/internal/bounds.ts deleted file mode 100644 index a5ba6451f1..0000000000 --- a/packages/geom2/src/internal/bounds.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { - add, - max, - min, - ReadonlyVec, - sub, - Vec -} from "@thi.ng/vectors3"; -import { bounds as _bounds, IShape, union } from "../api"; - -export const bounds = - (pts: ReadonlyArray, vmin: Vec, vmax: Vec): [Vec, Vec] => { - - for (let i = pts.length; --i >= 0;) { - const p = pts[i]; - min(null, vmin, p); - max(null, vmax, p); - } - return [vmin, vmax]; - }; - -export const collBounds = - (shapes: IShape[]) => { - - let n = shapes.length - 1; - let res: IShape = n >= 0 ? _bounds(shapes[n]) : undefined; - for (; --n >= 0;) { - res = union(res, _bounds(shapes[n]))[0]; - } - return res; - }; - -export const unionBounds = - (pos1: ReadonlyVec, size1: ReadonlyVec, pos2: ReadonlyVec, size2: ReadonlyVec): [Vec, Vec] => { - const p = add([], pos1, size1); - const q = add([], pos2, size2); - const pos = min([], pos1, pos2); - return [pos, sub(null, max(null, p, q), pos)]; - }; diff --git a/packages/geom2/src/internal/centroid.ts b/packages/geom2/src/internal/centroid.ts deleted file mode 100644 index c6552910bc..0000000000 --- a/packages/geom2/src/internal/centroid.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { illegalArgs } from "@thi.ng/errors"; -import { - add, - cross2, - divN, - empty, - ReadonlyVec, - Vec -} from "@thi.ng/vectors3"; - -export const centroid = - (pts: ReadonlyVec[], c?: Vec) => { - const num = pts.length; - !num && illegalArgs("no points available"); - !c && (c = empty(pts[0])); - for (let i = num; --i >= 0;) { - add(c, c, pts[i]); - } - return divN(null, c, num); - }; - -export const centerOfWeight2 = - (pts: ReadonlyVec[], c: Vec = []) => { - let area = 0; - let x = 0; - let y = 0; - for (let n = pts.length - 1, i = pts[n], j = pts[0], k = 0; k <= n; k++ , i = j, j = pts[k]) { - const z = cross2(i, j); - area += z; - x += (i[0] + j[0]) * z; - y += (i[1] + j[1]) * z; - } - area = 1 / (area * 3); - c[0] = x * area; - c[1] = y * area; - return c; - }; diff --git a/packages/geom2/src/internal/circumcenter.ts b/packages/geom2/src/internal/circumcenter.ts deleted file mode 100644 index a96a1bef5d..0000000000 --- a/packages/geom2/src/internal/circumcenter.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { EPS } from "@thi.ng/math"; -import { ReadonlyVec } from "@thi.ng/vectors3"; - -export const circumCenter = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, eps = EPS) => { - - const deltaAB = Math.abs(a[1] - b[1]); - const deltaBC = Math.abs(b[1] - c[1]); - if (deltaAB < eps && deltaBC < eps) { - return null; - } - const ax = a[0], ay = a[1]; - const bx = b[0], by = b[1]; - const cx = c[0], cy = c[1]; - let m1, m2, mx1, mx2, my1, my2, xc, yc; - if (deltaAB < eps) { - m2 = - (cx - bx) / (cy - by); - mx2 = (bx + cx) / 2; - my2 = (by + cy) / 2; - xc = (bx + ax) / 2; - yc = m2 * (xc - mx2) + my2; - } else if (deltaBC < eps) { - m1 = - (bx - ax) / (by - ay); - mx1 = (ax + bx) / 2; - my1 = (ay + by) / 2; - xc = (cx + bx) / 2; - yc = m1 * (xc - mx1) + my1; - } else { - m1 = - (bx - ax) / (by - ay); - m2 = - (cx - bx) / (cy - by); - mx1 = (ax + bx) / 2; - my1 = (ay + by) / 2; - mx2 = (bx + cx) / 2; - my2 = (by + cy) / 2; - xc = (m1 * mx1 - m2 * mx2 + my2 - my1) / (m1 - m2); - if (deltaAB > deltaBC) { - yc = m1 * (xc - mx1) + my1; - } else { - yc = m2 * (xc - mx2) + my2; - } - } - return [xc, yc]; - }; diff --git a/packages/geom2/src/internal/closest-point.ts b/packages/geom2/src/internal/closest-point.ts deleted file mode 100644 index 97b738b4c1..0000000000 --- a/packages/geom2/src/internal/closest-point.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { - distSq, - dot, - empty, - magSq, - mixN, - ReadonlyVec, - set, - sub, - Vec -} from "@thi.ng/vectors3"; - -export const closestPoint = - (p: ReadonlyVec, pts: Vec[]) => { - - let minD = Infinity; - let closest: Vec; - for (let i = pts.length; --i >= 0;) { - const d = distSq(pts[i], p); - if (d < minD) { - minD = d; - closest = pts[i]; - } - } - return closest; - }; - -export const closestCoeff = - (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec) => { - - const d = sub([], b, a); - const l = magSq(d); - if (l > 1e-6) { - return dot(sub([], p, a), d) / l; - } - }; - -/** - * Returns closest point to `p` on segment `a` -> `b`. By default, if - * the result point lies outside the segment, returns a copy of the - * closest end point. However, if `insideOnly` is true, only returns the - * closest point if it actually is inside the segment (incl. end - * points). - * - * @param p - * @param a - * @param b - * @param out - */ -export const closestPointSegment = - (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, out?: Vec, insideOnly = false) => { - - const t = closestCoeff(p, a, b); - if (t !== undefined && (!insideOnly || t >= 0 && t <= 1)) { - out = out || empty(p); - return t <= 0.0 ? - set(out, a) : - t >= 1.0 ? - set(out, b) : - mixN(out, a, b, t); - } - }; - -export const closestPointPolyline = - (p: ReadonlyVec, pts: ReadonlyArray, closed = false) => { - - const closest = empty(pts[0]); - const tmp = empty(closest); - const n = pts.length - 1; - let minD = Infinity, i, j; - if (closed) { - i = n; - j = 0; - } else { - i = 0; - j = 1; - } - for (; j <= n; i = j, j++) { - if (closestPointSegment(p, pts[i], pts[j], tmp)) { - const d = distSq(p, tmp); - if (d < minD) { - minD = d; - set(closest, tmp); - } - } - } - return closest; - }; - -/** - * Returns the index of the start point containing the segment in the - * polyline array `points` farthest away from `p` with regards to the - * line segment `a` to `b`. `points` is only checked between indices - * `from` and `to` (not including the latter). - * - * @param a - * @param b - * @param points - * @param from - * @param to - */ -export const farthestPointSegment = - (a: Vec, b: Vec, points: Vec[], from = 0, to = points.length) => { - let maxD = -1; - let maxIdx; - const tmp = empty(a); - for (let i = from; i < to; i++) { - const p = points[i]; - const d = distSq(p, closestPointSegment(p, a, b, tmp) || a); - if (d > maxD) { - maxD = d; - maxIdx = i; - } - } - return [maxIdx, Math.sqrt(maxD)]; - }; diff --git a/packages/geom2/src/internal/corner.ts b/packages/geom2/src/internal/corner.ts deleted file mode 100644 index aa4d7c6de4..0000000000 --- a/packages/geom2/src/internal/corner.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { EPS, sign } from "@thi.ng/math"; -import { ReadonlyVec, signedArea2 } from "@thi.ng/vectors3"; - -export const classify = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, eps = EPS) => - sign(signedArea2(a, b, c), eps); - -export const clockwise2 = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => - signedArea2(a, b, c) < 0; - -export const classifyPointInTriangle2 = - (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => { - const s = clockwise2(a, b, c) ? 1 : -1; - return sign( - Math.min( - s * signedArea2(a, c, p), - s * signedArea2(b, a, p), - s * signedArea2(c, b, p) - ) - ); - }; - -export const pointInTriangle2 = - (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => { - const s = clockwise2(a, b, c) ? 1 : -1; - return s * signedArea2(a, c, p) >= 0 && - s * signedArea2(b, a, p) >= 0 && - s * signedArea2(c, b, p) >= 0; - }; diff --git a/packages/geom2/src/internal/direction.ts b/packages/geom2/src/internal/direction.ts deleted file mode 100644 index 9c521ab5d0..0000000000 --- a/packages/geom2/src/internal/direction.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { - normalize, - perpendicularLeft2, - perpendicularRight2, - ReadonlyVec, - sub -} from "@thi.ng/vectors3"; - -export const direction = - (a: ReadonlyVec, b: ReadonlyVec, n = 1) => - normalize(null, sub([], b, a), n); - -export const normalL2 = - (a: ReadonlyVec, b: ReadonlyVec, n = 1) => - perpendicularLeft2(null, direction(a, b, n)); - -export const normalR2 = - (a: ReadonlyVec, b: ReadonlyVec, n = 1) => - perpendicularRight2(null, direction(a, b, n)); diff --git "a/packages/geom2/src/internal/douglas\342\200\223peucker.ts" "b/packages/geom2/src/internal/douglas\342\200\223peucker.ts" deleted file mode 100644 index 4a2636ef6b..0000000000 --- "a/packages/geom2/src/internal/douglas\342\200\223peucker.ts" +++ /dev/null @@ -1,42 +0,0 @@ -import { EPS } from "@thi.ng/math"; -import { peek } from "@thi.ng/transducers"; -import { eqDelta, Vec } from "@thi.ng/vectors3"; -import { farthestPointSegment } from "./closest-point"; - -// https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm - -export const douglasPeucker2 = - (pts: Vec[], eps = 0, closed = false) => { - - let num = pts.length; - const visited: boolean[] = []; - if (num <= 2) return pts.slice(); - if (closed && !eqDelta(pts[0], peek(pts), EPS)) { - pts = pts.slice(); - pts.push(pts[0]); - num++; - } - - const $ = (from: number, to: number) => { - visited[from] = visited[to] = true; - if (to <= from + 1) { - return; - } - const [maxIdx, maxD] = farthestPointSegment(pts[from], pts[to], pts, from + 1, to); - if (maxD <= eps) { - return; - } - $(from, maxIdx); - $(maxIdx, to); - }; - - $(0, num - 1); - - const res: Vec[] = []; - for (let i = 0, n = closed ? num - 1 : num; i < n; i++) { - if (visited[i]) { - res.push(pts[i]); - } - } - return res; - }; diff --git a/packages/geom2/src/internal/edges.ts b/packages/geom2/src/internal/edges.ts deleted file mode 100644 index 014278115d..0000000000 --- a/packages/geom2/src/internal/edges.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { partition, wrap } from "@thi.ng/transducers"; -import { Vec } from "@thi.ng/vectors3"; -import { VecPair } from "../api"; - -export const edges = - (vertices: Iterable, closed = false) => - >partition( - 2, 1, - closed ? - wrap(vertices, 1, false, true) : - vertices - ); diff --git a/packages/geom2/src/internal/graham-scan.ts b/packages/geom2/src/internal/graham-scan.ts deleted file mode 100644 index 0298ddaf1d..0000000000 --- a/packages/geom2/src/internal/graham-scan.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { comparator2, signedArea2, Vec } from "@thi.ng/vectors3"; - -/** - * Returns array of points defining the 2D Convex Hull of `pts` using - * the Graham Scan method. - * - * https://en.wikipedia.org/wiki/Graham_scan - * - * @param pts - */ -export const grahamScan2 = - (pts: ReadonlyArray) => { - const num = pts.length; - const res: Vec[] = []; - let h = 0, i; - pts = pts.slice().sort(comparator2(0, 1)); - - const scan = (p: Vec, thresh: number) => { - while (h >= thresh && signedArea2(res[h - 2], res[h - 1], p) >= 0) { - res.pop(); - h--; - } - res[h++] = p; - }; - - for (i = 0; i < num; i++) { - scan(pts[i], 2); - } - res.pop(); - h--; - const h2 = h + 2; - for (i = num - 1; i >= 0; i--) { - scan(pts[i], h2); - } - res.pop(); - return res; - }; diff --git a/packages/geom2/src/internal/greiner-hormann.ts b/packages/geom2/src/internal/greiner-hormann.ts deleted file mode 100644 index c783bc5d1f..0000000000 --- a/packages/geom2/src/internal/greiner-hormann.ts +++ /dev/null @@ -1,305 +0,0 @@ -import { ICopy } from "@thi.ng/api"; -import { equivArrayLike } from "@thi.ng/equiv"; -import { mapcat } from "@thi.ng/transducers"; -import { Vec } from "@thi.ng/vectors3"; -import { ClipMode, LineIntersectionType, VecPair } from "../api"; -import { edges as _edges } from "./edges"; -import { intersectLines2 } from "./line-intersection"; -import { pointInside, polygonArea } from "./polygon"; - -export const enum VertexFlag { - ISEC = 1, - ENTRY = 2, - VISITED = 4 -} - -export class ClipVertex implements - ICopy { - - pos: Vec; - next: ClipVertex; - prev: ClipVertex; - pair: ClipVertex; - flags: VertexFlag; - dist: number; - - constructor(pos: Vec, dist = 0, flags = VertexFlag.ENTRY) { - this.pos = pos; - this.dist = dist; - this.flags = flags; - this.next = this.prev = this.pair = null; - } - - copy() { - return new ClipVertex(this.pos); - } - - equiv(v: any) { - return v && equivArrayLike(this.pos, v.pos); - } - - reset() { - this.flags = VertexFlag.ENTRY; - this.pair = null; - this.dist = 0; - return this; - } - - visit() { - this.flags |= VertexFlag.VISITED; - this.pair && (this.pair.flags |= VertexFlag.VISITED); - } - - nextNonIntersecting() { - let v: ClipVertex = this; - while (v.flags & VertexFlag.ISEC) { - v = v.next; - } - return v; - } -} - -export class ClipPolygon implements - ICopy { - - protected first: ClipVertex; - protected firstIsec: ClipVertex; - protected lastProc: ClipVertex; - protected length: number; - protected clockwise: boolean; - - constructor(points: Vec[], orient = true) { - if (orient && polygonArea(points) > 0) { - points = points.slice().reverse(); - } - this.first = this.firstIsec = this.lastProc = null; - this.length = 0; - const n = points.length; - for (let i = 0; i < n; i++) { - this.addVertex(points[i]); - } - } - - copy() { - return new ClipPolygon(this.vertices()); - } - - addVertex(p: Vec) { - const v = new ClipVertex(p); - if (this.first) { - const next = this.first; - const prev = next.prev; - next.prev = v; - v.next = next; - v.prev = prev; - prev.next = v; - } else { - this.first = v; - v.next = v.prev = v; - } - this.length++; - } - - insertVertex(v: ClipVertex, start: ClipVertex, end: ClipVertex) { - let curr = start; - while (curr !== end && curr.dist < v.dist) { - curr = curr.next; - } - v.next = curr; - const prev = curr.prev; - v.prev = prev; - prev.next = v; - curr.prev = v; - this.length++; - } - - removeVertex(v: ClipVertex) { - if (this.first === v) { - if (this.length === 1) { - this.first = null; - this.length = 0; - return; - } - this.first = v.next; - } - this.firstIsec === v && (this.firstIsec = null); - this.lastProc === v && (this.lastProc = null); - v.prev.next = v.next; - v.next.prev = v.prev; - this.length--; - } - - edges() { - const edges: VecPair[] = []; - const f = this.first; - let v = f; - do { - edges.push([v.pos, v.next.pos]); - v = v.next; - } while (v !== f); - return edges; - } - - vertices() { - const vertices: Vec[] = []; - const f = this.first; - let v = f; - do { - vertices.push(v.pos); - v = v.next; - } while (v !== f); - return vertices; - } - - clip(clip: ClipPolygon, mode: ClipMode) { - this.insertIntersections(clip); - const sinc = clip.pointInside(this.first.pos); - const cins = this.pointInside(clip.first.pos); - this.markEntryVertices(((mode & 1) ^ sinc) > 0); - clip.markEntryVertices((((mode >> 1) & 1) ^ cins) > 0); - const res = this.buildClipPolys(); - if (res.length === 0) { - switch (mode) { - case ClipMode.UNION: - if (sinc) { res.push(clip); } - else if (cins) { res.push(this); } - else { res.push(this, clip); } - break; - case ClipMode.INTERSECTION: - if (sinc) { res.push(this); } - else if (cins) { res.push(clip); } - break; - default: - if (sinc) { res.push(clip, this); } - else if (cins) { res.push(this, clip); } - else { res.push(this); } - } - } - return res; - } - - reset() { - const f = this.first; - let v = f; - do { - v = v.reset().next; - } while (v !== f); - } - - pointInside(p: Vec) { - const f = this.first; - const x = p[0]; - const y = p[1]; - let v = f; - let n = v.next; - let inside = 0; - do { - inside = pointInside(v.pos, n.pos, x, y, inside); - v = n; - n = n.next || f; - } while (v !== f); - return inside; - } - - protected insertIntersections(clip: ClipPolygon) { - let s = this.first; - let c = clip.first; - do { - if (!(s.flags & VertexFlag.ISEC)) { - do { - if (!(c.flags & VertexFlag.ISEC)) { - const ns = s.next.nextNonIntersecting(); - const nc = c.next.nextNonIntersecting(); - const i = intersectLines2(s.pos, ns.pos, c.pos, nc.pos); - if (i && i.type === LineIntersectionType.INTERSECT) { - const is = new ClipVertex(i.isec, i.alpha, VertexFlag.ISEC); - const ic = new ClipVertex(i.isec, i.beta, VertexFlag.ISEC); - is.pair = ic; - ic.pair = is; - this.insertVertex(is, s, ns); - clip.insertVertex(ic, c, nc); - } - } - c = c.next; - } while (c !== clip.first); - } - s = s.next; - } while (s !== this.first); - } - - protected markEntryVertices(state: boolean) { - const f = this.first; - let v = f; - do { - if (v.flags & VertexFlag.ISEC) { - v.flags = state ? - (v.flags | VertexFlag.ENTRY) : - (v.flags & (~VertexFlag.ENTRY)); - state = !state; - } - v = v.next; - } while (v !== f); - } - - protected buildClipPolys() { - const res: ClipPolygon[] = []; - while (this.hasUnprocessed()) { - let curr = this.findfirstIntersection(); - const clipped = new ClipPolygon([curr.pos]); - do { - curr.visit(); - if (curr.flags & VertexFlag.ENTRY) { - do { - curr = curr.next; - clipped.addVertex(curr.pos); - } while (!(curr.flags & VertexFlag.ISEC)); - } else { - do { - curr = curr.prev; - clipped.addVertex(curr.pos); - } while (!(curr.flags & VertexFlag.ISEC)); - } - curr = curr.pair; - } while (curr.flags < VertexFlag.VISITED); - clipped.removeVertex(clipped.first.prev); - // TODO only return vertices? - res.push(clipped); - } - return res; - } - - protected findfirstIntersection() { - const f = this.first; - let v = this.firstIsec || f; - do { - if (v.flags < VertexFlag.VISITED && (v.flags & VertexFlag.ISEC)) { - break; - } - v = v.next; - } while (v !== f); - this.firstIsec = v; - return v; - } - - protected hasUnprocessed() { - const f = this.first; - let v = this.lastProc || f; - do { - if (v.flags < VertexFlag.VISITED && (v.flags & VertexFlag.ISEC)) { - this.lastProc = v; - return true; - } - v = v.next; - } while (v !== f); - this.lastProc = null; - return false; - } -}; - -export const booleanOp = (a: Vec[][], b: Vec[], mode: ClipMode, orient = true) => - [...mapcat( - (a) => - new ClipPolygon(a, orient) - .clip(new ClipPolygon(b, orient), mode) - .map((c) => c.vertices()), - a)]; diff --git a/packages/geom2/src/internal/liang-barsky.ts b/packages/geom2/src/internal/liang-barsky.ts deleted file mode 100644 index 0b69ecf34f..0000000000 --- a/packages/geom2/src/internal/liang-barsky.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { EPS } from "@thi.ng/math"; -import { Vec } from "@thi.ng/vectors3"; - -// https://en.wikipedia.org/wiki/Liang%E2%80%93Barsky_algorithm -// https://github.com/thi-ng/c-thing/blob/master/src/geom/clip/liangbarsky.c - -export const liangBarsky2 = ( - la: Vec, - lb: Vec, - tl: Vec, - br: Vec, - ca: Vec = [], - cb: Vec = [] -): [Vec, Vec, number, number] => { - const lax = la[0]; - const lay = la[1]; - const dx = lb[0] - lax; - const dy = lb[1] - lay; - let a = 0; - let b = 1; - - const clip = (p: number, q: number) => { - if (q < 0 && Math.abs(p) < EPS) { - return 0; - } - const r = q / p; - if (p < 0) { - if (r > b) { - return false; - } else if (r > a) { - a = r; - } - } else if (p > 0) { - if (r < a) { - return false; - } else if (r < b) { - b = r; - } - } - return true; - }; - - if (!( - clip(-dx, -(tl[0] - lax)) && - clip(dx, br[0] - lax) && - clip(-dy, -(tl[1] - lay)) && - clip(dy, br[1] - lay) - )) { - return; - } - - ca[0] = a * dx + lax; - ca[1] = a * dy + lay; - cb[0] = b * dx + lax; - cb[1] = b * dy + lay; - - return [ca, cb, a, b]; -}; diff --git a/packages/geom2/src/internal/line-intersection.ts b/packages/geom2/src/internal/line-intersection.ts deleted file mode 100644 index a6c9b38cd6..0000000000 --- a/packages/geom2/src/internal/line-intersection.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { EPS, eqDelta } from "@thi.ng/math"; -import { mixN2, ReadonlyVec } from "@thi.ng/vectors3"; -import { LineIntersection, LineIntersectionType } from "../api"; -import { closestPointSegment } from "./closest-point"; - -export const intersectLines2 = ( - a: ReadonlyVec, - b: ReadonlyVec, - c: ReadonlyVec, - d: ReadonlyVec, - eps = EPS -): LineIntersection => { - - const bax = b[0] - a[0]; - const bay = b[1] - a[1]; - const dcx = d[0] - c[0]; - const dcy = d[1] - c[1]; - const acx = a[0] - c[0]; - const acy = a[1] - c[1]; - const det = dcy * bax - dcx * bay; - let alpha = dcx * acy - dcy * acx; - let beta = bax * acy - bay * acx; - if (eqDelta(det, 0, eps)) { - if (eqDelta(alpha, 0, eps) && eqDelta(beta, 0, eps)) { - let isec = closestPointSegment(c, a, b, undefined, true) || - closestPointSegment(d, a, b, undefined, true); - return { - isec, - type: isec ? - LineIntersectionType.COINCIDENT : - LineIntersectionType.COINCIDENT_NO_INTERSECT, - }; - } - return { type: LineIntersectionType.PARALLEL }; - } - alpha /= det; - beta /= det; - const ieps = 1 - eps; - return { - type: (eps < alpha && alpha < ieps) && (eps < beta && beta < ieps) ? - LineIntersectionType.INTERSECT : - LineIntersectionType.INTERSECT_OUTSIDE, - isec: mixN2([], a, b, alpha), - alpha, - beta, - det, - }; -}; diff --git a/packages/geom2/src/internal/offset.ts b/packages/geom2/src/internal/offset.ts deleted file mode 100644 index f8a55dea0e..0000000000 --- a/packages/geom2/src/internal/offset.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { add2, sub2, Vec } from "@thi.ng/vectors3"; -import { ClipMode, VecPair } from "../api"; -import { arcVertices } from "./arc"; -import { normalL2 } from "./direction"; -import { edges as _edges } from "./edges"; -import { booleanOp } from "./greiner-hormann"; -import { polygonArea } from "./polygon"; - -export const offset = - (points: Vec[], dist: number, res = 8, closed = true) => { - if (!closed && dist < 0) return; - polygonArea(points) > 0 && (points = [...points].reverse()); - const contours = offsetEdges(_edges(points, closed), Math.abs(dist), res); - if (contours.length > 0) { - const a1 = Math.abs(polygonArea(contours[0])); - const a2 = Math.abs(polygonArea(contours[1])); - return contours[ - dist > 0 ? - a1 > a2 ? 0 : 1 : - a1 > a2 ? 1 : 0 - ]; - } - }; - -/** - * - * @param edges - * @param dist - * @param res - */ -export const offsetEdges = - (edges: Iterable, dist: number, res: number) => { - let result: Vec[][]; - for (let e of edges) { - const seg = offsetLine(e, dist, res); - result = result ? - booleanOp(result, seg, ClipMode.UNION, false) : - [seg]; - } - return result; - }; - -export const offsetLine = - ([ea, eb]: VecPair, dist: number, res: number) => { - const verts: Vec[] = []; - const r = [dist, dist]; - const n = normalL2(ea, eb, dist); - const e1 = [add2([], ea, n), add2([], eb, n)]; - const e2 = [sub2([], eb, n), sub2([], ea, n)]; - arcVertices(ea, e2[1], e1[0], r, verts, true, res); - return arcVertices(eb, e1[1], e2[0], r, verts, true, res); - }; diff --git a/packages/geom2/src/internal/perimeter.ts b/packages/geom2/src/internal/perimeter.ts deleted file mode 100644 index e81d9bd169..0000000000 --- a/packages/geom2/src/internal/perimeter.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { dist, ReadonlyVec } from "@thi.ng/vectors3"; - -export const perimeter = - (pts: ReadonlyVec[], closed = false) => { - const num = pts.length; - if (num < 2) return 0; - let res = 0; - let p = pts[0]; - let q = pts[1]; - for (let i = 1; i < num; i++ , p = q, q = pts[i]) { - res += dist(p, q); - } - closed && (res += dist(p, pts[0])); - return res; - }; diff --git a/packages/geom2/src/internal/polygon.ts b/packages/geom2/src/internal/polygon.ts deleted file mode 100644 index ee50f225a3..0000000000 --- a/packages/geom2/src/internal/polygon.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { cross2, ReadonlyVec } from "@thi.ng/vectors3"; - -export const polygonArea = - (pts: ReadonlyVec[]) => { - let res = 0; - for (let n = pts.length - 1, i = n, j = 0; n >= 0; i = j, j++ , n--) { - res += cross2(pts[i], pts[j]); - } - return res / 2; - }; - -export const pointInside = - (a: ReadonlyVec, b: ReadonlyVec, x: number, y: number, inside: number) => { - if (((a[1] < y && b[1] >= y) || - (b[1] < y && a[1] >= y)) && - (a[0] <= x || b[0] <= x)) { - inside ^= (((a[0] + (y - a[1]) / (b[1] - a[1]) * (b[0] - a[0])) < x) ? 1 : 0); - } - return inside; - }; diff --git a/packages/geom2/src/internal/sampler.ts b/packages/geom2/src/internal/sampler.ts deleted file mode 100644 index a054923558..0000000000 --- a/packages/geom2/src/internal/sampler.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { peek } from "@thi.ng/transducers"; -import { - copy, - dist, - mixN, - normalize, - ReadonlyVec, - sub, - Vec -} from "@thi.ng/vectors3"; -import { VecPair } from "../api"; - -export class Sampler { - - points: ReadonlyVec[]; - index: number[]; - - constructor(points: ReadonlyVec[], closed = false) { - if (closed) { - this.points = points.slice(); - this.points.push(points[0]); - } else { - this.points = points; - } - this.buildIndex(); - } - - pointAt(t: number) { - const pts = this.points; - const n = pts.length - 1; - if (n < 0) { - return; - } - if (n === 0 || t <= 0) { - return pts[0]; - } - if (t >= 1) { - return pts[n]; - } - const idx = this.index; - const t0 = t * idx[n]; - for (let i = 1; i <= n; i++) { - if (idx[i] >= t0) { - return mixN([], pts[i - 1], pts[i], (t0 - idx[i - 1]) / (idx[i] - idx[i - 1])); - } - } - } - - segmentAt(t: number): VecPair { - let i = this.indexAt(t); - if (i === undefined) { - return; - } - i = Math.max(1, i); - return [this.points[i - 1], this.points[i]]; - } - - tangentAt(t: number, n = 1) { - const seg = this.segmentAt(t); - return seg ? - normalize(null, sub([], seg[1], seg[0]), n) : - undefined; - } - - indexAt(t: number) { - const pts = this.points; - const n = pts.length - 1; - if (n < 0) { - return; - } - if (n === 0 || t <= 0) { - return 0; - } - if (t >= 1) { - return n; - } - const idx = this.index; - const t0 = t * idx[n]; - for (let i = 1; i <= n; i++) { - if (idx[i] >= t0) { - return i; - } - } - } - - sampleUniform(dist: number, includeLast = false, result: Vec[] = []) { - const index = this.index; - const pts = this.points; - const total = peek(index); - const delta = dist / total; - const n = index.length; - for (let t = 0, i = 1; t < 1; t += delta) { - const ct = t * total; - while (ct >= index[i] && i < n) { i++; } - if (i >= n) break; - const p = index[i - 1]; - result.push(mixN([], pts[i - 1], pts[i], (ct - p) / (index[i] - p))); - } - if (includeLast) { - result.push(copy(peek(pts))); - } - return result; - } - - sampleFixedNum(num: number, includeLast = false, result?: Vec[]) { - return this.sampleUniform(peek(this.index) / num, includeLast, result); - } - - protected buildIndex() { - const idx: number[] = [0]; - const pts = this.points; - const n = pts.length; - for (let i = 0, j = 1; j < n; i = j, j++) { - idx[j] = idx[i] + dist(pts[i], pts[j]); - } - this.index = idx; - } -} diff --git a/packages/geom2/src/internal/subdiv-curve.ts b/packages/geom2/src/internal/subdiv-curve.ts deleted file mode 100644 index 72893976c9..0000000000 --- a/packages/geom2/src/internal/subdiv-curve.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { - comp, - indexed, - mapcat, - partition, - push, - transduce, - wrap -} from "@thi.ng/transducers"; -import { - addW2, - addW3, - addW5, - ReadonlyVec, - Vec -} from "@thi.ng/vectors3"; -import { SubdivKernel } from "../api"; - -export const subdivKernel2 = - ([ua, ub]: number[], [va, vb]: number[]) => - ([a, b]: ReadonlyVec[]) => [ - addW2([], a, b, ua, ub), - addW2([], a, b, va, vb), - ]; - -export const subdivKernel3 = - ([ua, ub, uc]: number[], [va, vb, vc]: number[]) => - ([a, b, c]: ReadonlyVec[]) => [ - addW3([], a, b, c, ua, ub, uc), - addW3([], a, b, c, va, vb, vc), - ]; - -export const subdivKernel5 = - ([ua, ub, uc, ud, ue]: number[], [va, vb, vc, vd, ve]: number[]) => - ([a, b, c, d, e]: ReadonlyVec[]) => [ - addW5([], a, b, c, d, e, ua, ub, uc, ud, ue), - addW5([], a, b, c, d, e, va, vb, vc, vd, ve), - ]; - -/** - * http://algorithmicbotany.org/papers/subgpu.sig2003.pdf - * - * @param kernel subdivision scheme - * @param pts source points - * @param iter number of iterations - * @param closed true, if closed input geometry - */ -export const subdivideCurve = ( - { fn, size }: SubdivKernel, - pts: ReadonlyVec[], - iter = 1, - closed = false) => { - - while (--iter >= 0) { - const nump = pts.length; - pts = transduce( - comp( - partition(size, 1), - indexed(), - mapcat(([i, pts]) => fn(pts, i, nump)) - ), - push(), - closed ? - wrap(pts, size >> 1, true, true) : - pts - ); - } - return pts; -}; diff --git a/packages/geom2/src/internal/sutherland-hodgeman.ts b/packages/geom2/src/internal/sutherland-hodgeman.ts deleted file mode 100644 index 202ef7deae..0000000000 --- a/packages/geom2/src/internal/sutherland-hodgeman.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { ReadonlyVec } from "@thi.ng/vectors3"; -import { classify } from "./corner"; -import { intersectLines2 } from "./line-intersection"; - -/** - * Extended version of Sutherland-Hodgeman convex polygon clipping - * supporting any convex boundary (not only rects). Returns new array of - * clipped vertices. - * - * https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm - * - * @param pts subject poly vertices - * @param bounds clipping boundary vertices - * @param bc pre-computed boundary centroid - * @param eps edge classification tolerance - */ -export const sutherlandHodgeman = - (pts: ReadonlyVec[], bounds: ReadonlyVec[], bc: ReadonlyVec, eps = 1e-4) => { - for (let ne = bounds.length, j = ne - 1, i = 0; i < ne; j = i, i++) { - const clipped = []; - const ca = bounds[j]; - const cb = bounds[i]; - const sign = classify(ca, cb, bc, eps); - for (let np = pts.length, k = np - 1, l = 0; l < np; k = l, l++) { - const p = pts[k]; - const q = pts[l]; - const cqsign = classify(ca, cb, q, eps); - if (classify(ca, cb, p, eps) === sign) { - clipped.push( - cqsign !== sign ? - intersectLines2(ca, cb, p, q).isec : - q - ); - } else if (cqsign === sign) { - clipped.push(intersectLines2(ca, cb, p, q).isec, q); - } - } - if (clipped.length < 2) { - return []; - } - pts = clipped; - } - return pts; - }; diff --git a/packages/geom2/src/internal/transform.ts b/packages/geom2/src/internal/transform.ts deleted file mode 100644 index 0f02d2dbe3..0000000000 --- a/packages/geom2/src/internal/transform.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Mat, mulV } from "@thi.ng/matrices"; -import { ReadonlyVec } from "@thi.ng/vectors3"; - -export const transformPoints = (pts: ReadonlyVec[], mat: Mat) => - pts.map((p) => mulV([], mat, p)); diff --git a/packages/geom2/src/internal/warp.ts b/packages/geom2/src/internal/warp.ts deleted file mode 100644 index 30c9b9dfe3..0000000000 --- a/packages/geom2/src/internal/warp.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ReadonlyVec } from "@thi.ng/vectors3"; -import { IShape, mapPoint, unmapPoint } from "../api"; - -export const warpPoints = - (src: ReadonlyVec[], srcBounds: IShape, dest: IShape) => - src.map((p) => unmapPoint(dest, mapPoint(srcBounds, p))); diff --git a/packages/geom2/src/line.ts b/packages/geom2/src/line.ts deleted file mode 100644 index f33abed00b..0000000000 --- a/packages/geom2/src/line.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { implementations } from "@thi.ng/defmulti"; -import { Mat } from "@thi.ng/matrices"; -import { - dist, - mixN, - ReadonlyVec, - sub, - Vec -} from "@thi.ng/vectors3"; -import { - arcLength, - asCubic, - asPolyline, - Attribs, - bounds, - centroid, - Cubic2, - flip, - intersectLine, - Line2, - offset, - perimeter, - pointAt, - Polygon2, - Polyline2, - Rect2, - resample, - tangentAt, - transform, - Type, - VecPair, - vertices -} from "./api"; -import { direction } from "./internal/direction"; -import { intersectLines2 } from "./internal/line-intersection"; -import { offsetLine } from "./internal/offset"; -import { transformPoints } from "./internal/transform"; -import "./polygon"; - -export function line(a: Vec, b: Vec, attribs?: Attribs) { - return new Line2([a, b], attribs); -} - -export const lineNormal = (a: ReadonlyVec, b: ReadonlyVec, out?: Vec) => - sub(out, b, a); - -implementations( - Type.LINE2, - - { - [Type.POINTS2]: [ - flip, - ], - [Type.POLYLINE2]: [ - resample, - vertices, - ], - }, - - arcLength, - (line: Line2) => - dist(line.a, line.b), - - asCubic, - (line: Line2) => - [Cubic2.fromLine(line.a, line.b, { ...line.attribs })], - - asPolyline, - (line: Line2) => - new Polyline2([...line.points], { ...line.attribs }), - - bounds, - (line: Line2) => - Rect2.fromMinMax(...line.points), - - centroid, - (line: Line2, c: Vec = []) => - mixN(c, line.a, line.b, 0.5), - - intersectLine, - (l1: Line2, l2: Line2) => - intersectLines2(l1.a, l1.b, l2.a, l2.b), - - offset, - (line: Line2, dist: number, res = 8) => - new Polygon2( - offsetLine(line.points, dist, res), - { ...line.attribs } - ), - - perimeter, - (line: Line2) => - dist(...line.points), - - pointAt, - (line: Line2, t: number) => - mixN([], line.a, line.b, t), - - tangentAt, - (line: Line2, _, n = 1) => - direction(line.a, line.b, n), - - transform, - (line: Line2, mat: Mat) => - new Line2( - transformPoints(line.points, mat), - { ...line.attribs } - ), -); diff --git a/packages/geom2/src/path.ts b/packages/geom2/src/path.ts deleted file mode 100644 index da9c27997f..0000000000 --- a/packages/geom2/src/path.ts +++ /dev/null @@ -1,538 +0,0 @@ -import { isNumber } from "@thi.ng/checks"; -import { implementations } from "@thi.ng/defmulti"; -import { eqDelta, rad } from "@thi.ng/math"; -import { Mat, mulV } from "@thi.ng/matrices"; -import { - comp, - ensureArray, - filter, - iterator1, - map, - mapcat, - peek -} from "@thi.ng/transducers"; -import { - add, - add2, - copy, - maddN, - mulN2, - ReadonlyVec, - set2, - sub2, - Vec, - zeroes -} from "@thi.ng/vectors3"; -import { - Arc2, - asCubic, - asPolygon, - asPolyline, - Attribs, - bounds, - centroid, - Cubic2, - Line2, - Path2, - PathSegment, - Polygon2, - Polyline2, - Quadratic2, - SamplingOpts, - SegmentType, - simplify, - transform, - translate, - Type, - vertices -} from "./api"; -import { arcFrom2Points } from "./arc"; -import { collBounds } from "./internal/bounds"; -import "./polygon"; -import "./polyline"; -import { douglasPeucker2 } from "./internal/douglas–peucker"; - -const CMD_RE = /[achlmqstvz]/i; - -export function path(segments?: PathSegment[], attribs?: Attribs) { - return new Path2(segments, attribs); -} - -export const roundedRect = (pos: Vec, size: Vec, r: number | Vec) => { - r = isNumber(r) ? [r, r] : r; - const b = new PathBuilder(); - const [w, h] = maddN([], size, r, -2); - b.moveTo([pos[0] + r[0], pos[1]]); - b.hlineTo(w, true); - b.arcTo(r, r, 0, false, true, true); - b.vlineTo(h, true); - b.arcTo([-r[0], r[1]], r, 0, false, true, true); - b.hlineTo(-w, true); - b.arcTo([-r[0], -r[1]], r, 0, false, true, true); - b.vlineTo(-h, true); - b.arcTo([r[0], -r[1]], r, 0, false, true, true); - return b.curr; -}; - -export const normalizePath = (path: Path2) => - new Path2([...mapcat( - (s) => - s.geo ? - map( - (c) => ({ type: SegmentType.CUBIC, geo: c }), - asCubic(s.geo) - ) : - [{ ...s }], - path.segments - )]); - -export const pathFromSVG = (svg: string) => { - const b = new PathBuilder(); - try { - let cmd: string; - for (let n = svg.length, i = 0; i < n;) { - i = skipWS(svg, i); - const c = svg.charAt(i); - if (CMD_RE.test(c)) { - cmd = c; - i++; - } - let p, pa, pb, t1, t2, t3; - switch (cmd.toLowerCase()) { - case "m": - [p, i] = readPoint(svg, i); - b.moveTo(p, cmd === "m"); - break; - case "l": - [p, i] = readPoint(svg, i); - b.lineTo(p, cmd === "l"); - break; - case "h": - [p, i] = readFloat(svg, i); - b.hlineTo(p, cmd === "h"); - break; - case "v": - [p, i] = readFloat(svg, i); - b.vlineTo(p, cmd === "v"); - break; - case "q": - [pa, i] = readPoint(svg, i); - [p, i] = readPoint(svg, i); - // console.log("quadratic", pa.toString(), p.toString()); - b.quadraticTo(pa, p, cmd === "q"); - break; - case "c": - [pa, i] = readPoint(svg, i); - [pb, i] = readPoint(svg, i); - [p, i] = readPoint(svg, i); - // console.log("cubic", pa.toString(), pb.toString(), p.toString()); - b.cubicTo(pa, pb, p, cmd === "c"); - break; - case "s": - [pa, i] = readPoint(svg, i); - [p, i] = readPoint(svg, i); - // console.log("cubicChain", pa.toString(), p.toString()); - b.cubicChainTo(pa, p, cmd === "s"); - break; - case "t": - [p, i] = readPoint(svg, i); - // console.log("quadraticChain", p.toString()); - b.quadraticChainTo(p, cmd === "t"); - break; - case "a": { - [pa, i] = readPoint(svg, i); - [t1, i] = readFloat(svg, i); - [t2, i] = readFloat(svg, i); - [t3, i] = readFloat(svg, i); - [pb, i] = readPoint(svg, i); - // console.log("arc", pa.toString(), rad(t1), t2, t3, pb.toString()); - b.arcTo(pb, pa, rad(t1), !!t2, !!t3, cmd === "a"); - break; - } - case "z": - b.closePath(); - break; - default: - throw new Error(`unsupported segment type: ${c} @ pos ${i}`); - } - } - return b.paths; - } catch (e) { - throw e instanceof Error ? e : new Error(`illegal char '${svg.charAt(e)}' @ ${e}`); - } -}; - -implementations( - Type.PATH2, - - null, - - asCubic, - (path: Path2) => - [...mapcat( - (s) => s.geo ? asCubic(s.geo) : undefined, - path.segments - )], - - asPolygon, - (path: Path2, opts?: number | Partial) => - new Polygon2(vertices(path, opts), { ...path.attribs }), - - asPolyline, - (path: Path2, opts?: number | Partial) => - new Polyline2(vertices(path, opts), { ...path.attribs }), - - bounds, - (path: Path2) => - collBounds([...iterator1( - comp( - map((s: PathSegment) => s.geo), - filter((s) => !!s), - ), - path.segments) - ]), - - centroid, - (path: Path2) => centroid(bounds(path)), - - simplify, - (path: Path2, eps = 0.1) => { - const res: PathSegment[] = []; - const orig = path.segments; - const n = orig.length; - let points: Vec[]; - let lastP: Vec; - for (let i = 0; i < n; i++) { - const s = orig[i]; - if (s.type === SegmentType.LINE || s.type === SegmentType.POLYLINE) { - points = (points || []).concat(ensureArray(vertices(s.geo))); - lastP = peek(points); - } else if (points) { - points.push(lastP); - res.push({ - geo: new Polyline2(douglasPeucker2(points, eps)), - type: SegmentType.POLYLINE, - }); - points = null; - } else { - res.push({ ...s }); - } - } - if (points) { - points.push(lastP); - res.push({ - geo: new Polyline2(points), - type: SegmentType.POLYLINE, - }); - } - return new Path2(res, { ...path.attribs }); - }, - - transform, - (path: Path2, mat: Mat) => - new Path2( - [...mapcat((s) => transformSegment(s, mat), path.segments)], - { ...path.attribs } - ), - - translate, - (path: Path2, delta: ReadonlyVec) => - new Path2( - path.segments.map((s) => - s.geo ? - { - type: s.type, - geo: translate(s.geo, delta) - } : - { - type: s.type, - point: add2([], s.point, delta) - } - ), - { ...path.attribs } - ), - - vertices, - (path: Path2, opts?: number | Partial) => { - const _opts = isNumber(opts) ? { num: opts } : opts; - let verts: Vec[] = []; - for (let segs = path.segments, n = segs.length - 1, i = 0; i <= n; i++) { - const s = segs[i]; - if (s.geo) { - verts = verts.concat( - ensureArray( - vertices(s.geo, { ..._opts, last: i === n && !path.closed }) - ) - ); - } - } - return verts; - } -); - -export class PathBuilder { - - paths: Path2[]; - curr: Path2; - protected currP: Vec; - protected bezierP: Vec; - protected startP: Vec; - - constructor() { - this.paths = []; - this.newPath(); - } - - *[Symbol.iterator]() { - yield* this.paths; - } - - newPath() { - this.curr = new Path2(); - this.paths.push(this.curr); - this.currP = zeroes(2); - this.bezierP = zeroes(2); - this.startP = zeroes(2); - } - - moveTo(p: Vec, relative = false): PathBuilder { - if (this.curr.segments.length > 0) { - this.curr = new Path2(); - this.paths.push(this.curr); - } - p = this.updateCurrent(p, relative); - set2(this.startP, p); - set2(this.bezierP, p); - this.curr.add({ - point: p, - type: SegmentType.MOVE, - }); - return this; - } - - lineTo(p: Vec, relative = false): PathBuilder { - this.curr.add({ - geo: new Line2([ - copy(this.currP), - this.updateCurrent(p, relative) - ]), - type: SegmentType.LINE, - }); - set2(this.bezierP, this.currP); - return this; - } - - hlineTo(x: number, relative = false): PathBuilder { - const prev = copy(this.currP); - this.currP[0] = relative ? this.currP[0] + x : x; - set2(this.bezierP, this.currP); - this.curr.add({ - geo: new Line2([prev, copy(this.currP)]), - type: SegmentType.LINE, - }); - return this; - } - - vlineTo(y: number, relative = false): PathBuilder { - const prev = copy(this.currP); - this.currP[1] = relative ? this.currP[1] + y : y; - set2(this.bezierP, this.currP); - this.curr.add({ - geo: new Line2([prev, copy(this.currP)]), - type: SegmentType.LINE, - }); - return this; - } - - // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#Cubic_B%C3%A9zier_Curve - cubicTo(cp1: Vec, cp2: Vec, p: Vec, relative = false) { - const c2 = this.absPoint(cp2, relative); - set2(this.bezierP, c2); - this.curr.add({ - geo: new Cubic2([ - copy(this.currP), - this.absPoint(cp1, relative), - c2, - this.updateCurrent(p, relative), - ]), - type: SegmentType.CUBIC, - }); - return this; - } - - // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#Quadratic_B%C3%A9zier_Curve - quadraticTo(cp: Vec, p: Vec, relative = false) { - const c1 = this.absPoint(cp, relative); - set2(this.bezierP, c1); - this.curr.add({ - geo: new Quadratic2([ - copy(this.currP), - c1, - this.updateCurrent(p, relative), - ]), - type: SegmentType.QUADRATIC, - }); - return this; - } - - cubicChainTo(cp2: Vec, p: Vec, relative = false) { - const prevMode = peek(this.curr.segments).type; - const c1 = copy(this.currP); - if (prevMode === SegmentType.CUBIC) { - add2(null, sub2([], c1, this.bezierP), c1); - } - const c2 = this.absPoint(cp2, relative); - set2(this.bezierP, c2); - this.curr.add({ - geo: new Cubic2([ - copy(this.currP), - c1, - c2, - this.updateCurrent(p, relative), - ]), - type: SegmentType.CUBIC, - }); - return this; - } - - quadraticChainTo(p: Vec, relative = false) { - const prevMode = peek(this.curr.segments).type; - const c1 = copy(this.currP); - if (prevMode === SegmentType.QUADRATIC) { - sub2(null, mulN2(null, c1, 2), this.bezierP); - } - set2(this.bezierP, c1); - this.curr.add({ - geo: new Quadratic2([ - copy(this.currP), - c1, - this.updateCurrent(p, relative), - ]), - type: SegmentType.CUBIC, - }); - return this; - } - - arcTo(p: Vec, r: Vec, xaxis: number, xl: boolean, clockwise: boolean, relative = false) { - if (eqDelta(r[0], 0) || eqDelta(r[1], 0)) { - return this.lineTo(p, relative); - } - const prev = copy(this.currP); - this.curr.add({ - geo: arcFrom2Points( - prev, - this.updateCurrent(p, relative), - r, - xaxis, - xl, - clockwise - ), - type: SegmentType.ARC, - }); - set2(this.bezierP, this.currP); - return this; - } - - closePath() { - this.curr.add({ - geo: new Line2([copy(this.currP), copy(this.startP)]), - type: SegmentType.LINE, - }); - this.curr.closed = true; - return this; - } - - protected updateCurrent(p: Vec, relative: boolean) { - p = copy(relative ? add2(null, this.currP, p) : set2(this.currP, p)); - return p; - } - - protected absPoint(p: Vec, relative: boolean) { - return relative ? add(null, p, this.currP) : p; - } -} - -const transformSegment = (s: PathSegment, mat: Mat): Iterable => { - if (s.geo) { - return s.geo instanceof Arc2 ? - map( - (c) => ({ - type: SegmentType.CUBIC, - geo: transform(c, mat) - }), - asCubic(s.geo) - ) : - [{ - type: s.type, - geo: transform(s.geo, mat) - }]; - } - return s.point ? - [{ type: s.type, point: mulV([], mat, s.point) }] : - [{ ...s }]; -}; - -const readPoint = - (src: string, index: number): [Vec, number] => { - let x, y; - [x, index] = readFloat(src, index); - index = skipWS(src, index); - [y, index] = readFloat(src, index); - return [[x, y], index]; - }; - -const isWS = - (c: string) => c === " " || c === "\n" || c === "\r" || c === "\t"; - -const skipWS = - (src: string, i: number) => { - const n = src.length; - while (i < n && isWS(src.charAt(i))) i++; - return i; - }; - -const readFloat = - (src: string, index: number) => { - index = skipWS(src, index); - let signOk = true; - let dotOk = true; - let expOk = false; - let commaOk = false; - let i = index; - for (let n = src.length; i < n; i++) { - const c = src.charAt(i); - // console.log("float", src.substring(index, i + 1)); - if ("0" <= c && c <= "9") { - expOk = true; - commaOk = true; - signOk = false; - continue; - } - if (c === "-" || c === "+") { - if (!signOk) break; - signOk = false; - continue; - } - if (c === ".") { - if (!dotOk) break; - dotOk = false; - continue; - } - if (c === "e") { - if (!expOk) throw i; - expOk = false; - dotOk = false; - signOk = true; - continue; - } - if (c === ",") { - if (!commaOk) throw i; - i++; - } - break; - } - if (i === index) { - throw new Error(`expected coordinate @ pos: ${i}`); - } - return [parseFloat(src.substring(index, i)), i]; - }; diff --git a/packages/geom2/src/polygon.ts b/packages/geom2/src/polygon.ts deleted file mode 100644 index d436f146da..0000000000 --- a/packages/geom2/src/polygon.ts +++ /dev/null @@ -1,250 +0,0 @@ -import { isPlainObject } from "@thi.ng/checks"; -import { implementations } from "@thi.ng/defmulti"; -import { TAU } from "@thi.ng/math"; -import { Mat } from "@thi.ng/matrices"; -import { - cycle, - map, - normRange, - partition, - push, - reduced, - Reducer, - transduce, - tuples, - wrap -} from "@thi.ng/transducers"; -import { - add2, - cartesian2, - ReadonlyVec, - signedArea2, - Vec -} from "@thi.ng/vectors3"; -import { - arcLength, - area, - asPolygon, - Attribs, - bounds, - centroid, - clipConvex, - ClipMode, - convexHull, - Convexity, - difference, - edges, - flip, - intersection, - IShape, - offset, - perimeter, - pointAt, - pointInside, - Polygon2, - resample, - SamplingOpts, - simplify, - subdivide, - SubdivKernel, - tangentAt, - tessellate, - Tessellator, - transform, - translate, - Type, - union, - vertices -} from "./api"; -import "./container2"; -import { arcLength as _arcLength } from "./internal/arc-length"; -import { centerOfWeight2 } from "./internal/centroid"; -import { edges as _edges } from "./internal/edges"; -import { booleanOp } from "./internal/greiner-hormann"; -import { offset as _offset } from "./internal/offset"; -import { perimeter as _perimeter } from "./internal/perimeter"; -import { pointInside as _pointInside, polygonArea } from "./internal/polygon"; -import { Sampler } from "./internal/sampler"; -import { subdivideCurve } from "./internal/subdiv-curve"; -import { sutherlandHodgeman } from "./internal/sutherland-hodgeman"; -import { transformPoints } from "./internal/transform"; -import { tessellatePoints } from "./tessellate"; -import { douglasPeucker2 } from "./internal/douglas–peucker"; - -export function polygon(points: Vec[], attribs?: Attribs): Polygon2 { - return new Polygon2(points, attribs); -} - -export const star = (r: number, n: number, profile: number[]) => { - const total = n * profile.length; - const pts = transduce( - map(([i, p]) => cartesian2(null, [r * p, i * TAU])), - push(), - tuples(normRange(total, false), cycle(profile)) - ); - return new Polygon2(pts); -}; - -const convexityReducer: Reducer = [ - () => 0, - (x) => x, - (type, [a, b, c]) => { - const t = signedArea2(a, b, c); - if (t < 0) { - type |= 1; - } else if (t > 0) { - type |= 2; - } - return t === 3 ? reduced(3) : type; - } -]; - -export const convexity = (poly: Polygon2) => { - if (poly.points.length < 3) { - return Convexity.COLINEAR; - } - const type = transduce( - partition(3, 1), - convexityReducer, - wrap(poly.points, 1) - ); - return type === 3 ? - Convexity.CONCAVE : - type !== 0 ? Convexity.CONVEX : Convexity.COLINEAR; -}; - -implementations( - Type.POLYGON2, - - { - [Type.POINTS2]: [ - bounds, - convexHull, - flip, - vertices - ] - }, - - arcLength, - (poly: Polygon2) => - _arcLength(poly.points, true), - - area, - (poly: Polygon2, signed = true) => { - const area = polygonArea(poly.points); - return signed ? area : Math.abs(area); - }, - - asPolygon, - (poly: Polygon2) => poly, - - centroid, - (poly: Polygon2, c: Vec) => - centerOfWeight2(poly.points, c), - - clipConvex, - (poly: Polygon2, boundary: IShape) => - new Polygon2( - sutherlandHodgeman(poly.points, vertices(boundary), centroid(boundary)), - { ...poly.attribs } - ), - - difference, - (poly: Polygon2, other: IShape) => - booleanOp([poly.points], vertices(other), ClipMode.DIFF_A) - .map((pts) => new Polygon2(pts, { ...poly.attribs })), - - edges, - (poly: Polygon2, opts?: number | Partial) => - _edges(vertices(poly, opts), true), - - intersection, - (poly: Polygon2, other: IShape) => - booleanOp([poly.points], vertices(other), ClipMode.INTERSECTION) - .map((pts) => new Polygon2(pts)), - - offset, - (poly: Polygon2, dist: number, res = 8) => { - const pts = _offset(poly.points, dist, res, true); - return pts ? - new Polygon2(pts, { ...poly.attribs }) : - undefined; - }, - - perimeter, - (poly: Polygon2) => - _perimeter(poly.points, true), - - pointAt, - (poly: Polygon2, t: number) => - new Sampler(poly.points, true).pointAt(t), - - pointInside, - (poly: Polygon2, [x, y]: ReadonlyVec) => { - const pts = poly.points; - let inside = 0; - for (let n = pts.length - 1, i = n, j = 0; j <= n; i = j, j++) { - inside = _pointInside(pts[i], pts[j], x, y, inside); - } - return inside; - }, - - resample, - (poly: Polygon2, opts?: number | Partial) => - new Polygon2(vertices(poly, opts), { ...poly.attribs }), - - simplify, - (poly: Polygon2, eps = 0.1) => - new Polygon2( - douglasPeucker2(poly.points, eps, true), - { ...poly.attribs } - ), - - subdivide, - (poly: Polygon2, kernel: SubdivKernel, iter = 1) => - new Polygon2( - subdivideCurve(kernel, poly.points, iter, true), - { ...poly.attribs } - ), - - tangentAt, - (poly: Polygon2, t: number, n = 1) => - new Sampler(poly.points, true).tangentAt(t, n), - - tessellate, - (poly: Polygon2, tessel: Iterable) => - tessellatePoints(poly.points, tessel), - - transform, - (poly: Polygon2, mat: Mat) => - new Polygon2( - transformPoints(poly.points, mat), - { ...poly.attribs } - ), - - translate, - (poly: Polygon2, delta: ReadonlyVec) => - new Polygon2( - poly.points.map((p) => add2([], p, delta)), - { ...poly.attribs } - ), - - union, - (poly: Polygon2, other: IShape) => - booleanOp([poly.points], vertices(other), ClipMode.UNION) - .map((pts) => new Polygon2(pts)), - - vertices, - (poly: Polygon2, opts?: number | Partial) => { - if (opts !== undefined) { - const sampler = new Sampler(poly.points, true); - return isPlainObject(opts) ? - opts.dist ? - sampler.sampleUniform(opts.dist, opts.last) : - sampler.sampleFixedNum(opts.num, opts.last) : - sampler.sampleFixedNum(opts, false); - } - return poly.points; - }, - -); diff --git a/packages/geom2/src/polyline.ts b/packages/geom2/src/polyline.ts deleted file mode 100644 index 63aaaf4a5b..0000000000 --- a/packages/geom2/src/polyline.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { isPlainObject } from "@thi.ng/checks"; -import { implementations } from "@thi.ng/defmulti"; -import { Mat } from "@thi.ng/matrices"; -import { map } from "@thi.ng/transducers"; -import { add2, ReadonlyVec, Vec } from "@thi.ng/vectors3"; -import { - arcLength, - asCubic, - Attribs, - bounds, - centroid, - convexHull, - Cubic2, - DEFAULT_SAMPLES, - edges, - flip, - offset, - perimeter, - Polygon2, - Polyline2, - resample, - SamplingOpts, - simplify, - subdivide, - SubdivKernel, - tangentAt, - transform, - translate, - Type, - vertices -} from "./api"; -import "./container2"; -import { arcLength as _arcLength } from "./internal/arc-length"; -import { centroid as _centroid } from "./internal/centroid"; -import { edges as _edges } from "./internal/edges"; -import { offset as _offset } from "./internal/offset"; -import { perimeter as _perimeter } from "./internal/perimeter"; -import { Sampler } from "./internal/sampler"; -import { subdivideCurve } from "./internal/subdiv-curve"; -import { transformPoints } from "./internal/transform"; -import { douglasPeucker2 } from "./internal/douglas–peucker"; - -export function polyline(points: Vec[], attribs?: Attribs): Polyline2 { - return new Polyline2(points, attribs); -} - -implementations( - Type.POLYLINE2, - - { - [Type.POINTS2]: [ - bounds, - centroid, - convexHull, - flip - ], - }, - - arcLength, - (poly: Polygon2) => - _arcLength(poly.points), - - asCubic, - (line: Polyline2) => - map((e) => Cubic2.fromLine(...e), _edges(line.points)), - - edges, - (line: Polyline2, opts: number | SamplingOpts) => - _edges(vertices(line, opts), true), - - offset, - (line: Polyline2, dist: number, res = 8) => { - const pts = _offset(line.points, dist, res, false); - return pts ? - new Polygon2(pts, { ...line.attribs }) : - undefined; - }, - - perimeter, - (line: Polyline2) => _perimeter(line.points, false), - - resample, - (line: Polyline2, opts?: number | Partial) => - new Polyline2(vertices(line, opts), { ...line.attribs }), - - simplify, - (line: Polyline2, eps = 0.1) => - new Polyline2( - douglasPeucker2(line.points, eps, true), - { ...line.attribs } - ), - - subdivide, - (line: Polyline2, kernel: SubdivKernel, iter = 1) => - new Polyline2( - subdivideCurve(kernel, line.points, iter, false), - { ...line.attribs } - ), - - tangentAt, - (line: Polyline2, t: number, n = 1) => - new Sampler(line.points, false).tangentAt(t, n), - - transform, - (line: Polyline2, mat: Mat) => - new Polyline2( - transformPoints(line.points, mat), - { ...line.attribs } - ), - - translate, - (line: Polyline2, delta: ReadonlyVec) => - new Polyline2( - line.points.map((p) => add2([], p, delta)), - { ...line.attribs } - ), - - vertices, - (line: Polyline2, opts?: number | Partial) => { - if (opts !== undefined) { - const sampler = new Sampler(line.points, false); - return isPlainObject(opts) ? - opts.dist ? - sampler.sampleUniform(opts.dist, opts.last !== false) : - sampler.sampleFixedNum(opts.num, opts.last !== false) : - sampler.sampleFixedNum(opts || DEFAULT_SAMPLES, true); - } - return line.points; - }, - -); diff --git a/packages/geom2/src/quad.ts b/packages/geom2/src/quad.ts deleted file mode 100644 index 517cbda445..0000000000 --- a/packages/geom2/src/quad.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { implementations } from "@thi.ng/defmulti"; -import { Mat } from "@thi.ng/matrices"; -import { - add2, - mixBilinear2, - ReadonlyVec, - Vec -} from "@thi.ng/vectors3"; -import { - arcLength, - area, - Attribs, - bounds, - centroid, - clipConvex, - convexHull, - edges, - flip, - perimeter, - Quad2, - resample, - tessellate, - transform, - translate, - Type, - unmapPoint, - vertices -} from "./api"; -import "./container2"; -import { transformPoints } from "./internal/transform"; -import "./polygon"; - -export function quad(points: Vec[], attribs?: Attribs): Quad2 { - return new Quad2(points, attribs); -} - -implementations( - Type.QUAD2, - - { - [Type.POINTS2]: [ - bounds, - flip, - ], - [Type.POLYGON2]: [ - arcLength, - area, - centroid, - clipConvex, - convexHull, - edges, - perimeter, - resample, - tessellate, - vertices, - ], - }, - - transform, - (quad: Quad2, mat: Mat) => - new Quad2( - transformPoints(quad.points, mat), - { ...quad.attribs } - ), - - translate, - (quad: Quad2, delta: ReadonlyVec) => - new Quad2( - quad.points.map((p) => add2([], p, delta)), - { ...quad.attribs } - ), - - unmapPoint, - (quad: Quad2, p: ReadonlyVec, out?: Vec) => { - const pts = quad.points; - return mixBilinear2(out, pts[0], pts[1], pts[3], pts[2], p[0], p[1]); - }, - -); diff --git a/packages/geom2/src/ray.ts b/packages/geom2/src/ray.ts deleted file mode 100644 index 8cd3b51df7..0000000000 --- a/packages/geom2/src/ray.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { implementations } from "@thi.ng/defmulti"; -import { maddN, Vec } from "@thi.ng/vectors3"; -import { pointAt, Ray, Type } from "./api"; - -export const ray = - (pos: Vec, dir: Vec) => new Ray(pos, dir); - -implementations( - Type.RAY, - {}, - - pointAt, - (ray: Ray, t: number) => - maddN([], ray.pos, ray.dir, t) -); diff --git a/packages/geom2/src/rect.ts b/packages/geom2/src/rect.ts deleted file mode 100644 index f414352eab..0000000000 --- a/packages/geom2/src/rect.ts +++ /dev/null @@ -1,175 +0,0 @@ -import { implementations } from "@thi.ng/defmulti"; -import { Mat } from "@thi.ng/matrices"; -import { - add2, - copy, - div2, - madd2, - maddN2, - ReadonlyVec, - sub, - Vec -} from "@thi.ng/vectors3"; -import { - arcLength, - area, - Attribs, - bounds, - centroid, - Circle2, - clipConvex, - ClipMode, - edges, - intersectShape, - IShape, - mapPoint, - perimeter, - pointAt, - pointInside, - Polygon2, - Rect2, - resample, - SamplingOpts, - tessellate, - Tessellator, - transform, - translate, - Type, - union, - unmapPoint, - vertices -} from "./api"; -import { unionBounds } from "./internal/bounds"; -import { edges as _edges } from "./internal/edges"; -import { booleanOp } from "./internal/greiner-hormann"; -import { Sampler } from "./internal/sampler"; -import { sutherlandHodgeman } from "./internal/sutherland-hodgeman"; -import { transformPoints } from "./internal/transform"; -import "./polygon"; -import { tessellatePoints } from "./tessellate"; - -export function rect(pos: Vec, size: Vec, attribs?: Attribs) { - return new Rect2(pos, size, attribs); -} - -export const rectFromMinMax = (min: Vec, max: Vec, attribs?: Attribs) => - Rect2.fromMinMax(min, max, attribs); - -implementations( - Type.RECT, - - { - [Type.POLYGON2]: [ - resample, - ] - }, - - arcLength, - (rect: Rect2) => - 2 * (rect.size[0] * rect.size[1]), - - area, - (rect: Rect2) => - rect.size[0] * rect.size[1], - - bounds, - (rect: Rect2) => rect, - - centroid, - (rect: Rect2, o?: Vec) => - maddN2(o, rect.pos, rect.size, 0.5), - - clipConvex, - (rect: Rect2, boundary: IShape) => - new Polygon2( - sutherlandHodgeman(vertices(rect), vertices(boundary), centroid(boundary)), - { ...rect.attribs } - ), - - edges, - (rect: Rect2, opts: number | Partial) => - _edges(vertices(rect, opts), true), - - mapPoint, - (rect: Rect2, p: ReadonlyVec, out: Vec = []) => - div2(null, sub(out, p, rect.pos), rect.size), - - perimeter, - (rect: Rect2) => - 2 * (rect.size[0] + rect.size[1]), - - pointAt, - (rect: Rect2, t: number) => - new Sampler(vertices(rect), true).pointAt(t), - - pointInside, - (rect: Rect2, [x, y]: ReadonlyVec) => { - const [rx, ry] = rect.pos; - const [sx, sy] = rect.size; - return x >= rx && x <= rx + sx && y >= ry && y <= ry + sy; - }, - - tessellate, - (rect: Rect2, tessel: Tessellator | Iterable, iter?: number) => - tessellatePoints(vertices(rect), tessel, iter), - - transform, - (rect: Rect2, mat: Mat) => - new Polygon2( - transformPoints(vertices(rect), mat), - { ...rect.attribs } - ), - - translate, - (rect: Rect2, delta: ReadonlyVec) => - new Rect2( - add2([], rect.pos, delta), - copy(rect.size), - { ...rect.attribs } - ), - - union, - (r1: Rect2, r2: IShape) => - r2 instanceof Rect2 ? - [new Rect2(...unionBounds(r1.pos, r1.size, r2.pos, r2.size))] : - booleanOp([vertices(r1)], vertices(r2), ClipMode.UNION) - .map((pts) => new Polygon2(pts, { ...r1.attribs })), - - unmapPoint, - (rect: Rect2, p: ReadonlyVec, out: Vec = []) => - madd2(out, rect.pos, rect.size, p), - - vertices, - (rect: Rect2, opts: number | Partial) => { - const p = rect.pos; - const q = add2([], p, rect.size); - const verts = [copy(p), [q[0], p[1]], q, [p[0], q[1]]]; - return opts != null ? - vertices(new Polygon2(verts), opts) : - verts; - }, -); - -intersectShape.addAll({ - - [`${Type.RECT}-${Type.RECT}`]: - ({ pos: { 0: ax, 1: ay }, size: { 0: aw, 1: ah } }: Rect2, - { pos: { 0: bx, 1: by }, size: { 0: bw, 1: bh } }: Rect2) => - !((ax > bx + bw) || - (bx > ax + aw) || - (ay > by + bh) || - (by > ay + ah)), - - [`${Type.RECT}-${Type.CIRCLE}`]: - ({ pos: rp, size }: Rect2, { pos: cp, r }: Circle2) => - rcAxis(cp[0], rp[0], size[0]) + - rcAxis(cp[1], rp[1], size[1]) <= r * r, - -}); - -const rcAxis = (a: number, b: number, c: number) => - a < b ? - Math.pow(a - b, 2) : - a > b + c ? - Math.pow(a - b - c, 2) : - 0; diff --git a/packages/geom2/src/sphere.ts b/packages/geom2/src/sphere.ts deleted file mode 100644 index 9ddbd5ee43..0000000000 --- a/packages/geom2/src/sphere.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { - distSq3, - dot3, - maddN3, - magSq3, - sub3, - Vec -} from "@thi.ng/vectors3"; -import { - intersectShape, - Ray, - Sphere, - Type, -} from "./api"; - -export const sphere = - (pos: Vec, r = 1) => new Sphere(pos, r); - -intersectShape.addAll({ - - [`${Type.SPHERE}-${Type.SPHERE}`]: - (a: Sphere, b: Sphere) => - distSq3(a.pos, b.pos) <= Math.pow(a.r + b.r, 2), - - [`${Type.SPHERE}-${Type.RAY}`]: - ({ pos: spos, r: r }: Sphere, { pos: rpos, dir }: Ray) => { - const delta = sub3([], spos, rpos); - const w = dot3(delta, dir); - let d = r * r + w * w - magSq3(delta); - if (d >= 0) { - d = Math.sqrt(d); - const a = w + d; - const b = w - d; - d = a >= 0 ? - b >= 0 ? - a > b ? - b : - a : - a : - b >= 0 ? - b : - undefined; - // reuse delta as out - return d !== undefined ? - maddN3(delta, rpos, dir, d) : - d; - } - }, -}); - -// export const isecRaySphere = (ray: Ray, sphere: Sphere) => { -// const w = sub3([], ray.pos, sphere.pos); -// const rd = ray.dir; -// const b = 2 * dot3(w, rd); -// const a = magSq3(rd); -// const c = magSq3(w) - sphere.r * sphere.r; -// let d = b * b - 4 * a * c; -// return d >= 0 && ((d = (-b - Math.sqrt(d)) / (2 * a)) >= 0) ? -// maddN3([], ray.pos, rd, d) : -// undefined; -// }; diff --git a/packages/geom2/src/svg.ts b/packages/geom2/src/svg.ts deleted file mode 100644 index d2297d0555..0000000000 --- a/packages/geom2/src/svg.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { serialize } from "@thi.ng/hiccup"; -import { convertTree, ff, svg } from "@thi.ng/hiccup-svg"; -import { Attribs, IShape, Rect2 } from "./api"; -import { collBounds } from "./internal/bounds"; - -export const asSvg = (...args: any[]) => - args - .map((x) => serialize(convertTree(x))) - .join(""); - -export const svgDoc = (attribs: Attribs, ...args: IShape[]) => { - if (args.length > 0) { - if (!attribs || !attribs.viewBox) { - const b = collBounds(args); - attribs = { - width: ff(b.size[0]), - height: ff(b.size[1]), - viewBox: `${ff(b.pos[0])} ${ff(b.pos[1])} ${ff(b.size[0])} ${ff(b.size[1])}`, - ...attribs - }; - } - } - return svg(attribs, ...args); -}; diff --git a/packages/geom2/src/tessellate.ts b/packages/geom2/src/tessellate.ts deleted file mode 100644 index 3da971eed4..0000000000 --- a/packages/geom2/src/tessellate.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { isFunction } from "@thi.ng/checks"; -import { - comp, - last, - map, - mapcat, - partition, - push, - range, - reducer, - repeat, - scan, - transduce, - tuples, - wrap -} from "@thi.ng/transducers"; -import { - mixN, - ReadonlyVec, - signedArea2, - Vec -} from "@thi.ng/vectors3"; -import { Tessellator } from "./api"; -import { centroid } from "./internal/centroid"; -import { pointInTriangle2 } from "./internal/corner"; -import { polygonArea } from "./internal/polygon"; - -const snip = (points: ReadonlyVec[], u: number, v: number, w: number, n: number, ids: number[]) => { - const a = points[ids[u]]; - const b = points[ids[v]]; - const c = points[ids[w]]; - if (signedArea2(a, b, c) > 0) { - for (let i = 0; i < n; i++) { - if (i !== u && i !== v && i !== w) { - if (pointInTriangle2(points[ids[i]], a, b, c)) { - return; - } - } - } - return [a, b, c]; - } -}; - -export const earCut = (points: ReadonlyVec[]) => { - const tris: Vec[][] = []; - let n = points.length; - const ids = [ - ...(polygonArea(points) > 0 ? - range(n) : - range(n - 1, -1, -1)) - ]; - let count = 2 * n - 1; - let v = n - 1, u, w, t; - while (count > 0 && n > 2) { - u = n <= v ? 0 : v; - v = u + 1; - v = n <= v ? 0 : v; - w = v + 1; - w = n <= w ? 0 : w; - t = snip(points, u, v, w, n, ids); - if (t !== undefined) { - tris.push(t); - ids.splice(v, 1); - n--; - count = 2 * n; - } else { - count--; - } - } - return tris; -}; - -export const triFan = (points: ReadonlyVec[]) => { - const c = centroid(points); - return transduce( - comp( - partition(2, 1), - map(([a, b]) => [a, b, c]) - ), - push(), - wrap(points, 1, false, true) - ); -}; - -export const quadFan = (points: ReadonlyVec[]) => { - const p = centroid(points); - return transduce( - comp( - partition(3, 1), - map(([a, b, c]) => [mixN([], a, b, 0.5), b, mixN([], b, c, 0.5), p]) - ), - push(), - wrap(points, 1, true, true) - ); -}; - -export const edgeSplit = (points: ReadonlyVec[]) => { - const c = centroid(points); - return transduce( - comp( - partition(2, 1), - mapcat(([a, b]) => { - const m = mixN([], a, b, 0.5); - return [[a, m, c], [m, b, c]]; - })), - push(), - wrap(points, 1, false, true) - ); -}; - -export const rimTris = (points: ReadonlyVec[]) => { - const edgeCentroids = transduce( - comp( - partition(2, 1), - map((e) => mixN([], e[0], e[1], 0.5)) - ), - push(), - wrap(points, 1, false, true) - ); - return transduce( - comp( - partition(2, 1), - map((t) => [t[0][0], t[1][1], t[1][0]]) - ), - push(), - [edgeCentroids], - wrap([...tuples(edgeCentroids, points)], 1, true, false) - ); -}; - -export const inset = (inset = 0.5, keepInterior = false) => - (points: ReadonlyVec[]) => { - const c = centroid(points); - const inner = points.map((p) => mixN([], p, c, inset)); - return transduce( - comp( - partition(2, 1), - map(([[a, b], [c, d]]) => [a, b, d, c]) - ), - push(), - keepInterior ? [inner] : [], - wrap([...tuples(points, inner)], 1, false, true) - ); - }; - -export function tessellatePoints(points: ReadonlyVec[], tessFn: Tessellator, iter?: number): Vec[][]; -export function tessellatePoints(points: ReadonlyVec[], tessFns: Iterable): Vec[][]; -export function tessellatePoints(...args): Vec[][] { - return transduce( - scan( - reducer( - () => [args[0]], - (acc: Vec[][], fn: Tessellator) => - transduce( - mapcat(fn), - push(), - acc - ) - ) - ), - last(), - isFunction(args[1]) ? - repeat(args[1], args[2] || 1) : - args[1] - ); -} diff --git a/packages/geom2/src/triangle.ts b/packages/geom2/src/triangle.ts deleted file mode 100644 index 09f86ee779..0000000000 --- a/packages/geom2/src/triangle.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { implementations } from "@thi.ng/defmulti"; -import { PI } from "@thi.ng/math"; -import { Mat } from "@thi.ng/matrices"; -import { - add, - divN, - maddN, - mag, - normalize, - perpendicularLeft2, - ReadonlyVec, - signedArea2, - sub, - Vec -} from "@thi.ng/vectors3"; -import { - arcLength, - area, - Attribs, - bounds, - centroid, - classifyPoint, - clipConvex, - convexHull, - edges, - perimeter, - pointInside, - resample, - tessellate, - transform, - translate, - Triangle2, - Type, - vertices -} from "./api"; -import { classifyPointInTriangle2, pointInTriangle2 } from "./internal/corner"; -import { transformPoints } from "./internal/transform"; - -export function triangle(a: Vec, b: Vec, c: Vec, attribs?: Attribs) { - return new Triangle2([a, b, c], attribs); -} - -export const equilateralTriangle2 = (a: Vec, b: Vec) => { - const dir = sub([], b, a); - const c = normalize(null, perpendicularLeft2([], dir), mag(dir) * Math.sin(PI / 3)); - return new Triangle2([a, b, maddN(null, c, dir, 0.5)]); -}; - -implementations( - Type.TRIANGLE2, - - { - [Type.POINTS2]: [ - bounds, - ], - [Type.POLYGON2]: [ - arcLength, - clipConvex, - edges, - perimeter, - resample, - tessellate, - vertices, - ] - }, - - area, - (tri: Triangle2, signed = true) => { - const area = 0.5 * signedArea2(...<[Vec, Vec, Vec]>tri.points); - return signed ? area : Math.abs(area); - }, - - centroid, - (tri: Triangle2, c?: Vec) => { - const pts = tri.points; - return divN(null, add(null, add(c, pts[0], pts[1]), pts[2]), 3); - }, - - classifyPoint, - (tri: Triangle2, p: ReadonlyVec) => - classifyPointInTriangle2(p, ...<[Vec, Vec, Vec]>tri.points), - - convexHull, - (tri: Triangle2) => tri, - - pointInside, - (tri: Triangle2, p: ReadonlyVec) => - pointInTriangle2(p, ...<[Vec, Vec, Vec]>tri.points), - - transform, - (tri: Triangle2, mat: Mat) => - new Triangle2( - transformPoints(tri.points, mat), - { ...tri.attribs } - ), - - translate, - (tri: Triangle2, delta: ReadonlyVec) => - new Triangle2( - tri.points.map((p) => add([], p, delta)), - { ...tri.attribs } - ), -); diff --git a/packages/geom2/test/api.ts b/packages/geom2/test/api.ts deleted file mode 100644 index 2a8bf7d623..0000000000 --- a/packages/geom2/test/api.ts +++ /dev/null @@ -1,381 +0,0 @@ -import { DEFAULT, MultiFn } from "@thi.ng/defmulti"; -import * as assert from "assert"; -import { - area, - asCubic, - asPolygon, - asPolyline, - bounds, - center, - centroid, - classifyPoint, - clipConvex, - closestPoint, - convexHull, - depth, - difference, - edges, - extrude, - flip, - height, - intersection, - intersectLine, - intersectShape, - mapPoint, - normalAt, - offset, - perimeter, - pointAt, - pointInside, - resample, - simplify, - splitAt, - subdivide, - tangentAt, - tessellate, - transform, - translate, - Type, - union, - unmapPoint, - vertices, - warp, - width -} from "../src"; - -const _DEFAULT = DEFAULT.toString(); - -const checkImpls = (fn: MultiFn, types: PropertyKey[]) => - assert.deepEqual( - [...fn.impls()].map((x) => x.toString()).sort(), - types.map((x) => x.toString()).sort() - ); - -describe("api", () => { - - it("area", () => - checkImpls(area, [ - _DEFAULT, - Type.CIRCLE, - Type.ELLIPSE, - Type.GROUP, - Type.POLYGON2, - Type.QUAD2, - Type.RECT, - Type.TRIANGLE2, - ])); - - it("asCubic", () => - checkImpls(asCubic, [ - Type.ARC2, - Type.CUBIC2, - Type.LINE2, - Type.PATH2, - Type.POLYLINE2, - Type.QUADRATIC2, - ])); - - it("asPolygon", () => - checkImpls(asPolygon, [ - _DEFAULT, - Type.ELLIPSE, - Type.PATH2, - Type.POLYGON2, - ])); - - it("asPolyline", () => - checkImpls(asPolyline, [ - _DEFAULT, - Type.CUBIC2, - Type.LINE2, - Type.PATH2, - Type.QUADRATIC2, - ])); - - it("bounds", () => - checkImpls(bounds, [ - Type.ARC2, - Type.CIRCLE, - Type.CUBIC2, - Type.ELLIPSE, - Type.GROUP, - Type.LINE2, - Type.PATH2, - Type.POINTS2, - Type.POLYGON2, - Type.POLYLINE2, - Type.QUAD2, - Type.QUADRATIC2, - Type.RECT, - Type.TRIANGLE2, - ])); - - it("center", () => - checkImpls(center, [ - _DEFAULT, - Type.CIRCLE, - Type.ELLIPSE - ])); - - it("centroid", () => - checkImpls(centroid, [ - Type.ARC2, - Type.CIRCLE, - Type.ELLIPSE, - Type.GROUP, - Type.LINE2, - Type.PATH2, - Type.POINTS2, - Type.POLYGON2, - Type.POLYLINE2, - Type.QUAD2, - Type.RECT, - Type.TRIANGLE2, - ])); - - it("classifyPoint", () => - checkImpls(classifyPoint, [ - Type.CIRCLE, - Type.TRIANGLE2, - ])); - - it("closestPoint", () => - checkImpls(closestPoint, [ - Type.CIRCLE, - ])); - - it("clipConvex", () => - checkImpls(clipConvex, [ - Type.POLYGON2, - Type.QUAD2, - Type.RECT, - Type.TRIANGLE2, - ])); - - it("convexHull", () => - checkImpls(convexHull, [ - Type.POINTS2, - Type.POLYGON2, - Type.POLYLINE2, - Type.QUAD2, - Type.TRIANGLE2, - ])); - - it("depth", () => - checkImpls(depth, [ - _DEFAULT, - ])); - - it("difference", () => - checkImpls(difference, [ - Type.POLYGON2, - ])); - - it("edges", () => - checkImpls(edges, [ - Type.POLYGON2, - Type.POLYLINE2, - Type.QUAD2, - Type.RECT, - Type.TRIANGLE2, - ])); - - it("extrude", () => - checkImpls(extrude, [ - ])); - - it("flip", () => - checkImpls(flip, [ - Type.CUBIC2, - Type.LINE2, - Type.POINTS2, - Type.POLYGON2, - Type.POLYLINE2, - Type.QUAD2, - Type.QUADRATIC2, - ])); - - it("height", () => - checkImpls(height, [ - _DEFAULT, - ])); - - it("intersection", () => - checkImpls(intersection, [ - Type.POLYGON2 - ])); - - it("intersectShape", () => - checkImpls(intersectShape, [ - "rect-circle", - "rect-rect", - "sphere-ray", - "sphere-sphere" - ])); - - it("intersectLine", () => - checkImpls(intersectLine, [ - Type.LINE2 - ])); - - it("mapPoint", () => - checkImpls(mapPoint, [ - Type.RECT - ])); - - it("normalAt", () => - checkImpls(normalAt, [ - _DEFAULT, - ])); - - it("offset", () => - checkImpls(offset, [ - Type.LINE2, - Type.POLYGON2, - Type.POLYLINE2, - // TODO rect - ])); - - it("perimeter", () => - checkImpls(perimeter, [ - Type.CIRCLE, - Type.ELLIPSE, - Type.LINE2, - Type.POLYGON2, - Type.POLYLINE2, - Type.QUAD2, - Type.RECT, - Type.TRIANGLE2, - ])); - - it("pointAt", () => - checkImpls(pointAt, [ - Type.ARC2, - Type.CIRCLE, - Type.CUBIC2, - Type.ELLIPSE, - Type.LINE2, - Type.POLYGON2, - Type.QUADRATIC2, - Type.RAY, - Type.RECT, - ])); - - it("pointInside", () => - checkImpls(pointInside, [ - Type.CIRCLE, - Type.POLYGON2, - Type.TRIANGLE2, - Type.RECT, - ])); - - it("resample", () => - checkImpls(resample, [ - Type.LINE2, - Type.POLYGON2, - Type.POLYLINE2, - Type.QUAD2, - Type.RECT, - Type.TRIANGLE2, - ])); - - it("simplify", () => - checkImpls(simplify, [ - Type.PATH2, - Type.POLYGON2, - Type.POLYLINE2, - ])); - - it("splitAt", () => - checkImpls(splitAt, [ - Type.CUBIC2, - Type.QUADRATIC2, - ])); - - it("subdivide", () => - checkImpls(subdivide, [ - Type.POLYGON2, - Type.POLYLINE2 - ])); - - it("tangentAt", () => - checkImpls(tangentAt, [ - Type.CIRCLE, - Type.LINE2, - Type.POLYGON2, - Type.POLYLINE2, - ])); - - it("tessellate", () => - checkImpls(tessellate, [ - Type.POLYGON2, - Type.QUAD2, - Type.RECT, - Type.TRIANGLE2, - ])); - - it("transform", () => - checkImpls(transform, [ - Type.CUBIC2, - Type.LINE2, - Type.PATH2, - Type.POINTS2, - Type.POLYGON2, - Type.POLYLINE2, - Type.QUAD2, - Type.QUADRATIC2, - Type.RECT, - Type.TRIANGLE2, - ])); - - it("translate", () => - checkImpls(translate, [ - Type.CIRCLE, - Type.ELLIPSE, - Type.PATH2, - Type.POLYGON2, - Type.POLYLINE2, - Type.QUAD2, - Type.RECT, - Type.TRIANGLE2 - ])); - - it("union", () => - checkImpls(union, [ - Type.POLYGON2, - Type.RECT, - ])); - - it("unmapPoint", () => - checkImpls(unmapPoint, [ - Type.QUAD2, - Type.RECT, - ])); - - it("vertices", () => - checkImpls(vertices, [ - Type.ARC2, - Type.CIRCLE, - Type.CUBIC2, - Type.ELLIPSE, - Type.LINE2, - Type.PATH2, - Type.POINTS2, - Type.POLYGON2, - Type.POLYLINE2, - Type.QUAD2, - Type.QUADRATIC2, - Type.RECT, - Type.TRIANGLE2, - ])); - - it("warp", () => - checkImpls(warp, [ - _DEFAULT, - ])); - - it("width", () => - checkImpls(width, [ - _DEFAULT, - ])); -}); \ No newline at end of file diff --git a/packages/geom2/test/circle.ts b/packages/geom2/test/circle.ts deleted file mode 100644 index 5638b7393b..0000000000 --- a/packages/geom2/test/circle.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { equiv } from "@thi.ng/equiv"; -import { HALF_PI, PI, TAU } from "@thi.ng/math"; -import { eqDeltaArray, Vec } from "@thi.ng/vectors3"; -import * as assert from "assert"; -import { - area, - asPolygon, - asSvg, - bounds, - circle, - Circle2, - perimeter, - Polygon2, - Rect2, - vertices -} from "../src/index"; - -describe("circle", () => { - - let a: Circle2; - let apts: Vec[]; - - beforeEach(() => { - a = circle([100, 200], 10, { fill: "red" }); - apts = [[110, 200], [100, 210], [90, 200], [100, 190]]; - }); - - it("area", () => - assert.equal(area(a), a.r * a.r * PI)); - - it("perimeter", () => - assert.equal(perimeter(a), a.r * TAU)); - - it("asPolygon", () => - assert(equiv(asPolygon(a, 4), new Polygon2(apts)))); - - it("bounds", () => - assert(equiv(bounds(a), new Rect2([90, 190], [20, 20])))); - - it("vertices", () => - assert(eqDeltaArray(vertices(a, 4), apts))); - - it("vertices (theta)", () => - assert(eqDeltaArray(vertices(a, { theta: HALF_PI }), apts))); - - it("svg", () => { - assert.equal( - asSvg(a), - `` - ); - }); -}); diff --git a/packages/geom2/test/clip.ts b/packages/geom2/test/clip.ts deleted file mode 100644 index 154a231919..0000000000 --- a/packages/geom2/test/clip.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { translation23 } from "@thi.ng/matrices"; -import * as fs from "fs"; -import * as g from "../src"; - -const a = g.polygon([[0, 0], [35, 0], [35, 60], [65, 60], [65, 0], [100, 0], [100, 100], [0, 100]], { stroke: "red" }); -const b = g.polygon([[20, 25], [150, 80], [100, 150], [30, 110]], { stroke: "blue" }); - -fs.writeFileSync("clip-test.svg", - g.asSvg( - g.svgDoc({ - width: 600, - height: 600, - viewBox: "-10 -10 340 340", - fill: "none", - stroke: "black" - }, - g.group( - { transform: translation23([], [0, 0]) }, - g.group({ "stroke-width": 5 }, ...g.union(a, b)), - a, b - ), - g.group( - { transform: translation23([], [160, 0]) }, - g.group({ "stroke-width": 5 }, ...g.difference(a, b)), - a, b - ), - g.group( - { transform: translation23([], [0, 160]) }, - g.group({ "stroke-width": 5 }, ...g.difference(b, a)), - a, b - ), - g.group( - { transform: translation23([], [160, 160]) }, - g.group({ "stroke-width": 5 }, ...g.intersection(a, b)), - a, b - ), - ) - ) -); \ No newline at end of file diff --git a/packages/geom2/test/tsconfig.json b/packages/geom2/test/tsconfig.json deleted file mode 100644 index 2c9c12a650..0000000000 --- a/packages/geom2/test/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "../../../tsconfig.json", - "compilerOptions": { - "outDir": "../build", - "module": "commonjs", - }, - "include": [ - "./**/*.ts", - "../src/**/*.ts" - ] -} \ No newline at end of file diff --git a/packages/geom2/tsconfig.json b/packages/geom2/tsconfig.json deleted file mode 100644 index bcf03f18b4..0000000000 --- a/packages/geom2/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": ".", - "module": "es6", - "target": "es6" - }, - "include": [ - "./src/**/*.ts" - ] -} \ No newline at end of file From 485051db40254ab0f5a3d51a1f5a522bc20061fc Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 19 Jan 2019 22:21:57 +0000 Subject: [PATCH 308/333] refactor(geom-accel): update to use new vectors package --- packages/geom-accel/package.json | 4 ++-- packages/geom-accel/src/kdtree.ts | 34 +++++++++++++++---------------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/packages/geom-accel/package.json b/packages/geom-accel/package.json index 6c51e80c8f..6318f10ce5 100644 --- a/packages/geom-accel/package.json +++ b/packages/geom-accel/package.json @@ -16,7 +16,7 @@ "scripts": { "build": "yarn clean && yarn build:es6 && yarn build:bundle", "build:es6": "tsc --declaration", - "build:bundle": "../../scripts/bundle-module geomAccel api heaps math transducers vectors", + "build:bundle": "../../scripts/bundle-module geomAccel api heaps math transducers vectors3", "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib internal", "cover": "yarn test && nyc report --reporter=lcov", @@ -36,7 +36,7 @@ "@thi.ng/heaps": "^0.3.1", "@thi.ng/math": "^0.2.2", "@thi.ng/transducers": "^2.3.2", - "@thi.ng/vectors": "^1.4.12" + "@thi.ng/vectors3": "^0.0.1" }, "keywords": [ "ES6", diff --git a/packages/geom-accel/src/kdtree.ts b/packages/geom-accel/src/kdtree.ts index d7be2eedab..c4a2d24ea2 100644 --- a/packages/geom-accel/src/kdtree.ts +++ b/packages/geom-accel/src/kdtree.ts @@ -1,23 +1,21 @@ -import { ICopy, IEmpty, Pair } from "@thi.ng/api"; +import { ICopy, Pair } from "@thi.ng/api"; import { Heap } from "@thi.ng/heaps"; import { EPS } from "@thi.ng/math"; import { ensureArray } from "@thi.ng/transducers"; -import { IDistance } from "@thi.ng/vectors"; - -export type KdIndexable = IDistance & IEmpty; +import { distSq, empty, ReadonlyVec } from "@thi.ng/vectors3"; const CMP = (a, b) => b[0] - a[0]; -export class KdNode, V> { +export class KdNode { parent: KdNode; l: KdNode; r: KdNode; d: number; - k: Readonly; + k: K; v: V; - constructor(parent: KdNode, dim: number, key: Readonly, val: V) { + constructor(parent: KdNode, dim: number, key: K, val: V) { this.parent = parent; this.d = dim; this.k = key; @@ -62,7 +60,7 @@ export class KdNode, V> { * https://github.com/ubilabs/kd-tree-javascript * */ -export class KdTree, V> +export class KdTree implements ICopy> { root: KdNode; @@ -96,11 +94,11 @@ export class KdTree, V> return new KdTree(this.dim, this); } - add(p: Readonly, v: V, eps = EPS) { + add(p: K, v: V, eps = EPS) { eps *= eps; const search = (node: KdNode, parent: KdNode): KdNode | false => node ? - p.distSq(node.k) > eps ? + distSq(p, node.k) > eps ? search( p[node.d] < node.k[node.d] ? node.l : node.r, node @@ -217,14 +215,14 @@ export class KdTree, V> * @param node * @param epsSq squared epsilon / tolerance */ -const find = , V>(p: K, node: KdNode, epsSq: number) => { +const find = (p: K, node: KdNode, epsSq: number) => { if (!node) return; - return p.distSq(node.k) <= epsSq ? + return distSq(p, node.k) <= epsSq ? node : find(p, p[node.d] < node.k[node.d] ? node.l : node.r, epsSq); }; -const findMin = , V>(node: KdNode, dim: number): KdNode => { +const findMin = (node: KdNode, dim: number): KdNode => { if (!node) return; if (node.d === dim) { return node.l ? @@ -249,7 +247,7 @@ const findMin = , V>(node: KdNode, dim: number): * * @param node */ -const remove = , V>(node: KdNode) => { +const remove = (node: KdNode) => { if (!node.l && !node.r) { if (!node.parent) { return true; @@ -276,9 +274,9 @@ const remove = , V>(node: KdNode) => { } }; -const nearest = , V>(q: K, acc: Heap<[number, KdNode]>, dims: number, maxNum: number, node: KdNode) => { +const nearest = (q: K, acc: Heap<[number, KdNode]>, dims: number, maxNum: number, node: KdNode) => { const p = node.k; - const ndist = q.distSq(p); + const ndist = distSq(p, q); if (!node.l && !node.r) { if (ndist < acc.peek()[0]) { if (acc.length >= maxNum) { @@ -290,11 +288,11 @@ const nearest = , V>(q: K, acc: Heap<[number, KdNode= 0;) { tp[i] = i === ndim ? q[i] : p[i]; } - const tdist = tp.distSq(p); + const tdist = distSq(p, tp); let best = !node.r ? node.l : From 5d087367054fbed8581880bb3b1004937bbd87e1 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 19 Jan 2019 22:23:09 +0000 Subject: [PATCH 309/333] refactor(examples): update geom-knn demo --- examples/geom-knn/package.json | 2 +- examples/geom-knn/src/index.ts | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/geom-knn/package.json b/examples/geom-knn/package.json index ac4ce070a9..43b66d04e8 100644 --- a/examples/geom-knn/package.json +++ b/examples/geom-knn/package.json @@ -22,7 +22,7 @@ "@thi.ng/rstream-gestures": "latest", "@thi.ng/transducers": "latest", "@thi.ng/transducers-hdom": "latest", - "@thi.ng/vectors": "latest" + "@thi.ng/vectors3": "latest" }, "browserslist": [ "last 3 Chrome versions" diff --git a/examples/geom-knn/src/index.ts b/examples/geom-knn/src/index.ts index f8de31f99a..02fab5e727 100644 --- a/examples/geom-knn/src/index.ts +++ b/examples/geom-knn/src/index.ts @@ -5,7 +5,7 @@ import { sync, trigger } from "@thi.ng/rstream"; import { gestureStream } from "@thi.ng/rstream-gestures"; import { map, mapcat } from "@thi.ng/transducers"; import { updateDOM } from "@thi.ng/transducers-hdom"; -import { asVec2, Vec2 } from "@thi.ng/vectors"; +import { Vec } from "@thi.ng/vectors3"; const app = (main) => { // augment hdom-canvas component w/ `init` lifecycle method: this is @@ -22,7 +22,7 @@ const app = (main) => { // initialize 1st point & store in tree for fast KNN searches const width = window.innerWidth; const height = window.innerHeight; - let tree = new KdTree(2); + let tree = new KdTree(2); // return root component function, triggered by each new mouse / touch event return ({ mpos }) => { @@ -34,14 +34,14 @@ const app = (main) => { // `trigger()` stream defined further below. that means // initially, there will be no valid `mpos` and so we insert a // default point instead - mpos = mpos ? asVec2(mpos) : new Vec2([width / 2, height / 2, 5]); + mpos = mpos || [width / 2, height / 2, 5]; // record new pos in tree tree.addKey(mpos); // even though we only create 2d vectors, we store a 3rd value // in the backing array, which will be later used as radius when // the point has been selected as part of a KNN query and is // visualized as circle. - mpos.buf.push(1.5 + Math.random() * 5); + mpos.push(1.5 + Math.random() * 5); // select max. 200 neighbors for given mouse position, // measure execution time... let [selected, t1] = timedResult(() => @@ -67,7 +67,7 @@ const app = (main) => { ["points", { fill: "black" }, tree.keys()], // selected points as circles (using 3rd array item as radius) ["g", { fill: "rgba(0,192,255,0.5)" }, - ...selected.map((p) => ["circle", {}, p, p.buf[2]])], + ...selected.map((p) => ["circle", {}, p, p[2]])], // secondary neighbor connections ["g", { stroke: "rgba(0,0,0,0.25)" }, ...neighbors]]]; From 5270143a1d9ca49eefba2df1b3092e1f53d9b30b Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 19 Jan 2019 22:25:54 +0000 Subject: [PATCH 310/333] refactor(defmulti): remove optional excess args from type sigs --- packages/defmulti/src/index.ts | 66 +++++++++++++++++----------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/packages/defmulti/src/index.ts b/packages/defmulti/src/index.ts index 79d447ee8e..d0302e34f0 100644 --- a/packages/defmulti/src/index.ts +++ b/packages/defmulti/src/index.ts @@ -4,40 +4,40 @@ import { illegalArgs, unsupported, illegalArity } from "@thi.ng/errors"; export const DEFAULT: unique symbol = Symbol(); export type DispatchFn = (...args) => PropertyKey; -export type DispatchFn1
= (a: A, ...xs: any[]) => PropertyKey; -export type DispatchFn1O = (a: A, b?: B, ...xs: any[]) => PropertyKey; -export type DispatchFn2 = (a: A, b: B, ...xs: any[]) => PropertyKey; -export type DispatchFn2O = (a: A, b: B, c?: C, ...xs: any[]) => PropertyKey; -export type DispatchFn3 = (a: A, b: B, c: C, ...xs: any[]) => PropertyKey; -export type DispatchFn3O = (a: A, b: B, c: C, d?: D, ...xs: any[]) => PropertyKey; -export type DispatchFn4 = (a: A, b: B, c: C, d: D, ...xs: any[]) => PropertyKey; -export type DispatchFn4O = (a: A, b: B, c: C, d: D, e?: E, ...xs: any[]) => PropertyKey; -export type DispatchFn5 = (a: A, b: B, c: C, d: D, e: E, ...xs: any[]) => PropertyKey; -export type DispatchFn5O = (a: A, b: B, c: C, d: D, e: E, f?: F, ...xs: any[]) => PropertyKey; -export type DispatchFn6 = (a: A, b: B, c: C, d: D, e: E, f: F, ...xs: any[]) => PropertyKey; -export type DispatchFn6O = (a: A, b: B, c: C, d: D, e: E, f: F, g?: G, ...xs: any[]) => PropertyKey; -export type DispatchFn7 = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, ...xs: any[]) => PropertyKey; -export type DispatchFn7O = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h?: H, ...xs: any[]) => PropertyKey; -export type DispatchFn8 = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, ...xs: any[]) => PropertyKey; -export type DispatchFn8O = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i?: I, ...xs: any[]) => PropertyKey; +export type DispatchFn1 = (a: A) => PropertyKey; +export type DispatchFn1O = (a: A, b?: B) => PropertyKey; +export type DispatchFn2 = (a: A, b: B) => PropertyKey; +export type DispatchFn2O = (a: A, b: B, c?: C) => PropertyKey; +export type DispatchFn3 = (a: A, b: B, c: C) => PropertyKey; +export type DispatchFn3O = (a: A, b: B, c: C, d?: D) => PropertyKey; +export type DispatchFn4 = (a: A, b: B, c: C, d: D) => PropertyKey; +export type DispatchFn4O = (a: A, b: B, c: C, d: D, e?: E) => PropertyKey; +export type DispatchFn5 = (a: A, b: B, c: C, d: D, e: E) => PropertyKey; +export type DispatchFn5O = (a: A, b: B, c: C, d: D, e: E, f?: F) => PropertyKey; +export type DispatchFn6 = (a: A, b: B, c: C, d: D, e: E, f: F) => PropertyKey; +export type DispatchFn6O = (a: A, b: B, c: C, d: D, e: E, f: F, g?: G) => PropertyKey; +export type DispatchFn7 = (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => PropertyKey; +export type DispatchFn7O = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h?: H) => PropertyKey; +export type DispatchFn8 = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H) => PropertyKey; +export type DispatchFn8O = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i?: I) => PropertyKey; export type Implementation = (...args: any[]) => T; -export type Implementation1 = (a: A, ...xs: any[]) => T; -export type Implementation1O = (a: A, b?: B, ...xs: any[]) => T; -export type Implementation2 = (a: A, b: B, ...xs: any[]) => T; -export type Implementation2O = (a: A, b: B, c?: C, ...xs: any[]) => T; -export type Implementation3 = (a: A, b: B, c: C, ...xs: any[]) => T; -export type Implementation3O = (a: A, b: B, c: C, d?: D, ...xs: any[]) => T; -export type Implementation4 = (a: A, b: B, c: C, d: D, ...xs: any[]) => T; -export type Implementation4O = (a: A, b: B, c: C, d: D, e?: E, ...xs: any[]) => T; -export type Implementation5 = (a: A, b: B, c: C, d: D, e: E, ...xs: any[]) => T; -export type Implementation5O = (a: A, b: B, c: C, d: D, e: E, f?: F, ...xs: any[]) => T; -export type Implementation6 = (a: A, b: B, c: C, d: D, e: E, f: F, ...xs: any[]) => T; -export type Implementation6O = (a: A, b: B, c: C, d: D, e: E, f: F, g?: G, ...xs: any[]) => T; -export type Implementation7 = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, ...xs: any[]) => T; -export type Implementation7O = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h?: H, ...xs: any[]) => T; -export type Implementation8 = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, ...xs: any[]) => T; -export type Implementation8O = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i?: I, ...xs: any[]) => T; +export type Implementation1 = (a: A) => T; +export type Implementation1O = (a: A, b?: B) => T; +export type Implementation2 = (a: A, b: B) => T; +export type Implementation2O = (a: A, b: B, c?: C) => T; +export type Implementation3 = (a: A, b: B, c: C) => T; +export type Implementation3O = (a: A, b: B, c: C, d?: D) => T; +export type Implementation4 = (a: A, b: B, c: C, d: D) => T; +export type Implementation4O = (a: A, b: B, c: C, d: D, e?: E) => T; +export type Implementation5 = (a: A, b: B, c: C, d: D, e: E) => T; +export type Implementation5O = (a: A, b: B, c: C, d: D, e: E, f?: F) => T; +export type Implementation6 = (a: A, b: B, c: C, d: D, e: E, f: F) => T; +export type Implementation6O = (a: A, b: B, c: C, d: D, e: E, f: F, g?: G) => T; +export type Implementation7 = (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => T; +export type Implementation7O = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h?: H) => T; +export type Implementation8 = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H) => T; +export type Implementation8O = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i?: I) => T; export interface MultiFnBase { /** @@ -212,7 +212,7 @@ export function defmulti(f: DispatchFn6O(f: DispatchFn8, rels?: AncestorDefs): MultiFn8; export function defmulti(f: DispatchFn7O, rels?: AncestorDefs): MultiFn7O; export function defmulti(f: DispatchFn8O, rels?: AncestorDefs): MultiFn8O; -export function defmulti(f: any, ancestors?: AncestorDefs): MultiFn { +export function defmulti(f: any, ancestors?: AncestorDefs) { const impls: IObjectOf> = {}; const rels: IObjectOf> = ancestors ? makeRels(ancestors) : {}; const fn: any = (...args) => { From 5ca580327c80487ff25440561967ebfc12345c15 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sat, 19 Jan 2019 23:28:39 +0000 Subject: [PATCH 311/333] refactor(color): remove circular dependencies, update parseCss() --- packages/color/src/convert.ts | 7 +++-- packages/color/src/hcya.ts | 2 +- packages/color/src/hsia.ts | 2 +- packages/color/src/hsla.ts | 2 +- packages/color/src/hsva.ts | 2 +- .../internal/{ctor-args.ts => ensure-args.ts} | 0 packages/color/src/luminance-rgb.ts | 13 +++++++++ packages/color/src/luminance.ts | 21 ++------------ packages/color/src/parse-css.ts | 29 +++++++------------ packages/color/src/rgba-hcya.ts | 2 +- packages/color/src/rgba-ycbcra.ts | 2 +- packages/color/src/rgba.ts | 2 +- packages/color/src/xyza.ts | 2 +- packages/color/src/ycbcr.ts | 2 +- 14 files changed, 38 insertions(+), 50 deletions(-) rename packages/color/src/internal/{ctor-args.ts => ensure-args.ts} (100%) create mode 100644 packages/color/src/luminance-rgb.ts diff --git a/packages/color/src/convert.ts b/packages/color/src/convert.ts index 126e89b15a..8b130f16bd 100644 --- a/packages/color/src/convert.ts +++ b/packages/color/src/convert.ts @@ -23,7 +23,7 @@ import { hsvaHsla } from "./hsva-hsla"; import { hsvaRgba } from "./hsva-rgba"; import { int32Css } from "./int-css"; import { int32Rgba } from "./int-rgba"; -import { parseCSS } from "./parse-css"; +import { parseCss } from "./parse-css"; import { rgbaCss } from "./rgba-css"; import { rgbaHcya } from "./rgba-hcya"; import { rgbaHsia } from "./rgba-hsia"; @@ -123,19 +123,20 @@ const defConversions = ( // CSS +defConversion(ColorMode.RGBA, ColorMode.CSS, (x: string) => parseCss(x)); + [ ColorMode.HCYA, ColorMode.HSIA, ColorMode.HSLA, ColorMode.HSVA, ColorMode.INT32, - ColorMode.RGBA, ColorMode.XYZA, ColorMode.YCBCRA ].forEach( (id) => defConversion( id, ColorMode.CSS, - (x: string) => parseCSS(x, id) + (x: string) => convert(parseCss(x), id, ColorMode.RGBA) ) ); diff --git a/packages/color/src/hcya.ts b/packages/color/src/hcya.ts index a5cd327a0d..4a18dd3886 100644 --- a/packages/color/src/hcya.ts +++ b/packages/color/src/hcya.ts @@ -1,7 +1,7 @@ import { IVector, declareIndices } from "@thi.ng/vectors3"; import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; -import { ensureArgs } from "./internal/ctor-args"; +import { ensureArgs } from "./internal/ensure-args"; export function hcya(col: Color): HCYA export function hcya(h?: number, c?: number, y?: number, a?: number): HCYA; diff --git a/packages/color/src/hsia.ts b/packages/color/src/hsia.ts index cfbc66021a..5d2856925f 100644 --- a/packages/color/src/hsia.ts +++ b/packages/color/src/hsia.ts @@ -1,7 +1,7 @@ import { declareIndices, IVector } from "@thi.ng/vectors3"; import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; -import { ensureArgs } from "./internal/ctor-args"; +import { ensureArgs } from "./internal/ensure-args"; export function hsia(col: Color): HSIA export function hsia(h?: number, s?: number, i?: number, a?: number): HSIA; diff --git a/packages/color/src/hsla.ts b/packages/color/src/hsla.ts index 09b326eae4..b2e5fd7917 100644 --- a/packages/color/src/hsla.ts +++ b/packages/color/src/hsla.ts @@ -1,7 +1,7 @@ import { declareIndices, IVector } from "@thi.ng/vectors3"; import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; -import { ensureArgs } from "./internal/ctor-args"; +import { ensureArgs } from "./internal/ensure-args"; export function hsla(col: Color): HSLA export function hsla(h?: number, s?: number, l?: number, a?: number): HSLA; diff --git a/packages/color/src/hsva.ts b/packages/color/src/hsva.ts index cb164b2ffe..d9db735a4e 100644 --- a/packages/color/src/hsva.ts +++ b/packages/color/src/hsva.ts @@ -1,7 +1,7 @@ import { IVector, declareIndices } from "@thi.ng/vectors3"; import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; -import { ensureArgs } from "./internal/ctor-args"; +import { ensureArgs } from "./internal/ensure-args"; export function hsva(col: Color): HSVA export function hsva(h?: number, s?: number, v?: number, a?: number): HSVA; diff --git a/packages/color/src/internal/ctor-args.ts b/packages/color/src/internal/ensure-args.ts similarity index 100% rename from packages/color/src/internal/ctor-args.ts rename to packages/color/src/internal/ensure-args.ts diff --git a/packages/color/src/luminance-rgb.ts b/packages/color/src/luminance-rgb.ts new file mode 100644 index 0000000000..1ddce3b97d --- /dev/null +++ b/packages/color/src/luminance-rgb.ts @@ -0,0 +1,13 @@ +import { dot3 } from "@thi.ng/vectors3"; +import { INV8BIT, ReadonlyColor, RGB_LUMINANCE } from "./api"; + +export const luminanceRGB = + (rgb: ReadonlyColor, weights = RGB_LUMINANCE) => + dot3(rgb, weights); + +export const luminanceInt = + (rgb: number) => ( + ((rgb >>> 16) & 0xff) * 76 + + ((rgb >>> 8) & 0xff) * 150 + + (rgb & 0xff) * 29 + ) * INV8BIT * INV8BIT; diff --git a/packages/color/src/luminance.ts b/packages/color/src/luminance.ts index 3cfabb1839..d676eddf22 100644 --- a/packages/color/src/luminance.ts +++ b/packages/color/src/luminance.ts @@ -1,25 +1,8 @@ import { DEFAULT, defmulti, MultiFn1O } from "@thi.ng/defmulti"; import { illegalArgs } from "@thi.ng/errors"; -import { dot3 } from "@thi.ng/vectors3"; -import { - ColorMode, - IColor, - INV8BIT, - ReadonlyColor, - RGB_LUMINANCE -} from "./api"; +import { ColorMode, IColor, ReadonlyColor } from "./api"; import { convert } from "./convert"; - -export const luminanceRGB = - (rgb: ReadonlyColor, weights = RGB_LUMINANCE) => - dot3(rgb, weights); - -export const luminanceInt = - (rgb: number) => ( - ((rgb >>> 16) & 0xff) * 76 + - ((rgb >>> 8) & 0xff) * 150 + - (rgb & 0xff) * 29 - ) * INV8BIT * INV8BIT; +import { luminanceInt, luminanceRGB } from "./luminance-rgb"; /** * Multi-method to compute relative luminance from any supported input diff --git a/packages/color/src/parse-css.ts b/packages/color/src/parse-css.ts index a7efd3a36a..1e39594182 100644 --- a/packages/color/src/parse-css.ts +++ b/packages/color/src/parse-css.ts @@ -2,52 +2,43 @@ import { IDeref } from "@thi.ng/api"; import { illegalArgs } from "@thi.ng/errors"; import { clamp01 } from "@thi.ng/math"; import { maybeParseFloat, maybeParseInt } from "@thi.ng/strings"; -import { Color, ColorMode, INV8BIT } from "./api"; -import { convert } from "./convert"; +import { INV8BIT, Color } from "./api"; +import { hslaRgba } from "./hsla-rgba"; +import { int32Rgba } from "./int-rgba"; import { CSS_NAMES } from "./names"; const RE_HEX = /^#?([0-9a-f]{3,8})$/i; const RE_CSS = /^(rgb|hsl)a?\(\s*([0-9.]+?),\s*([0-9.]+%?),\s*([0-9.]+%?),?\s*([0-9.]+)?\s*\)$/; -export const parseCSS = - (col: string | IDeref, mode = ColorMode.RGBA) => { +export const parseCss = + (col: string | IDeref) => { col = typeof col === "string" ? col : col.deref(); - let res: Color | number; - let resMode: ColorMode; if (col.charAt(0) === "#") { - resMode = ColorMode.INT32; - res = parseHex(col); + return int32Rgba([], parseHex(col)); } else { const match = RE_CSS.exec(col); if (match) { if (match[1] === "rgb" || match[1] === "rgba") { - resMode = ColorMode.RGBA; - res = [ + return [ parseChannel(match[2]), parseChannel(match[3]), parseChannel(match[4]), maybeParseFloat(match[5], 1) ]; } else { - resMode = ColorMode.HSLA; - res = [ + return hslaRgba(null, [ maybeParseFloat(match[2]) / 360, parseChannel(match[3]), parseChannel(match[4]), maybeParseFloat(match[5], 1) - ]; + ]); } } else { const c = CSS_NAMES[col]; !c && illegalArgs(`invalid color: "${col}"`); - resMode = ColorMode.INT32; - res = parseHex(c); + return int32Rgba([], parseHex(c)); } } - if (res && resMode != mode) { - return convert(res, mode, resMode); - } - return res; }; export const parseHex = diff --git a/packages/color/src/rgba-hcya.ts b/packages/color/src/rgba-hcya.ts index 34de0347c1..aa4e2175eb 100644 --- a/packages/color/src/rgba-hcya.ts +++ b/packages/color/src/rgba-hcya.ts @@ -1,7 +1,7 @@ import { EPS } from "@thi.ng/math"; import { Color, ReadonlyColor } from "./api"; import { hueRgba } from "./hue-rgba"; -import { luminanceRGB } from "./luminance"; +import { luminanceRGB } from "./luminance-rgb"; import { rgbaHcva } from "./rgba-hcva"; /** diff --git a/packages/color/src/rgba-ycbcra.ts b/packages/color/src/rgba-ycbcra.ts index 923e5ab5a9..9dfb9835c3 100644 --- a/packages/color/src/rgba-ycbcra.ts +++ b/packages/color/src/rgba-ycbcra.ts @@ -1,7 +1,7 @@ import { setC3 } from "@thi.ng/vectors3"; import { Color, ReadonlyColor } from "./api"; import { clamp } from "./clamp"; -import { luminanceRGB } from "./luminance"; +import { luminanceRGB } from "./luminance-rgb"; export const rgbaYcbcra = (out: Color, src: ReadonlyColor) => { diff --git a/packages/color/src/rgba.ts b/packages/color/src/rgba.ts index 3c324ecbbc..842aa06091 100644 --- a/packages/color/src/rgba.ts +++ b/packages/color/src/rgba.ts @@ -1,7 +1,7 @@ import { declareIndices, IVector } from "@thi.ng/vectors3"; import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; -import { ensureArgs } from "./internal/ctor-args"; +import { ensureArgs } from "./internal/ensure-args"; export function rgba(col: Color): RGBA export function rgba(r?: number, g?: number, b?: number, a?: number): RGBA; diff --git a/packages/color/src/xyza.ts b/packages/color/src/xyza.ts index 386aec9c1f..dda33ba7c5 100644 --- a/packages/color/src/xyza.ts +++ b/packages/color/src/xyza.ts @@ -1,7 +1,7 @@ import { declareIndices, IVector } from "@thi.ng/vectors3"; import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; -import { ensureArgs } from "./internal/ctor-args"; +import { ensureArgs } from "./internal/ensure-args"; export function xyza(col: Color): XYZA export function xyza(x?: number, y?: number, z?: number, a?: number): XYZA; diff --git a/packages/color/src/ycbcr.ts b/packages/color/src/ycbcr.ts index da59fbac57..6b42f4d1c4 100644 --- a/packages/color/src/ycbcr.ts +++ b/packages/color/src/ycbcr.ts @@ -1,7 +1,7 @@ import { declareIndices, IVector } from "@thi.ng/vectors3"; import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; -import { ensureArgs } from "./internal/ctor-args"; +import { ensureArgs } from "./internal/ensure-args"; export function ycbcra(col: Color): YCbCrA export function ycbcra(y: number, b: number, r: number, a?: number): YCbCrA; From 12ad59a1486f42eadae510e583f00c54ee54b607 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 20 Jan 2019 01:10:25 +0000 Subject: [PATCH 312/333] refactor(examples): update geom-knn & geom-tessel demos --- examples/geom-knn/src/index.ts | 15 +++++----- examples/geom-tessel/src/index.ts | 48 ++++++++++++++----------------- 2 files changed, 29 insertions(+), 34 deletions(-) diff --git a/examples/geom-knn/src/index.ts b/examples/geom-knn/src/index.ts index 02fab5e727..a112743463 100644 --- a/examples/geom-knn/src/index.ts +++ b/examples/geom-knn/src/index.ts @@ -22,7 +22,7 @@ const app = (main) => { // initialize 1st point & store in tree for fast KNN searches const width = window.innerWidth; const height = window.innerHeight; - let tree = new KdTree(2); + let tree = new KdTree(2); // return root component function, triggered by each new mouse / touch event return ({ mpos }) => { @@ -34,24 +34,25 @@ const app = (main) => { // `trigger()` stream defined further below. that means // initially, there will be no valid `mpos` and so we insert a // default point instead - mpos = mpos || [width / 2, height / 2, 5]; + mpos = mpos || [width / 2, height / 2]; // record new pos in tree - tree.addKey(mpos); + tree.add(mpos, 1.5 + Math.random() * 5); // even though we only create 2d vectors, we store a 3rd value // in the backing array, which will be later used as radius when // the point has been selected as part of a KNN query and is // visualized as circle. - mpos.push(1.5 + Math.random() * 5); + // mpos.push(1.5 + Math.random() * 5); + // select max. 200 neighbors for given mouse position, // measure execution time... let [selected, t1] = timedResult(() => - tree.selectKeys(mpos, 200, width / 4) + tree.select(mpos, 200, width / 4) ); // for each selected neighbor, perform another KNN search and // create line segments to each of these secondary matches // use `mapcat` to yield a flat array of lines let [neighbors, t2] = timedResult(() => - [...mapcat((p) => tree.selectKeys(p, 8, width / 4).map((q) => ["line", {}, p, q]), selected)] + [...mapcat((p) => tree.selectKeys(p[0], 8, width / 4).map((q) => ["line", {}, p[0], q]), selected)] ); return ["div.overflow-hidden.sans-serif.f7", // tree stats @@ -67,7 +68,7 @@ const app = (main) => { ["points", { fill: "black" }, tree.keys()], // selected points as circles (using 3rd array item as radius) ["g", { fill: "rgba(0,192,255,0.5)" }, - ...selected.map((p) => ["circle", {}, p, p[2]])], + ...selected.map((p) => ["circle", {}, p[0], p[1]])], // secondary neighbor connections ["g", { stroke: "rgba(0,0,0,0.25)" }, ...neighbors]]]; diff --git a/examples/geom-tessel/src/index.ts b/examples/geom-tessel/src/index.ts index d7f0e66c7a..1301679691 100644 --- a/examples/geom-tessel/src/index.ts +++ b/examples/geom-tessel/src/index.ts @@ -3,43 +3,34 @@ import { arcLength, asPolygon, centroid, + circle, IShape, - Polygon2, + Polygon, + polygon, + tesselEdgeSplit, tessellate, Tessellator, - vertices -} from "@thi.ng/geom2/api"; -import { circle } from "@thi.ng/geom2/circle"; -import { polygon } from "@thi.ng/geom2/polygon"; -import { - edgeSplit, - inset, - quadFan, - triFan -} from "@thi.ng/geom2/tessellate"; + tesselQuadFan, + tesselTriFan +} from "@thi.ng/geom3"; import { canvas } from "@thi.ng/hdom-canvas"; -import { deg } from "@thi.ng/math/angle"; -import { fit01, fit11 } from "@thi.ng/math/fit"; -import { fromInterval } from "@thi.ng/rstream/from/interval"; -import { sync } from "@thi.ng/rstream/stream-sync"; +import { deg, fit01, fit11 } from "@thi.ng/math"; +import { fromInterval, sync } from "@thi.ng/rstream"; +import { map } from "@thi.ng/transducers"; import { updateDOM } from "@thi.ng/transducers-hdom"; -import { cycle } from "@thi.ng/transducers/iter/cycle"; -import { map } from "@thi.ng/transducers/xform/map"; -import { take } from "@thi.ng/transducers/xform/take"; -import { Vec } from "@thi.ng/vectors3/api"; -import { polar } from "@thi.ng/vectors3/polar"; +import { polar, Vec } from "@thi.ng/vectors3"; -type Tint = (p: Polygon2) => string; +type Tint = (p: Polygon) => string; const MIN_RES = 3; const MAX_RES = 30; // const MAX_RES = MIN_RES; -// const SUBDIVS = [quadFan]; -// const SUBDIVS = [triFan]; -// const SUBDIVS = [edgeSplit]; -const SUBDIVS = [quadFan, triFan, edgeSplit, quadFan]; -// const SUBDIVS = [...take(4, cycle([quadFan]))]; +// const SUBDIVS = [tesselQuadFan]; +// const SUBDIVS = [tesselTriFan]; +// const SUBDIVS = [tesselEdgeSplit]; +const SUBDIVS = [tesselQuadFan, tesselTriFan, tesselEdgeSplit, tesselQuadFan]; +// const SUBDIVS = [...take(4, cycle([tesselQuadFan]))]; const W = 600; const W2 = W / 2; @@ -81,7 +72,10 @@ const tintedPoly = (tint: Tint, points: Vec[]) => { */ const tessellation = (t: number, tessel: Tessellator[], tint: Tint) => { return tessellate( - asPolygon(circle([0, 0], W2), Math.floor(fit11(Math.sin(t), MIN_RES, MAX_RES))), + asPolygon( + circle([0, 0], W2), + Math.floor(fit11(Math.sin(t), MIN_RES, MAX_RES)) + ), tessel ).map(partial(tintedPoly, tint)); }; From 311b00746f7ff67418032f923376c7aae4074ead Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 20 Jan 2019 03:53:39 +0000 Subject: [PATCH 313/333] feat(vectors): add default output handling for set/setC/setS fns --- packages/vectors3/src/internal/codegen.ts | 1 + packages/vectors3/src/set.ts | 4 ++-- packages/vectors3/src/setc.ts | 5 +++++ packages/vectors3/src/sets.ts | 6 +++--- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/vectors3/src/internal/codegen.ts b/packages/vectors3/src/internal/codegen.ts index 64ea11edcc..56d5f84e80 100644 --- a/packages/vectors3/src/internal/codegen.ts +++ b/packages/vectors3/src/internal/codegen.ts @@ -28,6 +28,7 @@ export const SARGS_VV = "io=0,ia=0,ib=0,so=1,sa=1,sb=1"; export const SARGS_VVV = "io=0,ia=0,ib=0,ic=0,so=1,sa=1,sb=1,sc=1"; export const DEFAULT_OUT = "!o&&(o=a);"; +export const NEW_OUT = "!o&&(o=[]);"; export type Template = (syms: string[], i?: number) => string; diff --git a/packages/vectors3/src/set.ts b/packages/vectors3/src/set.ts index 568a729645..c7ad526776 100644 --- a/packages/vectors3/src/set.ts +++ b/packages/vectors3/src/set.ts @@ -1,6 +1,6 @@ import { MultiVecOpV, VecOpV } from "./api"; -import { defOp } from "./internal/codegen"; +import { defOp, NEW_OUT } from "./internal/codegen"; import { SET } from "./internal/templates"; export const [set, set2, set3, set4] = - defOp(SET, "o,a", undefined, "o", 1, ""); + defOp(SET, "o,a", undefined, "o", 1, NEW_OUT); diff --git a/packages/vectors3/src/setc.ts b/packages/vectors3/src/setc.ts index 1ce4556032..99e87d9c68 100644 --- a/packages/vectors3/src/setc.ts +++ b/packages/vectors3/src/setc.ts @@ -2,6 +2,7 @@ import { Vec } from "./api"; export const setC2 = (out: Vec, x: number, y: number) => ( + !out && (out = []), out[0] = x, out[1] = y, out @@ -9,6 +10,7 @@ export const setC2 = export const setC3 = (out: Vec, x: number, y: number, z: number) => ( + !out && (out = []), out[0] = x, out[1] = y, out[2] = z, @@ -17,6 +19,7 @@ export const setC3 = export const setC4 = (out: Vec, x: number, y: number, z: number, w: number) => ( + !out && (out = []), out[0] = x, out[1] = y, out[2] = z, @@ -26,6 +29,7 @@ export const setC4 = export const setC6 = (out: Vec, a: number, b: number, c: number, d: number, e: number, f: number) => ( + !out && (out = []), out[0] = a, out[1] = b, out[2] = c, @@ -37,6 +41,7 @@ export const setC6 = export const setC = (out: Vec, ...xs: number[]) => { + !out && (out = []); for (let i = 0, n = xs.length; i < n; i++) { out[i] = xs[i]; } diff --git a/packages/vectors3/src/sets.ts b/packages/vectors3/src/sets.ts index eb5258c9b7..dbb663a09b 100644 --- a/packages/vectors3/src/sets.ts +++ b/packages/vectors3/src/sets.ts @@ -1,9 +1,9 @@ -import { VecOpSV, ReadonlyVec, Vec } from "./api"; -import { defOpS, SARGS_V } from "./internal/codegen"; +import { ReadonlyVec, Vec, VecOpSV } from "./api"; +import { defOpS, NEW_OUT, SARGS_V } from "./internal/codegen"; import { SET } from "./internal/templates"; export const [setS2, setS3, setS4] = - defOpS(SET, `o,a,${SARGS_V}`, "o,a", "o", ""); + defOpS(SET, `o,a,${SARGS_V}`, "o,a", "o", NEW_OUT); export const setS = (out: Vec, a: ReadonlyVec, n: number, io = 0, ia = 0, so = 1, sa = 1) => { From 2aceab97f196de1097eb3f3c12419cf00f39a9fa Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 20 Jan 2019 03:54:22 +0000 Subject: [PATCH 314/333] feat(matrices): add m22 & m23 matrix converters --- packages/matrices/src/m22-m23.ts | 16 ++++++++++++++++ packages/matrices/src/m23-m22.ts | 11 +++++++++++ packages/matrices/src/m23-m44.ts | 21 +++++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 packages/matrices/src/m22-m23.ts create mode 100644 packages/matrices/src/m23-m22.ts create mode 100644 packages/matrices/src/m23-m44.ts diff --git a/packages/matrices/src/m22-m23.ts b/packages/matrices/src/m22-m23.ts new file mode 100644 index 0000000000..5df4b293eb --- /dev/null +++ b/packages/matrices/src/m22-m23.ts @@ -0,0 +1,16 @@ +import { set4 } from "@thi.ng/vectors3"; +import { MatOpM } from "./api"; + +/** + * Converts M22 to M23 and writes result to `out`. + * + * @param out + * @param m22 + */ +export const mat22to23: MatOpM = + (out, m22) => ( + !out && (out = []), + set4(out, m22), + out[4] = out[5] = 0, + out + ); diff --git a/packages/matrices/src/m23-m22.ts b/packages/matrices/src/m23-m22.ts new file mode 100644 index 0000000000..16bd1b8285 --- /dev/null +++ b/packages/matrices/src/m23-m22.ts @@ -0,0 +1,11 @@ +import { set4 } from "@thi.ng/vectors3"; +import { MatOpM } from "./api"; + +/** + * Converts M23 to M22 and writes result to `out`. + * + * @param out + * @param m23 + */ +export const mat23to22: MatOpM = + (out, m23) => set4(out || [], m23); diff --git a/packages/matrices/src/m23-m44.ts b/packages/matrices/src/m23-m44.ts new file mode 100644 index 0000000000..f3e2506fe6 --- /dev/null +++ b/packages/matrices/src/m23-m44.ts @@ -0,0 +1,21 @@ +import { MatOpM } from "./api"; + +/** + * Converts M23 to M44 and writes result to `out`. + * + * @param out + * @param m23 + */ +export const mat23to44: MatOpM = + (out, m23) => ( + !out && (out = []), + out[0] = m23[0], + out[1] = m23[1], + out[4] = m23[2], + out[5] = m23[3], + out[12] = m23[4], + out[13] = m23[5], + out[10] = out[15] = 1, + out[2] = out[3] = out[6] = out[7] = out[8] = out[9] = out[11] = out[14] = 0, + out + ); From 08f7bd16b9389729c45ec1c617f741aedbe11705 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 20 Jan 2019 03:55:02 +0000 Subject: [PATCH 315/333] docs(matrices): add docstrings for most fns --- packages/matrices/src/add.ts | 10 +++ packages/matrices/src/addn.ts | 10 +++ packages/matrices/src/alignment-quat.ts | 9 +++ packages/matrices/src/column.ts | 8 ++ packages/matrices/src/concat.ts | 10 +++ packages/matrices/src/conjugate.ts | 2 - packages/matrices/src/diag.ts | 6 ++ packages/matrices/src/div.ts | 10 +++ packages/matrices/src/divn.ts | 10 +++ packages/matrices/src/frustum.ts | 11 +++ packages/matrices/src/identity.ts | 3 + packages/matrices/src/index.ts | 3 + packages/matrices/src/invert.ts | 3 + packages/matrices/src/lookat.ts | 9 +++ packages/matrices/src/m33-m44.ts | 20 +++-- packages/matrices/src/m44-m33.ts | 16 ++-- packages/matrices/src/mixq.ts | 12 +++ packages/matrices/src/mul.ts | 10 +++ packages/matrices/src/mulm.ts | 8 ++ packages/matrices/src/muln.ts | 10 +++ packages/matrices/src/mulq.ts | 8 ++ packages/matrices/src/mulv.ts | 6 +- packages/matrices/src/ortho.ts | 12 +++ packages/matrices/src/perspective.ts | 10 +++ packages/matrices/src/quat-axis-angle.ts | 12 +++ packages/matrices/src/quat-euler.ts | 9 +++ packages/matrices/src/quat-m33.ts | 6 ++ packages/matrices/src/quat-m44.ts | 7 ++ packages/matrices/src/rotation-around-axis.ts | 29 ++++++- packages/matrices/src/rotation.ts | 80 +++++++++++++++---- packages/matrices/src/row.ts | 8 ++ packages/matrices/src/scale-center.ts | 14 ++++ packages/matrices/src/scale.ts | 28 +++++++ packages/matrices/src/sub.ts | 10 +++ packages/matrices/src/subn.ts | 10 +++ packages/matrices/src/translation.ts | 12 +++ packages/matrices/src/transpose.ts | 18 +++++ 37 files changed, 422 insertions(+), 37 deletions(-) diff --git a/packages/matrices/src/add.ts b/packages/matrices/src/add.ts index 22076ee8c1..914ba6b432 100644 --- a/packages/matrices/src/add.ts +++ b/packages/matrices/src/add.ts @@ -2,6 +2,16 @@ import { add as _add, add4 } from "@thi.ng/vectors3"; import { MatOpMM, MultiMatOpMM } from "./api"; import { defMath } from "./internal/codegen"; +/** + * Componentwise matrix addition. If `out` is not given, writes result + * in `a`. + * + * out = a + b + * + * @param out + * @param a + * @param b + */ export const add: MultiMatOpMM = _add; export const add22: MatOpMM = add4; export const [add23, add33, add44] = defMath(add, "+"); diff --git a/packages/matrices/src/addn.ts b/packages/matrices/src/addn.ts index 6ff41e2581..ee1e8f954f 100644 --- a/packages/matrices/src/addn.ts +++ b/packages/matrices/src/addn.ts @@ -2,6 +2,16 @@ import { addN as _addN, addN4 } from "@thi.ng/vectors3"; import { MatOpMN, MultiMatOpMN } from "./api"; import { defMathN } from "./internal/codegen"; +/** + * Adds single scalar componentwise to matrix. If `out` is not given, + * writes result in `mat`. + * + * out = mat + n + * + * @param out + * @param mat + * @param n + */ export const addN: MultiMatOpMN = _addN; export const addN22: MatOpMN = addN4; export const [addN23, addN33, addN44] = defMathN(addN, "+"); diff --git a/packages/matrices/src/alignment-quat.ts b/packages/matrices/src/alignment-quat.ts index 086f6edb18..e70bb85315 100644 --- a/packages/matrices/src/alignment-quat.ts +++ b/packages/matrices/src/alignment-quat.ts @@ -7,6 +7,15 @@ import { } from "@thi.ng/vectors3"; import { quatFromAxisAngle } from "./quat-axis-angle"; +/** + * Returns quaternion describing the rotation from direction vector + * `from` -> `to`. If `normalize` is true (default), first normalizes + * the vectors (not modifying original). + * + * @param from + * @param to + * @param normalize + */ export const alignmentQuat = (from: ReadonlyVec, to: ReadonlyVec, normalize = true) => { if (normalize) { diff --git a/packages/matrices/src/column.ts b/packages/matrices/src/column.ts index a8614d341e..0d4db5d221 100644 --- a/packages/matrices/src/column.ts +++ b/packages/matrices/src/column.ts @@ -6,6 +6,14 @@ import { } from "@thi.ng/vectors3"; import { MultiVecOpMN, VecOpMN } from "./api"; +/** + * Extracts column vector from given matrix and writes result to `out`. + * If `out` is null, creates new vector. + * + * @param out + * @param mat + * @param column + */ export const column: MultiVecOpMN = vop(1); export const column22: VecOpMN = diff --git a/packages/matrices/src/concat.ts b/packages/matrices/src/concat.ts index 5c1d8dca9f..e8c3d4390f 100644 --- a/packages/matrices/src/concat.ts +++ b/packages/matrices/src/concat.ts @@ -1,6 +1,16 @@ import { Mat, ReadonlyMat } from "./api"; import { mulM } from "./mulm"; +/** + * Concatenates / multiplies given matrices in left-to-right order. A + * minimum of 2 input matrices must be given. If `out` is null, writes + * result into `a`. + * + * @param out + * @param a + * @param b + * @param xs + */ export const concat = (out: Mat, a: ReadonlyMat, b: ReadonlyMat, ...xs: ReadonlyMat[]) => xs.reduce( diff --git a/packages/matrices/src/conjugate.ts b/packages/matrices/src/conjugate.ts index cbbdacaa15..2b28ca7532 100644 --- a/packages/matrices/src/conjugate.ts +++ b/packages/matrices/src/conjugate.ts @@ -9,5 +9,3 @@ export const conjugateQ = -a[2], a[3] ); - - diff --git a/packages/matrices/src/diag.ts b/packages/matrices/src/diag.ts index ef9667d1ef..cc01ebc051 100644 --- a/packages/matrices/src/diag.ts +++ b/packages/matrices/src/diag.ts @@ -1,6 +1,12 @@ import { vop, setS2, setS3, setS4 } from "@thi.ng/vectors3"; import { MultiVecOpM } from "./api"; +/** + * Extracts matrix diagonal into `out`. + * + * @param out + * @param mat + */ export const diag: MultiVecOpM = vop(1); export const diag22 = diff --git a/packages/matrices/src/div.ts b/packages/matrices/src/div.ts index 43a9177d59..405f54cc7d 100644 --- a/packages/matrices/src/div.ts +++ b/packages/matrices/src/div.ts @@ -2,6 +2,16 @@ import { div as _div, div4 } from "@thi.ng/vectors3"; import { MatOpMM, MultiMatOpMM } from "./api"; import { defMath } from "./internal/codegen"; +/** + * Componentwise matrix division. If `out` is not given, writes result + * in `a`. + * + * out = a / b + * + * @param out + * @param a + * @param b + */ export const div: MultiMatOpMM = _div; export const div22: MatOpMM = div4; export const [div23, div33, div44] = defMath(div, "/"); diff --git a/packages/matrices/src/divn.ts b/packages/matrices/src/divn.ts index 01e7eeef8b..cf34f6bd6b 100644 --- a/packages/matrices/src/divn.ts +++ b/packages/matrices/src/divn.ts @@ -2,6 +2,16 @@ import { divN as _divN, divN4 } from "@thi.ng/vectors3"; import { MatOpMN, MultiMatOpMN } from "./api"; import { defMathN } from "./internal/codegen"; +/** + * Componentwise matrix division by single scalar. If `out` is not + * given, writes result in `mat`. + * + * out = mat / n + * + * @param out + * @param mat + * @param n + */ export const divN: MultiMatOpMN = _divN; export const divN22: MatOpMN = divN4; export const [divN23, divN33, divN44] = defMathN(divN, "/"); diff --git a/packages/matrices/src/frustum.ts b/packages/matrices/src/frustum.ts index ff22cfbef4..c84e7310d9 100644 --- a/packages/matrices/src/frustum.ts +++ b/packages/matrices/src/frustum.ts @@ -2,6 +2,17 @@ import { DEG2RAD } from "@thi.ng/math"; import { setC } from "@thi.ng/vectors3"; import { Mat } from "./api"; +/** + * Constructs a M44 representing the given view frustum. + * + * @param out + * @param left + * @param right + * @param bottom + * @param top + * @param near + * @param far + */ export const frustum = ( out: Mat, left: number, diff --git a/packages/matrices/src/identity.ts b/packages/matrices/src/identity.ts index 40dcb9c1bc..734de8e481 100644 --- a/packages/matrices/src/identity.ts +++ b/packages/matrices/src/identity.ts @@ -8,6 +8,9 @@ import { } from "./api"; import { set } from "./set"; +/** + * Writes identity matrix into given matrix. + */ export const identity: MultiMatOp1 = vop(); export const identity22 = diff --git a/packages/matrices/src/index.ts b/packages/matrices/src/index.ts index 44d4d6cd64..d1ad224c37 100644 --- a/packages/matrices/src/index.ts +++ b/packages/matrices/src/index.ts @@ -15,6 +15,9 @@ export * from "./frustum"; export * from "./identity"; export * from "./invert"; export * from "./lookat"; +export * from "./m22-m23"; +export * from "./m23-m22"; +export * from "./m23-m44"; export * from "./m33-m44"; export * from "./m44-m33"; export * from "./mixq"; diff --git a/packages/matrices/src/invert.ts b/packages/matrices/src/invert.ts index cc63a73097..72128a32ee 100644 --- a/packages/matrices/src/invert.ts +++ b/packages/matrices/src/invert.ts @@ -15,6 +15,9 @@ import { det44FromCoeffs, detCoeffs44 } from "./determinant"; const dp4 = dotC4; const dp6 = dotC6; +/** + * Matrix inversion. + */ export const invert: MultiMatOpM = vop(1); export const invert22: MatOpM = diff --git a/packages/matrices/src/lookat.ts b/packages/matrices/src/lookat.ts index 559a976963..f806c98bca 100644 --- a/packages/matrices/src/lookat.ts +++ b/packages/matrices/src/lookat.ts @@ -8,6 +8,15 @@ import { } from "@thi.ng/vectors3"; import { Mat } from "./api"; +/** + * Constructs a M44 camera matrix for given `eye` position, look-at `target` + * (both in world space) and `up` vector. + * + * @param out + * @param eye + * @param target + * @param up + */ export const lookAt = ( out: Mat, eye: ReadonlyVec, diff --git a/packages/matrices/src/m33-m44.ts b/packages/matrices/src/m33-m44.ts index 933a932fd2..fd8a8896ad 100644 --- a/packages/matrices/src/m33-m44.ts +++ b/packages/matrices/src/m33-m44.ts @@ -1,12 +1,18 @@ import { setS3, setS4, ZERO4 } from "@thi.ng/vectors3"; import { MatOpM } from "./api"; +/** + * Converts M33 to M44 and writes result to `out`. + * + * @param out + * @param m33 + */ export const mat33to44: MatOpM = - (m44, m33) => ( - !m44 && (m44 = []), - setS3(m44, m33, 0, 0), - setS3(m44, m33, 4, 3), - setS3(m44, m33, 8, 6), - setS3(m44, ZERO4, 12), - setS4(m44, [0, 0, 0, 1], 3, 0, 4) + (out, m33) => ( + !out && (out = []), + setS3(out, m33, 0, 0), + setS3(out, m33, 4, 3), + setS3(out, m33, 8, 6), + setS3(out, ZERO4, 12), + setS4(out, [0, 0, 0, 1], 3, 0, 4) ); diff --git a/packages/matrices/src/m44-m33.ts b/packages/matrices/src/m44-m33.ts index 340782bcbe..09e8d8c42e 100644 --- a/packages/matrices/src/m44-m33.ts +++ b/packages/matrices/src/m44-m33.ts @@ -1,10 +1,16 @@ import { setS3 } from "@thi.ng/vectors3"; import { MatOpM } from "./api"; +/** + * Converts M44 to M33 and writes result to `out`. + * + * @param out + * @param m44 + */ export const mat44to33: MatOpM = - (m33, m44) => ( - !m33 && (m33 = []), - setS3(m33, m44), - setS3(m33, m44, 3, 4), - setS3(m33, m44, 6, 8) + (out, m44) => ( + !out && (out = []), + setS3(out, m44), + setS3(out, m44, 3, 4), + setS3(out, m44, 6, 8) ); diff --git a/packages/matrices/src/mixq.ts b/packages/matrices/src/mixq.ts index f85c8c707f..4f93f96b2e 100644 --- a/packages/matrices/src/mixq.ts +++ b/packages/matrices/src/mixq.ts @@ -7,6 +7,18 @@ import { Vec } from "@thi.ng/vectors3"; +/** + * Interpolates quaternion `a` to `b` by given amount `t`, using SLERP. + * Writes result to `out`. The optional `eps` (default 1e-3) is used to + * switch to linear interpolation if the angular difference is very + * small. + * + * @param out + * @param a + * @param b + * @param t + * @param eps + */ export const mixQ = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, t: number, eps = 1e-3) => { const d = dot4(a, b); diff --git a/packages/matrices/src/mul.ts b/packages/matrices/src/mul.ts index 04364392fa..047f8f50d9 100644 --- a/packages/matrices/src/mul.ts +++ b/packages/matrices/src/mul.ts @@ -2,6 +2,16 @@ import { mul as _mul, mul4 } from "@thi.ng/vectors3"; import { MatOpMM, MultiMatOpMM } from "./api"; import { defMath } from "./internal/codegen"; +/** + * Componentwise matrix addition. Use `mulM` for actual matrix-matrix + * multiplication. If `out` is not given, writes result in `a`. + * + * out = a * b + * + * @param out + * @param a + * @param b + */ export const mul: MultiMatOpMM = _mul; export const mul22: MatOpMM = mul4; export const [mul23, mul33, mul44] = defMath(mul, "*"); diff --git a/packages/matrices/src/mulm.ts b/packages/matrices/src/mulm.ts index 1537193cda..65880d34b9 100644 --- a/packages/matrices/src/mulm.ts +++ b/packages/matrices/src/mulm.ts @@ -9,6 +9,14 @@ import { } from "@thi.ng/vectors3"; import { MultiMatOpMM } from "./api"; +/** + * Performs matrix-matrix multiplication. If `out` is not given, writes + * result in `a`. + * + * @param out + * @param a + * @param b + */ export const mulM: MultiMatOpMM = vop(1); export const mulM22 = diff --git a/packages/matrices/src/muln.ts b/packages/matrices/src/muln.ts index be938739b6..8c21724e5e 100644 --- a/packages/matrices/src/muln.ts +++ b/packages/matrices/src/muln.ts @@ -2,6 +2,16 @@ import { mulN as _mulN, mulN4 } from "@thi.ng/vectors3"; import { MatOpMN, MultiMatOpMN } from "./api"; import { defMathN } from "./internal/codegen"; +/** + * Multiplies matrix componentwise with single scalar. If `out` is not + * given, writes result in `mat`. + * + * out = mat * n + * + * @param out + * @param mat + * @param n + */ export const mulN: MultiMatOpMN = _mulN; export const mulN22: MatOpMN = mulN4; export const [mulN23, mulN33, mulN44] = defMathN(mulN, "*"); diff --git a/packages/matrices/src/mulq.ts b/packages/matrices/src/mulq.ts index 046807c949..81e48eafcc 100644 --- a/packages/matrices/src/mulq.ts +++ b/packages/matrices/src/mulq.ts @@ -1,5 +1,13 @@ import { ReadonlyVec, setC4, Vec } from "@thi.ng/vectors3"; +/** + * Performs quaternion multiplication of `a` and `b` and writes result + * to `out`. If `out` is null, writes result into `a`. + * + * @param out + * @param a + * @param b + */ export const mulQ = (out: Vec, a: ReadonlyVec, b: ReadonlyVec) => { const { 0: ax, 1: ay, 2: az, 3: aw } = a; diff --git a/packages/matrices/src/mulv.ts b/packages/matrices/src/mulv.ts index 6c9666f561..16ee80de8d 100644 --- a/packages/matrices/src/mulv.ts +++ b/packages/matrices/src/mulv.ts @@ -117,13 +117,13 @@ export const mulV344: MatOpMV = * vector or modifies in-place if `out` is null or `v`. * * @param out - * @param quat + * @param q * @param v */ export const mulVQ = - (out: Vec, quat: ReadonlyVec, v: ReadonlyVec) => { + (out: Vec, q: ReadonlyVec, v: ReadonlyVec) => { const { 0: px, 1: py, 2: pz } = v; - const { 0: qx, 1: qy, 2: qz, 3: qw } = quat; + const { 0: qx, 1: qy, 2: qz, 3: qw } = q; const ix = qw * px + qy * pz - qz * py; const iy = qw * py + qz * px - qx * pz; const iz = qw * pz + qx * py - qy * px; diff --git a/packages/matrices/src/ortho.ts b/packages/matrices/src/ortho.ts index c31739d5a9..00836ba568 100644 --- a/packages/matrices/src/ortho.ts +++ b/packages/matrices/src/ortho.ts @@ -1,6 +1,18 @@ import { setC } from "@thi.ng/vectors3"; import { Mat } from "./api"; +/** + * Computes a M44 orthographic projection matrix and writes result to + * `out`. + * + * @param out + * @param left + * @param right + * @param bottom + * @param top + * @param near + * @param far + */ export const ortho = ( out: Mat, left: number, diff --git a/packages/matrices/src/perspective.ts b/packages/matrices/src/perspective.ts index 2efbf8296a..899648e628 100644 --- a/packages/matrices/src/perspective.ts +++ b/packages/matrices/src/perspective.ts @@ -1,6 +1,16 @@ import { Mat } from "./api"; import { frustum, frustumBounds } from "./frustum"; +/** + * Computes a M44 perspective projection matrix and writes result to + * `out`. + * + * @param out + * @param fov + * @param aspect + * @param near + * @param far + */ export const perspective = ( out: Mat, fov: number, diff --git a/packages/matrices/src/quat-axis-angle.ts b/packages/matrices/src/quat-axis-angle.ts index eea96ccb51..97a32f2d2f 100644 --- a/packages/matrices/src/quat-axis-angle.ts +++ b/packages/matrices/src/quat-axis-angle.ts @@ -1,6 +1,13 @@ import { EPS } from "@thi.ng/math"; import { normalize, ReadonlyVec } from "@thi.ng/vectors3"; +/** + * Computes a quaternion representing the rotation `theta` around + * `axis`. + * + * @param axis + * @param theta + */ export const quatFromAxisAngle = (axis: ReadonlyVec, theta: number) => { theta /= 2; @@ -11,6 +18,11 @@ export const quatFromAxisAngle = ); }; +/** + * Decomposes quaternion into `[axis, theta]` tuple. + * + * @param quat + */ export const quatToAxisAngle = (quat: ReadonlyVec) => { const n = normalize([], quat); diff --git a/packages/matrices/src/quat-euler.ts b/packages/matrices/src/quat-euler.ts index 00004211af..2c12feebc7 100644 --- a/packages/matrices/src/quat-euler.ts +++ b/packages/matrices/src/quat-euler.ts @@ -11,6 +11,15 @@ const axisOrder = { "zyx": [Z3, Y3, X3], }; +/** + * Constructs a quaternion from given rotation angles in specified + * `order`. + * + * @param order + * @param a + * @param b + * @param c + */ export const quatFromEuler = (order: keyof typeof axisOrder, a: number, b: number, c: number) => { const [aa, ab, ac] = axisOrder[order]; diff --git a/packages/matrices/src/quat-m33.ts b/packages/matrices/src/quat-m33.ts index ce1f2ec000..22a4ac6e5a 100644 --- a/packages/matrices/src/quat-m33.ts +++ b/packages/matrices/src/quat-m33.ts @@ -1,5 +1,11 @@ import { ReadonlyVec, setC, Vec } from "@thi.ng/vectors3"; +/** + * Converts quaternion into M33 and writes result to `out`. + * + * @param out + * @param q + */ export const quatToMat33 = (out: Vec, q: ReadonlyVec) => { const [x, y, z, w] = q; diff --git a/packages/matrices/src/quat-m44.ts b/packages/matrices/src/quat-m44.ts index 1597be737e..3cfe60f23b 100644 --- a/packages/matrices/src/quat-m44.ts +++ b/packages/matrices/src/quat-m44.ts @@ -5,6 +5,13 @@ import { ZERO3 } from "@thi.ng/vectors3"; +/** + * Converts quaternion into M44 with optional translation offset `t`, + * then writes result to `out`. + * + * @param out + * @param q + */ export const quatToMat44 = (out: Vec, a: ReadonlyVec, t: ReadonlyVec = ZERO3) => { const [x, y, z, w] = a; diff --git a/packages/matrices/src/rotation-around-axis.ts b/packages/matrices/src/rotation-around-axis.ts index 25b99403cc..cf7d134e61 100644 --- a/packages/matrices/src/rotation-around-axis.ts +++ b/packages/matrices/src/rotation-around-axis.ts @@ -1,9 +1,20 @@ -import { ReadonlyVec, setC } from "@thi.ng/vectors3"; +import { normalize as _normalize, ReadonlyVec, setC } from "@thi.ng/vectors3"; import { Mat } from "./api"; import { mat33to44 } from "./m33-m44"; +/** + * Constructs a M33 representing a rotation of `theta` around `axis` and + * writes result to `out`. If `normalize` is true (default false), + * non-destructively first normalizes axis vector. + * + * @param out + * @param axis + * @param theta + * @param normalize + */ export const rotationAroundAxis33 = - (out: Mat, [x, y, z]: ReadonlyVec, theta: number) => { + (out: Mat, axis: ReadonlyVec, theta: number, normalize = false) => { + const [x, y, z] = normalize ? _normalize([], axis) : axis; const s = Math.sin(theta); const c = Math.cos(theta); const t = 1 - c; @@ -21,6 +32,16 @@ export const rotationAroundAxis33 = ); }; +/** + * Constructs a M44 representing a rotation of `theta` around `axis` and + * writes result to `out`. If `normalize` is true (default false), + * non-destructively first normalizes axis vector. + * + * @param out + * @param axis + * @param theta + * @param normalize + */ export const rotationAroundAxis44 = - (out: Mat, axis: ReadonlyVec, theta: number) => - mat33to44(out, rotationAroundAxis33([], axis, theta)); + (out: Mat, axis: ReadonlyVec, theta: number, normalize = false) => + mat33to44(out, rotationAroundAxis33([], axis, theta, normalize)); diff --git a/packages/matrices/src/rotation.ts b/packages/matrices/src/rotation.ts index 41c2b5f056..57db32b88e 100644 --- a/packages/matrices/src/rotation.ts +++ b/packages/matrices/src/rotation.ts @@ -2,65 +2,101 @@ import { sincos } from "@thi.ng/math"; import { setC, setC4, setC6 } from "@thi.ng/vectors3"; import { Mat } from "./api"; +/** + * Constructs a M22 rotation matrix for given `theta`. + * + * @param out + * @param theta + */ export const rotation22 = - (m: Mat, theta: number) => { + (out: Mat, theta: number) => { const [s, c] = sincos(theta); return setC4( - m || [], + out || [], c, s, -s, c, ); }; +/** + * Constructs a M23 rotation matrix for given `theta`. + * + * @param out + * @param theta + */ export const rotation23 = - (m: Mat, theta: number) => { + (out: Mat, theta: number) => { const [s, c] = sincos(theta); return setC6( - m || [], + out || [], c, s, -s, c, 0, 0 ); }; +/** + * Constructs a M33 X rotation matrix for given `theta`. + * + * @param out + * @param theta + */ export const rotationX33 = - (m: Mat, theta: number) => { + (out: Mat, theta: number) => { const [s, c] = sincos(theta); return setC( - m || [], + out || [], 1, 0, 0, 0, c, s, 0, -s, c, ); }; +/** + * Constructs a M33 Y rotation matrix for given `theta`. + * + * @param out + * @param theta + */ export const rotationY33 = - (m: Mat, theta: number) => { + (out: Mat, theta: number) => { const [s, c] = sincos(theta); return setC( - m || [], + out || [], c, 0, -s, 0, 1, 0, s, 0, c, ); }; +/** + * Constructs a M33 Z rotation matrix for given `theta`. + * + * @param out + * @param theta + */ export const rotationZ33 = - (m: Mat, theta: number) => { + (out: Mat, theta: number) => { const [s, c] = sincos(theta); return setC( - m || [], + out || [], c, s, 0, -s, c, 0, 0, 0, 1, ); }; +/** + * Constructs a M44 X rotation matrix for given `theta`. + * + * @param out + * @param theta + */ export const rotationX44 = - (m: Mat, theta: number) => { + (out: Mat, theta: number) => { const [s, c] = sincos(theta); return setC( - m || [], + out || [], 1, 0, 0, 0, 0, c, s, 0, 0, -s, c, 0, @@ -68,11 +104,17 @@ export const rotationX44 = ); }; +/** + * Constructs a M44 Y rotation matrix for given `theta`. + * + * @param out + * @param theta + */ export const rotationY44 = - (m: Mat, theta: number) => { + (out: Mat, theta: number) => { const [s, c] = sincos(theta); return setC( - m || [], + out || [], c, 0, -s, 0, 0, 1, 0, 0, s, 0, c, 0, @@ -80,11 +122,17 @@ export const rotationY44 = ); }; +/** + * Constructs a M44 Z rotation matrix for given `theta`. + * + * @param out + * @param theta + */ export const rotationZ44 = - (m: Mat, theta: number) => { + (out: Mat, theta: number) => { const [s, c] = sincos(theta); return setC( - m || [], + out || [], c, s, 0, 0, -s, c, 0, 0, 0, 0, 1, 0, diff --git a/packages/matrices/src/row.ts b/packages/matrices/src/row.ts index 098f47ef63..df5344a440 100644 --- a/packages/matrices/src/row.ts +++ b/packages/matrices/src/row.ts @@ -6,6 +6,14 @@ import { } from "@thi.ng/vectors3"; import { MultiVecOpMN } from "./api"; +/** + * Extracts row vector from given matrix and writes result to `out`. If + * `out` is null, creates new vector. + * + * @param out + * @param mat + * @param column + */ export const row: MultiVecOpMN = vop(1); export const row22 = diff --git a/packages/matrices/src/scale-center.ts b/packages/matrices/src/scale-center.ts index 950a1ca76b..012cdef0cd 100644 --- a/packages/matrices/src/scale-center.ts +++ b/packages/matrices/src/scale-center.ts @@ -4,6 +4,13 @@ import { concat } from "./concat"; import { scale23, scale44 } from "./scale"; import { translation23, translation44 } from "./translation"; +/** + * Computes a M23 representing a scale operation with origin `p` and + * writes result to `out`. + * + * @param out + * @param m + */ export const scaleWithCenter23 = (m: Mat, p: ReadonlyVec, s: number | ReadonlyVec) => concat( m, @@ -12,6 +19,13 @@ export const scaleWithCenter23 = (m: Mat, p: ReadonlyVec, s: number | ReadonlyVe translation23([], neg([], p)) ); +/** + * Computes a M44 representing a scale operation with origin `p` and + * writes result to `out`. + * + * @param out + * @param m + */ export const scaleWithCenter44 = (m: Mat, p: ReadonlyVec, s: number | ReadonlyVec) => concat( m, diff --git a/packages/matrices/src/scale.ts b/packages/matrices/src/scale.ts index fb09068e14..2e1baf9709 100644 --- a/packages/matrices/src/scale.ts +++ b/packages/matrices/src/scale.ts @@ -7,6 +7,13 @@ import { } from "@thi.ng/vectors3"; import { Mat } from "./api"; +/** + * Computes M22 scale matrix and writes result to `out`. If `s` is a + * number, scaling will be uniform. + * + * @param m + * @param s + */ export const scale22 = (m: Mat, s: number | ReadonlyVec) => ( s = isNumber(s) ? [s, s] : s, @@ -17,6 +24,13 @@ export const scale22 = ) ); +/** + * Computes M23 scale matrix and writes result to `out`. If `s` is a + * number, scaling will be uniform. + * + * @param m + * @param s + */ export const scale23 = (m: Mat, s: number | ReadonlyVec) => ( s = isNumber(s) ? [s, s] : s, @@ -28,6 +42,13 @@ export const scale23 = ) ); +/** + * Computes M33 scale matrix and writes result to `out`. If `s` is a + * number, scaling will be uniform. + * + * @param m + * @param s + */ export const scale33 = (m: Mat, s: number | ReadonlyVec) => ( s = isNumber(s) ? [s, s, s] : s, @@ -39,6 +60,13 @@ export const scale33 = ) ); +/** + * Computes M44 scale matrix and writes result to `out`. If `s` is a + * number, scaling will be uniform. + * + * @param m + * @param s + */ export const scale44 = (m: Mat, s: number | ReadonlyVec) => ( s = isNumber(s) ? [s, s, s] : s, diff --git a/packages/matrices/src/sub.ts b/packages/matrices/src/sub.ts index 2b496d02e8..634ed5dc0e 100644 --- a/packages/matrices/src/sub.ts +++ b/packages/matrices/src/sub.ts @@ -2,6 +2,16 @@ import { sub as _sub, sub4 } from "@thi.ng/vectors3"; import { MatOpMM, MultiMatOpMM } from "./api"; import { defMath } from "./internal/codegen"; +/** + * Componentwise matrix subtraction. If `out` is not + * given, writes result in `a`. + * + * out = a - b + * + * @param out + * @param a + * @param b + */ export const sub: MultiMatOpMM = _sub; export const sub22: MatOpMM = sub4; export const [sub23, sub33, sub44] = defMath(sub, "-"); diff --git a/packages/matrices/src/subn.ts b/packages/matrices/src/subn.ts index a8338b1d09..6a3a19d5bd 100644 --- a/packages/matrices/src/subn.ts +++ b/packages/matrices/src/subn.ts @@ -2,6 +2,16 @@ import { subN as _subN, subN4 } from "@thi.ng/vectors3"; import { MatOpMN, MultiMatOpMN } from "./api"; import { defMathN } from "./internal/codegen"; +/** + * Subtracts matrix componentwise with single scalar. If `out` is not + * given, writes result in `mat`. + * + * out = mat - n + * + * @param out + * @param mat + * @param n + */ export const subN: MultiMatOpMN = _subN; export const subN22: MatOpMN = subN4; export const [subN23, subN33, subN44] = defMathN(subN, "-"); diff --git a/packages/matrices/src/translation.ts b/packages/matrices/src/translation.ts index 35d243edd9..dfe44d8054 100644 --- a/packages/matrices/src/translation.ts +++ b/packages/matrices/src/translation.ts @@ -1,10 +1,22 @@ import { ReadonlyVec, setC, setC6 } from "@thi.ng/vectors3"; import { Mat } from "./api"; +/** + * Constructs a M23 translation matrix. + * + * @param out + * @param v + */ export const translation23 = (m: Mat, v: ReadonlyVec) => setC6(m || [], 1, 0, 0, 1, v[0], v[1]); +/** + * Constructs a M44 translation matrix. + * + * @param out + * @param v + */ export const translation44 = (m: Mat, v: ReadonlyVec) => setC( diff --git a/packages/matrices/src/transpose.ts b/packages/matrices/src/transpose.ts index 2d96219287..5aa6bb6c54 100644 --- a/packages/matrices/src/transpose.ts +++ b/packages/matrices/src/transpose.ts @@ -1,6 +1,12 @@ import { setC, setC4 } from "@thi.ng/vectors3"; import { MatOpM } from "./api"; +/** + * Writes transposition of M22 `m` to `out`. + * + * @param out + * @param m + */ export const transpose22: MatOpM = (out, m) => setC4( @@ -9,6 +15,12 @@ export const transpose22: MatOpM = m[1], m[3], ); +/** + * Writes transposition of M33 `m` to `out`. + * + * @param out + * @param m + */ export const transpose33: MatOpM = (out, m) => setC( @@ -18,6 +30,12 @@ export const transpose33: MatOpM = m[2], m[5], m[8], ); +/** + * Writes transposition of M44 `m` to `out`. + * + * @param out + * @param m + */ export const transpose44: MatOpM = (out, m) => setC( From db4a2018d7b2a97856b9ab55754dc457390dd2d8 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 20 Jan 2019 04:24:18 +0000 Subject: [PATCH 316/333] feat(geom): re-add barycentric conversions, collation mappers (still unused) --- packages/geom3/src/internal/barycentric.ts | 29 +++++++++++++ packages/geom3/src/internal/collate.ts | 49 ++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 packages/geom3/src/internal/barycentric.ts create mode 100644 packages/geom3/src/internal/collate.ts diff --git a/packages/geom3/src/internal/barycentric.ts b/packages/geom3/src/internal/barycentric.ts new file mode 100644 index 0000000000..6e756627f9 --- /dev/null +++ b/packages/geom3/src/internal/barycentric.ts @@ -0,0 +1,29 @@ +import { + addW3, + dot, + magSq, + ReadonlyVec, + setC3, + sub, + Vec +} from "@thi.ng/vectors3"; + +export const toBarycentric = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, p: ReadonlyVec, out: Vec = []) => { + const u = sub([], b, a); + const v = sub([], c, a); + const w = sub([], p, a); + const uu = magSq(u); + const vv = magSq(v); + const uv = dot(u, v); + const uw = dot(u, w); + const vw = dot(v, w); + const d = 1 / (uv * uv - uu * vv); + const s = d * (uv * vw - vv * uw); + const t = d * (uv * uw - uu * vw); + return setC3(out, 1 - (s + t), s, t); + }; + +export const fromBarycentric = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, p: ReadonlyVec, out?: Vec) => + addW3(out, a, b, c, p[0], p[1], p[2]); diff --git a/packages/geom3/src/internal/collate.ts b/packages/geom3/src/internal/collate.ts new file mode 100644 index 0000000000..7a3d47726f --- /dev/null +++ b/packages/geom3/src/internal/collate.ts @@ -0,0 +1,49 @@ +import { Vec, StridedVec } from "@thi.ng/vectors3"; + +export interface CollateOpts { + buf: Vec; + start: number; + cstride: number; + estride: number; +} + +export const remap = ( + buf: Vec, + pts: StridedVec[], + start: number, + cstride: number, + estride: number +) => { + for (let i = pts.length; --i >= 0;) { + const p = pts[i]; + p.buf = buf; + p.offset = start + i * estride; + p.stride = cstride; + } + return buf; +}; + +export const collateWith = ( + fn: (buf: Vec, src: Iterable>, start, cstride, estride) => Vec, + pts: StridedVec[], + opts: Partial, + stride: number +) => { + opts = { + start: 0, + cstride: 1, + estride: stride, + ...opts + }; + const { start, cstride, estride } = opts; + return remap( + fn( + opts.buf || new Array(start + pts.length * estride).fill(0), + pts, + start, + cstride, + estride + ), + pts, start, cstride, estride + ); +}; From 6f341c5c9318200a27db7b9af8e22be62cb4c330 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 20 Jan 2019 12:57:10 +0000 Subject: [PATCH 317/333] docs(vector-pools): fix AttribPool example layout --- packages/vector-pools/src/attrib-pool.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/vector-pools/src/attrib-pool.ts b/packages/vector-pools/src/attrib-pool.ts index 5b1960d790..85c80d02d5 100644 --- a/packages/vector-pools/src/attrib-pool.ts +++ b/packages/vector-pools/src/attrib-pool.ts @@ -15,11 +15,11 @@ import { } from "./api"; /* - * WASM mem : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... - * typedarr : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... offset = 4 (bytes) - * pos (f32) : X X X X X Y Y Y Y X ... offset = 0 (bytes), size = 2 (f32) - * uv (f32) : U U U U V V V V ... offset = 8 (bytes), size = 2 (f32) - * col (u16) : R R G G B B A A ... offset = 16 (bytes), size = 4 (u16) + * WASM mem : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... + * typedarr : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... global offset = 4 (bytes) + * pos (f32) : X X X X Y Y Y Y X ... offset = 0 (bytes), size = 2 (f32) + * uv (f32) : U U U U V V V V ... offset = 8 (bytes), size = 2 (f32) + * col (u16) : R R G G B B A A ... offset = 16 (bytes), size = 4 (u16) * * global stride: 24 */ From 9a5076944a29537bd6013df67e897eb4c7ff7f35 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 20 Jan 2019 15:51:48 +0000 Subject: [PATCH 318/333] feat(hdom-canvas): add ellipse() / ellipticArc(), update readme --- packages/hdom-canvas/README.md | 133 +++++++++++++++++++++--------- packages/hdom-canvas/src/index.ts | 35 ++++++-- 2 files changed, 126 insertions(+), 42 deletions(-) diff --git a/packages/hdom-canvas/README.md b/packages/hdom-canvas/README.md index fdc8a39d57..71429dbae6 100644 --- a/packages/hdom-canvas/README.md +++ b/packages/hdom-canvas/README.md @@ -7,41 +7,42 @@ This project is part of the [@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo. - - -- [@thi.ng/hdom-canvas](#thinghdom-canvas) - - [About](#about) - - [Status](#status) - - [Installation](#installation) - - [Dependencies](#dependencies) - - [Usage examples](#usage-examples) - - [How it works](#how-it-works) - - [Restrictions & behavior controls](#restrictions--behavior-controls) - - [HDPI support](#hdpi-support) - - [SVG conversion](#svg-conversion) - - [Supported shape types](#supported-shape-types) - - [Group](#group) - - [Definition group](#definition-group) - - [Circle](#circle) - - [Rect](#rect) - - [Arc](#arc) - - [Line](#line) - - [Horizontal Line](#horizontal-line) - - [Vertical Line](#vertical-line) - - [Polyline / Polygon](#polyline--polygon) - - [Path](#path) - - [Points](#points) - - [Text](#text) - - [Image](#image) - - [Gradients](#gradients) - - [Attributes](#attributes) - - [Coordinate transformations](#coordinate-transformations) - - [Transform matrix](#transform-matrix) - - [Translation](#translation) - - [Scaling](#scaling) - - [Rotation](#rotation) - - [Authors](#authors) - - [License](#license) + + +- [About](#about) + - [Status](#status) +- [Installation](#installation) +- [Dependencies](#dependencies) +- [Usage examples](#usage-examples) +- [How it works](#how-it-works) + - [Restrictions & behavior controls](#restrictions--behavior-controls) + - [HDPI support](#hdpi-support) +- [SVG conversion](#svg-conversion) +- [Supported shape types](#supported-shape-types) + - [Group](#group) + - [Definition group](#definition-group) + - [Circle](#circle) + - [Ellipse](#ellipse) + - [Rect](#rect) + - [Arc](#arc) + - [Line](#line) + - [Horizontal Line](#horizontal-line) + - [Vertical Line](#vertical-line) + - [Polyline / Polygon](#polyline--polygon) + - [Path](#path) + - [SVG paths with arc segments](#svg-paths-with-arc-segments) + - [Points](#points) + - [Text](#text) + - [Image](#image) + - [Gradients](#gradients) +- [Attributes](#attributes) +- [Coordinate transformations](#coordinate-transformations) + - [Transform matrix](#transform-matrix) + - [Translation](#translation) + - [Scaling](#scaling) + - [Rotation](#rotation) +- [Authors](#authors) +- [License](#license) @@ -94,6 +95,31 @@ start(() => { }); ``` +Usage with +[@thi.ng/geom3](https://github.com/thi-ng/umbrella/tree/master/packages/geom3) +shape primitives: + +```ts +import { start } from "@thi.ng/hdom"; +import { canvas } from "@thi.ng/hdom-canvas"; +import * as g from "@thi.ng/geom3"; + +start(() => { + const t = Date.now() * 0.001; + return [canvas, { width: 100, height: 100 }, + g.group( + { translate: [50,50], fill: "none" }, + g.withAttribs( + g.asPolygon(g.circle(50), 6), + { rotate: (Date.now() * 0.01) % (Math.PI * 2), stroke: "red" } + ), + g.star(25 + 25 * Math.sin(t), 6, [0.5, 1], { stroke: "blue" }), + ) + ]; +}); + +``` + ## How it works The package provides a `canvas` component which uses the branch-local @@ -105,8 +131,11 @@ component, but are then translated into canvas API draw commands during the hdom update process. Any embedded shape component functions receive the user context object as first arg, just like normal hdom components. -Shape components are expressed in standard hiccup syntax, however with -the following... +Shape components are expressed in standard hiccup syntax (or as objects +implementing the `IToHiccup()` interface, like the shape types provided +by +[@thi.ng/geom3](https://github.com/thi-ng/umbrella/tree/master/packages/geom3)), +and with the following... ### Restrictions & behavior controls @@ -236,6 +265,12 @@ used, should always come first in a scene tree. ["circle", attribs, [x, y], radius] ``` +### Ellipse + +```ts +["ellipse", attribs, [x, y], [rx,ry], axisTheta?, start?, end?, ccw?] +``` + ### Rect ```ts @@ -251,6 +286,9 @@ clamped to `Math.min(w, h)/2`. ["arc", attribs, [x, y], radius, startAngle, endAngle, anticlockwise?] ``` +Only circular arcs are supported in this format. Please see [note about +differences to SVG](#svg-paths-with-arc-segments). + ### Line ```ts @@ -305,6 +343,27 @@ relative to the end point of the previous segment. | `["A", [x1,y1], [x2, y2], r]` | Arc | | `["Z"]` | Close (sub)path | +#### SVG paths with arc segments + +**IMPORTANT:** Due to differences between SVG and canvas API arc +handling, SVG paths containing arc segments are **NOT** compatible with +the above format. To draw such paths reliably, these should first be +converted to use cubics. E.g. here using +[@thi.ng/geom3](https://github.com/thi-ng/umbrella/tree/master/packages/geom3): + +```ts +import { normalizedPath, pathFromSVG } from "@thi.ng/geom3"; + +// path w/ ac segments +const a = pathFromSvg("M0,0H80A20,20,0,0,1,100,20V30A20,20,0,0,1,80,50")[0]; + +// normalized to only use cubic curves +const b = normalizedPath(a); + +asSvg(b); +// +``` + ### Points ```ts diff --git a/packages/hdom-canvas/src/index.ts b/packages/hdom-canvas/src/index.ts index 3be1838b54..bfb4f6e495 100644 --- a/packages/hdom-canvas/src/index.ts +++ b/packages/hdom-canvas/src/index.ts @@ -275,6 +275,9 @@ const walk = case "circle": circularArc(ctx, attribs, shape[2], shape[3]); break; + case "ellipse": + ellipticArc(ctx, attribs, shape[2], shape[3], shape[4], shape[5], shape[6]); + break; case "arc": circularArc(ctx, attribs, shape[2], shape[3], shape[4], shape[5]); break; @@ -505,29 +508,31 @@ const path = ( ctx.lineTo(b[0], b[1]); a = b; break; - // horizontal line + // horizontal line rel case "h": b = [a[0] + b, a[1]]; ctx.lineTo(b[0], b[1]); a = b; break; + // horizontal line abs case "H": b = [b, a[1]]; ctx.lineTo(b[0], b[1]); a = b; break; - // vertical line + // vertical line rel case "v": b = [a[0], a[1] + b]; ctx.lineTo(b[0], b[1]); a = b; break; + // vertical line abs case "V": b = [a[0], b]; ctx.lineTo(b[0], b[1]); a = b; break; - // cubic / bezier curve to + // cubic curve rel case "c": c = s[2]; d = s[3]; @@ -539,6 +544,7 @@ const path = ( ); a = d; break; + // cubic curve abs case "C": c = s[2]; d = s[3]; @@ -549,7 +555,7 @@ const path = ( ); a = d; break; - // quadratic curve to + // quadratic curve rel case "q": c = s[2]; c = [a[0] + c[0], a[1] + c[1]]; @@ -559,6 +565,7 @@ const path = ( ); a = c; break; + // quadratic curve abs case "Q": c = s[2]; ctx.quadraticCurveTo( @@ -567,7 +574,8 @@ const path = ( ); a = c; break; - // arc to + // circular arc rel + // Note: NOT compatible w/ SVG arc segments case "a": c = s[2]; c = [a[0] + c[0], a[1] + c[1]]; @@ -578,6 +586,8 @@ const path = ( ); a = c; break; + // circular arc abs + // Note: NOT compatible w/ SVG arc segments case "A": c = s[2]; ctx.arcTo( @@ -611,6 +621,21 @@ const circularArc = ( endShape(ctx, attribs); }; +const ellipticArc = ( + ctx: CanvasRenderingContext2D, + attribs: IObjectOf, + pos: ReadonlyVec, + r: ReadonlyVec, + axis = 0, + start = 0, + end = TAU, + ccw = false +) => { + ctx.beginPath(); + ctx.ellipse(pos[0], pos[1], r[0], r[1], axis, start, end, ccw); + endShape(ctx, attribs); +}; + const rect = (ctx: CanvasRenderingContext2D, attribs: IObjectOf, pos: ReadonlyVec, From 8e2c8b5c835487865200b65cdc5340ccfe7abd5d Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 20 Jan 2019 16:01:11 +0000 Subject: [PATCH 319/333] refactor(geom): update withAttribs() return type --- packages/geom3/src/ops/with-attribs.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/geom3/src/ops/with-attribs.ts b/packages/geom3/src/ops/with-attribs.ts index b1000a4c23..2b8649f836 100644 --- a/packages/geom3/src/ops/with-attribs.ts +++ b/packages/geom3/src/ops/with-attribs.ts @@ -1,7 +1,10 @@ import { Attribs, IShape } from "../api"; -export const withAttribs = - (shape: IShape, attribs: Attribs, replace = true) => { - shape.attribs = replace ? attribs : { ...shape.attribs, ...attribs }; - return shape; - }; +export const withAttribs = ( + shape: T, + attribs: Attribs, + replace = true +) => { + shape.attribs = replace ? attribs : { ...shape.attribs, ...attribs }; + return shape; +}; From 2f26cf68bbfcaf57acaa1b24785d712bb45c7e0a Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 20 Jan 2019 18:22:11 +0000 Subject: [PATCH 320/333] docs(hdom-canvas): fix readme example --- packages/hdom-canvas/README.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/hdom-canvas/README.md b/packages/hdom-canvas/README.md index 71429dbae6..55ad4cee5f 100644 --- a/packages/hdom-canvas/README.md +++ b/packages/hdom-canvas/README.md @@ -108,16 +108,17 @@ start(() => { const t = Date.now() * 0.001; return [canvas, { width: 100, height: 100 }, g.group( - { translate: [50,50], fill: "none" }, - g.withAttribs( - g.asPolygon(g.circle(50), 6), - { rotate: (Date.now() * 0.01) % (Math.PI * 2), stroke: "red" } - ), - g.star(25 + 25 * Math.sin(t), 6, [0.5, 1], { stroke: "blue" }), + [ + g.withAttribs( + g.asPolygon(g.circle(50), 6), + { rotate: t % Math.PI, stroke: "red" } + ), + g.star(25 + 25 * Math.sin(t), 6, [0.5, 1], { stroke: "blue" }), + ], + { translate: [50, 50], fill: "none" } ) ]; }); - ``` ## How it works From ff5036692dee25e60d7b51177eb8745a87f4b53a Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 20 Jan 2019 21:58:32 +0000 Subject: [PATCH 321/333] build: update depgraph script to display per package deps/dependents --- scripts/depgraph | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/scripts/depgraph b/scripts/depgraph index 9a35a2720c..ad39db192e 100755 --- a/scripts/depgraph +++ b/scripts/depgraph @@ -53,7 +53,14 @@ tx.run( ([p, d]) => g.addDependency(p, d), packages); -// console.log(g.transitiveDependencies("@thi.ng/geom3")); -console.log("topo order:", g.sort().map((x) => x.replace("@thi.ng/", "")).join(" ")); -console.log("done"); \ No newline at end of file +const sorted = g.sort(); +console.log("topo order:", sorted.map((x) => x.substr(8)).join(" "), "\n\n"); + +const noprefix = (ids) => [...ids].sort().map((x) => x.substr(8)); + +sorted.forEach((x) => { + console.log(`${x}:`); + console.log(`\t<-- ${noprefix(g.transitiveDependencies(x))}`); + console.log(`\t--> ${noprefix(g.transitiveDependents(x))}\n\n`); +}); From 682385a10c9f24ab6825121ffb69ad27b62b0da0 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 20 Jan 2019 22:06:15 +0000 Subject: [PATCH 322/333] build(geom): replace old geom package w/ geom3 --- packages/geom/package.json | 22 +- packages/geom/src/api.ts | 738 ++++++++++++++---- packages/geom/src/arc2.ts | 305 -------- packages/geom/src/bezier2.ts | 317 -------- packages/geom/src/circle2.ts | 191 ----- packages/geom/src/container2.ts | 133 ---- packages/geom/src/container3.ts | 108 --- packages/{geom3 => geom}/src/ctors/arc.ts | 0 packages/{geom3 => geom}/src/ctors/circle.ts | 0 packages/{geom3 => geom}/src/ctors/cubic.ts | 0 packages/{geom3 => geom}/src/ctors/ellipse.ts | 0 packages/{geom3 => geom}/src/ctors/group.ts | 0 packages/{geom3 => geom}/src/ctors/line.ts | 0 packages/{geom3 => geom}/src/ctors/path.ts | 0 packages/{geom3 => geom}/src/ctors/points.ts | 0 packages/{geom3 => geom}/src/ctors/polygon.ts | 0 .../{geom3 => geom}/src/ctors/polyline.ts | 0 packages/{geom3 => geom}/src/ctors/quad.ts | 0 .../{geom3 => geom}/src/ctors/quadratic.ts | 0 packages/{geom3 => geom}/src/ctors/ray.ts | 0 packages/{geom3 => geom}/src/ctors/rect.ts | 0 .../{geom3 => geom}/src/ctors/triangle.ts | 0 packages/geom/src/fit.ts | 41 - packages/geom/src/index.ts | 100 ++- packages/geom/src/internal/arc-length.ts | 14 - .../{geom3 => geom}/src/internal/arc-point.ts | 0 packages/geom/src/internal/area.ts | 9 - packages/geom/src/internal/args.ts | 117 ++- packages/geom/src/internal/barycentric.ts | 37 +- packages/geom/src/internal/bounds.ts | 153 +++- packages/geom/src/internal/centroid.ts | 35 +- packages/geom/src/internal/circumcenter.ts | 40 +- .../{geom3 => geom}/src/internal/clockwise.ts | 0 packages/geom/src/internal/closest-point.ts | 199 ++++- packages/geom/src/internal/collate.ts | 22 +- .../src/internal/copy-points.ts | 0 packages/geom/src/internal/corner.ts | 47 +- .../{geom3 => geom}/src/internal/direction.ts | 0 .../{geom3 => geom}/src/internal/dispatch.ts | 0 .../internal/douglas\342\200\223peucker.ts" | 15 +- packages/geom/src/internal/edges.ts | 13 +- packages/geom/src/internal/eq-delta.ts | 12 - packages/geom/src/internal/graham-scan.ts | 95 ++- packages/geom/src/internal/liang-barsky.ts | 107 ++- .../geom/src/internal/line-intersection.ts | 32 - .../src/internal/point-in-array.ts | 0 .../src/internal/poly-arc-length.ts | 0 .../{geom3 => geom}/src/internal/poly-area.ts | 0 .../src/internal/poly-centroid.ts | 0 .../src/internal/poly-point-inside.ts | 0 .../{geom3 => geom}/src/internal/sampler.ts | 0 .../{geom3 => geom}/src/internal/split.ts | 0 .../src/internal/subdiv-curve.ts | 0 .../geom/src/internal/sutherland-hodgeman.ts | 34 +- .../src/internal/tessellate.ts | 0 .../src/internal/transform-points.ts | 0 .../src/internal/translate-points.ts | 0 .../src/internal/triangle-point-inside.ts | 0 .../src/internal/union-bounds.ts | 0 .../{geom3 => geom}/src/isec/circle-circle.ts | 0 .../{geom3 => geom}/src/isec/line-line.ts | 0 .../{geom3 => geom}/src/isec/ray-circle.ts | 0 packages/{geom3 => geom}/src/isec/ray-line.ts | 0 packages/{geom3 => geom}/src/isec/ray-poly.ts | 0 .../{geom3 => geom}/src/isec/rect-circle.ts | 0 .../{geom3 => geom}/src/isec/rect-rect.ts | 0 packages/geom/src/line2.ts | 109 --- .../{geom3 => geom}/src/ops/arc-length.ts | 0 packages/{geom3 => geom}/src/ops/area.ts | 0 packages/{geom3 => geom}/src/ops/as-cubic.ts | 0 .../{geom3 => geom}/src/ops/as-polygon.ts | 0 packages/{geom3 => geom}/src/ops/as-svg.ts | 0 packages/{geom3 => geom}/src/ops/bounds.ts | 0 packages/{geom3 => geom}/src/ops/center.ts | 0 packages/{geom3 => geom}/src/ops/centroid.ts | 0 .../{geom3 => geom}/src/ops/classify-point.ts | 0 .../{geom3 => geom}/src/ops/clip-convex.ts | 0 .../{geom3 => geom}/src/ops/closest-point.ts | 0 .../{geom3 => geom}/src/ops/convex-hull.ts | 0 packages/{geom3 => geom}/src/ops/edges.ts | 0 .../src/ops/fit-into-bounds.ts | 0 packages/{geom3 => geom}/src/ops/flip.ts | 0 .../{geom3 => geom}/src/ops/intersects.ts | 0 packages/{geom3 => geom}/src/ops/map-point.ts | 0 packages/{geom3 => geom}/src/ops/point-at.ts | 0 .../{geom3 => geom}/src/ops/point-inside.ts | 0 packages/{geom3 => geom}/src/ops/resample.ts | 0 packages/{geom3 => geom}/src/ops/scatter.ts | 0 packages/{geom3 => geom}/src/ops/simplify.ts | 0 packages/{geom3 => geom}/src/ops/split-at.ts | 0 .../{geom3 => geom}/src/ops/split-near.ts | 0 .../{geom3 => geom}/src/ops/subdiv-curve.ts | 0 .../{geom3 => geom}/src/ops/tangent-at.ts | 0 .../{geom3 => geom}/src/ops/tessellate.ts | 0 packages/{geom3 => geom}/src/ops/transform.ts | 0 packages/{geom3 => geom}/src/ops/translate.ts | 0 packages/{geom3 => geom}/src/ops/union.ts | 0 .../{geom3 => geom}/src/ops/unmap-point.ts | 0 packages/{geom3 => geom}/src/ops/vertices.ts | 0 .../{geom3 => geom}/src/ops/warp-points.ts | 0 .../{geom3 => geom}/src/ops/with-attribs.ts | 0 packages/geom/src/path2.ts | 481 ------------ packages/geom/src/polygon2.ts | 167 ---- packages/geom/src/polyline2.ts | 100 --- packages/geom/src/quad2.ts | 76 -- packages/geom/src/rect2.ts | 198 ----- packages/geom/src/sampler.ts | 71 -- packages/geom/src/subdiv-curve.ts | 106 --- packages/geom/src/tessellate.ts | 165 ---- packages/geom/src/triangle2.ts | 96 --- packages/geom/src/warp.ts | 15 - packages/geom/test/circle2.ts | 125 --- packages/{geom3 => geom}/test/index.ts | 2 +- packages/geom/test/poly2.ts | 37 - packages/geom/test/tsconfig.json | 4 +- packages/geom/tsconfig.json | 3 +- packages/geom3/.npmignore | 13 - packages/geom3/LICENSE | 201 ----- packages/geom3/README.md | 52 -- packages/geom3/package.json | 57 -- packages/geom3/src/api.ts | 703 ----------------- packages/geom3/src/index.ts | 85 -- packages/geom3/src/internal/args.ts | 49 -- packages/geom3/src/internal/barycentric.ts | 29 - packages/geom3/src/internal/bounds.ts | 139 ---- packages/geom3/src/internal/centroid.ts | 19 - packages/geom3/src/internal/circumcenter.ts | 43 - packages/geom3/src/internal/closest-point.ts | 228 ------ packages/geom3/src/internal/collate.ts | 49 -- packages/geom3/src/internal/corner.ts | 14 - .../internal/douglas\342\200\223peucker.ts" | 42 - packages/geom3/src/internal/edges.ts | 12 - packages/geom3/src/internal/graham-scan.ts | 87 --- packages/geom3/src/internal/liang-barsky.ts | 75 -- .../geom3/src/internal/sutherland-hodgeman.ts | 44 -- packages/geom3/test/tsconfig.json | 11 - packages/geom3/tsconfig.json | 12 - 137 files changed, 1272 insertions(+), 5383 deletions(-) delete mode 100644 packages/geom/src/arc2.ts delete mode 100644 packages/geom/src/bezier2.ts delete mode 100644 packages/geom/src/circle2.ts delete mode 100644 packages/geom/src/container2.ts delete mode 100644 packages/geom/src/container3.ts rename packages/{geom3 => geom}/src/ctors/arc.ts (100%) rename packages/{geom3 => geom}/src/ctors/circle.ts (100%) rename packages/{geom3 => geom}/src/ctors/cubic.ts (100%) rename packages/{geom3 => geom}/src/ctors/ellipse.ts (100%) rename packages/{geom3 => geom}/src/ctors/group.ts (100%) rename packages/{geom3 => geom}/src/ctors/line.ts (100%) rename packages/{geom3 => geom}/src/ctors/path.ts (100%) rename packages/{geom3 => geom}/src/ctors/points.ts (100%) rename packages/{geom3 => geom}/src/ctors/polygon.ts (100%) rename packages/{geom3 => geom}/src/ctors/polyline.ts (100%) rename packages/{geom3 => geom}/src/ctors/quad.ts (100%) rename packages/{geom3 => geom}/src/ctors/quadratic.ts (100%) rename packages/{geom3 => geom}/src/ctors/ray.ts (100%) rename packages/{geom3 => geom}/src/ctors/rect.ts (100%) rename packages/{geom3 => geom}/src/ctors/triangle.ts (100%) delete mode 100644 packages/geom/src/fit.ts delete mode 100644 packages/geom/src/internal/arc-length.ts rename packages/{geom3 => geom}/src/internal/arc-point.ts (100%) delete mode 100644 packages/geom/src/internal/area.ts rename packages/{geom3 => geom}/src/internal/clockwise.ts (100%) rename packages/{geom3 => geom}/src/internal/copy-points.ts (100%) rename packages/{geom3 => geom}/src/internal/direction.ts (100%) rename packages/{geom3 => geom}/src/internal/dispatch.ts (100%) delete mode 100644 packages/geom/src/internal/eq-delta.ts delete mode 100644 packages/geom/src/internal/line-intersection.ts rename packages/{geom3 => geom}/src/internal/point-in-array.ts (100%) rename packages/{geom3 => geom}/src/internal/poly-arc-length.ts (100%) rename packages/{geom3 => geom}/src/internal/poly-area.ts (100%) rename packages/{geom3 => geom}/src/internal/poly-centroid.ts (100%) rename packages/{geom3 => geom}/src/internal/poly-point-inside.ts (100%) rename packages/{geom3 => geom}/src/internal/sampler.ts (100%) rename packages/{geom3 => geom}/src/internal/split.ts (100%) rename packages/{geom3 => geom}/src/internal/subdiv-curve.ts (100%) rename packages/{geom3 => geom}/src/internal/tessellate.ts (100%) rename packages/{geom3 => geom}/src/internal/transform-points.ts (100%) rename packages/{geom3 => geom}/src/internal/translate-points.ts (100%) rename packages/{geom3 => geom}/src/internal/triangle-point-inside.ts (100%) rename packages/{geom3 => geom}/src/internal/union-bounds.ts (100%) rename packages/{geom3 => geom}/src/isec/circle-circle.ts (100%) rename packages/{geom3 => geom}/src/isec/line-line.ts (100%) rename packages/{geom3 => geom}/src/isec/ray-circle.ts (100%) rename packages/{geom3 => geom}/src/isec/ray-line.ts (100%) rename packages/{geom3 => geom}/src/isec/ray-poly.ts (100%) rename packages/{geom3 => geom}/src/isec/rect-circle.ts (100%) rename packages/{geom3 => geom}/src/isec/rect-rect.ts (100%) delete mode 100644 packages/geom/src/line2.ts rename packages/{geom3 => geom}/src/ops/arc-length.ts (100%) rename packages/{geom3 => geom}/src/ops/area.ts (100%) rename packages/{geom3 => geom}/src/ops/as-cubic.ts (100%) rename packages/{geom3 => geom}/src/ops/as-polygon.ts (100%) rename packages/{geom3 => geom}/src/ops/as-svg.ts (100%) rename packages/{geom3 => geom}/src/ops/bounds.ts (100%) rename packages/{geom3 => geom}/src/ops/center.ts (100%) rename packages/{geom3 => geom}/src/ops/centroid.ts (100%) rename packages/{geom3 => geom}/src/ops/classify-point.ts (100%) rename packages/{geom3 => geom}/src/ops/clip-convex.ts (100%) rename packages/{geom3 => geom}/src/ops/closest-point.ts (100%) rename packages/{geom3 => geom}/src/ops/convex-hull.ts (100%) rename packages/{geom3 => geom}/src/ops/edges.ts (100%) rename packages/{geom3 => geom}/src/ops/fit-into-bounds.ts (100%) rename packages/{geom3 => geom}/src/ops/flip.ts (100%) rename packages/{geom3 => geom}/src/ops/intersects.ts (100%) rename packages/{geom3 => geom}/src/ops/map-point.ts (100%) rename packages/{geom3 => geom}/src/ops/point-at.ts (100%) rename packages/{geom3 => geom}/src/ops/point-inside.ts (100%) rename packages/{geom3 => geom}/src/ops/resample.ts (100%) rename packages/{geom3 => geom}/src/ops/scatter.ts (100%) rename packages/{geom3 => geom}/src/ops/simplify.ts (100%) rename packages/{geom3 => geom}/src/ops/split-at.ts (100%) rename packages/{geom3 => geom}/src/ops/split-near.ts (100%) rename packages/{geom3 => geom}/src/ops/subdiv-curve.ts (100%) rename packages/{geom3 => geom}/src/ops/tangent-at.ts (100%) rename packages/{geom3 => geom}/src/ops/tessellate.ts (100%) rename packages/{geom3 => geom}/src/ops/transform.ts (100%) rename packages/{geom3 => geom}/src/ops/translate.ts (100%) rename packages/{geom3 => geom}/src/ops/union.ts (100%) rename packages/{geom3 => geom}/src/ops/unmap-point.ts (100%) rename packages/{geom3 => geom}/src/ops/vertices.ts (100%) rename packages/{geom3 => geom}/src/ops/warp-points.ts (100%) rename packages/{geom3 => geom}/src/ops/with-attribs.ts (100%) delete mode 100644 packages/geom/src/path2.ts delete mode 100644 packages/geom/src/polygon2.ts delete mode 100644 packages/geom/src/polyline2.ts delete mode 100644 packages/geom/src/quad2.ts delete mode 100644 packages/geom/src/rect2.ts delete mode 100644 packages/geom/src/sampler.ts delete mode 100644 packages/geom/src/subdiv-curve.ts delete mode 100644 packages/geom/src/tessellate.ts delete mode 100644 packages/geom/src/triangle2.ts delete mode 100644 packages/geom/src/warp.ts delete mode 100644 packages/geom/test/circle2.ts rename packages/{geom3 => geom}/test/index.ts (80%) delete mode 100644 packages/geom/test/poly2.ts delete mode 100644 packages/geom3/.npmignore delete mode 100644 packages/geom3/LICENSE delete mode 100644 packages/geom3/README.md delete mode 100644 packages/geom3/package.json delete mode 100644 packages/geom3/src/api.ts delete mode 100644 packages/geom3/src/index.ts delete mode 100644 packages/geom3/src/internal/args.ts delete mode 100644 packages/geom3/src/internal/barycentric.ts delete mode 100644 packages/geom3/src/internal/bounds.ts delete mode 100644 packages/geom3/src/internal/centroid.ts delete mode 100644 packages/geom3/src/internal/circumcenter.ts delete mode 100644 packages/geom3/src/internal/closest-point.ts delete mode 100644 packages/geom3/src/internal/collate.ts delete mode 100644 packages/geom3/src/internal/corner.ts delete mode 100644 "packages/geom3/src/internal/douglas\342\200\223peucker.ts" delete mode 100644 packages/geom3/src/internal/edges.ts delete mode 100644 packages/geom3/src/internal/graham-scan.ts delete mode 100644 packages/geom3/src/internal/liang-barsky.ts delete mode 100644 packages/geom3/src/internal/sutherland-hodgeman.ts delete mode 100644 packages/geom3/test/tsconfig.json delete mode 100644 packages/geom3/tsconfig.json diff --git a/packages/geom/package.json b/packages/geom/package.json index bd08be6182..8a6f208839 100644 --- a/packages/geom/package.json +++ b/packages/geom/package.json @@ -1,7 +1,7 @@ { "name": "@thi.ng/geom", - "version": "0.2.11", - "description": "2D/3D geometry primitives", + "version": "0.0.1", + "description": "TODO", "module": "./index.js", "main": "./lib/index.js", "umd:main": "./lib/index.umd.js", @@ -16,9 +16,9 @@ "scripts": { "build": "yarn clean && yarn build:es6 && yarn build:bundle", "build:es6": "tsc --declaration", - "build:bundle": "../../scripts/bundle-module geom api checks errors math transducers vectors", + "build:bundle": "../../scripts/bundle-module geom api checks compose defmulti equiv errors hiccup hiccup-svg math matrices random transducers vectors3", "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib internal", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", "doc": "node_modules/.bin/typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public" @@ -34,18 +34,20 @@ "dependencies": { "@thi.ng/api": "^4.2.4", "@thi.ng/checks": "^1.5.14", + "@thi.ng/compose": "^0.3.0", + "@thi.ng/defmulti": "^0.7.0", + "@thi.ng/equiv": "^0.1.15", "@thi.ng/errors": "^0.1.12", + "@thi.ng/hiccup": "^2.7.2", + "@thi.ng/hiccup-svg": "^2.0.10", "@thi.ng/math": "^0.2.2", + "@thi.ng/matrices": "^0.0.1", + "@thi.ng/random": "^0.1.1", "@thi.ng/transducers": "^2.3.2", - "@thi.ng/vectors": "^1.4.12" + "@thi.ng/vectors3": "^0.0.1" }, "keywords": [ "ES6", - "geometry", - "2d", - "3d", - "shapes", - "intersection", "typescript" ], "publishConfig": { diff --git a/packages/geom/src/api.ts b/packages/geom/src/api.ts index f15cc72701..70df05131a 100644 --- a/packages/geom/src/api.ts +++ b/packages/geom/src/api.ts @@ -1,19 +1,59 @@ -import { IObjectOf } from "@thi.ng/api"; +import { ICopy, IObjectOf, IToHiccup } from "@thi.ng/api"; +import { isNumber } from "@thi.ng/checks"; +import { equiv } from "@thi.ng/equiv"; +import { illegalState } from "@thi.ng/errors"; import { - IVector, + add2, + add3, + maddN2, ReadonlyVec, - Vec, - Vec2 -} from "@thi.ng/vectors"; + set, + Vec +} from "@thi.ng/vectors3"; +import { arcPointAt, arcPointAtTheta } from "./internal/arc-point"; +import { copyPoints } from "./internal/copy-points"; -export const DEFAULT_SAMPLES = 32; - -export type Attribs = IObjectOf; +export const enum SegmentType { + MOVE, + LINE, + POLYLINE, + ARC, + CUBIC, + QUADRATIC, + CLOSE, +} -export type Tessellator> = - (points: ReadonlyArray) => T[][]; +export const enum Type { + AABB = 1, + ARC, + CIRCLE, + CUBIC, + CUBIC3, + ELLIPSE, + GROUP, + LINE, + LINE3, + PATH, + POINTS, + POINTS3, + POLYGON, + POLYGON3, + POLYLINE, + POLYLINE3, + QUAD, + QUAD3, + QUADRATIC, + QUADRATIC3, + RECT, + SPHERE, + TRIANGLE, + TRIANGLE3, + RAY, + RAY3, +} -export const enum LineIntersectionType { +export const enum IntersectionType { + NONE, PARALLEL, COINCIDENT, COINCIDENT_NO_INTERSECT, @@ -21,26 +61,40 @@ export const enum LineIntersectionType { INTERSECT_OUTSIDE, } -export const enum SegmentType { - MOVE, - LINE, - POLYLINE, - ARC, - CUBIC, - QUADRATIC, - CLOSE, +export const DEFAULT_SAMPLES = 20; + +export type Attribs = IObjectOf; + +export type Tessellator = (points: Vec[]) => Vec[][]; + +export type VecPair = [Vec, Vec]; + +export interface IShape extends + ICopy { + + readonly type: number | string; + attribs?: Attribs; } -export interface CollateOpts { - buf: Vec; - start: number; - cstride: number; - estride: number; +export interface AABBLike extends IShape { + pos: Vec; + size: Vec; + + max(): Vec; } -export interface LineIntersection { - type: LineIntersectionType; - isec?: T; +export interface IHiccupShape extends IShape, IToHiccup { } + +export interface IHiccupPathSegment { + toHiccupPathSegments(): any[]; +} + +export interface IntersectionResult { + type: IntersectionType; +} + +export interface LineIntersection extends IntersectionResult { + isec?: Vec; det?: number; alpha?: number; beta?: number; @@ -48,8 +102,16 @@ export interface LineIntersection { export interface PathSegment { type: SegmentType; - point?: Vec2; - geo?: IBoundsRaw & IVertices & IHiccupPathSegment & IToCubic; + point?: Vec; + geo?: IShape & IHiccupPathSegment; +} + +export interface PCLike extends IShape { + points: Vec[]; +} + +export interface PCLikeConstructor { + new(pts: Vec[], attribs: Attribs): PCLike; } export interface SamplingOpts { @@ -71,8 +133,8 @@ export interface SamplingOpts { /** * Currently only used by these types: * - * - Arc2 - * - Circle2 + * - Arc + * - Circle * * Defines the target angle between sampled points. If greater than * the actual range of the arc, only the two end points will be @@ -102,170 +164,540 @@ export interface SamplingOpts { last: boolean; } -export interface SubdivKernel> { - fn: (pts: T[], i: number, nump: number) => T[]; +export interface SubdivKernel { + fn: (pts: ReadonlyVec[], i: number, nump: number) => Vec[]; + iter?: (pts: ReadonlyVec[]) => Iterable; size: number; } -export interface IArea { - /** - * Computes and returns area. For types where orientation is taken - * into account, setting `signed` to false will always return the - * absolute area (default is `true`). - * - * @param unsigned - */ - area(signed?: boolean): number; -} +export abstract class APC implements + PCLike { -export interface IArcLength { - /** - * Returns arc length, or for closed shapes, circumference. - */ - arcLength(): number; -} + points: Vec[]; + attribs: Attribs; -export interface IBoundsRaw { - /** - * @return min / max points - */ - boundsRaw(): [V, V]; -} + constructor(points: Vec[], attribs?: Attribs) { + this.points = points; + this.attribs = attribs; + } -export interface IBounds { - /** - * Bounding shape - */ - bounds(): T; -} + abstract get type(): number | string; + abstract copy(): IShape; -export interface ICentroid { - /** - * Computes & returns centroid. If `c` is given it MUST be a zero - * vector and will be used to store result. - * - * @param c - */ - centroid(c?: T): T; + *[Symbol.iterator]() { + yield* this.points; + } } -export interface ICenter { - center(origin?: Readonly): this; -} +export class AABB implements + AABBLike { -export interface IClassifyPoint { - classifyPoint(p: Readonly): number; -} + pos: Vec; + size: Vec; + attribs: Attribs; -export interface IPointInside { - pointInside(p: Readonly): boolean; -} + constructor(pos: Vec = [0, 0, 0], size: Vec = [1, 1, 1], attribs?: Attribs) { + this.pos = pos; + this.size = size; + this.attribs = attribs; + } -export interface ICollate { - /** - * Collates all points into a single buffer and remaps existing - * vertices (by default). Points will written from given `start` - * index, using layout defined by `cstride` and `estride`. - * - * @param opts - */ - collate(opts?: Partial): Vec; -} + get type() { + return Type.AABB; + } -export interface IEdges { - edges(opts?: any): Iterable; -} + copy() { + return new AABB(set([], this.pos), set([], this.size), { ...this.attribs }); + } -export interface IHiccupPathSegment { - toHiccupPathSegments(): any[]; + max() { + return add3([], this.pos, this.size); + } } -export interface IPointMap { - mapPoint(p: Readonly, out?: B): B; - unmapPoint(p: Readonly, out?: A): A; -} -export interface IToCubic { - toCubic(): Iterable; -} +export class Arc implements + IHiccupShape, + IHiccupPathSegment { -export interface IToPolygon { - // FIXME return type should be interface - toPolygon(opts?: O): any; -} + pos: Vec; + r: Vec; + start: number; + end: number; + axis: number; + xl: boolean; + cw: boolean; + attribs: Attribs; + + constructor( + pos: Vec, + r: Vec, + axis: number, + start: number, + end: number, + xl = false, + cw = false, + attribs?: Attribs) { + + this.pos = pos; + this.r = r; + this.axis = axis; + this.start = start; + this.end = end; + this.xl = xl; + this.cw = cw; + this.attribs = attribs; + } + + get type() { + return Type.ARC; + } + + copy() { + return new Arc( + set([], this.pos), + set([], this.r), + this.axis, + this.start, + this.end, + this.xl, + this.cw, + { ...this.attribs } + ); + } + + equiv(o: any) { + return o instanceof Arc && + equiv(this.pos, o.pos) && + equiv(this.r, o.r) && + this.start === o.start && + this.end === o.end && + this.axis === o.axis && + this.xl === o.xl && + this.cw && o.cw; + } + + pointAt(t: number, out: Vec = []) { + return arcPointAt(this.pos, this.r, this.axis, this.start, this.end, t, out); + } + + pointAtTheta(theta: number, out: Vec = []) { + return arcPointAtTheta(this.pos, this.r, this.axis, theta, out); + } + + toHiccup() { + return ["path", this.attribs, [ + ["M", this.pointAt(0)], + ...this.toHiccupPathSegments() + ]]; + } + + toHiccupPathSegments() { + return [ + [ + "A", + this.r[0], + this.r[1], + this.axis, + this.xl, + this.cw, + this.pointAt(1) + ] + ]; + } +} + +export class Circle implements + IHiccupShape { -export interface ITessellateable> { - tessellate(tessel: Tessellator, iter?: number): T[][]; - tessellate(tessel: Iterable>): T[][]; -} + pos: Vec; + r: number; + attribs: Attribs; -export interface ITransformable { - transform(mat: M): this; -} + constructor(pos: Vec = [0, 0], r = 1, attribs?: Attribs) { + this.pos = pos; + this.r = r; + this.attribs = attribs; + } -export interface IUnion { - union(x: T): T; -} + get type() { + return Type.CIRCLE; + } -export interface IVertices { - vertices(opts?: O): Iterable; + copy() { + return new Circle(set([], this.pos), this.r, { ...this.attribs }); + } + + toHiccup() { + return ["circle", this.attribs, this.pos, this.r]; + } } -export interface JsonShape { - type: string; - attribs?: Attribs; +export class Cubic extends APC implements + IHiccupPathSegment { + + get type() { + return Type.CUBIC; + } + + copy() { + return new Cubic(copyPoints(this.points), { ...this.attribs }); + } + + toHiccup() { + return ["path", this.attribs, + [ + ["M", this.points[0]], + ...this.toHiccupPathSegments() + ] + ]; + } + + toHiccupPathSegments() { + const pts = this.points; + return [["C", pts[1], pts[2], pts[3]]]; + } } -export interface JsonArc2 extends JsonShape { +export class Ellipse implements + IHiccupShape { + pos: Vec; r: Vec; - axis: number; - start: number; - end: number; - xl: boolean; - clockwise: boolean; -} + attribs: Attribs; -export interface JsonCircle2 extends JsonShape { - pos: Vec; - r: number; -} + constructor(pos: Vec = [0, 0], r: number | Vec = [1, 1], attribs?: Attribs) { + this.pos = pos; + this.r = isNumber(r) ? [r, r] : r; + this.attribs = attribs; + } + + get type() { + return Type.ELLIPSE; + } + + copy() { + return new Ellipse(set([], this.pos), set([], this.r), { ...this.attribs }); + } + + toHiccup() { + return ["ellipse", this.attribs, this.pos, this.r]; + } +} + +export class Group implements + IHiccupShape { + + children: IHiccupShape[]; + attribs: Attribs; + + constructor(children: IHiccupShape[], attribs?: Attribs) { + this.children = children; + this.attribs = attribs; + } + + get type() { + return Type.GROUP; + } + + *[Symbol.iterator]() { + yield* this.children; + } + + copy() { + return new Group( + this.children.map((c) => c.copy()), + { ...this.attribs } + ); + } + + equiv(o: any) { + return o instanceof Group && + equiv(this.children, o.children); + } + + toHiccup() { + return ["g", this.attribs, ...this.children.map((x) => x.toHiccup())]; + } +} + +export class Line extends APC implements + IHiccupShape, + IHiccupPathSegment { + + get type() { + return Type.LINE; + } + + copy() { + return new Line(copyPoints(this.points), { ...this.attribs }); + } + + toHiccup() { + return ["line", this.attribs, this.points[0], this.points[1]]; + } + + toHiccupPathSegments() { + const [a, b] = this.points; + return [ + a[0] === b[0] ? + ["V", b[1]] : + a[1] === b[1] ? + ["H", b[0]] : + ["L", b] + ]; + } +} + +export class Path implements + IHiccupShape { + + segments: PathSegment[]; + closed: boolean; + attribs: Attribs; + + constructor(segments?: PathSegment[], attribs?: Attribs) { + this.segments = segments || []; + this.attribs = attribs; + this.closed = false; + } + + get type() { + return Type.PATH; + } + + *[Symbol.iterator]() { + yield* this.segments; + } + + copy() { + const p = new Path([...this.segments], { ...this.attribs }); + p.closed = this.closed; + return p; + } -export interface JsonCubic2 extends JsonShape { - points: Vec[]; -} + equiv(o: any) { + return o instanceof Path && + equiv(this.segments, o.segments); + } + + add(s: PathSegment) { + if (this.closed) illegalState("path already closed"); + this.segments.push(s); + } + + toHiccup() { + let dest: any[] = []; + const segments = this.segments; + const n = segments.length; + if (n > 1) { + dest.push(["M", segments[0].point]); + for (let i = 1; i < n; i++) { + dest = dest.concat(segments[i].geo.toHiccupPathSegments()); + } + if (this.closed) { + dest.push(["Z"]); + } + } + return ["path", this.attribs || {}, dest]; + } +} + +export class Points extends APC implements + IHiccupShape { + + get type() { + return Type.POINTS; + } + + copy() { + return new Points(copyPoints(this.points), { ...this.attribs }); + } + + toHiccup() { + return ["points", this.attribs, this.points]; + } +} + +export class Polygon extends APC implements + IHiccupShape { + + get type() { + return Type.POLYGON; + } + + copy() { + return new Polygon(copyPoints(this.points), { ...this.attribs }); + } + + toHiccup() { + return ["polygon", this.attribs, this.points]; + } +} + +export class Polyline extends APC implements + IHiccupShape, + IHiccupPathSegment { + + get type() { + return Type.POLYLINE; + } + + copy() { + return new Polyline(copyPoints(this.points), { ...this.attribs }); + } -export interface JsonQuadratic2 extends JsonShape { - points: Vec[]; + toHiccup() { + return ["polyline", { ...this.attribs, fill: "none" }, this.points]; + } + + toHiccupPathSegments() { + const res: any[] = []; + for (let pts = this.points, n = pts.length, i = 1; i < n; i++) { + res.push(["L", pts[i]]); + } + return res; + } +} + +export class Quad extends APC implements + IHiccupShape { + + get type() { + return Type.QUAD; + } + + copy() { + return new Quad(copyPoints(this.points), { ...this.attribs }); + } + + toHiccup() { + return ["polygon", this.attribs, this.points]; + } } -export interface JsonPolygon2 extends JsonShape { - points: Vec[]; +export class Quadratic extends APC implements + IHiccupShape, + IHiccupPathSegment { + + get type() { + return Type.QUADRATIC; + } + + copy() { + return new Quadratic(copyPoints(this.points), { ...this.attribs }); + } + + toHiccup() { + return ["path", this.attribs, + [ + ["M", this.points[0]], + ...this.toHiccupPathSegments() + ] + ]; + } + + toHiccupPathSegments() { + const pts = this.points; + return [["Q", pts[1], pts[2]]]; + } } -export interface JsonPolyline2 extends JsonShape { - points: Vec[]; +export class Ray implements + IHiccupShape { + + pos: Vec; + dir: Vec; + attribs: Attribs; + + constructor(pos: Vec, dir: Vec, attribs?: Attribs) { + this.pos = pos; + this.dir = dir; + this.attribs = attribs; + } + + get type() { + return Type.RAY; + } + + copy() { + return new Ray(set([], this.pos), set([], this.dir), { ...this.attribs }); + } + + toHiccup() { + return ["line", this.attribs, this.pos, maddN2([], this.pos, this.dir, 1e6)]; + } } -export interface JsonRect2 extends JsonShape { +export class Rect implements + AABBLike, + IHiccupShape { + pos: Vec; - size: Vec[]; + size: Vec; + attribs: Attribs; + + constructor(pos: Vec = [0, 0], size: number | Vec = [1, 1], attribs?: Attribs) { + this.pos = pos; + this.size = isNumber(size) ? [size, size] : size; + this.attribs = attribs; + } + + get type() { + return Type.RECT; + } + + copy() { + return new Rect(set([], this.pos), set([], this.size), { ...this.attribs }); + } + + max() { + return add2([], this.pos, this.size); + } + + toHiccup() { + return ["rect", this.attribs, this.pos, this.size]; + } } -export type HiccupArc2 = - ["arc", Attribs, ReadonlyVec, ReadonlyVec, number, number, number, boolean, boolean]; +export class Sphere implements + IHiccupShape { -export type HiccupCircle2 = - ["circle", Attribs, ReadonlyVec, number]; + pos: Vec; + r: number; + attribs: Attribs; + + constructor(pos: Vec = [0, 0, 0], r = 1, attribs?: Attribs) { + this.pos = pos; + this.r = r; + this.attribs = attribs; + } + + get type() { + return Type.SPHERE; + } -export type HiccupLine2 = - ["line", Attribs, ReadonlyVec, ReadonlyVec]; + copy() { + return new Sphere(set([], this.pos), this.r, { ...this.attribs }); + } -export type HiccupPolygon2 = - ["polygon", Attribs, number[] | number[][]]; + toHiccup() { + return ["sphere", this.attribs, this.pos, this.r]; + } +} + +export class Triangle extends APC implements + IHiccupShape { -export type HiccupPolyline2 = - ["polyline", Attribs, number[] | number[][]]; + get type() { + return Type.TRIANGLE; + } -export type HiccupRect2 = - ["rect", Attribs, ReadonlyVec, number, number, number?]; + copy() { + return new Triangle(copyPoints(this.points), { ...this.attribs }); + } + + toHiccup() { + return ["polygon", this.attribs, this.points]; + } +} diff --git a/packages/geom/src/arc2.ts b/packages/geom/src/arc2.ts deleted file mode 100644 index 26b9d8e5c1..0000000000 --- a/packages/geom/src/arc2.ts +++ /dev/null @@ -1,305 +0,0 @@ -import { ICopy } from "@thi.ng/api"; -import { isNumber, isPlainObject } from "@thi.ng/checks"; -import { - EPS, - HALF_PI, - inRange, - mix, - PI, - roundEps, - sincos, - TAU -} from "@thi.ng/math"; -import { - filter, - map, - push, - range, - transduce -} from "@thi.ng/transducers"; -import { - add2, - asVec2, - rotate2, - setS2, - Vec, - Vec2 -} from "@thi.ng/vectors"; -import { - Attribs, - DEFAULT_SAMPLES, - HiccupArc2, - IBounds, - IBoundsRaw, - IEdges, - IVertices, - JsonArc2, - SamplingOpts -} from "./api"; -import { Cubic2 } from "./bezier2"; -import { bounds } from "./internal/bounds"; -import { edges } from "./internal/edges"; -import { Rect2 } from "./rect2"; -import { Sampler } from "./sampler"; - -export class Arc2 implements - IBounds, - IBoundsRaw, - ICopy, - IEdges, - IVertices> { - - static fromJSON(spec: JsonArc2) { - return new Arc2( - new Vec2(spec.pos), - new Vec2(spec.r), - spec.axis, - spec.start, - spec.end, - spec.xl, - spec.clockwise, - spec.attribs - ); - } - - static fromHiccup(spec: HiccupArc2) { - return new Arc2( - asVec2(spec[2]), - asVec2(spec[3]), - spec[4], - spec[5], - spec[6], - spec[7], - spec[8], - spec[1] - ); - } - - static from2Points( - a: Readonly, - b: Readonly, - radii: Readonly, - axisTheta = 0, - large = false, - clockwise = true) { - - const r = radii.copy().abs(); - const co = Math.cos(axisTheta); - const si = Math.sin(axisTheta); - const m = a.subNew(b).mulN(0.5); - const px = co * m.x + si * m.y; - const py = -si * m.x + co * m.y; - const px2 = px * px; - const py2 = py * py; - - const l = px2 / (r.x * r.x) + py2 / (r.y * r.y); - l > 1 && r.mulN(Math.sqrt(l)); - - const rx2 = r.x * r.x; - const ry2 = r.y * r.y; - const rxpy = rx2 * py2; - const rypx = ry2 * px2; - const rad = ((large === clockwise) ? -1 : 1) * - Math.sqrt(Math.max(0, rx2 * ry2 - rxpy - rypx) / (rxpy + rypx)); - - const tc = new Vec2([rad * r.x / r.y * py, rad * -r.y / r.x * px]); - const c = new Vec2([co * tc.x - si * tc.y + (a.x + b.x) / 2, si * tc.x + co * tc.y + (a.y + b.y) / 2]); - const d1 = new Vec2([(px - tc.x) / r.x, (py - tc.y) / r.y]); - const d2 = new Vec2([(-px - tc.x) / r.x, (-py - tc.y) / r.y]); - - const theta = Vec2.X_AXIS.angleBetween(d1, true); - let delta = d1.angleBetween(d2, true); - - if (clockwise && delta < 0) { - delta += TAU; - } else if (!clockwise && delta > 0) { - delta -= TAU; - } - - return new Arc2(c, r, axisTheta, theta, theta + delta, large, clockwise); - } - - pos: Vec2; - r: Vec2; - axis: number; - start: number; - end: number; - xl: boolean; - clockwise: boolean; - attribs: Attribs; - - constructor( - pos: Vec2, - r: Vec2, - axis: number, - start: number, - end: number, - xl = false, - clockwise = false, - attribs?: Attribs) { - - this.pos = pos; - this.r = r; - this.axis = axis; - this.start = start; - this.end = end; - this.clockwise = clockwise; - this.xl = xl; - this.attribs = attribs; - } - - copy() { - return new Arc2( - this.pos.copy(), - this.r.copy(), - this.axis, - this.start, - this.end, - this.xl, - this.clockwise, - { ...this.attribs } - ); - } - - boundsRaw() { - // https://stackoverflow.com/a/1336739/294515 - const pts = transduce( - map(this.pointAtTheta.bind(this)), - push(), - [ - this.start, - this.end, - // multiples of HALF_PI in arc range - ...filter( - (t: number) => inRange(t, this.start, this.end), - range(-3 * PI, 3.01 * PI, HALF_PI) - ) - ] - ); - return bounds(pts, Vec2.MAX.copy(), Vec2.MIN.copy()); - } - - bounds() { - return Rect2.fromMinMax(...this.boundsRaw()); - } - - edges(opts?: number | Partial) { - return edges(this.vertices(opts)); - } - - pointAt(t: number) { - return this.pointAtTheta(mix(this.start, this.end, t)); - } - - pointAtTheta(theta: number, pos?: Vec2) { - return (pos || new Vec2()) - .setS(Math.cos(theta), Math.sin(theta)) - .mul(this.r) - .rotate(this.axis) - .add(this.pos); - } - - vertices(opts?: number | Partial): Vec2[] { - if (isPlainObject(opts) && (opts).dist !== undefined) { - return new Sampler(this.vertices((opts).num || DEFAULT_SAMPLES)) - .sampleUniform((opts).dist, (opts).last !== false); - } - opts = isNumber(opts) ? - { num: opts, last: true } : - { num: DEFAULT_SAMPLES, ...opts }; - let num: number; - const start = this.start; - let delta = this.end - start; - num = opts.theta ? - Math.round(delta / opts.theta) : - opts.num; - delta /= num; - opts.last !== false && num++; - const pts: Vec = new Array(num * 2); - const pos = this.pos; - const [rx, ry] = this.r; - const axis = this.axis; - for (let i = 0, j = 0; i < num; i++ , j += 2) { - const t = start + i * delta; - setS2(pts, Math.cos(t) * rx, Math.sin(t) * ry, j); - rotate2(pts, axis, j); - add2(pts, pos.buf, j, pos.i, 1, pos.s); - } - return Vec2.mapBuffer(pts, num); - } - - toCubic() { - const p = this.pointAtTheta(this.start); - const q = this.pointAtTheta(this.end); - const [rx, ry] = this.r; - const [sphi, cphi] = sincos(this.axis); - const dx = cphi * (p.x - q.x) / 2 + sphi * (p.y - q.y) / 2; - const dy = -sphi * (p.x - q.x) / 2 + cphi * (p.y - q.y) / 2; - if ((dx === 0 && dy === 0) || this.r.magSq() < EPS) { - return [Cubic2.fromLine(p, q, { ...this.attribs })]; - } - - const mapP = (x, y) => { - x *= rx; - y *= ry; - return new Vec2([ - cphi * x - sphi * y, - sphi * x + cphi * y - ]).add(this.pos); - }; - - const res: Cubic2[] = []; - const delta = this.end - this.start; - const n = Math.max(roundEps(Math.abs(delta) / HALF_PI), 1); - // https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/svg/svg_path_parser.cc#L253 - const d = delta / n; - const t = 8 / 6 * Math.tan(0.25 * d); - if (!isFinite(t)) { - return [Cubic2.fromLine(p, q)]; - } - for (let i = n, theta = this.start; i > 0; i-- , theta += d) { - const [s1, c1] = sincos(theta); - const [s2, c2] = sincos(theta + d); - const curve = new Cubic2([ - mapP(c1, s1), - mapP(c1 - s1 * t, s1 + c1 * t), - mapP(c2 + s2 * t, s2 - c2 * t), - mapP(c2, s2), - ]); - res.push(curve); - } - return res; - } - - toHiccup() { - return ["path", this.attribs, [ - ["M", this.pointAtTheta(this.start)], - ...this.toHiccupPathSegments() - ]]; - } - - toHiccupPathSegments() { - return [["A", - this.r.x, - this.r.y, - this.axis, - this.xl, - this.clockwise, - this.pointAtTheta(this.end) - ]]; - } - - toJSON(): JsonArc2 { - return { - type: "arc2", - pos: this.pos.toJSON(), - r: this.r.toJSON(), - start: this.start, - end: this.end, - axis: this.axis, - xl: this.xl, - clockwise: this.clockwise, - attribs: this.attribs, - }; - } -} diff --git a/packages/geom/src/bezier2.ts b/packages/geom/src/bezier2.ts deleted file mode 100644 index 5e8e8f78fa..0000000000 --- a/packages/geom/src/bezier2.ts +++ /dev/null @@ -1,317 +0,0 @@ -import { ICopy } from "@thi.ng/api"; -import { isNumber, isPlainObject } from "@thi.ng/checks"; -import { clamp01, mixCubic as _mixC, mixQuadratic as _mixQ } from "@thi.ng/math"; -import { - IMath, - ReadonlyVec, - Vec, - Vec2 -} from "@thi.ng/vectors"; -import { - Attribs, - DEFAULT_SAMPLES, - IToCubic, - IVertices, - JsonCubic2, - JsonQuadratic2, - SamplingOpts -} from "./api"; -import { PointContainer2 } from "./container2"; -import { args3, args4 } from "./internal/args"; -import { Sampler } from "./sampler"; - -export const mixQuadratic = & IMath>(a: T, b: T, c: T, t: number) => { - const s = 1 - t; - return a.mulNewN(s * s) - .maddN(b, 2 * s * t) - .maddN(c, t * t); -}; - -export const mixCubic = & IMath>(a: T, b: T, c: T, d: T, t: number) => { - const t2 = t * t; - const s = 1 - t; - const s2 = s * s; - return a.mulNewN(s2 * s) - .maddN(b, 3 * s2 * t) - .maddN(c, 3 * t2 * s) - .maddN(d, t2 * t); -}; - -const cubicAxisBounds = (pa: number, pb: number, pc: number, pd: number) => { - let a = 3 * pd - 9 * pc + 9 * pb - 3 * pa; - let b = 6 * pa - 12 * pb + 6 * pc; - let c = 3 * pb - 3 * pa; - let disc = b * b - 4 * a * c; - let l = pa; - let h = pa; - - const bounds = (t: number) => { - if (t > 0 && t < 1) { - const x = _mixC(pa, pb, pc, pd, t); - x < l && (l = x); - x > h && (h = x); - } - }; - - pd < l && (l = pd); - pd > h && (h = pd); - if (disc >= 0) { - disc = Math.sqrt(disc); - a *= 2; - bounds((-b + disc) / a); - bounds((-b - disc) / a); - } - return [l, h]; -}; - -export class Cubic2 extends PointContainer2 implements - IToCubic, - IVertices> { - - static fromJSON(spec: JsonCubic2) { - return cubic2(spec.points, spec.attribs); - } - - static fromLine(a: Vec2, b: Vec2, attribs?: Attribs) { - return new Cubic2([a, a.mixNewN(b, 1 / 3), b.mixNewN(a, 1 / 3), b], attribs); - } - - copy() { - return new Cubic2(this._copy(), this.attribs); - } - - boundsRaw(): [Vec2, Vec2] { - // https://stackoverflow.com/a/24814530/294515 - // https://iquilezles.org/www/articles/bezierbbox/bezierbbox.htm - const [a, b, c, d] = this.points; - const x = cubicAxisBounds(a.x, b.x, c.x, d.x); - const y = cubicAxisBounds(a.y, b.y, c.y, d.y); - return Vec2.mapBuffer([x[0], y[0], x[1], y[1]], 2); - } - - pointAt(t: number) { - const pts = this.points; - return mixCubic(pts[0], pts[1], pts[2], pts[3], t); - } - - /** - * Splits curve into 2 sub-curves at position `t`. - * - * http://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm - * - * @param t - */ - splitAt(t: number): [Cubic2, Cubic2] { - const [a, b, c, d] = this.points; - if (t <= 0 || t >= 1) { - const p = t <= 0 ? a : d; - const c1 = new Cubic2(Vec2.mapBuffer([p.x, p.y, p.x, p.y, p.x, p.y], 4)); - const c2 = new Cubic2(Vec2.mapBuffer([a.x, a.y, b.x, b.y, c.x, c.y, d.x, d.y], 4)); - return t <= 0 ? [c1, c2] : [c2, c1]; - } - const ab = a.mixNewN(b, t); - const bc = b.mixNewN(c, t); - const cd = c.mixNewN(d, t); - const abc = ab.mixNewN(bc, t); - const bcd = bc.mixNewN(cd, t); - const p = abc.mixNewN(bcd, t); - return [ - new Cubic2(Vec2.mapBuffer([a.x, a.y, ab.x, ab.y, abc.x, abc.y, p.x, p.y], 4)), - new Cubic2(Vec2.mapBuffer([p.x, p.y, bcd.x, bcd.y, cd.x, cd.y, d.x, d.y], 4)) - ]; - } - - vertices(opts?: Partial) { - if (isPlainObject(opts) && (opts).dist !== undefined) { - return new Sampler(this.vertices((opts).num || DEFAULT_SAMPLES)) - .sampleUniform((opts).dist, (opts).last !== false); - } - opts = isNumber(opts) ? - { - num: opts, - last: true - } : - { - num: DEFAULT_SAMPLES, - ...opts - }; - const res: number[] = []; - const [a, b, c, d] = this.points; - const delta = 1 / opts.num; - for (let t = 0; t < opts.num; t++) { - res.push( - _mixC(a.x, b.x, c.x, d.x, t * delta), - _mixC(a.y, b.y, c.y, d.y, t * delta) - ); - } - opts.last && res.push(d.x, d.y); - return Vec2.mapBuffer(res); - } - - toCubic() { - return [this]; - } - - toHiccup() { - return ["path", this.attribs, - [ - ["M", this.points[0]], - ...this.toHiccupPathSegments() - ] - ]; - } - - toHiccupPathSegments() { - const pts = this.points; - return [["C", pts[1], pts[2], pts[3]]]; - } - - toJSON() { - return this._toJSON("cubic2"); - } -} - -export class Quadratic2 extends PointContainer2 implements - IToCubic, - IVertices> { - - static fromJSON(spec: JsonQuadratic2) { - return quadratic2(spec.points, spec.attribs); - } - - static fromLine(a: Vec2, b: Vec2, attribs?: Attribs) { - return new Quadratic2([a, a.mixNewN(b), b], attribs); - } - - copy() { - return new Quadratic2(this._copy(), this.attribs); - } - - boundsRaw(): [Vec2, Vec2] { - const [a, b, c] = this.points; - const mi = a.copy().min(c); - const ma = a.copy().max(c); - const solve = (a, b, c) => { - const t = clamp01((a - b) / (a - 2.0 * b + c)); - const s = 1 - t; - return s * s * a + 2.0 * s * t * b + t * t * c; - }; - if (b.x < mi.x || b.x > ma.x || b.y < mi.y || b.y > ma.y) { - const q = new Vec2([ - solve(a.x, b.x, c.x), - solve(a.y, b.y, c.y), - ]); - mi.min(q); - ma.max(q); - } - return [mi, ma]; - } - - pointAt(t: number) { - const pts = this.points; - return mixQuadratic(pts[0], pts[1], pts[2], t); - } - - /** - * Splits curve into 2 sub-curves at position `t`. - * - * http://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm - * - * @param t - */ - splitAt(t: number): [Quadratic2, Quadratic2] { - const [a, b, c] = this.points; - if (t == 0) { - return [ - new Quadratic2(this._copy([a, a, a])), - new Quadratic2(this._copy([a, b, c])) - ]; - } - if (t == 1) { - return [ - new Quadratic2(this._copy([a, b, c])), - new Quadratic2(this._copy([c, c, c])) - ]; - } - const ab = a.mixNewN(b, t); - const bc = b.mixNewN(c, t); - const p = ab.mixNewN(bc, t); - return [ - new Quadratic2([a.copy(), ab, p]), - new Quadratic2([p, bc, c.copy()]) - ]; - } - - vertices(opts?: number | Partial) { - if (isPlainObject(opts) && (opts).dist !== undefined) { - return new Sampler(this.vertices((opts).num || DEFAULT_SAMPLES)) - .sampleUniform((opts).dist, (opts).last !== false); - } - opts = isNumber(opts) ? - { - num: opts, - last: true - } : - { - num: DEFAULT_SAMPLES, - ...opts - }; - const res: number[] = []; - const delta = 1 / opts.num; - const [a, b, c] = this.points; - for (let t = 0; t < opts.num; t++) { - res.push( - _mixQ(a.x, b.x, c.x, t * delta), - _mixQ(a.y, b.y, c.y, t * delta) - ); - } - opts.last && res.push(c.x, c.y); - return Vec2.mapBuffer(res); - } - - toCubic() { - const [a, b, c] = this.points; - return [ - new Cubic2([ - a.copy(), - a.mulNewN(1 / 3).maddN(b, 2 / 3), - c.mulNewN(1 / 3).maddN(b, 2 / 3), - c.copy() - ]) - ]; - } - - toHiccup() { - return ["path", this.attribs, - [ - ["M", this.points[0]], - ...this.toHiccupPathSegments() - ] - ]; - } - - toHiccupPathSegments() { - const pts = this.points; - return [["Q", pts[1], pts[2]]]; - } - - toJSON() { - return this._toJSON("quadratic2"); - } -} - -export function cubic2(points: Vec, start?: number, cstride?: number, estride?: number, attribs?: Attribs): Cubic2; -export function cubic2(a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, attribs?: Attribs): Cubic2; -export function cubic2(points: ReadonlyVec[], attribs?: Attribs): Cubic2; -export function cubic2(...args: any[]) { - const [points, attribs] = args4(args); - return new Cubic2(points, attribs); -} - -export function quadratic2(points: Vec, start?: number, cstride?: number, estride?: number, attribs?: Attribs): Quadratic2; -export function quadratic2(a: Vec2 | ReadonlyVec, b: Vec2 | ReadonlyVec, c: Vec2 | ReadonlyVec, attribs?: Attribs): Quadratic2; -export function quadratic2(points: ReadonlyVec[], attribs?: Attribs): Quadratic2; -export function quadratic2(...args: any[]) { - const [points, attribs] = args3(args); - return new Quadratic2(points, attribs); -} diff --git a/packages/geom/src/circle2.ts b/packages/geom/src/circle2.ts deleted file mode 100644 index 1f49dde94f..0000000000 --- a/packages/geom/src/circle2.ts +++ /dev/null @@ -1,191 +0,0 @@ -import { IToHiccup } from "@thi.ng/api"; -import { isArrayLike, isNumber, isPlainObject } from "@thi.ng/checks"; -import { eqDelta, PI, TAU } from "@thi.ng/math"; -import { - asVec2, - ReadonlyVec, - setS2, - toCartesian2, - Vec, - Vec2 -} from "@thi.ng/vectors"; -import { - Attribs, - DEFAULT_SAMPLES, - HiccupCircle2, - IArcLength, - IBounds, - IBoundsRaw, - ICentroid, - IClassifyPoint, - IPointInside, - IToPolygon, - IVertices, - JsonCircle2, - SamplingOpts -} from "./api"; -import { circumCenter } from "./internal/circumcenter"; -import { edges } from "./internal/edges"; -import { Polygon2 } from "./polygon2"; -import { Rect2 } from "./rect2"; - -export class Circle2 implements - IArcLength, - IBoundsRaw, - IBounds, - ICentroid, - IClassifyPoint, - IPointInside, - IToHiccup, - IToPolygon>, - IVertices> { - - static fromJSON(spec: JsonCircle2) { - return new Circle2( - new Vec2(spec.pos), - spec.r, - spec.attribs - ); - } - - static fromHiccup(spec: HiccupCircle2) { - return new Circle2(asVec2(spec[2]), spec[3], spec[1]); - } - - static from2Points(a: Readonly, b: Readonly, attribs?: Attribs) { - return new Circle2(a.mixNewN(b), a.dist(b) / 2, attribs); - } - static from3Points(a: Readonly, b: Readonly, c: Readonly, attribs?: Attribs) { - const o = circumCenter(a, b, c); - if (o) { - return new Circle2(o, a.dist(o), attribs); - } - } - - pos: Vec2; - r: number; - attribs: Attribs; - - constructor(pos: Vec2, r = 1, attribs?: Attribs) { - this.pos = pos; - this.r = r; - this.attribs = attribs; - } - - copy() { - return new Circle2(this.pos.copy(), this.r, { ...this.attribs }); - } - - edges(opts?: Partial) { - return edges(this.vertices(opts)); - } - - vertices(opts?: number | Partial) { - let [num, last] = isNumber(opts) ? - [opts, false] : - [ - opts.theta ? - Math.floor(TAU / opts.theta) : - opts.dist ? - Math.floor(TAU / (opts.dist / this.r)) : - opts.num || DEFAULT_SAMPLES, - opts.last === true - ]; - const buf: Vec = []; - const pos = this.pos.buf; - const po = this.pos.i; - const ps = this.pos.s; - const r = this.r; - const delta = TAU / num; - last && num++; - for (let i = 0; i < num; i++) { - toCartesian2( - setS2(buf, r, i * delta, i * 2), - pos, i * 2, po, 1, ps - ); - } - return Vec2.mapBuffer(buf, num); - } - - area() { - return PI * this.r * this.r; - } - - arcLength() { - return TAU * this.r; - } - - boundsRaw(): [Vec2, Vec2] { - return [ - this.pos.subNewN(this.r), - this.pos.addNewN(this.r) - ]; - } - - bounds(): Rect2 { - return new Rect2( - this.pos.subNewN(this.r), - new Vec2([this.r, this.r]) - ); - } - - centroid(c?: Vec2) { - return c ? c.set(this.pos) : this.pos; - } - - classifyPoint(p: Readonly) { - const d = p.distSq(this.pos); - const r = this.r * this.r; - return eqDelta(d, r) ? 0 : d < r ? 1 : -1; - } - - pointInside(p: Readonly) { - return this.classifyPoint(p) >= 0; - } - - toPolygon(opts?: number | Partial) { - return new Polygon2(this.vertices(opts)); - } - - toHiccup(): HiccupCircle2 { - return ["circle", this.attribs || {}, this.pos, this.r]; - } - - toJSON() { - return { - type: "circle2", - pos: this.pos.toJSON(), - r: this.r, - attribs: this.attribs, - }; - } -} - -export function circle2(r: number, attribs?: Attribs): Circle2; -export function circle2(x: number, y: number, attribs?: Attribs): Circle2; -export function circle2(x: number, y: number, r: number, attribs?: Attribs): Circle2; -export function circle2(pos: ReadonlyVec, attribs?: Attribs): Circle2; -export function circle2(pos: ReadonlyVec, r: number, attribs?: Attribs): Circle2; -export function circle2(...args: any[]) { - let attribs; - let n = args.length - 1; - if (isPlainObject(args[n]) || args[n] == null) { - attribs = args[n]; - n--; - } - if (isArrayLike(args[0])) { - return new Circle2( - asVec2(args[0]), - n === 1 ? args[n] : 1, - attribs - ); - } - if (n > 0) { - return new Circle2( - new Vec2([args[0], args[1]]), - n === 2 ? args[n] : 1, - attribs - ); - } - return new Circle2(new Vec2(), args[0], attribs); -} diff --git a/packages/geom/src/container2.ts b/packages/geom/src/container2.ts deleted file mode 100644 index f4660564d3..0000000000 --- a/packages/geom/src/container2.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { Mat23, Vec2 } from "@thi.ng/vectors"; -import { - Attribs, - CollateOpts, - IBounds, - IBoundsRaw, - ICenter, - ICentroid, - ICollate, - IVertices -} from "./api"; -import { fitIntoBounds2 } from "./fit"; -import { bounds } from "./internal/bounds"; -import { centroid } from "./internal/centroid"; -import { collateWith } from "./internal/collate"; -import { convexHull } from "./internal/graham-scan"; -import { Rect2 } from "./rect2"; - -export class PointContainer2 implements - IBoundsRaw, - IBounds, - ICentroid, - ICenter, - ICollate, - IVertices { - - points: Vec2[]; - attribs: Attribs; - - constructor(pts: Vec2[], attribs?: Attribs) { - this.points = pts; - this.attribs = attribs; - } - - *[Symbol.iterator]() { - yield* this.vertices(); - } - - collate(opts?: Partial) { - return collateWith(Vec2.intoBuffer, this.points, opts, 2); - } - - vertices() { - return this.points; - } - - boundsRaw() { - return bounds(this.points, Vec2.MAX.copy(), Vec2.MIN.copy()); - } - - bounds(): Rect2 { - return Rect2.fromMinMax(...this.boundsRaw()); - } - - convextHull() { - return convexHull(this.points); - } - - centroid(c?: Vec2) { - return centroid(this.points, c || new Vec2()); - } - - center(origin?: Readonly) { - const d = this.centroid().neg(); - return this.translate(origin ? d.add(origin) : d); - } - - flip() { - this.points.reverse(); - return this; - } - - fit(bounds: Rect2) { - fitIntoBounds2(this, bounds); - return this; - } - - rotate(theta: number) { - const pts = this.points; - for (let i = pts.length; --i >= 0;) { - pts[i].rotate(theta); - } - return this; - } - - scale(v: Readonly) { - const pts = this.points; - for (let i = pts.length; --i >= 0;) { - pts[i].mul(v); - } - return this; - } - - scaleN(n: number) { - const pts = this.points; - for (let i = pts.length; --i >= 0;) { - pts[i].mulN(n); - } - return this; - } - - translate(v: Readonly) { - const pts = this.points; - for (let i = pts.length; --i >= 0;) { - pts[i].add(v); - } - return this; - } - - transform(mat: Readonly) { - const pts = this.points; - for (let i = pts.length; --i >= 0;) { - mat.mulV(pts[i]); - } - return this; - } - - protected _copy(pts = this.points) { - return Vec2.mapBuffer(Vec2.intoBuffer([], pts), pts.length); - } - - protected _toJSON(type: string) { - return { - type, - attribs: this.attribs, - points: this.points.map((p) => p.toJSON()) - }; - } - - protected _toHiccup(type: string) { - return [type, this.attribs, this.points]; - } -} diff --git a/packages/geom/src/container3.ts b/packages/geom/src/container3.ts deleted file mode 100644 index 81cbd867f9..0000000000 --- a/packages/geom/src/container3.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { illegalArgs } from "@thi.ng/errors"; -import { Mat44, Vec3, vec3 } from "@thi.ng/vectors"; -import { - Attribs, - CollateOpts, - IBounds, - IBoundsRaw, - ICenter, - ICentroid, - ICollate, - IVertices -} from "./api"; -import { bounds } from "./internal/bounds"; -import { collateWith } from "./internal/collate"; - -export class PointContainer3 implements - IBoundsRaw, - IBounds, // TODO - ICentroid, - ICenter, - ICollate, - IVertices { - - points: Vec3[]; - attribs: Attribs; - - constructor(pts: Vec3[], attribs?: Attribs) { - this.points = pts; - this.attribs = attribs; - } - - *[Symbol.iterator]() { - yield* this.vertices(); - } - - collate(opts?: Partial) { - return collateWith(Vec3.intoBuffer, this.points, opts, 3); - } - - vertices() { - return this.points; - } - - boundsRaw() { - return bounds(this.points, Vec3.MAX.copy(), Vec3.MIN.copy()); - } - - bounds() { - return this.boundsRaw(); - } - - centroid(c?: Vec3): Vec3 { - const pts = this.points; - const num = pts.length; - !num && illegalArgs("no points available"); - !c && (c = vec3()); - for (let i = num; --i >= 0;) { - c.add(pts[i]); - } - return c.divN(num); - } - - center(p?: Readonly) { - const d = this.centroid().neg(); - return this.translate(p ? d.add(p) : d); - } - - flip() { - this.points.reverse(); - return this; - } - - scale(v: Readonly) { - const pts = this.points; - for (let i = pts.length; --i >= 0;) { - pts[i].mul(v); - } - return this; - } - - translate(v: Readonly) { - const pts = this.points; - for (let i = pts.length; --i >= 0;) { - pts[i].add(v); - } - return this; - } - - transform(mat: Readonly) { - const pts = this.points; - for (let i = pts.length; --i >= 0;) { - mat.mulV3(pts[i]); - } - return this; - } - - protected _copy() { - return Vec3.mapBuffer(Vec3.intoBuffer([], this.points), this.points.length); - } - - protected _toJSON(type: string) { - return { - type, - attribs: this.attribs, - points: this.points.map((p) => p.toJSON()) - }; - } -} diff --git a/packages/geom3/src/ctors/arc.ts b/packages/geom/src/ctors/arc.ts similarity index 100% rename from packages/geom3/src/ctors/arc.ts rename to packages/geom/src/ctors/arc.ts diff --git a/packages/geom3/src/ctors/circle.ts b/packages/geom/src/ctors/circle.ts similarity index 100% rename from packages/geom3/src/ctors/circle.ts rename to packages/geom/src/ctors/circle.ts diff --git a/packages/geom3/src/ctors/cubic.ts b/packages/geom/src/ctors/cubic.ts similarity index 100% rename from packages/geom3/src/ctors/cubic.ts rename to packages/geom/src/ctors/cubic.ts diff --git a/packages/geom3/src/ctors/ellipse.ts b/packages/geom/src/ctors/ellipse.ts similarity index 100% rename from packages/geom3/src/ctors/ellipse.ts rename to packages/geom/src/ctors/ellipse.ts diff --git a/packages/geom3/src/ctors/group.ts b/packages/geom/src/ctors/group.ts similarity index 100% rename from packages/geom3/src/ctors/group.ts rename to packages/geom/src/ctors/group.ts diff --git a/packages/geom3/src/ctors/line.ts b/packages/geom/src/ctors/line.ts similarity index 100% rename from packages/geom3/src/ctors/line.ts rename to packages/geom/src/ctors/line.ts diff --git a/packages/geom3/src/ctors/path.ts b/packages/geom/src/ctors/path.ts similarity index 100% rename from packages/geom3/src/ctors/path.ts rename to packages/geom/src/ctors/path.ts diff --git a/packages/geom3/src/ctors/points.ts b/packages/geom/src/ctors/points.ts similarity index 100% rename from packages/geom3/src/ctors/points.ts rename to packages/geom/src/ctors/points.ts diff --git a/packages/geom3/src/ctors/polygon.ts b/packages/geom/src/ctors/polygon.ts similarity index 100% rename from packages/geom3/src/ctors/polygon.ts rename to packages/geom/src/ctors/polygon.ts diff --git a/packages/geom3/src/ctors/polyline.ts b/packages/geom/src/ctors/polyline.ts similarity index 100% rename from packages/geom3/src/ctors/polyline.ts rename to packages/geom/src/ctors/polyline.ts diff --git a/packages/geom3/src/ctors/quad.ts b/packages/geom/src/ctors/quad.ts similarity index 100% rename from packages/geom3/src/ctors/quad.ts rename to packages/geom/src/ctors/quad.ts diff --git a/packages/geom3/src/ctors/quadratic.ts b/packages/geom/src/ctors/quadratic.ts similarity index 100% rename from packages/geom3/src/ctors/quadratic.ts rename to packages/geom/src/ctors/quadratic.ts diff --git a/packages/geom3/src/ctors/ray.ts b/packages/geom/src/ctors/ray.ts similarity index 100% rename from packages/geom3/src/ctors/ray.ts rename to packages/geom/src/ctors/ray.ts diff --git a/packages/geom3/src/ctors/rect.ts b/packages/geom/src/ctors/rect.ts similarity index 100% rename from packages/geom3/src/ctors/rect.ts rename to packages/geom/src/ctors/rect.ts diff --git a/packages/geom3/src/ctors/triangle.ts b/packages/geom/src/ctors/triangle.ts similarity index 100% rename from packages/geom3/src/ctors/triangle.ts rename to packages/geom/src/ctors/triangle.ts diff --git a/packages/geom/src/fit.ts b/packages/geom/src/fit.ts deleted file mode 100644 index 8d43994e33..0000000000 --- a/packages/geom/src/fit.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Mat23, Vec2 } from "@thi.ng/vectors"; -import { IBounds, ICentroid, ITransformable } from "./api"; -import { collBounds } from "./internal/bounds"; -import { Rect2 } from "./rect2"; - -const translateScale = (shape: ITransformable, c1: Vec2, c2: Vec2, smat: Mat23) => - shape.transform( - Mat23.concat( - Mat23.translation(c1), - smat, - Mat23.translation(c2) - ) - ); - -export const fitIntoBounds2 = & ITransformable>(shape: T, bounds: Rect2) => { - const obounds = shape.bounds(); - const tscale = bounds.size.copy().divNew(obounds.size); - const scale = Math.min(tscale.x, tscale.y); - return translateScale( - shape, - bounds.centroid(), - obounds.centroid().neg(), - Mat23.scale(scale) - ); -} - -export const fitAllIntoBounds2 = & ICentroid & ITransformable>(shapes: T[], dest: Rect2) => { - const src: Rect2 = collBounds(shapes); - const w = dest.size.x / src.size.x; - const h = dest.size.y / src.size.y; - const s = w > 0 && h > 0 ? Math.min(w, h) : w > 0 ? w : h; - const b = src.copy().scaleN(s).center(dest.centroid()); - const smat = Mat23.scale(s); - for (let i = shapes.length; --i >= 0;) { - const s = shapes[i]; - const c1 = s.centroid(); - const c2 = b.unmapPoint(src.mapPoint(c1)); - translateScale(s, c2, c1.neg(), smat); - } - return shapes; -}; diff --git a/packages/geom/src/index.ts b/packages/geom/src/index.ts index 98b9fc69da..bd89097857 100644 --- a/packages/geom/src/index.ts +++ b/packages/geom/src/index.ts @@ -1,19 +1,85 @@ export * from "./api"; -export * from "./arc2"; -export * from "./bezier2"; -export * from "./circle2"; -export * from "./container2"; -export * from "./container3"; -export * from "./line2"; -export * from "./path2"; -export * from "./polygon2"; -export * from "./polyline2"; -export * from "./quad2"; -export * from "./rect2"; -export * from "./sampler"; -export * from "./triangle2"; -export * from "./fit"; -export * from "./subdiv-curve"; -export * from "./tessellate"; -export * from "./warp"; +export * from "./ctors/arc"; +export * from "./ctors/circle"; +export * from "./ctors/cubic"; +export * from "./ctors/ellipse"; +export * from "./ctors/group"; +export * from "./ctors/line"; +export * from "./ctors/path"; +export * from "./ctors/points"; +export * from "./ctors/polygon"; +export * from "./ctors/polyline"; +export * from "./ctors/quad"; +export * from "./ctors/quadratic"; +export * from "./ctors/ray"; +export * from "./ctors/rect"; +export * from "./ctors/triangle"; + +export * from "./ops/arc-length"; +export * from "./ops/area"; +export * from "./ops/as-cubic"; +export * from "./ops/as-polygon"; +export * from "./ops/as-svg"; +export * from "./ops/bounds"; +export * from "./ops/center"; +export * from "./ops/centroid"; +export * from "./ops/classify-point"; +export * from "./ops/clip-convex"; +export * from "./ops/closest-point"; +export * from "./ops/convex-hull"; +export * from "./ops/edges"; +export * from "./ops/fit-into-bounds"; +export * from "./ops/flip"; +export * from "./ops/intersects"; +export * from "./ops/map-point"; +export * from "./ops/point-at"; +export * from "./ops/point-inside"; +export * from "./ops/resample"; +export * from "./ops/scatter"; +export * from "./ops/simplify"; +export * from "./ops/split-at"; +export * from "./ops/split-near"; +export * from "./ops/subdiv-curve"; +export * from "./ops/tangent-at"; +export * from "./ops/tessellate"; +export * from "./ops/transform"; +export * from "./ops/translate"; +export * from "./ops/union"; +export * from "./ops/unmap-point"; +export * from "./ops/vertices"; +export * from "./ops/warp-points"; +export * from "./ops/with-attribs"; + +export * from "./internal/arc-point"; +export * from "./internal/bounds"; +export * from "./internal/centroid"; +export * from "./internal/circumcenter"; +export * from "./internal/clockwise"; +export * from "./internal/closest-point"; +export * from "./internal/copy-points"; +export * from "./internal/corner"; +export * from "./internal/douglas–peucker"; +export * from "./internal/edges"; +export * from "./internal/graham-scan"; +export * from "./internal/liang-barsky"; +export * from "./internal/poly-arc-length"; +export * from "./internal/poly-area"; +export * from "./internal/poly-centroid"; +export * from "./internal/poly-point-inside"; +export * from "./internal/sampler"; +export * from "./internal/split"; +export * from "./internal/subdiv-curve"; +export * from "./internal/sutherland-hodgeman"; +export * from "./internal/tessellate"; +export * from "./internal/transform-points"; +export * from "./internal/triangle-point-inside"; +export * from "./internal/union-bounds"; + +export * from "./isec/circle-circle"; +export * from "./isec/line-line"; +export * from "./isec/ray-circle"; +export * from "./isec/ray-line"; +export * from "./isec/ray-poly"; +export * from "./isec/rect-circle"; +export * from "./isec/rect-rect"; diff --git a/packages/geom/src/internal/arc-length.ts b/packages/geom/src/internal/arc-length.ts deleted file mode 100644 index 1d539f0af5..0000000000 --- a/packages/geom/src/internal/arc-length.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { IVector } from "@thi.ng/vectors"; - -export const arcLength = >(pts: ReadonlyArray, closed = false) => { - const num = pts.length; - if (num < 2) return 0; - let res = 0; - let p = pts[0]; - let q = pts[1]; - for (let i = 1; i < num; i++ , p = q, q = pts[i]) { - res += p.dist(q); - } - closed && (res += p.dist(pts[0])); - return res; -}; diff --git a/packages/geom3/src/internal/arc-point.ts b/packages/geom/src/internal/arc-point.ts similarity index 100% rename from packages/geom3/src/internal/arc-point.ts rename to packages/geom/src/internal/arc-point.ts diff --git a/packages/geom/src/internal/area.ts b/packages/geom/src/internal/area.ts deleted file mode 100644 index 95197e5eed..0000000000 --- a/packages/geom/src/internal/area.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Vec2 } from "@thi.ng/vectors"; - -export const polygonArea = (pts: ReadonlyArray) => { - let res = 0; - for (let n = pts.length - 1, i = n, j = 0; n >= 0; i = j, j++ , n--) { - res += pts[i].cross(pts[j]); - } - return res / 2; -}; diff --git a/packages/geom/src/internal/args.ts b/packages/geom/src/internal/args.ts index 150bdcc193..7bf1bba99f 100644 --- a/packages/geom/src/internal/args.ts +++ b/packages/geom/src/internal/args.ts @@ -1,74 +1,49 @@ -import { isArrayLike, isNumber } from "@thi.ng/checks"; -import { illegalArgs } from "@thi.ng/errors"; -import { asVec2, ReadonlyVec, Vec2 } from "@thi.ng/vectors"; +import { isNumber, isPlainObject } from "@thi.ng/checks"; +import { peek } from "@thi.ng/transducers"; -export const args3 = (args: any[]) => { - let points = args[0], attribs; - if (isArrayLike(points[0])) { - points = (points).map(asVec2); - attribs = args[1]; - } else if (args.length >= 3 && - isArrayLike(points) && - isArrayLike(args[1]) && - isArrayLike(args[2])) { - points = [asVec2(points), asVec2(args[1]), asVec2(args[2])]; - attribs = args[3]; - } else if (isNumber(points[0])) { - points = Vec2.mapBuffer( - points, - 3, - args[1] || 0, - args[2] || 1, - args[3] || 2 - ); - attribs = args[4]; - } else { - illegalArgs(); - } - return [points, attribs]; -}; +/** + * Takes an array of arguments, checks if last element is a plain object + * and if so, removes it from array and returns it. Else returns + * `undefined`. + * + * @param args + */ +export const argAttribs = + (args: any[]) => + isPlainObject(peek(args)) ? + args.pop() : + undefined; -export const args4 = (args: any[]) => { - let points = args[0], attribs; - if (isArrayLike(points[0])) { - points = (points).map(asVec2); - attribs = args[1]; - } else if (args.length >= 4 && - isArrayLike(points) && - isArrayLike(args[1]) && - isArrayLike(args[2]) && - isArrayLike(args[3])) { - points = [asVec2(points), asVec2(args[1]), asVec2(args[2]), asVec2(args[3])]; - attribs = args[4]; - } else if (isNumber(points[0])) { - points = Vec2.mapBuffer( - points, - 4, - args[1] || 0, - args[2] || 1, - args[3] || 2 - ); - attribs = args[4]; - } else { - illegalArgs(); - } - return [points, attribs]; -}; +/** + * Args parser for functions expecting up to 2 vector args and optional + * attribs object. Returns 3-tuple of re-structured args. + * + * @param args + */ +export const argsVV = + (args: any[]) => { + const attr = argAttribs(args); + return args.length ? + args.length === 2 ? + [args[0], args[1], attr] : + [undefined, args[0], attr] : + [undefined, undefined, attr]; + }; -export const argsN = (args: any[]) => { - let points = args[0], attribs; - if (isNumber(points[0])) { - points = Vec2.mapBuffer( - points, - args[1] || points.length / 2, - args[2] || 0, - args[3] || 1, - args[4] || 2 - ); - attribs = args[5]; - } else if (isArrayLike(points[0])) { - points = (points).map(asVec2); - attribs = args[1]; - } - return [points, attribs]; -}; +/** + * Args parser for functions expecting a vector, numeric and/or optional + * attribs object. Returns 3-tuple of re-structured args. + * + * @param args + */ +export const argsVN = + (args: any[]) => { + const attr = argAttribs(args); + return args.length ? + args.length === 2 ? + [args[0], args[1], attr] : + isNumber(args[0]) ? + [undefined, args[0], attr] : + [args[0], undefined, attr] : + [undefined, undefined, attr]; + }; diff --git a/packages/geom/src/internal/barycentric.ts b/packages/geom/src/internal/barycentric.ts index f0c873a0dd..6e756627f9 100644 --- a/packages/geom/src/internal/barycentric.ts +++ b/packages/geom/src/internal/barycentric.ts @@ -1,24 +1,29 @@ -import { IVector, Vec3 } from "@thi.ng/vectors"; +import { + addW3, + dot, + magSq, + ReadonlyVec, + setC3, + sub, + Vec +} from "@thi.ng/vectors3"; export const toBarycentric = - > - (a: Readonly, b: Readonly, c: Readonly, p: Readonly, out = new Vec3()) => { - - const u = b.subNew(a); - const v = c.subNew(a); - const w = p.subNew(a); - const uu = u.magSq(); - const vv = v.magSq(); - const uv = u.dot(v); - const uw = u.dot(w); - const vw = v.dot(w); + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, p: ReadonlyVec, out: Vec = []) => { + const u = sub([], b, a); + const v = sub([], c, a); + const w = sub([], p, a); + const uu = magSq(u); + const vv = magSq(v); + const uv = dot(u, v); + const uw = dot(u, w); + const vw = dot(v, w); const d = 1 / (uv * uv - uu * vv); const s = d * (uv * vw - vv * uw); const t = d * (uv * uw - uu * vw); - return out.setS(1 - (s + t), s, t); + return setC3(out, 1 - (s + t), s, t); }; export const fromBarycentric = - > - (a: Readonly, b: Readonly, c: Readonly, p: Readonly, out?: T) => - a.mulNewN(p.x, out).maddN(b, p.y).maddN(c, p.z); + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, p: ReadonlyVec, out?: Vec) => + addW3(out, a, b, c, p[0], p[1], p[2]); diff --git a/packages/geom/src/internal/bounds.ts b/packages/geom/src/internal/bounds.ts index 0f834b5ba8..fa3e198284 100644 --- a/packages/geom/src/internal/bounds.ts +++ b/packages/geom/src/internal/bounds.ts @@ -1,40 +1,139 @@ -import { IVector } from "@thi.ng/vectors"; -import { IBounds, IUnion } from "../api"; - -export const axisBounds = - > - (points: ReadonlyArray, axis: number): [number, number] => { - - let min = Infinity; - let max = -Infinity; - for (let i = points.length; --i >= 0;) { - const x = points[i][axis]; - x < min && (min = x); - x > max && (max = x); - } - return [min, max]; - }; +import { Fn } from "@thi.ng/api"; +import { clamp01, mixCubic as _mixCubic } from "@thi.ng/math"; +import { max, min, Vec } from "@thi.ng/vectors3"; +import { + max2, + max3, + min2, + min3, + ReadonlyVec +} from "@thi.ng/vectors3"; +import { VecPair } from "../api"; +import { AABBLike, IShape } from "../api"; +import { unionBounds } from "./union-bounds"; -export const bounds = - > - (pts: ReadonlyArray, vmin: T, vmax: T): [T, T] => { +/** + * Computes the nD bounds of given vectors. `vmin` should be initialized + * to `+Infinity` and `vmax` to `-Infinity` (e.g. use copies of `MIN*` / + * `MAX*` constants defined in thi.ng/vectors3). + * + * Returns 2-tuple of modified `[vmin, vmax]`. + * + * @param pts + * @param vmin + * @param vmax + */ +export const boundsRaw = + (pts: ReadonlyArray, vmin: Vec, vmax: Vec): VecPair => { for (let i = pts.length; --i >= 0;) { const p = pts[i]; - vmin.min(p); - vmax.max(p); + min(null, vmin, p); + max(null, vmax, p); } return [vmin, vmax]; }; +/** + * Computes the total bounds for the given shape collection, which + * should either contain only 2D or 3D types. No mixed dimensions are + * allowed! Currently the `bounds` function must be passed in as arg to + * avoid circular module dependencies. + * + * @param shapes + * @param bounds + */ export const collBounds = - , B extends IBounds & IUnion> - (shapes: T[]) => { - + (shapes: IShape[], bounds: Fn) => { let n = shapes.length - 1; - let res: B = n > 0 ? shapes[n].bounds() : undefined; + if (n < 0) return; + let { pos, size } = bounds(shapes[n]); for (; --n >= 0;) { - res = res.union(shapes[n].bounds()); + const b = bounds(shapes[n]); + [pos, size] = unionBounds(pos, size, b.pos, b.size); + } + return [pos, size]; + }; + +const cubicAxisBounds = + (pa: number, pb: number, pc: number, pd: number) => { + let a = 3 * pd - 9 * pc + 9 * pb - 3 * pa; + let b = 6 * pa - 12 * pb + 6 * pc; + let c = 3 * pb - 3 * pa; + let disc = b * b - 4 * a * c; + let l = pa; + let h = pa; + + const bounds = (t: number) => { + if (t > 0 && t < 1) { + const x = _mixCubic(pa, pb, pc, pd, t); + x < l && (l = x); + x > h && (h = x); + } + }; + + pd < l && (l = pd); + pd > h && (h = pd); + if (disc >= 0) { + disc = Math.sqrt(disc); + a *= 2; + bounds((-b + disc) / a); + bounds((-b - disc) / a); + } + return [l, h]; + }; + +export const cubicBounds2 = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec): VecPair => { + const x = cubicAxisBounds(a[0], b[0], c[0], d[0]); + const y = cubicAxisBounds(a[1], b[1], c[1], d[1]); + return [[x[0], y[0]], [x[1], y[1]]]; + }; + +export const cubicBounds3 = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec): VecPair => { + const x = cubicAxisBounds(a[0], b[0], c[0], d[0]); + const y = cubicAxisBounds(a[1], b[1], c[1], d[1]); + const z = cubicAxisBounds(a[2], b[2], c[2], d[2]); + return [[x[0], y[0], z[0]], [x[1], y[1], z[1]]]; + }; + +const solveQuadratic = + (a: number, b: number, c: number) => { + const t = clamp01((a - b) / (a - 2.0 * b + c)); + const s = 1 - t; + return s * s * a + 2.0 * s * t * b + t * t * c; + }; + +export const quadraticBounds2 = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec): VecPair => { + const mi = min2([], a, c); + const ma = max2([], a, c); + if (b[0] < mi[0] || b[0] > ma[0] || b[1] < mi[1] || b[1] > ma[1]) { + const q = [ + solveQuadratic(a[0], b[0], c[0]), + solveQuadratic(a[1], b[1], c[1]), + ]; + min2(null, mi, q); + max2(null, ma, q); + } + return [mi, ma]; + }; + +export const quadraticBounds3 = + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec): VecPair => { + const mi = min3([], a, c); + const ma = max3([], a, c); + if (b[0] < mi[0] || b[0] > ma[0] || + b[1] < mi[1] || b[1] > ma[1] || + b[2] < mi[2] || b[2] > ma[2]) { + const q = [ + solveQuadratic(a[0], b[0], c[0]), + solveQuadratic(a[1], b[1], c[1]), + solveQuadratic(a[2], b[2], c[2]), + ]; + min3(null, mi, q); + max3(null, ma, q); } - return res; + return [mi, ma]; }; diff --git a/packages/geom/src/internal/centroid.ts b/packages/geom/src/internal/centroid.ts index a356869195..cffe402581 100644 --- a/packages/geom/src/internal/centroid.ts +++ b/packages/geom/src/internal/centroid.ts @@ -1,30 +1,19 @@ import { illegalArgs } from "@thi.ng/errors"; -import { IVector, Vec2 } from "@thi.ng/vectors"; +import { + add, + divN, + empty, + ReadonlyVec, + Vec +} from "@thi.ng/vectors3"; -export const centroid = - >(pts: ReadonlyArray, c?: T) => { +export const centroidRaw = + (pts: ReadonlyVec[], out?: Vec) => { const num = pts.length; !num && illegalArgs("no points available"); - !c && (c = pts[0].empty()); + !out && (out = empty(pts[0])); for (let i = num; --i >= 0;) { - c.add(pts[i]); + add(out, out, pts[i]); } - return c.divN(num); - }; - -export const centerOfWeight = - (pts: Vec2[], c?: Vec2) => { - let area = 0; - let x = 0; - let y = 0; - for (let n = pts.length - 1, i = pts[n], j = pts[0], k = 0; k <= n; k++ , i = j, j = pts[k]) { - const z = i.cross(j); - area += z; - x += (i.x + j.x) * z; - y += (i.y + j.y) * z; - } - area = 1 / (area * 3); - x *= area; - y *= area; - return c ? c.setS(x, y) : new Vec2([x, y]); + return divN(null, out, num); }; diff --git a/packages/geom/src/internal/circumcenter.ts b/packages/geom/src/internal/circumcenter.ts index b0e4d4768b..a5ccca08c7 100644 --- a/packages/geom/src/internal/circumcenter.ts +++ b/packages/geom/src/internal/circumcenter.ts @@ -1,43 +1,43 @@ import { EPS } from "@thi.ng/math"; -import { Vec2 } from "@thi.ng/vectors"; +import { ReadonlyVec } from "@thi.ng/vectors3"; export const circumCenter = - (a: Readonly, b: Readonly, c: Readonly, eps = EPS) => { + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, eps = EPS) => { - const deltaAB = Math.abs(a.y - b.y); - const deltaBC = Math.abs(b.y - c.y); - if (deltaAB < eps && deltaBC < eps) { - return null; - } - const ax = a.x, ay = a.y; - const bx = b.x, by = b.y; - const cx = c.x, cy = c.y; + const deltaAB = Math.abs(a[1] - b[1]); + const deltaBC = Math.abs(b[1] - c[1]); + + if (deltaAB < eps && deltaBC < eps) return; + + const ax = a[0], ay = a[1]; + const bx = b[0], by = b[1]; + const cx = c[0], cy = c[1]; let m1, m2, mx1, mx2, my1, my2, xc, yc; + if (deltaAB < eps) { - m2 = - (cx - bx) / (cy - by); + m2 = -(cx - bx) / (cy - by); mx2 = (bx + cx) / 2; my2 = (by + cy) / 2; xc = (bx + ax) / 2; yc = m2 * (xc - mx2) + my2; } else if (deltaBC < eps) { - m1 = - (bx - ax) / (by - ay); + m1 = -(bx - ax) / (by - ay); mx1 = (ax + bx) / 2; my1 = (ay + by) / 2; xc = (cx + bx) / 2; yc = m1 * (xc - mx1) + my1; } else { - m1 = - (bx - ax) / (by - ay); - m2 = - (cx - bx) / (cy - by); + m1 = -(bx - ax) / (by - ay); + m2 = -(cx - bx) / (cy - by); mx1 = (ax + bx) / 2; my1 = (ay + by) / 2; mx2 = (bx + cx) / 2; my2 = (by + cy) / 2; xc = (m1 * mx1 - m2 * mx2 + my2 - my1) / (m1 - m2); - if (deltaAB > deltaBC) { - yc = m1 * (xc - mx1) + my1; - } else { - yc = m2 * (xc - mx2) + my2; - } + yc = deltaAB > deltaBC ? + m1 * (xc - mx1) + my1 : + m2 * (xc - mx2) + my2; } - return new Vec2(xc, yc); + + return [xc, yc]; }; diff --git a/packages/geom3/src/internal/clockwise.ts b/packages/geom/src/internal/clockwise.ts similarity index 100% rename from packages/geom3/src/internal/clockwise.ts rename to packages/geom/src/internal/clockwise.ts diff --git a/packages/geom/src/internal/closest-point.ts b/packages/geom/src/internal/closest-point.ts index 485313641e..55b6e149ff 100644 --- a/packages/geom/src/internal/closest-point.ts +++ b/packages/geom/src/internal/closest-point.ts @@ -1,12 +1,28 @@ -import { IVector } from "@thi.ng/vectors"; +import { Fn } from "@thi.ng/api"; +import { partial } from "@thi.ng/compose"; +import { fit01 } from "@thi.ng/math"; +import { + distSq, + dot, + empty, + magSq, + mixCubic, + mixN, + mixQuadratic, + ReadonlyVec, + set, + sub, + Vec +} from "@thi.ng/vectors3"; +import { arcPointAtTheta } from "./arc-point"; -export const closestPoint = - >(p: T, pts: T[]) => { +export const closestPointArray = + (p: ReadonlyVec, pts: Vec[]) => { let minD = Infinity; - let closest: T; + let closest: Vec; for (let i = pts.length; --i >= 0;) { - const d = pts[i].distSq(p); + const d = distSq(pts[i], p); if (d < minD) { minD = d; closest = pts[i]; @@ -16,33 +32,44 @@ export const closestPoint = }; export const closestCoeff = - >(p: T, a: T, b: T) => { + (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec) => { - const d = b.subNew(a); - const l = d.magSq(); - if (l > 1e-6) { - return p.subNew(a).dot(d) / l; - } + const d = sub([], b, a); + const l = magSq(d); + return l > 1e-6 ? + dot(sub([], p, a), d) / l : + undefined; }; +/** + * Returns closest point to `p` on segment `a` -> `b`. By default, if + * the result point lies outside the segment, returns a copy of the + * closest end point. However, if `insideOnly` is true, only returns the + * closest point if it actually is inside the segment (incl. end + * points). + * + * @param p + * @param a + * @param b + * @param out + */ export const closestPointSegment = - >(p: T, a: T, b: T, out: T) => { + (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, out?: Vec, insideOnly = false) => { const t = closestCoeff(p, a, b); - if (t !== undefined) { - return t <= 0.0 ? - out.set(a) : - t >= 1.0 ? - out.set(b) : - a.mixNewN(b, t, out); + if (t !== undefined && (!insideOnly || t >= 0 && t <= 1)) { + out = out || empty(p); + return t <= 0 ? + set(out, a) : + t >= 1 ? + set(out, b) : + mixN(out, a, b, t); } }; export const closestPointPolyline = - >(p: Readonly, pts: ReadonlyArray, closed = false) => { - - const closest = pts[0].empty(); - const tmp = closest.empty(); + (p: ReadonlyVec, pts: ReadonlyArray, closed = false, out: Vec = []) => { + const tmp = []; const n = pts.length - 1; let minD = Infinity, i, j; if (closed) { @@ -54,21 +81,21 @@ export const closestPointPolyline = } for (; j <= n; i = j, j++) { if (closestPointSegment(p, pts[i], pts[j], tmp)) { - const d = p.distSq(tmp); + const d = distSq(p, tmp); if (d < minD) { minD = d; - closest.set(tmp); + set(out, tmp); } } } - return closest; + return out; }; /** * Returns the index of the start point containing the segment in the * polyline array `points` farthest away from `p` with regards to the * line segment `a` to `b`. `points` is only checked between indices - * `from` and `to`. + * `from` and `to` (not including the latter). * * @param a * @param b @@ -77,19 +104,13 @@ export const closestPointPolyline = * @param to */ export const farthestPointSegment = - >( - a: T, - b: T, - points: T[], - from = 0, - to = points.length) => { - + (a: ReadonlyVec, b: ReadonlyVec, points: ReadonlyVec[], from = 0, to = points.length) => { let maxD = -1; let maxIdx; - const tmp = a.empty(); + const tmp = empty(a); for (let i = from; i < to; i++) { const p = points[i]; - const d = p.distSq(closestPointSegment(p, a, b, tmp) || a); + const d = distSq(p, closestPointSegment(p, a, b, tmp) || a); if (d > maxD) { maxD = d; maxIdx = i; @@ -97,3 +118,111 @@ export const farthestPointSegment = } return [maxIdx, Math.sqrt(maxD)]; }; + +export const closestPointArc = ( + p: ReadonlyVec, + o: ReadonlyVec, + r: ReadonlyVec, + axis: number, + start: number, + end: number, + out: Vec = [], + res?: number, + iter?: number +) => { + const fn = (t: number) => arcPointAtTheta(o, r, axis, fit01(t, start, end), out); + return fn(findClosestT(fn, p, res, iter)); +}; + +/** + * Performs recursive search for closest point to `p` on cubic curve + * defined by control points `a`,`b`,`c`,`d`. The `res` and `recur` + * params are used to control the recursion behavior. See `closestT`. + * + * @param p + * @param a + * @param b + * @param c + * @param d + * @param res + * @param iter + */ +export const closestPointCubic = ( + p: ReadonlyVec, + a: ReadonlyVec, + b: ReadonlyVec, + c: ReadonlyVec, + d: ReadonlyVec, + out: Vec = [], + res?: number, + iter?: number +) => { + const fn = partial(mixCubic, out, a, b, c, d); + return fn(findClosestT(fn, p, res, iter)); +}; + +/** + * Performs recursive search for closest point to `p` on quadratic curve + * defined by control points `a`,`b`,`c`. The `res` and `recur` params + * are used to control the recursion behavior. See `closestT`. + * + * @param p + * @param a + * @param b + * @param c + * @param res + * @param iter + */ +export const closestPointQuadratic = ( + p: ReadonlyVec, + a: ReadonlyVec, + b: ReadonlyVec, + c: ReadonlyVec, + out: Vec = [], + res?: number, + iter?: number +) => { + const fn = partial(mixQuadratic, out, a, b, c); + return fn(findClosestT(fn, p, res, iter)); +}; + +/** + * Recursively evaluates function `fn` for `res` uniformly spaced values + * `t` in the closed interval `[start,end]` to compute points and + * returns the `t` of the point producing the minimum distance to query + * point `p`. At each level of recursion the search interval is + * increasingly narrowed / centered around the currently best `t`. + * + * @param fn + * @param p + * @param res + * @param iter + * @param start + * @param end + */ +export const findClosestT = ( + fn: Fn, + p: ReadonlyVec, + res = 8, + iter = 4, + start = 0, + end = 1 +) => { + if (iter <= 0) return (start + end) / 2; + const delta = (end - start) / res; + let minT = start; + let minD = Infinity; + for (let i = 0; i <= res; i++) { + const t = start + i * delta; + const d = distSq(p, fn(t)); + if (d < minD) { + minD = d; + minT = t; + } + } + return findClosestT( + fn, p, res, iter - 1, + Math.max(minT - delta, 0), + Math.min(minT + delta, 1) + ); +}; diff --git a/packages/geom/src/internal/collate.ts b/packages/geom/src/internal/collate.ts index 4fa27e767c..7a3d47726f 100644 --- a/packages/geom/src/internal/collate.ts +++ b/packages/geom/src/internal/collate.ts @@ -1,9 +1,15 @@ -import { IVec, Vec } from "@thi.ng/vectors"; -import { CollateOpts } from "../api"; +import { Vec, StridedVec } from "@thi.ng/vectors3"; + +export interface CollateOpts { + buf: Vec; + start: number; + cstride: number; + estride: number; +} export const remap = ( buf: Vec, - pts: IVec[], + pts: StridedVec[], start: number, cstride: number, estride: number @@ -11,15 +17,15 @@ export const remap = ( for (let i = pts.length; --i >= 0;) { const p = pts[i]; p.buf = buf; - p.i = start + i * estride; - p.s = cstride; + p.offset = start + i * estride; + p.stride = cstride; } return buf; }; -export const collateWith = ( - fn: (buf: Vec, src: Iterable>, start, cstride, estride) => Vec, - pts: T[], +export const collateWith = ( + fn: (buf: Vec, src: Iterable>, start, cstride, estride) => Vec, + pts: StridedVec[], opts: Partial, stride: number ) => { diff --git a/packages/geom3/src/internal/copy-points.ts b/packages/geom/src/internal/copy-points.ts similarity index 100% rename from packages/geom3/src/internal/copy-points.ts rename to packages/geom/src/internal/copy-points.ts diff --git a/packages/geom/src/internal/corner.ts b/packages/geom/src/internal/corner.ts index b817da7d0f..cfea7cf3d1 100644 --- a/packages/geom/src/internal/corner.ts +++ b/packages/geom/src/internal/corner.ts @@ -1,37 +1,14 @@ import { EPS, sign } from "@thi.ng/math"; -import { Vec2 } from "@thi.ng/vectors"; - +import { ReadonlyVec, signedArea2 } from "@thi.ng/vectors3"; + +/** + * Syntax sugar for `sign(signedArea2(a,b,c))`. + * + * @param a + * @param b + * @param c + * @param eps + */ export const corner = - (a: Readonly, b: Readonly, c: Readonly) => { - const ax = a.x; - const ay = a.y; - return (b.x - ax) * (c.y - ay) - (c.x - ax) * (b.y - ay); - }; - -export const classify = - (a: Readonly, b: Readonly, c: Readonly, eps = EPS) => - sign(corner(a, b, c), eps); - -export const clockwise2 = - (a: Readonly, b: Readonly, c: Readonly) => - corner(a, b, c) < 0; - -export const classifyPointInTriangle2 = - (p: Readonly, a: Readonly, b: Readonly, c: Readonly) => { - const s = clockwise2(a, b, c) ? 1 : -1; - return sign( - Math.min( - s * corner(a, c, p), - s * corner(b, a, p), - s * corner(c, b, p) - ) - ); - }; - -export const pointInTriangle2 = - (p: Readonly, a: Readonly, b: Readonly, c: Readonly) => { - const s = clockwise2(a, b, c) ? 1 : -1; - return s * corner(a, c, p) >= 0 && - s * corner(b, a, p) >= 0 && - s * corner(c, b, p) >= 0; - }; + (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, eps = EPS) => + sign(signedArea2(a, b, c), eps); diff --git a/packages/geom3/src/internal/direction.ts b/packages/geom/src/internal/direction.ts similarity index 100% rename from packages/geom3/src/internal/direction.ts rename to packages/geom/src/internal/direction.ts diff --git a/packages/geom3/src/internal/dispatch.ts b/packages/geom/src/internal/dispatch.ts similarity index 100% rename from packages/geom3/src/internal/dispatch.ts rename to packages/geom/src/internal/dispatch.ts diff --git "a/packages/geom/src/internal/douglas\342\200\223peucker.ts" "b/packages/geom/src/internal/douglas\342\200\223peucker.ts" index 5f6ae4e122..3051fc747d 100644 --- "a/packages/geom/src/internal/douglas\342\200\223peucker.ts" +++ "b/packages/geom/src/internal/douglas\342\200\223peucker.ts" @@ -1,18 +1,17 @@ +import { EPS } from "@thi.ng/math"; import { peek } from "@thi.ng/transducers"; -import { IVector } from "@thi.ng/vectors"; +import { eqDelta, Vec } from "@thi.ng/vectors3"; import { farthestPointSegment } from "./closest-point"; // https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm -export const simplifyPolyline = - >(pts: T[], eps = 0, closed = false) => { +export const douglasPeucker = + (pts: Vec[], eps = 0, closed = false) => { let num = pts.length; const visited: boolean[] = []; - if (num <= 2) { - return pts.slice(); - } - if (closed && !pts[0].eqDelta(peek(pts))) { + if (num <= 2) return pts.slice(); + if (closed && !eqDelta(pts[0], peek(pts), EPS)) { pts = pts.slice(); pts.push(pts[0]); num++; @@ -33,7 +32,7 @@ export const simplifyPolyline = $(0, num - 1); - const res: T[] = []; + const res: Vec[] = []; for (let i = 0, n = closed ? num - 1 : num; i < n; i++) { if (visited[i]) { res.push(pts[i]); diff --git a/packages/geom/src/internal/edges.ts b/packages/geom/src/internal/edges.ts index 537fe27010..b8b21d2b92 100644 --- a/packages/geom/src/internal/edges.ts +++ b/packages/geom/src/internal/edges.ts @@ -1,5 +1,12 @@ import { partition, wrap } from "@thi.ng/transducers"; +import { ReadonlyVec } from "@thi.ng/vectors3"; +import { VecPair } from "../api"; -export const edges = - (vertices: Iterable, closed = false) => - partition(2, 1, closed ? wrap(vertices, 1, false, true) : vertices); +export const edgeIterator = + (vertices: Iterable, closed = false) => + >partition( + 2, 1, + closed ? + wrap(vertices, 1, false, true) : + vertices + ); diff --git a/packages/geom/src/internal/eq-delta.ts b/packages/geom/src/internal/eq-delta.ts deleted file mode 100644 index 26a715de2a..0000000000 --- a/packages/geom/src/internal/eq-delta.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { EPS } from "@thi.ng/math"; -import { IVector } from "@thi.ng/vectors"; - -export const containsDelta = - >(pts: Iterable, q: Readonly, eps = EPS) => { - for (let p of pts) { - if (p.eqDelta(q, eps)) { - return true; - } - } - return false; - }; diff --git a/packages/geom/src/internal/graham-scan.ts b/packages/geom/src/internal/graham-scan.ts index 4134e7647c..76ede164c0 100644 --- a/packages/geom/src/internal/graham-scan.ts +++ b/packages/geom/src/internal/graham-scan.ts @@ -1,5 +1,5 @@ -import { Vec2 } from "@thi.ng/vectors"; -import { corner } from "./corner"; +import { EPS } from "@thi.ng/math"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors3"; /** * Returns array of points defining the 2D Convex Hull of `pts` using @@ -9,30 +9,79 @@ import { corner } from "./corner"; * * @param pts */ -export const convexHull = - (pts: ReadonlyArray) => { +export const grahamScan2 = + (pts: ReadonlyVec[], eps = EPS) => { const num = pts.length; - const res: Vec2[] = []; - let h = 0, i; - pts = pts.slice().sort(Vec2.comparator(0, 1)); - - const scan = (p: Vec2, thresh: number) => { - while (h >= thresh && corner(res[h - 2], res[h - 1], p) >= 0) { - res.pop(); + if (num <= 3) return pts.slice(); + let h = 1, i, p, q, r, rx, ry; + // find min YX index + const min = findMin(pts); + [rx, ry] = pts[min]; + const sorted = []; + // compute & sort by polar ordering relative to min + for (i = 0; i < num; i++) { + p = pts[i]; + sorted[i] = { p, t: Math.atan2(p[1] - ry, p[0] - rx) }; + } + sorted.sort( + (a, b) => + a.t !== b.t ? + a.t - b.t : + a.p[0] - b.p[0] + ); + const hull: Vec[] = [sorted[0].p]; + for (i = 1; i < num; i++) { + p = hull[h - 2]; + q = hull[h - 1]; + r = sorted[i].p; + rx = r[0]; + ry = r[1]; + while ((h > 1 && notCCW(p[0], p[1], q[0], q[1], rx, ry, eps)) || + (h === 1 && q[0] === rx && q[1] === ry)) { h--; + q = p; + p = hull[h - 2]; } - res[h++] = p; - }; - - for (i = 0; i < num; i++) { - scan(pts[i], 2); + hull[h++] = r; } - res.pop(); - h--; - const h2 = h + 2; - for (i = num - 1; i >= 0; i--) { - scan(pts[i], h2); + hull.length = h; + return hull; + }; + +/** + * Returns true, if triangle defined by ABC is NOT counter clockwise, + * i.e. clockwise or colinear. + * + * @see thi.ng/vectors3/signedArea2 + * + * @param ax + * @param ay + * @param bx + * @param by + * @param cx + * @param cy + */ +const notCCW = (ax: number, ay: number, bx: number, by: number, cx: number, cy: number, eps: number) => + (by - ay) * (cx - ax) >= (bx - ax) * (cy - ay) - eps; + +/** + * Returns index of point with lowest YX coords. + * + * @param pts + */ +const findMin = + (pts: ReadonlyVec[]) => { + let n = pts.length - 1; + let minID = n; + let min = pts[n][1]; + let p, y; + for (; --n >= 0;) { + p = pts[n]; + y = p[1]; + if (y < min || (y === min && p[0] < pts[minID][0])) { + min = y; + minID = n; + } } - res.pop(); - return res; + return minID; }; diff --git a/packages/geom/src/internal/liang-barsky.ts b/packages/geom/src/internal/liang-barsky.ts index e08223f671..f30ffcc3da 100644 --- a/packages/geom/src/internal/liang-barsky.ts +++ b/packages/geom/src/internal/liang-barsky.ts @@ -1,50 +1,75 @@ import { EPS } from "@thi.ng/math"; -import { Vec2 } from "@thi.ng/vectors"; +import { Vec } from "@thi.ng/vectors3"; -// https://en.wikipedia.org/wiki/Liang%E2%80%93Barsky_algorithm -// https://github.com/thi-ng/c-thing/blob/master/src/geom/clip/liangbarsky.c +/** + * Performs Liang-Barsky clipping with given line endpoints `la`, `lb` + * and clipping rect defined by top-left `tr` and bottom-right `br` + * points. The optional `ca` and `cb` vectors can be given to store the + * result (clipped points). If omitted creates new vectors. Returns a + * tuple of `[ca, cb, a, b]`, where the latter two values represent the + * normalized distances of the clipped points relative to original given + * line segment. Returns `undefined` iff the line lies completely + * outside the rect. + * + * https://en.wikipedia.org/wiki/Liang%E2%80%93Barsky_algorithm + * https://github.com/thi-ng/c-thing/blob/master/src/geom/clip/liangbarsky.c + * + * @param la + * @param lb + * @param tl + * @param br + * @param ca + * @param cb + */ +export const liangBarsky = ( + la: Vec, + lb: Vec, + tl: Vec, + br: Vec, + ca: Vec = [], + cb: Vec = [] +): [Vec, Vec, number, number] => { + const lax = la[0]; + const lay = la[1]; + const dx = lb[0] - lax; + const dy = lb[1] - lay; + let a = 0; + let b = 1; -export const liangBarsky2 = - (la: Vec2, lb: Vec2, tl: Vec2, br: Vec2, ca?: Vec2, cb?: Vec2): [Vec2, Vec2, number, number] => { - const [lax, lay] = la; - const dx = lb.x - lax; - const dy = lb.y - lay; - let a = 0; - let b = 1; - - const clip = (p: number, q: number) => { - if (q < 0 && Math.abs(p) < EPS) { - return 0; + const clip = (p: number, q: number) => { + if (q < 0 && Math.abs(p) < EPS) { + return 0; + } + const r = q / p; + if (p < 0) { + if (r > b) { + return false; + } else if (r > a) { + a = r; } - const r = q / p; - if (p < 0) { - if (r > b) { - return false; - } else if (r > a) { - a = r; - } - } else if (p > 0) { - if (r < a) { - return false; - } else if (r < b) { - b = r; - } + } else { + if (r < a) { + return false; + } else if (r < b) { + b = r; } - return true; - }; - - if (!(clip(-dx, -(tl.x - lax)) && - clip(dx, br.x - lax) && - clip(-dy, -(tl.y - lay)) && - clip(dy, br.y - lay))) { - return; } + return true; + }; - !ca && (ca = new Vec2()); - !cb && (cb = new Vec2()); + if (!( + clip(-dx, -(tl[0] - lax)) && + clip(dx, br[0] - lax) && + clip(-dy, -(tl[1] - lay)) && + clip(dy, br[1] - lay) + )) { + return; + } - ca.setS(a * dx + lax, a * dy + lay); - cb.setS(b * dx + lax, b * dy + lay); + ca[0] = a * dx + lax; + ca[1] = a * dy + lay; + cb[0] = b * dx + lax; + cb[1] = b * dy + lay; - return [ca, cb, a, b]; - }; + return [ca, cb, a, b]; +}; diff --git a/packages/geom/src/internal/line-intersection.ts b/packages/geom/src/internal/line-intersection.ts deleted file mode 100644 index 0272f666bd..0000000000 --- a/packages/geom/src/internal/line-intersection.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Vec2 } from "@thi.ng/vectors"; -import { LineIntersection, LineIntersectionType } from "../api"; - -export const intersectLines2 = - (a: Vec2, b: Vec2, c: Vec2, d: Vec2) => { - const bax = b.x - a.x; - const bay = b.y - a.y; - const dcx = d.x - c.x; - const dcy = d.y - c.y; - const acx = a.x - c.x; - const acy = a.y - c.y; - const det = dcy * bax - dcx * bay; - let alpha = dcx * acy - dcy * acx; - let beta = bax * acy - bay * acx; - if (det === 0) { - if (alpha === 0 && beta === 0) { - return { type: LineIntersectionType.COINCIDENT }; - } - return { type: LineIntersectionType.PARALLEL }; - } - alpha /= det; - beta /= det; - return >{ - type: (0 <= alpha && alpha <= 1) && (0 <= beta && beta <= 1) ? - LineIntersectionType.INTERSECT : - LineIntersectionType.INTERSECT_OUTSIDE, - isec: a.mixNewN(b, alpha), - alpha, - beta, - det, - }; - }; diff --git a/packages/geom3/src/internal/point-in-array.ts b/packages/geom/src/internal/point-in-array.ts similarity index 100% rename from packages/geom3/src/internal/point-in-array.ts rename to packages/geom/src/internal/point-in-array.ts diff --git a/packages/geom3/src/internal/poly-arc-length.ts b/packages/geom/src/internal/poly-arc-length.ts similarity index 100% rename from packages/geom3/src/internal/poly-arc-length.ts rename to packages/geom/src/internal/poly-arc-length.ts diff --git a/packages/geom3/src/internal/poly-area.ts b/packages/geom/src/internal/poly-area.ts similarity index 100% rename from packages/geom3/src/internal/poly-area.ts rename to packages/geom/src/internal/poly-area.ts diff --git a/packages/geom3/src/internal/poly-centroid.ts b/packages/geom/src/internal/poly-centroid.ts similarity index 100% rename from packages/geom3/src/internal/poly-centroid.ts rename to packages/geom/src/internal/poly-centroid.ts diff --git a/packages/geom3/src/internal/poly-point-inside.ts b/packages/geom/src/internal/poly-point-inside.ts similarity index 100% rename from packages/geom3/src/internal/poly-point-inside.ts rename to packages/geom/src/internal/poly-point-inside.ts diff --git a/packages/geom3/src/internal/sampler.ts b/packages/geom/src/internal/sampler.ts similarity index 100% rename from packages/geom3/src/internal/sampler.ts rename to packages/geom/src/internal/sampler.ts diff --git a/packages/geom3/src/internal/split.ts b/packages/geom/src/internal/split.ts similarity index 100% rename from packages/geom3/src/internal/split.ts rename to packages/geom/src/internal/split.ts diff --git a/packages/geom3/src/internal/subdiv-curve.ts b/packages/geom/src/internal/subdiv-curve.ts similarity index 100% rename from packages/geom3/src/internal/subdiv-curve.ts rename to packages/geom/src/internal/subdiv-curve.ts diff --git a/packages/geom/src/internal/sutherland-hodgeman.ts b/packages/geom/src/internal/sutherland-hodgeman.ts index 9b8175aab5..967481a32e 100644 --- a/packages/geom/src/internal/sutherland-hodgeman.ts +++ b/packages/geom/src/internal/sutherland-hodgeman.ts @@ -1,6 +1,6 @@ -import { Vec2 } from "@thi.ng/vectors"; -import { classify } from "./corner"; -import { intersectLines2 } from "./line-intersection"; +import { ReadonlyVec } from "@thi.ng/vectors3"; +import { corner } from "./corner"; +import { intersectLineLine } from "../isec/line-line"; /** * Extended version of Sutherland-Hodgeman convex polygon clipping @@ -9,36 +9,36 @@ import { intersectLines2 } from "./line-intersection"; * * https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm * - * @param poly subject poly - * @param bounds clipping boundary + * @param pts subject poly vertices + * @param bounds clipping boundary vertices * @param bc pre-computed boundary centroid * @param eps edge classification tolerance */ -export const clipConvex = - (poly: Vec2[], bounds: Vec2[], bc: Vec2, eps = 1e-4) => { +export const sutherlandHodgeman = + (pts: ReadonlyVec[], bounds: ReadonlyVec[], bc: ReadonlyVec, eps = 1e-4) => { for (let ne = bounds.length, j = ne - 1, i = 0; i < ne; j = i, i++) { const clipped = []; const ca = bounds[j]; const cb = bounds[i]; - const sign = classify(ca, cb, bc, eps); - for (let np = poly.length, k = np - 1, l = 0; l < np; k = l, l++) { - const p = poly[k]; - const q = poly[l]; - const cqsign = classify(ca, cb, q, eps); - if (classify(ca, cb, p, eps) === sign) { + const sign = corner(ca, cb, bc, eps); + for (let np = pts.length, k = np - 1, l = 0; l < np; k = l, l++) { + const p = pts[k]; + const q = pts[l]; + const cqsign = corner(ca, cb, q, eps); + if (corner(ca, cb, p, eps) === sign) { clipped.push( cqsign !== sign ? - intersectLines2(ca, cb, p, q).isec : + intersectLineLine(ca, cb, p, q).isec : q ); } else if (cqsign === sign) { - clipped.push(intersectLines2(ca, cb, p, q).isec, q); + clipped.push(intersectLineLine(ca, cb, p, q).isec, q); } } if (clipped.length < 2) { return []; } - poly = clipped; + pts = clipped; } - return poly; + return pts; }; diff --git a/packages/geom3/src/internal/tessellate.ts b/packages/geom/src/internal/tessellate.ts similarity index 100% rename from packages/geom3/src/internal/tessellate.ts rename to packages/geom/src/internal/tessellate.ts diff --git a/packages/geom3/src/internal/transform-points.ts b/packages/geom/src/internal/transform-points.ts similarity index 100% rename from packages/geom3/src/internal/transform-points.ts rename to packages/geom/src/internal/transform-points.ts diff --git a/packages/geom3/src/internal/translate-points.ts b/packages/geom/src/internal/translate-points.ts similarity index 100% rename from packages/geom3/src/internal/translate-points.ts rename to packages/geom/src/internal/translate-points.ts diff --git a/packages/geom3/src/internal/triangle-point-inside.ts b/packages/geom/src/internal/triangle-point-inside.ts similarity index 100% rename from packages/geom3/src/internal/triangle-point-inside.ts rename to packages/geom/src/internal/triangle-point-inside.ts diff --git a/packages/geom3/src/internal/union-bounds.ts b/packages/geom/src/internal/union-bounds.ts similarity index 100% rename from packages/geom3/src/internal/union-bounds.ts rename to packages/geom/src/internal/union-bounds.ts diff --git a/packages/geom3/src/isec/circle-circle.ts b/packages/geom/src/isec/circle-circle.ts similarity index 100% rename from packages/geom3/src/isec/circle-circle.ts rename to packages/geom/src/isec/circle-circle.ts diff --git a/packages/geom3/src/isec/line-line.ts b/packages/geom/src/isec/line-line.ts similarity index 100% rename from packages/geom3/src/isec/line-line.ts rename to packages/geom/src/isec/line-line.ts diff --git a/packages/geom3/src/isec/ray-circle.ts b/packages/geom/src/isec/ray-circle.ts similarity index 100% rename from packages/geom3/src/isec/ray-circle.ts rename to packages/geom/src/isec/ray-circle.ts diff --git a/packages/geom3/src/isec/ray-line.ts b/packages/geom/src/isec/ray-line.ts similarity index 100% rename from packages/geom3/src/isec/ray-line.ts rename to packages/geom/src/isec/ray-line.ts diff --git a/packages/geom3/src/isec/ray-poly.ts b/packages/geom/src/isec/ray-poly.ts similarity index 100% rename from packages/geom3/src/isec/ray-poly.ts rename to packages/geom/src/isec/ray-poly.ts diff --git a/packages/geom3/src/isec/rect-circle.ts b/packages/geom/src/isec/rect-circle.ts similarity index 100% rename from packages/geom3/src/isec/rect-circle.ts rename to packages/geom/src/isec/rect-circle.ts diff --git a/packages/geom3/src/isec/rect-rect.ts b/packages/geom/src/isec/rect-rect.ts similarity index 100% rename from packages/geom3/src/isec/rect-rect.ts rename to packages/geom/src/isec/rect-rect.ts diff --git a/packages/geom/src/line2.ts b/packages/geom/src/line2.ts deleted file mode 100644 index e545dc5a0c..0000000000 --- a/packages/geom/src/line2.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { isArrayLike, isNumber, isPlainObject } from "@thi.ng/checks"; -import { - asVec2, - ReadonlyVec, - Vec, - Vec2 -} from "@thi.ng/vectors"; -import { - Attribs, - HiccupLine2, - IToCubic, - SamplingOpts -} from "./api"; -import { Cubic2 } from "./bezier2"; -import { PointContainer2 } from "./container2"; -import { liangBarsky2 } from "./internal/liang-barsky"; -import { intersectLines2 } from "./internal/line-intersection"; -import { Rect2 } from "./rect2"; -import { Sampler } from "./sampler"; - -export class Line2 extends PointContainer2 implements - IToCubic { - - constructor(points: Vec2[], attribs?: Attribs) { - if (points.length > 2) { - points = points.slice(0, 2); - } - super(points, attribs); - } - - copy() { - return new Line2(this._copy(), { ...this.attribs }); - } - - edges() { - return this.points.slice(0, 2); - } - - area() { - return 0; - } - - arcLength() { - const pts = this.points; - return pts[0].dist(pts[1]); - } - - vertices(opts?: number | Partial) { - const sampler = new Sampler(this.points); - if (opts !== undefined) { - if (isPlainObject(opts)) { - return opts.dist ? - sampler.sampleUniform(opts.dist, opts.last !== false) : - sampler.sampleFixedNum(opts.num, opts.last !== false); - } - return sampler.sampleFixedNum(opts, true); - } else { - return this.points; - } - } - - intersectLine(l: Line2) { - return intersectLines2(this.points[0], this.points[1], l.points[0], l.points[1]); - } - - clipRect(bounds: [Vec2, Vec2] | Rect2) { - const res = bounds instanceof Rect2 ? - liangBarsky2(this.points[0], this.points[1], bounds.pos, bounds.pos.addNew(bounds.size)) : - liangBarsky2(this.points[0], this.points[1], bounds[0], bounds[1]); - if (res) { - return new Line2([res[0], res[1]], { ...this.attribs }); - } - } - - toCubic() { - return [Cubic2.fromLine(this.points[0], this.points[1], { ...this.attribs })]; - } - - toHiccup(): HiccupLine2 { - return ["line", this.attribs || {}, this.points[0], this.points[1]]; - } - - toHiccupPathSegments() { - return [["L", this.points[1]]]; - } - - toJSON() { - return this._toJSON("line2"); - } -} - -export function line2(points: Vec, start?: number, cstride?: number, estride?: number, attribs?: Attribs): Line2; -export function line2(x1: number, y1: number, x2: number, y2: number, attribs?: Attribs): Line2; -export function line2(a: ReadonlyVec, b: ReadonlyVec, attribs?: Attribs): Line2; -export function line2(...args: any[]) { - let points = args[0], attribs; - let n = args.length - 1; - if (isPlainObject(args[n]) || args[n] == null) { - attribs = args[n]; - n--; - } - if (isNumber(points)) { - return new Line2(Vec2.mapBuffer(args.slice(0, 4), 2), attribs); - } - if (isArrayLike(points)) { - return new Line2([asVec2(points), asVec2(args[1])], attribs); - } - return new Line2(Vec2.mapBuffer(points, 2, args[1] || 0, args[2] || 1, args[3] || 2), attribs); -} diff --git a/packages/geom3/src/ops/arc-length.ts b/packages/geom/src/ops/arc-length.ts similarity index 100% rename from packages/geom3/src/ops/arc-length.ts rename to packages/geom/src/ops/arc-length.ts diff --git a/packages/geom3/src/ops/area.ts b/packages/geom/src/ops/area.ts similarity index 100% rename from packages/geom3/src/ops/area.ts rename to packages/geom/src/ops/area.ts diff --git a/packages/geom3/src/ops/as-cubic.ts b/packages/geom/src/ops/as-cubic.ts similarity index 100% rename from packages/geom3/src/ops/as-cubic.ts rename to packages/geom/src/ops/as-cubic.ts diff --git a/packages/geom3/src/ops/as-polygon.ts b/packages/geom/src/ops/as-polygon.ts similarity index 100% rename from packages/geom3/src/ops/as-polygon.ts rename to packages/geom/src/ops/as-polygon.ts diff --git a/packages/geom3/src/ops/as-svg.ts b/packages/geom/src/ops/as-svg.ts similarity index 100% rename from packages/geom3/src/ops/as-svg.ts rename to packages/geom/src/ops/as-svg.ts diff --git a/packages/geom3/src/ops/bounds.ts b/packages/geom/src/ops/bounds.ts similarity index 100% rename from packages/geom3/src/ops/bounds.ts rename to packages/geom/src/ops/bounds.ts diff --git a/packages/geom3/src/ops/center.ts b/packages/geom/src/ops/center.ts similarity index 100% rename from packages/geom3/src/ops/center.ts rename to packages/geom/src/ops/center.ts diff --git a/packages/geom3/src/ops/centroid.ts b/packages/geom/src/ops/centroid.ts similarity index 100% rename from packages/geom3/src/ops/centroid.ts rename to packages/geom/src/ops/centroid.ts diff --git a/packages/geom3/src/ops/classify-point.ts b/packages/geom/src/ops/classify-point.ts similarity index 100% rename from packages/geom3/src/ops/classify-point.ts rename to packages/geom/src/ops/classify-point.ts diff --git a/packages/geom3/src/ops/clip-convex.ts b/packages/geom/src/ops/clip-convex.ts similarity index 100% rename from packages/geom3/src/ops/clip-convex.ts rename to packages/geom/src/ops/clip-convex.ts diff --git a/packages/geom3/src/ops/closest-point.ts b/packages/geom/src/ops/closest-point.ts similarity index 100% rename from packages/geom3/src/ops/closest-point.ts rename to packages/geom/src/ops/closest-point.ts diff --git a/packages/geom3/src/ops/convex-hull.ts b/packages/geom/src/ops/convex-hull.ts similarity index 100% rename from packages/geom3/src/ops/convex-hull.ts rename to packages/geom/src/ops/convex-hull.ts diff --git a/packages/geom3/src/ops/edges.ts b/packages/geom/src/ops/edges.ts similarity index 100% rename from packages/geom3/src/ops/edges.ts rename to packages/geom/src/ops/edges.ts diff --git a/packages/geom3/src/ops/fit-into-bounds.ts b/packages/geom/src/ops/fit-into-bounds.ts similarity index 100% rename from packages/geom3/src/ops/fit-into-bounds.ts rename to packages/geom/src/ops/fit-into-bounds.ts diff --git a/packages/geom3/src/ops/flip.ts b/packages/geom/src/ops/flip.ts similarity index 100% rename from packages/geom3/src/ops/flip.ts rename to packages/geom/src/ops/flip.ts diff --git a/packages/geom3/src/ops/intersects.ts b/packages/geom/src/ops/intersects.ts similarity index 100% rename from packages/geom3/src/ops/intersects.ts rename to packages/geom/src/ops/intersects.ts diff --git a/packages/geom3/src/ops/map-point.ts b/packages/geom/src/ops/map-point.ts similarity index 100% rename from packages/geom3/src/ops/map-point.ts rename to packages/geom/src/ops/map-point.ts diff --git a/packages/geom3/src/ops/point-at.ts b/packages/geom/src/ops/point-at.ts similarity index 100% rename from packages/geom3/src/ops/point-at.ts rename to packages/geom/src/ops/point-at.ts diff --git a/packages/geom3/src/ops/point-inside.ts b/packages/geom/src/ops/point-inside.ts similarity index 100% rename from packages/geom3/src/ops/point-inside.ts rename to packages/geom/src/ops/point-inside.ts diff --git a/packages/geom3/src/ops/resample.ts b/packages/geom/src/ops/resample.ts similarity index 100% rename from packages/geom3/src/ops/resample.ts rename to packages/geom/src/ops/resample.ts diff --git a/packages/geom3/src/ops/scatter.ts b/packages/geom/src/ops/scatter.ts similarity index 100% rename from packages/geom3/src/ops/scatter.ts rename to packages/geom/src/ops/scatter.ts diff --git a/packages/geom3/src/ops/simplify.ts b/packages/geom/src/ops/simplify.ts similarity index 100% rename from packages/geom3/src/ops/simplify.ts rename to packages/geom/src/ops/simplify.ts diff --git a/packages/geom3/src/ops/split-at.ts b/packages/geom/src/ops/split-at.ts similarity index 100% rename from packages/geom3/src/ops/split-at.ts rename to packages/geom/src/ops/split-at.ts diff --git a/packages/geom3/src/ops/split-near.ts b/packages/geom/src/ops/split-near.ts similarity index 100% rename from packages/geom3/src/ops/split-near.ts rename to packages/geom/src/ops/split-near.ts diff --git a/packages/geom3/src/ops/subdiv-curve.ts b/packages/geom/src/ops/subdiv-curve.ts similarity index 100% rename from packages/geom3/src/ops/subdiv-curve.ts rename to packages/geom/src/ops/subdiv-curve.ts diff --git a/packages/geom3/src/ops/tangent-at.ts b/packages/geom/src/ops/tangent-at.ts similarity index 100% rename from packages/geom3/src/ops/tangent-at.ts rename to packages/geom/src/ops/tangent-at.ts diff --git a/packages/geom3/src/ops/tessellate.ts b/packages/geom/src/ops/tessellate.ts similarity index 100% rename from packages/geom3/src/ops/tessellate.ts rename to packages/geom/src/ops/tessellate.ts diff --git a/packages/geom3/src/ops/transform.ts b/packages/geom/src/ops/transform.ts similarity index 100% rename from packages/geom3/src/ops/transform.ts rename to packages/geom/src/ops/transform.ts diff --git a/packages/geom3/src/ops/translate.ts b/packages/geom/src/ops/translate.ts similarity index 100% rename from packages/geom3/src/ops/translate.ts rename to packages/geom/src/ops/translate.ts diff --git a/packages/geom3/src/ops/union.ts b/packages/geom/src/ops/union.ts similarity index 100% rename from packages/geom3/src/ops/union.ts rename to packages/geom/src/ops/union.ts diff --git a/packages/geom3/src/ops/unmap-point.ts b/packages/geom/src/ops/unmap-point.ts similarity index 100% rename from packages/geom3/src/ops/unmap-point.ts rename to packages/geom/src/ops/unmap-point.ts diff --git a/packages/geom3/src/ops/vertices.ts b/packages/geom/src/ops/vertices.ts similarity index 100% rename from packages/geom3/src/ops/vertices.ts rename to packages/geom/src/ops/vertices.ts diff --git a/packages/geom3/src/ops/warp-points.ts b/packages/geom/src/ops/warp-points.ts similarity index 100% rename from packages/geom3/src/ops/warp-points.ts rename to packages/geom/src/ops/warp-points.ts diff --git a/packages/geom3/src/ops/with-attribs.ts b/packages/geom/src/ops/with-attribs.ts similarity index 100% rename from packages/geom3/src/ops/with-attribs.ts rename to packages/geom/src/ops/with-attribs.ts diff --git a/packages/geom/src/path2.ts b/packages/geom/src/path2.ts deleted file mode 100644 index 4e89502311..0000000000 --- a/packages/geom/src/path2.ts +++ /dev/null @@ -1,481 +0,0 @@ -import { implementsFunction, isNumber } from "@thi.ng/checks"; -import { eqDelta, rad } from "@thi.ng/math"; -import { - ensureArray, - map, - mapcat, - peek -} from "@thi.ng/transducers"; -import { Vec2 } from "@thi.ng/vectors"; -import { - Attribs, - IBounds, - IBoundsRaw, - IToPolygon, - IVertices, - PathSegment, - SamplingOpts, - SegmentType -} from "./api"; -import { Arc2 } from "./arc2"; -import { Cubic2, Quadratic2 } from "./bezier2"; -import { Line2 } from "./line2"; -import { Polygon2 } from "./polygon2"; -import { Polyline2 } from "./polyline2"; -import { Rect2 } from "./rect2"; -import { simplifyPolyline } from "./internal/douglas–peucker"; - -export class Path2 implements - Iterable, - IBoundsRaw, - IBounds, - IToPolygon, - IVertices { - - segments: PathSegment[]; - closed: boolean; - attribs: Attribs; - - constructor(segments?: PathSegment[], attribs?: Attribs) { - this.segments = segments || []; - this.attribs = attribs; - this.closed = false; - } - - *[Symbol.iterator]() { - yield* (this.segments); - } - - add(s: PathSegment) { - this.segments.push(s); - } - - boundsRaw(): [Vec2, Vec2] { - const min = Vec2.MAX.copy(); - const max = Vec2.MIN.copy(); - for (let s of this.segments) { - if (s.geo) { - const b = s.geo.boundsRaw(); - min.min(b[0]); - max.max(b[1]); - } - } - return [min, max]; - } - - bounds() { - return Rect2.fromMinMax(...this.boundsRaw()); - } - - simplify(eps = 0.01): Path2 { - const res: PathSegment[] = []; - const orig = this.segments; - const n = orig.length; - let points: Vec2[]; - let lastP: Vec2; - for (let i = 0; i < n; i++) { - const s = orig[i]; - if (s.type === SegmentType.LINE || s.type === SegmentType.POLYLINE) { - points = (points || []).concat(ensureArray(s.geo.vertices())); - lastP = peek(points); - } else if (points) { - points.push(lastP); - res.push({ - geo: new Polyline2(simplifyPolyline(points, eps)), - type: SegmentType.POLYLINE, - }); - points = null; - } else { - res.push({ ...s }); - } - } - if (points) { - points.push(lastP); - res.push({ - geo: new Polyline2(points), - type: SegmentType.POLYLINE, - }); - } - return new Path2(res); - } - - vertices(opts?: number | Partial) { - const _opts = isNumber(opts) ? { num: opts } : opts; - let verts: Vec2[] = []; - for (let segs = this.segments, n = segs.length - 1, i = 0; i <= n; i++) { - const s = segs[i]; - if (s.geo) { - const v = ensureArray(s.geo.vertices({ ..._opts, last: i === n && !this.closed })); - verts = verts.concat(v); - } - } - return verts; - } - - normalize() { - return new Path2([...mapcat( - (s) => - implementsFunction(s.geo, "toCubic") ? - map( - (c) => ({ type: SegmentType.CUBIC, geo: c }), - s.geo.toCubic() - ) : - [s], - this.segments - )]); - } - - toPolygon(opts?: number | Partial) { - return new Polygon2(this.vertices(opts)); - } - - toPolyline(res = 10) { - return new Polyline2(this.vertices(res)); - } - - toHiccup() { - const dest: any[] = []; - const res: any[] = ["path", this.attribs || {}, dest]; - const src = this.segments; - const n = src.length; - if (n > 1) { - dest.push(["M", src[0].point]); - for (let i = 1; i < n; i++) { - dest.push(...src[i].geo.toHiccupPathSegments()); - } - if (this.closed) { - dest.push(["Z"]); - } - } - return res; - } -} - -const CMD_RE = /[achlmqstvz]/i; - -export class PathBuilder { - - static roundedRect(pos: Vec2, size: Vec2, r: Vec2) { - const b = new PathBuilder(), - w = size.x - 2 * r.x, - h = size.y - 2 * r.y; - b.moveTo(new Vec2([pos.x + r.x, pos.y])); - b.hlineTo(w, true); - b.arcTo(r, r, 0, false, true, true); - b.vlineTo(h, true); - b.arcTo(new Vec2([-r.x, r.y]), r, 0, false, true, true); - b.hlineTo(-w, true); - b.arcTo(new Vec2([-r.x, -r.y]), r, 0, false, true, true); - b.vlineTo(-h, true); - b.arcTo(new Vec2([r.x, -r.y]), r, 0, false, true, true); - return b.curr; - } - - static fromSVG(svg: string) { - const b = new PathBuilder(); - try { - let cmd: string; - for (let n = svg.length, i = 0; i < n;) { - i = skipWS(svg, i); - const c = svg.charAt(i); - if (CMD_RE.test(c)) { - cmd = c; - i++; - } - let p, pa, pb, t1, t2, t3; - switch (cmd.toLowerCase()) { - case "m": - [p, i] = readPoint(svg, i); - b.moveTo(p, cmd === "m"); - break; - case "l": - [p, i] = readPoint(svg, i); - b.lineTo(p, cmd === "l"); - break; - case "h": - [p, i] = readFloat(svg, i); - b.hlineTo(p, cmd === "h"); - break; - case "v": - [p, i] = readFloat(svg, i); - b.vlineTo(p, cmd === "v"); - break; - case "q": - [pa, i] = readPoint(svg, i); - [p, i] = readPoint(svg, i); - // console.log("quadratic", pa.toString(), p.toString()); - b.quadraticTo(pa, p, cmd === "q"); - break; - case "c": - [pa, i] = readPoint(svg, i); - [pb, i] = readPoint(svg, i); - [p, i] = readPoint(svg, i); - // console.log("cubic", pa.toString(), pb.toString(), p.toString()); - b.cubicTo(pa, pb, p, cmd === "c"); - break; - case "s": - [pa, i] = readPoint(svg, i); - [p, i] = readPoint(svg, i); - // console.log("cubicChain", pa.toString(), p.toString()); - b.cubicChainTo(pa, p, cmd === "s"); - break; - case "t": - [p, i] = readPoint(svg, i); - // console.log("quadraticChain", p.toString()); - b.quadraticChainTo(p, cmd === "t"); - break; - case "a": { - [pa, i] = readPoint(svg, i); - [t1, i] = readFloat(svg, i); - [t2, i] = readFloat(svg, i); - [t3, i] = readFloat(svg, i); - [pb, i] = readPoint(svg, i); - // console.log("arc", pa.toString(), rad(t1), t2, t3, pb.toString()); - b.arcTo(pb, pa, rad(t1), !!t2, !!t3, cmd === "a"); - break; - } - case "z": - b.closePath(); - break; - default: - throw new Error(`unsupported segment type: ${c} @ pos ${i}`); - } - } - return b.paths; - } catch (e) { - throw e instanceof Error ? e : new Error(`illegal char '${svg.charAt(e)}' @ ${e}`); - } - } - - paths: Path2[]; - protected curr: Path2; - protected currP: Vec2; - protected bezierP: Vec2; - protected startP: Vec2; - - constructor() { - this.paths = []; - this.newPath(); - } - - *[Symbol.iterator]() { - yield* this.paths; - } - - newPath() { - this.curr = new Path2(); - this.paths.push(this.curr); - this.currP = new Vec2(); - this.bezierP = new Vec2(); - this.startP = new Vec2(); - } - - moveTo(p: Vec2, relative = false): PathBuilder { - if (this.curr.segments.length > 0) { - this.curr = new Path2(); - this.paths.push(this.curr); - } - p = this.updateCurrent(p, relative); - this.startP.set(p); - this.bezierP.set(p); - this.curr.add({ - point: p, - type: SegmentType.MOVE, - }); - return this; - } - - lineTo(p: Vec2, relative = false): PathBuilder { - this.curr.add({ - geo: new Line2([ - this.currP.copy(), - this.updateCurrent(p, relative) - ]), - type: SegmentType.LINE, - }); - this.bezierP.set(this.currP); - return this; - } - - hlineTo(x: number, relative = false): PathBuilder { - const prev = this.currP.copy(); - this.currP.x = relative ? this.currP.x + x : x; - this.bezierP.set(this.currP); - this.curr.add({ - geo: new Line2([prev, this.currP.copy()]), - type: SegmentType.LINE, - }); - return this; - } - - vlineTo(y: number, relative = false): PathBuilder { - const prev = this.currP.copy(); - this.currP.y = relative ? this.currP.y + y : y; - this.bezierP.set(this.currP); - this.curr.add({ - geo: new Line2([prev, this.currP.copy()]), - type: SegmentType.LINE, - }); - return this; - } - - cubicTo(cp1: Vec2, cp2: Vec2, p: Vec2, relative = false) { - const c2 = this.absPoint(cp2, relative); - this.bezierP.set(c2); - this.curr.add({ - geo: new Cubic2([ - this.currP.copy(), - this.absPoint(cp1, relative), - c2, - this.updateCurrent(p, relative), - ]), - type: SegmentType.CUBIC, - }); - return this; - } - - quadraticTo(cp: Vec2, p: Vec2, relative = false) { - const c1 = this.absPoint(cp, relative); - this.bezierP.set(c1); - this.curr.add({ - geo: new Quadratic2([ - this.currP.copy(), - c1, - this.updateCurrent(p, relative), - ]), - type: SegmentType.QUADRATIC, - }); - return this; - } - - cubicChainTo(cp2: Vec2, p: Vec2, relative = false) { - const prevMode = peek(this.curr.segments).type; - const c1 = this.currP.copy(); - if (prevMode === SegmentType.CUBIC) { - c1.add(c1.subNew(this.bezierP)); - } - const c2 = this.absPoint(cp2, relative); - this.bezierP.set(c2); - this.curr.add({ - geo: new Cubic2([ - this.currP.copy(), - c1, - c2, - this.updateCurrent(p, relative), - ]), - type: SegmentType.CUBIC, - }); - return this; - } - - quadraticChainTo(p: Vec2, relative = false) { - const prevMode = peek(this.curr.segments).type; - const c1 = this.currP.copy(); - if (prevMode === SegmentType.QUADRATIC) { - c1.mulN(2).sub(this.bezierP); - } - this.bezierP.set(c1); - this.curr.add({ - geo: new Quadratic2([ - this.currP.copy(), - c1, - this.updateCurrent(p, relative), - ]), - type: SegmentType.CUBIC, - }); - return this; - } - - arcTo(p: Vec2, r: Vec2, xaxis: number, xl: boolean, clockwise: boolean, relative = false) { - if (eqDelta(r.x, 0) || eqDelta(r.y, 0)) { - return this.lineTo(p, relative); - } - const prev = this.currP.copy(); - const arc = Arc2.from2Points(prev, this.updateCurrent(p, relative), r, xaxis, xl, clockwise); - this.curr.add({ - geo: arc, - type: SegmentType.ARC, - }); - this.bezierP.set(this.currP); - return this; - } - - closePath() { - this.curr.add({ - geo: new Line2([this.currP.copy(), this.startP.copy()]), - type: SegmentType.LINE, - }); - this.curr.closed = true; - return this; - } - - protected updateCurrent(p: Vec2, relative: boolean) { - p = (relative ? this.currP.add(p) : this.currP.set(p)).copy(); - return p; - } - - protected absPoint(p: Vec2, relative: boolean) { - return relative ? p.add(this.currP) : p; - } -} - -const readPoint = (src: string, index: number): [Vec2, number] => { - let x, y; - [x, index] = readFloat(src, index); - index = skipWS(src, index); - [y, index] = readFloat(src, index); - return [new Vec2([x, y]), index]; -}; - -const isWS = (c: string) => c === " " || c === "\n" || c === "\r" || c === "\t"; - -const skipWS = (src: string, i: number) => { - const n = src.length; - while (i < n && isWS(src.charAt(i))) i++; - return i; -}; - -const readFloat = (src: string, index: number) => { - index = skipWS(src, index); - let signOk = true; - let dotOk = true; - let expOk = false; - let commaOk = false; - let i = index; - for (let n = src.length; i < n; i++) { - const c = src.charAt(i); - // console.log("float", src.substring(index, i + 1)); - if ("0" <= c && c <= "9") { - expOk = true; - commaOk = true; - signOk = false; - continue; - } - if (c === "-" || c === "+") { - if (!signOk) break; - signOk = false; - continue; - } - if (c === ".") { - if (!dotOk) break; - dotOk = false; - continue; - } - if (c === "e") { - if (!expOk) throw i; - expOk = false; - dotOk = false; - signOk = true; - continue; - } - if (c === ",") { - if (!commaOk) throw i; - i++; - } - break; - } - if (i === index) { - throw new Error(`expected coordinate @ pos: ${i}`); - } - return [parseFloat(src.substring(index, i)), i]; -} diff --git a/packages/geom/src/polygon2.ts b/packages/geom/src/polygon2.ts deleted file mode 100644 index cd5b255c07..0000000000 --- a/packages/geom/src/polygon2.ts +++ /dev/null @@ -1,167 +0,0 @@ -import { ICopy, IToHiccup } from "@thi.ng/api"; -import { isNumber, isPlainObject } from "@thi.ng/checks"; -import { TAU } from "@thi.ng/math"; -import { - cycle, - map, - normRange, - push, - transduce, - tuples -} from "@thi.ng/transducers"; -import { - asVec2, - ReadonlyVec, - toCartesian2, - Vec, - Vec2 -} from "@thi.ng/vectors"; -import { - Attribs, - HiccupPolygon2, - IArcLength, - IArea, - IEdges, - IPointInside, - ITessellateable, - SamplingOpts, - SubdivKernel, - Tessellator -} from "./api"; -import { PointContainer2 } from "./container2"; -import { arcLength } from "./internal/arc-length"; -import { polygonArea } from "./internal/area"; -import { argsN } from "./internal/args"; -import { centerOfWeight, centroid } from "./internal/centroid"; -import { closestPointPolyline } from "./internal/closest-point"; -import { edges } from "./internal/edges"; -import { containsDelta } from "./internal/eq-delta"; -import { clipConvex } from "./internal/sutherland-hodgeman"; -import { Sampler } from "./sampler"; -import { subdivideCurve } from "./subdiv-curve"; -import { tessellate } from "./tessellate"; -import { simplifyPolyline } from "./internal/douglas–peucker"; - -export class Polygon2 extends PointContainer2 implements - IArcLength, - IArea, - ICopy, - IEdges, - IPointInside, - ITessellateable, - IToHiccup { - - static fromHiccup([_, attribs, pts]: HiccupPolygon2) { - return new Polygon2( - isNumber(pts[0]) ? - Vec2.mapBuffer(pts) : - (pts).map(asVec2), - attribs - ); - } - - static star(r: number, n: number, profile: number[]) { - const total = n * profile.length; - const pts = transduce( - map(([i, p]) => new Vec2(toCartesian2([r * p, i * TAU]))), - push(), - tuples(normRange(total, false), cycle(profile)) - ); - return new Polygon2(pts); - } - - copy() { - return new Polygon2(this._copy(), { ...this.attribs }); - } - - edges() { - return edges(this.points, true); - } - - area(signed = true) { - const area = polygonArea(this.points); - return signed ? area : Math.abs(area); - } - - arcLength() { - return arcLength(this.points, true); - } - - centroid(c?: Vec2): Vec2 { - return centerOfWeight(this.points, c); - } - - closestPoint(p: Readonly) { - return closestPointPolyline(p, this.points, true); - } - - pointInside(p: Readonly) { - const pts = this.points; - if (containsDelta(pts, p)) return true; - const px = p.x; - const py = p.y; - let inside = false; - for (let n = pts.length - 1, i = n, j = 0; j < n; i = j, j++) { - const [ax, ay] = pts[i]; - const [bx, by] = pts[j]; - (((by < py && ay >= py) || (ay < py && by >= py)) && - ((py - by) / (ay - by) * (ax - bx) + bx) < px) && - (inside = !inside); - } - return inside; - } - - simplify(eps: number) { - return new Polygon2(simplifyPolyline(this.points, eps, true), { ...this.attribs }); - } - - vertices(opts?: number | Partial) { - const sampler = new Sampler(this.points, true); - if (opts !== undefined) { - return isPlainObject(opts) ? - opts.dist ? - sampler.sampleUniform(opts.dist, opts.last) : - sampler.sampleFixedNum(opts.num, opts.last) : - sampler.sampleFixedNum(opts, false); - } else { - return this.points; - } - } - - clipConvex(boundary: Polygon2 | Vec2[]) { - let bpts, bc; - if (boundary instanceof Polygon2) { - bpts = boundary.points; - bc = boundary.centroid(); - } else { - bpts = boundary; - bc = centroid(bpts, new Vec2()); - } - return new Polygon2(clipConvex(this.points, bpts, bc), { ...this.attribs }); - } - - subdivide(kernel: SubdivKernel, iter = 1) { - return new Polygon2(subdivideCurve(kernel, this.points, iter, true), { ...this.attribs }); - } - - tessellate(tessel: Tessellator, iter?: number): Vec2[][]; - tessellate(tessel: Iterable>): Vec2[][]; - tessellate(...args: any[]) { - return tessellate.apply(null, [this.points, ...args]); - } - - toHiccup() { - return this._toHiccup("polygon"); - } - - toJSON() { - return this._toJSON("polygon2"); - } -} - -export function polygon2(points: Vec, num?: number, start?: number, cstride?: number, estride?: number, attribs?: Attribs): Polygon2; -export function polygon2(points: ReadonlyVec[], attribs?: Attribs): Polygon2; -export function polygon2(...args: any[]) { - const [points, attribs] = argsN(args); - return new Polygon2(points, attribs); -} diff --git a/packages/geom/src/polyline2.ts b/packages/geom/src/polyline2.ts deleted file mode 100644 index 552289fdee..0000000000 --- a/packages/geom/src/polyline2.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { ICopy, IToHiccup } from "@thi.ng/api"; -import { isPlainObject } from "@thi.ng/checks"; -import { map, partition } from "@thi.ng/transducers"; -import { ReadonlyVec, Vec, Vec2 } from "@thi.ng/vectors"; -import { - Attribs, - IArcLength, - IArea, - IEdges, - IToCubic, - IVertices, - SamplingOpts, - SubdivKernel -} from "./api"; -import { Cubic2 } from "./bezier2"; -import { PointContainer2 } from "./container2"; -import { arcLength } from "./internal/arc-length"; -import { argsN } from "./internal/args"; -import { closestPointPolyline } from "./internal/closest-point"; -import { edges } from "./internal/edges"; -import { Sampler } from "./sampler"; -import { subdivideCurve } from "./subdiv-curve"; - -export class Polyline2 extends PointContainer2 implements - IArcLength, - IArea, - ICopy, - IEdges, - IVertices>, - IToCubic, - IToHiccup { - - copy() { - return new Polyline2(this._copy(), { ...this.attribs }); - } - - edges() { - return edges(this.points); - } - - area() { - return 0; - } - - arcLength() { - return arcLength(this.points); - } - - closestPoint(p: Readonly) { - return closestPointPolyline(p, this.points, false); - } - - subdivide(kernel: SubdivKernel, iter = 1) { - return new Polyline2(subdivideCurve(kernel, this.points, iter, false), { ...this.attribs }); - } - - vertices(opts?: number | Partial) { - const sampler = new Sampler(this.points); - if (opts !== undefined) { - if (isPlainObject(opts)) { - return opts.dist ? - sampler.sampleUniform(opts.dist, opts.last !== false) : - sampler.sampleFixedNum(opts.num, opts.last !== false); - } - return sampler.sampleFixedNum(opts, true); - } else { - return this.points; - } - } - - toCubic() { - return map( - ([a, b]) => Cubic2.fromLine(a, b, { ...this.attribs }), - partition(2, 1, this.points) - ); - } - - toHiccup() { - return this._toHiccup("polyline"); - } - - toHiccupPathSegments() { - const res: any[] = []; - for (let pts = this.points, n = pts.length, i = 1; i < n; i++) { - res.push(["L", pts[i]]); - } - return res; - } - - toJSON() { - return this._toJSON("polyline2"); - } -} - -export function polyline2(points: Vec, num?: number, start?: number, cstride?: number, estride?: number, attribs?: Attribs): Polyline2; -export function polyline2(points: ReadonlyVec[], attribs?: Attribs): Polyline2; -export function polyline2(...args: any[]) { - const [points, attribs] = argsN(args); - return new Polyline2(points, attribs); -} diff --git a/packages/geom/src/quad2.ts b/packages/geom/src/quad2.ts deleted file mode 100644 index e5dfdaf6a8..0000000000 --- a/packages/geom/src/quad2.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { ICopy } from "@thi.ng/api"; -import { ReadonlyVec, Vec, Vec2 } from "@thi.ng/vectors"; -import { - Attribs, - IArcLength, - IArea, - IEdges, - IPointMap, - ITessellateable, - Tessellator -} from "./api"; -import { PointContainer2 } from "./container2"; -import { arcLength } from "./internal/arc-length"; -import { args4 } from "./internal/args"; -import { corner } from "./internal/corner"; -import { edges } from "./internal/edges"; -import { tessellate } from "./tessellate"; - -export class Quad2 extends PointContainer2 implements - IArea, - IArcLength, - ICopy, - IEdges, - IPointMap, - ITessellateable { - - copy() { - return new Quad2(this._copy(), { ...this.attribs }); - } - - arcLength() { - return arcLength(this.points, true); - } - - area(signed = true) { - const [a, b, c, d] = this.points; - const area = 0.5 * (corner(a, b, c) + corner(a, c, d)); - return signed ? area : Math.abs(area); - } - - edges() { - return edges(this.points, true); - } - - mapPoint(_: Readonly, __?: Vec2): Vec2 { - throw new Error("TODO"); - } - - unmapPoint(q: Readonly, out?: Vec2) { - const p = this.points; - const res = Vec2.mixBilinear(p[0], p[1], p[3], p[2], q.x, q.y); - return out ? out.set(res) : res; - } - - tessellate(tessel: Tessellator, iter?: number): Vec2[][]; - tessellate(tessel: Iterable>): Vec2[][]; - tessellate(...args: any[]) { - return tessellate.apply(null, [this.points, ...args]); - } - - toHiccup() { - return this._toHiccup("polygon"); - } - - toJSON() { - return this._toJSON("quad2"); - } -} - -export function quad2(points: Vec, start?: number, cstride?: number, estride?: number, attribs?: Attribs): Quad2; -export function quad2(a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, attribs?: Attribs): Quad2; -export function quad2(points: ReadonlyVec[], attribs?: Attribs): Quad2; -export function quad2(...args: any[]) { - const [points, attribs] = args4(args); - return new Quad2(points, attribs); -} diff --git a/packages/geom/src/rect2.ts b/packages/geom/src/rect2.ts deleted file mode 100644 index 12e6b5a21c..0000000000 --- a/packages/geom/src/rect2.ts +++ /dev/null @@ -1,198 +0,0 @@ -import { ICopy } from "@thi.ng/api"; -import { isArrayLike, isNumber, isPlainObject } from "@thi.ng/checks"; -import { asVec2, ReadonlyVec, Vec2 } from "@thi.ng/vectors"; -import { - Attribs, - CollateOpts, - IArcLength, - IArea, - IBounds, - IBoundsRaw, - ICenter, - ICentroid, - ICollate, - IPointInside, - IPointMap, - ITessellateable, - IVertices, - Tessellator -} from "./api"; -import { collateWith } from "./internal/collate"; -import { edges } from "./internal/edges"; -import { tessellate } from "./tessellate"; - -export class Rect2 implements - IArea, - IArcLength, - IBoundsRaw, - IBounds, - ICentroid, - ICenter, - ICollate, - ICopy, - IPointInside, - IPointMap, - ITessellateable, - IVertices { - - static fromMinMax(min: Vec2, max: Vec2) { - return new Rect2(min, max.subNew(min)); - } - - pos: Vec2; - size: Vec2; - attribs: Attribs; - - constructor(pos: Vec2, size: Vec2, attribs?: any) { - this.pos = pos; - this.size = size; - this.attribs = attribs; - } - - copy() { - const buf = Vec2.intoBuffer([], [this.pos, this.size]); - return new Rect2(new Vec2(buf, 0), new Vec2(buf, 2), { ...this.attribs }) - } - - collate(opts?: Partial) { - return collateWith(Vec2.intoBuffer, [this.pos, this.size], opts, 2); - } - - area() { - return this.size.x * this.size.y; - } - - arcLength() { - return 2 * (this.size.x + this.size.y); - } - - boundsRaw(): [Vec2, Vec2] { - return [this.pos.copy(), this.pos.addNew(this.size)]; - } - - bounds() { - return this; - } - - centroid(c?: Vec2) { - return this.pos.maddNewN(this.size, 0.5, c); - } - - center(origin?: Readonly) { - const d = this.centroid().neg(); - this.pos.add(origin ? d.add(origin) : d); - return this; - } - - pointInside(p: Readonly) { - const px = p.x; - const py = p.y; - const x1 = this.pos.x; - const y1 = this.pos.y; - const x2 = x1 + this.size.x; - const y2 = y1 + this.size.y; - return px >= x1 && px <= x2 && py >= y1 && py <= y2; - } - - mapPoint(p: Readonly, out?: Vec2) { - return p.subNew(this.pos, out).div(this.size); - } - - unmapPoint(p: Readonly, out?: Vec2) { - return (out ? out.set(this.pos) : this.pos.copy()).madd(this.size, p); - } - - tessellate(tessel: Tessellator, iter?: number): Vec2[][]; - tessellate(tessel: Iterable>): Vec2[][]; - tessellate(...args: any[]) { - return tessellate.apply(null, [this.vertices(), ...args]); - } - - scale(v: Readonly) { - this.pos.mul(v); - this.size.mul(v); - return this; - } - - scaleN(n: number) { - this.pos.mulN(n); - this.size.mulN(n); - return this; - } - - translate(v: Readonly) { - this.pos.add(v); - return this; - } - - union(r: Rect2) { - const p = this.pos.addNew(this.size); - const q = r.pos.addNew(r.size); - this.pos.min(r.pos); - this.size.set(p.max(q).sub(this.pos)); - return this; - } - - edges() { - return edges(this.vertices(), true); - } - - vertices() { - const [x, y] = this.pos; - const [w, h] = this.size; - return Vec2.mapBuffer([x, y, x + w, y, x + w, y + h, x, y + h], 4); - } - - toHiccup() { - return ["rect", this.attribs, this.pos, this.size.x, this.size.y]; - } - - toJSON() { - return { - type: "rect2", - pos: this.pos.toJSON(), - size: this.size.toJSON(), - }; - } -} - -export function rect2(x: number, y: number, w: number, h: number, attribs?: Attribs): Rect2; -export function rect2(x: number, y: number, w: number, attribs?: Attribs): Rect2; -export function rect2(w: number, h: number, attribs?: Attribs): Rect2; -export function rect2(pos: ReadonlyVec, w: number, attribs?: Attribs): Rect2; -export function rect2(pos: ReadonlyVec, size: ReadonlyVec, attribs?: Attribs): Rect2; -export function rect2(w: number, attribs?: Attribs): Rect2; -export function rect2(...args: any[]) { - let attribs; - let n = args.length - 1; - if (isPlainObject(args[n]) || args[n] == null) { - attribs = args[n]; - n--; - } - if (isArrayLike(args[0])) { - const size = args[1]; - return new Rect2( - asVec2(args[0]), - isNumber(size) ? - new Vec2([size, size]) : - asVec2(size), - attribs - ); - } - if (n > 1) { - return new Rect2( - new Vec2([args[0], args[1]]), - new Vec2( - n === 2 ? - [args[2], args[2]] : - [args[2], args[3]] - ), - attribs - ); - } - return new Rect2( - new Vec2([0, 0]), - new Vec2(n > 0 ? [args[0], args[1]] : [args[0], args[0]]), - attribs - ); -}; diff --git a/packages/geom/src/sampler.ts b/packages/geom/src/sampler.ts deleted file mode 100644 index df343220e5..0000000000 --- a/packages/geom/src/sampler.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { peek } from "@thi.ng/transducers"; -import { IVector } from "@thi.ng/vectors"; - -export class Sampler> { - - points: T[]; - index: number[]; - - constructor(points: ReadonlyArray, closed = false) { - if (closed) { - this.points = points.slice(); - this.points.push(points[0]); - } else { - this.points = points; - } - this.buildIndex(); - } - - pointAt(t: number) { - const pts = this.points; - const n = pts.length - 1; - if (n < 0) { - return; - } - if (n === 0 || t <= 0) { - return pts[0]; - } - if (t >= 1) { - return pts[n]; - } - const idx = this.index; - const t0 = t * idx[n]; - for (let i = 1; i <= n; i++) { - if (idx[i] >= t0) { - return pts[i - 1].mixNewN(pts[i], (t0 - idx[i - 1]) / (idx[i] - idx[i - 1])); - } - } - } - - sampleUniform(dist: number, includeLast = false, result: T[] = []) { - const index = this.index; - const total = peek(index); - const delta = dist / total; - const n = index.length; - for (let t = 0, i = 1; t < 1; t += delta) { - const ct = t * total; - while (ct >= index[i] && i < n) { i++; } - if (i >= n) break; - const p = index[i - 1]; - result.push(this.points[i - 1].mixNewN(this.points[i], (ct - p) / (index[i] - p))); - } - if (includeLast) { - result.push(this.points[this.points.length - 1].copy()); - } - return result; - } - - sampleFixedNum(num: number, includeLast = false, result?: T[]) { - return this.sampleUniform(peek(this.index) / num, includeLast, result); - } - - protected buildIndex() { - const idx: number[] = [0]; - const pts = this.points; - const n = pts.length; - for (let i = 0, j = 1; j < n; i = j, j++) { - idx[j] = idx[i] + pts[i].dist(pts[j]); - } - this.index = idx; - } -} diff --git a/packages/geom/src/subdiv-curve.ts b/packages/geom/src/subdiv-curve.ts deleted file mode 100644 index 4b8c36edc9..0000000000 --- a/packages/geom/src/subdiv-curve.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { - comp, - indexed, - mapcat, - partition, - push, - transduce, - wrap -} from "@thi.ng/transducers"; -import { IVector } from "@thi.ng/vectors"; -import { SubdivKernel } from "./api"; - -const madd2 = - > - (a: Readonly, b: Readonly, ua: number, ub: number) => - a.mulNewN(ua).maddN(b, ub); - -const madd3 = - > - (a: Readonly, b: Readonly, c: Readonly, ua: number, ub: number, uc: number) => - a.mulNewN(ua).maddN(b, ub).maddN(c, uc); - -const madd5 = - > - (a: Readonly, b: Readonly, c: Readonly, d: Readonly, e: Readonly, - ua: number, ub: number, uc: number, ud: number, ue: number) => - a.mulNewN(ua).maddN(b, ub).maddN(c, uc).maddN(d, ud).maddN(e, ue); - -export const subdivKernel2 = - ([ua, ub]: number[], [va, vb]: number[]) => - >([a, b]: T[]) => [ - madd2(a, b, ua, ub), - madd2(a, b, va, vb), - ]; - -export const subdivKernel3 = - ([ua, ub, uc]: number[], [va, vb, vc]: number[]) => - >([a, b, c]: T[]) => [ - madd3(a, b, c, ua, ub, uc), - madd3(a, b, c, va, vb, vc), - ]; - -export const subdivKernel5 = - ([ua, ub, uc, ud, ue]: number[], [va, vb, vc, vd, ve]: number[]) => - >([a, b, c, d, e]: T[]) => [ - madd5(a, b, c, d, e, ua, ub, uc, ud, ue), - madd5(a, b, c, d, e, va, vb, vc, vd, ve), - ]; - -/** - * http://algorithmicbotany.org/papers/subgpu.sig2003.pdf - * - * @param kernel subdivision scheme - * @param pts source points - * @param iter number of iterations - * @param closed true, if closed input geometry - */ -export const subdivideCurve = - >( - { fn, size }: SubdivKernel, - pts: T[], - iter = 1, - closed = false) => { - - while (--iter >= 0) { - const nump = pts.length; - pts = transduce( - comp( - partition(size, 1), - indexed(), - mapcat(([i, pts]) => fn(pts, i, nump)) - ), - push(), - closed ? - wrap(pts, size >> 1, true, true) : - pts - ); - } - return pts; - }; - -const CHAIKIN_FIRST = subdivKernel3([1 / 2, 1 / 2, 0], [0, 3 / 4, 1 / 4]); -const CHAIKIN_MAIN = subdivKernel3([1 / 4, 3 / 4, 0], [0, 3 / 4, 1 / 4]); -const CHAIKIN_LAST = subdivKernel3([1 / 4, 3 / 4, 0], [0, 1 / 2, 1 / 2]); - -const CUBIC_MAIN = subdivKernel3([1 / 8, 3 / 4, 1 / 8], [0, 1 / 2, 1 / 2]); - -export const CHAIKIN_CLOSED: SubdivKernel = { - fn: CHAIKIN_MAIN, - size: 3 -}; - -export const CHAIKIN_OPEN: SubdivKernel = { - fn: (pts, i, n) => - i == 0 ? - [pts[0], ...CHAIKIN_FIRST(pts)] : - i === n - 3 ? - [...CHAIKIN_LAST(pts), pts[2]] : - CHAIKIN_MAIN(pts), - size: 3 -}; - -export const CUBIC_CLOSED: SubdivKernel = { - fn: CUBIC_MAIN, - size: 3 -}; diff --git a/packages/geom/src/tessellate.ts b/packages/geom/src/tessellate.ts deleted file mode 100644 index 78be1ab2c3..0000000000 --- a/packages/geom/src/tessellate.ts +++ /dev/null @@ -1,165 +0,0 @@ -import { isFunction } from "@thi.ng/checks"; -import { - comp, - last, - map, - mapcat, - partition, - push, - range, - reducer, - repeat, - scan, - transduce, - tuples, - wrap -} from "@thi.ng/transducers"; -import { IVector, Vec2 } from "@thi.ng/vectors"; -import { Tessellator } from "./api"; -import { polygonArea } from "./internal/area"; -import { centroid } from "./internal/centroid"; -import { corner, pointInTriangle2 } from "./internal/corner"; - -const snip = (points: ReadonlyArray, u: number, v: number, w: number, n: number, ids: number[]) => { - const a = points[ids[u]]; - const b = points[ids[v]]; - const c = points[ids[w]]; - if (corner(a, b, c) > 0) { - for (let i = 0; i < n; i++) { - if (i !== u && i !== v && i !== w) { - if (pointInTriangle2(points[ids[i]], a, b, c)) { - return; - } - } - } - return [a, b, c]; - } -}; - -export const earCut = (points: ReadonlyArray) => { - const tris: Vec2[][] = []; - let n = points.length; - const ids = [ - ...(polygonArea(points) > 0 ? - range(n) : - range(n - 1, -1, -1)) - ]; - let count = 2 * n - 1; - let v = n - 1, u, w, t; - while (count > 0 && n > 2) { - u = n <= v ? 0 : v; - v = u + 1; - v = n <= v ? 0 : v; - w = v + 1; - w = n <= w ? 0 : w; - t = snip(points, u, v, w, n, ids); - if (t !== undefined) { - tris.push(t); - ids.splice(v, 1); - n--; - count = 2 * n; - } else { - count--; - } - } - return tris; -}; - -export const triFan = >(points: ReadonlyArray) => { - const c = centroid(points); - return transduce( - comp( - partition(2, 1), - map(([a, b]) => [a, b, c]) - ), - push(), - wrap(points, 1, false, true) - ); -}; - -export const quadFan = >(points: ReadonlyArray) => { - const p = centroid(points); - return transduce( - comp( - partition(3, 1), - map(([a, b, c]) => [a.mixNewN(b, 0.5), b, b.mixNewN(c, 0.5), p]) - ), - push(), - wrap(points, 1, true, true) - ); -}; - -export const edgeSplit = >(points: ReadonlyArray) => { - const c = centroid(points); - return transduce( - comp( - partition(2, 1), - mapcat(([a, b]) => { - const m = a.mixNewN(b, 0.5); - return [[a, m, c], [m, b, c]]; - })), - push(), - wrap(points, 1, false, true) - ); -}; - -export const rimTris = >(points: ReadonlyArray) => { - const edgeCentroids = transduce( - comp( - partition(2, 1), - map((e) => e[0].mixNewN(e[1], 0.5)) - ), - push(), - wrap(points, 1, false, true) - ); - return transduce( - comp( - partition(2, 1), - map((t) => [t[0][0], t[1][1], t[1][0]]) - ), - push(), - [edgeCentroids], - wrap([...tuples(edgeCentroids, points)], 1, true, false) - ); -}; - -export const inset = (inset = 0.5, keepInterior = false) => - >(points: ReadonlyArray) => { - const c = centroid(points); - const inner = points.map((p) => p.mixNewN(c, inset)); - return transduce( - comp( - partition(2, 1), - map(([[a, b], [c, d]]) => [a, b, d, c]) - ), - push(), - keepInterior ? [inner] : [], - wrap([...tuples(points, inner)], 1, false, true) - ); - }; - -export function tessellate>(points: T[], tessFn: Tessellator, iter?: number): T[][]; -export function tessellate>(points: T[], tessFns: Iterable>): T[][]; -export function tessellate>(...args): T[][] { - return transduce( - scan( - reducer( - () => [args[0]], - (acc: T[][], fn: Tessellator) => - transduce( - mapcat(fn), - push(), - acc - ) - ) - ), - last(), - isFunction(args[1]) ? - repeat(args[1], args[2] || 1) : - args[1] - ); -} - -/* -v=require("@thi.ng/vectors"); g=require("@thi.ng/geom"); h=require("@thi.ng/hiccup"); svg=require("@thi.ng/hiccup-svg"); s=require("@thi.ng/strings"); tx=require("@thi.ng/transducers"); fs=require("fs"); -*/ \ No newline at end of file diff --git a/packages/geom/src/triangle2.ts b/packages/geom/src/triangle2.ts deleted file mode 100644 index 0b7f1e1d16..0000000000 --- a/packages/geom/src/triangle2.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { ICopy } from "@thi.ng/api"; -import { PI } from "@thi.ng/math"; -import { - ReadonlyVec, - Vec, - Vec2, - Vec3 -} from "@thi.ng/vectors"; -import { - Attribs, - IArcLength, - IArea, - IClassifyPoint, - IPointInside, - IPointMap, - ITessellateable, - Tessellator -} from "./api"; -import { PointContainer2 } from "./container2"; -import { arcLength } from "./internal/arc-length"; -import { args3 } from "./internal/args"; -import { fromBarycentric, toBarycentric } from "./internal/barycentric"; -import { classifyPointInTriangle2, corner, pointInTriangle2 } from "./internal/corner"; -import { tessellate } from "./tessellate"; - -export class Triangle2 extends PointContainer2 implements - IArea, - IArcLength, - IClassifyPoint, - ICopy, - IPointInside, - IPointMap, - ITessellateable { - - static equilateral(a: Vec2, b: Vec2) { - const dir = b.subNew(a); - const c = dir.perpendicularLeft().normalize(dir.mag() * Math.sin(PI / 3)); - return new Triangle2([a, b, c.maddN(dir, 0.5)]); - } - - copy() { - return new Triangle2(this._copy(), { ...this.attribs }); - } - - classifyPoint(p: Readonly): number { - const [a, b, c] = this.points; - return classifyPointInTriangle2(p, a, b, c); - } - - pointInside(p: Readonly): boolean { - const [a, b, c] = this.points; - return pointInTriangle2(p, a, b, c); - } - - arcLength(): number { - return arcLength(this.points, true); - } - - area(signed = true) { - const [a, b, c] = this.points; - const area = 0.5 * corner(a, b, c); - return signed ? area : Math.abs(area); - } - - mapPoint(p: Readonly, out?: Vec3): Vec3 { - const [a, b, c] = this.points; - return toBarycentric(a, b, c, p, out); - } - - unmapPoint(p: Readonly, out?: Vec2): Vec2 { - const [a, b, c] = this.points; - return fromBarycentric(a, b, c, p, out); - } - - tessellate(tessel: Tessellator, iter?: number): Vec2[][]; - tessellate(tessel: Iterable>): Vec2[][]; - tessellate(...args: any[]) { - return tessellate.apply(null, [this.points, ...args]); - } - - toHiccup() { - return this._toHiccup("polygon"); - } - - toJSON() { - return this._toJSON("triangle2"); - } -} - -export function triangle2(points: Vec, start?: number, cstride?: number, estride?: number, attribs?: Attribs): Triangle2; -export function triangle2(a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, attribs?: Attribs): Triangle2; -export function triangle2(points: ReadonlyVec[], attribs?: Attribs): Triangle2; -export function triangle2(...args: any[]) { - const [points, attribs] = args3(args); - return new Triangle2(points, attribs); -} \ No newline at end of file diff --git a/packages/geom/src/warp.ts b/packages/geom/src/warp.ts deleted file mode 100644 index 6628ae86b9..0000000000 --- a/packages/geom/src/warp.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { IVector } from "@thi.ng/vectors"; -import { IPointMap } from "./api"; - -export const warpPoints = < - V extends IVector, - V2 extends IVector, - A extends IPointMap, - B extends IPointMap ->(dest: B, src: ReadonlyArray, srcBounds: A) => { - const res: V[] = []; - for (let n = src.length, i = 0; i < n; i++) { - res.push(dest.unmapPoint(srcBounds.mapPoint(src[i]))); - } - return res; -}; diff --git a/packages/geom/test/circle2.ts b/packages/geom/test/circle2.ts deleted file mode 100644 index d5f877c2f9..0000000000 --- a/packages/geom/test/circle2.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { equiv } from "@thi.ng/equiv"; -import { HALF_PI, PI, TAU } from "@thi.ng/math"; -import { eqDelta2array, vec2 } from "@thi.ng/vectors"; -import * as assert from "assert"; -import { circle2, Circle2, HiccupCircle2 } from "../src"; - -describe("circle2", () => { - - it("ctor1", () => { - const c = circle2(10, 20); - assert(c instanceof Circle2); - assert(equiv(c.pos, [10, 20])); - assert.equal(c.r, 1); - assert.strictEqual(c.attribs, undefined); - }); - - it("ctor2", () => { - const c = circle2(10, 20, 5); - assert(equiv(c.pos, [10, 20])); - assert.equal(c.r, 5); - assert.strictEqual(c.attribs, undefined); - }); - - it("ctor3", () => { - const c = circle2(10, 20, 5, { a: 1 }); - assert(equiv(c.pos, [10, 20])); - assert.equal(c.r, 5); - assert.deepEqual(c.attribs, { a: 1 }); - }); - - it("ctor4", () => { - const c = circle2(vec2(10, 20)); - assert(equiv(c.pos, [10, 20])); - assert.equal(c.r, 1); - assert.strictEqual(c.attribs, undefined); - }); - - it("ctor5", () => { - const c = circle2(vec2(10, 20), 5); - assert(equiv(c.pos, [10, 20])); - assert.equal(c.r, 5); - assert.strictEqual(c.attribs, undefined); - }); - - it("ctor6", () => { - const c = circle2(vec2(10, 20), { a: 1 }); - assert(equiv(c.pos, [10, 20])); - assert.equal(c.r, 1); - assert.deepEqual(c.attribs, { a: 1 }); - }); - - - it("ctor7", () => { - const c = circle2(vec2(10, 20), 5, { a: 1 }); - assert(equiv(c.pos, [10, 20])); - assert.equal(c.r, 5); - assert.deepEqual(c.attribs, { a: 1 }); - }); - - it("ctor8", () => { - const c = circle2(5); - assert(equiv(c.pos, [0, 0])); - assert.equal(c.r, 5); - assert.strictEqual(c.attribs, undefined); - }); - - it("ctor9", () => { - const c = circle2(5, { a: 1 }); - assert(equiv(c.pos, [0, 0])); - assert.equal(c.r, 5); - assert.deepEqual(c.attribs, { a: 1 }); - }); - - it("hiccup", () => { - const src: HiccupCircle2 = ["circle", { a: 1 }, [10, 20], 5]; - const c = Circle2.fromHiccup(src); - assert(equiv(c.pos, [10, 20])); - assert.equal(c.r, 5); - assert.deepEqual(c.attribs, { a: 1 }); - assert(equiv(c.toHiccup(), src)); - }); - - it("area", () => { - assert.equal(circle2(10).area(), PI * 100); - }); - - it("arclength", () => { - assert.equal(circle2(10).arcLength(), TAU * 10); - }); - - it("vertices (num)", () => { - assert(eqDelta2array( - circle2(10).vertices(4), - [[10, 0], [0, 10], [-10, 0], [0, -10]] - )) - }); - - it("vertices ({ num })", () => { - assert(eqDelta2array( - circle2(10).vertices({ num: 4 }), - [[10, 0], [0, 10], [-10, 0], [0, -10]] - )) - }); - - it("vertices ({ num, last: true })", () => { - assert(eqDelta2array( - circle2(10).vertices({ num: 4, last: true }), - [[10, 0], [0, 10], [-10, 0], [0, -10], [10, 0]] - )) - }); - - it("vertices ({ theta })", () => { - assert(eqDelta2array( - circle2(10).vertices({ theta: HALF_PI }), - [[10, 0], [0, 10], [-10, 0], [0, -10]] - )) - }); - - it("vertices ({ dist })", () => { - assert(eqDelta2array( - circle2(10).vertices({ dist: TAU * 10 / 4 }), - [[10, 0], [0, 10], [-10, 0], [0, -10]] - )) - }); -}); diff --git a/packages/geom3/test/index.ts b/packages/geom/test/index.ts similarity index 80% rename from packages/geom3/test/index.ts rename to packages/geom/test/index.ts index b3cc7672bc..f5862820cb 100644 --- a/packages/geom3/test/index.ts +++ b/packages/geom/test/index.ts @@ -1,6 +1,6 @@ // import * as assert from "assert"; // import * as g from "../src/index"; -describe("geom3", () => { +describe("geom", () => { it("tests pending"); }); diff --git a/packages/geom/test/poly2.ts b/packages/geom/test/poly2.ts deleted file mode 100644 index 292b81f86e..0000000000 --- a/packages/geom/test/poly2.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { equiv } from "@thi.ng/equiv"; -import * as assert from "assert"; -import { polygon2, Polygon2, HiccupPolygon2 } from "../src/index"; - -describe("polygon2", () => { - - it("area", () => { - const a = polygon2([0, 0, 100, 0, 100, 100, 0, 100]); - assert.equal(a.area(), 100 * 100); - a.points.pop() - assert.equal(a.area(), 100 * 100 / 2); - }); - - it("circumference", () => { - const a = polygon2([0, 0, 100, 0, 100, 100, 0, 100]); - assert.equal(a.arcLength(), 400); - a.points.pop() - assert.equal(a.arcLength(), 200 + Math.sqrt(2) * 100); - }); - - it("hiccup", () => { - const src: HiccupPolygon2 = ["polygon", { fill: "red" }, [[0, 0], [100, 0], [100, 100], [0, 100]]]; - const src2: HiccupPolygon2 = ["polygon", { fill: "red" }, [0, 0, 100, 0, 100, 100, 0, 100]]; - let a = Polygon2.fromHiccup(src); - assert(equiv(a.points, src[2])); - assert.deepEqual(a.attribs, src[1]); - a = Polygon2.fromHiccup(src2); - assert(equiv(a.points, src[2])); - assert.deepEqual(a.attribs, src2[1]); - assert( - equiv( - a.toHiccup(), - src - ) - ); - }); -}); diff --git a/packages/geom/test/tsconfig.json b/packages/geom/test/tsconfig.json index 2c9c12a650..f6e63560dd 100644 --- a/packages/geom/test/tsconfig.json +++ b/packages/geom/test/tsconfig.json @@ -2,10 +2,10 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "../build", - "module": "commonjs", + "module": "commonjs" }, "include": [ "./**/*.ts", "../src/**/*.ts" ] -} \ No newline at end of file +} diff --git a/packages/geom/tsconfig.json b/packages/geom/tsconfig.json index bcf03f18b4..faed4e5fe7 100644 --- a/packages/geom/tsconfig.json +++ b/packages/geom/tsconfig.json @@ -3,7 +3,8 @@ "compilerOptions": { "outDir": ".", "module": "es6", - "target": "es6" + "target": "es6", + "preserveConstEnums": false }, "include": [ "./src/**/*.ts" diff --git a/packages/geom3/.npmignore b/packages/geom3/.npmignore deleted file mode 100644 index 67d0c55714..0000000000 --- a/packages/geom3/.npmignore +++ /dev/null @@ -1,13 +0,0 @@ -.cache -.meta -.nyc_output -*.gz -*.html -*.tgz -build -coverage -dev -doc -src* -test -tsconfig.json diff --git a/packages/geom3/LICENSE b/packages/geom3/LICENSE deleted file mode 100644 index 8dada3edaf..0000000000 --- a/packages/geom3/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/packages/geom3/README.md b/packages/geom3/README.md deleted file mode 100644 index 5333c8241a..0000000000 --- a/packages/geom3/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# @thi.ng/geom3 - -[![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/geom3.svg)](https://www.npmjs.com/package/@thi.ng/geom3) -![npm downloads](https://img.shields.io/npm/dm/@thi.ng/geom3.svg) -[![Twitter Follow](https://img.shields.io/twitter/follow/thing_umbrella.svg?style=flat-square&label=twitter)](https://twitter.com/thing_umbrella) - -This project is part of the -[@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo. - - - -- [About](#about) -- [Installation](#installation) -- [Dependencies](#dependencies) -- [Usage examples](#usage-examples) -- [Authors](#authors) -- [License](#license) - - - -## About - -Temporary WIP refactoring of -[@thi.ng/geom](https://github.com/thi-ng/umbrella/tree/master/packages/geom), -based on multi-methods -([@thi.ng/defmulti](https://github.com/thi-ng/umbrella/tree/master/packages/defmulti)). - -[up-to-date feature matrix spreadsheet](https://docs.google.com/spreadsheets/d/1GxJm-zOQaGECui2MJUmy3gQPTF-T6BJ6vhNlUnPsmDs/edit?usp=sharing) - -## Installation - -```bash -yarn add @thi.ng/geom3 -``` - -## Dependencies - -- TODO... - -## Usage examples - -```ts -import * as g from "@thi.ng/geom3"; -``` - -## Authors - -- Karsten Schmidt - -## License - -© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/packages/geom3/package.json b/packages/geom3/package.json deleted file mode 100644 index 356cbbf7df..0000000000 --- a/packages/geom3/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "@thi.ng/geom3", - "version": "0.0.1", - "description": "TODO", - "module": "./index.js", - "main": "./lib/index.js", - "umd:main": "./lib/index.umd.js", - "typings": "./index.d.ts", - "repository": { - "type": "git", - "url": "https://github.com/thi-ng/umbrella.git" - }, - "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/geom3", - "author": "Karsten Schmidt ", - "license": "Apache-2.0", - "scripts": { - "build": "yarn clean && yarn build:es6 && yarn build:bundle", - "build:es6": "tsc --declaration", - "build:bundle": "../../scripts/bundle-module geom3 api checks compose defmulti equiv errors hiccup hiccup-svg math matrices random transducers vectors3", - "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", - "cover": "yarn test && nyc report --reporter=lcov", - "doc": "node_modules/.bin/typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public" - }, - "devDependencies": { - "@types/mocha": "^5.2.5", - "@types/node": "^10.12.15", - "mocha": "^5.2.0", - "nyc": "^13.1.0", - "typedoc": "^0.14.0", - "typescript": "^3.2.2" - }, - "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/compose": "^0.3.0", - "@thi.ng/defmulti": "^0.7.0", - "@thi.ng/equiv": "^0.1.15", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/hiccup": "^2.7.2", - "@thi.ng/hiccup-svg": "^2.0.10", - "@thi.ng/math": "^0.2.2", - "@thi.ng/matrices": "^0.0.1", - "@thi.ng/random": "^0.1.1", - "@thi.ng/transducers": "^2.3.2", - "@thi.ng/vectors3": "^0.0.1" - }, - "keywords": [ - "ES6", - "typescript" - ], - "publishConfig": { - "access": "public" - }, - "sideEffects": false -} \ No newline at end of file diff --git a/packages/geom3/src/api.ts b/packages/geom3/src/api.ts deleted file mode 100644 index 70df05131a..0000000000 --- a/packages/geom3/src/api.ts +++ /dev/null @@ -1,703 +0,0 @@ -import { ICopy, IObjectOf, IToHiccup } from "@thi.ng/api"; -import { isNumber } from "@thi.ng/checks"; -import { equiv } from "@thi.ng/equiv"; -import { illegalState } from "@thi.ng/errors"; -import { - add2, - add3, - maddN2, - ReadonlyVec, - set, - Vec -} from "@thi.ng/vectors3"; -import { arcPointAt, arcPointAtTheta } from "./internal/arc-point"; -import { copyPoints } from "./internal/copy-points"; - -export const enum SegmentType { - MOVE, - LINE, - POLYLINE, - ARC, - CUBIC, - QUADRATIC, - CLOSE, -} - -export const enum Type { - AABB = 1, - ARC, - CIRCLE, - CUBIC, - CUBIC3, - ELLIPSE, - GROUP, - LINE, - LINE3, - PATH, - POINTS, - POINTS3, - POLYGON, - POLYGON3, - POLYLINE, - POLYLINE3, - QUAD, - QUAD3, - QUADRATIC, - QUADRATIC3, - RECT, - SPHERE, - TRIANGLE, - TRIANGLE3, - RAY, - RAY3, -} - -export const enum IntersectionType { - NONE, - PARALLEL, - COINCIDENT, - COINCIDENT_NO_INTERSECT, - INTERSECT, - INTERSECT_OUTSIDE, -} - -export const DEFAULT_SAMPLES = 20; - -export type Attribs = IObjectOf; - -export type Tessellator = (points: Vec[]) => Vec[][]; - -export type VecPair = [Vec, Vec]; - -export interface IShape extends - ICopy { - - readonly type: number | string; - attribs?: Attribs; -} - -export interface AABBLike extends IShape { - pos: Vec; - size: Vec; - - max(): Vec; -} - -export interface IHiccupShape extends IShape, IToHiccup { } - -export interface IHiccupPathSegment { - toHiccupPathSegments(): any[]; -} - -export interface IntersectionResult { - type: IntersectionType; -} - -export interface LineIntersection extends IntersectionResult { - isec?: Vec; - det?: number; - alpha?: number; - beta?: number; -} - -export interface PathSegment { - type: SegmentType; - point?: Vec; - geo?: IShape & IHiccupPathSegment; -} - -export interface PCLike extends IShape { - points: Vec[]; -} - -export interface PCLikeConstructor { - new(pts: Vec[], attribs: Attribs): PCLike; -} - -export interface SamplingOpts { - /** - * Number of points to sample & return. Defaults to the implementing - * type's `DEFAULT_RES` if neither this nor `theta` option is given - * (see `ArcSamplingOpts`). - */ - num: number; - /** - * Approximate desired distance between sampled result points. If - * given, takes priority over the `num` option, but the latter MIGHT - * be used as part of the sampling process (implementation - * specific). Note: For circles this value is interpreted as arc - * length, not cartesian distance (error will be proportional to the - * given value relative to the circle's radius). - */ - dist: number; - /** - * Currently only used by these types: - * - * - Arc - * - Circle - * - * Defines the target angle between sampled points. If greater than - * the actual range of the arc, only the two end points will be - * returned at most. This option is used to derive a `num` value and - * takes priority if `num` is given as well. - * - * This option is useful to adapt the sampling based on angular - * resolution, rather than a fixed number of samples. - */ - theta: number; - /** - * If `true`, the shape's end point will be included in the result - * array. The default setting for open geometries is `true`, for - * closed ones `false`. This option has no influence on any internal - * resolution calculation. - * - * For open geometry this option is useful to when re-sampling paths - * of consecutive segments, where the end points of each segment - * coincide with the start points of the next segment. For all but - * the last segment, this option should be `false` and so can be - * used to avoid duplicate vertices in the concatenated result. - * - * When sampling closed shapes, enabling this option will include an - * extra point (start), i.e. if the `num` option was given, results - * in `num+1` points. - */ - last: boolean; -} - -export interface SubdivKernel { - fn: (pts: ReadonlyVec[], i: number, nump: number) => Vec[]; - iter?: (pts: ReadonlyVec[]) => Iterable; - size: number; -} - -export abstract class APC implements - PCLike { - - points: Vec[]; - attribs: Attribs; - - constructor(points: Vec[], attribs?: Attribs) { - this.points = points; - this.attribs = attribs; - } - - abstract get type(): number | string; - abstract copy(): IShape; - - *[Symbol.iterator]() { - yield* this.points; - } -} - -export class AABB implements - AABBLike { - - pos: Vec; - size: Vec; - attribs: Attribs; - - constructor(pos: Vec = [0, 0, 0], size: Vec = [1, 1, 1], attribs?: Attribs) { - this.pos = pos; - this.size = size; - this.attribs = attribs; - } - - get type() { - return Type.AABB; - } - - copy() { - return new AABB(set([], this.pos), set([], this.size), { ...this.attribs }); - } - - max() { - return add3([], this.pos, this.size); - } -} - - -export class Arc implements - IHiccupShape, - IHiccupPathSegment { - - pos: Vec; - r: Vec; - start: number; - end: number; - axis: number; - xl: boolean; - cw: boolean; - attribs: Attribs; - - constructor( - pos: Vec, - r: Vec, - axis: number, - start: number, - end: number, - xl = false, - cw = false, - attribs?: Attribs) { - - this.pos = pos; - this.r = r; - this.axis = axis; - this.start = start; - this.end = end; - this.xl = xl; - this.cw = cw; - this.attribs = attribs; - } - - get type() { - return Type.ARC; - } - - copy() { - return new Arc( - set([], this.pos), - set([], this.r), - this.axis, - this.start, - this.end, - this.xl, - this.cw, - { ...this.attribs } - ); - } - - equiv(o: any) { - return o instanceof Arc && - equiv(this.pos, o.pos) && - equiv(this.r, o.r) && - this.start === o.start && - this.end === o.end && - this.axis === o.axis && - this.xl === o.xl && - this.cw && o.cw; - } - - pointAt(t: number, out: Vec = []) { - return arcPointAt(this.pos, this.r, this.axis, this.start, this.end, t, out); - } - - pointAtTheta(theta: number, out: Vec = []) { - return arcPointAtTheta(this.pos, this.r, this.axis, theta, out); - } - - toHiccup() { - return ["path", this.attribs, [ - ["M", this.pointAt(0)], - ...this.toHiccupPathSegments() - ]]; - } - - toHiccupPathSegments() { - return [ - [ - "A", - this.r[0], - this.r[1], - this.axis, - this.xl, - this.cw, - this.pointAt(1) - ] - ]; - } -} - -export class Circle implements - IHiccupShape { - - pos: Vec; - r: number; - attribs: Attribs; - - constructor(pos: Vec = [0, 0], r = 1, attribs?: Attribs) { - this.pos = pos; - this.r = r; - this.attribs = attribs; - } - - get type() { - return Type.CIRCLE; - } - - copy() { - return new Circle(set([], this.pos), this.r, { ...this.attribs }); - } - - toHiccup() { - return ["circle", this.attribs, this.pos, this.r]; - } -} - -export class Cubic extends APC implements - IHiccupPathSegment { - - get type() { - return Type.CUBIC; - } - - copy() { - return new Cubic(copyPoints(this.points), { ...this.attribs }); - } - - toHiccup() { - return ["path", this.attribs, - [ - ["M", this.points[0]], - ...this.toHiccupPathSegments() - ] - ]; - } - - toHiccupPathSegments() { - const pts = this.points; - return [["C", pts[1], pts[2], pts[3]]]; - } -} - -export class Ellipse implements - IHiccupShape { - - pos: Vec; - r: Vec; - attribs: Attribs; - - constructor(pos: Vec = [0, 0], r: number | Vec = [1, 1], attribs?: Attribs) { - this.pos = pos; - this.r = isNumber(r) ? [r, r] : r; - this.attribs = attribs; - } - - get type() { - return Type.ELLIPSE; - } - - copy() { - return new Ellipse(set([], this.pos), set([], this.r), { ...this.attribs }); - } - - toHiccup() { - return ["ellipse", this.attribs, this.pos, this.r]; - } -} - -export class Group implements - IHiccupShape { - - children: IHiccupShape[]; - attribs: Attribs; - - constructor(children: IHiccupShape[], attribs?: Attribs) { - this.children = children; - this.attribs = attribs; - } - - get type() { - return Type.GROUP; - } - - *[Symbol.iterator]() { - yield* this.children; - } - - copy() { - return new Group( - this.children.map((c) => c.copy()), - { ...this.attribs } - ); - } - - equiv(o: any) { - return o instanceof Group && - equiv(this.children, o.children); - } - - toHiccup() { - return ["g", this.attribs, ...this.children.map((x) => x.toHiccup())]; - } -} - -export class Line extends APC implements - IHiccupShape, - IHiccupPathSegment { - - get type() { - return Type.LINE; - } - - copy() { - return new Line(copyPoints(this.points), { ...this.attribs }); - } - - toHiccup() { - return ["line", this.attribs, this.points[0], this.points[1]]; - } - - toHiccupPathSegments() { - const [a, b] = this.points; - return [ - a[0] === b[0] ? - ["V", b[1]] : - a[1] === b[1] ? - ["H", b[0]] : - ["L", b] - ]; - } -} - -export class Path implements - IHiccupShape { - - segments: PathSegment[]; - closed: boolean; - attribs: Attribs; - - constructor(segments?: PathSegment[], attribs?: Attribs) { - this.segments = segments || []; - this.attribs = attribs; - this.closed = false; - } - - get type() { - return Type.PATH; - } - - *[Symbol.iterator]() { - yield* this.segments; - } - - copy() { - const p = new Path([...this.segments], { ...this.attribs }); - p.closed = this.closed; - return p; - } - - equiv(o: any) { - return o instanceof Path && - equiv(this.segments, o.segments); - } - - add(s: PathSegment) { - if (this.closed) illegalState("path already closed"); - this.segments.push(s); - } - - toHiccup() { - let dest: any[] = []; - const segments = this.segments; - const n = segments.length; - if (n > 1) { - dest.push(["M", segments[0].point]); - for (let i = 1; i < n; i++) { - dest = dest.concat(segments[i].geo.toHiccupPathSegments()); - } - if (this.closed) { - dest.push(["Z"]); - } - } - return ["path", this.attribs || {}, dest]; - } -} - -export class Points extends APC implements - IHiccupShape { - - get type() { - return Type.POINTS; - } - - copy() { - return new Points(copyPoints(this.points), { ...this.attribs }); - } - - toHiccup() { - return ["points", this.attribs, this.points]; - } -} - -export class Polygon extends APC implements - IHiccupShape { - - get type() { - return Type.POLYGON; - } - - copy() { - return new Polygon(copyPoints(this.points), { ...this.attribs }); - } - - toHiccup() { - return ["polygon", this.attribs, this.points]; - } -} - -export class Polyline extends APC implements - IHiccupShape, - IHiccupPathSegment { - - get type() { - return Type.POLYLINE; - } - - copy() { - return new Polyline(copyPoints(this.points), { ...this.attribs }); - } - - toHiccup() { - return ["polyline", { ...this.attribs, fill: "none" }, this.points]; - } - - toHiccupPathSegments() { - const res: any[] = []; - for (let pts = this.points, n = pts.length, i = 1; i < n; i++) { - res.push(["L", pts[i]]); - } - return res; - } -} - -export class Quad extends APC implements - IHiccupShape { - - get type() { - return Type.QUAD; - } - - copy() { - return new Quad(copyPoints(this.points), { ...this.attribs }); - } - - toHiccup() { - return ["polygon", this.attribs, this.points]; - } -} - -export class Quadratic extends APC implements - IHiccupShape, - IHiccupPathSegment { - - get type() { - return Type.QUADRATIC; - } - - copy() { - return new Quadratic(copyPoints(this.points), { ...this.attribs }); - } - - toHiccup() { - return ["path", this.attribs, - [ - ["M", this.points[0]], - ...this.toHiccupPathSegments() - ] - ]; - } - - toHiccupPathSegments() { - const pts = this.points; - return [["Q", pts[1], pts[2]]]; - } -} - -export class Ray implements - IHiccupShape { - - pos: Vec; - dir: Vec; - attribs: Attribs; - - constructor(pos: Vec, dir: Vec, attribs?: Attribs) { - this.pos = pos; - this.dir = dir; - this.attribs = attribs; - } - - get type() { - return Type.RAY; - } - - copy() { - return new Ray(set([], this.pos), set([], this.dir), { ...this.attribs }); - } - - toHiccup() { - return ["line", this.attribs, this.pos, maddN2([], this.pos, this.dir, 1e6)]; - } -} - -export class Rect implements - AABBLike, - IHiccupShape { - - pos: Vec; - size: Vec; - attribs: Attribs; - - constructor(pos: Vec = [0, 0], size: number | Vec = [1, 1], attribs?: Attribs) { - this.pos = pos; - this.size = isNumber(size) ? [size, size] : size; - this.attribs = attribs; - } - - get type() { - return Type.RECT; - } - - copy() { - return new Rect(set([], this.pos), set([], this.size), { ...this.attribs }); - } - - max() { - return add2([], this.pos, this.size); - } - - toHiccup() { - return ["rect", this.attribs, this.pos, this.size]; - } -} - -export class Sphere implements - IHiccupShape { - - pos: Vec; - r: number; - attribs: Attribs; - - constructor(pos: Vec = [0, 0, 0], r = 1, attribs?: Attribs) { - this.pos = pos; - this.r = r; - this.attribs = attribs; - } - - get type() { - return Type.SPHERE; - } - - copy() { - return new Sphere(set([], this.pos), this.r, { ...this.attribs }); - } - - toHiccup() { - return ["sphere", this.attribs, this.pos, this.r]; - } -} - -export class Triangle extends APC implements - IHiccupShape { - - get type() { - return Type.TRIANGLE; - } - - copy() { - return new Triangle(copyPoints(this.points), { ...this.attribs }); - } - - toHiccup() { - return ["polygon", this.attribs, this.points]; - } -} diff --git a/packages/geom3/src/index.ts b/packages/geom3/src/index.ts deleted file mode 100644 index bd89097857..0000000000 --- a/packages/geom3/src/index.ts +++ /dev/null @@ -1,85 +0,0 @@ -export * from "./api"; - -export * from "./ctors/arc"; -export * from "./ctors/circle"; -export * from "./ctors/cubic"; -export * from "./ctors/ellipse"; -export * from "./ctors/group"; -export * from "./ctors/line"; -export * from "./ctors/path"; -export * from "./ctors/points"; -export * from "./ctors/polygon"; -export * from "./ctors/polyline"; -export * from "./ctors/quad"; -export * from "./ctors/quadratic"; -export * from "./ctors/ray"; -export * from "./ctors/rect"; -export * from "./ctors/triangle"; - -export * from "./ops/arc-length"; -export * from "./ops/area"; -export * from "./ops/as-cubic"; -export * from "./ops/as-polygon"; -export * from "./ops/as-svg"; -export * from "./ops/bounds"; -export * from "./ops/center"; -export * from "./ops/centroid"; -export * from "./ops/classify-point"; -export * from "./ops/clip-convex"; -export * from "./ops/closest-point"; -export * from "./ops/convex-hull"; -export * from "./ops/edges"; -export * from "./ops/fit-into-bounds"; -export * from "./ops/flip"; -export * from "./ops/intersects"; -export * from "./ops/map-point"; -export * from "./ops/point-at"; -export * from "./ops/point-inside"; -export * from "./ops/resample"; -export * from "./ops/scatter"; -export * from "./ops/simplify"; -export * from "./ops/split-at"; -export * from "./ops/split-near"; -export * from "./ops/subdiv-curve"; -export * from "./ops/tangent-at"; -export * from "./ops/tessellate"; -export * from "./ops/transform"; -export * from "./ops/translate"; -export * from "./ops/union"; -export * from "./ops/unmap-point"; -export * from "./ops/vertices"; -export * from "./ops/warp-points"; -export * from "./ops/with-attribs"; - -export * from "./internal/arc-point"; -export * from "./internal/bounds"; -export * from "./internal/centroid"; -export * from "./internal/circumcenter"; -export * from "./internal/clockwise"; -export * from "./internal/closest-point"; -export * from "./internal/copy-points"; -export * from "./internal/corner"; -export * from "./internal/douglas–peucker"; -export * from "./internal/edges"; -export * from "./internal/graham-scan"; -export * from "./internal/liang-barsky"; -export * from "./internal/poly-arc-length"; -export * from "./internal/poly-area"; -export * from "./internal/poly-centroid"; -export * from "./internal/poly-point-inside"; -export * from "./internal/sampler"; -export * from "./internal/split"; -export * from "./internal/subdiv-curve"; -export * from "./internal/sutherland-hodgeman"; -export * from "./internal/tessellate"; -export * from "./internal/transform-points"; -export * from "./internal/triangle-point-inside"; -export * from "./internal/union-bounds"; - -export * from "./isec/circle-circle"; -export * from "./isec/line-line"; -export * from "./isec/ray-circle"; -export * from "./isec/ray-line"; -export * from "./isec/ray-poly"; -export * from "./isec/rect-circle"; -export * from "./isec/rect-rect"; diff --git a/packages/geom3/src/internal/args.ts b/packages/geom3/src/internal/args.ts deleted file mode 100644 index 7bf1bba99f..0000000000 --- a/packages/geom3/src/internal/args.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { isNumber, isPlainObject } from "@thi.ng/checks"; -import { peek } from "@thi.ng/transducers"; - -/** - * Takes an array of arguments, checks if last element is a plain object - * and if so, removes it from array and returns it. Else returns - * `undefined`. - * - * @param args - */ -export const argAttribs = - (args: any[]) => - isPlainObject(peek(args)) ? - args.pop() : - undefined; - -/** - * Args parser for functions expecting up to 2 vector args and optional - * attribs object. Returns 3-tuple of re-structured args. - * - * @param args - */ -export const argsVV = - (args: any[]) => { - const attr = argAttribs(args); - return args.length ? - args.length === 2 ? - [args[0], args[1], attr] : - [undefined, args[0], attr] : - [undefined, undefined, attr]; - }; - -/** - * Args parser for functions expecting a vector, numeric and/or optional - * attribs object. Returns 3-tuple of re-structured args. - * - * @param args - */ -export const argsVN = - (args: any[]) => { - const attr = argAttribs(args); - return args.length ? - args.length === 2 ? - [args[0], args[1], attr] : - isNumber(args[0]) ? - [undefined, args[0], attr] : - [args[0], undefined, attr] : - [undefined, undefined, attr]; - }; diff --git a/packages/geom3/src/internal/barycentric.ts b/packages/geom3/src/internal/barycentric.ts deleted file mode 100644 index 6e756627f9..0000000000 --- a/packages/geom3/src/internal/barycentric.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { - addW3, - dot, - magSq, - ReadonlyVec, - setC3, - sub, - Vec -} from "@thi.ng/vectors3"; - -export const toBarycentric = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, p: ReadonlyVec, out: Vec = []) => { - const u = sub([], b, a); - const v = sub([], c, a); - const w = sub([], p, a); - const uu = magSq(u); - const vv = magSq(v); - const uv = dot(u, v); - const uw = dot(u, w); - const vw = dot(v, w); - const d = 1 / (uv * uv - uu * vv); - const s = d * (uv * vw - vv * uw); - const t = d * (uv * uw - uu * vw); - return setC3(out, 1 - (s + t), s, t); - }; - -export const fromBarycentric = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, p: ReadonlyVec, out?: Vec) => - addW3(out, a, b, c, p[0], p[1], p[2]); diff --git a/packages/geom3/src/internal/bounds.ts b/packages/geom3/src/internal/bounds.ts deleted file mode 100644 index fa3e198284..0000000000 --- a/packages/geom3/src/internal/bounds.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { Fn } from "@thi.ng/api"; -import { clamp01, mixCubic as _mixCubic } from "@thi.ng/math"; -import { max, min, Vec } from "@thi.ng/vectors3"; -import { - max2, - max3, - min2, - min3, - ReadonlyVec -} from "@thi.ng/vectors3"; -import { VecPair } from "../api"; -import { AABBLike, IShape } from "../api"; -import { unionBounds } from "./union-bounds"; - -/** - * Computes the nD bounds of given vectors. `vmin` should be initialized - * to `+Infinity` and `vmax` to `-Infinity` (e.g. use copies of `MIN*` / - * `MAX*` constants defined in thi.ng/vectors3). - * - * Returns 2-tuple of modified `[vmin, vmax]`. - * - * @param pts - * @param vmin - * @param vmax - */ -export const boundsRaw = - (pts: ReadonlyArray, vmin: Vec, vmax: Vec): VecPair => { - - for (let i = pts.length; --i >= 0;) { - const p = pts[i]; - min(null, vmin, p); - max(null, vmax, p); - } - return [vmin, vmax]; - }; - -/** - * Computes the total bounds for the given shape collection, which - * should either contain only 2D or 3D types. No mixed dimensions are - * allowed! Currently the `bounds` function must be passed in as arg to - * avoid circular module dependencies. - * - * @param shapes - * @param bounds - */ -export const collBounds = - (shapes: IShape[], bounds: Fn) => { - let n = shapes.length - 1; - if (n < 0) return; - let { pos, size } = bounds(shapes[n]); - for (; --n >= 0;) { - const b = bounds(shapes[n]); - [pos, size] = unionBounds(pos, size, b.pos, b.size); - } - return [pos, size]; - }; - -const cubicAxisBounds = - (pa: number, pb: number, pc: number, pd: number) => { - let a = 3 * pd - 9 * pc + 9 * pb - 3 * pa; - let b = 6 * pa - 12 * pb + 6 * pc; - let c = 3 * pb - 3 * pa; - let disc = b * b - 4 * a * c; - let l = pa; - let h = pa; - - const bounds = (t: number) => { - if (t > 0 && t < 1) { - const x = _mixCubic(pa, pb, pc, pd, t); - x < l && (l = x); - x > h && (h = x); - } - }; - - pd < l && (l = pd); - pd > h && (h = pd); - if (disc >= 0) { - disc = Math.sqrt(disc); - a *= 2; - bounds((-b + disc) / a); - bounds((-b - disc) / a); - } - return [l, h]; - }; - -export const cubicBounds2 = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec): VecPair => { - const x = cubicAxisBounds(a[0], b[0], c[0], d[0]); - const y = cubicAxisBounds(a[1], b[1], c[1], d[1]); - return [[x[0], y[0]], [x[1], y[1]]]; - }; - -export const cubicBounds3 = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec): VecPair => { - const x = cubicAxisBounds(a[0], b[0], c[0], d[0]); - const y = cubicAxisBounds(a[1], b[1], c[1], d[1]); - const z = cubicAxisBounds(a[2], b[2], c[2], d[2]); - return [[x[0], y[0], z[0]], [x[1], y[1], z[1]]]; - }; - -const solveQuadratic = - (a: number, b: number, c: number) => { - const t = clamp01((a - b) / (a - 2.0 * b + c)); - const s = 1 - t; - return s * s * a + 2.0 * s * t * b + t * t * c; - }; - -export const quadraticBounds2 = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec): VecPair => { - const mi = min2([], a, c); - const ma = max2([], a, c); - if (b[0] < mi[0] || b[0] > ma[0] || b[1] < mi[1] || b[1] > ma[1]) { - const q = [ - solveQuadratic(a[0], b[0], c[0]), - solveQuadratic(a[1], b[1], c[1]), - ]; - min2(null, mi, q); - max2(null, ma, q); - } - return [mi, ma]; - }; - -export const quadraticBounds3 = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec): VecPair => { - const mi = min3([], a, c); - const ma = max3([], a, c); - if (b[0] < mi[0] || b[0] > ma[0] || - b[1] < mi[1] || b[1] > ma[1] || - b[2] < mi[2] || b[2] > ma[2]) { - const q = [ - solveQuadratic(a[0], b[0], c[0]), - solveQuadratic(a[1], b[1], c[1]), - solveQuadratic(a[2], b[2], c[2]), - ]; - min3(null, mi, q); - max3(null, ma, q); - } - return [mi, ma]; - }; diff --git a/packages/geom3/src/internal/centroid.ts b/packages/geom3/src/internal/centroid.ts deleted file mode 100644 index cffe402581..0000000000 --- a/packages/geom3/src/internal/centroid.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { illegalArgs } from "@thi.ng/errors"; -import { - add, - divN, - empty, - ReadonlyVec, - Vec -} from "@thi.ng/vectors3"; - -export const centroidRaw = - (pts: ReadonlyVec[], out?: Vec) => { - const num = pts.length; - !num && illegalArgs("no points available"); - !out && (out = empty(pts[0])); - for (let i = num; --i >= 0;) { - add(out, out, pts[i]); - } - return divN(null, out, num); - }; diff --git a/packages/geom3/src/internal/circumcenter.ts b/packages/geom3/src/internal/circumcenter.ts deleted file mode 100644 index a5ccca08c7..0000000000 --- a/packages/geom3/src/internal/circumcenter.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { EPS } from "@thi.ng/math"; -import { ReadonlyVec } from "@thi.ng/vectors3"; - -export const circumCenter = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, eps = EPS) => { - - const deltaAB = Math.abs(a[1] - b[1]); - const deltaBC = Math.abs(b[1] - c[1]); - - if (deltaAB < eps && deltaBC < eps) return; - - const ax = a[0], ay = a[1]; - const bx = b[0], by = b[1]; - const cx = c[0], cy = c[1]; - let m1, m2, mx1, mx2, my1, my2, xc, yc; - - if (deltaAB < eps) { - m2 = -(cx - bx) / (cy - by); - mx2 = (bx + cx) / 2; - my2 = (by + cy) / 2; - xc = (bx + ax) / 2; - yc = m2 * (xc - mx2) + my2; - } else if (deltaBC < eps) { - m1 = -(bx - ax) / (by - ay); - mx1 = (ax + bx) / 2; - my1 = (ay + by) / 2; - xc = (cx + bx) / 2; - yc = m1 * (xc - mx1) + my1; - } else { - m1 = -(bx - ax) / (by - ay); - m2 = -(cx - bx) / (cy - by); - mx1 = (ax + bx) / 2; - my1 = (ay + by) / 2; - mx2 = (bx + cx) / 2; - my2 = (by + cy) / 2; - xc = (m1 * mx1 - m2 * mx2 + my2 - my1) / (m1 - m2); - yc = deltaAB > deltaBC ? - m1 * (xc - mx1) + my1 : - m2 * (xc - mx2) + my2; - } - - return [xc, yc]; - }; diff --git a/packages/geom3/src/internal/closest-point.ts b/packages/geom3/src/internal/closest-point.ts deleted file mode 100644 index 55b6e149ff..0000000000 --- a/packages/geom3/src/internal/closest-point.ts +++ /dev/null @@ -1,228 +0,0 @@ -import { Fn } from "@thi.ng/api"; -import { partial } from "@thi.ng/compose"; -import { fit01 } from "@thi.ng/math"; -import { - distSq, - dot, - empty, - magSq, - mixCubic, - mixN, - mixQuadratic, - ReadonlyVec, - set, - sub, - Vec -} from "@thi.ng/vectors3"; -import { arcPointAtTheta } from "./arc-point"; - -export const closestPointArray = - (p: ReadonlyVec, pts: Vec[]) => { - - let minD = Infinity; - let closest: Vec; - for (let i = pts.length; --i >= 0;) { - const d = distSq(pts[i], p); - if (d < minD) { - minD = d; - closest = pts[i]; - } - } - return closest; - }; - -export const closestCoeff = - (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec) => { - - const d = sub([], b, a); - const l = magSq(d); - return l > 1e-6 ? - dot(sub([], p, a), d) / l : - undefined; - }; - -/** - * Returns closest point to `p` on segment `a` -> `b`. By default, if - * the result point lies outside the segment, returns a copy of the - * closest end point. However, if `insideOnly` is true, only returns the - * closest point if it actually is inside the segment (incl. end - * points). - * - * @param p - * @param a - * @param b - * @param out - */ -export const closestPointSegment = - (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, out?: Vec, insideOnly = false) => { - - const t = closestCoeff(p, a, b); - if (t !== undefined && (!insideOnly || t >= 0 && t <= 1)) { - out = out || empty(p); - return t <= 0 ? - set(out, a) : - t >= 1 ? - set(out, b) : - mixN(out, a, b, t); - } - }; - -export const closestPointPolyline = - (p: ReadonlyVec, pts: ReadonlyArray, closed = false, out: Vec = []) => { - const tmp = []; - const n = pts.length - 1; - let minD = Infinity, i, j; - if (closed) { - i = n; - j = 0; - } else { - i = 0; - j = 1; - } - for (; j <= n; i = j, j++) { - if (closestPointSegment(p, pts[i], pts[j], tmp)) { - const d = distSq(p, tmp); - if (d < minD) { - minD = d; - set(out, tmp); - } - } - } - return out; - }; - -/** - * Returns the index of the start point containing the segment in the - * polyline array `points` farthest away from `p` with regards to the - * line segment `a` to `b`. `points` is only checked between indices - * `from` and `to` (not including the latter). - * - * @param a - * @param b - * @param points - * @param from - * @param to - */ -export const farthestPointSegment = - (a: ReadonlyVec, b: ReadonlyVec, points: ReadonlyVec[], from = 0, to = points.length) => { - let maxD = -1; - let maxIdx; - const tmp = empty(a); - for (let i = from; i < to; i++) { - const p = points[i]; - const d = distSq(p, closestPointSegment(p, a, b, tmp) || a); - if (d > maxD) { - maxD = d; - maxIdx = i; - } - } - return [maxIdx, Math.sqrt(maxD)]; - }; - -export const closestPointArc = ( - p: ReadonlyVec, - o: ReadonlyVec, - r: ReadonlyVec, - axis: number, - start: number, - end: number, - out: Vec = [], - res?: number, - iter?: number -) => { - const fn = (t: number) => arcPointAtTheta(o, r, axis, fit01(t, start, end), out); - return fn(findClosestT(fn, p, res, iter)); -}; - -/** - * Performs recursive search for closest point to `p` on cubic curve - * defined by control points `a`,`b`,`c`,`d`. The `res` and `recur` - * params are used to control the recursion behavior. See `closestT`. - * - * @param p - * @param a - * @param b - * @param c - * @param d - * @param res - * @param iter - */ -export const closestPointCubic = ( - p: ReadonlyVec, - a: ReadonlyVec, - b: ReadonlyVec, - c: ReadonlyVec, - d: ReadonlyVec, - out: Vec = [], - res?: number, - iter?: number -) => { - const fn = partial(mixCubic, out, a, b, c, d); - return fn(findClosestT(fn, p, res, iter)); -}; - -/** - * Performs recursive search for closest point to `p` on quadratic curve - * defined by control points `a`,`b`,`c`. The `res` and `recur` params - * are used to control the recursion behavior. See `closestT`. - * - * @param p - * @param a - * @param b - * @param c - * @param res - * @param iter - */ -export const closestPointQuadratic = ( - p: ReadonlyVec, - a: ReadonlyVec, - b: ReadonlyVec, - c: ReadonlyVec, - out: Vec = [], - res?: number, - iter?: number -) => { - const fn = partial(mixQuadratic, out, a, b, c); - return fn(findClosestT(fn, p, res, iter)); -}; - -/** - * Recursively evaluates function `fn` for `res` uniformly spaced values - * `t` in the closed interval `[start,end]` to compute points and - * returns the `t` of the point producing the minimum distance to query - * point `p`. At each level of recursion the search interval is - * increasingly narrowed / centered around the currently best `t`. - * - * @param fn - * @param p - * @param res - * @param iter - * @param start - * @param end - */ -export const findClosestT = ( - fn: Fn, - p: ReadonlyVec, - res = 8, - iter = 4, - start = 0, - end = 1 -) => { - if (iter <= 0) return (start + end) / 2; - const delta = (end - start) / res; - let minT = start; - let minD = Infinity; - for (let i = 0; i <= res; i++) { - const t = start + i * delta; - const d = distSq(p, fn(t)); - if (d < minD) { - minD = d; - minT = t; - } - } - return findClosestT( - fn, p, res, iter - 1, - Math.max(minT - delta, 0), - Math.min(minT + delta, 1) - ); -}; diff --git a/packages/geom3/src/internal/collate.ts b/packages/geom3/src/internal/collate.ts deleted file mode 100644 index 7a3d47726f..0000000000 --- a/packages/geom3/src/internal/collate.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Vec, StridedVec } from "@thi.ng/vectors3"; - -export interface CollateOpts { - buf: Vec; - start: number; - cstride: number; - estride: number; -} - -export const remap = ( - buf: Vec, - pts: StridedVec[], - start: number, - cstride: number, - estride: number -) => { - for (let i = pts.length; --i >= 0;) { - const p = pts[i]; - p.buf = buf; - p.offset = start + i * estride; - p.stride = cstride; - } - return buf; -}; - -export const collateWith = ( - fn: (buf: Vec, src: Iterable>, start, cstride, estride) => Vec, - pts: StridedVec[], - opts: Partial, - stride: number -) => { - opts = { - start: 0, - cstride: 1, - estride: stride, - ...opts - }; - const { start, cstride, estride } = opts; - return remap( - fn( - opts.buf || new Array(start + pts.length * estride).fill(0), - pts, - start, - cstride, - estride - ), - pts, start, cstride, estride - ); -}; diff --git a/packages/geom3/src/internal/corner.ts b/packages/geom3/src/internal/corner.ts deleted file mode 100644 index cfea7cf3d1..0000000000 --- a/packages/geom3/src/internal/corner.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { EPS, sign } from "@thi.ng/math"; -import { ReadonlyVec, signedArea2 } from "@thi.ng/vectors3"; - -/** - * Syntax sugar for `sign(signedArea2(a,b,c))`. - * - * @param a - * @param b - * @param c - * @param eps - */ -export const corner = - (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, eps = EPS) => - sign(signedArea2(a, b, c), eps); diff --git "a/packages/geom3/src/internal/douglas\342\200\223peucker.ts" "b/packages/geom3/src/internal/douglas\342\200\223peucker.ts" deleted file mode 100644 index 3051fc747d..0000000000 --- "a/packages/geom3/src/internal/douglas\342\200\223peucker.ts" +++ /dev/null @@ -1,42 +0,0 @@ -import { EPS } from "@thi.ng/math"; -import { peek } from "@thi.ng/transducers"; -import { eqDelta, Vec } from "@thi.ng/vectors3"; -import { farthestPointSegment } from "./closest-point"; - -// https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm - -export const douglasPeucker = - (pts: Vec[], eps = 0, closed = false) => { - - let num = pts.length; - const visited: boolean[] = []; - if (num <= 2) return pts.slice(); - if (closed && !eqDelta(pts[0], peek(pts), EPS)) { - pts = pts.slice(); - pts.push(pts[0]); - num++; - } - - const $ = (from: number, to: number) => { - visited[from] = visited[to] = true; - if (to <= from + 1) { - return; - } - const [maxIdx, maxD] = farthestPointSegment(pts[from], pts[to], pts, from + 1, to); - if (maxD <= eps) { - return; - } - $(from, maxIdx); - $(maxIdx, to); - }; - - $(0, num - 1); - - const res: Vec[] = []; - for (let i = 0, n = closed ? num - 1 : num; i < n; i++) { - if (visited[i]) { - res.push(pts[i]); - } - } - return res; - }; diff --git a/packages/geom3/src/internal/edges.ts b/packages/geom3/src/internal/edges.ts deleted file mode 100644 index b8b21d2b92..0000000000 --- a/packages/geom3/src/internal/edges.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { partition, wrap } from "@thi.ng/transducers"; -import { ReadonlyVec } from "@thi.ng/vectors3"; -import { VecPair } from "../api"; - -export const edgeIterator = - (vertices: Iterable, closed = false) => - >partition( - 2, 1, - closed ? - wrap(vertices, 1, false, true) : - vertices - ); diff --git a/packages/geom3/src/internal/graham-scan.ts b/packages/geom3/src/internal/graham-scan.ts deleted file mode 100644 index 76ede164c0..0000000000 --- a/packages/geom3/src/internal/graham-scan.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { EPS } from "@thi.ng/math"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3"; - -/** - * Returns array of points defining the 2D Convex Hull of `pts` using - * the Graham Scan method. - * - * https://en.wikipedia.org/wiki/Graham_scan - * - * @param pts - */ -export const grahamScan2 = - (pts: ReadonlyVec[], eps = EPS) => { - const num = pts.length; - if (num <= 3) return pts.slice(); - let h = 1, i, p, q, r, rx, ry; - // find min YX index - const min = findMin(pts); - [rx, ry] = pts[min]; - const sorted = []; - // compute & sort by polar ordering relative to min - for (i = 0; i < num; i++) { - p = pts[i]; - sorted[i] = { p, t: Math.atan2(p[1] - ry, p[0] - rx) }; - } - sorted.sort( - (a, b) => - a.t !== b.t ? - a.t - b.t : - a.p[0] - b.p[0] - ); - const hull: Vec[] = [sorted[0].p]; - for (i = 1; i < num; i++) { - p = hull[h - 2]; - q = hull[h - 1]; - r = sorted[i].p; - rx = r[0]; - ry = r[1]; - while ((h > 1 && notCCW(p[0], p[1], q[0], q[1], rx, ry, eps)) || - (h === 1 && q[0] === rx && q[1] === ry)) { - h--; - q = p; - p = hull[h - 2]; - } - hull[h++] = r; - } - hull.length = h; - return hull; - }; - -/** - * Returns true, if triangle defined by ABC is NOT counter clockwise, - * i.e. clockwise or colinear. - * - * @see thi.ng/vectors3/signedArea2 - * - * @param ax - * @param ay - * @param bx - * @param by - * @param cx - * @param cy - */ -const notCCW = (ax: number, ay: number, bx: number, by: number, cx: number, cy: number, eps: number) => - (by - ay) * (cx - ax) >= (bx - ax) * (cy - ay) - eps; - -/** - * Returns index of point with lowest YX coords. - * - * @param pts - */ -const findMin = - (pts: ReadonlyVec[]) => { - let n = pts.length - 1; - let minID = n; - let min = pts[n][1]; - let p, y; - for (; --n >= 0;) { - p = pts[n]; - y = p[1]; - if (y < min || (y === min && p[0] < pts[minID][0])) { - min = y; - minID = n; - } - } - return minID; - }; diff --git a/packages/geom3/src/internal/liang-barsky.ts b/packages/geom3/src/internal/liang-barsky.ts deleted file mode 100644 index f30ffcc3da..0000000000 --- a/packages/geom3/src/internal/liang-barsky.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { EPS } from "@thi.ng/math"; -import { Vec } from "@thi.ng/vectors3"; - -/** - * Performs Liang-Barsky clipping with given line endpoints `la`, `lb` - * and clipping rect defined by top-left `tr` and bottom-right `br` - * points. The optional `ca` and `cb` vectors can be given to store the - * result (clipped points). If omitted creates new vectors. Returns a - * tuple of `[ca, cb, a, b]`, where the latter two values represent the - * normalized distances of the clipped points relative to original given - * line segment. Returns `undefined` iff the line lies completely - * outside the rect. - * - * https://en.wikipedia.org/wiki/Liang%E2%80%93Barsky_algorithm - * https://github.com/thi-ng/c-thing/blob/master/src/geom/clip/liangbarsky.c - * - * @param la - * @param lb - * @param tl - * @param br - * @param ca - * @param cb - */ -export const liangBarsky = ( - la: Vec, - lb: Vec, - tl: Vec, - br: Vec, - ca: Vec = [], - cb: Vec = [] -): [Vec, Vec, number, number] => { - const lax = la[0]; - const lay = la[1]; - const dx = lb[0] - lax; - const dy = lb[1] - lay; - let a = 0; - let b = 1; - - const clip = (p: number, q: number) => { - if (q < 0 && Math.abs(p) < EPS) { - return 0; - } - const r = q / p; - if (p < 0) { - if (r > b) { - return false; - } else if (r > a) { - a = r; - } - } else { - if (r < a) { - return false; - } else if (r < b) { - b = r; - } - } - return true; - }; - - if (!( - clip(-dx, -(tl[0] - lax)) && - clip(dx, br[0] - lax) && - clip(-dy, -(tl[1] - lay)) && - clip(dy, br[1] - lay) - )) { - return; - } - - ca[0] = a * dx + lax; - ca[1] = a * dy + lay; - cb[0] = b * dx + lax; - cb[1] = b * dy + lay; - - return [ca, cb, a, b]; -}; diff --git a/packages/geom3/src/internal/sutherland-hodgeman.ts b/packages/geom3/src/internal/sutherland-hodgeman.ts deleted file mode 100644 index 967481a32e..0000000000 --- a/packages/geom3/src/internal/sutherland-hodgeman.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { ReadonlyVec } from "@thi.ng/vectors3"; -import { corner } from "./corner"; -import { intersectLineLine } from "../isec/line-line"; - -/** - * Extended version of Sutherland-Hodgeman convex polygon clipping - * supporting any convex boundary (not only rects). Returns new array of - * clipped vertices. - * - * https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm - * - * @param pts subject poly vertices - * @param bounds clipping boundary vertices - * @param bc pre-computed boundary centroid - * @param eps edge classification tolerance - */ -export const sutherlandHodgeman = - (pts: ReadonlyVec[], bounds: ReadonlyVec[], bc: ReadonlyVec, eps = 1e-4) => { - for (let ne = bounds.length, j = ne - 1, i = 0; i < ne; j = i, i++) { - const clipped = []; - const ca = bounds[j]; - const cb = bounds[i]; - const sign = corner(ca, cb, bc, eps); - for (let np = pts.length, k = np - 1, l = 0; l < np; k = l, l++) { - const p = pts[k]; - const q = pts[l]; - const cqsign = corner(ca, cb, q, eps); - if (corner(ca, cb, p, eps) === sign) { - clipped.push( - cqsign !== sign ? - intersectLineLine(ca, cb, p, q).isec : - q - ); - } else if (cqsign === sign) { - clipped.push(intersectLineLine(ca, cb, p, q).isec, q); - } - } - if (clipped.length < 2) { - return []; - } - pts = clipped; - } - return pts; - }; diff --git a/packages/geom3/test/tsconfig.json b/packages/geom3/test/tsconfig.json deleted file mode 100644 index f6e63560dd..0000000000 --- a/packages/geom3/test/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "../../../tsconfig.json", - "compilerOptions": { - "outDir": "../build", - "module": "commonjs" - }, - "include": [ - "./**/*.ts", - "../src/**/*.ts" - ] -} diff --git a/packages/geom3/tsconfig.json b/packages/geom3/tsconfig.json deleted file mode 100644 index faed4e5fe7..0000000000 --- a/packages/geom3/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": ".", - "module": "es6", - "target": "es6", - "preserveConstEnums": false - }, - "include": [ - "./src/**/*.ts" - ] -} \ No newline at end of file From 4bd77082442a3942d5de88e712e00da37138fa93 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 20 Jan 2019 22:06:52 +0000 Subject: [PATCH 323/333] build: update geom3 => geom references --- examples/geom-tessel/src/index.ts | 2 +- packages/hdom-canvas/README.md | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/geom-tessel/src/index.ts b/examples/geom-tessel/src/index.ts index 1301679691..de96857f05 100644 --- a/examples/geom-tessel/src/index.ts +++ b/examples/geom-tessel/src/index.ts @@ -12,7 +12,7 @@ import { Tessellator, tesselQuadFan, tesselTriFan -} from "@thi.ng/geom3"; +} from "@thi.ng/geom"; import { canvas } from "@thi.ng/hdom-canvas"; import { deg, fit01, fit11 } from "@thi.ng/math"; import { fromInterval, sync } from "@thi.ng/rstream"; diff --git a/packages/hdom-canvas/README.md b/packages/hdom-canvas/README.md index 55ad4cee5f..72bf02358a 100644 --- a/packages/hdom-canvas/README.md +++ b/packages/hdom-canvas/README.md @@ -96,13 +96,13 @@ start(() => { ``` Usage with -[@thi.ng/geom3](https://github.com/thi-ng/umbrella/tree/master/packages/geom3) +[@thi.ng/geom](https://github.com/thi-ng/umbrella/tree/master/packages/geom) shape primitives: ```ts import { start } from "@thi.ng/hdom"; import { canvas } from "@thi.ng/hdom-canvas"; -import * as g from "@thi.ng/geom3"; +import * as g from "@thi.ng/geom"; start(() => { const t = Date.now() * 0.001; @@ -135,7 +135,7 @@ the user context object as first arg, just like normal hdom components. Shape components are expressed in standard hiccup syntax (or as objects implementing the `IToHiccup()` interface, like the shape types provided by -[@thi.ng/geom3](https://github.com/thi-ng/umbrella/tree/master/packages/geom3)), +[@thi.ng/geom](https://github.com/thi-ng/umbrella/tree/master/packages/geom)), and with the following... ### Restrictions & behavior controls @@ -350,10 +350,10 @@ relative to the end point of the previous segment. handling, SVG paths containing arc segments are **NOT** compatible with the above format. To draw such paths reliably, these should first be converted to use cubics. E.g. here using -[@thi.ng/geom3](https://github.com/thi-ng/umbrella/tree/master/packages/geom3): +[@thi.ng/geom](https://github.com/thi-ng/umbrella/tree/master/packages/geom): ```ts -import { normalizedPath, pathFromSVG } from "@thi.ng/geom3"; +import { normalizedPath, pathFromSVG } from "@thi.ng/geom"; // path w/ ac segments const a = pathFromSvg("M0,0H80A20,20,0,0,1,100,20V30A20,20,0,0,1,80,50")[0]; From 0fd2498e490d361757fb297a71b8385cbb828e51 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 20 Jan 2019 22:23:06 +0000 Subject: [PATCH 324/333] build(vectors): replace old vectors package w/ vectors3 (renamed back to vectors) --- packages/vectors/README.md | 632 +++++++------ packages/vectors/bench/index.js | 56 -- packages/vectors/package.json | 64 +- packages/{vectors3 => vectors}/src/abs.ts | 0 packages/{vectors3 => vectors}/src/acos.ts | 0 packages/{vectors3 => vectors}/src/add.ts | 0 packages/{vectors3 => vectors}/src/addm.ts | 0 packages/{vectors3 => vectors}/src/addmn.ts | 0 packages/{vectors3 => vectors}/src/addn.ts | 0 packages/{vectors3 => vectors}/src/adds.ts | 0 packages/{vectors3 => vectors}/src/addw.ts | 0 .../src/angle-between.ts | 0 packages/vectors/src/api.ts | 263 ++---- packages/{vectors3 => vectors}/src/asin.ts | 0 packages/{vectors3 => vectors}/src/bisect.ts | 0 .../{vectors3 => vectors}/src/cartesian.ts | 0 packages/{vectors3 => vectors}/src/ceil.ts | 0 packages/{vectors3 => vectors}/src/clamp.ts | 0 packages/{vectors3 => vectors}/src/clampn.ts | 0 packages/vectors/src/codegen.ts | 249 ----- packages/vectors/src/common.ts | 186 ---- packages/{vectors3 => vectors}/src/compare.ts | 0 packages/{vectors3 => vectors}/src/copy.ts | 0 packages/{vectors3 => vectors}/src/cos.ts | 0 packages/{vectors3 => vectors}/src/cosh.ts | 0 packages/{vectors3 => vectors}/src/cross.ts | 0 .../src/dist-chebyshev.ts | 0 .../src/dist-manhattan.ts | 0 packages/{vectors3 => vectors}/src/dist.ts | 0 packages/{vectors3 => vectors}/src/distsq.ts | 0 packages/{vectors3 => vectors}/src/div.ts | 0 packages/{vectors3 => vectors}/src/divn.ts | 0 packages/{vectors3 => vectors}/src/divs.ts | 0 packages/{vectors3 => vectors}/src/dot.ts | 0 packages/{vectors3 => vectors}/src/dotc.ts | 0 packages/{vectors3 => vectors}/src/dots.ts | 0 packages/{vectors3 => vectors}/src/empty.ts | 0 packages/{vectors3 => vectors}/src/eqdelta.ts | 0 packages/{vectors3 => vectors}/src/exp.ts | 0 .../{vectors3 => vectors}/src/face-forward.ts | 0 packages/{vectors3 => vectors}/src/floor.ts | 0 packages/{vectors3 => vectors}/src/fract.ts | 0 packages/vectors/src/gvec.ts | 747 ++++----------- packages/{vectors3 => vectors}/src/heading.ts | 0 .../{vectors3 => vectors}/src/homogeneous.ts | 0 packages/vectors/src/index.ts | 114 ++- .../src/internal/accessors.ts | 0 .../src/internal/avec.ts | 0 .../src/internal/codegen.ts | 0 .../src/internal/templates.ts | 0 .../src/internal/vec-utils.ts | 0 .../{vectors3 => vectors}/src/internal/vop.ts | 0 packages/{vectors3 => vectors}/src/invert.ts | 0 packages/{vectors3 => vectors}/src/invsqrt.ts | 0 packages/{vectors3 => vectors}/src/jitter.ts | 0 packages/{vectors3 => vectors}/src/limit.ts | 0 packages/{vectors3 => vectors}/src/log.ts | 0 packages/{vectors3 => vectors}/src/madd.ts | 0 packages/{vectors3 => vectors}/src/maddn.ts | 0 packages/{vectors3 => vectors}/src/mag.ts | 0 packages/{vectors3 => vectors}/src/magsq.ts | 0 packages/{vectors3 => vectors}/src/major.ts | 0 packages/{vectors3 => vectors}/src/map.ts | 0 packages/vectors/src/mat23.ts | 309 ------ packages/vectors/src/mat33.ts | 355 ------- packages/vectors/src/mat44.ts | 598 ------------ packages/{vectors3 => vectors}/src/max.ts | 0 packages/{vectors3 => vectors}/src/min.ts | 0 packages/{vectors3 => vectors}/src/minor.ts | 0 .../{vectors3 => vectors}/src/mix-bilinear.ts | 0 .../{vectors3 => vectors}/src/mix-cubic.ts | 0 .../src/mix-quadratic.ts | 0 packages/{vectors3 => vectors}/src/mix.ts | 0 packages/{vectors3 => vectors}/src/mixn.ts | 0 packages/{vectors3 => vectors}/src/mod.ts | 0 packages/{vectors3 => vectors}/src/modn.ts | 0 packages/{vectors3 => vectors}/src/mul.ts | 0 packages/{vectors3 => vectors}/src/muln.ts | 0 packages/{vectors3 => vectors}/src/muls.ts | 0 packages/{vectors3 => vectors}/src/neg.ts | 0 .../{vectors3 => vectors}/src/normalize.ts | 0 .../{vectors3 => vectors}/src/ortho-normal.ts | 0 .../src/perpendicular.ts | 0 packages/{vectors3 => vectors}/src/polar.ts | 0 packages/{vectors3 => vectors}/src/pow.ts | 0 packages/{vectors3 => vectors}/src/pown.ts | 0 packages/{vectors3 => vectors}/src/project.ts | 0 packages/{vectors3 => vectors}/src/random.ts | 0 packages/{vectors3 => vectors}/src/reflect.ts | 0 packages/{vectors3 => vectors}/src/refract.ts | 0 .../src/rotate-around-axis.ts | 0 .../src/rotate-around-point.ts | 0 packages/{vectors3 => vectors}/src/rotate.ts | 0 packages/{vectors3 => vectors}/src/round.ts | 0 packages/{vectors3 => vectors}/src/set.ts | 0 packages/{vectors3 => vectors}/src/setc.ts | 0 packages/{vectors3 => vectors}/src/setn.ts | 0 packages/{vectors3 => vectors}/src/sets.ts | 0 packages/{vectors3 => vectors}/src/setsn.ts | 0 packages/{vectors3 => vectors}/src/sign.ts | 0 .../{vectors3 => vectors}/src/signed-area.ts | 0 packages/{vectors3 => vectors}/src/sin.ts | 0 packages/{vectors3 => vectors}/src/sinh.ts | 0 .../{vectors3 => vectors}/src/smoothstep.ts | 0 packages/{vectors3 => vectors}/src/sqrt.ts | 0 packages/{vectors3 => vectors}/src/step.ts | 0 packages/{vectors3 => vectors}/src/sub.ts | 0 packages/{vectors3 => vectors}/src/subm.ts | 0 packages/{vectors3 => vectors}/src/submn.ts | 0 packages/{vectors3 => vectors}/src/subn.ts | 0 packages/{vectors3 => vectors}/src/subs.ts | 0 packages/{vectors3 => vectors}/src/sum.ts | 0 packages/{vectors3 => vectors}/src/swizzle.ts | 0 packages/{vectors3 => vectors}/src/tan.ts | 0 packages/{vectors3 => vectors}/src/tanh.ts | 0 packages/{vectors3 => vectors}/src/trunc.ts | 0 packages/vectors/src/vec2.ts | 803 ++-------------- packages/vectors/src/vec3.ts | 893 ++---------------- packages/vectors/src/vec4.ts | 730 ++------------ packages/{vectors3 => vectors}/src/wrap.ts | 0 packages/vectors/test/gvec.ts | 82 -- packages/{vectors3 => vectors}/test/index.ts | 0 packages/vectors/test/swizzle.ts | 88 -- packages/vectors/test/vec2.ts | 103 -- packages/vectors/test/vec3.ts | 111 --- packages/vectors/test/vec4.ts | 115 --- packages/vectors3/.npmignore | 13 - packages/vectors3/LICENSE | 201 ---- packages/vectors3/README.md | 401 -------- packages/vectors3/package.json | 101 -- packages/vectors3/src/api.ts | 114 --- packages/vectors3/src/gvec.ts | 167 ---- packages/vectors3/src/index.ts | 113 --- packages/vectors3/src/vec2.ts | 127 --- packages/vectors3/src/vec3.ts | 130 --- packages/vectors3/src/vec4.ts | 135 --- packages/vectors3/test/tsconfig.json | 11 - packages/vectors3/tsconfig.json | 11 - 138 files changed, 925 insertions(+), 7097 deletions(-) delete mode 100644 packages/vectors/bench/index.js rename packages/{vectors3 => vectors}/src/abs.ts (100%) rename packages/{vectors3 => vectors}/src/acos.ts (100%) rename packages/{vectors3 => vectors}/src/add.ts (100%) rename packages/{vectors3 => vectors}/src/addm.ts (100%) rename packages/{vectors3 => vectors}/src/addmn.ts (100%) rename packages/{vectors3 => vectors}/src/addn.ts (100%) rename packages/{vectors3 => vectors}/src/adds.ts (100%) rename packages/{vectors3 => vectors}/src/addw.ts (100%) rename packages/{vectors3 => vectors}/src/angle-between.ts (100%) rename packages/{vectors3 => vectors}/src/asin.ts (100%) rename packages/{vectors3 => vectors}/src/bisect.ts (100%) rename packages/{vectors3 => vectors}/src/cartesian.ts (100%) rename packages/{vectors3 => vectors}/src/ceil.ts (100%) rename packages/{vectors3 => vectors}/src/clamp.ts (100%) rename packages/{vectors3 => vectors}/src/clampn.ts (100%) delete mode 100644 packages/vectors/src/codegen.ts delete mode 100644 packages/vectors/src/common.ts rename packages/{vectors3 => vectors}/src/compare.ts (100%) rename packages/{vectors3 => vectors}/src/copy.ts (100%) rename packages/{vectors3 => vectors}/src/cos.ts (100%) rename packages/{vectors3 => vectors}/src/cosh.ts (100%) rename packages/{vectors3 => vectors}/src/cross.ts (100%) rename packages/{vectors3 => vectors}/src/dist-chebyshev.ts (100%) rename packages/{vectors3 => vectors}/src/dist-manhattan.ts (100%) rename packages/{vectors3 => vectors}/src/dist.ts (100%) rename packages/{vectors3 => vectors}/src/distsq.ts (100%) rename packages/{vectors3 => vectors}/src/div.ts (100%) rename packages/{vectors3 => vectors}/src/divn.ts (100%) rename packages/{vectors3 => vectors}/src/divs.ts (100%) rename packages/{vectors3 => vectors}/src/dot.ts (100%) rename packages/{vectors3 => vectors}/src/dotc.ts (100%) rename packages/{vectors3 => vectors}/src/dots.ts (100%) rename packages/{vectors3 => vectors}/src/empty.ts (100%) rename packages/{vectors3 => vectors}/src/eqdelta.ts (100%) rename packages/{vectors3 => vectors}/src/exp.ts (100%) rename packages/{vectors3 => vectors}/src/face-forward.ts (100%) rename packages/{vectors3 => vectors}/src/floor.ts (100%) rename packages/{vectors3 => vectors}/src/fract.ts (100%) rename packages/{vectors3 => vectors}/src/heading.ts (100%) rename packages/{vectors3 => vectors}/src/homogeneous.ts (100%) rename packages/{vectors3 => vectors}/src/internal/accessors.ts (100%) rename packages/{vectors3 => vectors}/src/internal/avec.ts (100%) rename packages/{vectors3 => vectors}/src/internal/codegen.ts (100%) rename packages/{vectors3 => vectors}/src/internal/templates.ts (100%) rename packages/{vectors3 => vectors}/src/internal/vec-utils.ts (100%) rename packages/{vectors3 => vectors}/src/internal/vop.ts (100%) rename packages/{vectors3 => vectors}/src/invert.ts (100%) rename packages/{vectors3 => vectors}/src/invsqrt.ts (100%) rename packages/{vectors3 => vectors}/src/jitter.ts (100%) rename packages/{vectors3 => vectors}/src/limit.ts (100%) rename packages/{vectors3 => vectors}/src/log.ts (100%) rename packages/{vectors3 => vectors}/src/madd.ts (100%) rename packages/{vectors3 => vectors}/src/maddn.ts (100%) rename packages/{vectors3 => vectors}/src/mag.ts (100%) rename packages/{vectors3 => vectors}/src/magsq.ts (100%) rename packages/{vectors3 => vectors}/src/major.ts (100%) rename packages/{vectors3 => vectors}/src/map.ts (100%) delete mode 100644 packages/vectors/src/mat23.ts delete mode 100644 packages/vectors/src/mat33.ts delete mode 100644 packages/vectors/src/mat44.ts rename packages/{vectors3 => vectors}/src/max.ts (100%) rename packages/{vectors3 => vectors}/src/min.ts (100%) rename packages/{vectors3 => vectors}/src/minor.ts (100%) rename packages/{vectors3 => vectors}/src/mix-bilinear.ts (100%) rename packages/{vectors3 => vectors}/src/mix-cubic.ts (100%) rename packages/{vectors3 => vectors}/src/mix-quadratic.ts (100%) rename packages/{vectors3 => vectors}/src/mix.ts (100%) rename packages/{vectors3 => vectors}/src/mixn.ts (100%) rename packages/{vectors3 => vectors}/src/mod.ts (100%) rename packages/{vectors3 => vectors}/src/modn.ts (100%) rename packages/{vectors3 => vectors}/src/mul.ts (100%) rename packages/{vectors3 => vectors}/src/muln.ts (100%) rename packages/{vectors3 => vectors}/src/muls.ts (100%) rename packages/{vectors3 => vectors}/src/neg.ts (100%) rename packages/{vectors3 => vectors}/src/normalize.ts (100%) rename packages/{vectors3 => vectors}/src/ortho-normal.ts (100%) rename packages/{vectors3 => vectors}/src/perpendicular.ts (100%) rename packages/{vectors3 => vectors}/src/polar.ts (100%) rename packages/{vectors3 => vectors}/src/pow.ts (100%) rename packages/{vectors3 => vectors}/src/pown.ts (100%) rename packages/{vectors3 => vectors}/src/project.ts (100%) rename packages/{vectors3 => vectors}/src/random.ts (100%) rename packages/{vectors3 => vectors}/src/reflect.ts (100%) rename packages/{vectors3 => vectors}/src/refract.ts (100%) rename packages/{vectors3 => vectors}/src/rotate-around-axis.ts (100%) rename packages/{vectors3 => vectors}/src/rotate-around-point.ts (100%) rename packages/{vectors3 => vectors}/src/rotate.ts (100%) rename packages/{vectors3 => vectors}/src/round.ts (100%) rename packages/{vectors3 => vectors}/src/set.ts (100%) rename packages/{vectors3 => vectors}/src/setc.ts (100%) rename packages/{vectors3 => vectors}/src/setn.ts (100%) rename packages/{vectors3 => vectors}/src/sets.ts (100%) rename packages/{vectors3 => vectors}/src/setsn.ts (100%) rename packages/{vectors3 => vectors}/src/sign.ts (100%) rename packages/{vectors3 => vectors}/src/signed-area.ts (100%) rename packages/{vectors3 => vectors}/src/sin.ts (100%) rename packages/{vectors3 => vectors}/src/sinh.ts (100%) rename packages/{vectors3 => vectors}/src/smoothstep.ts (100%) rename packages/{vectors3 => vectors}/src/sqrt.ts (100%) rename packages/{vectors3 => vectors}/src/step.ts (100%) rename packages/{vectors3 => vectors}/src/sub.ts (100%) rename packages/{vectors3 => vectors}/src/subm.ts (100%) rename packages/{vectors3 => vectors}/src/submn.ts (100%) rename packages/{vectors3 => vectors}/src/subn.ts (100%) rename packages/{vectors3 => vectors}/src/subs.ts (100%) rename packages/{vectors3 => vectors}/src/sum.ts (100%) rename packages/{vectors3 => vectors}/src/swizzle.ts (100%) rename packages/{vectors3 => vectors}/src/tan.ts (100%) rename packages/{vectors3 => vectors}/src/tanh.ts (100%) rename packages/{vectors3 => vectors}/src/trunc.ts (100%) rename packages/{vectors3 => vectors}/src/wrap.ts (100%) delete mode 100644 packages/vectors/test/gvec.ts rename packages/{vectors3 => vectors}/test/index.ts (100%) delete mode 100644 packages/vectors/test/swizzle.ts delete mode 100644 packages/vectors/test/vec2.ts delete mode 100644 packages/vectors/test/vec3.ts delete mode 100644 packages/vectors/test/vec4.ts delete mode 100644 packages/vectors3/.npmignore delete mode 100644 packages/vectors3/LICENSE delete mode 100644 packages/vectors3/README.md delete mode 100644 packages/vectors3/package.json delete mode 100644 packages/vectors3/src/api.ts delete mode 100644 packages/vectors3/src/gvec.ts delete mode 100644 packages/vectors3/src/index.ts delete mode 100644 packages/vectors3/src/vec2.ts delete mode 100644 packages/vectors3/src/vec3.ts delete mode 100644 packages/vectors3/src/vec4.ts delete mode 100644 packages/vectors3/test/tsconfig.json delete mode 100644 packages/vectors3/tsconfig.json diff --git a/packages/vectors/README.md b/packages/vectors/README.md index cc8b5bc054..a2492a17c8 100644 --- a/packages/vectors/README.md +++ b/packages/vectors/README.md @@ -1,7 +1,7 @@ -# @thi.ng/vectors +# @thi.ng/vectors3 -[![npm version](https://img.shields.io/npm/v/@thi.ng/vectors.svg)](https://www.npmjs.com/package/@thi.ng/vectors) -![npm downloads](https://img.shields.io/npm/dm/@thi.ng/vectors.svg) +[![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/vectors3.svg)](https://www.npmjs.com/package/@thi.ng/vectors3) +![npm downloads](https://img.shields.io/npm/dm/@thi.ng/vectors3.svg) [![Twitter Follow](https://img.shields.io/twitter/follow/thing_umbrella.svg?style=flat-square&label=twitter)](https://twitter.com/thing_umbrella) This project is part of the @@ -10,14 +10,32 @@ This project is part of the - [About](#about) - - [Vectors](#vectors) - - [Matrices](#matrices) + - [Features](#features) + - [Related packages](#related-packages) - [Installation](#installation) - [Dependencies](#dependencies) - [Usage examples](#usage-examples) - - [Basics](#basics) - - [Vector classes & interleaved vectors in large buffer](#vector-classes--interleaved-vectors-in-large-buffer) - - [Image RGB grayscale conversion](#image-rgb-grayscale-conversion) +- [API](#api) + - [Constants](#constants) + - [Component setters & copying](#component-setters--copying) + - [Component swizzling](#component-swizzling) + - [Vector creation](#vector-creation) + - [Basic vector math](#basic-vector-math) + - [Multiply-add](#multiply-add) + - [Constraints](#constraints) + - [Cross product](#cross-product) + - [Dot product](#dot-product) + - [Interpolation](#interpolation) + - [Normalization / magnitude](#normalization--magnitude) + - [Distances](#distances) + - [Orientation](#orientation) + - [Rotations](#rotations) + - [Polar / cartesian conversion](#polar--cartesian-conversion) + - [Randomness](#randomness) + - [Unary vector math ops](#unary-vector-math-ops) + - [Vector array batch processing](#vector-array-batch-processing) + - [Comparison / equality](#comparison--equality) + - [Code generator](#code-generator) - [Authors](#authors) - [License](#license) @@ -25,330 +43,350 @@ This project is part of the ## About -This package provides vector and matrix operations as plain functions -and class wrappers with fluid interface. All functions support any array -/ typed array storage, incl. mapped views of larger buffers (e.g. for -WebGL / WASM interop, pixel buffers). Additionally, vectors support -flexible data layouts, incl. [AOS / -SOA](https://en.wikipedia.org/wiki/AOS_and_SOA), striped, interleaved, -aligned etc. +This package provides 350+ largely code generated functions & supporting +types to perform vector operations on fixed and arbitrary-length +vectors, both packed and strided (i.e. where individual vector +components are not successive array elements, for example in SOA +layouts). + +### Features + +- Small & fast: The vast majority of these functions are code generated + with fixed-sized versions not using any loops. Minified + gzipped, the + entire package is ~7.6KB. +- Unified API: Any `ArrayLike` type can be used as vector containers + (e.g. JS arrays, typed arrays, custom impls). Most functions are + implemented as multi-methods, dispatching to any potentially optimized + versions based on given vector arguments. +- Highly modular: Each function is defined in its own submodule / file. + In addition to each generic multi-method base function, all + fixed-length optimized versions are exported too. E.g. If + [`add`](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/add.ts) + performs vector addition on arbitrary-length vectors, `add2`, `add3`, + `add4` are the optimized version for fixed-length vectors... +- Extensible: Custom vector ops can be defined in a similar manner using + the provided code generation helpers (see + [vop.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/vop.ts) + and + [codegen.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/codegen.ts) + for details). +- Immutable by default: Each operation producing a vector result takes + an output vector as first argument. If `null`, the vector given as 2nd + argument will be used as output (i.e. for mutation). +- Strided vector support is handled via the lightweight + [`Vec2/3/4`](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/vec2.ts) + class wrappers and the + [`gvec()`](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/gvec.ts) + proxy (for generic, arbitrary-length vectors). These types behave like + normal arrays (for read/write operations) and are also iterable. A + subset of functions (suffixed with `S`, e.g. + [`addS`](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/adds.ts) + vs. `add`) also support striding without the need for extra class + wrappers. This is handled via additional index and stride arguments + for each input/output vector. These functions are only available for + sizes 2 / 3 / 4, though. +- Random vector functions support the `IRandom` interface defined by + [@thi.ng/random](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/random) + to work with custom (P)RNGs. If omitted, the built-in `Math.random()` + will be used. + +### Related packages + +- [@thi.ng/color](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/color) - vector based color operations / conversions +- [@thi.ng/geom2](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/geom2) - 2D/3D geometry types & operations +- [@thi.ng/matrices](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/matrices) - 2x2, 2x3, 3x3, 4x4 matrix & quaternion ops +- [@thi.ng/vector-pools](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vector-pools) - operations on memory mapped data -**This package will soon be replaced by the currently still unreleased -[@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3) -and -[@thi.ng/matrices](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/matrices) -packages** - -### Vectors +## Installation -In addition to [arbitrary sized -vectors](https://github.com/thi-ng/umbrella/tree/master/packages/vectors/src/gvec.ts), -the library provides these optimized fixed-sized versions: +```bash +yarn add @thi.ng/vectors3 +``` -- [Vec2](https://github.com/thi-ng/umbrella/tree/master/packages/vectors/src/vec2.ts) -- [Vec3](https://github.com/thi-ng/umbrella/tree/master/packages/vectors/src/vec3.ts) -- [Vec4](https://github.com/thi-ng/umbrella/tree/master/packages/vectors/src/vec4.ts) +## Dependencies -#### Vector classes +- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/api) +- [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/master/packages/checks) +- [@thi.ng/equiv](https://github.com/thi-ng/umbrella/tree/master/packages/equiv) +- [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/master/packages/errors) +- [@thi.ng/math](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/math) +- [@thi.ng/random](https://github.com/thi-ng/umbrella/tree/master/packages/random) +- [@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/master/packages/transducers) -All of the vector operations listed below are also available via class -wrappers of strided buffer views. These vector classes (`Vec2/3/4`) are -array-like themselves and provide array index and `.x`, `.y`, `.z`, `.w` -property accessors (including `.length`). The `GVec` class wrapper only -provides `.length` read access and element access via `getAt()` and -`setAt()`. All classes are iterable and provide `toString()` and -`toJSON()` implementations. +## Usage examples ```ts -buf = [0, 1, 0, 2, 0, 3]; +import * as v from "@thi.ng/vectors3"; -// create Vec3 view from index 1, w/ stride 2 -a = new v.Vec3(buf, 1, 2); +// immutable vector addition (1st arg is result) +v.add([], [1, 2, 3, 4], [10, 20, 30, 40]) +// [11, 22, 33, 44] -a[0] *= 10; -a[1] *= 100; -a[2] *= 1000; +// mutable addition (if first arg is null) +a = [1, 2, 3]; +v.add(null, a, a); +// [2, 4, 6] -a.x // 10 -a.y // 200 -a.z // 3000 -a.length // 3 +// multiply-add (o = a + b * c) +v.madd([], [1, 2], [10, 20], [0.5, 0.25]); +// [6, 7] -// iterable -[...a] -// [ 10, 200, 3000 ] +// multiply-add w/ scalar (o = a + b * n) +v.maddN([], [1, 2], [10, 20], 0.5); +// [6, 12] -buf -// [ 0, 10, 0, 200, 0, 3000 ] -``` +// scalar addition w/ arbitrary length & strided vector +v.addN([], gvec([0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0], 3, 1, 4), 10); +// [11, 12, 13] -#### Supported operations - -Note: Most functions are provided in different (optimized) versions, -depending on vector size. E.g. `add` performs vector addition for -arbitrary sizes, `add2` for 2D vectors, `add3` for 3D, `add4` for 4D... -**Class wrapper methods use the non-suffixed naming.** - -All vector operations (regardless of size) operate on any array-like -buffer and accept optional start indices and component strides (number -of elements (+1) between individual vector components). This allows for -zero-copy vector operations on sections of larger buffers. The default -start index is 0, default stride 1. See examples below and -[tests](https://github.com/thi-ng/umbrella/tree/master/packages/vectors/test/). - -Naming conventions (suffixes): - -- `N` = uniform: 2nd or 3rd arg is a scalar which will be used for all - vector components, e.g. `setN3([], 0) => [0, 0, 0]` -- `S` = scalar: args are individual scalar values, - e.g. `setS3([], 10, 20, 30) => [10, 20, 30]` -- `o` = output: operation writes to separate output vector (1st arg), e.g. - `add2o([], [1,2], [10, 20])` - -| Operation | Generic | 2D | 3D | 4D | -|---------------------------------|--------------|-----------------------|---------------------|------------------| -| Get vector (dense copy) | `get` | `get2` | `get3` | `get4` | -| Set vector components (vector) | `set` | `set2` | `set3` | `set4` | -| Set vector components (uniform) | `setN` | `setN2` | `setN3` | `setN4` | -| Set vector components (scalars) | | `setS2` | `setS3` | `setS4` | -| Swizzle vector components | | `swizzle2` | `swizzle3` | `swizzle4` | -| Swap vectors | | `swap2` | `swap3` | `swap4` | -| Equality (w/ epsilon) | `eqDelta` | `eqDelta2` | `eqDelta3` | `eqDelta4` | -| Vector addition | `add` | `add2` | `add3` | `add4` | -| | | `add2o` | `add3o` | `add4o` | -| Vector subtraction | `sub` | `sub2` | `sub3` | `sub4` | -| | | `sub2o` | `sub3o` | `sub4o` | -| Vector multiplication | `mul` | `mul2` | `mul3` | `mul4` | -| | | `mul2o` | `mul3o` | `mul4o` | -| Vector division | `div` | `div2` | `div3` | `div4` | -| | | `div2o` | `div3o` | `div4o` | -| Uniform scalar addition | `addN` | `addN2` | `addN3` | `addN4` | -| | | `addN2o` | `addN3o` | `addN4o` | -| Uniform scalar subtraction | `subN` | `subN2` | `subN3` | `subN4` | -| | | `subN2o` | `subN3o` | `subN4o` | -| Uniform scalar multiply | `mulN` | `mulN2` | `mulN3` | `mulN4` | -| | | `mulN2o` | `mulN3o` | `mulN4o` | -| Uniform scalar multiply | `divN` | `divN2` | `divN3` | `divN4` | -| | | `divN2o` | `divN3o` | `divN4o` | -| Vector negation | `neg` | `neg2` | `neg3` | `neg4` | -| Multiply-add vectors | `madd` | `madd2` | `madd3` | `madd4` | -| Multiply-add scalar | `maddN` | `maddN2` | `maddN3` | `maddN4` | -| Linear interpolation (vector) | `mix` | `mix2` | `mix3` | `mix4` | -| | | `mix2o` | `mix3o` | `mix4o` | -| Linear interpolation (uniform) | `mixN` | `mixN2` | `mixN3` | `mixN4` | -| | | `mixN2o` | `mixN3o` | `mixN4o` | -| Bilinear interpolation* | | `mixBilinear2` | `mixBilinear3` | `mixBilinear4` | -| Dot product | `dot` | `dot2` | `dot3` | `dot4` | -| Cross product | | `cross2` | `cross3` | | -| Magnitude | `mag` | `mag2` | `mag3` | `mag4` | -| Magnitude (squared) | `magSq` | `magSq2` | `magSq3` | `magSq4` | -| Normalize (w/ opt length) | `normalize` | `normalize2` | `normalize3` | `normalize4` | -| Limit to length | | `limit2` | `limit3` | `limit4` | -| Distance | `dist` | `dist2` | `dist3` | `dist4` | -| Distance (squared) | `distSq` | `distSq2` | `distSq3` | `distSq4` | -| Manhattan distance | | `distManhattan2` | `distManhattan3` | `distManhattan4` | -| Chebyshev distance | | `distChebyshev2` | `distChebyshev3` | `distChebyshev4` | -| Reflection | | `reflect2` | `reflect3` | `reflect4` | -| Refraction | | `refract2` | `refract3` | `refract4` | -| Perpendicular | | `perpendicularLeft2` | | | -| | | `perpendicularRight2` | | | -| RotationX | | | `rotateX3` | | -| RotationY | | | `rotateY3` | | -| RotationZ | | `rotate2` | `rotateZ3` | | -| Rotation around point | | `rotateAroundPoint2` | | | -| Rotation around axis | | | `rotateAroundAxis3` | | -| Heading XY | | `heading2` | `headingXY3` | | -| Heading XZ | | | `headingXZ3` | | -| Heading YZ | | | `headingYZ3` | | -| Angle between vectors | | `angleBetween2` | `angleBetween3` | | -| Bisector angle | | `bisect2` | | | -| Cartesian -> Polar | | `toPolar2` | `toSpherical3` | | -| Polar -> Cartesian | | `toCartesian2` | `toCartesian3` | | -| Cartesian -> Cylindrical | | | `toCylindrical3` | | -| Cylindrical -> Cartesian | | | `fromCylindrical3` | | -| Minor axis | | `minorAxis2` | `minorAxis3` | `minorAxis4` | -| Major axis | | `majorAxis2` | `majorAxis3` | `majorAxis4` | -| Minimum | `min` | `min2` | `min3` | `min4` | -| Maximum | `max` | `max2` | `max3` | `max4` | -| Range clamping | `clamp` | `clamp2` | `clamp3` | `clamp4` | -| Step (like GLSL) | `step` | `step2` | `step3` | `step4` | -| SmoothStep (like GLSL) | `smoothStep` | `smoothStep2` | `smoothStep3` | `smoothStep4` | -| Absolute value | `abs` | `abs2` | `abs3` | `abs4` | -| Sign (w/ opt epsilon) | `sign` | `sign2` | `sign3` | `sign4` | -| Round down | `floor` | `floor2` | `floor3` | `floor4` | -| Round up | `ceil` | `ceil2` | `ceil3` | `ceil4` | -| Square root | `sqrt` | `sqrt2` | `sqrt3` | `sqrt4` | -| Power (vector) | `pow` | `pow2` | `pow3` | `pow4` | -| Power (uniform) | `powN` | `powN2` | `powN3` | `powN4` | - -(*) Static method in class wrapper - -### Matrices - -All matrix types are in WebGL layout (column major) and densely packed -(stride always 1). **As with vectors, class wrapper methods use the -non-suffixed naming.** - -- [Mat23](https://github.com/thi-ng/umbrella/tree/master/packages/vectors/src/mat23.ts) -- [Mat33](https://github.com/thi-ng/umbrella/tree/master/packages/vectors/src/mat33.ts) -- [Mat44](https://github.com/thi-ng/umbrella/tree/master/packages/vectors/src/mat44.ts) - -| Operation | 2x3 | 3x3 | 4x4 | -|--------------------------------------|-------------------------|---------------|---------------------| -| Set identity* | `identity23` | `identity33` | `identity44` | -| Get matrix components (dense copy) | `get23` | `get33` | `get44` | -| Set matrix components (matrix) | `set23` | `set33` | `set44` | -| Set matrix components (scalars) | `setS23` | `setS33` | `setS44` | -| Create rotation matrix* | | `rotationX33` | `rotationX44` | -| | | `rotationY33` | `rotationY44` | -| | `rotation23` | `rotationZ33` | `rotationZ44` | -| | `rotationAroundPoint23` | | | -| Create scale matrix* (vector) | `scaleV23` | `scaleV33` | `scaleV44` | -| Create scale matrix* (uniform) | `scaleN23` | `scaleN33` | `scaleN44` | -| Create scale matrix* (scalars) | `scaleS23` | `scaleS33` | `scaleS44` | -| | `scaleWithCenter23` | | `scaleWithCenter44` | -| Create translation matrix* (vector) | `translationV23` | | `translationV44` | -| Create translation matrix* (scalars) | `translationS23` | | `translationS44` | -| Create skew matrix* | `skewX23` / `shearX23` | | | -| | `skewY23` / `shearY23` | | | -| Create projection matrix* | | | `projection` | -| | | | `ortho` | -| | | | `frustum` | -| Create camera matrix* | | | `lookAt` | -| Matrix multiply | `mul23` | `mul33` | `mul44` | -| Matrix concatenation* (multiple) | `concat23` | `concat33` | `concat44` | -| Matrix vector multiply | `mulV23` | `mulV33` | `mulV44` (Vec4) | -| | | | `mulV344` (Vec3) | -| Determinant | `det23` | `det33` | `det44` | -| Matrix inversion | `invert23` | `invert33` | `invert44` | -| Matrix transpose | | `transpose33` | `transpose44` | - -(*) Static method in class wrapper +v.dist([1, 2], [100, 200]); +// 221.37072977247917 -## Installation +v.distManhattan([1, 2], [100, 200]); +// 297 -```bash -yarn add @thi.ng/vectors +v.distChebyshev([1, 2], [100, 200]); +// 198 + +v.mixN([], [1, 2], [10, 20], 0.5); +// [5.5, 11] + +v.fromHomogeneous([], [100, 200, 0.5]); +// [200, 400] + +v.swizzle4([], [1, 2], 1, 1, 0, 0); +// [ 2, 2, 1, 1 ] ``` -## Dependencies +## API -- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/master/packages/api) -- [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/master/packages/checks) -- [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/master/packages/errors) +### Constants -## Usage examples +- `MAX2` / `MAX3` / `MAX4` - each component `+Infinity` +- `MIN2` / `MIN3` / `MIN4` - each component `-Infinity` +- `ONE2` / `ONE3` / `ONE4` - each component `1` +- `ZERO2` / `ZERO3` / `ZERO4` - each component `0` +- `X2` / `X3` / `X4` - positive X axis +- `Y2` / `Y3` / `Y4` - positive Y axis +- `Z3` / `Z4` - positive Z axis +- `W4` - positive W axis -### Basics +### Component setters & copying -```ts -import * as v from "@thi.ng/vectors"; +- `set` / `set2` / `set3` / `set4` +- `setC` / `setC2` / `setC3` / `setC4` / `setC6` +- `setN` / `setN2` / `setN3` / `setN4` +- `setS` / `setS2` / `setS3` / `setS4` +- `setSN2` / `setSN3` / `setSN4` +- `copy` +- `empty` +- `one` +- `zero` -// raw vector addition -v.add4([1, 2, 3, 4], [10, 20, 30, 40]); -// [ 11, 22, 33, 44 ] +### Component swizzling -// with custom layout -// here 3x 3D vectors in SOA layout: -// [x, x, x, y, y, y, z, z, z] -points = [1, 4, 7, 2, 5, 8, 3, 6, 9]; +- `swizzle2` / `swizzle3` / `swizzle4` +- `swapXY` / `swapXZ` / `swapYZ` -// specify start indices and stride lengths -// update 1st vector -v.add3(points, [100, 200, 300], 0, 0, 3, 1); -// [ 101, 4, 7, 202, 5, 8, 303, 6, 9 ] +### Vector creation -// update 2nd vector -v.add3(points, [100, 200, 300], 1, 0, 3, 1); -// [ 101, 104, 7, 202, 205, 8, 303, 306, 9 ] +Functions to create wrapped vector instances: -// update 3rd vector -v.add3(points, [100, 200, 300], 2, 0, 3, 1); -// [ 101, 104, 107, 202, 205, 208, 303, 306, 309 ] +- `vec2` / `vec2n` +- `vec3` / `vec3n` +- `vec4` / `vec4n` +- `gvec` -// add 1st and 3rd vector and extract result -v.get3(v.add3(points, points, 0, 2, 3, 3), 0, 3); -// [ 208, 410, 612 ] +Wrap existing vanilla vectors: -// re-arrange vector components into new vector -// the last 4 args define component order: +- `asVec2` / `asVec3` / `asVec4` -// YXWZ -v.swizzle4([], [10, 20, 30, 40], 1, 0, 3, 2); -// [ 20, 10, 40, 30 ] +Vanilla vector (array) factories: -// XXZZ -v.swizzle4([], [10, 20, 30, 40], 0, 0, 2, 2); -// [ 10, 10, 30, 30 ] +- `ones` +- `zeroes` -// arbitrary length vectors -norm = v.normalize([1, 2, 3, 4, 5, 6, 7, 8, 6, 4]); -// [ 0.0625, 0.125, 0.1875, 0.25, 0.3125, 0.375, 0.4375, 0.5, 0.375, 0.25 ] +### Basic vector math -v.mag(norm); -// 1 -``` +#### Vector / vector -### Vector classes & interleaved vectors in large buffer +Component wise op with 2 input vectors: -```ts -// element stride 3 + 2 + 4 = 9 -buf = [ - // pos uv color (rgba) - 0,0,0, 0,0, 1,0,0,1, - 100,0,0, 1,0, 1,1,0,1, - 100,100,0, 1,1, 1,0,1,1, - 0,100,0, 0,1, 0,1,1,1, -]; - -// create memory mapped vector instances (using classes) -pos = v.Vec3.mapBuffer(buf, 4, 0, 1, 9); // offset = 0 -uv = v.Vec2.mapBuffer(buf, 4, 3, 1, 9); // offset = 3 -col = v.Vec4.mapBuffer(buf, 4, 5, 1, 9); // offset = 5 - -console.log(`pos: ${pos[1]}, uv: ${uv[1]}, color: ${col[1]}`); -// pos: [100, 0, 0], uv: [1, 0], color: [1, 1, 0, 1] - -// compute centroid -centroid = pos.reduce((c, p) => c.add(p), v.vec3()).divN(pos.length); -// Vec3 { buf: [ 50, 50, 0 ], i: 0, s: 1 } - -// build matrix to transform geometry -tx = v.Mat44.concat( - v.Mat44.scale(0.01), - v.Mat44.translation(centroid.copy().neg()), - v.Mat44.rotationZ(v.rad(90)), -); - -// apply transform to all positions -pos.forEach((p) => tx.mulV3(p)); -``` +- `add` / `add2` / `add3` / `add4` +- `div` / `div2` / `div3` / `div4` +- `mul` / `mul2` / `mul3` / `mul4` +- `sub` / `sub2` / `sub3` / `sub4` +- `mod` / `mod2` / `mod3` / `mod4` +- `pow` / `pow2` / `pow3` / `pow4` -### Image RGB grayscale conversion +#### Vector / scalar -```ts -canvas = document.getElementById("main"); -img = canvas.getContext("2d").getImageData(0,0, canvas.width, canvas.height); - -v.transformVectors1( - // multiply each RGB vector w/ weights - // then use result for all 3 color channels - (a, b, ia, ib, sa, sb) => - v.setN3(a, v.dot3(a, b, ia, ib, sa, sb), ia, sa), - // pixel buffer - img, - // RGB weight coefficients - [0.29, 0.6, 0.11], - // num pixels (RGBA vectors) - canvas.width * canvas.height, - // start indices - 0, 0, - // component strides - 1, 1, - // pixel stride - 4 -); -``` +Component wise op with one input vector and single scalar: + +- `addN` / `addN2` / `addN3` / `addN4` +- `divN` / `divN2` / `divN3` / `divN4` +- `mulN` / `mulN2` / `mulN3` / `mulN4` +- `subN` / `subN2` / `subN3` / `subN4` +- `neg` - same as `mulN(out, v, -1)` +- `modN` / `modN2` / `modN3` / `modN4` +- `powN` / `powN2` / `powN3` / `powN4` + +#### Strided vectors + +Functions for memory mapped, strided vectors (without requiring wrappers): + +- `addS2` / `addS3` / `addS4` +- `divS2` / `divS3` / `divS4` +- `mulS2` / `mulS3` / `mulS4` +- `subS2` / `subS3` / `subS4` + +### Multiply-add + +- `addm` / `addm2` / `addm3` / `addm4` +- `addmN` / `addmN2` / `addmN3` / `addmN4` +- `addW2` / `addW3` / `addW4` / `addW5` +- `madd` / `madd2` / `madd3` / `madd4` +- `maddN` / `maddN2` / `maddN3` / `maddN4` +- `subm` / `subm2` / `subm3` / `subm4` +- `submN` / `submN2` / `submN3` / `submN4` + +### Constraints + +- `clamp` +- `clamp2` / `clamp3` / `clamp4` +- `clampN` / `clampN2` / `clampN3` / `clampN4` +- `clamp01` / `clamp01_2` / `clamp01_3` / `clamp01_4` +- `clamp11` / `clamp11_2` / `clamp11_3` / `clamp11_4` +- `max` / `max2` / `max3` / `max4` +- `min` / `min2` / `min3` / `min4` + +### Cross product + +- `cross2` +- `cross3` +- `orthoNormal3` +- `signedArea2` + +### Dot product + +- `dot` +- `dot2` / `dot3` / `dot4` +- `dotC4` / `dotC6` / `dotC8` +- `dotS2` / `dotS3` / `dotS4` + +### Interpolation + +- `mix` / `mix2` / `mix3` / `mix4` +- `mixN` / `mixN2` / `mixN3` / `mixN4` +- `mixBilinear` / `mixBilinear2` / `mixBilinear3` / `mixBilinear4` +- `mixCubic` +- `mixQuadratic` +- `smoothStep` / `smoothStep2` / `smoothStep3` / `smoothStep4` +- `step` / `step2` / `step3` / `step4` + +### Normalization / magnitude + +- `limit` +- `mag` +- `magSq` / `magSq2` / `magSq3` / `magSq4` +- `normalize` + +### Distances + +- `dist` +- `distSq` / `distSq2` / `distSq3` / `distSq4` +- `distChebyshev` / `distChebyshev2` / `distChebyshev3` / `distChebyshev4` +- `distManhattan` / `distManhattan2` / `distManhattan3` / `distManhattan4` + +### Orientation + +- `angleBetween` +- `angleRatio` +- `bisect2` +- `faceForward` +- `heading` / `headingXY` / `headingXZ` / `headingYZ` +- `perpendicularLeft2` / `perpendicularRight2` +- `project` +- `reflect` +- `refract` + +### Rotations + +(Also see rotation matrices provided by +[@thi.ng/matrices](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/matrices)) + +- `rotateAroundAxis3` +- `rotateAroundPoint2` +- `rotateX` \ `rotateY` \ `rotateZ` + +### Polar / cartesian conversion + +- `cartesian` / `cartesian2` / `cartesian3` +- `polar` / `polar2` / `polar3` + +### Randomness + +All ops support custom PRNG impls based on the +[@thi.ng/random](https://github.com/thi-ng/umbrella/tree/master/packages/random) +`IRandom` interface and use `Math.random` by default: + +- `jitter` +- `randNorm` +- `random` / `random2` / `random3` / `random4` + +### Unary vector math ops + +- `abs` / `abs2` / `abs3` / `abs4` +- `acos` / `acos2` / `acos3` / `acos4` +- `asin` / `asin2` / `asin3` / `asin4` +- `ceil` / `ceil2` / `ceil3` / `ceil4` +- `cos` / `cos2` / `cos3` / `cos4` +- `cosh` / `cosh2` / `cosh3` / `cosh4` +- `exp` / `exp2` / `exp3` / `exp4` +- `floor` / `floor2` / `floor3` / `floor4` +- `fract` / `fract2` / `fract3` / `fract4` +- `fromHomogeneous` / `fromHomogeneous3` / `fromHomogeneous4` +- `invert` / `invert2` / `invert3` / `invert4` +- `invSqrt` / `invSqrt2` / `invSqrt3` / `invSqrt4` +- `log` / `log2` / `log3` / `log4` +- `major` / `major2` / `major3` / `major4` +- `minor` / `minor2` / `minor3` / `minor4` +- `round` / `round2` / `round3` / `round4` +- `sign` / `sign2` / `sign3` / `sign4` +- `sin` / `sin2` / `sin3` / `sin4` +- `sinh` / `sinh2` / `sinh3` / `sinh4` +- `sqrt` / `sqrt2` / `sqrt3` / `sqrt4` +- `sum` / `sum2` / `sum3` / `sum4` +- `tan` / `tan2` / `tan3` / `tan4` +- `tanh` / `tanh2` / `tanh3` / `tanh4` +- `trunc` / `trunc2` / `trunc3` / `trunc4` +- `wrap` / `wrap2` / `wrap3` / `wrap4` + +### Vector array batch processing + +Functions to transform flat / strided buffers w/ vector operations: + +- `mapV` / `mapVN` / `mapVV` / `mapVVN` / `mapVVV` + +### Comparison / equality + +- `comparator2` / `comparator3` / `comparator4` +- `eqDelta` / `eqDelta2` / `eqDelta3` / `eqDelta4` +- `eqDeltaS` +- `eqDeltaArray` + +### Code generator + +- `compile` / `compileG` / `compileGHOF` / `compileHOF` +- `defOp` / `defOpS` / `defFnOp` / `defHofOp` +- `defMathNOp` / `defMathOp` +- `vop` + +For more information about the code generator see: + +- [codegen.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/codegen.ts) +- [templates.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/templates.ts) +- [vop.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/vop.ts) ## Authors @@ -356,4 +394,4 @@ v.transformVectors1( ## License -© 2016 - 2018 Karsten Schmidt // Apache Software License 2.0 +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/packages/vectors/bench/index.js b/packages/vectors/bench/index.js deleted file mode 100644 index 94fafa9a84..0000000000 --- a/packages/vectors/bench/index.js +++ /dev/null @@ -1,56 +0,0 @@ -const Benchmark = require("benchmark"); -const vec = require("../index"); - -const setS2Lib = (buf, n) => { - n *= 2; - for (let i = 0; i < n; i += 2) { - vec.setS2(buf, i, i + 1, i); - } - return buf; -}; - -const setS2Plain = (n) => { - const res = new Array(n); - for (let i = 0; i < n; i++) { - res[i] = [i, i + 1]; - } - return res; -}; - -const op2Lib = (buf, n, op, v) => - vec.transformVectors1(op, setS2Lib(buf, n), v, n, 0, 0, 1, 1, 2); - -const op2Plain = (n, op, v) => { - const res = setS2Plain(n); - for (let i = 0; i < n; i++) { - op(res[i], v); - } - return res; -}; - -const add2 = (a, b) => ( - a[0] += b[0], - a[1] += b[1], - a -); - -new Benchmark.Suite() - .add({ name: "set2 1k (lib, array)", fn: () => setS2Lib(new Array(2 * 1024), 1024) }) - .add({ name: "set2 1k (vanilla)", fn: () => setS2Plain(1024) }) - .add({ name: "set2 4k (lib, array)", fn: () => setS2Lib(new Array(2 * 4 * 1024), 4 * 1024) }) - .add({ name: "set2 4k (vanilla)", fn: () => setS2Plain(4 * 1024) }) - .add({ name: "add2 1k (lib, array)", fn: () => op2Lib(new Array(2 * 1024), 1024, vec.add2, [10, 20]) }) - .add({ name: "add2 1k (lib, f32)", fn: () => op2Lib(new Float32Array(2 * 1024), 1024, vec.add2, [10, 20]) }) - .add({ name: "add2 1k (lib, f64)", fn: () => op2Lib(new Float64Array(2 * 1024), 1024, vec.add2, [10, 20]) }) - .add({ name: "add2 1k (vanilla)", fn: () => op2Plain(1024, add2, [10, 20]) }) - .add({ name: "add2 4k (lib, array)", fn: () => op2Lib(new Array(2 * 4 * 1024), 4 * 1024, vec.add2, [10, 20]) }) - .add({ name: "add2 4k (lib, f32)", fn: () => op2Lib(new Float32Array(2 * 4 * 1024), 4 * 1024, vec.add2, [10, 20]) }) - .add({ name: "add2 4k (lib, f64)", fn: () => op2Lib(new Float64Array(2 * 4 * 1024), 4 * 1024, vec.add2, [10, 20]) }) - .add({ name: "add2 4k (vanilla)", fn: () => op2Plain(4 * 1024, add2, [10, 20]) }) - .on("cycle", (event) => - console.log( - event.target.toString(), - `mean: ${(event.target.stats.mean * 1e3).toFixed(5)}sec` - ) - ) - .run({ "async": false }); \ No newline at end of file diff --git a/packages/vectors/package.json b/packages/vectors/package.json index 0081e3567e..124bed314d 100644 --- a/packages/vectors/package.json +++ b/packages/vectors/package.json @@ -1,7 +1,7 @@ { "name": "@thi.ng/vectors", - "version": "1.4.12", - "description": "Vector algebra for fixed & variable sizes, memory mapped, flexible layouts", + "version": "0.0.1", + "description": "Optimized 2d/3d/4d and arbitrary length vector operations", "module": "./index.js", "main": "./lib/index.js", "umd:main": "./lib/index.umd.js", @@ -10,23 +10,22 @@ "type": "git", "url": "https://github.com/thi-ng/umbrella.git" }, - "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/vectors", + "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/", "author": "Karsten Schmidt ", "license": "Apache-2.0", "scripts": { "build": "yarn clean && yarn build:es6 && yarn build:bundle", "build:es6": "tsc --declaration", - "build:bundle": "../../scripts/bundle-module vectors api checks errors math transducers", + "build:bundle": "../../scripts/bundle-module vectors api checks equiv errors math memoize random transducers", "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", - "doc": "node_modules/.bin/typedoc --mode modules --out doc src", + "doc": "typedoc --mode modules --out doc src", "pub": "yarn build && yarn publish --access public" }, "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", - "benchmark": "^2.1.4", "mocha": "^5.2.0", "nyc": "^13.1.0", "typedoc": "^0.14.0", @@ -35,21 +34,68 @@ "dependencies": { "@thi.ng/api": "^4.2.4", "@thi.ng/checks": "^1.5.14", + "@thi.ng/equiv": "^0.1.15", "@thi.ng/errors": "^0.1.12", "@thi.ng/math": "^0.2.2", + "@thi.ng/memoize": "^0.2.6", + "@thi.ng/random": "^0.1.1", "@thi.ng/transducers": "^2.3.2" }, "keywords": [ + "2D", + "3D", + "4D", + "abitrary length", + "bilinear", + "cartesian", + "chebyshev", + "clamp", + "code generator", + "cubic", + "data structures", + "distance", + "dot product", + "equality", "ES6", - "matrix", + "faceforward", + "geometry", + "gvec", + "heading", + "homogeneous", + "interpolation", + "manhattan", + "magnitude", + "math", "memory mapped", + "normal", + "normalize", + "polar", + "projection", + "quadratic", + "random", + "reflect", + "refract", + "rotation", + "setter", + "smoothstep", + "step", + "strided", "typescript", "webgl", - "wasm", - "vector algebra" + "vector", + "vec2", + "vec3", + "vec4" ], "publishConfig": { "access": "public" }, + "browserslist": [ + "since 2018-07" + ], + "browser": { + "process": false, + "setTimeout": false + }, "sideEffects": false } \ No newline at end of file diff --git a/packages/vectors3/src/abs.ts b/packages/vectors/src/abs.ts similarity index 100% rename from packages/vectors3/src/abs.ts rename to packages/vectors/src/abs.ts diff --git a/packages/vectors3/src/acos.ts b/packages/vectors/src/acos.ts similarity index 100% rename from packages/vectors3/src/acos.ts rename to packages/vectors/src/acos.ts diff --git a/packages/vectors3/src/add.ts b/packages/vectors/src/add.ts similarity index 100% rename from packages/vectors3/src/add.ts rename to packages/vectors/src/add.ts diff --git a/packages/vectors3/src/addm.ts b/packages/vectors/src/addm.ts similarity index 100% rename from packages/vectors3/src/addm.ts rename to packages/vectors/src/addm.ts diff --git a/packages/vectors3/src/addmn.ts b/packages/vectors/src/addmn.ts similarity index 100% rename from packages/vectors3/src/addmn.ts rename to packages/vectors/src/addmn.ts diff --git a/packages/vectors3/src/addn.ts b/packages/vectors/src/addn.ts similarity index 100% rename from packages/vectors3/src/addn.ts rename to packages/vectors/src/addn.ts diff --git a/packages/vectors3/src/adds.ts b/packages/vectors/src/adds.ts similarity index 100% rename from packages/vectors3/src/adds.ts rename to packages/vectors/src/adds.ts diff --git a/packages/vectors3/src/addw.ts b/packages/vectors/src/addw.ts similarity index 100% rename from packages/vectors3/src/addw.ts rename to packages/vectors/src/addw.ts diff --git a/packages/vectors3/src/angle-between.ts b/packages/vectors/src/angle-between.ts similarity index 100% rename from packages/vectors3/src/angle-between.ts rename to packages/vectors/src/angle-between.ts diff --git a/packages/vectors/src/api.ts b/packages/vectors/src/api.ts index afff2a2c45..3f7f631d9a 100644 --- a/packages/vectors/src/api.ts +++ b/packages/vectors/src/api.ts @@ -1,207 +1,114 @@ import { - ICompare, ICopy, IEmpty, IEqualsDelta, - IEquiv, ILength, - NumericArray } from "@thi.ng/api"; -export type Vec = NumericArray; -export type ReadonlyVec = ArrayLike & Iterable; - -export type Mat = NumericArray; -export type ReadonlyMat = ArrayLike & Iterable; - -/** - * A vector operation involving only a single vector. The vector might - * be modified. - */ -export type VecOp1 = (v: Vec, i?: number, s?: number) => T; - -/** - * A vector operation involving 2 vectors. The first vector might be - * modified. - */ -export type VecOp2 = (a: Vec, b: ReadonlyVec, ia?: number, ib?: number, sa?: number, sb?: number) => T; - -/** - * A vector operation involving a vector and a scalar. The vector might - * be modified. - */ -export type VecOpN2 = (a: Vec, n: number, ia?: number, sa?: number) => T; - -/** - * A vector operation involving 2 readonly vectors and storing result - * in output vector `out`. - */ -export type VecOp2o = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, io?: number, ia?: number, ib?: number, so?: number, sa?: number, sb?: number) => T; - -/** - * A vector operation involving a readonly vector and a scalar, - * storing result in output vector `out`. - */ -export type VecOpN2o = (out: Vec, a: ReadonlyVec, n: number, io?: number, ia?: number, so?: number, sa?: number) => T; - -/** - * A vector operation involving 3 vectors. The first vector might be - * modified. - */ -export type VecOp3 = (a: Vec, b: ReadonlyVec, c: ReadonlyVec, ia?: number, ib?: number, ic?: number, sa?: number, sb?: number, sc?: number) => T; - -/** - * A vector operation involving 2 vectors and a scalar. The first - * vector might be modified. - */ -export type VecOpN3 = (a: Vec, b: ReadonlyVec, n: number, ia?: number, ib?: number, sa?: number, sb?: number) => T; - -/** - * A vector operation involving 3 readonly vectors and storing result in - * output vector `out`. - */ -export type VecOp3o = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, io?: number, ia?: number, ib?: number, ic?: number, so?: number, sa?: number, sb?: number, sc?: number) => T; - -/** - * A vector operation involving 3 operands: 2 readonly vectors and a - * scalar, storing result in output vector `out`. - */ -export type VecOpN3o = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, n: number, io?: number, ia?: number, ib?: number, so?: number, sa?: number, sb?: number) => T; - -/** - * A readonly vector operation involving only a single vector. - */ -export type ReadonlyVecOp1 = (v: ReadonlyVec, i?: number, s?: number) => T; - -/** - * A readonly vector operation involving two vectors. - */ -export type ReadonlyVecOp2 = (a: ReadonlyVec, b: ReadonlyVec, ia?: number, ib?: number, sa?: number, sb?: number) => T; - -export type Vec2Coord = 0 | 1; -export type Vec3Coord = 0 | 1 | 2; -export type Vec4Coord = 0 | 1 | 2 | 3; - -export interface IVec extends ILength { - buf: Vec; - i: number; - s: number; -} - -export interface IVector extends +export interface Vec extends Iterable, - IVec, - ICopy, - ICompare, - IEmpty, - IEquiv, - IEqualsDelta, - IDistance, - IDotProduct, - IMagnitude, - IMath, - IMinMax, - IMix, - INormalize { - - set(v: T): T; - setN(n: number): T; -} - -export interface IAngleBetween { - angleBetween(v: Readonly, normalize?: boolean): number; -} + ILength { -export interface IDistance { - dist(v: Readonly): number; - distSq(v: Readonly): number; -} -export interface IDotProduct { - dot(v: Readonly): number; -} - -export interface ICrossProduct { - cross(v: Readonly): R; + [id: number]: number; } -export interface IMagnitude<> { - mag(): number; - magSq(): number; +export interface ReadonlyVec extends + Iterable, + ILength { + readonly [id: number]: number; } -export interface IMath { - add(v: Readonly): T; - sub(v: Readonly): T; - mul(v: Readonly): T; - div(v: Readonly): T; - addN(n: number): T; - subN(n: number): T; - mulN(n: number): T; - divN(n: number): T; - madd(v: Readonly, w: Readonly): T; - maddN(v: Readonly, n: number): T; - msub(v: Readonly, w: Readonly): T; - msubN(v: Readonly, n: number): T; - addNew(v: Readonly, out?: T): T; - subNew(v: Readonly, out?: T): T; - mulNew(v: Readonly, out?: T): T; - divNew(v: Readonly, out?: T): T; - addNewN(n: number, out?: T): T; - subNewN(n: number, out?: T): T; - mulNewN(n: number, out?: T): T; - divNewN(n: number, out?: T): T; - maddNew(v: Readonly, w: Readonly, out?: T): T; - maddNewN(v: Readonly, n: number, out?: T): T; - msubNew(v: Readonly, w: Readonly, out?: T): T; - msubNewN(v: Readonly, n: number, out?: T): T; +export interface StridedVec { + buf: Vec; + offset: number; + stride: number; } -export interface IMinMax { - min(v: Readonly): T; - max(v: Readonly): T; - clamp(min: Readonly, max: Readonly): T; +export interface IVector extends + Vec, + ICopy, + ICopyView, + IEmpty, + IEqualsDelta, + StridedVec { } -export interface IMix { - mix(v: Readonly, t: Readonly): T; - mixN(v: Readonly, t: number): T; - mixNew(v: Readonly, t: Readonly, out?: T): T; - mixNewN(v: Readonly, t: number, out?: T): T; +export interface ICopyView { + copyView(): T; } -export interface INormalize { - /** - * Normalizes vector to given `length`. If omitted, target length - * will be 1.0. - * - * @param length - */ - normalize(length?: number): T; +export interface VectorConstructor { + new(buf: Vec, offset?: number, stride?: number): T; } -export interface IPolar { - /** - * Converts vector into polar coordinates. For the 3D case, these - * will be spherical coordinates. - */ - toPolar(): T; - /** - * Converts vector with polar coordinates into cartesian form. The - * optional `offset` will be added to the result. - * - * @param offset - */ - toCartesian(offset?: Readonly): T; +export interface MultiVecOp { + add(dim: number, op: VOP): VOP; + default(op: VOP): VOP; } -const min = -Infinity; -const max = Infinity; -export const MIN4 = Object.freeze([min, min, min, min]); -export const MAX4 = Object.freeze([max, max, max, max]); +export type VecOpV = (out: Vec, a: ReadonlyVec) => Vec; +export type VecOpN = (out: Vec, n: number) => Vec; +export type VecOpVV = (out: Vec, a: ReadonlyVec, b: ReadonlyVec) => Vec; +export type VecOpVN = (out: Vec, a: ReadonlyVec, n: number) => Vec; +export type VecOpVVV = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => Vec; +export type VecOpVVN = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, n: number) => Vec; +export type VecOpVNN = (out: Vec, a: ReadonlyVec, u: number, v: number) => Vec; +export type VecOpVVVVNN = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, u: number, v: number) => Vec; + +export type VecOpVO = (out: Vec, a: ReadonlyVec, b?: T) => Vec; +export type VecOpOO = (out: Vec, a?: A, b?: B) => Vec; +export type VecOpOOO = (out: Vec, a?: A, b?: B, c?: C) => Vec; +export type VecOpNNO = (out: Vec, a: number, b: number, c?: T) => Vec; + +export type VecOpRoV = (a: ReadonlyVec) => T; +export type VecOpRoVV = (a: ReadonlyVec, b: ReadonlyVec) => T; +export type VecOpRoVVO = (a: ReadonlyVec, b: ReadonlyVec, c?: O) => T; + +export type VecOpSV = (out: Vec, a: ReadonlyVec, io?: number, ia?: number, so?: number, sa?: number) => Vec; +export type VecOpSVV = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, io?: number, ia?: number, ib?: number, so?: number, sa?: number, sb?: number) => Vec; +export type VecOpSRoVV = (a: ReadonlyVec, b: ReadonlyVec, ia?: number, ib?: number, sa?: number, sb?: number) => T; + +export interface MultiVecOpV extends VecOpV, MultiVecOp { } +export interface MultiVecOpN extends VecOpN, MultiVecOp { } +export interface MultiVecOpVV extends VecOpVV, MultiVecOp { } +export interface MultiVecOpVN extends VecOpVN, MultiVecOp { } +export interface MultiVecOpVVV extends VecOpVVV, MultiVecOp { } +export interface MultiVecOpVVN extends VecOpVVN, MultiVecOp { } +export interface MultiVecOpVNN extends VecOpVNN, MultiVecOp { } +export interface MultiVecOpVVVVNN extends VecOpVVVVNN, MultiVecOp { } + +export interface MultiVecOpVO extends VecOpVO, MultiVecOp> { } +export interface MultiVecOpOO extends VecOpOO, MultiVecOp> { } +export interface MultiVecOpOOO extends VecOpOOO, MultiVecOp> { } +export interface MultiVecOpNNO extends VecOpNNO, MultiVecOp> { } + +export interface MultiVecOpRoV extends VecOpRoV, MultiVecOp> { } +export interface MultiVecOpRoVV extends VecOpRoVV, MultiVecOp> { } +export interface MultiVecOpRoVVO extends VecOpRoVVO, MultiVecOp> { } + +const mi = -Infinity; +const mx = Infinity; + +export const MIN2 = Object.freeze([mi, mi]); +export const MAX2 = Object.freeze([mx, mx]); +export const ONE2 = Object.freeze([1, 1]); +export const ZERO2 = Object.freeze([0, 0]); +export const X2 = Object.freeze([1, 0]); +export const Y2 = Object.freeze([0, 1]); + +export const MIN3 = Object.freeze([mi, mi, mi]); +export const MAX3 = Object.freeze([mx, mx, mx]); +export const ONE3 = Object.freeze([1, 1, 1]); +export const ZERO3 = Object.freeze([0, 0, 0]); +export const X3 = Object.freeze([1, 0, 0]); +export const Y3 = Object.freeze([0, 1, 0]); +export const Z3 = Object.freeze([0, 0, 1]); + +export const MIN4 = Object.freeze([mi, mi, mi, mi]); +export const MAX4 = Object.freeze([mx, mx, mx, mx]); export const ONE4 = Object.freeze([1, 1, 1, 1]); export const ZERO4 = Object.freeze([0, 0, 0, 0]); export const X4 = Object.freeze([1, 0, 0, 0]); export const Y4 = Object.freeze([0, 1, 0, 0]); export const Z4 = Object.freeze([0, 0, 1, 0]); export const W4 = Object.freeze([0, 0, 0, 1]); - diff --git a/packages/vectors3/src/asin.ts b/packages/vectors/src/asin.ts similarity index 100% rename from packages/vectors3/src/asin.ts rename to packages/vectors/src/asin.ts diff --git a/packages/vectors3/src/bisect.ts b/packages/vectors/src/bisect.ts similarity index 100% rename from packages/vectors3/src/bisect.ts rename to packages/vectors/src/bisect.ts diff --git a/packages/vectors3/src/cartesian.ts b/packages/vectors/src/cartesian.ts similarity index 100% rename from packages/vectors3/src/cartesian.ts rename to packages/vectors/src/cartesian.ts diff --git a/packages/vectors3/src/ceil.ts b/packages/vectors/src/ceil.ts similarity index 100% rename from packages/vectors3/src/ceil.ts rename to packages/vectors/src/ceil.ts diff --git a/packages/vectors3/src/clamp.ts b/packages/vectors/src/clamp.ts similarity index 100% rename from packages/vectors3/src/clamp.ts rename to packages/vectors/src/clamp.ts diff --git a/packages/vectors3/src/clampn.ts b/packages/vectors/src/clampn.ts similarity index 100% rename from packages/vectors3/src/clampn.ts rename to packages/vectors/src/clampn.ts diff --git a/packages/vectors/src/codegen.ts b/packages/vectors/src/codegen.ts deleted file mode 100644 index 3e840bcc65..0000000000 --- a/packages/vectors/src/codegen.ts +++ /dev/null @@ -1,249 +0,0 @@ -import { - comp, - map, - mapcat, - push, - range, - take, - transduce, - tuples -} from "@thi.ng/transducers"; -import { - Vec, - VecOp1, - VecOp2, - VecOp2o, - VecOp3, - VecOp3o, - VecOpN2, - VecOpN2o, - VecOpN3, - VecOpN3o -} from "./api"; - -type CommonOps = [ - - // set, setN - VecOp2, - VecOpN2, - - // add, sub, mul, div - VecOp2, - VecOp2, - VecOp2, - VecOp2, - - VecOp2o, - VecOp2o, - VecOp2o, - VecOp2o, - - VecOpN2, - VecOpN2, - VecOpN2, - VecOpN2, - - VecOpN2o, - VecOpN2o, - VecOpN2o, - VecOpN2o, - - // madd / msub - VecOp3, - VecOpN3, - VecOp3, - VecOpN3, - - // Math.* - VecOp1, - VecOp1, - VecOp1, - VecOp1, - VecOp1, - VecOp1, - VecOp1, - - // pow, min,max - VecOp2, - VecOp2, - VecOp2, - - // mix, mixN, mixo, mixNo - VecOp3, - VecOpN3, - VecOp3o, - VecOpN3o -]; - -/** - * HOF array index lookup gen to provide optimized versions of: - * - * ``` - * lookup("a")(0) // a[ia] - * lookup("a")(1) // a[ia * sa] - * lookup("a")(2) // a[ia + 2 * sa] - * ``` - * - * @param sym - */ -const lookup = (sym) => - (i) => i > 1 ? - `${sym}[i${sym}+${i}*s${sym}]` : - i == 1 ? `${sym}[i${sym}+s${sym}]` : - `${sym}[i${sym}]`; - -/** - * Infinite iterator of index lookups for `sym`. - * - * @param sym - */ -const indices = (sym) => map(lookup(sym), range()); - -/** - * Takes a vector size `dim`, a code template function and an array of - * symbol names participating in the template. For each symbol, creates - * iterator of index lookups, forms them into tuples and passes them to - * template to generate code. If the optional `ret` arg is not `null` - * (default `"a"`), appends a `return` statement to the result array, - * using `ret` as return value. Returns array - * - * @param dim - * @param tpl - * @param syms - * @param ret - */ -const assemble = (dim: number, tpl: (syms: string[]) => string, syms: string[], ret = "a") => { - const src = transduce( - comp(take(dim), map(tpl)), - push(), - tuples.apply(null, [...map(indices, syms)]) - ); - ret !== null && src.push(`return ${ret};`); - return src; -}; - -const compile = (args: string, src: string[]) => - new Function(args, src.join("")); - -export const defop1 = (dim: number, op: string): VecOp1 => - compile( - "a,ia=0,sa=1", - assemble(dim, ([a]) => `${a}=${op}(${a});`, ["a"]) - ); - -export const defop2 = (dim: number, op: string): VecOp2 => - compile( - "a,b,ia=0,ib=0,sa=1,sb=1", - assemble(dim, ([a, b]) => `${a}${op}=${b};`, ["a", "b"]) - ); - -export const defopfn2 = (dim: number, fn: string): VecOp2 => - compile( - "a,b,ia=0,ib=0,sa=1,sb=1", - assemble(dim, ([a, b]) => `${a}=${fn}(${a},${b});`, ["a", "b"]) - ); - -export const defopN = (dim: number, op: string): VecOpN2 => - compile( - "a,n,ia=0,sa=1", - assemble(dim, ([a]) => `${a}${op}=n;`, ["a"]) - ); - -export const defop2o = (dim: number, op: string): VecOp2o => - compile( - "o,a,b,io=0,ia=0,ib=0,so=1,sa=1,sb=1", - assemble(dim, ([o, a, b]) => `${o}=${a}${op}${b};`, ["o", "a", "b"], "o") - ); - -export const defopNo = (dim: number, op: string): VecOpN2o => - compile( - "o,a,n,io=0,ia=0,so=1,sa=1", - assemble(dim, ([o, a]) => `${o}=${a}${op}n;`, ["o", "a"], "o") - ); - -export const defop3 = (dim: number, op1: string, op2: string): VecOp3 => - compile( - "a,b,c,ia=0,ib=0,ic=0,sa=1,sb=1,sc=1", - assemble(dim, ([a, b, c]) => `${a}${op1}=${b}${op2}${c};`, ["a", "b", "c"]) - ); - -export const defopN3 = (dim: number, op1: string, op2: string): VecOpN3 => - compile( - "a,b,n,ia=0,ib=0,sa=1,sb=1", - assemble(dim, ([a, b]) => `${a}${op1}=${b}${op2}n;`, ["a", "b"]) - ); - -export const defmix = (dim: number): VecOp3 => - compile( - "a,b,c,ia=0,ib=0,ic=0,sa=1,sb=1,sc=1", - assemble(dim, ([a, b, c]) => `${a}+=(${b}-${a})*${c};`, ["a", "b", "c"]) - ); - -export const defmixN = (dim: number): VecOpN3 => - compile( - "a,b,n,ia=0,ib=0,sa=1,sb=1", - assemble(dim, ([a, b]) => `${a}+=(${b}-${a})*n;`, ["a", "b"]) - ); - -export const defmixo = (dim: number): VecOp3o => - compile( - "o,a,b,c,io=0,ia=0,ib=0,ic=0,so=1,sa=1,sb=1,sc=1", - assemble(dim, ([o, a, b, c]) => `${o}=${a}+(${b}-${a})*${c};`, ["o", "a", "b", "c"], "o") - ); - -export const defmixNo = (dim: number): VecOpN3o => - compile( - "o,a,b,n,io=0,ia=0,ib=0,so=1,sa=1,sb=1", - assemble(dim, ([o, a, b]) => `${o}=${a}+(${b}-${a})*n;`, ["o", "a", "b"], "o") - ); - -export const defcommon = (dim: number): CommonOps => - [ - defop2(dim, ""), - defopN(dim, ""), - - ...mapcat( - (f) => map((op) => f(dim, op), "+-*/"), - [defop2, defop2o, defopN, defopNo] - ), - ...mapcat( - ([op1, op2]) => [defop3(dim, op1, op2), defopN3(dim, op1, op2)], - [["+", "*"], ["-", "*"]] - ), - ...map( - (op) => defop1(dim, `Math.${op}`), - ["abs", "sign", "floor", "ceil", "sin", "cos", "sqrt"] - ), - ...map( - (op) => defopfn2(dim, `Math.${op}`), - ["pow", "min", "max"] - ), - defmix(dim), - defmixN(dim), - defmixo(dim), - defmixNo(dim), - ]; - -/** - * Helper function to create vector/matrix index & property accessors. - * - * @param proto - * @param indices - * @param props - */ -export const declareIndices = (proto: any, props: string[]) => { - const get = (i: number) => function () { return this.buf[this.i + i * (this.s || 1)]; }; - const set = (i: number) => function (n: number) { this.buf[this.i + i * (this.s || 1)] = n; }; - props.forEach((id, i) => { - Object.defineProperty(proto, i, { - get: get(i), - set: set(i), - enumerable: true, - }); - Object.defineProperty(proto, id, { - get: get(i), - set: set(i), - enumerable: true, - }); - }); -}; diff --git a/packages/vectors/src/common.ts b/packages/vectors/src/common.ts deleted file mode 100644 index 4e4664af96..0000000000 --- a/packages/vectors/src/common.ts +++ /dev/null @@ -1,186 +0,0 @@ -import { EPS, eqDelta as _eqDelta } from "@thi.ng/math"; -import { - ReadonlyVec, - ReadonlyVecOp1, - Vec, - VecOp2, - VecOp2o -} from "./api"; - -export const x: ReadonlyVecOp1 = (v: ReadonlyVec, i = 0) => v[i]; -export const y: ReadonlyVecOp1 = (v: ReadonlyVec, i = 0, s = 1) => v[i + s]; -export const z: ReadonlyVecOp1 = (v: ReadonlyVec, i = 0, s = 1) => v[i + 2 * s]; -export const w: ReadonlyVecOp1 = (v: ReadonlyVec, i = 0, s = 1) => v[i + 3 * s]; - -export function* $iter(buf: Vec, n: number, i = 0, s = 1) { - for (; n > 0; n-- , i += s) { - yield buf[i]; - } -} - -/** - * Applies vector op `fn` to all raw vectors in array `a`, using the - * same raw vector `b` as 2nd argument for each iteration. Assumes `fn` - * writes results back into `a` and no other copying is performed. - * - * ``` - * transformVectors1( - * v.add3, - * [1, 2, 3, 0, 4, 5, 6, 0], - * [10, 20, 30], - * 2, 0, 0, 1, 1, 4 - * ) - * // [ 11, 22, 33, 0, 14, 25, 36, 0 ] - * ``` - * - * @param fn op - * @param a vector array to process - * @param b vector operand - * @param num num elements - * @param esa element stride `a` - * @param ia start index `a` - * @param ib start index `b` - * @param csa component stride `a` - * @param csb component stride `b` - */ -export const transformVectors1 = ( - fn: VecOp2, a: Vec, b: ReadonlyVec, num: number, - esa: number, - ia = 0, ib = 0, - csa = 1, csb = 1) => { - for (; num > 0; num-- , ia += esa) { - fn(a, b, ia, ib, csa, csb); - } - return a; -}; - -/** - * Similar to `transformVectors1`, but for ops which don't modify `a` or - * `b` and instead write result into given `out` vector, which is then - * also returned. - * - * @param fn - * @param out - * @param a - * @param b - * @param num - * @param eso - * @param esa - * @param io - * @param ia - * @param ib - * @param cso - * @param csa - * @param csb - */ -export const transformVectors1o = ( - fn: VecOp2o, out: Vec, a: ReadonlyVec, b: ReadonlyVec, num: number, - eso: number, esa: number, - io = 0, ia = 0, ib = 0, - cso = 1, csa = 1, csb = 1) => { - for (; num > 0; num-- , io += eso, ia += esa) { - fn(out, a, b, io, ia, ib, cso, csa, csb); - } - return out; -}; - -/** - * Similar to `transformVectors1` but also traverses vector `b` array, - * i.e. applies `fn` to 1st vector of `a` and `b`, then to 2nd `a` and - * `b` etc. - * - * @param fn - * @param a - * @param b - * @param n - * @param esa - * @param esb - * @param ia - * @param ib - * @param csa - * @param csb - */ -export const transformVectors2 = ( - fn: VecOp2, a: Vec, b: ReadonlyVec, n: number, - esa: number, esb: number, - ia = 0, ib = 0, - csa = 1, csb = 1) => { - for (; n > 0; n-- , ia += esa, ib += esb) { - fn(a, b, ia, ib, csa, csb); - } - return a; -}; - -/** - * Similar to `transformVectors2`, but for ops which don't modify `a` or - * `b` and instead write result into given `out` vector, which is then - * also returned. - * - * @param fn - * @param out - * @param a - * @param b - * @param n - * @param eso - * @param esa - * @param esb - * @param io - * @param ia - * @param ib - * @param cso - * @param csa - * @param csb - */ -export const transformVectors2o = ( - fn: VecOp2o, out: Vec, a: ReadonlyVec, b: ReadonlyVec, n: number, - eso: number, esa: number, esb: number, - io = 0, ia = 0, ib = 0, - cso = 1, csa = 1, csb = 1) => { - for (; n > 0; n-- , io += eso, ia += esa, ib += esb) { - fn(out, a, b, io, ia, ib, cso, csa, csb); - } - return out; -}; - -/** - * Takes 2 vectors `a` and `b`, their offsets and strides, returns true - * if the first `n` elements are equal. - * - * @param a - * @param b - * @param n - * @param ia - * @param ib - * @param sa - * @param sb - */ -export const equiv = (a: ReadonlyVec, b: ReadonlyVec, n: number, ia = 0, ib = 0, sa = 1, sb = 1) => { - for (; n > 0; n-- , ia += sa, ib += sb) { - if (a[ia] !== b[ib]) { - return false; - } - } - return true; -}; - -/** - * Similar to `equiv()`, but takes tolerance `eps` into account for - * equality checks. - * - * @param a first vector - * @param b second vector - * @param n number of elements - * @param eps tolerance - * @param ia start index a - * @param ib start index b - * @param sa stride a - * @param sb stride b - */ -export const eqDelta = (a: ReadonlyVec, b: ReadonlyVec, n: number, eps = EPS, ia = 0, ib = 0, sa = 1, sb = 1) => { - for (; n > 0; n-- , ia += sa, ib += sb) { - if (!_eqDelta(a[ia], b[ib], eps)) { - return false; - } - } - return true; -}; diff --git a/packages/vectors3/src/compare.ts b/packages/vectors/src/compare.ts similarity index 100% rename from packages/vectors3/src/compare.ts rename to packages/vectors/src/compare.ts diff --git a/packages/vectors3/src/copy.ts b/packages/vectors/src/copy.ts similarity index 100% rename from packages/vectors3/src/copy.ts rename to packages/vectors/src/copy.ts diff --git a/packages/vectors3/src/cos.ts b/packages/vectors/src/cos.ts similarity index 100% rename from packages/vectors3/src/cos.ts rename to packages/vectors/src/cos.ts diff --git a/packages/vectors3/src/cosh.ts b/packages/vectors/src/cosh.ts similarity index 100% rename from packages/vectors3/src/cosh.ts rename to packages/vectors/src/cosh.ts diff --git a/packages/vectors3/src/cross.ts b/packages/vectors/src/cross.ts similarity index 100% rename from packages/vectors3/src/cross.ts rename to packages/vectors/src/cross.ts diff --git a/packages/vectors3/src/dist-chebyshev.ts b/packages/vectors/src/dist-chebyshev.ts similarity index 100% rename from packages/vectors3/src/dist-chebyshev.ts rename to packages/vectors/src/dist-chebyshev.ts diff --git a/packages/vectors3/src/dist-manhattan.ts b/packages/vectors/src/dist-manhattan.ts similarity index 100% rename from packages/vectors3/src/dist-manhattan.ts rename to packages/vectors/src/dist-manhattan.ts diff --git a/packages/vectors3/src/dist.ts b/packages/vectors/src/dist.ts similarity index 100% rename from packages/vectors3/src/dist.ts rename to packages/vectors/src/dist.ts diff --git a/packages/vectors3/src/distsq.ts b/packages/vectors/src/distsq.ts similarity index 100% rename from packages/vectors3/src/distsq.ts rename to packages/vectors/src/distsq.ts diff --git a/packages/vectors3/src/div.ts b/packages/vectors/src/div.ts similarity index 100% rename from packages/vectors3/src/div.ts rename to packages/vectors/src/div.ts diff --git a/packages/vectors3/src/divn.ts b/packages/vectors/src/divn.ts similarity index 100% rename from packages/vectors3/src/divn.ts rename to packages/vectors/src/divn.ts diff --git a/packages/vectors3/src/divs.ts b/packages/vectors/src/divs.ts similarity index 100% rename from packages/vectors3/src/divs.ts rename to packages/vectors/src/divs.ts diff --git a/packages/vectors3/src/dot.ts b/packages/vectors/src/dot.ts similarity index 100% rename from packages/vectors3/src/dot.ts rename to packages/vectors/src/dot.ts diff --git a/packages/vectors3/src/dotc.ts b/packages/vectors/src/dotc.ts similarity index 100% rename from packages/vectors3/src/dotc.ts rename to packages/vectors/src/dotc.ts diff --git a/packages/vectors3/src/dots.ts b/packages/vectors/src/dots.ts similarity index 100% rename from packages/vectors3/src/dots.ts rename to packages/vectors/src/dots.ts diff --git a/packages/vectors3/src/empty.ts b/packages/vectors/src/empty.ts similarity index 100% rename from packages/vectors3/src/empty.ts rename to packages/vectors/src/empty.ts diff --git a/packages/vectors3/src/eqdelta.ts b/packages/vectors/src/eqdelta.ts similarity index 100% rename from packages/vectors3/src/eqdelta.ts rename to packages/vectors/src/eqdelta.ts diff --git a/packages/vectors3/src/exp.ts b/packages/vectors/src/exp.ts similarity index 100% rename from packages/vectors3/src/exp.ts rename to packages/vectors/src/exp.ts diff --git a/packages/vectors3/src/face-forward.ts b/packages/vectors/src/face-forward.ts similarity index 100% rename from packages/vectors3/src/face-forward.ts rename to packages/vectors/src/face-forward.ts diff --git a/packages/vectors3/src/floor.ts b/packages/vectors/src/floor.ts similarity index 100% rename from packages/vectors3/src/floor.ts rename to packages/vectors/src/floor.ts diff --git a/packages/vectors3/src/fract.ts b/packages/vectors/src/fract.ts similarity index 100% rename from packages/vectors3/src/fract.ts rename to packages/vectors/src/fract.ts diff --git a/packages/vectors/src/gvec.ts b/packages/vectors/src/gvec.ts index e4aa908a30..99da073a48 100644 --- a/packages/vectors/src/gvec.ts +++ b/packages/vectors/src/gvec.ts @@ -1,580 +1,167 @@ -import { - ICopy, - IEqualsDelta, - IEquiv, - ILength -} from "@thi.ng/api"; -import { isArrayLike } from "@thi.ng/checks"; -import { illegalArgs } from "@thi.ng/errors"; -import { - clamp as _clamp, - EPS, - fract as _fract, - sign as _sign, - smoothStep as _smoothStep, - step as _step -} from "@thi.ng/math"; -import { - IDotProduct, - IMagnitude, - IMath, - IMinMax, - IMix, - INormalize, - IVec, - ReadonlyVec, - Vec -} from "./api"; -import { $iter, eqDelta, equiv } from "./common"; - -export const opg0 = (fn: () => number, a: Vec, num = a.length, i = 0, s = 1) => { - i += num * s; - while (i -= s, --num >= 0) { - a[i] = fn(); - } - return a; -}; - -export const opg1 = (fn: (x: number) => number, a: Vec, num = a.length, i = 0, s = 1) => { - i += num * s; - while (i -= s, --num >= 0) { - a[i] = fn(a[i]); - } - return a; -}; - -export const opg2 = (fn: (x: number, y: number) => number, a: Vec, b: ReadonlyVec, num = a.length, ia = 0, ib = 0, sa = 1, sb = 1) => { - ia += num * sa; - ib += num * sb; - while (ia -= sa, ib -= sb, --num >= 0) { - a[ia] = fn(a[ia], b[ib]); - } - return a; -}; - -export const opg3 = (fn: (x: number, y: number, z: number) => number, a: Vec, b: ReadonlyVec, c: ReadonlyVec, num = a.length, ia = 0, ib = 0, ic = 0, sa = 1, sb = 1, sc = 1) => { - ia += num * sa; - ib += num * sb; - ic += num * sc; - while (ia -= sa, ib -= sb, ic -= sc, --num >= 0) { - a[ia] = fn(a[ia], b[ib], c[ic]); - } - return a; -}; - -export const get = (a: ReadonlyVec, num = a.length, i = 0, s = 1) => - set(new ((a.constructor))(num), a, num, 0, i, 1, s); - -export const set = (a: Vec, b: ReadonlyVec, num = a.length, ia = 0, ib = 0, sa = 1, sb = 1) => { - ia += num * sa; - ib += num * sb; - while (ia -= sa, ib -= sb, --num >= 0) { - a[ia] = b[ib]; - } - return a; -}; - -export const setN = (a: Vec, n: number, num = a.length, ia = 0, sa = 1) => { - ia += num * sa; - while (ia -= sa, --num >= 0) { - a[ia] = n; - } - return a; -}; - -export const randNorm = (a: Vec, n = 1, num = a.length, ia = 0, sa = 1) => - randMinMax(a, -n, n, num, ia, sa); - -export const randMinMax = (a: Vec, min: number, max: number, num = a.length, ia = 0, sa = 1) => { - const d = max - min; - return opg0(() => min + d * Math.random(), a, num, ia, sa); -}; - -export const jitter = (a: Vec, n: number, num = a.length, ia = 0, sa = 1) => - opg1((x) => x + Math.random() * 2 * n - n, a, num, ia, sa); - -export const add = (a: Vec, b: ReadonlyVec, num = a.length, ia = 0, ib = 0, sa = 1, sb = 1) => - opg2((x, y) => x + y, a, b, num, ia, ib, sa, sb); - -export const sub = (a: Vec, b: ReadonlyVec, num = a.length, ia = 0, ib = 0, sa = 1, sb = 1) => - opg2((x, y) => x - y, a, b, num, ia, ib, sa, sb); - -export const mul = (a: Vec, b: ReadonlyVec, num = a.length, ia = 0, ib = 0, sa = 1, sb = 1) => - opg2((x, y) => x * y, a, b, num, ia, ib, sa, sb); - -export const div = (a: Vec, b: ReadonlyVec, num = a.length, ia = 0, ib = 0, sa = 1, sb = 1) => - opg2((x, y) => x / y, a, b, num, ia, ib, sa, sb); - -export const addN = (a: Vec, n: number, num = a.length, i = 0, s = 1) => - opg1((x) => x + n, a, num, i, s); - -export const subN = (a: Vec, n: number, num = a.length, i = 0, s = 1) => - opg1((x) => x - n, a, num, i, s); - -export const mulN = (a: Vec, n: number, num = a.length, i = 0, s = 1) => - opg1((x) => x * n, a, num, i, s); - -export const divN = (a: Vec, n: number, num = a.length, i = 0, s = 1) => - opg1((x) => x / n, a, num, i, s); - -export const dot = (a: ReadonlyVec, b: ReadonlyVec, num = a.length, ia = 0, ib = 0, sa = 1, sb = 1) => { - let res = 0; - while (--num >= 0) { - res += a[ia + num * sa] * b[ib + num * sb]; - } - return res; -}; - -export const madd = (a: Vec, b: ReadonlyVec, c: ReadonlyVec, num = a.length, ia = 0, ib = 0, ic = 0, sa = 1, sb = 1, sc = 1) => - opg3((x, y, z) => x + y * z, a, b, c, num, ia, ib, ic, sa, sb, sc); - -export const maddN = (a: Vec, b: ReadonlyVec, n: number, num = a.length, ia = 0, ib = 0, sa = 1, sb = 1) => - opg2((x, y) => x + y * n, a, b, num, ia, ib, sa, sb); - -export const msub = (a: Vec, b: ReadonlyVec, c: ReadonlyVec, num = a.length, ia = 0, ib = 0, ic = 0, sa = 1, sb = 1, sc = 1) => - opg3((x, y, z) => x - y * z, a, b, c, num, ia, ib, ic, sa, sb, sc); - -export const msubN = (a: Vec, b: ReadonlyVec, n: number, num = a.length, ia = 0, ib = 0, sa = 1, sb = 1) => - opg2((x, y) => x + y * n, a, b, num, ia, ib, sa, sb); - -export const mix = (a: Vec, b: ReadonlyVec, c: ReadonlyVec, num = a.length, ia = 0, ib = 0, ic = 0, sa = 1, sb = 1, sc = 1) => - opg3((x, y, z) => x + (y - x) * z, a, b, c, num, ia, ib, ic, sa, sb, sc); - -export const mixN = (a: Vec, b: ReadonlyVec, n: number, num = a.length, ia = 0, ib = 0, sa = 1, sb = 1) => - opg2((x, y) => x + (y - x) * n, a, b, num, ia, ib, sa, sb); - -export const magSq = (a: ReadonlyVec, num = a.length, i = 0, s = 1) => - dot(a, a, num, i, i, s, s); - -export const mag = (a: ReadonlyVec, num = a.length, i = 0, s = 1) => - Math.sqrt(magSq(a, num, i, s)); - -export const distSq = (a: ReadonlyVec, b: ReadonlyVec, num = a.length, ia = 0, ib = 0, sa = 1, sb = 1) => { - let res = 0; - while (--num >= 0) { - res += Math.pow(a[ia + num * sa] - b[ib + num * sb], 2); - } - return res; -}; - -export const dist = (a: ReadonlyVec, b: ReadonlyVec, num = a.length, ia = 0, ib = 0, sa = 1, sb = 1) => - Math.sqrt(distSq(a, b, num, ia, ib, sa, sb)); - -export const normalize = (a: Vec, num = a.length, len = 1, i = 0, s = 1) => { - const m = mag(a, num, i, s); - m >= EPS && mulN(a, len / m, num, i, s); - return a; -}; - -export const neg = (a: Vec, num = a.length, i = 0, s = 1) => - mulN(a, -1, num, i, s); - -export const abs = (a: Vec, num = a.length, i = 0, s = 1) => - opg1(Math.abs, a, num, i, s); - -export const sign = (a: Vec, num = a.length, eps = EPS, i = 0, s = 1) => - opg1((x) => _sign(x, eps), a, num, i, s); - -export const floor = (a: Vec, num = a.length, i = 0, s = 1) => - opg1(Math.floor, a, num, i, s); - -export const ceil = (a: Vec, num = a.length, i = 0, s = 1) => - opg1(Math.ceil, a, num, i, s); - -export const fract = (a: Vec, num = a.length, i = 0, s = 1) => - opg1(_fract, a, num, i, s); - -export const sin = (a: Vec, num = a.length, i = 0, s = 1) => - opg1(Math.sin, a, num, i, s); - -export const cos = (a: Vec, num = a.length, i = 0, s = 1) => - opg1(Math.cos, a, num, i, s); - -export const sqrt = (a: Vec, num = a.length, i = 0, s = 1) => - opg1(Math.sqrt, a, num, i, s); - -export const pow = (a: Vec, b: ReadonlyVec, num = a.length, ia = 0, ib = 0, sa = 1, sb = 1) => - opg2(Math.pow, a, b, num, ia, ib, sa, sb); - -export const powN = (a: Vec, n: number, num = a.length, i = 0, s = 1) => - opg1((x) => Math.pow(x, n), a, num, i, s); - -export const min = (a: Vec, b: ReadonlyVec, num = a.length, ia = 0, ib = 0, sa = 1, sb = 1) => - opg2(Math.min, a, b, num, ia, ib, sa, sb); - -export const max = (a: Vec, b: ReadonlyVec, num = a.length, ia = 0, ib = 0, sa = 1, sb = 1) => - opg2(Math.max, a, b, num, ia, ib, sa, sb); - -export const clamp = (a: Vec, b: ReadonlyVec, c: ReadonlyVec, num = a.length, ia = 0, ib = 0, ic = 0, sa = 1, sb = 1, sc = 1) => - opg3(_clamp, a, b, c, num, ia, ib, ic, sa, sb, sc); - -export const step = (a: Vec, b: ReadonlyVec, num = a.length, ia = 0, ib = 0, sa = 1, sb = 1) => - opg2((x, e) => _step(e, x), a, b, num, ia, ib, sa, sb); - -export const smoothStep = (a: Vec, b: ReadonlyVec, c: ReadonlyVec, num = a.length, ia = 0, ib = 0, ic = 0, sa = 1, sb = 1, sc = 1) => - opg3((x, e1, e2) => _smoothStep(e1, e2, x), a, b, c, num, ia, ib, ic, sa, sb, sc); - -export const gvec = (...coords: number[]) => - new GVec(coords, coords.length); - -export class GVec implements - ICopy, - IDotProduct, - IEqualsDelta, - IEquiv, - ILength, - IMagnitude, - IMath, - IMinMax, - IMix, - INormalize, - Iterable, - IVec { - - static mapBuffer(buf: Vec, numV: number, length: number, start = 0, cstride = 1, estride = length) { - const res: GVec[] = []; - while (--numV >= 0) { - res.push(new GVec(buf, length, start, cstride)); - start += estride; - } - return res; - } - - static intoBuffer(buf: Vec, src: Iterable>, start = 0, cstride: number, estride: number) { - for (let v of src) { - set(buf, v.buf, v.n, start, v.i, cstride, v.s); - start += estride; - } - return buf; - } - - static of(size: number, n = 0) { - return new GVec(setN([], n, size)); - } - - static randNorm(size: number, n = 1) { - return new GVec(randNorm([], n, size)); - } - - static random(size: number, min: number, max: number) { - return new GVec(randMinMax([], min, max, size)); - } - - buf: Vec; - n: number; - i: number; - s: number; - - constructor(buf: Vec, n = buf.length, i = 0, s = 1) { - this.buf = buf; - this.n = n; - this.i = i; - this.s = s; - } - - [Symbol.iterator]() { - return $iter(this.buf, this.n, this.i, this.s); - } - - get length() { - return this.n; - } - - getAt(i: number, safe = true) { - safe && this.ensureIndex(i); - return this.buf[this.i + i * this.s]; - } - - setAt(i: number, x: number, safe = true) { - safe && this.ensureIndex(i); - this.buf[this.i + i * this.s] = x; - } - - copy() { - return new GVec(get(this.buf, this.n, this.i, this.s)); - } - - equiv(v: any) { - return v instanceof GVec && v.n === this.n ? - equiv(this.buf, v.buf, this.n, this.i, v.i, this.s, v.s) : - isArrayLike(v) && v.length === this.n ? - equiv(this.buf, v, this.n, this.i, 0, this.s, 1) : - false; - } - - eqDelta(v: Readonly, eps = EPS) { - return this.n === v.n && eqDelta(this.buf, v.buf, this.n, eps, this.i, v.i, this.s, v.s); - } - - set(v: Readonly) { - this.ensureSize(v); - set(this.buf, v.buf, this.n, this.i, v.i, this.s, v.s); - return this; - } - - setN(n: number) { - setN(this.buf, n, this.n, this.i, this.s); - return this; - } - - jitter(n = 1) { - jitter(this.buf, n, this.n, this.i, this.s); - return this; - } - - add(v: Readonly) { - this.ensureSize(v); - add(this.buf, v.buf, this.n, this.i, v.i, this.s, v.s); - return this; - } - - sub(v: Readonly) { - this.ensureSize(v); - sub(this.buf, v.buf, this.n, this.i, v.i, this.s, v.s); - return this; - } - - mul(v: Readonly) { - this.ensureSize(v); - mul(this.buf, v.buf, this.n, this.i, v.i, this.s, v.s); - return this; - } - - div(v: Readonly) { - this.ensureSize(v); - div(this.buf, v.buf, this.n, this.i, v.i, this.s, v.s); - return this; - } - - addN(n: number) { - addN(this.buf, n, this.n, this.i, this.s); - return this; - } - - subN(n: number) { - subN(this.buf, n, this.n, this.i, this.s); - return this; - } - - mulN(n: number) { - mulN(this.buf, n, this.n, this.i, this.s); - return this; - } - - divN(n: number) { - divN(this.buf, n, this.n, this.i, this.s); - return this; - } - - madd(b: Readonly, c: Readonly) { - this.ensureSize(b); - this.ensureSize(c); - madd(this.buf, b.buf, c.buf, this.n, this.i, b.i, c.i, this.s, b.s, c.s); - return this; - } - - maddN(v: Readonly, n: number) { - this.ensureSize(v); - maddN(this.buf, v.buf, n, this.n, this.i, v.i, this.s, v.s); - return this; - } - - msub(b: Readonly, c: Readonly) { - this.ensureSize(b); - this.ensureSize(c); - msub(this.buf, b.buf, c.buf, this.n, this.i, b.i, c.i, this.s, b.s, c.s); - return this; - } - - msubN(v: Readonly, n: number) { - this.ensureSize(v); - msubN(this.buf, v.buf, n, this.n, this.i, v.i, this.s, v.s); - return this; - } - - mix(b: Readonly, c: Readonly) { - this.ensureSize(b); - this.ensureSize(c); - mix(this.buf, b.buf, c.buf, this.n, this.i, b.i, c.i, this.s, b.s, c.s); - return this; - } - - mixN(v: Readonly, n = 0.5) { - this.ensureSize(v); - mixN(this.buf, v.buf, n, this.n, this.i, v.i, this.s, v.s); - return this; - } - - mixNew(b: Readonly, c: Readonly, out?: GVec) { - return (out || this.copy()).mix(b, c); - } - - mixNewN(v: Readonly, n = 0.5, out?: GVec) { - return (out || this.copy()).mixN(v, n); - } - - addNew(v: Readonly, out?: GVec) { - return (out || this.copy()).add(v); - } - - subNew(v: Readonly, out?: GVec) { - return (out || this.copy()).sub(v); - } - - mulNew(v: Readonly, out?: GVec) { - return (out || this.copy()).mul(v); - } - - divNew(v: Readonly, out?: GVec) { - return (out || this.copy()).div(v); - } - - addNewN(n: number, out?: GVec) { - return (out || this.copy()).addN(n); - } - - subNewN(n: number, out?: GVec) { - return (out || this.copy()).subN(n); - } - - mulNewN(n: number, out?: GVec) { - return (out || this.copy()).mulN(n); - } - - divNewN(n: number, out?: GVec) { - return (out || this.copy()).divN(n); - } - - maddNew(v: Readonly, w: Readonly, out?: GVec) { - return (out || this.copy()).madd(v, w); - } - - maddNewN(v: Readonly, n: number, out?: GVec) { - return (out || this.copy()).maddN(v, n); - } - - msubNew(v: Readonly, w: Readonly, out?: GVec) { - return (out || this.copy()).msub(v, w); - } - - msubNewN(v: Readonly, n: number, out?: GVec) { - return (out || this.copy()).msubN(v, n); - } - - magSq() { - return magSq(this.buf, this.n, this.i, this.s); - } - - mag() { - return mag(this.buf, this.n, this.i, this.s); - } - - normalize(len = 1) { - normalize(this.buf, this.n, len, this.i, this.s); - return this; - } - - dot(v: Readonly) { - this.ensureSize(v); - return dot(this.buf, v.buf, this.n, this.i, v.i, this.s, v.s); - } - - abs() { - abs(this.buf, this.n, this.i, this.s); - return this; - } - - sign() { - sign(this.buf, this.n, this.i, this.s); - return this; - } - - ceil() { - ceil(this.buf, this.n, this.i, this.s); - return this; - } - - fract() { - fract(this.buf, this.n, this.i, this.s); - return this; - } - - floor() { - floor(this.buf, this.n, this.i, this.s); - return this; - } - - sin() { - sin(this.buf, this.n, this.i, this.s); - return this; - } - - cos() { - cos(this.buf, this.n, this.i, this.s); - return this; - } - - sqrt() { - sqrt(this.buf, this.n, this.i, this.s); - return this; - } - - pow(v: Readonly) { - this.ensureSize(v); - pow(this.buf, v.buf, this.n, this.i, v.i, this.s, v.s); - return this; - } - - powN(n: number) { - powN(this.buf, n, this.n, this.i, this.s); - return this; - } - - min(v: Readonly) { - this.ensureSize(v); - min(this.buf, v.buf, this.n, this.i, v.i, this.s, v.s); - return this; - } - - max(v: Readonly) { - this.ensureSize(v); - max(this.buf, v.buf, this.n, this.i, v.i, this.s, v.s); - return this; - } - - clamp(min: Readonly, max: Readonly) { - this.ensureSize(min); - this.ensureSize(max); - clamp(this.buf, min.buf, max.buf, this.n, this.i, min.i, max.i, this.s, min.s, max.s); - return this; - } - - step(e: Readonly) { - this.ensureSize(e); - step(this.buf, e.buf, this.n, this.i, e.i, this.s, e.s); - return this; - } - - smoothStep(e1: Readonly, e2: Readonly) { - this.ensureSize(e1); - this.ensureSize(e2); - smoothStep(this.buf, e1.buf, e2.buf, this.n, this.i, e1.i, e2.i, this.s, e1.s, e2.s); - return this; - } - - toString() { - return `[${get(this.buf, this.n, this.i, this.s).join(", ")}]`; - } - - toJSON() { - return get(this.buf, this.n, this.i, this.s); - } - - protected ensureSize(v: Readonly) { - this.n !== v.n && illegalArgs(`vector size: ${v.n} (needed ${this.n})`); - } - - protected ensureIndex(i: number) { - (i < 0 && i >= this.n) && illegalArgs(`index out of bounds: ${i}`); - } -} +import { EPS } from "@thi.ng/math"; +import { memoize1 } from "@thi.ng/memoize"; +import { map, range } from "@thi.ng/transducers"; +import { IVector, Vec } from "./api"; +import { eqDeltaS } from "./eqdelta"; +import { values } from "./internal/vec-utils"; +import { zeroes } from "./setn"; +import { setS } from "./sets"; + +const SYM_B = "buf"; +const SYM_L = "length"; +const SYM_O = "offset"; +const SYM_S = "stride"; +const SYM_C = "copy"; +const SYM_CV = "copyView"; +const SYM_EMPTY = "empty"; +const SYM_EQD = "eqDelta"; +const SYM_STR = "toString"; + +const PROPS = new Set([ + SYM_B, + SYM_C, + SYM_CV, + SYM_EMPTY, + SYM_EQD, + SYM_L, + SYM_O, + SYM_S, + SYM_STR, + Symbol.iterator +]); + +const keys = memoize1( + (size: number) => [ + ...map(String, range(size)), + ...PROPS + ] +); + +/** + * Wrapper for strided, arbitrary length vectors. Wraps given buffer in + * ES6 `Proxy` with custom property getters/setters and implements the + * following interfaces: + * + * - `Iterable` (ES6) + * - `ICopy` + * - `IEmpty` + * - `IEqualsDelta` + * - `IVector` + * - `Object.toString()` + * + * Read/write access for the following properties: + * + * - array indices in the [0 .. `size`) interval + * - `offset` - start index + * - `stride` - component stride + * - `buf` - backing buffer (readonly) + * - `length` - vector size + * + * Array index access uses bounds checking against the [0 .. `size`) + * interval, but, for performance reasons, **not** against the actual + * wrapped buffer. + * + * Note: ES6 proxies are ~10x slower than standard array accesses. If + * several computations are to be performed on such vectors it will be + * much more efficient to first copy them to compact arrays and then + * copy result back if needed. + * + * ``` + * // 3D vector w/ stride length of 4 + * a = gvec([1,0,0,0,2,0,0,0,3,0,0,0], 3, 0, 4); + * a[0] // 1 + * a[1] // 2 + * a[2] // 3 + * + * a.stride + * // 4 + * + * [...a] + * // [1, 2, 3] + * + * a.toString() + * // "[1,2,3]" + * + * add([], a, a) + * // [2, 4, 6] + * + * copy(a) + * // [1, 2, 3] + * + * a.copyView() + * // Proxy [ [ 1, 0, 2, 0, 3, 0 ], ... } + * + * eqDelta(a, [1, 2, 3]) + * // true + * ``` + * + * @param buf + * @param size + * @param offset + * @param stride + */ +export const gvec = + (buf: Vec, size: number, offset = 0, stride = 1): IVector => + new Proxy(buf, { + get(obj, id) { + switch (id) { + case Symbol.iterator: + return () => values(obj, size, offset, stride); + case SYM_L: + return size; + case SYM_B: + return buf; + case SYM_O: + return offset; + case SYM_S: + return stride; + case SYM_C: + return () => + setS([], obj, size, 0, offset, 1, stride); + case SYM_CV: + return () => + gvec(obj, size, offset, stride); + case SYM_EMPTY: + return () => zeroes(size); + case SYM_EQD: + return (o, eps = EPS) => + eqDeltaS(buf, o, size, eps, offset, 0, stride, 1); + case SYM_STR: + return () => + JSON.stringify([...values(obj, size, offset, stride)]); + default: + const j = parseInt(id); + return !isNaN(j) && j >= 0 && j < size ? + obj[offset + j * stride] : + undefined; + } + }, + set(obj, id, value) { + const j = parseInt(id); + if (!isNaN(j) && j >= 0 && j < size) { + obj[offset + (id | 0) * stride] = value; + } else { + switch (id) { + case SYM_O: + offset = value; + break; + case SYM_S: + stride = value; + break; + case SYM_L: + size = value; + break; + default: + return false; + } + } + return true + }, + has(_, id) { + return (id >= 0 && id < size) || + PROPS.has(id); + }, + ownKeys() { + return keys(size); + } + }); diff --git a/packages/vectors3/src/heading.ts b/packages/vectors/src/heading.ts similarity index 100% rename from packages/vectors3/src/heading.ts rename to packages/vectors/src/heading.ts diff --git a/packages/vectors3/src/homogeneous.ts b/packages/vectors/src/homogeneous.ts similarity index 100% rename from packages/vectors3/src/homogeneous.ts rename to packages/vectors/src/homogeneous.ts diff --git a/packages/vectors/src/index.ts b/packages/vectors/src/index.ts index 921f2cba05..b7bcb04093 100644 --- a/packages/vectors/src/index.ts +++ b/packages/vectors/src/index.ts @@ -1,11 +1,113 @@ export * from "./api"; -export * from "./common"; -export * from "./mat23"; -export * from "./mat33"; -export * from "./mat44"; -export * from "./gvec"; +export * from "./internal/accessors"; +export * from "./internal/avec"; +export * from "./internal/codegen"; +export * from "./internal/templates"; +export * from "./internal/vec-utils"; +export * from "./internal/vop"; + export * from "./vec2"; export * from "./vec3"; export * from "./vec4"; -// export * from "./codegen"; +export * from "./abs"; +export * from "./acos"; +export * from "./addw"; +export * from "./add"; +export * from "./addm"; +export * from "./addmn"; +export * from "./addn"; +export * from "./adds"; +export * from "./angle-between"; +export * from "./asin"; +export * from "./bisect"; +export * from "./cartesian"; +export * from "./ceil"; +export * from "./clamp"; +export * from "./clampn"; +export * from "./compare"; +export * from "./copy"; +export * from "./cos"; +export * from "./cosh"; +export * from "./cross"; +export * from "./dist"; +export * from "./dist-chebyshev"; +export * from "./dist-manhattan"; +export * from "./distsq"; +export * from "./div"; +export * from "./divn"; +export * from "./divs"; +export * from "./dot"; +export * from "./dotc"; +export * from "./dots"; +export * from "./empty"; +export * from "./eqdelta"; +export * from "./exp"; +export * from "./face-forward"; +export * from "./floor"; +export * from "./fract"; +export * from "./gvec"; +export * from "./heading"; +export * from "./homogeneous"; +export * from "./invert"; +export * from "./invsqrt"; +export * from "./jitter"; +export * from "./limit"; +export * from "./log"; +export * from "./madd"; +export * from "./maddn"; +export * from "./mag"; +export * from "./magsq"; +export * from "./major"; +export * from "./map"; +export * from "./max"; +export * from "./min"; +export * from "./minor"; +export * from "./mix-bilinear"; +export * from "./mix-cubic"; +export * from "./mix-quadratic"; +export * from "./mix"; +export * from "./mixn"; +export * from "./mod"; +export * from "./modn"; +export * from "./mul"; +export * from "./muln"; +export * from "./muls"; +export * from "./neg"; +export * from "./normalize"; +export * from "./ortho-normal"; +export * from "./perpendicular"; +export * from "./polar"; +export * from "./pow"; +export * from "./pown"; +export * from "./project"; +export * from "./random"; +export * from "./reflect"; +export * from "./refract"; +export * from "./rotate-around-axis"; +export * from "./rotate-around-point"; +export * from "./rotate"; +export * from "./round"; +export * from "./set"; +export * from "./setc"; +export * from "./setn"; +export * from "./sets"; +export * from "./setsn"; +export * from "./sign"; +export * from "./signed-area"; +export * from "./sin"; +export * from "./sinh"; +export * from "./sqrt"; +export * from "./step"; +export * from "./smoothstep"; +export * from "./sub"; +export * from "./subm"; +export * from "./submn"; +export * from "./subn"; +export * from "./subs"; +export * from "./sum"; +export * from "./swizzle"; +export * from "./tan"; +export * from "./tanh"; +export * from "./trunc"; +export * from "./wrap"; diff --git a/packages/vectors3/src/internal/accessors.ts b/packages/vectors/src/internal/accessors.ts similarity index 100% rename from packages/vectors3/src/internal/accessors.ts rename to packages/vectors/src/internal/accessors.ts diff --git a/packages/vectors3/src/internal/avec.ts b/packages/vectors/src/internal/avec.ts similarity index 100% rename from packages/vectors3/src/internal/avec.ts rename to packages/vectors/src/internal/avec.ts diff --git a/packages/vectors3/src/internal/codegen.ts b/packages/vectors/src/internal/codegen.ts similarity index 100% rename from packages/vectors3/src/internal/codegen.ts rename to packages/vectors/src/internal/codegen.ts diff --git a/packages/vectors3/src/internal/templates.ts b/packages/vectors/src/internal/templates.ts similarity index 100% rename from packages/vectors3/src/internal/templates.ts rename to packages/vectors/src/internal/templates.ts diff --git a/packages/vectors3/src/internal/vec-utils.ts b/packages/vectors/src/internal/vec-utils.ts similarity index 100% rename from packages/vectors3/src/internal/vec-utils.ts rename to packages/vectors/src/internal/vec-utils.ts diff --git a/packages/vectors3/src/internal/vop.ts b/packages/vectors/src/internal/vop.ts similarity index 100% rename from packages/vectors3/src/internal/vop.ts rename to packages/vectors/src/internal/vop.ts diff --git a/packages/vectors3/src/invert.ts b/packages/vectors/src/invert.ts similarity index 100% rename from packages/vectors3/src/invert.ts rename to packages/vectors/src/invert.ts diff --git a/packages/vectors3/src/invsqrt.ts b/packages/vectors/src/invsqrt.ts similarity index 100% rename from packages/vectors3/src/invsqrt.ts rename to packages/vectors/src/invsqrt.ts diff --git a/packages/vectors3/src/jitter.ts b/packages/vectors/src/jitter.ts similarity index 100% rename from packages/vectors3/src/jitter.ts rename to packages/vectors/src/jitter.ts diff --git a/packages/vectors3/src/limit.ts b/packages/vectors/src/limit.ts similarity index 100% rename from packages/vectors3/src/limit.ts rename to packages/vectors/src/limit.ts diff --git a/packages/vectors3/src/log.ts b/packages/vectors/src/log.ts similarity index 100% rename from packages/vectors3/src/log.ts rename to packages/vectors/src/log.ts diff --git a/packages/vectors3/src/madd.ts b/packages/vectors/src/madd.ts similarity index 100% rename from packages/vectors3/src/madd.ts rename to packages/vectors/src/madd.ts diff --git a/packages/vectors3/src/maddn.ts b/packages/vectors/src/maddn.ts similarity index 100% rename from packages/vectors3/src/maddn.ts rename to packages/vectors/src/maddn.ts diff --git a/packages/vectors3/src/mag.ts b/packages/vectors/src/mag.ts similarity index 100% rename from packages/vectors3/src/mag.ts rename to packages/vectors/src/mag.ts diff --git a/packages/vectors3/src/magsq.ts b/packages/vectors/src/magsq.ts similarity index 100% rename from packages/vectors3/src/magsq.ts rename to packages/vectors/src/magsq.ts diff --git a/packages/vectors3/src/major.ts b/packages/vectors/src/major.ts similarity index 100% rename from packages/vectors3/src/major.ts rename to packages/vectors/src/major.ts diff --git a/packages/vectors3/src/map.ts b/packages/vectors/src/map.ts similarity index 100% rename from packages/vectors3/src/map.ts rename to packages/vectors/src/map.ts diff --git a/packages/vectors/src/mat23.ts b/packages/vectors/src/mat23.ts deleted file mode 100644 index 8e412ad833..0000000000 --- a/packages/vectors/src/mat23.ts +++ /dev/null @@ -1,309 +0,0 @@ -import { ICopy, IEqualsDelta } from "@thi.ng/api"; -import { isArrayLike } from "@thi.ng/checks"; -import { EPS } from "@thi.ng/math"; -import { - Mat, - ReadonlyMat, - ReadonlyVec, - Vec -} from "./api"; -import { declareIndices } from "./codegen"; -import { $iter, eqDelta } from "./common"; -import { - cross2, - dot2, - setS2, - Vec2 -} from "./vec2"; - -export const get23 = (a: Mat, i = 0) => - a.slice(i, i + 6); - -export const set23 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => ( - a[ia] = b[ib], - a[ia + 1] = b[ib + 1], - a[ia + 2] = b[ib + 2], - a[ia + 3] = b[ib + 3], - a[ia + 4] = b[ib + 4], - a[ia + 5] = b[ib + 5], - a -); - -/** - * ``` - * m00 m10 m20 - * m01 m11 m21 - * ``` - * - * @param m - * @param m00 - * @param m01 - * @param m10 - * @param m11 - * @param m20 - * @param m21 - * @param i - */ -export const setS23 = ( - m: Mat, - m00: number, m01: number, - m10: number, m11: number, - m20: number, m21: number, - i = 0) => ( - m[i] = m00, - m[i + 1] = m01, - m[i + 2] = m10, - m[i + 3] = m11, - m[i + 4] = m20, - m[i + 5] = m21, - m - ); - -export const identity23 = (m?: Mat, i = 0) => - setS23(m || [], 1, 0, 0, 1, 0, 0, i); - -export const rotation23 = (m: Mat, theta: number, i = 0) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS23(m || [], c, s, -s, c, 0, 0, i); -}; - -export const rotationAroundPoint23 = (m: Mat, p: ReadonlyVec, theta: number, im = 0, iv = 0, sv = 1) => - concat23( - translationV23(m || [], p, im, iv, sv), im, - rotation23([], theta), - translationS23([], -p[iv], -p[iv + sv]) - ); - -export const scaleV23 = (m: Mat, v: Vec, i = 0, iv = 0, sv = 1) => - scaleS23(m, v[iv], v[iv + sv], i); - -export const scaleN23 = (m: Mat, n: number, i = 0) => - scaleS23(m, n, n, i); - -export const scaleS23 = (m: Mat, sx: number, sy: number, i = 0) => - setS23(m || [], sx, 0, 0, sy, 0, 0, i); - -export const scaleWithCenter23 = (m: Mat, p: ReadonlyVec, sx: number, sy: number, im = 0, iv = 0, sv = 1) => - concat23( - translationV23(m || [], p, im, iv, sv), im, - scaleS23([], sx, sy), - translationS23([], -p[iv], -p[iv + sv]) - ); - -export const translationV23 = (m: Mat, v: ReadonlyVec, i = 0, iv = 0, sv = 1) => - translationS23(m, v[iv], v[iv + sv], i); - -export const translationS23 = (m: Mat, x: number, y: number, i = 0) => - setS23(m || [], 1, 0, 0, 1, x, y, i); - -export const shearX23 = (m: Mat, x: number, i = 0) => - setS23(m || [], 1, 0, x, 1, 0, 0, i); - -export const shearY23 = (m: Mat, y: number, i = 0) => - setS23(m || [], 1, y, 0, 1, 0, 0, i); - -export const skewX23 = (m: Mat, theta: number, i = 0) => - shearX23(m, Math.tan(theta), i); - -export const skewY23 = (m: Mat, theta: number, i = 0) => - shearY23(m, Math.tan(theta), i); - -export const mul23 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => - setS23( - a, - dot2(a, b, ia, ib, 2), - dot2(a, b, ia + 1, ib, 2), - dot2(a, b, ia, ib + 2, 2), - dot2(a, b, ia + 1, ib + 2, 2), - dot2(a, b, ia, ib + 4, 2) + a[ia + 4], - dot2(a, b, ia + 1, ib + 4, 2) + a[ia + 5], - ia - ); - -export const concat23 = (a: Mat, ia: number, ...xs: (ReadonlyMat | [ReadonlyMat, number])[]) => - xs.reduce( - (acc: Mat, x) => isArrayLike(x[0]) ? - mul23(acc, x[0], ia, x[1]) : - mul23(acc, x, ia), - a - ); - -export const mulV23 = (v: Vec, m: ReadonlyMat, iv = 0, im = 0, sv = 1) => - setS2( - v, - dot2(m, v, im, iv, 2, sv) + m[im + 4], - dot2(m, v, im + 1, iv, 2, sv) + m[im + 5], - iv, sv - ); - -export const det23 = (m: ReadonlyMat, i = 0) => - cross2(m, m, i, i + 1, 2, 2); - -export const invert23 = (m: Mat, i = 0) => { - const m00 = m[i]; - const m01 = m[i + 1]; - const m10 = m[i + 2]; - const m11 = m[i + 3]; - const m20 = m[i + 4]; - const m21 = m[i + 5]; - let det = m00 * m11 - m01 * m10; - if (!det) { - return; - } - det = 1.0 / det; - return setS23( - m, - m11 * det, - -m01 * det, - -m10 * det, - m00 * det, - (m10 * m21 - m11 * m20) * det, - (m01 * m20 - m00 * m21) * det, - i - ); -} - -export class Mat23 implements - ICopy, - IEqualsDelta { - - static identity() { - return new Mat23(identity23()); - } - - static rotation(theta: number) { - return new Mat23(rotation23([], theta)); - } - - static rotationAroundPoint(p: Readonly, theta: number) { - return new Mat23(rotationAroundPoint23([], p.buf, theta, 0, p.i, p.s)); - } - - static scale(v: Vec2): Mat23; - static scale(n: number): Mat23; - static scale(x: number, y: number): Mat23; - static scale(x: any, y = x) { - return new Mat23( - x instanceof Vec2 ? - scaleV23([], x.buf, 0, x.i, x.s) : - scaleS23([], x, y) - ); - } - - static scaleWithCenter(p: Readonly, sx: number, sy = sx) { - return new Mat23(scaleWithCenter23([], p.buf, sx, sy, 0, p.i, p.s)); - } - - static translation(v: Readonly): Mat23; - static translation(x: number, y: number): Mat23; - static translation(x: any, y?: any) { - return new Mat23( - x instanceof Vec2 ? - translationV23([], x.buf, 0, x.i) : - translationS23([], x, y) - ); - } - - static skewX(x: number) { - return new Mat23(skewX23([], x)); - } - - static skewY(y: number) { - return new Mat23(skewY23([], y)); - } - - static shearX(theta: number) { - return new Mat23(shearX23([], theta)); - } - - static shearY(theta: number) { - return new Mat23(shearY23([], theta)); - } - - static concat(m: Readonly, ...xs: Readonly[]) { - return new Mat23(concat23.apply(null, [ - get23(m.buf, m.i), 0, - ...<[ReadonlyMat, number][]>xs.map((x) => [x.buf, x.i])]) - ); - } - - buf: Mat; - i: number; - m00: number; - m01: number; - m10: number; - m11: number; - m20: number; - m21: number; - [id: number]: number; - - constructor(buf?: Mat, i = 0) { - this.buf = buf || [0, 0, 0, 0, 0, 0]; - this.i = i; - } - - [Symbol.iterator]() { - return $iter(this.buf, 6, this.i); - } - - get length() { - return 6; - } - - copy() { - return new Mat23(get23(this.buf, this.i)); - } - - eqDelta(m: Mat23, eps = EPS) { - return eqDelta(this.buf, m.buf, 6, eps, this.i, m.i); - } - - identity() { - identity23(this.buf, this.i); - return this; - } - - set(m: Readonly) { - set23(this.buf, m.buf, this.i, m.i); - return this; - } - - setS(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number) { - setS23(this.buf, m00, m01, m10, m11, m20, m21, this.i); - return this; - } - - mul(m: Readonly) { - mul23(this.buf, m.buf, this.i, m.i); - return this; - } - - mulV(v: Vec2) { - mulV23(v.buf, this.buf, v.i, this.i, v.s); - return v; - } - - determinant() { - return det23(this.buf, this.i); - } - - invert() { - invert23(this.buf, this.i); - return this; - } - - toString() { - const b = (get23(this.buf, this.i)).map((x) => x.toFixed(4)); - return `${b[0]} ${b[2]} ${b[4]}\n${b[1]} ${b[3]} ${b[5]}`; - } - - toJSON() { - return get23(this.buf, this.i); - } -} - -declareIndices( - Mat23.prototype, - ["m00", "m01", "m10", "m11", "m20", "m21"] -); diff --git a/packages/vectors/src/mat33.ts b/packages/vectors/src/mat33.ts deleted file mode 100644 index 8019b6393b..0000000000 --- a/packages/vectors/src/mat33.ts +++ /dev/null @@ -1,355 +0,0 @@ -import { ICopy, IEqualsDelta } from "@thi.ng/api"; -import { isArrayLike } from "@thi.ng/checks"; -import { EPS } from "@thi.ng/math"; -import { - Mat, - ReadonlyMat, - ReadonlyVec, - Vec -} from "./api"; -import { declareIndices } from "./codegen"; -import { $iter, eqDelta } from "./common"; -import { - dot3, - set3, - setS3, - Vec3 -} from "./vec3"; -import { setS4 } from "./vec4"; - -export const get33 = (a: Mat, i = 0) => - a.slice(i, i + 9); - -export const set33 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => ( - a[ia] = b[ib], - a[ia + 1] = b[ib + 1], - a[ia + 2] = b[ib + 2], - a[ia + 3] = b[ib + 3], - a[ia + 4] = b[ib + 4], - a[ia + 5] = b[ib + 5], - a[ia + 6] = b[ib + 6], - a[ia + 7] = b[ib + 7], - a[ia + 8] = b[ib + 8], - a -); - -/** - * ``` - * m00 m10 m20 - * m01 m11 m21 - * m02 m12 m22 - * ``` - * - * @param m - * @param m00 - * @param m01 - * @param m02 - * @param m10 - * @param m11 - * @param m12 - * @param m20 - * @param m21 - * @param m22 - * @param i - */ -export const setS33 = ( - m: Mat, - m00: number, m01: number, m02: number, - m10: number, m11: number, m12: number, - m20: number, m21: number, m22: number, - i = 0) => ( - m[i] = m00, - m[i + 1] = m01, - m[i + 2] = m02, - m[i + 3] = m10, - m[i + 4] = m11, - m[i + 5] = m12, - m[i + 6] = m20, - m[i + 7] = m21, - m[i + 8] = m22, - m - ); - -export const identity33 = (m?: Mat, i = 0) => - setS33(m || [], - 1, 0, 0, - 0, 1, 0, - 0, 0, 1, - i - ); - -export const rotationX33 = (m: Mat, theta: number, i = 0) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS33(m || [], - 1, 0, 0, - 0, c, s, - 0, -s, c, - i - ); -}; - -export const rotationY33 = (m: Mat, theta: number, i = 0) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS33(m || [], - c, 0, -s, - 0, 1, 0, - s, 0, c, - i - ); -}; - -export const rotationZ33 = (m: Mat, theta: number, i = 0) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS33(m || [], - c, s, 0, - -s, c, 0, - 0, 0, 1, - i - ); -}; - -export const scaleV33 = (m: Mat, v: ReadonlyVec, i = 0, iv = 0, sv = 1) => - scaleS33(m, v[iv], v[iv + sv], v[iv + 2 * sv], i); - -export const scaleN33 = (m: Mat, n: number, i = 0) => - scaleS33(m, n, n, n, i); - -export const scaleS33 = (m: Mat, sx: number, sy: number, sz: number, i = 0) => - setS33(m || [], - sx, 0, 0, - 0, sy, 0, - 0, 0, sz, - i - ); - -export const mul33 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => - setS33( - a, - dot3(a, b, ia, ib, 3), - dot3(a, b, ia + 1, ib, 3), - dot3(a, b, ia + 2, ib, 3), - dot3(a, b, ia, ib + 3, 3), - dot3(a, b, ia + 1, ib + 3, 3), - dot3(a, b, ia + 2, ib + 3, 3), - dot3(a, b, ia, ib + 6, 3), - dot3(a, b, ia + 1, ib + 6, 3), - dot3(a, b, ia + 2, ib + 6, 3), - ia - ); - -export const concat33 = (a: Mat, ia: number, ...xs: (ReadonlyMat | [ReadonlyMat, number])[]) => - xs.reduce( - (acc: Mat, x) => isArrayLike(x[0]) ? - mul33(acc, x[0], ia, x[1]) : - mul33(acc, x, ia), - a - ); - -export const mulV33 = (v: Vec, m: ReadonlyMat, iv = 0, im = 0, sv = 1) => - setS3( - v, - dot3(m, v, im, iv, 3, sv), - dot3(m, v, im + 1, iv, 3, sv), - dot3(m, v, im + 2, iv, 3, sv), - iv, sv - ); - -export const det33 = (m: ReadonlyMat, i = 0) => { - const m00 = m[i]; - const m01 = m[i + 1]; - const m02 = m[i + 2]; - const m10 = m[i + 3]; - const m11 = m[i + 4]; - const m12 = m[i + 5]; - const m20 = m[i + 6]; - const m21 = m[i + 7]; - const m22 = m[i + 8]; - const d01 = m22 * m11 - m12 * m21; - const d11 = -m22 * m10 + m12 * m20; - const d21 = m21 * m10 - m11 * m20; - return m00 * d01 + m01 * d11 + m02 * d21; -}; - -export const invert33 = (m: Mat, i = 0) => { - const m00 = m[i]; - const m01 = m[i + 1]; - const m02 = m[i + 2]; - const m10 = m[i + 3]; - const m11 = m[i + 4]; - const m12 = m[i + 5]; - const m20 = m[i + 6]; - const m21 = m[i + 7]; - const m22 = m[i + 8]; - const d01 = m22 * m11 - m12 * m21; - const d11 = -m22 * m10 + m12 * m20; - const d21 = m21 * m10 - m11 * m20; - let det = m00 * d01 + m01 * d11 + m02 * d21; - if (!det) { - return; - } - det = 1.0 / det; - return setS33( - m, - d01 * det, - (-m22 * m01 + m02 * m21) * det, - (m12 * m01 - m02 * m11) * det, - d11 * det, - (m22 * m00 - m02 * m20) * det, - (-m12 * m00 + m02 * m10) * det, - d21 * det, - (-m21 * m00 + m01 * m20) * det, - (m11 * m00 - m01 * m10) * det, - i - ); -} - -export const transpose33 = (m: Mat, i = 0) => - setS33( - m, - m[i], m[i + 3], m[i + 6], - m[i + 1], m[i + 4], m[i + 7], - m[i + 2], m[i + 5], m[i + 8], - i - ); - -export const mat33to44 = (m44: Mat, m33: ReadonlyMat, ia = 0, ib = 0) => ( - set3(m44, m33, ia, ib), - set3(m44, m33, ia + 4, ib + 3), - set3(m44, m33, ia + 8, ib + 6), - setS3(m44, 0, 0, 0, ia + 12), - setS4(m44, 0, 0, 0, 1, ia + 3, 4), - m44 -); - -export class Mat33 implements - ICopy, - IEqualsDelta { - - static identity() { - return new Mat33(identity33()); - } - - static rotationX(theta: number) { - return new Mat33(rotationX33([], theta)); - } - - static rotationY(theta: number) { - return new Mat33(rotationY33([], theta)); - } - - static rotationZ(theta: number) { - return new Mat33(rotationZ33([], theta)); - } - - static scale(v: Readonly): Mat33; - static scale(n: number): Mat33; - static scale(x: number, y: number, z: number): Mat33; - static scale(x: any, y = x, z = x) { - return new Mat33( - x instanceof Vec3 ? - scaleV33([], x.buf, 0, x.i) : - scaleS33([], x, y, z) - ); - } - - static concat(m: Readonly, ...xs: Readonly[]) { - return new Mat33(concat33.apply(null, [ - get33(m.buf, m.i), 0, - ...<[ReadonlyMat, number][]>xs.map((x) => [x.buf, x.i])]) - ); - } - - buf: Mat; - i: number; - m00: number; - m01: number; - m02: number; - m10: number; - m11: number; - m12: number; - m20: number; - m21: number; - m22: number; - [id: number]: number; - - constructor(buf?: Mat, i = 0) { - this.buf = buf || [0, 0, 0, 0, 0, 0, 0, 0, 0]; - this.i = i; - } - - [Symbol.iterator]() { - return $iter(this.buf, 9, this.i); - } - - get length() { - return 9; - } - - copy() { - return new Mat33(get33(this.buf, this.i)); - } - - eqDelta(m: Mat33, eps = EPS) { - return eqDelta(this.buf, m.buf, 9, eps, this.i, m.i); - } - - identity() { - identity33(this.buf, this.i); - return this; - } - - set(m: Readonly) { - set33(this.buf, m.buf, this.i, m.i); - return this; - } - - setS(m00: number, m01: number, m02: number, - m10: number, m11: number, m12: number, - m20: number, m21: number, m22: number) { - setS33(this.buf, m00, m01, m02, m10, m11, m12, m20, m21, m22, this.i); - return this; - } - - mul(m: Readonly) { - mul33(this.buf, m.buf, this.i, m.i); - return this; - } - - mulV(v: Vec3) { - mulV33(v.buf, this.buf, v.i, this.i, v.s); - return v; - } - - determinant() { - return det33(this.buf, this.i); - } - - invert() { - invert33(this.buf, this.i); - return this; - } - - transpose() { - transpose33(this.buf, this.i); - return this; - } - - toString() { - const b = (get33(this.buf, this.i)).map((x) => x.toFixed(4)); - return `${b[0]} ${b[3]} ${b[6]} -${b[1]} ${b[4]} ${b[7]} -${b[2]} ${b[5]} ${b[8]}`; - } - - toJSON() { - return get33(this.buf, this.i); - } -} - -declareIndices( - Mat33.prototype, - ["m00", "m01", "m02", "m10", "m11", "m12", "m20", "m21", "m22"] -); diff --git a/packages/vectors/src/mat44.ts b/packages/vectors/src/mat44.ts deleted file mode 100644 index 7dfae1fae6..0000000000 --- a/packages/vectors/src/mat44.ts +++ /dev/null @@ -1,598 +0,0 @@ -import { ICopy, IEqualsDelta } from "@thi.ng/api"; -import { isArrayLike } from "@thi.ng/checks"; -import { DEG2RAD, EPS } from "@thi.ng/math"; -import { - Mat, - ReadonlyMat, - ReadonlyVec, - Vec -} from "./api"; -import { declareIndices } from "./codegen"; -import { $iter, eqDelta } from "./common"; -import { Mat33 } from "./mat33"; -import { - cross3, - dot3, - get3, - normalize3, - set3, - setS3, - sub3, - Vec3 -} from "./vec3"; -import { dot4, setS4, Vec4 } from "./vec4"; - -export const get44 = (a: Mat, i = 0) => - a.slice(i, i + 16); - -export const set44 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => { - for (let i = 0; i < 16; i++) { - a[ia + i] = b[ib + i]; - } - return a; -}; - -/** - * ``` - * m00 m10 m20 m30 - * m01 m11 m21 m31 - * m02 m12 m22 m32 - * m03 m13 m23 m33 - * ``` - */ -export const setS44 = ( - m: Mat, - m00: number, m01: number, m02: number, m03: number, - m10: number, m11: number, m12: number, m13: number, - m20: number, m21: number, m22: number, m23: number, - m30: number, m31: number, m32: number, m33: number, - i = 0) => ( - m[i] = m00, - m[i + 1] = m01, - m[i + 2] = m02, - m[i + 3] = m03, - m[i + 4] = m10, - m[i + 5] = m11, - m[i + 6] = m12, - m[i + 7] = m13, - m[i + 8] = m20, - m[i + 9] = m21, - m[i + 10] = m22, - m[i + 11] = m23, - m[i + 12] = m30, - m[i + 13] = m31, - m[i + 14] = m32, - m[i + 15] = m33, - m - ); - -export const identity44 = (m?: Mat, i = 0) => - setS44(m || [], - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1, - i - ); - -export const rotationX44 = (m: Mat, theta: number, i = 0) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS44(m || [], - 1, 0, 0, 0, - 0, c, s, 0, - 0, -s, c, 0, - 0, 0, 0, 1, - i - ); -}; - -export const rotationY44 = (m: Mat, theta: number, i = 0) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS44(m || [], - c, 0, -s, 0, - 0, 1, 0, 0, - s, 0, c, 0, - 0, 0, 0, 1, - i - ); -}; - -export const rotationZ44 = (m: Mat, theta: number, i = 0) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS44(m || [], - c, s, 0, 0, - -s, c, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1, - i - ); -}; - -export const scaleV44 = (m: Mat, v: ReadonlyVec, i = 0, iv = 0, sv = 1) => - scaleS44(m, v[iv], v[iv + sv], v[iv + 2 * sv], i); - -export const scaleN44 = (m: Mat, n: number, i = 0) => - scaleS44(m, n, n, n, i); - -export const scaleS44 = (m: Mat, sx: number, sy: number, sz: number, i = 0) => - setS44(m || [], - sx, 0, 0, 0, - 0, sy, 0, 0, - 0, 0, sz, 0, - 0, 0, 0, 1, - i - ); - -export const scaleWithCenter44 = (m: Mat, p: ReadonlyVec, sx: number, sy: number, sz: number, im = 0, iv = 0, sv = 1) => - concat44( - translationV44(m || [], p, im, iv, sv), im, - scaleS44([], sx, sy, sz), - translationS44([], -p[iv], -p[iv + sv], -p[iv + 2 * sv]) - ); - -export const translationV44 = (m: Mat, v: ReadonlyVec, i = 0, iv = 0, sv = 1) => - translationS44(m, v[iv], v[iv + sv], v[iv + 2 * sv], i); - -export const translationS44 = (m: Mat, x: number, y: number, z: number, i = 0) => - setS44(m || [], - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - x, y, z, 1, - i - ); - -export const frustum = (m: Mat, left: number, right: number, bottom: number, top: number, near: number, far: number, i = 0) => { - const dx = 1 / (right - left); - const dy = 1 / (top - bottom); - const dz = 1 / (far - near); - return setS44(m || [], - near * 2 * dx, 0, 0, 0, - 0, near * 2 * dy, 0, 0, - (right + left) * dx, (top + bottom) * dy, -(far + near) * dz, -1, - 0, 0, -(far * near * 2) * dz, 0, - i - ); -}; - -export const frustumBounds = (fovy: number, aspect: number, near: number, far: number) => { - const top = near * Math.tan(fovy * DEG2RAD / 2); - const right = top * aspect; - return { - left: -right, - right, - bottom: -top, - top, - near, - far - }; -}; - -export const perspective = (m: Mat, fov: number, aspect: number, near: number, far: number, i = 0) => { - const f = frustumBounds(fov, aspect, near, far); - return frustum(m || [], f.left, f.right, f.bottom, f.top, f.near, f.far, i); -}; - -export const ortho = (m: Mat, left: number, right: number, bottom: number, top: number, near: number, far: number, i = 0) => { - const dx = 1 / (right - left); - const dy = 1 / (top - bottom); - const dz = 1 / (far - near); - return setS44(m || [], - 2 * dx, 0, 0, 0, - 0, 2 * dy, 0, 0, - 0, 0, -2 * dz, 0, - -(left + right) * dx, -(top + bottom) * dy, -(far + near) * dz, 1, - i - ); -}; - -export const lookAt = (m: Mat, eye: ReadonlyVec, target: ReadonlyVec, up: ReadonlyVec, im = 0, ie = 0, it = 0, iu = 0, se = 1, st = 1, su = 1) => { - const z = normalize3(sub3(get3(eye, ie, se), get3(target, it, st))); - const x = normalize3(cross3(get3(up, iu, su), z)); - const y = normalize3(cross3([...z], x)); - return setS44(m || [], - x[0], y[0], z[0], 0, - x[1], y[1], z[1], 0, - x[2], y[2], z[2], 0, - -dot3(eye, x, ie, 0, se), -dot3(eye, y, ie, 0, se), -dot3(eye, z, ie, 0, se), 1, - im - ); -} - -export const mul44 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => - setS44( - a, - dot4(a, b, ia, ib, 4), - dot4(a, b, ia + 1, ib, 4), - dot4(a, b, ia + 2, ib, 4), - dot4(a, b, ia + 3, ib, 4), - dot4(a, b, ia, ib + 4, 4), - dot4(a, b, ia + 1, ib + 4, 4), - dot4(a, b, ia + 2, ib + 4, 4), - dot4(a, b, ia + 3, ib + 4, 4), - dot4(a, b, ia, ib + 8, 4), - dot4(a, b, ia + 1, ib + 8, 4), - dot4(a, b, ia + 2, ib + 8, 4), - dot4(a, b, ia + 3, ib + 8, 4), - dot4(a, b, ia, ib + 12, 4), - dot4(a, b, ia + 1, ib + 12, 4), - dot4(a, b, ia + 2, ib + 12, 4), - dot4(a, b, ia + 3, ib + 12, 4), - ia - ); - -export const concat44 = (a: Mat, ia: number, ...xs: (ReadonlyMat | [ReadonlyMat, number])[]) => - xs.reduce( - (acc: Mat, x) => isArrayLike(x[0]) ? - mul44(acc, x[0], ia, x[1]) : - mul44(acc, x, ia), - a - ); - -export const mulV344 = (v: Vec, m: ReadonlyMat, iv = 0, im = 0, sv = 1) => - setS3( - v, - dot3(m, v, im, iv, 4, sv) + m[12], - dot3(m, v, im + 1, iv, 4, sv) + m[13], - dot3(m, v, im + 2, iv, 4, sv) + m[14], - iv, sv - ); - -export const mulV44 = (v: Vec, m: ReadonlyMat, iv = 0, im = 0, sv = 1) => - setS4( - v, - dot4(m, v, im, iv, 4, sv), - dot4(m, v, im + 1, iv, 4, sv), - dot4(m, v, im + 2, iv, 4, sv), - dot4(m, v, im + 3, iv, 4, sv), - iv, sv - ); - -const detCoeffs44 = (m: ReadonlyMat, i = 0) => { - const m00 = m[i]; - const m01 = m[i + 1]; - const m02 = m[i + 2]; - const m03 = m[i + 3]; - const m10 = m[i + 4]; - const m11 = m[i + 5]; - const m12 = m[i + 6]; - const m13 = m[i + 7]; - const m20 = m[i + 8]; - const m21 = m[i + 9]; - const m22 = m[i + 10]; - const m23 = m[i + 11]; - const m30 = m[i + 12]; - const m31 = m[i + 13]; - const m32 = m[i + 14]; - const m33 = m[i + 15]; - return [ - m00 * m11 - m01 * m10, - m00 * m12 - m02 * m10, - m00 * m13 - m03 * m10, - m01 * m12 - m02 * m11, - m01 * m13 - m03 * m11, - m02 * m13 - m03 * m12, - m20 * m31 - m21 * m30, - m20 * m32 - m22 * m30, - m20 * m33 - m23 * m30, - m21 * m32 - m22 * m31, - m21 * m33 - m23 * m31, - m22 * m33 - m23 * m32, - ]; -}; - -export const det44 = (m: ReadonlyMat, i = 0) => { - const d = detCoeffs44(m, i); - return d[0] * d[11] - d[1] * d[10] + d[2] * d[9] + - d[3] * d[8] - d[4] * d[7] + d[5] * d[6]; -}; - -export const invert44 = (m: Mat, i = 0) => { - const m00 = m[i]; - const m01 = m[i + 1]; - const m02 = m[i + 2]; - const m03 = m[i + 3]; - const m10 = m[i + 4]; - const m11 = m[i + 5]; - const m12 = m[i + 6]; - const m13 = m[i + 7]; - const m20 = m[i + 8]; - const m21 = m[i + 9]; - const m22 = m[i + 10]; - const m23 = m[i + 11]; - const m30 = m[i + 12]; - const m31 = m[i + 13]; - const m32 = m[i + 14]; - const m33 = m[i + 15]; - const d = detCoeffs44(m, i); - const d00 = d[0]; - const d01 = d[1]; - const d02 = d[2]; - const d03 = d[3]; - const d04 = d[4]; - const d05 = d[5]; - const d06 = d[6]; - const d07 = d[7]; - const d08 = d[8]; - const d09 = d[9]; - const d10 = d[10]; - const d11 = d[11]; - let det = (d00 * d11 - d01 * d10 + d02 * d09 + d03 * d08 - d04 * d07 + d05 * d06); - if (!det) { - return; - } - det = 1.0 / det; - return setS44( - m, - (m11 * d11 - m12 * d10 + m13 * d09) * det, - (-m01 * d11 + m02 * d10 - m03 * d09) * det, - (m31 * d05 - m32 * d04 + m33 * d03) * det, - (-m21 * d05 + m22 * d04 - m23 * d03) * det, - (-m10 * d11 + m12 * d08 - m13 * d07) * det, - (m00 * d11 - m02 * d08 + m03 * d07) * det, - (-m30 * d05 + m32 * d02 - m33 * d01) * det, - (m20 * d05 - m22 * d02 + m23 * d01) * det, - (m10 * d10 - m11 * d08 + m13 * d06) * det, - (-m00 * d10 + m01 * d08 - m03 * d06) * det, - (m30 * d04 - m31 * d02 + m33 * d00) * det, - (-m20 * d04 + m21 * d02 - m23 * d00) * det, - (-m10 * d09 + m11 * d07 - m12 * d06) * det, - (m00 * d09 - m01 * d07 + m02 * d06) * det, - (-m30 * d03 + m31 * d01 - m32 * d00) * det, - (m20 * d03 - m21 * d01 + m22 * d00) * det, - i - ); -} - -export const transpose44 = (m: Mat, i = 0) => - setS44( - m, - m[i], m[i + 4], m[i + 8], m[i + 12], - m[i + 1], m[i + 5], m[i + 9], m[i + 13], - m[i + 2], m[i + 6], m[i + 10], m[i + 14], - m[i + 3], m[i + 7], m[i + 11], m[i + 15], - i - ); - -export const normal44 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => { - const m00 = b[ib]; - const m01 = b[ib + 1]; - const m02 = b[ib + 2]; - const m10 = b[ib + 4]; - const m11 = b[ib + 5]; - const m12 = b[ib + 6]; - const m20 = b[ib + 8]; - const m21 = b[ib + 9]; - const m22 = b[ib + 10]; - const d01 = m22 * m11 - m12 * m21; - const d11 = -m22 * m10 + m12 * m20; - const d21 = m21 * m10 - m11 * m20; - let det = m00 * d01 + m01 * d11 + m02 * d21; - if (!det) { - return; - } - det = 1.0 / det; - a[ia] = d01 * det; - a[ia + 1] = d11 * det; - a[ia + 2] = d21 * det; - a[ia + 3] = (-m22 * m01 + m02 * m21) * det; - a[ia + 4] = (m22 * m00 - m02 * m20) * det; - a[ia + 5] = (-m21 * m00 + m01 * m20) * det; - a[ia + 6] = (m12 * m01 - m02 * m11) * det; - a[ia + 7] = (-m12 * m00 + m02 * m10) * det; - a[ia + 8] = (m11 * m00 - m01 * m10) * det; - return a; -}; - -export const mat44to33 = (m33: Mat, m44: ReadonlyMat, ia = 0, ib = 0) => ( - set3(m33, m44, ia, ib), - set3(m33, m44, ia + 3, ib + 4), - set3(m33, m44, ia + 6, ib + 8), - m33 -); - -export class Mat44 implements - ICopy, - IEqualsDelta { - - static identity() { - return new Mat44(identity44()); - } - - static rotationX(theta: number) { - return new Mat44(rotationX44([], theta)); - } - - static rotationY(theta: number) { - return new Mat44(rotationY44([], theta)); - } - - static rotationZ(theta: number) { - return new Mat44(rotationZ44([], theta)); - } - - static scale(v: Readonly): Mat44; - static scale(n: number): Mat44; - static scale(x: number, y: number, z: number): Mat44; - static scale(x: any, y = x, z = x) { - return new Mat44( - x instanceof Vec3 ? - scaleV44([], x.buf, 0, x.i) : - scaleS44([], x, y, z) - ); - } - - static scaleWithCenter(p: Readonly, sx: number, sy = sx, sz = sy) { - return new Mat44(scaleWithCenter44([], p.buf, sx, sy, sz, p.i, p.s)); - } - - static translation(v: Readonly): Mat44; - static translation(x: number, y: number, z: number): Mat44; - static translation(x: any, y?: any, z?: any) { - return new Mat44( - x instanceof Vec3 ? - translationV44([], x.buf, 0, x.i) : - translationS44([], x, y, z) - ); - } - - static perspective(fov: number, aspect: number, near: number, far: number) { - return new Mat44(perspective([], fov, aspect, near, far)); - } - - static ortho(left: number, right: number, bottom: number, top: number, near: number, far: number) { - return new Mat44(ortho([], left, right, bottom, top, near, far)); - } - - static frustum(left: number, right: number, bottom: number, top: number, near: number, far: number) { - return new Mat44(frustum([], left, right, bottom, top, near, far)); - } - - static lookAt(eye: Readonly, target: Readonly, up: Readonly) { - return new Mat44(lookAt( - [], - eye.buf, target.buf, up.buf, - 0, eye.i, target.i, up.i, - eye.s, target.s, up.s - )); - } - - static concat(m: Readonly, ...xs: Readonly[]) { - return new Mat44(concat44.apply(null, [ - get44(m.buf, m.i), 0, - ...<[ReadonlyMat, number][]>xs.map((x) => [x.buf, x.i])]) - ); - } - - buf: Mat; - i: number; - m00: number; - m01: number; - m02: number; - m03: number; - m10: number; - m11: number; - m12: number; - m13: number; - m20: number; - m21: number; - m22: number; - m23: number; - m30: number; - m31: number; - m32: number; - m33: number; - [id: number]: number; - - constructor(buf?: Mat, i = 0) { - this.buf = buf || (new Array(16).fill(0)); - this.i = i; - } - - [Symbol.iterator]() { - return $iter(this.buf, 16, this.i); - } - - get length() { - return 16; - } - - copy() { - return new Mat44(get44(this.buf, this.i)); - } - - eqDelta(m: Mat44, eps = EPS) { - return eqDelta(this.buf, m.buf, 16, eps, this.i, m.i); - } - - identity() { - identity44(this.buf, this.i); - return this; - } - - set(m: Readonly) { - set44(this.buf, m.buf, this.i, m.i); - return this; - } - - setS(m00: number, m01: number, m02: number, m03: number, - m10: number, m11: number, m12: number, m13: number, - m20: number, m21: number, m22: number, m23: number, - m30: number, m31: number, m32: number, m33: number) { - setS44( - this.buf, - m00, m01, m02, m03, - m10, m11, m12, m13, - m20, m21, m22, m23, - m30, m31, m32, m33, - this.i - ); - return this; - } - - mul(m: Readonly) { - mul44(this.buf, m.buf, this.i, m.i); - return this; - } - - mulV3(v: Vec3) { - mulV344(v.buf, this.buf, v.i, this.i, v.s); - return v; - } - - mulV(v: Vec4) { - mulV44(v.buf, this.buf, v.i, this.i, v.s); - return v; - } - - determinant() { - return det44(this.buf, this.i); - } - - invert() { - invert44(this.buf, this.i); - return this; - } - - transpose() { - transpose44(this.buf, this.i); - return this; - } - - normalMat(m?: Mat33) { - !m && (m = new Mat33([])); - normal44(m.buf, this.buf, m.i, this.i); - return m; - } - - toMat33(m?: Mat33) { - !m && (m = new Mat33([])); - mat44to33(m.buf, this.buf, m.i, this.i); - return m; - } - - toString() { - const b = (get44(this.buf, this.i)).map((x) => x.toFixed(4)); - return `${b[0]} ${b[4]} ${b[8]} ${b[12]} -${b[1]} ${b[5]} ${b[9]} ${b[13]} -${b[2]} ${b[6]} ${b[10]} ${b[14]} -${b[3]} ${b[7]} ${b[11]} ${b[15]}`; - } - - toJSON() { - return get44(this.buf, this.i); - } -} - -declareIndices( - Mat44.prototype, - [ - "m00", "m01", "m02", "m03", - "m10", "m11", "m12", "m13", - "m20", "m21", "m22", "m23", - "m30", "m31", "m32", "m33" - ] -); diff --git a/packages/vectors3/src/max.ts b/packages/vectors/src/max.ts similarity index 100% rename from packages/vectors3/src/max.ts rename to packages/vectors/src/max.ts diff --git a/packages/vectors3/src/min.ts b/packages/vectors/src/min.ts similarity index 100% rename from packages/vectors3/src/min.ts rename to packages/vectors/src/min.ts diff --git a/packages/vectors3/src/minor.ts b/packages/vectors/src/minor.ts similarity index 100% rename from packages/vectors3/src/minor.ts rename to packages/vectors/src/minor.ts diff --git a/packages/vectors3/src/mix-bilinear.ts b/packages/vectors/src/mix-bilinear.ts similarity index 100% rename from packages/vectors3/src/mix-bilinear.ts rename to packages/vectors/src/mix-bilinear.ts diff --git a/packages/vectors3/src/mix-cubic.ts b/packages/vectors/src/mix-cubic.ts similarity index 100% rename from packages/vectors3/src/mix-cubic.ts rename to packages/vectors/src/mix-cubic.ts diff --git a/packages/vectors3/src/mix-quadratic.ts b/packages/vectors/src/mix-quadratic.ts similarity index 100% rename from packages/vectors3/src/mix-quadratic.ts rename to packages/vectors/src/mix-quadratic.ts diff --git a/packages/vectors3/src/mix.ts b/packages/vectors/src/mix.ts similarity index 100% rename from packages/vectors3/src/mix.ts rename to packages/vectors/src/mix.ts diff --git a/packages/vectors3/src/mixn.ts b/packages/vectors/src/mixn.ts similarity index 100% rename from packages/vectors3/src/mixn.ts rename to packages/vectors/src/mixn.ts diff --git a/packages/vectors3/src/mod.ts b/packages/vectors/src/mod.ts similarity index 100% rename from packages/vectors3/src/mod.ts rename to packages/vectors/src/mod.ts diff --git a/packages/vectors3/src/modn.ts b/packages/vectors/src/modn.ts similarity index 100% rename from packages/vectors3/src/modn.ts rename to packages/vectors/src/modn.ts diff --git a/packages/vectors3/src/mul.ts b/packages/vectors/src/mul.ts similarity index 100% rename from packages/vectors3/src/mul.ts rename to packages/vectors/src/mul.ts diff --git a/packages/vectors3/src/muln.ts b/packages/vectors/src/muln.ts similarity index 100% rename from packages/vectors3/src/muln.ts rename to packages/vectors/src/muln.ts diff --git a/packages/vectors3/src/muls.ts b/packages/vectors/src/muls.ts similarity index 100% rename from packages/vectors3/src/muls.ts rename to packages/vectors/src/muls.ts diff --git a/packages/vectors3/src/neg.ts b/packages/vectors/src/neg.ts similarity index 100% rename from packages/vectors3/src/neg.ts rename to packages/vectors/src/neg.ts diff --git a/packages/vectors3/src/normalize.ts b/packages/vectors/src/normalize.ts similarity index 100% rename from packages/vectors3/src/normalize.ts rename to packages/vectors/src/normalize.ts diff --git a/packages/vectors3/src/ortho-normal.ts b/packages/vectors/src/ortho-normal.ts similarity index 100% rename from packages/vectors3/src/ortho-normal.ts rename to packages/vectors/src/ortho-normal.ts diff --git a/packages/vectors3/src/perpendicular.ts b/packages/vectors/src/perpendicular.ts similarity index 100% rename from packages/vectors3/src/perpendicular.ts rename to packages/vectors/src/perpendicular.ts diff --git a/packages/vectors3/src/polar.ts b/packages/vectors/src/polar.ts similarity index 100% rename from packages/vectors3/src/polar.ts rename to packages/vectors/src/polar.ts diff --git a/packages/vectors3/src/pow.ts b/packages/vectors/src/pow.ts similarity index 100% rename from packages/vectors3/src/pow.ts rename to packages/vectors/src/pow.ts diff --git a/packages/vectors3/src/pown.ts b/packages/vectors/src/pown.ts similarity index 100% rename from packages/vectors3/src/pown.ts rename to packages/vectors/src/pown.ts diff --git a/packages/vectors3/src/project.ts b/packages/vectors/src/project.ts similarity index 100% rename from packages/vectors3/src/project.ts rename to packages/vectors/src/project.ts diff --git a/packages/vectors3/src/random.ts b/packages/vectors/src/random.ts similarity index 100% rename from packages/vectors3/src/random.ts rename to packages/vectors/src/random.ts diff --git a/packages/vectors3/src/reflect.ts b/packages/vectors/src/reflect.ts similarity index 100% rename from packages/vectors3/src/reflect.ts rename to packages/vectors/src/reflect.ts diff --git a/packages/vectors3/src/refract.ts b/packages/vectors/src/refract.ts similarity index 100% rename from packages/vectors3/src/refract.ts rename to packages/vectors/src/refract.ts diff --git a/packages/vectors3/src/rotate-around-axis.ts b/packages/vectors/src/rotate-around-axis.ts similarity index 100% rename from packages/vectors3/src/rotate-around-axis.ts rename to packages/vectors/src/rotate-around-axis.ts diff --git a/packages/vectors3/src/rotate-around-point.ts b/packages/vectors/src/rotate-around-point.ts similarity index 100% rename from packages/vectors3/src/rotate-around-point.ts rename to packages/vectors/src/rotate-around-point.ts diff --git a/packages/vectors3/src/rotate.ts b/packages/vectors/src/rotate.ts similarity index 100% rename from packages/vectors3/src/rotate.ts rename to packages/vectors/src/rotate.ts diff --git a/packages/vectors3/src/round.ts b/packages/vectors/src/round.ts similarity index 100% rename from packages/vectors3/src/round.ts rename to packages/vectors/src/round.ts diff --git a/packages/vectors3/src/set.ts b/packages/vectors/src/set.ts similarity index 100% rename from packages/vectors3/src/set.ts rename to packages/vectors/src/set.ts diff --git a/packages/vectors3/src/setc.ts b/packages/vectors/src/setc.ts similarity index 100% rename from packages/vectors3/src/setc.ts rename to packages/vectors/src/setc.ts diff --git a/packages/vectors3/src/setn.ts b/packages/vectors/src/setn.ts similarity index 100% rename from packages/vectors3/src/setn.ts rename to packages/vectors/src/setn.ts diff --git a/packages/vectors3/src/sets.ts b/packages/vectors/src/sets.ts similarity index 100% rename from packages/vectors3/src/sets.ts rename to packages/vectors/src/sets.ts diff --git a/packages/vectors3/src/setsn.ts b/packages/vectors/src/setsn.ts similarity index 100% rename from packages/vectors3/src/setsn.ts rename to packages/vectors/src/setsn.ts diff --git a/packages/vectors3/src/sign.ts b/packages/vectors/src/sign.ts similarity index 100% rename from packages/vectors3/src/sign.ts rename to packages/vectors/src/sign.ts diff --git a/packages/vectors3/src/signed-area.ts b/packages/vectors/src/signed-area.ts similarity index 100% rename from packages/vectors3/src/signed-area.ts rename to packages/vectors/src/signed-area.ts diff --git a/packages/vectors3/src/sin.ts b/packages/vectors/src/sin.ts similarity index 100% rename from packages/vectors3/src/sin.ts rename to packages/vectors/src/sin.ts diff --git a/packages/vectors3/src/sinh.ts b/packages/vectors/src/sinh.ts similarity index 100% rename from packages/vectors3/src/sinh.ts rename to packages/vectors/src/sinh.ts diff --git a/packages/vectors3/src/smoothstep.ts b/packages/vectors/src/smoothstep.ts similarity index 100% rename from packages/vectors3/src/smoothstep.ts rename to packages/vectors/src/smoothstep.ts diff --git a/packages/vectors3/src/sqrt.ts b/packages/vectors/src/sqrt.ts similarity index 100% rename from packages/vectors3/src/sqrt.ts rename to packages/vectors/src/sqrt.ts diff --git a/packages/vectors3/src/step.ts b/packages/vectors/src/step.ts similarity index 100% rename from packages/vectors3/src/step.ts rename to packages/vectors/src/step.ts diff --git a/packages/vectors3/src/sub.ts b/packages/vectors/src/sub.ts similarity index 100% rename from packages/vectors3/src/sub.ts rename to packages/vectors/src/sub.ts diff --git a/packages/vectors3/src/subm.ts b/packages/vectors/src/subm.ts similarity index 100% rename from packages/vectors3/src/subm.ts rename to packages/vectors/src/subm.ts diff --git a/packages/vectors3/src/submn.ts b/packages/vectors/src/submn.ts similarity index 100% rename from packages/vectors3/src/submn.ts rename to packages/vectors/src/submn.ts diff --git a/packages/vectors3/src/subn.ts b/packages/vectors/src/subn.ts similarity index 100% rename from packages/vectors3/src/subn.ts rename to packages/vectors/src/subn.ts diff --git a/packages/vectors3/src/subs.ts b/packages/vectors/src/subs.ts similarity index 100% rename from packages/vectors3/src/subs.ts rename to packages/vectors/src/subs.ts diff --git a/packages/vectors3/src/sum.ts b/packages/vectors/src/sum.ts similarity index 100% rename from packages/vectors3/src/sum.ts rename to packages/vectors/src/sum.ts diff --git a/packages/vectors3/src/swizzle.ts b/packages/vectors/src/swizzle.ts similarity index 100% rename from packages/vectors3/src/swizzle.ts rename to packages/vectors/src/swizzle.ts diff --git a/packages/vectors3/src/tan.ts b/packages/vectors/src/tan.ts similarity index 100% rename from packages/vectors3/src/tan.ts rename to packages/vectors/src/tan.ts diff --git a/packages/vectors3/src/tanh.ts b/packages/vectors/src/tanh.ts similarity index 100% rename from packages/vectors3/src/tanh.ts rename to packages/vectors/src/tanh.ts diff --git a/packages/vectors3/src/trunc.ts b/packages/vectors/src/trunc.ts similarity index 100% rename from packages/vectors3/src/trunc.ts rename to packages/vectors/src/trunc.ts diff --git a/packages/vectors/src/vec2.ts b/packages/vectors/src/vec2.ts index 7a3ee8ea46..c4273a4615 100644 --- a/packages/vectors/src/vec2.ts +++ b/packages/vectors/src/vec2.ts @@ -1,313 +1,28 @@ -import { isArrayLike } from "@thi.ng/checks"; +import { EPS } from "@thi.ng/math"; import { - atan2Abs, - EPS, - eqDelta, - fract, - HALF_PI, - max2id, - min2id, - mixBilinear, - PI, - smoothStep, - step -} from "@thi.ng/math"; -import { - IAngleBetween, - ICrossProduct, - IPolar, - IVec, IVector, - MAX4, - MIN4, - ONE4, + MAX2, + MIN2, + ONE2, ReadonlyVec, Vec, - Vec2Coord, - X4, - Y4, - ZERO4 + X2, + Y2, + ZERO2 } from "./api"; -import { declareIndices, defcommon } from "./codegen"; -import { $iter } from "./common"; - -export const op2 = (fn: (x: number) => number, a: Vec, ia = 0, sa = 1) => - (a[ia] = fn(a[ia]), a[ia + sa] = fn(a[ia + sa]), a); - -export const op20 = (fn: () => number, a: Vec, ia = 0, sa = 1) => ( - a[ia] = fn(), - a[ia + sa] = fn(), - a -); - -export const op21 = (fn: (a: number, n: number) => number, a: Vec, n: number, ia = 0, sa = 1) => ( - a[ia] = fn(a[ia], n), - a[ia + sa] = fn(a[ia + sa], n), - a -); - -export const get2 = (a: ReadonlyVec, ia = 0, sa = 1) => - set2(new ((a.constructor))(2), a, 0, ia, 1, sa); - -export const setS2 = (a: Vec, x: number, y: number, ia = 0, sa = 1) => - (a[ia] = x, a[ia + sa] = y, a); - -export const randNorm2 = (a: Vec, n = 1, ia = 0, sa = 1) => - randMinMax2(a, -n, n, ia, sa); - -export const randMinMax2 = (a: Vec, min: number, max: number, ia = 0, sa = 1) => { - const d = max - min; - return op20(() => min + d * Math.random(), a, ia, sa); -}; - -export const jitter2 = (a: Vec, n: number, ia = 0, sa = 1) => - op2((x) => x + Math.random() * 2 * n - n, a, ia, sa); - -export const swizzle2 = (a: Vec, b: ReadonlyVec, x: number, y: number, ia = 0, ib = 0, sa = 1, sb = 1) => - setS2(a, b[ib + x * sb], b[ib + y * sb], ia, sa); - -export const swap2 = (a: Vec, b: Vec, ia = 0, ib = 0, sa = 1, sb = 1) => { - let t = a[ia]; a[ia] = b[ib]; b[ib] = t; - ia += sa; ib += sb; - t = a[ia]; a[ia] = b[ib]; b[ib] = t; - return a; -}; - -export const equiv2 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - a[ia] === b[ib] && - a[ia + sa] === b[ib + sb]; - -export const eqDelta2 = (a: ReadonlyVec, b: ReadonlyVec, eps = EPS, ia = 0, ib = 0, sa = 1, sb = 1) => - eqDelta(a[ia], b[ib], eps) && - eqDelta(a[ia + sa], b[ib + sb], eps); - -export const eqDelta2buf = (a: ReadonlyVec, b: ReadonlyVec, num: number, eps = EPS, ia = 0, ib = 0, sca = 1, scb = 1, sea = 2, seb = 2) => { - while (--num >= 0) { - if (!eqDelta2(a, b, eps, ia + num * sea, ib + num * seb, sca, scb)) { - return false; - } - } - return true; -}; - -export const eqDelta2array = (a: ReadonlyVec[], b: ReadonlyVec[], eps = EPS) => { - const na = a.length; - if (b.length !== na) { - return false; - } - for (let i = 0; i < na; i++) { - if (!eqDelta2(a[i], b[i], eps)) { - return false; - } - } - return true; -}; - -export const compare2 = ( - a: ReadonlyVec, - b: ReadonlyVec, - o1: Vec2Coord, o2: Vec2Coord, - ia = 0, ib = 0, sa = 1, sb = 1): number => { - - const ax = a[ia + o1 * sa]; - const ay = a[ia + o2 * sa]; - const bx = b[ib + o1 * sb]; - const by = b[ib + o2 * sb]; - return ax === bx ? - ay === by ? - 0 : - ay < by ? -2 : 2 : - ax < bx ? -1 : 1; -}; - -export const collate2 = (buf: Vec, src: Iterable, start = 0, cstride = 1, estride = 2) => { - for (let v of src) { - set2(buf, v, start, 0, cstride, 1); - start += estride; - } - return buf; -}; - -export const [ - set2, setN2, - add2, sub2, mul2, div2, - add2o, sub2o, mul2o, div2o, - addN2, subN2, mulN2, divN2, - addN2o, subN2o, mulN2o, divN2o, - madd2, maddN2, msub2, msubN2, - abs2, sign2, floor2, ceil2, sin2, cos2, sqrt2, - pow2, min2, max2, - mix2, mixN2, mix2o, mixN2o -] = defcommon(2); - -export const neg2 = (a: Vec, ia = 0, sa = 1) => - mulN2(a, -1, ia, sa); - -export const fract2 = (a: Vec, ia = 0, sa = 1) => - op2(fract, a, ia, sa); - -export const powN2 = (a: Vec, n: number, ia = 0, sa = 1) => - op21(Math.pow, a, n, ia, sa); - -export const dot2 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - a[ia] * b[ib] + a[ia + sa] * b[ib + sb]; - -export const cross2 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - a[ia] * b[ib + sb] - a[ia + sa] * b[ib]; - -export const mixBilinear2 = ( - a: Vec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, u: number, v: number, - ia = 0, ib = 0, ic = 0, id = 0, - sa = 1, sb = 1, sc = 1, sd = 1) => ( - a[ia] = mixBilinear(a[ia], b[ib], c[ic], d[id], u, v), - a[ia + sa] = mixBilinear(a[ia + sa], b[ib + sb], c[ic + sc], d[id + sd], u, v), - a - ); - -export const clamp2 = (a: Vec, min: ReadonlyVec, max: ReadonlyVec, ia = 0, imin = 0, imax = 0, sa = 1, smin = 1, smax = 1) => - max2(min2(a, max, ia, imax, sa, smax), min, ia, imin, sa, smin); - -export const step2 = (a: Vec, e: ReadonlyVec, ia = 0, ie = 0, sa = 1, stridee = 1) => - (a[ia] = step(e[ie], a[ia]), a[ia + sa] = step(e[ie + stridee], a[ia + sa]), a); - -export const smoothStep2 = (a: Vec, e1: ReadonlyVec, e2: ReadonlyVec, ia = 0, ie1 = 0, ie2 = 0, sa = 1, se1 = 1, se2 = 1) => ( - a[ia] = smoothStep(e1[ie1], e2[ie2], a[ia]), - a[ia + sa] = smoothStep(e1[ie1 + se1], e2[ie2 + se2], a[ia + sa]), - a -); - -export const magSq2 = (a: ReadonlyVec, ia = 0, sa = 1) => { - const x = a[ia], y = a[ia + sa]; - return x * x + y * y; -}; - -export const mag2 = (a: ReadonlyVec, ia = 0, sa = 1) => - Math.sqrt(magSq2(a, ia, sa)); - -export const distSq2 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => { - const x = a[ia] - b[ib]; - const y = a[ia + sa] - b[ib + sb]; - return x * x + y * y; -}; - -export const dist2 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - Math.sqrt(distSq2(a, b, ia, ib, sa, sb)); - -export const distManhattan2 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => { - return Math.abs(a[ia] - b[ib]) + Math.abs(a[ia + sa] - b[ib + sb]) -}; - -export const distChebyshev2 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => { - return Math.max(Math.abs(a[ia] - b[ib]), Math.abs(a[ia + sa] - b[ib + sb])) -}; - -export const normalize2 = (a: Vec, n = 1, ia = 0, sa = 1) => { - const m = mag2(a, ia, sa); - m >= EPS && mulN2(a, n / m, ia, sa); - return a; -}; - -export const limit2 = (a: Vec, n: number, ia = 0, sa = 1) => { - const m = mag2(a, ia, sa); - m >= n && mulN2(a, n / m, ia, sa); - return a; -}; - -export const reflect2 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - maddN2(a, b, -2 * dot2(a, b, ia, ib, sa, sb), ia, ib, sa, sb); - -export const refract2 = (a: Vec, b: ReadonlyVec, eta: number, ia = 0, ib = 0, sa = 1, sb = 1) => { - const d = dot2(a, b, ia, ib, sa, sb); - const k = 1 - eta * eta * (1 - d * d); - return k < 0 ? - setN2(a, 0, ia, sa) : - msubN2(mulN2(a, eta, ia, sa), b, eta * d + Math.sqrt(k), ia, ib, sa, sb); -}; - -export const perpendicularLeft2 = (a: Vec, ia = 0, sa = 1) => { - const x = a[ia]; - a[ia] = -a[ia + sa]; - a[ia + sa] = x; - return a; -}; - -export const perpendicularRight2 = (a: Vec, ia = 0, sa = 1) => { - const x = -a[ia]; - a[ia] = a[ia + sa]; - a[ia + sa] = x; - return a; -}; - -export const rotate2 = (a: Vec, theta: number, ia = 0, sa = 1) => { - const s = Math.sin(theta); - const c = Math.cos(theta); - const x = a[ia]; - const y = a[ia + sa]; - return setS2(a, x * c - y * s, x * s + y * c, ia, sa); -}; - -export const rotateAroundPoint2 = (a: Vec, b: Vec, theta: number, ia = 0, ib = 0, sa = 1, sb = 1) => { - const x = a[ia] - b[ib]; - const y = a[ia + sa] - b[ib + sb]; - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS2( - a, - x * c - y * s + b[ib], - x * s + y * c + b[ib + sb], - ia, sa - ); -}; - -export const heading2 = (a: ReadonlyVec, ia = 0, sa = 1) => - atan2Abs(a[ia + sa], a[ia]); - -export const angleRatio2 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - dot2(a, b, ia, ib, sa, sb) / (mag2(a, ia, sa) * mag2(b, ib, sb)); - -export const angleBetween2 = (a: ReadonlyVec, b: ReadonlyVec, normalize = false, ia = 0, ib = 0, sa = 1, sb = 1): number => - normalize ? - (a[ia] * b[ib + sb] < a[ia + sa] * b[ib] ? -1 : 1) * - Math.acos(angleRatio2(a, b, ia, ib, sa, sb)) : - Math.acos(dot2(a, b, ia, ib, sa, sb)); - -export const bisect2 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => { - const theta = (heading2(a, ia, sa) + heading2(b, ib, sb)) / 2; - return theta <= HALF_PI ? theta : PI - theta; -} - -export const toPolar2 = (a: Vec, ia = 0, sa = 1) => { - const x = a[ia], y = a[ia + sa]; - return setS2(a, Math.sqrt(x * x + y * y), Math.atan2(y, x), ia, sa); -}; - -export const toCartesian2 = (a: Vec, b: ReadonlyVec = ZERO4, ia = 0, ib = 0, sa = 1, sb = 1) => { - const r = a[ia], theta = a[ia + sa]; - return setS2( - a, - r * Math.cos(theta) + b[ib], - r * Math.sin(theta) + b[ib + sb], - ia, sa - ); -}; - -export const minorAxis2 = (a: Vec, ia = 0, sa = 1) => - min2id(Math.abs(a[ia]), Math.abs(a[ia + sa])); - -export const majorAxis2 = (a: Vec, ia = 0, sa = 1) => - max2id(Math.abs(a[ia]), Math.abs(a[ia + sa])); - -export const vec2 = (x = 0, y = 0) => - new Vec2([x, y]); - -export const asVec2 = (x: ReadonlyVec) => - x instanceof Vec2 ? x : new Vec2([x[0] || 0, x[1] || 0]); +import { eqDelta2 } from "./eqdelta"; +import { declareIndices } from "./internal/accessors"; +import { AVec } from "./internal/avec"; +import { + intoBuffer, + mapBuffer, + values, + vecIterator +} from "./internal/vec-utils"; +import { setS2 } from "./sets"; -export class Vec2 implements - IVector, - IAngleBetween, - ICrossProduct, - IPolar { +export class Vec2 extends AVec implements + IVector { /** * Returns array of memory mapped `Vec2` instances using given @@ -318,18 +33,13 @@ export class Vec2 implements * interleaved etc. * * @param buf backing array - * @param n num vectors + * @param num num vectors * @param start start index * @param cstride component stride * @param estride element stride */ - static mapBuffer(buf: Vec, n: number = buf.length >> 1, start = 0, cstride = 1, estride = 2) { - const res: Vec2[] = []; - while (--n >= 0) { - res.push(new Vec2(buf, start, cstride)); - start += estride; - } - return res; + static mapBuffer(buf: Vec, num: number = buf.length >> 1, start = 0, cstride = 1, estride = 2) { + return mapBuffer(Vec2, buf, num, start, cstride, estride); } /** @@ -338,7 +48,7 @@ export class Vec2 implements * strides, starting at `start` index. It's the user's * responsibility to ensure the target buffer has sufficient * capacity to hold the input vectors. See `Vec2.mapBuffer` for the - * reverse operation. Returns buffer. + * inverse operation. Returns `buf`. * * @param buf * @param src @@ -346,66 +56,31 @@ export class Vec2 implements * @param cstride * @param estride */ - static intoBuffer(buf: Vec, src: Iterable>, start = 0, cstride = 1, estride = 2) { - for (let v of src) { - set2(buf, v.buf, start, v.i, cstride, v.s); - start += estride; - } - return buf; - } - - static swizzle(v: IVec, x: number, y: number) { - return new Vec2([]).swizzle(v, x, y); - } - - static mixBilinear(a: Readonly, b: Readonly, c: Readonly, d: Readonly, u: number, v: number) { - return new Vec2( - mixBilinear2( - get2(a.buf, a.i, a.s), b.buf, c.buf, d.buf, u, v, - 0, b.i, c.i, d.i, - 1, b.s, c.s, d.s, - ) - ); - } - - static randNorm(n = 1) { - return new Vec2(randNorm2([], n)); + static intoBuffer(buf: Vec, src: Iterable, start = 0, cstride = 1, estride = 2) { + return intoBuffer(setS2, buf, src, start, cstride, estride); } - static random(min: number, max: number) { - return new Vec2(randMinMax2([], min, max)); + static iterator(buf: Vec, num: number, start = 0, cstride = 1, estride = 2) { + return vecIterator(Vec2, buf, num, start, cstride, estride); } - static comparator(o1: Vec2Coord, o2: Vec2Coord) { - return (a: Readonly, b: Readonly) => a.compare(b, o1, o2); - } - - static readonly ZERO = Object.freeze(new Vec2(ZERO4)); - static readonly ONE = Object.freeze(new Vec2(ONE4)); - static readonly MIN = Object.freeze(new Vec2(MIN4)); - static readonly MAX = Object.freeze(new Vec2(MAX4)); - static readonly X_AXIS = Object.freeze(new Vec2(X4)); - static readonly Y_AXIS = Object.freeze(new Vec2(Y4)); + static readonly X_AXIS = new Vec2(X2); + static readonly Y_AXIS = new Vec2(Y2); + static readonly MIN = new Vec2(MIN2); + static readonly MAX = new Vec2(MAX2); + static readonly ZERO = new Vec2(ZERO2); + static readonly ONE = new Vec2(ONE2); - buf: Vec; - i: number; - s: number; x: number; y: number; [id: number]: number; - constructor(buf?: Vec, index = 0, stride = 1) { - this.buf = buf || [0, 0]; - this.i = index; - this.s = stride; + constructor(buf?: Vec, offset = 0, stride = 1) { + super(buf || [0, 0], offset, stride); } [Symbol.iterator]() { - return $iter(this.buf, 2, this.i, this.s); - } - - array() { - return get2(this.buf, this.i, this.s); + return values(this.buf, 2, this.offset, this.stride); } get length() { @@ -413,402 +88,40 @@ export class Vec2 implements } copy() { - return new Vec2(get2(this.buf, this.i, this.s)); - } - - empty() { - return new Vec2(); - } - - equiv(v: any) { - return v instanceof Vec2 ? - equiv2(this.buf, v.buf, this.i, v.i, this.s, v.s) : - isArrayLike(v) && v.length === 2 ? - equiv2(this.buf, v, this.i, 0, this.s, 1) : - false; - } - - eqDelta(v: Readonly, eps = EPS) { - return eqDelta2(this.buf, v.buf, eps, this.i, v.i, this.s, v.s); - } - - compare(v: Readonly, o1: Vec2Coord = 0, o2: Vec2Coord = 1) { - return compare2(this.buf, v.buf, o1, o2, this.i, v.i, this.s, v.s); - } - - set(v: Readonly) { - set2(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - setN(n: number) { - setN2(this.buf, n, this.i, this.s); - return this; - } - - setS(x: number, y: number) { - setS2(this.buf, x, y, this.i, this.s); - return this; - } - - jitter(n = 1) { - jitter2(this.buf, n, this.i, this.s); - return this; - } - - swizzle(v: IVec, x: number, y: number) { - swizzle2(this.buf, v.buf, x, y, this.i, v.i, this.s, v.s); - return this; - } - - swap(v: Vec2) { - swap2(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - add(v: Readonly) { - add2(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - sub(v: Readonly) { - sub2(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - mul(v: Readonly) { - mul2(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - div(v: Readonly) { - div2(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - addN(n: number) { - addN2(this.buf, n, this.i, this.s); - return this; - } - - subN(n: number) { - subN2(this.buf, n, this.i, this.s); - return this; - } - - mulN(n: number) { - mulN2(this.buf, n, this.i, this.s); - return this; - } - - divN(n: number) { - divN2(this.buf, n, this.i, this.s); - return this; + return new Vec2([this.x, this.y]); } - addNew(b: Readonly, out?: Vec2) { - !out && (out = new Vec2([])); - add2o(out.buf, this.buf, b.buf, out.i, this.i, b.i, out.s, this.s, b.s); - return out; + copyView() { + return new Vec2(this.buf, this.offset, this.stride); } - subNew(b: Readonly, out?: Vec2) { - !out && (out = new Vec2([])); - sub2o(out.buf, this.buf, b.buf, out.i, this.i, b.i, out.s, this.s, b.s); - return out; - } - - mulNew(b: Readonly, out?: Vec2) { - !out && (out = new Vec2([])); - mul2o(out.buf, this.buf, b.buf, out.i, this.i, b.i, out.s, this.s, b.s); - return out; - } - - divNew(b: Readonly, out?: Vec2) { - !out && (out = new Vec2([])); - div2o(out.buf, this.buf, b.buf, out.i, this.i, b.i, out.s, this.s, b.s); - return out; - } - - addNewN(n: number, out?: Vec2) { - !out && (out = new Vec2([])); - addN2o(out.buf, this.buf, n, out.i, this.i, out.s, this.s); - return out; - } - - subNewN(n: number, out?: Vec2) { - !out && (out = new Vec2([])); - subN2o(out.buf, this.buf, n, out.i, this.i, out.s, this.s); - return out; - } - - mulNewN(n: number, out?: Vec2) { - !out && (out = new Vec2([])); - mulN2o(out.buf, this.buf, n, out.i, this.i, out.s, this.s); - return out; - } - - divNewN(n: number, out?: Vec2) { - !out && (out = new Vec2([])); - divN2o(out.buf, this.buf, n, out.i, this.i, out.s, this.s); - return out; - } - - maddNew(b: Readonly, c: Readonly, out?: Vec2) { - out = out ? out.set(this) : this.copy(); - madd2(out.buf, b.buf, c.buf, out.i, b.i, c.i, out.s, b.s, c.s); - return out; - } - - maddNewN(b: Readonly, n: number, out?: Vec2) { - out = out ? out.set(this) : this.copy(); - maddN2(out.buf, b.buf, n, out.i, b.i, out.s, b.s); - return out; - } - - msubNew(b: Readonly, c: Readonly, out?: Vec2) { - out = out ? out.set(this) : this.copy(); - msub2(out.buf, b.buf, c.buf, out.i, b.i, c.i, out.s, b.s, c.s); - return out; - } - - msubNewN(b: Readonly, n: number, out?: Vec2) { - out = out ? out.set(this) : this.copy(); - msubN2(out.buf, b.buf, n, out.i, b.i, out.s, b.s); - return out; - } - - mixNew(b: Readonly, t: Readonly, out?: Vec2) { - !out && (out = new Vec2([])); - mix2o(out.buf, this.buf, b.buf, t.buf, out.i, this.i, b.i, t.i, out.s, this.s, b.s, t.s); - return out; - } - - mixNewN(b: Readonly, n = 0.5, out?: Vec2) { - !out && (out = new Vec2([])); - mixN2o(out.buf, this.buf, b.buf, n, out.i, this.i, b.i, out.s, this.s, b.s); - return out; - } - - neg() { - mulN2(this.buf, -1, this.i, this.s); - return this; - } - - abs() { - abs2(this.buf, this.i, this.s); - return this; - } - - sign() { - sign2(this.buf, this.i, this.s); - return this; - } - - floor() { - floor2(this.buf, this.i, this.s); - return this; - } - - ceil() { - ceil2(this.buf, this.i, this.s); - return this; - } - - fract() { - fract2(this.buf, this.i, this.s); - return this; - } - - sqrt() { - sqrt2(this.buf, this.i, this.s); - return this; - } - - pow(v: Readonly) { - pow2(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - powN(n: number) { - powN2(this.buf, n, this.i, this.s); - return this; - } - - sin() { - sin2(this.buf, this.i, this.s); - return this; - } - - cos() { - cos2(this.buf, this.i, this.s); - return this; - } - - madd(b: Readonly, c: Readonly) { - madd2(this.buf, b.buf, c.buf, this.i, b.i, c.i, this.s, b.s, c.s); - return this; - } - - maddN(b: Readonly, n: number) { - maddN2(this.buf, b.buf, n, this.i, b.i, this.s, b.s); - return this; - } - - msub(b: Readonly, c: Readonly) { - msub2(this.buf, b.buf, c.buf, this.i, b.i, c.i, this.s, b.s, c.s); - return this; - } - - msubN(b: Readonly, n: number) { - msubN2(this.buf, b.buf, n, this.i, b.i, this.s, b.s); - return this; - } - - mix(b: Readonly, c: Readonly) { - mix2(this.buf, b.buf, c.buf, this.i, b.i, c.i, this.s, b.s, c.s); - return this; - } - - mixN(b: Readonly, n = 0.5) { - mixN2(this.buf, b.buf, n, this.i, b.i, this.s, b.s); - return this; - } - - min(v: Readonly) { - min2(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - max(v: Readonly) { - max2(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - clamp(min: Readonly, max: Readonly) { - clamp2(this.buf, min.buf, max.buf, this.i, min.i, max.i, this.s, min.s, max.s); - return this; - } - - minorAxis() { - return minorAxis2(this.buf, this.i, this.s); - } - - majorAxis() { - return majorAxis2(this.buf, this.i, this.s); - } - - step(e: Readonly) { - step2(this.buf, e.buf, this.i, e.i, this.s, e.s); - return this; - } - - smoothStep(e1: Readonly, e2: Readonly) { - smoothStep2(this.buf, e1.buf, e2.buf, this.i, e1.i, e2.i, this.s, e1.s, e2.s); - return this; - } - - dot(v: Readonly) { - return dot2(this.buf, v.buf, this.i, v.i, this.s, v.s); - } - - cross(v: Readonly) { - return cross2(this.buf, v.buf, this.i, v.i, this.s, v.s); - } - - mag() { - return mag2(this.buf, this.i, this.s); - } - - magSq() { - return magSq2(this.buf, this.i, this.s); - } - - dist(v: Readonly) { - return dist2(this.buf, v.buf, this.i, v.i, this.s, v.s); - } - - distSq(v: Readonly) { - return distSq2(this.buf, v.buf, this.i, v.i, this.s, v.s); - } - - distManhattan(v: Readonly) { - return distManhattan2(this.buf, v.buf, this.i, v.i, this.s, v.s); - } - - distChebyshev(v: Readonly) { - return distChebyshev2(this.buf, v.buf, this.i, v.i, this.s, v.s); - } - - normalize(len = 1) { - normalize2(this.buf, len, this.i, this.s); - return this; - } - - limit(len: number) { - limit2(this.buf, len, this.i, this.s); - return this; - } - - reflect(n: Readonly) { - reflect2(this.buf, n.buf, this.i, n.i, this.s, n.s); - return this; - } - - refract(n: Readonly, eta: number) { - refract2(this.buf, n.buf, eta, this.i, n.i, this.s, n.s); - return this; - } - - rotate(theta: number) { - rotate2(this.buf, theta, this.i, this.s); - return this; - } - - rotateAroundPoint(v: Readonly, theta: number) { - rotateAroundPoint2(this.buf, v.buf, theta, this.i, v.i, this.s, v.s); - return this; - } - - heading() { - return heading2(this.buf, this.i, this.s); - } - - angleBetween(v: Readonly, normalize = false) { - return angleBetween2(this.buf, v.buf, normalize, this.i, v.i, this.s, v.s); - } - - bisect(v: Readonly) { - return bisect2(this.buf, v.buf, this.i, v.i, this.s, v.s); - } - - perpendicularLeft() { - perpendicularLeft2(this.buf, this.i, this.s); - return this; - } - - perpendicularRight() { - perpendicularRight2(this.buf, this.i, this.s); - return this; + empty() { + return new Vec2(); } - toPolar() { - toPolar2(this.buf, this.i, this.s); - return this; + eqDelta(v: ReadonlyVec, eps = EPS) { + return eqDelta2(this, v, eps); } - toCartesian(o: Readonly = Vec2.ZERO) { - toCartesian2(this.buf, o.buf, this.i, o.i, this.s, o.s); - return this; + toJSON() { + return [this.x, this.y]; } toString() { - return `[${this.buf[this.i]}, ${this.buf[this.i + this.s]}]`; - } - - toJSON() { - return this.array(); + return `[${this.x}, ${this.y}]`; } } declareIndices(Vec2.prototype, ["x", "y"]); + +export const vec2 = + (x = 0, y = 0) => new Vec2([x, y]); + +export const vec2n = + (n: number) => new Vec2([n, n]); + +export const asVec2 = + (x: Vec) => + x instanceof Vec2 ? + x : + new Vec2(x.length >= 2 ? x : [x[0] || 0, x[1] || 0]); diff --git a/packages/vectors/src/vec3.ts b/packages/vectors/src/vec3.ts index c8003a52ec..b800a053c3 100644 --- a/packages/vectors/src/vec3.ts +++ b/packages/vectors/src/vec3.ts @@ -1,377 +1,29 @@ -import { isArrayLike } from "@thi.ng/checks"; +import { EPS } from "@thi.ng/math"; import { - atan2Abs, - EPS, - eqDelta, - fract, - max3id, - min3id, - mixBilinear, - smoothStep, - step -} from "@thi.ng/math"; -import { - IAngleBetween, - ICrossProduct, - IPolar, - IVec, IVector, - MAX4, - MIN4, - ONE4, + MAX3, + MIN3, + ONE3, ReadonlyVec, Vec, - Vec3Coord, - X4, - Y4, - Z4, - ZERO4 + X3, + Y3, + Z3, + ZERO3 } from "./api"; -import { declareIndices, defcommon } from "./codegen"; -import { $iter } from "./common"; +import { eqDelta3 } from "./eqdelta"; +import { declareIndices } from "./internal/accessors"; +import { AVec } from "./internal/avec"; import { - heading2, - rotate2, - toCartesian2, - toPolar2 -} from "./vec2"; - -export const op3 = (fn: (x: number) => number, a: Vec, ia = 0, sa = 1) => ( - a[ia] = fn(a[ia]), - a[ia + sa] = fn(a[ia + sa]), - a[ia + 2 * sa] = fn(a[ia + 2 * sa]), - a -); - -export const op30 = (fn: () => number, a: Vec, ia = 0, sa = 1) => ( - a[ia] = fn(), - a[ia + sa] = fn(), - a[ia + 2 * sa] = fn(), - a -); - -export const op31 = (fn: (a: number, n: number) => number, a: Vec, n: number, ia = 0, sa = 1) => ( - a[ia] = fn(a[ia], n), - a[ia + sa] = fn(a[ia + sa], n), - a[ia + 2 * sa] = fn(a[ia + 2 * sa], n), - a -); - -export const get3 = (a: ReadonlyVec, ia = 0, sa = 1) => - set3(new ((a.constructor))(3), a, 0, ia, 1, sa); - -export const setS3 = (a: Vec, x: number, y: number, z: number, ia = 0, sa = 1) => - (a[ia] = x, a[ia + sa] = y, a[ia + 2 * sa] = z, a); - -export const randNorm3 = (a: Vec, n = 1, ia = 0, sa = 1) => - randMinMax3(a, -n, n, ia, sa); - -export const randMinMax3 = (a: Vec, min: number, max: number, ia = 0, sa = 1) => { - const d = max - min; - return op30(() => min + d * Math.random(), a, ia, sa); -}; - -export const jitter3 = (a: Vec, n: number, ia = 0, sa = 1) => - op3((x) => x + Math.random() * 2 * n - n, a, ia, sa); - -export const swizzle3 = (a: Vec, b: ReadonlyVec, x: number, y: number, z: number, ia = 0, ib = 0, sa = 1, sb = 1) => - setS3(a, b[ib + x * sb], b[ib + y * sb], b[ib + z * sb], ia, sa); - -export const swap3 = (a: Vec, b: Vec, ia = 0, ib = 0, sa = 1, sb = 1) => { - let t = a[ia]; a[ia] = b[ib]; b[ib] = t; - ia += sa; ib += sb; - t = a[ia]; a[ia] = b[ib]; b[ib] = t; - ia += sa; ib += sb; - t = a[ia]; a[ia] = b[ib]; b[ib] = t; - return a; -}; - -export const equiv3 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - a[ia] === b[ib] && - a[ia + sa] === b[ib + sb] && - a[ia + 2 * sa] === b[ib + 2 * sb]; - -export const eqDelta3 = (a: ReadonlyVec, b: ReadonlyVec, eps = EPS, ia = 0, ib = 0, sa = 1, sb = 1) => - eqDelta(a[ia], b[ib], eps) && - eqDelta(a[ia + sa], b[ib + sb], eps) && - eqDelta(a[ia + 2 * sa], b[ib + 2 * sb], eps); - -export const eqDelta3buf = (a: ReadonlyVec, b: ReadonlyVec, num: number, eps = EPS, ia = 0, ib = 0, sca = 1, scb = 1, sea = 3, seb = 3) => { - while (--num >= 0) { - if (!eqDelta3(a, b, eps, ia + num * sea, ib + num * seb, sca, scb)) { - return false; - } - } - return true; -}; - -export const eqDelta3array = (a: ReadonlyVec[], b: ReadonlyVec[], eps = EPS) => { - const na = a.length; - if (b.length !== na) { - return false; - } - for (let i = 0; i < na; i++) { - if (!eqDelta3(a[i], b[i], eps)) { - return false; - } - } - return true; -}; - -export const compare3 = ( - a: ReadonlyVec, - b: ReadonlyVec, - o1: Vec3Coord, o2: Vec3Coord, o3: Vec3Coord, - ia = 0, ib = 0, sa = 1, sb = 1): number => { - - const ax = a[ia + o1 * sa]; - const ay = a[ia + o2 * sa]; - const az = a[ia + o3 * sa]; - const bx = b[ib + o1 * sb]; - const by = b[ib + o2 * sb]; - const bz = b[ib + o3 * sb]; - return ax === bx ? - ay === by ? - az === bz ? - 0 : - az < bz ? -3 : 3 : - ay < by ? -2 : 2 : - ax < bx ? -1 : 1; -}; - -export const collate3 = (buf: Vec, src: Iterable, start = 0, cstride = 1, estride = 3) => { - for (let v of src) { - set3(buf, v, start, 0, cstride, 1); - start += estride; - } - return buf; -}; - -export const [ - set3, setN3, - add3, sub3, mul3, div3, - add3o, sub3o, mul3o, div3o, - addN3, subN3, mulN3, divN3, - addN3o, subN3o, mulN3o, divN3o, - madd3, maddN3, msub3, msubN3, - abs3, sign3, floor3, ceil3, sin3, cos3, sqrt3, - pow3, min3, max3, - mix3, mixN3, mix3o, mixN3o -] = defcommon(3); - -export const neg3 = (a: Vec, ia = 0, sa = 1) => - mulN3(a, -1, ia, sa); - -export const fract3 = (a: Vec, ia = 0, sa = 1) => - op3(fract, a, ia, sa); - -export const powN3 = (a: Vec, n: number, ia = 0, sa = 1) => - op31(Math.pow, a, n, ia, sa); - -export const dot3 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - a[ia] * b[ib] + - a[ia + sa] * b[ib + sb] + - a[ia + 2 * sa] * b[ib + 2 * sb]; - -export const cross3 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => { - const iay = ia + sa; - const iaz = ia + 2 * sa; - const iby = ib + sb; - const ibz = ib + 2 * sb; - const x = a[iay] * b[ibz] - a[iaz] * b[iby]; - const y = a[iaz] * b[ib] - a[ia] * b[ibz]; - a[iaz] = a[ia] * b[iby] - a[iay] * b[ib]; - a[iay] = y; - a[ia] = x; - return a; -}; - -export const orthoNormal3 = (a: Vec, b: Vec, c: Vec, ia = 0, ib = 0, ic = 0, sa = 1, sb = 1, sc = 1) => - cross3( - sub3(get3(c, ic, sc), a, 0, ia, 1, sa), - sub3(get3(b, ib, sb), a, 0, ia, 1, sa) - ); - -export const mixBilinear3 = ( - a: Vec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, u: number, v: number, - ia = 0, ib = 0, ic = 0, id = 0, - sa = 1, sb = 1, sc = 1, sd = 1) => ( - a[ia] = mixBilinear(a[ia], b[ib], c[ic], d[id], u, v), - a[ia + sa] = mixBilinear(a[ia + sa], b[ib + sb], c[ic + sc], d[id + sd], u, v), - a[ia + 2 * sa] = mixBilinear(a[ia + 2 * sa], b[ib + 2 * sb], c[ic + 2 * sc], d[id + 2 * sd], u, v), - a - ); - -export const clamp3 = (a: Vec, min: ReadonlyVec, max: ReadonlyVec, ia = 0, imin = 0, imax = 0, sa = 1, smin = 1, smax = 1) => - max3(min3(a, max, ia, imax, sa, smax), min, ia, imin, sa, smin); - -export const step3 = (a: Vec, e: ReadonlyVec, ia = 0, ie = 0, sa = 1, se = 1) => ( - a[ia] = step(e[ie], a[ia]), - a[ia + sa] = step(e[ie + se], a[ia + sa]), - a[ia + 2 * sa] = step(e[ie + 2 * se], a[ia + 2 * sa]), - a -); - -export const smoothStep3 = (a: Vec, e1: ReadonlyVec, e2: ReadonlyVec, ia = 0, ie1 = 0, ie2 = 0, sa = 1, se1 = 1, se2 = 1) => ( - a[ia] = smoothStep(e1[ie1], e2[ie2], a[ia]), - a[ia + sa] = smoothStep(e1[ie1 + se1], e2[ie2 + se2], a[ia + sa]), - a[ia + 2 * sa] = smoothStep(e1[ie1 + 2 * se1], e2[ie2 + 2 * se2], a[ia + 2 * sa]), - a -); - -export const magSq3 = (a: ReadonlyVec, ia = 0, sa = 1) => { - const x = a[ia]; - const y = a[ia + sa]; - const z = a[ia + 2 * sa]; - return x * x + y * y + z * z; -}; - -export const mag3 = (a: ReadonlyVec, ia = 0, sa = 1) => - Math.sqrt(magSq3(a, ia, sa)); - -export const distSq3 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => { - const x = a[ia] - b[ib]; - const y = a[ia + sa] - b[ib + sb]; - const z = a[ia + 2 * sa] - b[ib + 2 * sb]; - return x * x + y * y + z * z; -}; - -export const dist3 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - Math.sqrt(distSq3(a, b, ia, ib, sa, sb)); - -export const distManhattan3 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - Math.abs(a[ia] - b[ib]) + - Math.abs(a[ia + sa] - b[ib + sb]) + - Math.abs(a[ia + 2 * sa] - b[ib + 2 * sb]); - -export const distChebyshev3 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - Math.max( - Math.abs(a[ia] - b[ib]), - Math.abs(a[ia + sa] - b[ib + sb]), - Math.abs(a[ia + 2 * sa] - b[ib + 2 * sb]) - ); - -export const normalize3 = (a: Vec, n = 1, ia = 0, sa = 1) => { - const m = mag3(a, ia, sa); - m >= EPS && mulN3(a, n / m, ia, sa); - return a; -}; - -export const limit3 = (a: Vec, n: number, ia = 0, sa = 1) => { - const m = mag3(a, ia, sa); - m >= n && mulN3(a, n / m, ia, sa); - return a; -}; - -export const reflect3 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - maddN3(a, b, -2 * dot3(a, b, ia, ib, sa, sb), ia, ib, sa, sb); - -export const refract3 = (a: Vec, b: ReadonlyVec, eta: number, ia = 0, ib = 0, sa = 1, sb = 1) => { - const d = dot3(a, b, ia, ib, sa, sb); - const k = 1 - eta * eta * (1 - d * d); - return k < 0 ? - setN3(a, 0, ia, sa) : - msubN3(mulN3(a, eta, ia, sa), b, eta * d + Math.sqrt(k), ia, ib, sa, sb); -}; - -export const rotateX3 = (a: Vec, theta: number, ia = 0, sa = 1) => - rotate2(a, theta, ia + sa, sa); - -export const rotateY3 = (a: Vec, theta: number, ia = 0, sa = 1) => - rotate2(a, theta, ia + 2 * sa, -2 * sa); - -export const rotateZ3 = rotate2; - -export const rotateAroundAxis3 = (v: Vec, axis: Vec, theta: number, ia = 0, ib = 0, sa = 1, sb = 1) => { - const x = v[ia]; - const y = v[ia + sa]; - const z = v[ia + 2 * sa]; - const ax = axis[ib]; - const ay = axis[ib + sb]; - const az = axis[ib + 2 * sb]; - const ux = ax * x; - const uy = ax * y; - const uz = ax * z; - const vx = ay * x; - const vy = ay * y; - const vz = ay * z; - const wx = az * x; - const wy = az * y; - const wz = az * z; - const uvw = ux + vy + wz; - const s = Math.sin(theta); - const c = Math.cos(theta); - return setS3(v, - (ax * uvw + (x * (ay * ay + az * az) - ax * (vy + wz)) * c + (-wy + vz) * s), - (ay * uvw + (y * (ax * ax + az * az) - ay * (ux + wz)) * c + (wx - uz) * s), - (az * uvw + (z * (ax * ax + ay * ay) - az * (ux + vy)) * c + (-vx + uy) * s), - ia, sa - ); -} - -export const headingXY3 = heading2; - -export const headingXZ3 = (a: ReadonlyVec, ia = 0, sa = 1) => - atan2Abs(a[ia + 2 * sa], a[ia]); - -export const headingYZ3 = (a: ReadonlyVec, ia = 0, sa = 1) => - atan2Abs(a[ia + 2 * sa], a[ia + sa]); - -export const angleRatio3 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - dot3(a, b, ia, ib, sa, sb) / (mag3(a, ia, sa) * mag3(b, ib, sb)); - -export const angleBetween3 = (a: ReadonlyVec, b: ReadonlyVec, normalize = false, ia = 0, ib = 0, sa = 1, sb = 1): number => - normalize ? - (a[ia] * b[ib + sb] < a[ia + sa] * b[ib] ? -1 : 1) * - Math.acos(angleRatio3(a, b, ia, ib, sa, sb)) : - Math.acos(dot3(a, b, ia, ib, sa, sb)); - -export const toPolar3 = (a: Vec, ia = 0, sa = 1) => { - const x = a[ia]; - const y = a[ia + sa]; - const z = a[ia + 2 * sa]; - const r = Math.sqrt(x * x + y * y + z * z); - return setS3(a, r, Math.asin(z / r), Math.atan2(y, x), ia, sa); -}; - -export const toCartesian3 = (a: Vec, b: ReadonlyVec = ZERO4, ia = 0, ib = 0, sa = 1, sb = 1) => { - const r = a[ia]; - const theta = a[ia + sa]; - const phi = a[ia + 2 * sa]; - const ct = Math.cos(theta); - return setS3(a, - r * ct * Math.cos(phi) + b[ib], - r * ct * Math.sin(phi) + b[ib + sb], - r * Math.sin(theta) + b[ib + 2 * sb], - ia, sa - ); -}; - -export const toCylindrical3 = toPolar2; - -export const fromCylindrical3 = (a: Vec, b: ReadonlyVec = ZERO4, ia = 0, ib = 0, sa = 1, sb = 1) => { - toCartesian2(a, b, ia, ib, sa, sb); - a[ia + 2 * sa] += b[ib + 2 * sb]; - return a; -}; - -export const minorAxis3 = (a: Vec, ia = 0, sa = 1) => - min3id(Math.abs(a[ia]), Math.abs(a[ia + sa]), Math.abs(a[ia + 2 * sa])); - -export const majorAxis3 = (a: Vec, ia = 0, sa = 1) => - max3id(Math.abs(a[ia]), Math.abs(a[ia + sa]), Math.abs(a[ia + 2 * sa])); - -export const vec3 = (x = 0, y = 0, z = 0) => - new Vec3([x, y, z]); + intoBuffer, + mapBuffer, + values, + vecIterator +} from "./internal/vec-utils"; +import { setS3 } from "./sets"; -export const asVec3 = (x: ReadonlyVec) => - x instanceof Vec3 ? x : new Vec3([x[0] || 0, x[1] || 0, x[2] || 0]); - -export class Vec3 implements - IVector, - IAngleBetween, - ICrossProduct, - IPolar { +export class Vec3 extends AVec implements + IVector { /** * Returns array of memory mapped `Vec3` instances using given @@ -382,18 +34,13 @@ export class Vec3 implements * interleaved etc. * * @param buf backing array - * @param n num vectors + * @param num num vectors * @param start start index * @param cstride component stride * @param estride element stride */ - static mapBuffer(buf: Vec, n = (buf.length / 3) | 0, start = 0, cstride = 1, estride = 3) { - const res: Vec3[] = []; - while (--n >= 0) { - res.push(new Vec3(buf, start, cstride)); - start += estride; - } - return res; + static mapBuffer(buf: Vec, num: number = (buf.length / 3) | 0, start = 0, cstride = 1, estride = 3) { + return mapBuffer(Vec3, buf, num, start, cstride, estride); } /** @@ -402,7 +49,7 @@ export class Vec3 implements * strides, starting at `start` index. It's the user's * responsibility to ensure the target buffer has sufficient * capacity to hold the input vectors. See `Vec3.mapBuffer` for the - * reverse operation. Returns buffer. + * inverse operation. Returns `buf`. * * @param buf * @param src @@ -410,72 +57,33 @@ export class Vec3 implements * @param cstride * @param estride */ - static intoBuffer(buf: Vec, src: Iterable>, start = 0, cstride = 1, estride = 3) { - for (let v of src) { - set3(buf, v.buf, start, v.i, cstride, v.s); - start += estride; - } - return buf; - } - - static swizzle(v: IVec, x: number, y: number, z: number) { - return new Vec3([]).swizzle(v, x, y, z); - } - - static mixBilinear(a: Readonly, b: Readonly, c: Readonly, d: Readonly, u: number, v: number) { - return new Vec3( - mixBilinear3( - get3(a.buf, a.i, a.s), b.buf, c.buf, d.buf, u, v, - 0, b.i, c.i, d.i, - 1, b.s, c.s, d.s - ) - ); - } - - static orthoNormal3(a: Readonly, b: Readonly, c: Readonly) { - return new Vec3(orthoNormal3(a.buf, b.buf, c.buf, a.i, b.i, c.i, a.s, b.s, c.s)); + static intoBuffer(buf: Vec, src: Iterable, start = 0, cstride = 1, estride = 3) { + return intoBuffer(setS3, buf, src, start, cstride, estride); } - static randNorm(n = 1) { - return new Vec3(randNorm3([], n)); + static iterator(buf: Vec, num: number, start = 0, cstride = 1, estride = 3) { + return vecIterator(Vec3, buf, num, start, cstride, estride); } - static random(min: number, max: number) { - return new Vec3(randMinMax3([], min, max)); - } + static readonly X_AXIS = new Vec3(X3); + static readonly Y_AXIS = new Vec3(Y3); + static readonly Z_AXIS = new Vec3(Z3); + static readonly MIN = new Vec3(MIN3); + static readonly MAX = new Vec3(MAX3); + static readonly ZERO = new Vec3(ZERO3); + static readonly ONE = new Vec3(ONE3); - static comparator(o1: Vec3Coord, o2: Vec3Coord, o3: Vec3Coord) { - return (a: Readonly, b: Readonly) => a.compare(b, o1, o2, o3); - } - - static readonly ZERO = Object.freeze(new Vec3(ZERO4)); - static readonly ONE = Object.freeze(new Vec3(ONE4)); - static readonly MIN = Object.freeze(new Vec3(MIN4)); - static readonly MAX = Object.freeze(new Vec3(MAX4)); - static readonly X_AXIS = Object.freeze(new Vec3(X4)); - static readonly Y_AXIS = Object.freeze(new Vec3(Y4)); - static readonly Z_AXIS = Object.freeze(new Vec3(Z4)); - - buf: Vec; - i: number; - s: number; x: number; y: number; z: number; [id: number]: number; - constructor(buf?: Vec, index = 0, stride = 1) { - this.buf = buf || [0, 0, 0]; - this.i = index; - this.s = stride; + constructor(buf?: Vec, offset = 0, stride = 1) { + super(buf || [0, 0, 0], offset, stride); } [Symbol.iterator]() { - return $iter(this.buf, 3, this.i, this.s); - } - - array() { - return get3(this.buf, this.i, this.s); + return values(this.buf, 3, this.offset, this.stride); } get length() { @@ -483,423 +91,40 @@ export class Vec3 implements } copy() { - return new Vec3(get3(this.buf, this.i, this.s)); - } - - empty() { - return new Vec3(); - } - - equiv(v: any) { - return v instanceof Vec3 ? - equiv3(this.buf, v.buf, this.i, v.i, this.s, v.s) : - isArrayLike(v) && v.length === 3 ? - equiv3(this.buf, v, this.i, 0, this.s, 1) : - false; - } - - eqDelta(v: Readonly, eps = EPS) { - return eqDelta3(this.buf, v.buf, eps, this.i, v.i, this.s, v.s); - } - - compare(v: Readonly, o1: Vec3Coord = 0, o2: Vec3Coord = 1, o3: Vec3Coord = 2) { - return compare3(this.buf, v.buf, o1, o2, o3, this.i, v.i, this.s, v.s); - } - - set(v: Readonly) { - set3(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - setN(n: number) { - setN3(this.buf, n, this.i, this.s); - return this; - } - - setS(x: number, y: number, z: number) { - setS3(this.buf, x, y, z, this.i, this.s); - return this; - } - - jitter(n = 1) { - jitter3(this.buf, n, this.i, this.s); - return this; - } - - swizzle(v: IVec, x: number, y: number, z: number) { - swizzle3(this.buf, v.buf, x, y, z, this.i, v.i, this.s, v.s); - return this; - } - - swap(v: Vec3) { - swap3(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - add(v: Readonly) { - add3(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - sub(v: Readonly) { - sub3(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - mul(v: Readonly) { - mul3(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - div(v: Readonly) { - div3(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - addN(n: number) { - addN3(this.buf, n, this.i, this.s); - return this; - } - - subN(n: number) { - subN3(this.buf, n, this.i, this.s); - return this; - } - - mulN(n: number) { - mulN3(this.buf, n, this.i, this.s); - return this; - } - - divN(n: number) { - divN3(this.buf, n, this.i, this.s); - return this; - } - - addNew(b: Readonly, out?: Vec3) { - !out && (out = new Vec3([])); - add3o(out.buf, this.buf, b.buf, out.i, this.i, b.i, out.s, this.s, b.s); - return out; - } - - subNew(b: Readonly, out?: Vec3) { - !out && (out = new Vec3([])); - sub3o(out.buf, this.buf, b.buf, out.i, this.i, b.i, out.s, this.s, b.s); - return out; - } - - mulNew(b: Readonly, out?: Vec3) { - !out && (out = new Vec3([])); - mul3o(out.buf, this.buf, b.buf, out.i, this.i, b.i, out.s, this.s, b.s); - return out; - } - - divNew(b: Readonly, out?: Vec3) { - !out && (out = new Vec3([])); - div3o(out.buf, this.buf, b.buf, out.i, this.i, b.i, out.s, this.s, b.s); - return out; + return new Vec3([this.x, this.y, this.z]); } - addNewN(n: number, out?: Vec3) { - !out && (out = new Vec3([])); - addN3o(out.buf, this.buf, n, out.i, this.i, out.s, this.s); - return out; + copyView() { + return new Vec3(this.buf, this.offset, this.stride); } - subNewN(n: number, out?: Vec3) { - !out && (out = new Vec3([])); - subN3o(out.buf, this.buf, n, out.i, this.i, out.s, this.s); - return out; - } - - mulNewN(n: number, out?: Vec3) { - !out && (out = new Vec3([])); - mulN3o(out.buf, this.buf, n, out.i, this.i, out.s, this.s); - return out; - } - - divNewN(n: number, out?: Vec3) { - !out && (out = new Vec3([])); - divN3o(out.buf, this.buf, n, out.i, this.i, out.s, this.s); - return out; - } - - maddNew(b: Readonly, c: Readonly, out?: Vec3) { - out = out ? out.set(this) : this.copy(); - madd3(out.buf, b.buf, c.buf, out.i, b.i, c.i, out.s, b.s, c.s); - return out; - } - - maddNewN(b: Readonly, n: number, out?: Vec3) { - out = out ? out.set(this) : this.copy(); - maddN3(out.buf, b.buf, n, out.i, b.i, out.s, b.s); - return out; - } - - msubNew(b: Readonly, c: Readonly, out?: Vec3) { - out = out ? out.set(this) : this.copy(); - msub3(out.buf, b.buf, c.buf, out.i, b.i, c.i, out.s, b.s, c.s); - return out; - } - - msubNewN(b: Readonly, n: number, out?: Vec3) { - out = out ? out.set(this) : this.copy(); - msubN3(out.buf, b.buf, n, out.i, b.i, out.s, b.s); - return out; - } - - mixNew(b: Readonly, t: Readonly, out?: Vec3) { - !out && (out = new Vec3([])); - mix3o(out.buf, this.buf, b.buf, t.buf, out.i, this.i, b.i, t.i, out.s, this.s, b.s, t.s); - return out; - } - - mixNewN(b: Readonly, n = 0.5, out?: Vec3) { - !out && (out = new Vec3([])); - mixN3o(out.buf, this.buf, b.buf, n, out.i, this.i, b.i, out.s, this.s, b.s); - return out; - } - - neg() { - mulN3(this.buf, -1, this.i, this.s); - return this; - } - - abs() { - abs3(this.buf, this.i, this.s); - return this; - } - - sign() { - sign3(this.buf, this.i, this.s); - return this; - } - - floor() { - floor3(this.buf, this.i, this.s); - return this; - } - - ceil() { - ceil3(this.buf, this.i, this.s); - return this; - } - - fract() { - fract3(this.buf, this.i, this.s); - return this; - } - - sqrt() { - sqrt3(this.buf, this.i, this.s); - return this; - } - - pow(v: Readonly) { - pow3(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - powN(n: number) { - powN3(this.buf, n, this.i, this.s); - return this; - } - - sin() { - sin3(this.buf, this.i, this.s); - return this; - } - - cos() { - cos3(this.buf, this.i, this.s); - return this; - } - - madd(b: Readonly, c: Readonly) { - madd3(this.buf, b.buf, c.buf, this.i, b.i, c.i, this.s, b.s, c.s); - return this; - } - - maddN(b: Readonly, n: number) { - maddN3(this.buf, b.buf, n, this.i, b.i, this.s, b.s); - return this; - } - - msub(b: Readonly, c: Readonly) { - msub3(this.buf, b.buf, c.buf, this.i, b.i, c.i, this.s, b.s, c.s); - return this; - } - - msubN(b: Readonly, n: number) { - msubN3(this.buf, b.buf, n, this.i, b.i, this.s, b.s); - return this; - } - - mix(b: Readonly, c: Readonly) { - mix3(this.buf, b.buf, c.buf, this.i, b.i, c.i, this.s, b.s, c.s); - return this; - } - - mixN(b: Readonly, n = 0.5) { - mixN3(this.buf, b.buf, n, this.i, b.i, this.s, b.s); - return this; - } - - min(v: Readonly) { - min3(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - max(v: Readonly) { - max3(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - clamp(min: Readonly, max: Readonly) { - clamp3(this.buf, min.buf, max.buf, this.i, min.i, max.i, this.s, min.s, max.s); - return this; - } - - minorAxis() { - return minorAxis3(this.buf, this.i, this.s); - } - - majorAxis() { - return majorAxis3(this.buf, this.i, this.s); - } - - step(e: Readonly) { - step3(this.buf, e.buf, this.i, e.i, this.s, e.s); - return this; - } - - smoothStep(e1: Readonly, e2: Readonly) { - smoothStep3(this.buf, e1.buf, e2.buf, this.i, e1.i, e2.i, this.s, e1.s, e2.s); - return this; - } - - dot(v: Readonly) { - return dot3(this.buf, v.buf, this.i, v.i, this.s, v.s); - } - - cross(v: Readonly) { - cross3(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - orthoNormal(v: Readonly) { - return this.cross(v).normalize(); - } - - mag() { - return mag3(this.buf, this.i, this.s); - } - - magSq() { - return magSq3(this.buf, this.i, this.s); - } - - dist(v: Readonly) { - return dist3(this.buf, v.buf, this.i, v.i, this.s, v.s); - } - - distSq(v: Readonly) { - return distSq3(this.buf, v.buf, this.i, v.i, this.s, v.s); - } - - distManhattan(v: Readonly) { - return distManhattan3(this.buf, v.buf, this.i, v.i, this.s, v.s); - } - - distChebyshev(v: Readonly) { - return distChebyshev3(this.buf, v.buf, this.i, v.i, this.s, v.s); - } - - normalize(len = 1) { - normalize3(this.buf, len, this.i, this.s); - return this; - } - - limit(len: number) { - limit3(this.buf, len, this.i, this.s); - return this; - } - - reflect(n: Readonly) { - reflect3(this.buf, n.buf, this.i, n.i, this.s, n.s); - return this; - } - - refract(n: Readonly, eta: number) { - refract3(this.buf, n.buf, eta, this.i, n.i, this.s, n.s); - return this; - } - - rotateX(theta: number) { - rotateX3(this.buf, theta, this.i, this.s); - return this; - } - - rotateY(theta: number) { - rotateY3(this.buf, theta, this.i, this.s); - return this; - } - - rotateZ(theta: number) { - rotateZ3(this.buf, theta, this.i, this.s); - return this; - } - - rotateAroundAxis(axis: Vec3, theta: number) { - rotateAroundAxis3(this.buf, axis.buf, theta, this.i, axis.i, this.s, axis.s); - return this; - } - - headingXY() { - return headingXY3(this.buf, this.i, this.s); - } - - headingXZ() { - return headingXZ3(this.buf, this.i, this.s); - } - - headingYZ() { - return headingYZ3(this.buf, this.i, this.s); - } - - angleBetween(v: Readonly, normalize = false) { - return angleBetween3(this.buf, v.buf, normalize, this.i, v.i, this.s, v.s); - } - - toPolar() { - toPolar3(this.buf, this.i, this.s); - return this; - } - - toCartesian(o: Readonly = Vec3.ZERO) { - toCartesian3(this.buf, o.buf, this.i, o.i, this.s, o.s); - return this; + empty() { + return new Vec3(); } - toCylindrical() { - toCylindrical3(this.buf, this.i, this.s); - return this; + eqDelta(v: ReadonlyVec, eps = EPS) { + return eqDelta3(this, v, eps); } - fromCylindrical(o: Readonly = Vec3.ZERO) { - fromCylindrical3(this.buf, o.buf, this.i, o.i, this.s, o.s); - return this; + toJSON() { + return [this.x, this.y, this.z]; } toString() { - const i = this.i; - const s = this.s; - return `[${this.buf[i]}, ${this.buf[i + s]}, ${this.buf[i + 2 * s]}]`; - } - - toJSON() { - return this.array(); + return `[${this.x}, ${this.y}, ${this.z}]`; } } declareIndices(Vec3.prototype, ["x", "y", "z"]); + +export const vec3 = + (x = 0, y = 0, z = 0) => new Vec3([x, y, z]); + +export const vec3n = + (n: number) => new Vec3([n, n, n]); + +export const asVec3 = + (x: Vec) => + x instanceof Vec3 ? + x : + new Vec3(x.length >= 3 ? x : [x[0] || 0, x[1] || 0, x[2] || 0]); diff --git a/packages/vectors/src/vec4.ts b/packages/vectors/src/vec4.ts index 90f83ae776..dc5e27059f 100644 --- a/packages/vectors/src/vec4.ts +++ b/packages/vectors/src/vec4.ts @@ -1,311 +1,46 @@ -import { isArrayLike } from "@thi.ng/checks"; +import { EPS } from "@thi.ng/math"; import { - EPS, - eqDelta, - fract, - max4id, - min4id, - mixBilinear, - smoothStep, - step -} from "@thi.ng/math"; -import { - IVec, IVector, MAX4, MIN4, ONE4, ReadonlyVec, Vec, - Vec4Coord, - W4, X4, Y4, Z4, ZERO4 } from "./api"; -import { declareIndices, defcommon } from "./codegen"; -import { $iter } from "./common"; - -export const op4 = (fn: (x: number) => number, a: Vec, ia = 0, sa = 1) => ( - a[ia] = fn(a[ia]), - a[ia + sa] = fn(a[ia + sa]), - a[ia + 2 * sa] = fn(a[ia + 2 * sa]), - a[ia + 3 * sa] = fn(a[ia + 3 * sa]), - a -); - -export const op40 = (fn: () => number, a: Vec, ia = 0, sa = 1) => ( - a[ia] = fn(), - a[ia + sa] = fn(), - a[ia + 2 * sa] = fn(), - a[ia + 3 * sa] = fn(), - a -); - -export const op41 = (fn: (a: number, n: number) => number, a: Vec, n: number, ia = 0, sa = 1) => ( - a[ia] = fn(a[ia], n), - a[ia + sa] = fn(a[ia + sa], n), - a[ia + 2 * sa] = fn(a[ia + 2 * sa], n), - a[ia + 3 * sa] = fn(a[ia + 3 * sa], n), - a -); - -export const get4 = (a: ReadonlyVec, ia = 0, sa = 1) => - set4(new ((a.constructor))(4), a, 0, ia, 1, sa); - -export const setS4 = (a: Vec, x: number, y: number, z: number, w: number, ia = 0, sa = 1) => ( - a[ia] = x, - a[ia + sa] = y, - a[ia + 2 * sa] = z, - a[ia + 3 * sa] = w, - a -); - -export const randNorm4 = (a: Vec, n = 1, ia = 0, sa = 1) => - randMinMax4(a, -n, n, ia, sa); - -export const randMinMax4 = (a: Vec, min: number, max: number, ia = 0, sa = 1) => { - const d = max - min; - return op40(() => min + d * Math.random(), a, ia, sa); -}; - -export const jitter4 = (a: Vec, n: number, ia = 0, sa = 1) => - op4((x) => x + Math.random() * 2 * n - n, a, ia, sa); - -export const swizzle4 = (a: Vec, b: ReadonlyVec, x: number, y: number, z: number, w: number, ia = 0, ib = 0, sa = 1, sb = 1) => - setS4(a, b[ib + x * sb], b[ib + y * sb], b[ib + z * sb], b[ib + w * sb], ia, sa); - -export const swap4 = (a: Vec, b: Vec, ia = 0, ib = 0, sa = 1, sb = 1) => { - let t = a[ia]; a[ia] = b[ib]; b[ib] = t; - ia += sa; ib += sb; - t = a[ia]; a[ia] = b[ib]; b[ib] = t; - ia += sa; ib += sb; - t = a[ia]; a[ia] = b[ib]; b[ib] = t; - ia += sa; ib += sb; - t = a[ia]; a[ia] = b[ib]; b[ib] = t; - return a; -}; - -export const equiv4 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - a[ia] === b[ib] && - a[ia + sa] === b[ib + sb] && - a[ia + 2 * sa] === b[ib + 2 * sb] && - a[ia + 3 * sa] === b[ib + 3 * sb]; - -export const eqDelta4 = (a: ReadonlyVec, b: ReadonlyVec, eps = EPS, ia = 0, ib = 0, sa = 1, sb = 1) => - eqDelta(a[ia], b[ib], eps) && - eqDelta(a[ia + sa], b[ib + sb], eps) && - eqDelta(a[ia + 2 * sa], b[ib + 2 * sb], eps) && - eqDelta(a[ia + 3 * sa], b[ib + 3 * sb], eps); - -export const eqDelta4buf = (a: ReadonlyVec, b: ReadonlyVec, num: number, eps = EPS, ia = 0, ib = 0, sca = 1, scb = 1, sea = 4, seb = 4) => { - while (--num >= 0) { - if (!eqDelta4(a, b, eps, ia + num * sea, ib + num * seb, sca, scb)) { - return false; - } - } - return true; -}; - -export const eqDelta4array = (a: ReadonlyVec[], b: ReadonlyVec[], eps = EPS) => { - const na = a.length; - if (b.length !== na) { - return false; - } - for (let i = 0; i < na; i++) { - if (!eqDelta4(a[i], b[i], eps)) { - return false; - } - } - return true; -}; - -export const compare4 = ( - a: ReadonlyVec, - b: ReadonlyVec, - o1: Vec4Coord, o2: Vec4Coord, o3: Vec4Coord, o4: Vec4Coord, - ia = 0, ib = 0, sa = 1, sb = 1): number => { - - const ax = a[ia + o1 * sa]; - const ay = a[ia + o2 * sa]; - const az = a[ia + o3 * sa]; - const aw = b[ia + o4 * sa]; - const bx = b[ib + o1 * sb]; - const by = b[ib + o2 * sb]; - const bz = b[ib + o3 * sb]; - const bw = b[ib + o4 * sb]; - return ax === bx ? - ay === by ? - az === bz ? - aw === bw ? - 0 : - aw < bw ? -4 : 4 : - az < bz ? -3 : 3 : - ay < by ? -2 : 2 : - ax < bx ? -1 : 1; -}; - -export const collate4 = (buf: Vec, src: Iterable, start = 0, cstride = 1, estride = 4) => { - for (let v of src) { - set4(buf, v, start, 0, cstride, 1); - start += estride; - } - return buf; -}; - -export const [ - set4, setN4, - add4, sub4, mul4, div4, - add4o, sub4o, mul4o, div4o, - addN4, subN4, mulN4, divN4, - addN4o, subN4o, mulN4o, divN4o, - madd4, maddN4, msub4, msubN4, - abs4, sign4, floor4, ceil4, sin4, cos4, sqrt4, - pow4, min4, max4, - mix4, mixN4, mix4o, mixN4o -] = defcommon(4); - -export const neg4 = (a: Vec, ia = 0, sa = 1) => - mulN4(a, -1, ia, sa); - -export const fract4 = (a: Vec, ia = 0, sa = 1) => - op4(fract, a, ia, sa); - -export const powN4 = (a: Vec, n: number, ia = 0, sa = 1) => - op41(Math.pow, a, n, ia, sa); - -export const dot4 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - a[ia] * b[ib] + - a[ia + sa] * b[ib + sb] + - a[ia + 2 * sa] * b[ib + 2 * sb] + - a[ia + 3 * sa] * b[ib + 3 * sb]; - -export const mixBilinear4 = ( - a: Vec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, u: number, v: number, - ia = 0, ib = 0, ic = 0, id = 0, - sa = 1, sb = 1, sc = 1, sd = 1) => ( - a[ia] = mixBilinear(a[ia], b[ib], c[ic], d[id], u, v), - a[ia + sa] = mixBilinear(a[ia + sa], b[ib + sb], c[ic + sc], d[id + sd], u, v), - a[ia + 2 * sa] = mixBilinear(a[ia + 2 * sa], b[ib + 2 * sb], c[ic + 2 * sc], d[id + 2 * sd], u, v), - a[ia + 3 * sa] = mixBilinear(a[ia + 3 * sa], b[ib + 3 * sb], c[ic + 3 * sc], d[id + 3 * sd], u, v), - a - ); - -export const clamp4 = (a: Vec, min: ReadonlyVec, max: ReadonlyVec, ia = 0, imin = 0, imax = 0, sa = 1, smin = 1, smax = 1) => - max4(min4(a, max, ia, imax, sa, smax), min, ia, imin, sa, smin); - -export const step4 = (a: Vec, e: ReadonlyVec, ia = 0, ie = 0, sa = 1, se = 1) => ( - a[ia] = step(e[ie], a[ia]), - a[ia + sa] = step(e[ie + se], a[ia + sa]), - a[ia + 2 * sa] = step(e[ie + 2 * se], a[ia + 2 * sa]), - a[ia + 3 * sa] = step(e[ie + 3 * se], a[ia + 3 * sa]), - a -); - -export const smoothStep4 = (a: Vec, e1: ReadonlyVec, e2: ReadonlyVec, ia = 0, ie1 = 0, ie2 = 0, sa = 1, se1 = 1, se2 = 1) => ( - a[ia] = smoothStep(e1[ie1], e2[ie2], a[ia]), - a[ia + sa] = smoothStep(e1[ie1 + se1], e2[ie2 + se2], a[ia + sa]), - a[ia + 2 * sa] = smoothStep(e1[ie1 + 2 * se1], e2[ie2 + 2 * se2], a[ia + 2 * sa]), - a[ia + 3 * sa] = smoothStep(e1[ie1 + 3 * se1], e2[ie2 + 2 * se2], a[ia + 3 * sa]), - a -); - -export const magSq4 = (a: ReadonlyVec, ia = 0, sa = 1) => { - const x = a[ia]; - const y = a[ia + sa]; - const z = a[ia + 2 * sa]; - const w = a[ia + 3 * sa]; - return x * x + y * y + z * z + w * w; -}; - -export const mag4 = (a: ReadonlyVec, ia = 0, sa = 1) => - Math.sqrt(magSq4(a, ia, sa)); - -export const distSq4 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => { - const x = a[ia] - b[ib]; - const y = a[ia + sa] - b[ib + sb]; - const z = a[ia + 2 * sa] - b[ib + 2 * sb]; - const w = a[ia + 3 * sa] - b[ib + 3 * sb]; - return x * x + y * y + z * z + w * w; -}; - -export const dist4 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - Math.sqrt(distSq4(a, b, ia, ib, sa, sb)); - -export const distManhattan4 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - Math.abs(a[ia] - b[ib]) + - Math.abs(a[ia + sa] - b[ib + sb]) + - Math.abs(a[ia + 2 * sa] - b[ib + 2 * sb]) + - Math.abs(a[ia + 3 * sa] - b[ib + 3 * sb]); - -export const distChebyshev4 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - Math.max( - Math.abs(a[ia] - b[ib]), - Math.abs(a[ia + sa] - b[ib + sb]), - Math.abs(a[ia + 2 * sa] - b[ib + 2 * sb]), - Math.abs(a[ia + 3 * sa] - b[ib + 3 * sb]) - ); - -export const normalize4 = (a: Vec, n = 1, ia = 0, sa = 1) => { - const m = mag4(a, ia, sa); - m >= EPS && mulN4(a, n / m, ia, sa); - return a; -}; - -export const limit4 = (a: Vec, n: number, ia = 0, sa = 1) => { - const m = mag4(a, ia, sa); - m >= n && mulN4(a, n / m, ia, sa); - return a; -}; - -export const reflect4 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - maddN4(a, b, -2 * dot4(a, b, ia, ib, sa, sb), ia, ib, sa, sb); - -export const refract4 = (a: Vec, b: ReadonlyVec, eta: number, ia = 0, ib = 0, sa = 1, sb = 1) => { - const d = dot4(a, b, ia, ib, sa, sb); - const k = 1 - eta * eta * (1 - d * d); - return k < 0 ? - setN4(a, 0, ia, sa) : - msubN4(mulN4(a, eta, ia, sa), b, eta * d + Math.sqrt(k), ia, ib, sa, sb); -}; - -export const minorAxis4 = (a: Vec, ia = 0, sa = 1) => - min4id(Math.abs(a[ia]), Math.abs(a[ia + sa]), Math.abs(a[ia + 2 * sa]), Math.abs(a[ia + 3 * sa])); - -export const majorAxis4 = (a: Vec, ia = 0, sa = 1) => - max4id(Math.abs(a[ia]), Math.abs(a[ia + sa]), Math.abs(a[ia + 2 * sa]), Math.abs(a[ia + 3 * sa])); - -export const vec4 = (x = 0, y = 0, z = 0, w = 0) => - new Vec4([x, y, z, w]); - -export const asVec4 = (x: ReadonlyVec) => - x instanceof Vec4 ? x : new Vec4([x[0] || 0, x[1] || 0, x[2] || 0, x[3] || 0]); - -export class Vec4 implements +import { eqDelta4 } from "./eqdelta"; +import { declareIndices } from "./internal/accessors"; +import { AVec } from "./internal/avec"; +import { + intoBuffer, + mapBuffer, + values, + vecIterator +} from "./internal/vec-utils"; +import { setS4 } from "./sets"; + +export class Vec4 extends AVec implements IVector { /** * Returns array of memory mapped `Vec4` instances using given * backing array and stride settings: The `cstride` is the step size - * between individual XYZW vector components. `estride` is the step + * between individual XYZ vector components. `estride` is the step * size between successive vectors. This arrangement allows for * different storage approaches, incl. SOA, AOS, striped / * interleaved etc. * * @param buf backing array - * @param n num vectors + * @param num num vectors * @param start start index * @param cstride component stride * @param estride element stride */ - static mapBuffer(buf: Vec, n = buf.length >> 2, start = 0, cstride = 1, estride = 4) { - const res: Vec4[] = []; - while (--n >= 0) { - res.push(new Vec4(buf, start, cstride)); - start += estride; - } - return res; + static mapBuffer(buf: Vec, num: number = buf.length >> 2, start = 0, cstride = 1, estride = 4) { + return mapBuffer(Vec4, buf, num, start, cstride, estride); } /** @@ -314,7 +49,7 @@ export class Vec4 implements * strides, starting at `start` index. It's the user's * responsibility to ensure the target buffer has sufficient * capacity to hold the input vectors. See `Vec4.mapBuffer` for the - * reverse operation. Returns buffer. + * inverse operation. Returns `buf`. * * @param buf * @param src @@ -322,69 +57,34 @@ export class Vec4 implements * @param cstride * @param estride */ - static intoBuffer(buf: Vec, src: Iterable>, start = 0, cstride = 1, estride = 4) { - for (let v of src) { - set4(buf, v.buf, start, v.i, cstride, v.s); - start += estride; - } - return buf; - } - - static swizzle(v: IVec, x: number, y: number, z: number, w: number) { - return new Vec4([]).swizzle(v, x, y, z, w); - } - - static mixBilinear(a: Readonly, b: Readonly, c: Readonly, d: Readonly, u: number, v: number) { - return new Vec4( - mixBilinear4( - get4(a.buf, a.i, a.s), b.buf, c.buf, d.buf, u, v, - 0, b.i, c.i, d.i, - 1, b.s, c.s, d.s - ) - ); + static intoBuffer(buf: Vec, src: Iterable, start = 0, cstride = 1, estride = 4) { + return intoBuffer(setS4, buf, src, start, cstride, estride); } - static randNorm(n = 1) { - return new Vec4(randNorm4([], n)); + static *iterator(buf: Vec, num: number, start = 0, cstride = 1, estride = 4) { + return vecIterator(Vec4, buf, num, start, cstride, estride); } - static random(min: number, max: number) { - return new Vec4(randMinMax4([], min, max)); - } - - static comparator(o1: Vec4Coord, o2: Vec4Coord, o3: Vec4Coord, o4: Vec4Coord) { - return (a: Readonly, b: Readonly) => a.compare(b, o1, o2, o3, o4); - } + static readonly X_AXIS = new Vec4(X4); + static readonly Y_AXIS = new Vec4(Y4); + static readonly Z_AXIS = new Vec4(Z4); + static readonly MIN = new Vec4(MIN4); + static readonly MAX = new Vec4(MAX4); + static readonly ZERO = new Vec4(ZERO4); + static readonly ONE = new Vec4(ONE4); - static readonly ZERO = Object.freeze(new Vec4(ZERO4)); - static readonly ONE = Object.freeze(new Vec4(ONE4)); - static readonly MIN = Object.freeze(new Vec4(MIN4)); - static readonly MAX = Object.freeze(new Vec4(MAX4)); - static readonly X_AXIS = Object.freeze(new Vec4(X4)); - static readonly Y_AXIS = Object.freeze(new Vec4(Y4)); - static readonly Z_AXIS = Object.freeze(new Vec4(Z4)); - static readonly W_AXIS = Object.freeze(new Vec4(W4)); - buf: Vec; - i: number; - s: number; x: number; y: number; z: number; w: number; [id: number]: number; - constructor(buf?: Vec, index = 0, stride = 1) { - this.buf = buf || [0, 0, 0, 0]; - this.i = index; - this.s = stride; + constructor(buf?: Vec, offset = 0, stride = 1) { + super(buf || [0, 0, 0, 0], offset, stride); } [Symbol.iterator]() { - return $iter(this.buf, 4, this.i, this.s); - } - - array() { - return get4(this.buf, this.i, this.s); + return values(this.buf, 4, this.offset, this.stride); } get length() { @@ -392,358 +92,44 @@ export class Vec4 implements } copy() { - return new Vec4(get4(this.buf, this.i, this.s)); - } - - empty() { - return new Vec4(); - } - - equiv(v: any) { - return v instanceof Vec4 ? - equiv4(this.buf, v.buf, this.i, v.i, this.s, v.s) : - isArrayLike(v) && v.length === 4 ? - equiv4(this.buf, v, this.i, 0, this.s, 1) : - false; - } - - eqDelta(v: Readonly, eps = EPS) { - return eqDelta4(this.buf, v.buf, eps, this.i, v.i, this.s, v.s); - } - - compare(v: Readonly, o1: Vec4Coord = 0, o2: Vec4Coord = 1, o3: Vec4Coord = 2, o4: Vec4Coord = 3) { - return compare4(this.buf, v.buf, o1, o2, o3, o4, this.i, v.i, this.s, v.s); - } - - set(v: Readonly) { - set4(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - setN(n: number) { - setN4(this.buf, n, this.i, this.s); - return this; - } - - setS(x: number, y: number, z: number, w: number) { - setS4(this.buf, x, y, z, w, this.i, this.s); - return this; - } - - jitter(n = 1) { - jitter4(this.buf, n, this.i, this.s); - return this; - } - - swizzle(v: IVec, x: number, y: number, z: number, w: number) { - swizzle4(this.buf, v.buf, x, y, z, w, this.i, v.i, this.s, v.s); - return this; - } - - swap(v: Vec4) { - swap4(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - add(v: Readonly) { - add4(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - sub(v: Readonly) { - sub4(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - mul(v: Readonly) { - mul4(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - div(v: Readonly) { - div4(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - addN(n: number) { - addN4(this.buf, n, this.i, this.s); - return this; - } - - subN(n: number) { - subN4(this.buf, n, this.i, this.s); - return this; - } - - mulN(n: number) { - mulN4(this.buf, n, this.i, this.s); - return this; - } - - divN(n: number) { - divN4(this.buf, n, this.i, this.s); - return this; - } - - addNew(b: Readonly, out?: Vec4) { - !out && (out = new Vec4([])); - add4o(out.buf, this.buf, b.buf, out.i, this.i, b.i, out.s, this.s, b.s); - return out; + return new Vec4([this.x, this.y, this.z, this.w]); } - subNew(b: Readonly, out?: Vec4) { - !out && (out = new Vec4([])); - sub4o(out.buf, this.buf, b.buf, out.i, this.i, b.i, out.s, this.s, b.s); - return out; + copyView() { + return new Vec4(this.buf, this.offset, this.stride); } - mulNew(b: Readonly, out?: Vec4) { - !out && (out = new Vec4([])); - mul4o(out.buf, this.buf, b.buf, out.i, this.i, b.i, out.s, this.s, b.s); - return out; - } - - divNew(b: Readonly, out?: Vec4) { - !out && (out = new Vec4([])); - div4o(out.buf, this.buf, b.buf, out.i, this.i, b.i, out.s, this.s, b.s); - return out; - } - - addNewN(n: number, out?: Vec4) { - !out && (out = new Vec4([])); - addN4o(out.buf, this.buf, n, out.i, this.i, out.s, this.s); - return out; - } - - subNewN(n: number, out?: Vec4) { - !out && (out = new Vec4([])); - subN4o(out.buf, this.buf, n, out.i, this.i, out.s, this.s); - return out; - } - - mulNewN(n: number, out?: Vec4) { - !out && (out = new Vec4([])); - mulN4o(out.buf, this.buf, n, out.i, this.i, out.s, this.s); - return out; - } - - divNewN(n: number, out?: Vec4) { - !out && (out = new Vec4([])); - divN4o(out.buf, this.buf, n, out.i, this.i, out.s, this.s); - return out; - } - - maddNew(b: Readonly, c: Readonly, out?: Vec4) { - out = out ? out.set(this) : this.copy(); - madd4(out.buf, b.buf, c.buf, out.i, b.i, c.i, out.s, b.s, c.s); - return out; - } - - maddNewN(b: Readonly, n: number, out?: Vec4) { - out = out ? out.set(this) : this.copy(); - maddN4(out.buf, b.buf, n, out.i, b.i, out.s, b.s); - return out; - } - - msubNew(b: Readonly, c: Readonly, out?: Vec4) { - out = out ? out.set(this) : this.copy(); - msub4(out.buf, b.buf, c.buf, out.i, b.i, c.i, out.s, b.s, c.s); - return out; - } - - msubNewN(b: Readonly, n: number, out?: Vec4) { - out = out ? out.set(this) : this.copy(); - msubN4(out.buf, b.buf, n, out.i, b.i, out.s, b.s); - return out; - } - - mixNew(b: Readonly, t: Readonly, out?: Vec4) { - !out && (out = new Vec4([])); - mix4o(out.buf, this.buf, b.buf, t.buf, out.i, this.i, b.i, t.i, out.s, this.s, b.s, t.s); - return out; - } - - mixNewN(b: Readonly, n = 0.5, out?: Vec4) { - !out && (out = new Vec4([])); - mixN4o(out.buf, this.buf, b.buf, n, out.i, this.i, b.i, out.s, this.s, b.s); - return out; - } - - neg() { - mulN4(this.buf, -1, this.i, this.s); - return this; - } - - abs() { - abs4(this.buf, this.i, this.s); - return this; - } - - sign() { - sign4(this.buf, this.i, this.s); - return this; - } - - floor() { - floor4(this.buf, this.i, this.s); - return this; - } - - ceil() { - ceil4(this.buf, this.i, this.s); - return this; - } - - fract() { - fract4(this.buf, this.i, this.s); - return this; - } - - sqrt() { - sqrt4(this.buf, this.i, this.s); - return this; - } - - pow(v: Readonly) { - pow4(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - powN(n: number) { - powN4(this.buf, n, this.i, this.s); - return this; - } - - sin() { - sin4(this.buf, this.i, this.s); - return this; - } - - cos() { - cos4(this.buf, this.i, this.s); - return this; - } - - madd(b: Readonly, c: Readonly) { - madd4(this.buf, b.buf, c.buf, this.i, b.i, c.i, this.s, b.s, c.s); - return this; - } - - maddN(b: Readonly, n: number) { - maddN4(this.buf, b.buf, n, this.i, b.i, this.s, b.s); - return this; - } - - msub(b: Readonly, c: Readonly) { - msub4(this.buf, b.buf, c.buf, this.i, b.i, c.i, this.s, b.s, c.s); - return this; - } - - msubN(b: Readonly, n: number) { - msubN4(this.buf, b.buf, n, this.i, b.i, this.s, b.s); - return this; - } - - mix(b: Readonly, c: Readonly) { - mix4(this.buf, b.buf, c.buf, this.i, b.i, c.i, this.s, b.s, c.s); - return this; - } - - mixN(b: Readonly, n = 0.5) { - mixN4(this.buf, b.buf, n, this.i, b.i, this.s, b.s); - return this; - } - - min(v: Readonly) { - min4(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - max(v: Readonly) { - max4(this.buf, v.buf, this.i, v.i, this.s, v.s); - return this; - } - - clamp(min: Readonly, max: Readonly) { - clamp4(this.buf, min.buf, max.buf, this.i, min.i, max.i, this.s, min.s, max.s); - return this; - } - - minorAxis() { - return minorAxis4(this.buf, this.i, this.s); - } - - majorAxis() { - return majorAxis4(this.buf, this.i, this.s); - } - - step(e: Readonly) { - step4(this.buf, e.buf, this.i, e.i, this.s, e.s); - return this; - } - - smoothStep(e1: Readonly, e2: Readonly) { - smoothStep4(this.buf, e1.buf, e2.buf, this.i, e1.i, e2.i, this.s, e1.s, e2.s); - return this; - } - - dot(v: Readonly) { - return dot4(this.buf, v.buf, this.i, v.i, this.s, v.s); - } - - mag() { - return mag4(this.buf, this.i, this.s); - } - - magSq() { - return magSq4(this.buf, this.i, this.s); - } - - dist(v: Readonly) { - return dist4(this.buf, v.buf, this.i, v.i, this.s, v.s); - } - - distSq(v: Readonly) { - return distSq4(this.buf, v.buf, this.i, v.i, this.s, v.s); - } - - distManhattan(v: Readonly) { - return distManhattan4(this.buf, v.buf, this.i, v.i, this.s, v.s); - } - - distChebyshev(v: Readonly) { - return distChebyshev4(this.buf, v.buf, this.i, v.i, this.s, v.s); - } - - normalize(len = 1) { - normalize4(this.buf, len, this.i, this.s); - return this; - } - - limit(len: number) { - limit4(this.buf, len, this.i, this.s); - return this; + empty() { + return new Vec4(); } - reflect(n: Readonly) { - reflect4(this.buf, n.buf, this.i, n.i, this.s, n.s); - return this; + eqDelta(v: ReadonlyVec, eps = EPS) { + return eqDelta4(this, v, eps); } - refract(n: Readonly, eta: number) { - refract4(this.buf, n.buf, eta, this.i, n.i, this.s, n.s); - return this; + toJSON() { + return [this.x, this.y, this.z, this.w]; } toString() { - const i = this.i; - const s = this.s; - return `[${this.buf[i]}, ${this.buf[i + s]}, ${this.buf[i + 2 * s]}, ${this.buf[i + 3 * s]}]`; - } - - toJSON() { - return this.array(); + return `[${this.x}, ${this.y}, ${this.z}, ${this.w}]`; } } declareIndices(Vec4.prototype, ["x", "y", "z", "w"]); + +export const vec4 = + (x = 0, y = 0, z = 0, w = 0) => new Vec4([x, y, z, w]); + +export const vec4n = + (n: number) => new Vec4([n, n, n, n]); + +export const asVec4 = + (x: Vec) => + x instanceof Vec4 ? + x : + new Vec4( + x.length >= 4 ? + x : + [x[0] || 0, x[1] || 0, x[2] || 0, x[3] || 0] + ); diff --git a/packages/vectors3/src/wrap.ts b/packages/vectors/src/wrap.ts similarity index 100% rename from packages/vectors3/src/wrap.ts rename to packages/vectors/src/wrap.ts diff --git a/packages/vectors/test/gvec.ts b/packages/vectors/test/gvec.ts deleted file mode 100644 index 79120ab66c..0000000000 --- a/packages/vectors/test/gvec.ts +++ /dev/null @@ -1,82 +0,0 @@ -import * as assert from "assert"; -import * as v from "../src/index"; - -describe("gvec", () => { - - const op2 = (fn, x, y, z, w) => { - assert.deepEqual( - fn([1, 2, 3, 4], [10, 20, 30, 40], 4), - [x, y, z, w] - ); - assert.deepEqual( - fn([0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0], [0, 10, 0, 20, 0, 30, 0, 40, 0], 4, 1, 1, 4, 2), - [0, x, 0, 0, 0, y, 0, 0, 0, z, 0, 0, 0, w, 0, 0] - ); - }; - - const opn = (fn, x, y, z, w) => { - assert.deepEqual( - fn([1, 2, 3, 4], 10, 4), - [x, y, z, w] - ); - assert.deepEqual( - fn([0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0], 10, 4, 1, 4), - [0, x, 0, 0, 0, y, 0, 0, 0, z, 0, 0, 0, w, 0, 0] - ); - }; - - it("add", () => op2(v.add, 11, 22, 33, 44)); - it("sub", () => op2(v.sub, -9, -18, -27, -36)); - it("mul", () => op2(v.mul, 10, 40, 90, 160)); - it("div", () => op2(v.div, 0.1, 0.1, 0.1, 0.1)); - - it("addn", () => opn(v.addN, 11, 12, 13, 14)); - it("subn", () => opn(v.subN, -9, -8, -7, -6)); - it("muln", () => opn(v.mulN, 10, 20, 30, 40)); - it("divn", () => opn(v.divN, 0.1, 0.2, 0.3, 0.4)); - - it("madd", () => { - assert.deepEqual( - v.madd([1, 2, 3, 4], [10, 20, 30, 40], [0.5, 0.25, 0.75, 0.125], 4), - [1 + 10 * 0.5, 2 + 20 * 0.25, 3 + 30 * 0.75, 4 + 40 * 0.125] - ); - assert.deepEqual( - v.madd([1, 2, 3, 4], [10, 0, 20, 0, 30, 0, 40], [0.5, 0, 0, 0.25, 0, 0, 0.75, 0, 0, 0.125], 4, 0, 0, 0, 1, 2, 3), - [1 + 10 * 0.5, 2 + 20 * 0.25, 3 + 30 * 0.75, 4 + 40 * 0.125] - ); - }); - - it("maddn", () => { - assert.deepEqual( - v.maddN([1, 2, 3, 4], [10, 20, 30, 40], 0.5, 4), - [1 + 10 * 0.5, 2 + 20 * 0.5, 3 + 30 * 0.5, 4 + 40 * 0.5] - ); - assert.deepEqual( - v.maddN([1, 2, 3, 4], [10, 0, 20, 0, 30, 0, 40], 0.5, 4, 0, 0, 1, 2), - [1 + 10 * 0.5, 2 + 20 * 0.5, 3 + 30 * 0.5, 4 + 40 * 0.5] - ); - }); - - it("equiv", () => { - const buf = [1, 2, 3, 4, 1, 0, 2, 0, 3, 0, 4]; - assert(v.equiv(buf, buf, 4, 0, 4, 1, 2)); - assert(!v.equiv(buf, buf, 4, 0, 4)); - assert(new v.GVec(buf, 4).equiv(buf.slice(0, 4))); - assert(new v.GVec(buf, 4).equiv(new v.GVec(buf, 4, 4, 2))); - assert(!new v.GVec(buf, 4).equiv(new v.GVec(buf, 4, 4, 1))); - }); - - it("eqdelta", () => { - assert(v.eqDelta([0, 1.001, 0, 1.999, 0, 3.0099, 0, 3.991], [1, 2, 3, 4], 4, 0.01, 1, 0, 2, 1)); - assert(!v.eqDelta([0, 1.001, 0, 1.999, 0, 3.04, 0, 4], [1, 2, 3, 4], 4, 0.01, 1, 0, 2, 1)); - }); - - it("iterator", () => { - assert.deepEqual([...v.gvec(1, 2, 3)], [1, 2, 3]); - assert.deepEqual([...new v.GVec([0, 1, 0, 2, 0, 3], 3, 1, 2)], [1, 2, 3]); - }); - - it("length", () => { - assert.deepEqual(v.gvec(1, 2, 3).length, 3); - }); -}); diff --git a/packages/vectors3/test/index.ts b/packages/vectors/test/index.ts similarity index 100% rename from packages/vectors3/test/index.ts rename to packages/vectors/test/index.ts diff --git a/packages/vectors/test/swizzle.ts b/packages/vectors/test/swizzle.ts deleted file mode 100644 index dbf85f9df9..0000000000 --- a/packages/vectors/test/swizzle.ts +++ /dev/null @@ -1,88 +0,0 @@ -import * as assert from "assert"; -import { Vec2, swizzle2 } from "../src/vec2"; -import { Vec3, swizzle3 } from "../src/vec3"; -import { Vec4, swizzle4 } from "../src/vec4"; - -describe("swizzle", () => { - - it("vec2", () => { - assert.deepEqual( - swizzle2([], [10, 20], 1, 0), - [20, 10] - ); - assert.deepEqual( - swizzle2([], [10, 20], 1, 1), - [20, 20] - ); - assert.deepEqual( - swizzle2([0, 0, 0, 0], [10, 20], 1, 0, 1, 0, 2, 1), - [0, 20, 0, 10] - ); - assert.deepEqual( - swizzle2([], [0, 10, 0, 0, 0, 20], 1, 0, 0, 1, 1, 4), - [20, 10] - ); - assert.deepEqual( - new Vec2([]).swizzle(new Vec2([10, 0, 20, 0], 0, 2), 1, 0).buf, - [20, 10] - ); - assert.deepEqual( - new Vec2([0, 0, 0, 0, 0], 1, 2).swizzle(new Vec2([10, 0, 0, 0, 20, 0, 0, 0], 0, 4), 1, 0).buf, - [0, 20, 0, 10, 0] - ); - }); - - it("vec3", () => { - assert.deepEqual( - swizzle3([], [10, 20, 30], 2, 1, 0), - [30, 20, 10] - ); - assert.deepEqual( - swizzle3([], [10, 20, 30], 1, 1, 1), - [20, 20, 20] - ); - assert.deepEqual( - swizzle3([0, 0, 0, 0, 0, 0], [10, 20, 30], 2, 1, 0, 1, 0, 2, 1), - [0, 30, 0, 20, 0, 10] - ); - assert.deepEqual( - swizzle3([], [0, 10, 0, 0, 0, 20, 0, 0, 0, 30], 2, 1, 0, 0, 1, 1, 4), - [30, 20, 10] - ); - assert.deepEqual( - new Vec3([]).swizzle(new Vec3([10, 0, 20, 0, 30, 0], 0, 2), 2, 1, 0).buf, - [30, 20, 10] - ); - assert.deepEqual( - new Vec3([0, 0, 0, 0, 0, 0, 0], 1, 2).swizzle(new Vec2([10, 0, 0, 0, 20, 0, 0, 0], 0, 4), 1, 1, 0).buf, - [0, 20, 0, 20, 0, 10, 0] - ); - }); - - it("vec4", () => { - assert.deepEqual( - swizzle4([], [10, 20, 30, 40], 3, 2, 1, 0), - [40, 30, 20, 10] - ); - assert.deepEqual( - swizzle4([], [10, 20, 30, 40], 1, 1, 1, 1), - [20, 20, 20, 20] - ); - assert.deepEqual( - swizzle4([0, 0, 0, 0, 0, 0, 0, 0], [10, 20, 30, 40], 3, 2, 1, 0, 1, 0, 2, 1), - [0, 40, 0, 30, 0, 20, 0, 10] - ); - assert.deepEqual( - swizzle4([], [0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 40], 3, 2, 1, 0, 0, 1, 1, 4), - [40, 30, 20, 10] - ); - assert.deepEqual( - new Vec4([]).swizzle(new Vec4([10, 0, 20, 0, 30, 0, 40, 0], 0, 2), 3, 2, 1, 0).buf, - [40, 30, 20, 10] - ); - assert.deepEqual( - new Vec4([0, 0, 0, 0, 0, 0, 0, 0, 0], 1, 2).swizzle(new Vec2([10, 0, 0, 0, 20, 0, 0, 0], 0, 4), 1, 1, 0, 0).buf, - [0, 20, 0, 20, 0, 10, 0, 10, 0] - ); - }); -}); diff --git a/packages/vectors/test/vec2.ts b/packages/vectors/test/vec2.ts deleted file mode 100644 index 31e4df35b7..0000000000 --- a/packages/vectors/test/vec2.ts +++ /dev/null @@ -1,103 +0,0 @@ -import * as assert from "assert"; -import * as v from "../src/index"; - -describe("vec2", () => { - - const op2 = (fn, x, y) => { - assert.deepEqual( - fn([1, 2], [10, 20]), - [x, y] - ); - assert.deepEqual( - fn([0, 1, 0, 0, 0, 2, 0, 0], [0, 10, 0, 20, 0], 1, 1, 4, 2), - [0, x, 0, 0, 0, y, 0, 0] - ); - }; - - const opn = (fn, x, y) => { - assert.deepEqual( - fn([1, 2], 10), - [x, y] - ); - assert.deepEqual( - fn([0, 1, 0, 0, 0, 2, 0, 0], 10, 1, 4), - [0, x, 0, 0, 0, y, 0, 0] - ); - }; - - it("add", () => op2(v.add2, 11, 22)); - it("sub", () => op2(v.sub2, -9, -18)); - it("mul", () => op2(v.mul2, 10, 40)); - it("div", () => op2(v.div2, 0.1, 0.1)); - - it("addn", () => opn(v.addN2, 11, 12)); - it("subn", () => opn(v.subN2, -9, -8)); - it("muln", () => opn(v.mulN2, 10, 20)); - it("divn", () => opn(v.divN2, 0.1, 0.2)); - - it("madd", () => { - assert.deepEqual( - v.madd2([1, 2], [10, 20], [0.5, 0.25]), - [1 + 10 * 0.5, 2 + 20 * 0.25] - ); - assert.deepEqual( - v.madd2([1, 2], [10, 0, 20, 0], [0.5, 0, 0, 0.25], 0, 0, 0, 1, 2, 3), - [1 + 10 * 0.5, 2 + 20 * 0.25] - ); - }); - - it("maddn", () => { - assert.deepEqual( - v.maddN2([1, 2], [10, 20], 0.5), - [1 + 10 * 0.5, 2 + 20 * 0.5] - ); - assert.deepEqual( - v.maddN2([1, 2], [10, 0, 20, 0], 0.5, 0, 0, 1, 2), - [1 + 10 * 0.5, 2 + 20 * 0.5] - ); - }); - - it("equiv", () => { - const buf = [1, 2, 1, 0, 2, 0] - assert(v.equiv2(buf, buf, 0, 2, 1, 2)); - assert(!v.equiv2(buf, buf, 0, 2)); - assert(new v.Vec2(buf).equiv(buf.slice(0, 2))); - assert(new v.Vec2(buf).equiv(new v.Vec2(buf, 2, 2))); - assert(!new v.Vec2(buf).equiv(new v.Vec2(buf, 2, 1))); - }); - - it("eqdelta", () => { - assert(v.eqDelta2([0, 1.001, 0, 1.999, 0], [1, 2], 0.01, 1, 0, 2, 1)); - assert(!v.eqDelta2([0, 1.001, 0, 1.979, 0], [1, 2], 0.01, 1, 0, 2, 1)); - }); - - it("iterator", () => { - assert.deepEqual([...new v.Vec2([1, 2])], [1, 2]); - assert.deepEqual([...new v.Vec2([0, 1, 0, 2], 1, 2)], [1, 2]); - }); - - it("arraylike", () => { - const buf = [0, 1, 0, 2]; - const a = new v.Vec2(buf, 1, 2); - assert.equal(a.length, 2); - assert.equal(a[0], 1); - assert.equal(a[1], 2); - a[0] = 10; - a[1] = 20; - assert.equal(a[0], 10); - assert.equal(a[1], 20); - assert.deepEqual(a.buf, [0, 10, 0, 20]); - }); - - it("prop access", () => { - const buf = [0, 1, 0, 2]; - const a = new v.Vec2(buf, 1, 2); - assert.equal(a.x, 1); - assert.equal(a.y, 2); - a.x = 10; - a.y = 20; - assert.equal(a.x, 10); - assert.equal(a.y, 20); - assert.deepEqual(a.buf, [0, 10, 0, 20]); - }); -}); diff --git a/packages/vectors/test/vec3.ts b/packages/vectors/test/vec3.ts deleted file mode 100644 index 5929f74745..0000000000 --- a/packages/vectors/test/vec3.ts +++ /dev/null @@ -1,111 +0,0 @@ -import * as assert from "assert"; -import * as v from "../src/index"; - -describe("vec3", () => { - - const op2 = (fn, x, y, z) => { - assert.deepEqual( - fn([1, 2, 3], [10, 20, 30]), - [x, y, z] - ); - assert.deepEqual( - fn([0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0], [0, 10, 0, 20, 0, 30, 0], 1, 1, 4, 2), - [0, x, 0, 0, 0, y, 0, 0, 0, z, 0, 0] - ); - }; - - const opn = (fn, x, y, z) => { - assert.deepEqual( - fn([1, 2, 3], 10), - [x, y, z] - ); - assert.deepEqual( - fn([0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0], 10, 1, 4), - [0, x, 0, 0, 0, y, 0, 0, 0, z, 0, 0] - ); - }; - - it("add", () => op2(v.add3, 11, 22, 33)); - it("sub", () => op2(v.sub3, -9, -18, -27)); - it("mul", () => op2(v.mul3, 10, 40, 90)); - it("div", () => op2(v.div3, 0.1, 0.1, 0.1)); - - it("addn", () => opn(v.addN3, 11, 12, 13)); - it("subn", () => opn(v.subN3, -9, -8, -7)); - it("muln", () => opn(v.mulN3, 10, 20, 30)); - it("divn", () => opn(v.divN3, 0.1, 0.2, 0.3)); - - it("madd", () => { - assert.deepEqual( - v.madd3([1, 2, 3], [10, 20, 30], [0.5, 0.25, 0.75]), - [1 + 10 * 0.5, 2 + 20 * 0.25, 3 + 30 * 0.75] - ); - assert.deepEqual( - v.madd3([1, 2, 3], [10, 0, 20, 0, 30], [0.5, 0, 0, 0.25, 0, 0, 0.75], 0, 0, 0, 1, 2, 3), - [1 + 10 * 0.5, 2 + 20 * 0.25, 3 + 30 * 0.75] - ); - }); - - it("maddn", () => { - assert.deepEqual( - v.maddN3([1, 2, 3], [10, 20, 30], 0.5), - [1 + 10 * 0.5, 2 + 20 * 0.5, 3 + 30 * 0.5] - ); - assert.deepEqual( - v.maddN3([1, 2, 3], [10, 0, 20, 0, 30], 0.5, 0, 0, 1, 2), - [1 + 10 * 0.5, 2 + 20 * 0.5, 3 + 30 * 0.5] - ); - }); - - it("equiv", () => { - const buf = [1, 2, 3, 0, 1, 0, 2, 0, 3] - assert(v.equiv3(buf, buf, 0, 4, 1, 2)); - assert(!v.equiv3(buf, buf, 0, 4)); - assert(new v.Vec3(buf).equiv(buf.slice(0, 3))); - assert(new v.Vec3(buf).equiv(new v.Vec3(buf, 4, 2))); - assert(!new v.Vec3(buf).equiv(new v.Vec3(buf, 4, 1))); - }); - - it("eqdelta", () => { - assert(v.eqDelta3([0, 1.001, 0, 1.999, 0, 3.0099], [1, 2, 3], 0.01, 1, 0, 2, 1)); - assert(!v.eqDelta3([0, 1.001, 0, 1.999, 0, 3.04], [1, 2, 3], 0.01, 1, 0, 2, 1)); - assert(new v.Vec3([0, 1.001, 0, 1.999, 0, 3.0099], 1, 2).eqDelta(v.vec3(1, 2, 3), 0.01)); - assert(!new v.Vec3([0, 1.001, 0, 1.999, 0, 3.04], 1, 2).eqDelta(v.vec3(1, 2, 3), 0.01)); - }); - - it("iterator", () => { - assert.deepEqual([...new v.Vec3([1, 2, 3])], [1, 2, 3]); - assert.deepEqual([...new v.Vec3([0, 1, 0, 2, 0, 3], 1, 2)], [1, 2, 3]); - }); - - it("arraylike", () => { - const buf = [0, 1, 0, 2, 0, 3]; - const a = new v.Vec3(buf, 1, 2); - assert.equal(a.length, 3); - assert.equal(a[0], 1); - assert.equal(a[1], 2); - assert.equal(a[2], 3); - a[0] = 10; - a[1] = 20; - a[2] = 30; - assert.equal(a[0], 10); - assert.equal(a[1], 20); - assert.equal(a[2], 30); - assert.deepEqual(a.buf, [0, 10, 0, 20, 0, 30]); - }); - - it("prop access", () => { - const buf = [0, 1, 0, 2, 0, 3]; - const a = new v.Vec3(buf, 1, 2); - assert.equal(a.x, 1); - assert.equal(a.y, 2); - assert.equal(a.z, 3); - a.x = 10; - a.y = 20; - a.z = 30; - assert.equal(a.x, 10); - assert.equal(a.y, 20); - assert.equal(a.z, 30); - assert.deepEqual(a.buf, [0, 10, 0, 20, 0, 30]); - }); -}); diff --git a/packages/vectors/test/vec4.ts b/packages/vectors/test/vec4.ts deleted file mode 100644 index 8843955fcf..0000000000 --- a/packages/vectors/test/vec4.ts +++ /dev/null @@ -1,115 +0,0 @@ -import * as assert from "assert"; -import * as v from "../src/index"; - -describe("vec4", () => { - - const op2 = (fn, x, y, z, w) => { - assert.deepEqual( - fn([1, 2, 3, 4], [10, 20, 30, 40]), - [x, y, z, w] - ); - assert.deepEqual( - fn([0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0], [0, 10, 0, 20, 0, 30, 0, 40, 0], 1, 1, 4, 2), - [0, x, 0, 0, 0, y, 0, 0, 0, z, 0, 0, 0, w, 0, 0] - ); - }; - - const opn = (fn, x, y, z, w) => { - assert.deepEqual( - fn([1, 2, 3, 4], 10), - [x, y, z, w] - ); - assert.deepEqual( - fn([0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0], 10, 1, 4), - [0, x, 0, 0, 0, y, 0, 0, 0, z, 0, 0, 0, w, 0, 0] - ); - }; - - it("add", () => op2(v.add4, 11, 22, 33, 44)); - it("sub", () => op2(v.sub4, -9, -18, -27, -36)); - it("mul", () => op2(v.mul4, 10, 40, 90, 160)); - it("div", () => op2(v.div4, 0.1, 0.1, 0.1, 0.1)); - - it("addn", () => opn(v.addN4, 11, 12, 13, 14)); - it("subn", () => opn(v.subN4, -9, -8, -7, -6)); - it("muln", () => opn(v.mulN4, 10, 20, 30, 40)); - it("divn", () => opn(v.divN4, 0.1, 0.2, 0.3, 0.4)); - - it("madd", () => { - assert.deepEqual( - v.madd4([1, 2, 3, 4], [10, 20, 30, 40], [0.5, 0.25, 0.75, 0.125]), - [1 + 10 * 0.5, 2 + 20 * 0.25, 3 + 30 * 0.75, 4 + 40 * 0.125] - ); - assert.deepEqual( - v.madd4([1, 2, 3, 4], [10, 0, 20, 0, 30, 0, 40], [0.5, 0, 0, 0.25, 0, 0, 0.75, 0, 0, 0.125], 0, 0, 0, 1, 2, 3), - [1 + 10 * 0.5, 2 + 20 * 0.25, 3 + 30 * 0.75, 4 + 40 * 0.125] - ); - }); - - it("maddn", () => { - assert.deepEqual( - v.maddN4([1, 2, 3, 4], [10, 20, 30, 40], 0.5), - [1 + 10 * 0.5, 2 + 20 * 0.5, 3 + 30 * 0.5, 4 + 40 * 0.5] - ); - assert.deepEqual( - v.maddN4([1, 2, 3, 4], [10, 0, 20, 0, 30, 0, 40], 0.5, 0, 0, 1, 2), - [1 + 10 * 0.5, 2 + 20 * 0.5, 3 + 30 * 0.5, 4 + 40 * 0.5] - ); - }); - - it("equiv", () => { - const buf = [1, 2, 3, 4, 1, 0, 2, 0, 3, 0, 4] - assert(v.equiv4(buf, buf, 0, 4, 1, 2)); - assert(!v.equiv4(buf, buf, 0, 4)); - assert(new v.Vec4(buf).equiv(buf.slice(0, 4))); - assert(new v.Vec4(buf).equiv(new v.Vec4(buf, 4, 2))); - assert(!new v.Vec4(buf).equiv(new v.Vec4(buf, 4, 1))); - }); - - it("eqdelta", () => { - assert(v.eqDelta4([0, 1.001, 0, 1.999, 0, 3.0099, 0, 3.991], [1, 2, 3, 4], 0.01, 1, 0, 2, 1)); - assert(!v.eqDelta4([0, 1.001, 0, 1.999, 0, 3.04, 0, 4], [1, 2, 3, 4], 0.01, 1, 0, 2, 1)); - }); - - it("iterator", () => { - assert.deepEqual([...new v.Vec4([1, 2, 3, 4])], [1, 2, 3, 4]); - assert.deepEqual([...new v.Vec4([0, 1, 0, 2, 0, 3, 0, 4], 1, 2)], [1, 2, 3, 4]); - }); - - it("arraylike", () => { - const buf = [0, 1, 0, 2, 0, 3, 0, 4]; - const a = new v.Vec4(buf, 1, 2); - assert.equal(a.length, 4); - assert.equal(a[0], 1); - assert.equal(a[1], 2); - assert.equal(a[2], 3); - assert.equal(a[3], 4); - a[0] = 10; - a[1] = 20; - a[2] = 30; - a[3] = 40; - assert.equal(a[0], 10); - assert.equal(a[1], 20); - assert.equal(a[2], 30); - assert.equal(a[3], 40); - assert.deepEqual(a.buf, [0, 10, 0, 20, 0, 30, 0, 40]); - }); - - it("prop access", () => { - const buf = [0, 1, 0, 2, 0, 3, 0, 4]; - const a = new v.Vec4(buf, 1, 2); - assert.equal(a.x, 1); - assert.equal(a.y, 2); - assert.equal(a.z, 3); - assert.equal(a.w, 4); - a.x = 10; - a.y = 20; - a.z = 30; - a.w = 40; - assert.equal(a.x, 10); - assert.equal(a.y, 20); - assert.equal(a.z, 30); - assert.equal(a.w, 40); - assert.deepEqual(a.buf, [0, 10, 0, 20, 0, 30, 0, 40]); - }); -}); diff --git a/packages/vectors3/.npmignore b/packages/vectors3/.npmignore deleted file mode 100644 index 67d0c55714..0000000000 --- a/packages/vectors3/.npmignore +++ /dev/null @@ -1,13 +0,0 @@ -.cache -.meta -.nyc_output -*.gz -*.html -*.tgz -build -coverage -dev -doc -src* -test -tsconfig.json diff --git a/packages/vectors3/LICENSE b/packages/vectors3/LICENSE deleted file mode 100644 index 8dada3edaf..0000000000 --- a/packages/vectors3/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/packages/vectors3/README.md b/packages/vectors3/README.md deleted file mode 100644 index c96ab1d918..0000000000 --- a/packages/vectors3/README.md +++ /dev/null @@ -1,401 +0,0 @@ -# @thi.ng/vectors3 - -[![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/vectors3.svg)](https://www.npmjs.com/package/@thi.ng/vectors3) -![npm downloads](https://img.shields.io/npm/dm/@thi.ng/vectors3.svg) -[![Twitter Follow](https://img.shields.io/twitter/follow/thing_umbrella.svg?style=flat-square&label=twitter)](https://twitter.com/thing_umbrella) - -This project is part of the -[@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo. - - - -- [About](#about) - - [Features](#features) - - [Related packages](#related-packages) -- [Installation](#installation) -- [Dependencies](#dependencies) -- [Usage examples](#usage-examples) -- [API](#api) - - [Constants](#constants) - - [Component setters & copying](#component-setters--copying) - - [Component swizzling](#component-swizzling) - - [Vector creation](#vector-creation) - - [Basic vector math](#basic-vector-math) - - [Multiply-add](#multiply-add) - - [Constraints](#constraints) - - [Cross product](#cross-product) - - [Dot product](#dot-product) - - [Interpolation](#interpolation) - - [Normalization / magnitude](#normalization--magnitude) - - [Distances](#distances) - - [Orientation](#orientation) - - [Rotations](#rotations) - - [Polar / cartesian conversion](#polar--cartesian-conversion) - - [Randomness](#randomness) - - [Unary vector math ops](#unary-vector-math-ops) - - [Vector array batch processing](#vector-array-batch-processing) - - [Comparison / equality](#comparison--equality) - - [Code generator](#code-generator) -- [Authors](#authors) -- [License](#license) - - - -## About - -**This still unreleased package will soon replace the existing -[@thi.ng/vectors](https://github.com/thi-ng/umbrella/tree/master/packages/vectors) -package.** - -This package provides 350+ largely code generated functions & supporting -types to perform vector operations on fixed and arbitrary-length -vectors, both packed and strided (i.e. where individual vector -components are not successive array elements, for example in SOA -layouts). - -### Features - -- Small & fast: The vast majority of these functions are code generated - with fixed-sized versions not using any loops. Minified + gzipped, the - entire package is ~12.7KB. -- Unified API: Any `ArrayLike` type can be used as vector containers - (e.g. JS arrays, typed arrays, custom impls). Most functions are - implemented as multi-methods, dispatching to any potentially optimized - versions based on given vector arguments. -- Highly modular: Each function is defined in its own submodule / file. - In addition to each generic multi-method base function, all - fixed-length optimized versions are exported too. E.g. If - [`add`](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/add.ts) - performs vector addition on arbitrary-length vectors, `add2`, `add3`, - `add4` are the optimized version for fixed-length vectors... -- Extensible: Custom vector ops can be defined in a similar manner using - the provided code generation helpers (see - [vop.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/vop.ts) - and - [codegen.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/codegen.ts) - for details). -- Immutable by default: Each operation producing a vector result takes - an output vector as first argument. If `null`, the vector given as 2nd - argument will be used as output (i.e. for mutation). -- Strided vector support is handled via the lightweight - [`Vec2/3/4`](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/vec2.ts) - class wrappers and the - [`gvec()`](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/gvec.ts) - proxy (for generic, arbitrary-length vectors). These types behave like - normal arrays (for read/write operations) and are also iterable. A - subset of functions (suffixed with `S`, e.g. - [`addS`](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/adds.ts) - vs. `add`) also support striding without the need for extra class - wrappers. This is handled via additional index and stride arguments - for each input/output vector. These functions are only available for - sizes 2 / 3 / 4, though. -- Random vector functions support the `IRandom` interface defined by - [@thi.ng/random](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/random) - to work with custom (P)RNGs. If omitted, the built-in `Math.random()` - will be used. - -### Related packages - -- [@thi.ng/color](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/color) - vector based color operations / conversions -- [@thi.ng/geom2](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/geom2) - 2D/3D geometry types & operations -- [@thi.ng/matrices](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/matrices) - 2x2, 2x3, 3x3, 4x4 matrix & quaternion ops -- [@thi.ng/vector-pools](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vector-pools) - operations on memory mapped data - -## Installation - -```bash -yarn add @thi.ng/vectors3 -``` - -## Dependencies - -- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/api) -- [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/master/packages/checks) -- [@thi.ng/equiv](https://github.com/thi-ng/umbrella/tree/master/packages/equiv) -- [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/master/packages/errors) -- [@thi.ng/math](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/math) -- [@thi.ng/random](https://github.com/thi-ng/umbrella/tree/master/packages/random) -- [@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/master/packages/transducers) - -## Usage examples - -```ts -import * as v from "@thi.ng/vectors3"; - -// immutable vector addition (1st arg is result) -v.add([], [1, 2, 3, 4], [10, 20, 30, 40]) -// [11, 22, 33, 44] - -// mutable addition (if first arg is null) -a = [1, 2, 3]; -v.add(null, a, a); -// [2, 4, 6] - -// multiply-add (o = a + b * c) -v.madd([], [1, 2], [10, 20], [0.5, 0.25]); -// [6, 7] - -// multiply-add w/ scalar (o = a + b * n) -v.maddN([], [1, 2], [10, 20], 0.5); -// [6, 12] - -// scalar addition w/ arbitrary length & strided vector -v.addN([], gvec([0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0], 3, 1, 4), 10); -// [11, 12, 13] - -v.dist([1, 2], [100, 200]); -// 221.37072977247917 - -v.distManhattan([1, 2], [100, 200]); -// 297 - -v.distChebyshev([1, 2], [100, 200]); -// 198 - -v.mixN([], [1, 2], [10, 20], 0.5); -// [5.5, 11] - -v.fromHomogeneous([], [100, 200, 0.5]); -// [200, 400] - -v.swizzle4([], [1, 2], 1, 1, 0, 0); -// [ 2, 2, 1, 1 ] -``` - -## API - -### Constants - -- `MAX2` / `MAX3` / `MAX4` - each component `+Infinity` -- `MIN2` / `MIN3` / `MIN4` - each component `-Infinity` -- `ONE2` / `ONE3` / `ONE4` - each component `1` -- `ZERO2` / `ZERO3` / `ZERO4` - each component `0` -- `X2` / `X3` / `X4` - positive X axis -- `Y2` / `Y3` / `Y4` - positive Y axis -- `Z3` / `Z4` - positive Z axis -- `W4` - positive W axis - -### Component setters & copying - -- `set` / `set2` / `set3` / `set4` -- `setC` / `setC2` / `setC3` / `setC4` / `setC6` -- `setN` / `setN2` / `setN3` / `setN4` -- `setS` / `setS2` / `setS3` / `setS4` -- `setSN2` / `setSN3` / `setSN4` -- `copy` -- `empty` -- `one` -- `zero` - -### Component swizzling - -- `swizzle2` / `swizzle3` / `swizzle4` -- `swapXY` / `swapXZ` / `swapYZ` - -### Vector creation - -Functions to create wrapped vector instances: - -- `vec2` / `vec2n` -- `vec3` / `vec3n` -- `vec4` / `vec4n` -- `gvec` - -Wrap existing vanilla vectors: - -- `asVec2` / `asVec3` / `asVec4` - -Vanilla vector (array) factories: - -- `ones` -- `zeroes` - -### Basic vector math - -#### Vector / vector - -Component wise op with 2 input vectors: - -- `add` / `add2` / `add3` / `add4` -- `div` / `div2` / `div3` / `div4` -- `mul` / `mul2` / `mul3` / `mul4` -- `sub` / `sub2` / `sub3` / `sub4` -- `mod` / `mod2` / `mod3` / `mod4` -- `pow` / `pow2` / `pow3` / `pow4` - -#### Vector / scalar - -Component wise op with one input vector and single scalar: - -- `addN` / `addN2` / `addN3` / `addN4` -- `divN` / `divN2` / `divN3` / `divN4` -- `mulN` / `mulN2` / `mulN3` / `mulN4` -- `subN` / `subN2` / `subN3` / `subN4` -- `neg` - same as `mulN(out, v, -1)` -- `modN` / `modN2` / `modN3` / `modN4` -- `powN` / `powN2` / `powN3` / `powN4` - -#### Strided vectors - -Functions for memory mapped, strided vectors (without requiring wrappers): - -- `addS2` / `addS3` / `addS4` -- `divS2` / `divS3` / `divS4` -- `mulS2` / `mulS3` / `mulS4` -- `subS2` / `subS3` / `subS4` - -### Multiply-add - -- `addm` / `addm2` / `addm3` / `addm4` -- `addmN` / `addmN2` / `addmN3` / `addmN4` -- `addW2` / `addW3` / `addW4` / `addW5` -- `madd` / `madd2` / `madd3` / `madd4` -- `maddN` / `maddN2` / `maddN3` / `maddN4` -- `subm` / `subm2` / `subm3` / `subm4` -- `submN` / `submN2` / `submN3` / `submN4` - -### Constraints - -- `clamp` -- `clamp2` / `clamp3` / `clamp4` -- `clampN` / `clampN2` / `clampN3` / `clampN4` -- `clamp01` / `clamp01_2` / `clamp01_3` / `clamp01_4` -- `clamp11` / `clamp11_2` / `clamp11_3` / `clamp11_4` -- `max` / `max2` / `max3` / `max4` -- `min` / `min2` / `min3` / `min4` - -### Cross product - -- `cross2` -- `cross3` -- `orthoNormal3` -- `signedArea2` - -### Dot product - -- `dot` -- `dot2` / `dot3` / `dot4` -- `dotC4` / `dotC6` / `dotC8` -- `dotS2` / `dotS3` / `dotS4` - -### Interpolation - -- `mix` / `mix2` / `mix3` / `mix4` -- `mixN` / `mixN2` / `mixN3` / `mixN4` -- `mixBilinear` / `mixBilinear2` / `mixBilinear3` / `mixBilinear4` -- `mixCubic` -- `mixQuadratic` -- `smoothStep` / `smoothStep2` / `smoothStep3` / `smoothStep4` -- `step` / `step2` / `step3` / `step4` - -### Normalization / magnitude - -- `limit` -- `mag` -- `magSq` / `magSq2` / `magSq3` / `magSq4` -- `normalize` - -### Distances - -- `dist` -- `distSq` / `distSq2` / `distSq3` / `distSq4` -- `distChebyshev` / `distChebyshev2` / `distChebyshev3` / `distChebyshev4` -- `distManhattan` / `distManhattan2` / `distManhattan3` / `distManhattan4` - -### Orientation - -- `angleBetween` -- `angleRatio` -- `bisect2` -- `faceForward` -- `heading` / `headingXY` / `headingXZ` / `headingYZ` -- `perpendicularLeft2` / `perpendicularRight2` -- `project` -- `reflect` -- `refract` - -### Rotations - -(Also see rotation matrices provided by -[@thi.ng/matrices](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/matrices)) - -- `rotateAroundAxis3` -- `rotateAroundPoint2` -- `rotateX` \ `rotateY` \ `rotateZ` - -### Polar / cartesian conversion - -- `cartesian` / `cartesian2` / `cartesian3` -- `polar` / `polar2` / `polar3` - -### Randomness - -All ops support custom PRNG impls based on the -[@thi.ng/random](https://github.com/thi-ng/umbrella/tree/master/packages/random) -`IRandom` interface and use `Math.random` by default: - -- `jitter` -- `randNorm` -- `random` / `random2` / `random3` / `random4` - -### Unary vector math ops - -- `abs` / `abs2` / `abs3` / `abs4` -- `acos` / `acos2` / `acos3` / `acos4` -- `asin` / `asin2` / `asin3` / `asin4` -- `ceil` / `ceil2` / `ceil3` / `ceil4` -- `cos` / `cos2` / `cos3` / `cos4` -- `cosh` / `cosh2` / `cosh3` / `cosh4` -- `exp` / `exp2` / `exp3` / `exp4` -- `floor` / `floor2` / `floor3` / `floor4` -- `fract` / `fract2` / `fract3` / `fract4` -- `fromHomogeneous` / `fromHomogeneous3` / `fromHomogeneous4` -- `invert` / `invert2` / `invert3` / `invert4` -- `invSqrt` / `invSqrt2` / `invSqrt3` / `invSqrt4` -- `log` / `log2` / `log3` / `log4` -- `major` / `major2` / `major3` / `major4` -- `minor` / `minor2` / `minor3` / `minor4` -- `round` / `round2` / `round3` / `round4` -- `sign` / `sign2` / `sign3` / `sign4` -- `sin` / `sin2` / `sin3` / `sin4` -- `sinh` / `sinh2` / `sinh3` / `sinh4` -- `sqrt` / `sqrt2` / `sqrt3` / `sqrt4` -- `sum` / `sum2` / `sum3` / `sum4` -- `tan` / `tan2` / `tan3` / `tan4` -- `tanh` / `tanh2` / `tanh3` / `tanh4` -- `trunc` / `trunc2` / `trunc3` / `trunc4` -- `wrap` / `wrap2` / `wrap3` / `wrap4` - -### Vector array batch processing - -Functions to transform flat / strided buffers w/ vector operations: - -- `mapV` / `mapVN` / `mapVV` / `mapVVN` / `mapVVV` - -### Comparison / equality - -- `comparator2` / `comparator3` / `comparator4` -- `eqDelta` / `eqDelta2` / `eqDelta3` / `eqDelta4` -- `eqDeltaS` -- `eqDeltaArray` - -### Code generator - -- `compile` / `compileG` / `compileGHOF` / `compileHOF` -- `defOp` / `defOpS` / `defFnOp` / `defHofOp` -- `defMathNOp` / `defMathOp` -- `vop` - -For more information about the code generator see: - -- [codegen.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/codegen.ts) -- [templates.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/templates.ts) -- [vop.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/vop.ts) - -## Authors - -- Karsten Schmidt - -## License - -© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/packages/vectors3/package.json b/packages/vectors3/package.json deleted file mode 100644 index ce6ea74895..0000000000 --- a/packages/vectors3/package.json +++ /dev/null @@ -1,101 +0,0 @@ -{ - "name": "@thi.ng/vectors3", - "version": "0.0.1", - "description": "Optimized 2d/3d/4d and arbitrary length vector operations", - "module": "./index.js", - "main": "./lib/index.js", - "umd:main": "./lib/index.umd.js", - "typings": "./index.d.ts", - "repository": { - "type": "git", - "url": "https://github.com/thi-ng/umbrella.git" - }, - "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/vectors3", - "author": "Karsten Schmidt ", - "license": "Apache-2.0", - "scripts": { - "build": "yarn clean && yarn build:es6 && yarn build:bundle", - "build:es6": "tsc --declaration", - "build:bundle": "../../scripts/bundle-module vectors3 api checks equiv errors math memoize random transducers", - "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", - "cover": "yarn test && nyc report --reporter=lcov", - "doc": "typedoc --mode modules --out doc src", - "pub": "yarn build && yarn publish --access public" - }, - "devDependencies": { - "@types/mocha": "^5.2.5", - "@types/node": "^10.12.15", - "mocha": "^5.2.0", - "nyc": "^13.1.0", - "typedoc": "^0.14.0", - "typescript": "^3.2.2" - }, - "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/equiv": "^0.1.15", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/math": "^0.2.2", - "@thi.ng/memoize": "^0.2.6", - "@thi.ng/random": "^0.1.1", - "@thi.ng/transducers": "^2.3.2" - }, - "keywords": [ - "2D", - "3D", - "4D", - "abitrary length", - "bilinear", - "cartesian", - "chebyshev", - "clamp", - "code generator", - "cubic", - "data structures", - "distance", - "dot product", - "equality", - "ES6", - "faceforward", - "geometry", - "gvec", - "heading", - "homogeneous", - "interpolation", - "manhattan", - "magnitude", - "math", - "memory mapped", - "normal", - "normalize", - "polar", - "projection", - "quadratic", - "random", - "reflect", - "refract", - "rotation", - "setter", - "smoothstep", - "step", - "strided", - "typescript", - "webgl", - "vector", - "vec2", - "vec3", - "vec4" - ], - "publishConfig": { - "access": "public" - }, - "browserslist": [ - "since 2018-07" - ], - "browser": { - "process": false, - "setTimeout": false - }, - "sideEffects": false -} \ No newline at end of file diff --git a/packages/vectors3/src/api.ts b/packages/vectors3/src/api.ts deleted file mode 100644 index 3f7f631d9a..0000000000 --- a/packages/vectors3/src/api.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { - ICopy, - IEmpty, - IEqualsDelta, - ILength, -} from "@thi.ng/api"; - -export interface Vec extends - Iterable, - ILength { - - [id: number]: number; -} - -export interface ReadonlyVec extends - Iterable, - ILength { - readonly [id: number]: number; -} - -export interface StridedVec { - buf: Vec; - offset: number; - stride: number; -} - -export interface IVector extends - Vec, - ICopy, - ICopyView, - IEmpty, - IEqualsDelta, - StridedVec { -} - -export interface ICopyView { - copyView(): T; -} - -export interface VectorConstructor { - new(buf: Vec, offset?: number, stride?: number): T; -} - -export interface MultiVecOp { - add(dim: number, op: VOP): VOP; - default(op: VOP): VOP; -} - -export type VecOpV = (out: Vec, a: ReadonlyVec) => Vec; -export type VecOpN = (out: Vec, n: number) => Vec; -export type VecOpVV = (out: Vec, a: ReadonlyVec, b: ReadonlyVec) => Vec; -export type VecOpVN = (out: Vec, a: ReadonlyVec, n: number) => Vec; -export type VecOpVVV = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => Vec; -export type VecOpVVN = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, n: number) => Vec; -export type VecOpVNN = (out: Vec, a: ReadonlyVec, u: number, v: number) => Vec; -export type VecOpVVVVNN = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, d: ReadonlyVec, u: number, v: number) => Vec; - -export type VecOpVO = (out: Vec, a: ReadonlyVec, b?: T) => Vec; -export type VecOpOO = (out: Vec, a?: A, b?: B) => Vec; -export type VecOpOOO = (out: Vec, a?: A, b?: B, c?: C) => Vec; -export type VecOpNNO = (out: Vec, a: number, b: number, c?: T) => Vec; - -export type VecOpRoV = (a: ReadonlyVec) => T; -export type VecOpRoVV = (a: ReadonlyVec, b: ReadonlyVec) => T; -export type VecOpRoVVO = (a: ReadonlyVec, b: ReadonlyVec, c?: O) => T; - -export type VecOpSV = (out: Vec, a: ReadonlyVec, io?: number, ia?: number, so?: number, sa?: number) => Vec; -export type VecOpSVV = (out: Vec, a: ReadonlyVec, b: ReadonlyVec, io?: number, ia?: number, ib?: number, so?: number, sa?: number, sb?: number) => Vec; -export type VecOpSRoVV = (a: ReadonlyVec, b: ReadonlyVec, ia?: number, ib?: number, sa?: number, sb?: number) => T; - -export interface MultiVecOpV extends VecOpV, MultiVecOp { } -export interface MultiVecOpN extends VecOpN, MultiVecOp { } -export interface MultiVecOpVV extends VecOpVV, MultiVecOp { } -export interface MultiVecOpVN extends VecOpVN, MultiVecOp { } -export interface MultiVecOpVVV extends VecOpVVV, MultiVecOp { } -export interface MultiVecOpVVN extends VecOpVVN, MultiVecOp { } -export interface MultiVecOpVNN extends VecOpVNN, MultiVecOp { } -export interface MultiVecOpVVVVNN extends VecOpVVVVNN, MultiVecOp { } - -export interface MultiVecOpVO extends VecOpVO, MultiVecOp> { } -export interface MultiVecOpOO extends VecOpOO, MultiVecOp> { } -export interface MultiVecOpOOO extends VecOpOOO, MultiVecOp> { } -export interface MultiVecOpNNO extends VecOpNNO, MultiVecOp> { } - -export interface MultiVecOpRoV extends VecOpRoV, MultiVecOp> { } -export interface MultiVecOpRoVV extends VecOpRoVV, MultiVecOp> { } -export interface MultiVecOpRoVVO extends VecOpRoVVO, MultiVecOp> { } - -const mi = -Infinity; -const mx = Infinity; - -export const MIN2 = Object.freeze([mi, mi]); -export const MAX2 = Object.freeze([mx, mx]); -export const ONE2 = Object.freeze([1, 1]); -export const ZERO2 = Object.freeze([0, 0]); -export const X2 = Object.freeze([1, 0]); -export const Y2 = Object.freeze([0, 1]); - -export const MIN3 = Object.freeze([mi, mi, mi]); -export const MAX3 = Object.freeze([mx, mx, mx]); -export const ONE3 = Object.freeze([1, 1, 1]); -export const ZERO3 = Object.freeze([0, 0, 0]); -export const X3 = Object.freeze([1, 0, 0]); -export const Y3 = Object.freeze([0, 1, 0]); -export const Z3 = Object.freeze([0, 0, 1]); - -export const MIN4 = Object.freeze([mi, mi, mi, mi]); -export const MAX4 = Object.freeze([mx, mx, mx, mx]); -export const ONE4 = Object.freeze([1, 1, 1, 1]); -export const ZERO4 = Object.freeze([0, 0, 0, 0]); -export const X4 = Object.freeze([1, 0, 0, 0]); -export const Y4 = Object.freeze([0, 1, 0, 0]); -export const Z4 = Object.freeze([0, 0, 1, 0]); -export const W4 = Object.freeze([0, 0, 0, 1]); diff --git a/packages/vectors3/src/gvec.ts b/packages/vectors3/src/gvec.ts deleted file mode 100644 index 99da073a48..0000000000 --- a/packages/vectors3/src/gvec.ts +++ /dev/null @@ -1,167 +0,0 @@ -import { EPS } from "@thi.ng/math"; -import { memoize1 } from "@thi.ng/memoize"; -import { map, range } from "@thi.ng/transducers"; -import { IVector, Vec } from "./api"; -import { eqDeltaS } from "./eqdelta"; -import { values } from "./internal/vec-utils"; -import { zeroes } from "./setn"; -import { setS } from "./sets"; - -const SYM_B = "buf"; -const SYM_L = "length"; -const SYM_O = "offset"; -const SYM_S = "stride"; -const SYM_C = "copy"; -const SYM_CV = "copyView"; -const SYM_EMPTY = "empty"; -const SYM_EQD = "eqDelta"; -const SYM_STR = "toString"; - -const PROPS = new Set([ - SYM_B, - SYM_C, - SYM_CV, - SYM_EMPTY, - SYM_EQD, - SYM_L, - SYM_O, - SYM_S, - SYM_STR, - Symbol.iterator -]); - -const keys = memoize1( - (size: number) => [ - ...map(String, range(size)), - ...PROPS - ] -); - -/** - * Wrapper for strided, arbitrary length vectors. Wraps given buffer in - * ES6 `Proxy` with custom property getters/setters and implements the - * following interfaces: - * - * - `Iterable` (ES6) - * - `ICopy` - * - `IEmpty` - * - `IEqualsDelta` - * - `IVector` - * - `Object.toString()` - * - * Read/write access for the following properties: - * - * - array indices in the [0 .. `size`) interval - * - `offset` - start index - * - `stride` - component stride - * - `buf` - backing buffer (readonly) - * - `length` - vector size - * - * Array index access uses bounds checking against the [0 .. `size`) - * interval, but, for performance reasons, **not** against the actual - * wrapped buffer. - * - * Note: ES6 proxies are ~10x slower than standard array accesses. If - * several computations are to be performed on such vectors it will be - * much more efficient to first copy them to compact arrays and then - * copy result back if needed. - * - * ``` - * // 3D vector w/ stride length of 4 - * a = gvec([1,0,0,0,2,0,0,0,3,0,0,0], 3, 0, 4); - * a[0] // 1 - * a[1] // 2 - * a[2] // 3 - * - * a.stride - * // 4 - * - * [...a] - * // [1, 2, 3] - * - * a.toString() - * // "[1,2,3]" - * - * add([], a, a) - * // [2, 4, 6] - * - * copy(a) - * // [1, 2, 3] - * - * a.copyView() - * // Proxy [ [ 1, 0, 2, 0, 3, 0 ], ... } - * - * eqDelta(a, [1, 2, 3]) - * // true - * ``` - * - * @param buf - * @param size - * @param offset - * @param stride - */ -export const gvec = - (buf: Vec, size: number, offset = 0, stride = 1): IVector => - new Proxy(buf, { - get(obj, id) { - switch (id) { - case Symbol.iterator: - return () => values(obj, size, offset, stride); - case SYM_L: - return size; - case SYM_B: - return buf; - case SYM_O: - return offset; - case SYM_S: - return stride; - case SYM_C: - return () => - setS([], obj, size, 0, offset, 1, stride); - case SYM_CV: - return () => - gvec(obj, size, offset, stride); - case SYM_EMPTY: - return () => zeroes(size); - case SYM_EQD: - return (o, eps = EPS) => - eqDeltaS(buf, o, size, eps, offset, 0, stride, 1); - case SYM_STR: - return () => - JSON.stringify([...values(obj, size, offset, stride)]); - default: - const j = parseInt(id); - return !isNaN(j) && j >= 0 && j < size ? - obj[offset + j * stride] : - undefined; - } - }, - set(obj, id, value) { - const j = parseInt(id); - if (!isNaN(j) && j >= 0 && j < size) { - obj[offset + (id | 0) * stride] = value; - } else { - switch (id) { - case SYM_O: - offset = value; - break; - case SYM_S: - stride = value; - break; - case SYM_L: - size = value; - break; - default: - return false; - } - } - return true - }, - has(_, id) { - return (id >= 0 && id < size) || - PROPS.has(id); - }, - ownKeys() { - return keys(size); - } - }); diff --git a/packages/vectors3/src/index.ts b/packages/vectors3/src/index.ts deleted file mode 100644 index b7bcb04093..0000000000 --- a/packages/vectors3/src/index.ts +++ /dev/null @@ -1,113 +0,0 @@ -export * from "./api"; -export * from "./internal/accessors"; -export * from "./internal/avec"; -export * from "./internal/codegen"; -export * from "./internal/templates"; -export * from "./internal/vec-utils"; -export * from "./internal/vop"; - -export * from "./vec2"; -export * from "./vec3"; -export * from "./vec4"; - -export * from "./abs"; -export * from "./acos"; -export * from "./addw"; -export * from "./add"; -export * from "./addm"; -export * from "./addmn"; -export * from "./addn"; -export * from "./adds"; -export * from "./angle-between"; -export * from "./asin"; -export * from "./bisect"; -export * from "./cartesian"; -export * from "./ceil"; -export * from "./clamp"; -export * from "./clampn"; -export * from "./compare"; -export * from "./copy"; -export * from "./cos"; -export * from "./cosh"; -export * from "./cross"; -export * from "./dist"; -export * from "./dist-chebyshev"; -export * from "./dist-manhattan"; -export * from "./distsq"; -export * from "./div"; -export * from "./divn"; -export * from "./divs"; -export * from "./dot"; -export * from "./dotc"; -export * from "./dots"; -export * from "./empty"; -export * from "./eqdelta"; -export * from "./exp"; -export * from "./face-forward"; -export * from "./floor"; -export * from "./fract"; -export * from "./gvec"; -export * from "./heading"; -export * from "./homogeneous"; -export * from "./invert"; -export * from "./invsqrt"; -export * from "./jitter"; -export * from "./limit"; -export * from "./log"; -export * from "./madd"; -export * from "./maddn"; -export * from "./mag"; -export * from "./magsq"; -export * from "./major"; -export * from "./map"; -export * from "./max"; -export * from "./min"; -export * from "./minor"; -export * from "./mix-bilinear"; -export * from "./mix-cubic"; -export * from "./mix-quadratic"; -export * from "./mix"; -export * from "./mixn"; -export * from "./mod"; -export * from "./modn"; -export * from "./mul"; -export * from "./muln"; -export * from "./muls"; -export * from "./neg"; -export * from "./normalize"; -export * from "./ortho-normal"; -export * from "./perpendicular"; -export * from "./polar"; -export * from "./pow"; -export * from "./pown"; -export * from "./project"; -export * from "./random"; -export * from "./reflect"; -export * from "./refract"; -export * from "./rotate-around-axis"; -export * from "./rotate-around-point"; -export * from "./rotate"; -export * from "./round"; -export * from "./set"; -export * from "./setc"; -export * from "./setn"; -export * from "./sets"; -export * from "./setsn"; -export * from "./sign"; -export * from "./signed-area"; -export * from "./sin"; -export * from "./sinh"; -export * from "./sqrt"; -export * from "./step"; -export * from "./smoothstep"; -export * from "./sub"; -export * from "./subm"; -export * from "./submn"; -export * from "./subn"; -export * from "./subs"; -export * from "./sum"; -export * from "./swizzle"; -export * from "./tan"; -export * from "./tanh"; -export * from "./trunc"; -export * from "./wrap"; diff --git a/packages/vectors3/src/vec2.ts b/packages/vectors3/src/vec2.ts deleted file mode 100644 index c4273a4615..0000000000 --- a/packages/vectors3/src/vec2.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { EPS } from "@thi.ng/math"; -import { - IVector, - MAX2, - MIN2, - ONE2, - ReadonlyVec, - Vec, - X2, - Y2, - ZERO2 -} from "./api"; -import { eqDelta2 } from "./eqdelta"; -import { declareIndices } from "./internal/accessors"; -import { AVec } from "./internal/avec"; -import { - intoBuffer, - mapBuffer, - values, - vecIterator -} from "./internal/vec-utils"; -import { setS2 } from "./sets"; - -export class Vec2 extends AVec implements - IVector { - - /** - * Returns array of memory mapped `Vec2` instances using given - * backing array and stride settings: The `cstride` is the step size - * between individual XY vector components. `estride` is the step - * size between successive vectors. This arrangement allows for - * different storage approaches, incl. SOA, AOS, striped / - * interleaved etc. - * - * @param buf backing array - * @param num num vectors - * @param start start index - * @param cstride component stride - * @param estride element stride - */ - static mapBuffer(buf: Vec, num: number = buf.length >> 1, start = 0, cstride = 1, estride = 2) { - return mapBuffer(Vec2, buf, num, start, cstride, estride); - } - - /** - * Merges given `src` iterable of `Vec2`s into single array `buf`. - * Vectors will be arranged according to given component and element - * strides, starting at `start` index. It's the user's - * responsibility to ensure the target buffer has sufficient - * capacity to hold the input vectors. See `Vec2.mapBuffer` for the - * inverse operation. Returns `buf`. - * - * @param buf - * @param src - * @param start - * @param cstride - * @param estride - */ - static intoBuffer(buf: Vec, src: Iterable, start = 0, cstride = 1, estride = 2) { - return intoBuffer(setS2, buf, src, start, cstride, estride); - } - - static iterator(buf: Vec, num: number, start = 0, cstride = 1, estride = 2) { - return vecIterator(Vec2, buf, num, start, cstride, estride); - } - - static readonly X_AXIS = new Vec2(X2); - static readonly Y_AXIS = new Vec2(Y2); - static readonly MIN = new Vec2(MIN2); - static readonly MAX = new Vec2(MAX2); - static readonly ZERO = new Vec2(ZERO2); - static readonly ONE = new Vec2(ONE2); - - x: number; - y: number; - [id: number]: number; - - constructor(buf?: Vec, offset = 0, stride = 1) { - super(buf || [0, 0], offset, stride); - } - - [Symbol.iterator]() { - return values(this.buf, 2, this.offset, this.stride); - } - - get length() { - return 2; - } - - copy() { - return new Vec2([this.x, this.y]); - } - - copyView() { - return new Vec2(this.buf, this.offset, this.stride); - } - - empty() { - return new Vec2(); - } - - eqDelta(v: ReadonlyVec, eps = EPS) { - return eqDelta2(this, v, eps); - } - - toJSON() { - return [this.x, this.y]; - } - - toString() { - return `[${this.x}, ${this.y}]`; - } -} - -declareIndices(Vec2.prototype, ["x", "y"]); - -export const vec2 = - (x = 0, y = 0) => new Vec2([x, y]); - -export const vec2n = - (n: number) => new Vec2([n, n]); - -export const asVec2 = - (x: Vec) => - x instanceof Vec2 ? - x : - new Vec2(x.length >= 2 ? x : [x[0] || 0, x[1] || 0]); diff --git a/packages/vectors3/src/vec3.ts b/packages/vectors3/src/vec3.ts deleted file mode 100644 index b800a053c3..0000000000 --- a/packages/vectors3/src/vec3.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { EPS } from "@thi.ng/math"; -import { - IVector, - MAX3, - MIN3, - ONE3, - ReadonlyVec, - Vec, - X3, - Y3, - Z3, - ZERO3 -} from "./api"; -import { eqDelta3 } from "./eqdelta"; -import { declareIndices } from "./internal/accessors"; -import { AVec } from "./internal/avec"; -import { - intoBuffer, - mapBuffer, - values, - vecIterator -} from "./internal/vec-utils"; -import { setS3 } from "./sets"; - -export class Vec3 extends AVec implements - IVector { - - /** - * Returns array of memory mapped `Vec3` instances using given - * backing array and stride settings: The `cstride` is the step size - * between individual XYZ vector components. `estride` is the step - * size between successive vectors. This arrangement allows for - * different storage approaches, incl. SOA, AOS, striped / - * interleaved etc. - * - * @param buf backing array - * @param num num vectors - * @param start start index - * @param cstride component stride - * @param estride element stride - */ - static mapBuffer(buf: Vec, num: number = (buf.length / 3) | 0, start = 0, cstride = 1, estride = 3) { - return mapBuffer(Vec3, buf, num, start, cstride, estride); - } - - /** - * Merges given `src` iterable of `Vec3`s into single array `buf`. - * Vectors will be arranged according to given component and element - * strides, starting at `start` index. It's the user's - * responsibility to ensure the target buffer has sufficient - * capacity to hold the input vectors. See `Vec3.mapBuffer` for the - * inverse operation. Returns `buf`. - * - * @param buf - * @param src - * @param start - * @param cstride - * @param estride - */ - static intoBuffer(buf: Vec, src: Iterable, start = 0, cstride = 1, estride = 3) { - return intoBuffer(setS3, buf, src, start, cstride, estride); - } - - static iterator(buf: Vec, num: number, start = 0, cstride = 1, estride = 3) { - return vecIterator(Vec3, buf, num, start, cstride, estride); - } - - static readonly X_AXIS = new Vec3(X3); - static readonly Y_AXIS = new Vec3(Y3); - static readonly Z_AXIS = new Vec3(Z3); - static readonly MIN = new Vec3(MIN3); - static readonly MAX = new Vec3(MAX3); - static readonly ZERO = new Vec3(ZERO3); - static readonly ONE = new Vec3(ONE3); - - x: number; - y: number; - z: number; - [id: number]: number; - - constructor(buf?: Vec, offset = 0, stride = 1) { - super(buf || [0, 0, 0], offset, stride); - } - - [Symbol.iterator]() { - return values(this.buf, 3, this.offset, this.stride); - } - - get length() { - return 3; - } - - copy() { - return new Vec3([this.x, this.y, this.z]); - } - - copyView() { - return new Vec3(this.buf, this.offset, this.stride); - } - - empty() { - return new Vec3(); - } - - eqDelta(v: ReadonlyVec, eps = EPS) { - return eqDelta3(this, v, eps); - } - - toJSON() { - return [this.x, this.y, this.z]; - } - - toString() { - return `[${this.x}, ${this.y}, ${this.z}]`; - } -} - -declareIndices(Vec3.prototype, ["x", "y", "z"]); - -export const vec3 = - (x = 0, y = 0, z = 0) => new Vec3([x, y, z]); - -export const vec3n = - (n: number) => new Vec3([n, n, n]); - -export const asVec3 = - (x: Vec) => - x instanceof Vec3 ? - x : - new Vec3(x.length >= 3 ? x : [x[0] || 0, x[1] || 0, x[2] || 0]); diff --git a/packages/vectors3/src/vec4.ts b/packages/vectors3/src/vec4.ts deleted file mode 100644 index dc5e27059f..0000000000 --- a/packages/vectors3/src/vec4.ts +++ /dev/null @@ -1,135 +0,0 @@ -import { EPS } from "@thi.ng/math"; -import { - IVector, - MAX4, - MIN4, - ONE4, - ReadonlyVec, - Vec, - X4, - Y4, - Z4, - ZERO4 -} from "./api"; -import { eqDelta4 } from "./eqdelta"; -import { declareIndices } from "./internal/accessors"; -import { AVec } from "./internal/avec"; -import { - intoBuffer, - mapBuffer, - values, - vecIterator -} from "./internal/vec-utils"; -import { setS4 } from "./sets"; - -export class Vec4 extends AVec implements - IVector { - - /** - * Returns array of memory mapped `Vec4` instances using given - * backing array and stride settings: The `cstride` is the step size - * between individual XYZ vector components. `estride` is the step - * size between successive vectors. This arrangement allows for - * different storage approaches, incl. SOA, AOS, striped / - * interleaved etc. - * - * @param buf backing array - * @param num num vectors - * @param start start index - * @param cstride component stride - * @param estride element stride - */ - static mapBuffer(buf: Vec, num: number = buf.length >> 2, start = 0, cstride = 1, estride = 4) { - return mapBuffer(Vec4, buf, num, start, cstride, estride); - } - - /** - * Merges given `src` iterable of `Vec4`s into single array `buf`. - * Vectors will be arranged according to given component and element - * strides, starting at `start` index. It's the user's - * responsibility to ensure the target buffer has sufficient - * capacity to hold the input vectors. See `Vec4.mapBuffer` for the - * inverse operation. Returns `buf`. - * - * @param buf - * @param src - * @param start - * @param cstride - * @param estride - */ - static intoBuffer(buf: Vec, src: Iterable, start = 0, cstride = 1, estride = 4) { - return intoBuffer(setS4, buf, src, start, cstride, estride); - } - - static *iterator(buf: Vec, num: number, start = 0, cstride = 1, estride = 4) { - return vecIterator(Vec4, buf, num, start, cstride, estride); - } - - static readonly X_AXIS = new Vec4(X4); - static readonly Y_AXIS = new Vec4(Y4); - static readonly Z_AXIS = new Vec4(Z4); - static readonly MIN = new Vec4(MIN4); - static readonly MAX = new Vec4(MAX4); - static readonly ZERO = new Vec4(ZERO4); - static readonly ONE = new Vec4(ONE4); - - x: number; - y: number; - z: number; - w: number; - [id: number]: number; - - constructor(buf?: Vec, offset = 0, stride = 1) { - super(buf || [0, 0, 0, 0], offset, stride); - } - - [Symbol.iterator]() { - return values(this.buf, 4, this.offset, this.stride); - } - - get length() { - return 4; - } - - copy() { - return new Vec4([this.x, this.y, this.z, this.w]); - } - - copyView() { - return new Vec4(this.buf, this.offset, this.stride); - } - - empty() { - return new Vec4(); - } - - eqDelta(v: ReadonlyVec, eps = EPS) { - return eqDelta4(this, v, eps); - } - - toJSON() { - return [this.x, this.y, this.z, this.w]; - } - - toString() { - return `[${this.x}, ${this.y}, ${this.z}, ${this.w}]`; - } -} - -declareIndices(Vec4.prototype, ["x", "y", "z", "w"]); - -export const vec4 = - (x = 0, y = 0, z = 0, w = 0) => new Vec4([x, y, z, w]); - -export const vec4n = - (n: number) => new Vec4([n, n, n, n]); - -export const asVec4 = - (x: Vec) => - x instanceof Vec4 ? - x : - new Vec4( - x.length >= 4 ? - x : - [x[0] || 0, x[1] || 0, x[2] || 0, x[3] || 0] - ); diff --git a/packages/vectors3/test/tsconfig.json b/packages/vectors3/test/tsconfig.json deleted file mode 100644 index 2c9c12a650..0000000000 --- a/packages/vectors3/test/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "../../../tsconfig.json", - "compilerOptions": { - "outDir": "../build", - "module": "commonjs", - }, - "include": [ - "./**/*.ts", - "../src/**/*.ts" - ] -} \ No newline at end of file diff --git a/packages/vectors3/tsconfig.json b/packages/vectors3/tsconfig.json deleted file mode 100644 index bcf03f18b4..0000000000 --- a/packages/vectors3/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": ".", - "module": "es6", - "target": "es6" - }, - "include": [ - "./src/**/*.ts" - ] -} \ No newline at end of file From 0779337dfecb426659ef672b1f49630fb4a7cce2 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 20 Jan 2019 22:27:43 +0000 Subject: [PATCH 325/333] build: update vectors3 => vectors references everywhere --- examples/geom-knn/package.json | 2 +- examples/geom-knn/src/index.ts | 2 +- examples/geom-tessel/src/index.ts | 2 +- examples/gesture-analysis/src/index.ts | 8 ++++---- packages/color/package.json | 4 ++-- packages/color/src/alpha.ts | 2 +- packages/color/src/api.ts | 2 +- packages/color/src/clamp.ts | 2 +- packages/color/src/hcya-rgba.ts | 2 +- packages/color/src/hcya.ts | 2 +- packages/color/src/hsia-rgba.ts | 2 +- packages/color/src/hsia.ts | 2 +- packages/color/src/hsla-rgba.ts | 2 +- packages/color/src/hsla.ts | 2 +- packages/color/src/hsva-rgba.ts | 2 +- packages/color/src/hsva.ts | 2 +- packages/color/src/hue-rgba.ts | 2 +- packages/color/src/int-rgba.ts | 2 +- packages/color/src/internal/acolor.ts | 2 +- packages/color/src/internal/matrix-ops.ts | 4 ++-- packages/color/src/invert.ts | 2 +- packages/color/src/luminance-rgb.ts | 2 +- packages/color/src/mix.ts | 2 +- packages/color/src/porter-duff.ts | 2 +- packages/color/src/premultiply.ts | 2 +- packages/color/src/rgba-hcva.ts | 2 +- packages/color/src/rgba-hsia.ts | 2 +- packages/color/src/rgba-ycbcra.ts | 2 +- packages/color/src/rgba.ts | 2 +- packages/color/src/srgba.ts | 2 +- packages/color/src/xyza.ts | 2 +- packages/color/src/ycbcr.ts | 2 +- packages/color/src/ycbcra-rgba.ts | 2 +- packages/geom-accel/package.json | 4 ++-- packages/geom-accel/src/kdtree.ts | 2 +- packages/geom/package.json | 4 ++-- packages/geom/src/api.ts | 2 +- packages/geom/src/ctors/arc.ts | 2 +- packages/geom/src/ctors/circle.ts | 2 +- packages/geom/src/ctors/cubic.ts | 2 +- packages/geom/src/ctors/ellipse.ts | 2 +- packages/geom/src/ctors/line.ts | 2 +- packages/geom/src/ctors/path.ts | 2 +- packages/geom/src/ctors/points.ts | 2 +- packages/geom/src/ctors/polygon.ts | 2 +- packages/geom/src/ctors/polyline.ts | 2 +- packages/geom/src/ctors/quad.ts | 2 +- packages/geom/src/ctors/quadratic.ts | 2 +- packages/geom/src/ctors/ray.ts | 2 +- packages/geom/src/ctors/rect.ts | 2 +- packages/geom/src/ctors/triangle.ts | 2 +- packages/geom/src/internal/arc-point.ts | 2 +- packages/geom/src/internal/barycentric.ts | 2 +- packages/geom/src/internal/bounds.ts | 6 +++--- packages/geom/src/internal/centroid.ts | 2 +- packages/geom/src/internal/circumcenter.ts | 2 +- packages/geom/src/internal/clockwise.ts | 2 +- packages/geom/src/internal/closest-point.ts | 2 +- packages/geom/src/internal/collate.ts | 2 +- packages/geom/src/internal/copy-points.ts | 2 +- packages/geom/src/internal/corner.ts | 2 +- packages/geom/src/internal/direction.ts | 2 +- .../geom/src/internal/douglas\342\200\223peucker.ts" | 2 +- packages/geom/src/internal/edges.ts | 2 +- packages/geom/src/internal/graham-scan.ts | 4 ++-- packages/geom/src/internal/liang-barsky.ts | 2 +- packages/geom/src/internal/point-in-array.ts | 2 +- packages/geom/src/internal/poly-arc-length.ts | 2 +- packages/geom/src/internal/poly-area.ts | 2 +- packages/geom/src/internal/poly-centroid.ts | 2 +- packages/geom/src/internal/poly-point-inside.ts | 2 +- packages/geom/src/internal/sampler.ts | 2 +- packages/geom/src/internal/split.ts | 2 +- packages/geom/src/internal/subdiv-curve.ts | 2 +- packages/geom/src/internal/sutherland-hodgeman.ts | 2 +- packages/geom/src/internal/tessellate.ts | 2 +- packages/geom/src/internal/transform-points.ts | 2 +- packages/geom/src/internal/translate-points.ts | 2 +- packages/geom/src/internal/triangle-point-inside.ts | 2 +- packages/geom/src/internal/union-bounds.ts | 2 +- packages/geom/src/isec/circle-circle.ts | 2 +- packages/geom/src/isec/line-line.ts | 2 +- packages/geom/src/isec/ray-circle.ts | 2 +- packages/geom/src/isec/ray-line.ts | 2 +- packages/geom/src/isec/ray-poly.ts | 2 +- packages/geom/src/ops/arc-length.ts | 2 +- packages/geom/src/ops/area.ts | 2 +- packages/geom/src/ops/as-cubic.ts | 2 +- packages/geom/src/ops/bounds.ts | 2 +- packages/geom/src/ops/center.ts | 2 +- packages/geom/src/ops/centroid.ts | 2 +- packages/geom/src/ops/classify-point.ts | 2 +- packages/geom/src/ops/closest-point.ts | 2 +- packages/geom/src/ops/fit-into-bounds.ts | 2 +- packages/geom/src/ops/flip.ts | 2 +- packages/geom/src/ops/map-point.ts | 2 +- packages/geom/src/ops/point-at.ts | 2 +- packages/geom/src/ops/point-inside.ts | 2 +- packages/geom/src/ops/scatter.ts | 2 +- packages/geom/src/ops/simplify.ts | 2 +- packages/geom/src/ops/split-at.ts | 2 +- packages/geom/src/ops/split-near.ts | 2 +- packages/geom/src/ops/subdiv-curve.ts | 2 +- packages/geom/src/ops/tangent-at.ts | 2 +- packages/geom/src/ops/tessellate.ts | 2 +- packages/geom/src/ops/translate.ts | 2 +- packages/geom/src/ops/unmap-point.ts | 2 +- packages/geom/src/ops/vertices.ts | 2 +- packages/geom/src/ops/warp-points.ts | 2 +- packages/matrices/package.json | 4 ++-- packages/matrices/src/add.ts | 2 +- packages/matrices/src/addn.ts | 2 +- packages/matrices/src/alignment-quat.ts | 2 +- packages/matrices/src/api.ts | 2 +- packages/matrices/src/column.ts | 2 +- packages/matrices/src/conjugate.ts | 2 +- packages/matrices/src/determinant.ts | 2 +- packages/matrices/src/diag.ts | 2 +- packages/matrices/src/div.ts | 2 +- packages/matrices/src/divn.ts | 2 +- packages/matrices/src/frustum.ts | 2 +- packages/matrices/src/identity.ts | 2 +- packages/matrices/src/internal/codegen.ts | 2 +- packages/matrices/src/invert.ts | 2 +- packages/matrices/src/lookat.ts | 2 +- packages/matrices/src/m22-m23.ts | 2 +- packages/matrices/src/m23-m22.ts | 2 +- packages/matrices/src/m33-m44.ts | 2 +- packages/matrices/src/m44-m33.ts | 2 +- packages/matrices/src/mixq.ts | 2 +- packages/matrices/src/mul.ts | 2 +- packages/matrices/src/mulm.ts | 2 +- packages/matrices/src/muln.ts | 2 +- packages/matrices/src/mulq.ts | 2 +- packages/matrices/src/mulv.ts | 2 +- packages/matrices/src/ortho.ts | 2 +- packages/matrices/src/project.ts | 2 +- packages/matrices/src/quat-axis-angle.ts | 2 +- packages/matrices/src/quat-euler.ts | 2 +- packages/matrices/src/quat-m33.ts | 2 +- packages/matrices/src/quat-m44.ts | 2 +- packages/matrices/src/rotation-around-axis.ts | 2 +- packages/matrices/src/rotation.ts | 2 +- packages/matrices/src/row.ts | 2 +- packages/matrices/src/scale-center.ts | 2 +- packages/matrices/src/scale.ts | 2 +- packages/matrices/src/set.ts | 2 +- packages/matrices/src/sub.ts | 2 +- packages/matrices/src/subn.ts | 2 +- packages/matrices/src/trace.ts | 2 +- packages/matrices/src/translation.ts | 2 +- packages/matrices/src/transpose.ts | 2 +- packages/vector-pools/package.json | 4 ++-- packages/vector-pools/src/alist.ts | 2 +- packages/vector-pools/src/api.ts | 2 +- packages/vector-pools/src/array-list.ts | 2 +- packages/vector-pools/src/attrib-pool.ts | 2 +- packages/vector-pools/src/linked-list.ts | 2 +- packages/vector-pools/src/vec-pool.ts | 2 +- packages/vector-pools/src/wrap.ts | 2 +- packages/vectors/test/index.ts | 2 +- 161 files changed, 173 insertions(+), 173 deletions(-) diff --git a/examples/geom-knn/package.json b/examples/geom-knn/package.json index 43b66d04e8..ac4ce070a9 100644 --- a/examples/geom-knn/package.json +++ b/examples/geom-knn/package.json @@ -22,7 +22,7 @@ "@thi.ng/rstream-gestures": "latest", "@thi.ng/transducers": "latest", "@thi.ng/transducers-hdom": "latest", - "@thi.ng/vectors3": "latest" + "@thi.ng/vectors": "latest" }, "browserslist": [ "last 3 Chrome versions" diff --git a/examples/geom-knn/src/index.ts b/examples/geom-knn/src/index.ts index a112743463..06282c8fce 100644 --- a/examples/geom-knn/src/index.ts +++ b/examples/geom-knn/src/index.ts @@ -5,7 +5,7 @@ import { sync, trigger } from "@thi.ng/rstream"; import { gestureStream } from "@thi.ng/rstream-gestures"; import { map, mapcat } from "@thi.ng/transducers"; import { updateDOM } from "@thi.ng/transducers-hdom"; -import { Vec } from "@thi.ng/vectors3"; +import { Vec } from "@thi.ng/vectors"; const app = (main) => { // augment hdom-canvas component w/ `init` lifecycle method: this is diff --git a/examples/geom-tessel/src/index.ts b/examples/geom-tessel/src/index.ts index de96857f05..5f929e179a 100644 --- a/examples/geom-tessel/src/index.ts +++ b/examples/geom-tessel/src/index.ts @@ -18,7 +18,7 @@ import { deg, fit01, fit11 } from "@thi.ng/math"; import { fromInterval, sync } from "@thi.ng/rstream"; import { map } from "@thi.ng/transducers"; import { updateDOM } from "@thi.ng/transducers-hdom"; -import { polar, Vec } from "@thi.ng/vectors3"; +import { polar, Vec } from "@thi.ng/vectors"; type Tint = (p: Polygon) => string; diff --git a/examples/gesture-analysis/src/index.ts b/examples/gesture-analysis/src/index.ts index 97a345f1a9..4e01ed0c27 100644 --- a/examples/gesture-analysis/src/index.ts +++ b/examples/gesture-analysis/src/index.ts @@ -26,10 +26,10 @@ import { filter } from "@thi.ng/transducers/xform/filter"; import { map } from "@thi.ng/transducers/xform/map"; import { multiplexObj } from "@thi.ng/transducers/xform/multiplex-obj"; import { partition } from "@thi.ng/transducers/xform/partition"; -import { angleBetween } from "@thi.ng/vectors3/angle-between"; -import { Vec } from "@thi.ng/vectors3/api"; -import { mixN2 } from "@thi.ng/vectors3/mixn"; -import { sub2 } from "@thi.ng/vectors3/sub"; +import { angleBetween } from "@thi.ng/vectors/angle-between"; +import { Vec } from "@thi.ng/vectors/api"; +import { mixN2 } from "@thi.ng/vectors/mixn"; +import { sub2 } from "@thi.ng/vectors/sub"; import { CTA } from "./config"; /** diff --git a/packages/color/package.json b/packages/color/package.json index 4a4fde5c60..abac0592f5 100644 --- a/packages/color/package.json +++ b/packages/color/package.json @@ -16,7 +16,7 @@ "scripts": { "build": "yarn clean && yarn build:es6 && yarn build:bundle", "build:es6": "tsc --declaration", - "build:bundle": "../../scripts/bundle-module color api compose defmulti errors math strings transducers vectors3", + "build:bundle": "../../scripts/bundle-module color api compose defmulti errors math strings transducers vectors", "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib internal", "cover": "yarn test && nyc report --reporter=lcov", @@ -39,7 +39,7 @@ "@thi.ng/math": "^0.2.2", "@thi.ng/strings": "^0.7.1", "@thi.ng/transducers": "^2.3.2", - "@thi.ng/vectors3": "^0.0.1" + "@thi.ng/vectors": "^1.4.12" }, "keywords": [ "alpha", diff --git a/packages/color/src/alpha.ts b/packages/color/src/alpha.ts index 54d358d36a..516b62130c 100644 --- a/packages/color/src/alpha.ts +++ b/packages/color/src/alpha.ts @@ -1,4 +1,4 @@ -import { setC4 } from "@thi.ng/vectors3"; +import { setC4 } from "@thi.ng/vectors"; import { Color, ReadonlyColor } from "./api"; export const alpha = diff --git a/packages/color/src/api.ts b/packages/color/src/api.ts index 70e914a4d3..82f2b9814e 100644 --- a/packages/color/src/api.ts +++ b/packages/color/src/api.ts @@ -1,5 +1,5 @@ import { float, percent } from "@thi.ng/strings"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors"; export type Color = Vec; export type ReadonlyColor = ReadonlyVec; diff --git a/packages/color/src/clamp.ts b/packages/color/src/clamp.ts index 0143d32a27..0265c72f0a 100644 --- a/packages/color/src/clamp.ts +++ b/packages/color/src/clamp.ts @@ -1,5 +1,5 @@ import { clamp01 } from "@thi.ng/math"; -import { setC4 } from "@thi.ng/vectors3"; +import { setC4 } from "@thi.ng/vectors"; import { Color, ReadonlyColor } from "./api"; import { ensureAlpha } from "./internal/ensure-alpha"; import { ensureHue } from "./internal/ensure-hue"; diff --git a/packages/color/src/hcya-rgba.ts b/packages/color/src/hcya-rgba.ts index fd1ef8b4e7..5e596e13d1 100644 --- a/packages/color/src/hcya-rgba.ts +++ b/packages/color/src/hcya-rgba.ts @@ -1,5 +1,5 @@ import { clamp01 } from "@thi.ng/math"; -import { dot3, setC3 } from "@thi.ng/vectors3"; +import { dot3, setC3 } from "@thi.ng/vectors"; import { Color, ReadonlyColor, RGB_LUMINANCE } from "./api"; import { hueRgba } from "./hue-rgba"; import { ensureAlpha } from "./internal/ensure-alpha"; diff --git a/packages/color/src/hcya.ts b/packages/color/src/hcya.ts index 4a18dd3886..dcd0055553 100644 --- a/packages/color/src/hcya.ts +++ b/packages/color/src/hcya.ts @@ -1,4 +1,4 @@ -import { IVector, declareIndices } from "@thi.ng/vectors3"; +import { IVector, declareIndices } from "@thi.ng/vectors"; import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ensure-args"; diff --git a/packages/color/src/hsia-rgba.ts b/packages/color/src/hsia-rgba.ts index df77bc8c35..1288846e31 100644 --- a/packages/color/src/hsia-rgba.ts +++ b/packages/color/src/hsia-rgba.ts @@ -1,4 +1,4 @@ -import { setC3 } from "@thi.ng/vectors3"; +import { setC3 } from "@thi.ng/vectors"; import { Color, ReadonlyColor } from "./api"; import { clampH } from "./clamp"; diff --git a/packages/color/src/hsia.ts b/packages/color/src/hsia.ts index 5d2856925f..8e6dbeedbc 100644 --- a/packages/color/src/hsia.ts +++ b/packages/color/src/hsia.ts @@ -1,4 +1,4 @@ -import { declareIndices, IVector } from "@thi.ng/vectors3"; +import { declareIndices, IVector } from "@thi.ng/vectors"; import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ensure-args"; diff --git a/packages/color/src/hsla-rgba.ts b/packages/color/src/hsla-rgba.ts index 79d2b02790..9704ce0525 100644 --- a/packages/color/src/hsla-rgba.ts +++ b/packages/color/src/hsla-rgba.ts @@ -1,5 +1,5 @@ import { clamp01 } from "@thi.ng/math"; -import { setC3 } from "@thi.ng/vectors3"; +import { setC3 } from "@thi.ng/vectors"; import { Color, ReadonlyColor } from "./api"; import { hueRgba } from "./hue-rgba"; import { ensureAlpha } from "./internal/ensure-alpha"; diff --git a/packages/color/src/hsla.ts b/packages/color/src/hsla.ts index b2e5fd7917..85da646801 100644 --- a/packages/color/src/hsla.ts +++ b/packages/color/src/hsla.ts @@ -1,4 +1,4 @@ -import { declareIndices, IVector } from "@thi.ng/vectors3"; +import { declareIndices, IVector } from "@thi.ng/vectors"; import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ensure-args"; diff --git a/packages/color/src/hsva-rgba.ts b/packages/color/src/hsva-rgba.ts index cde4befe7c..835c07731f 100644 --- a/packages/color/src/hsva-rgba.ts +++ b/packages/color/src/hsva-rgba.ts @@ -1,4 +1,4 @@ -import { setC3 } from "@thi.ng/vectors3"; +import { setC3 } from "@thi.ng/vectors"; import { Color, ReadonlyColor } from "./api"; import { clampH } from "./clamp"; import { hueRgba } from "./hue-rgba"; diff --git a/packages/color/src/hsva.ts b/packages/color/src/hsva.ts index d9db735a4e..6aee7309cd 100644 --- a/packages/color/src/hsva.ts +++ b/packages/color/src/hsva.ts @@ -1,4 +1,4 @@ -import { IVector, declareIndices } from "@thi.ng/vectors3"; +import { IVector, declareIndices } from "@thi.ng/vectors"; import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ensure-args"; diff --git a/packages/color/src/hue-rgba.ts b/packages/color/src/hue-rgba.ts index a3c1544668..80feb44264 100644 --- a/packages/color/src/hue-rgba.ts +++ b/packages/color/src/hue-rgba.ts @@ -1,5 +1,5 @@ import { clamp01 } from "@thi.ng/math"; -import { setC4 } from "@thi.ng/vectors3"; +import { setC4 } from "@thi.ng/vectors"; import { Color, Hue } from "./api"; import { ensureHue } from "./internal/ensure-hue"; diff --git a/packages/color/src/int-rgba.ts b/packages/color/src/int-rgba.ts index 295442e5bf..a391cf5b7f 100644 --- a/packages/color/src/int-rgba.ts +++ b/packages/color/src/int-rgba.ts @@ -1,5 +1,5 @@ import { IDeref } from "@thi.ng/api"; -import { setC4 } from "@thi.ng/vectors3"; +import { setC4 } from "@thi.ng/vectors"; import { Color, INV8BIT } from "./api"; export const int32Rgba = diff --git a/packages/color/src/internal/acolor.ts b/packages/color/src/internal/acolor.ts index 79d9c1e907..52b129c660 100644 --- a/packages/color/src/internal/acolor.ts +++ b/packages/color/src/internal/acolor.ts @@ -1,6 +1,6 @@ import { IDeref } from "@thi.ng/api"; import { EPS } from "@thi.ng/math"; -import { eqDelta4, values } from "@thi.ng/vectors3"; +import { eqDelta4, values } from "@thi.ng/vectors"; import { Color, IColor } from "../api"; export abstract class AColor implements diff --git a/packages/color/src/internal/matrix-ops.ts b/packages/color/src/internal/matrix-ops.ts index fd3ca3fe49..656cde8584 100644 --- a/packages/color/src/internal/matrix-ops.ts +++ b/packages/color/src/internal/matrix-ops.ts @@ -1,6 +1,6 @@ import { clamp01 } from "@thi.ng/math"; -import { dotS3, dotS4 } from "@thi.ng/vectors3"; -import { setC4 } from "@thi.ng/vectors3"; +import { dotS3, dotS4 } from "@thi.ng/vectors"; +import { setC4 } from "@thi.ng/vectors"; import { Color, ColorMatrix, ReadonlyColor } from "../api"; import { ensureAlpha } from "./ensure-alpha"; diff --git a/packages/color/src/invert.ts b/packages/color/src/invert.ts index c22ff4e4cb..f8ed7657a5 100644 --- a/packages/color/src/invert.ts +++ b/packages/color/src/invert.ts @@ -1,4 +1,4 @@ -import { ONE3, sub3 } from "@thi.ng/vectors3"; +import { ONE3, sub3 } from "@thi.ng/vectors"; import { Color, ReadonlyColor } from "./api"; import { clamp } from "./clamp"; diff --git a/packages/color/src/luminance-rgb.ts b/packages/color/src/luminance-rgb.ts index 1ddce3b97d..c244868138 100644 --- a/packages/color/src/luminance-rgb.ts +++ b/packages/color/src/luminance-rgb.ts @@ -1,4 +1,4 @@ -import { dot3 } from "@thi.ng/vectors3"; +import { dot3 } from "@thi.ng/vectors"; import { INV8BIT, ReadonlyColor, RGB_LUMINANCE } from "./api"; export const luminanceRGB = diff --git a/packages/color/src/mix.ts b/packages/color/src/mix.ts index 991880c29b..4e5d205f55 100644 --- a/packages/color/src/mix.ts +++ b/packages/color/src/mix.ts @@ -1,5 +1,5 @@ import { mix as _mix } from "@thi.ng/math"; -import { mixN4, setC4 } from "@thi.ng/vectors3"; +import { mixN4, setC4 } from "@thi.ng/vectors"; import { Color, ReadonlyColor } from "./api"; export const mix: (out: Color, a: ReadonlyColor, b: ReadonlyColor, t: number) => Color = diff --git a/packages/color/src/porter-duff.ts b/packages/color/src/porter-duff.ts index 4db003c7b5..97bba35630 100644 --- a/packages/color/src/porter-duff.ts +++ b/packages/color/src/porter-duff.ts @@ -1,4 +1,4 @@ -import { setC4, setN4 } from "@thi.ng/vectors3"; +import { setC4, setN4 } from "@thi.ng/vectors"; import { Color, ReadonlyColor } from "./api"; import { postmultiply, premultiply } from "./premultiply"; diff --git a/packages/color/src/premultiply.ts b/packages/color/src/premultiply.ts index 43355711e9..cac68983b3 100644 --- a/packages/color/src/premultiply.ts +++ b/packages/color/src/premultiply.ts @@ -1,4 +1,4 @@ -import { set, setC4 } from "@thi.ng/vectors3"; +import { set, setC4 } from "@thi.ng/vectors"; import { Color, ReadonlyColor } from "./api"; /** diff --git a/packages/color/src/rgba-hcva.ts b/packages/color/src/rgba-hcva.ts index cce29153a4..ff3f514463 100644 --- a/packages/color/src/rgba-hcva.ts +++ b/packages/color/src/rgba-hcva.ts @@ -1,5 +1,5 @@ import { EPS, clamp01 } from "@thi.ng/math"; -import { setC3 } from "@thi.ng/vectors3"; +import { setC3 } from "@thi.ng/vectors"; import { Color, ReadonlyColor } from "./api"; import { clamp } from "./clamp"; diff --git a/packages/color/src/rgba-hsia.ts b/packages/color/src/rgba-hsia.ts index e0b6470265..3ee3267207 100644 --- a/packages/color/src/rgba-hsia.ts +++ b/packages/color/src/rgba-hsia.ts @@ -4,7 +4,7 @@ import { TAU, THIRD } from "@thi.ng/math"; -import { setC3 } from "@thi.ng/vectors3"; +import { setC3 } from "@thi.ng/vectors"; import { Color, ReadonlyColor } from "./api"; import { clamp } from "./clamp"; diff --git a/packages/color/src/rgba-ycbcra.ts b/packages/color/src/rgba-ycbcra.ts index 9dfb9835c3..b72787416c 100644 --- a/packages/color/src/rgba-ycbcra.ts +++ b/packages/color/src/rgba-ycbcra.ts @@ -1,4 +1,4 @@ -import { setC3 } from "@thi.ng/vectors3"; +import { setC3 } from "@thi.ng/vectors"; import { Color, ReadonlyColor } from "./api"; import { clamp } from "./clamp"; import { luminanceRGB } from "./luminance-rgb"; diff --git a/packages/color/src/rgba.ts b/packages/color/src/rgba.ts index 842aa06091..345bb268e7 100644 --- a/packages/color/src/rgba.ts +++ b/packages/color/src/rgba.ts @@ -1,4 +1,4 @@ -import { declareIndices, IVector } from "@thi.ng/vectors3"; +import { declareIndices, IVector } from "@thi.ng/vectors"; import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ensure-args"; diff --git a/packages/color/src/srgba.ts b/packages/color/src/srgba.ts index c71f9915bc..0bfc3258b1 100644 --- a/packages/color/src/srgba.ts +++ b/packages/color/src/srgba.ts @@ -1,4 +1,4 @@ -import { setC4 } from "@thi.ng/vectors3"; +import { setC4 } from "@thi.ng/vectors"; import { Color, ReadonlyColor, SRGB_ALPHA } from "./api"; import { ensureAlpha } from "./internal/ensure-alpha"; diff --git a/packages/color/src/xyza.ts b/packages/color/src/xyza.ts index dda33ba7c5..b8edca35fd 100644 --- a/packages/color/src/xyza.ts +++ b/packages/color/src/xyza.ts @@ -1,4 +1,4 @@ -import { declareIndices, IVector } from "@thi.ng/vectors3"; +import { declareIndices, IVector } from "@thi.ng/vectors"; import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ensure-args"; diff --git a/packages/color/src/ycbcr.ts b/packages/color/src/ycbcr.ts index 6b42f4d1c4..206f886c89 100644 --- a/packages/color/src/ycbcr.ts +++ b/packages/color/src/ycbcr.ts @@ -1,4 +1,4 @@ -import { declareIndices, IVector } from "@thi.ng/vectors3"; +import { declareIndices, IVector } from "@thi.ng/vectors"; import { Color, ColorMode } from "./api"; import { AColor } from "./internal/acolor"; import { ensureArgs } from "./internal/ensure-args"; diff --git a/packages/color/src/ycbcra-rgba.ts b/packages/color/src/ycbcra-rgba.ts index 3b6cbdce1f..62269d26a2 100644 --- a/packages/color/src/ycbcra-rgba.ts +++ b/packages/color/src/ycbcra-rgba.ts @@ -1,5 +1,5 @@ import { clamp01 } from "@thi.ng/math"; -import { setC4 } from "@thi.ng/vectors3"; +import { setC4 } from "@thi.ng/vectors"; import { Color, ReadonlyColor } from "./api"; import { ensureAlpha } from "./internal/ensure-alpha"; diff --git a/packages/geom-accel/package.json b/packages/geom-accel/package.json index 6318f10ce5..6c51e80c8f 100644 --- a/packages/geom-accel/package.json +++ b/packages/geom-accel/package.json @@ -16,7 +16,7 @@ "scripts": { "build": "yarn clean && yarn build:es6 && yarn build:bundle", "build:es6": "tsc --declaration", - "build:bundle": "../../scripts/bundle-module geomAccel api heaps math transducers vectors3", + "build:bundle": "../../scripts/bundle-module geomAccel api heaps math transducers vectors", "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib internal", "cover": "yarn test && nyc report --reporter=lcov", @@ -36,7 +36,7 @@ "@thi.ng/heaps": "^0.3.1", "@thi.ng/math": "^0.2.2", "@thi.ng/transducers": "^2.3.2", - "@thi.ng/vectors3": "^0.0.1" + "@thi.ng/vectors": "^1.4.12" }, "keywords": [ "ES6", diff --git a/packages/geom-accel/src/kdtree.ts b/packages/geom-accel/src/kdtree.ts index c4a2d24ea2..895f4aefcc 100644 --- a/packages/geom-accel/src/kdtree.ts +++ b/packages/geom-accel/src/kdtree.ts @@ -2,7 +2,7 @@ import { ICopy, Pair } from "@thi.ng/api"; import { Heap } from "@thi.ng/heaps"; import { EPS } from "@thi.ng/math"; import { ensureArray } from "@thi.ng/transducers"; -import { distSq, empty, ReadonlyVec } from "@thi.ng/vectors3"; +import { distSq, empty, ReadonlyVec } from "@thi.ng/vectors"; const CMP = (a, b) => b[0] - a[0]; diff --git a/packages/geom/package.json b/packages/geom/package.json index 8a6f208839..db7df7b2c6 100644 --- a/packages/geom/package.json +++ b/packages/geom/package.json @@ -16,7 +16,7 @@ "scripts": { "build": "yarn clean && yarn build:es6 && yarn build:bundle", "build:es6": "tsc --declaration", - "build:bundle": "../../scripts/bundle-module geom api checks compose defmulti equiv errors hiccup hiccup-svg math matrices random transducers vectors3", + "build:bundle": "../../scripts/bundle-module geom api checks compose defmulti equiv errors hiccup hiccup-svg math matrices random transducers vectors", "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", @@ -44,7 +44,7 @@ "@thi.ng/matrices": "^0.0.1", "@thi.ng/random": "^0.1.1", "@thi.ng/transducers": "^2.3.2", - "@thi.ng/vectors3": "^0.0.1" + "@thi.ng/vectors": "^1.4.12" }, "keywords": [ "ES6", diff --git a/packages/geom/src/api.ts b/packages/geom/src/api.ts index 70df05131a..dd764ccec6 100644 --- a/packages/geom/src/api.ts +++ b/packages/geom/src/api.ts @@ -9,7 +9,7 @@ import { ReadonlyVec, set, Vec -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { arcPointAt, arcPointAtTheta } from "./internal/arc-point"; import { copyPoints } from "./internal/copy-points"; diff --git a/packages/geom/src/ctors/arc.ts b/packages/geom/src/ctors/arc.ts index 4846f8cce6..9878354394 100644 --- a/packages/geom/src/ctors/arc.ts +++ b/packages/geom/src/ctors/arc.ts @@ -13,7 +13,7 @@ import { submN2, Vec, X2 -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { Arc } from "../api"; export const arc = ( diff --git a/packages/geom/src/ctors/circle.ts b/packages/geom/src/ctors/circle.ts index d3482ed808..9eda53bf3e 100644 --- a/packages/geom/src/ctors/circle.ts +++ b/packages/geom/src/ctors/circle.ts @@ -3,7 +3,7 @@ import { mixN2, ReadonlyVec, Vec -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { Attribs, Circle } from "../api"; import { argsVN } from "../internal/args"; import { circumCenter } from "../internal/circumcenter"; diff --git a/packages/geom/src/ctors/cubic.ts b/packages/geom/src/ctors/cubic.ts index e7041f2443..2eb1b32c94 100644 --- a/packages/geom/src/ctors/cubic.ts +++ b/packages/geom/src/ctors/cubic.ts @@ -10,7 +10,7 @@ import { mixN2, set2, Vec -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { Arc, Attribs, Cubic } from "../api"; import { argAttribs } from "../internal/args"; diff --git a/packages/geom/src/ctors/ellipse.ts b/packages/geom/src/ctors/ellipse.ts index f8f87f477a..08b1c166f1 100644 --- a/packages/geom/src/ctors/ellipse.ts +++ b/packages/geom/src/ctors/ellipse.ts @@ -1,4 +1,4 @@ -import { Vec } from "@thi.ng/vectors3"; +import { Vec } from "@thi.ng/vectors"; import { Attribs, Ellipse } from "../api"; import { argsVV } from "../internal/args"; diff --git a/packages/geom/src/ctors/line.ts b/packages/geom/src/ctors/line.ts index 842fae4f04..69cc98b97a 100644 --- a/packages/geom/src/ctors/line.ts +++ b/packages/geom/src/ctors/line.ts @@ -1,4 +1,4 @@ -import { Vec } from "@thi.ng/vectors3"; +import { Vec } from "@thi.ng/vectors"; import { Attribs, Line, diff --git a/packages/geom/src/ctors/path.ts b/packages/geom/src/ctors/path.ts index e455f4bbef..1526ec6908 100644 --- a/packages/geom/src/ctors/path.ts +++ b/packages/geom/src/ctors/path.ts @@ -10,7 +10,7 @@ import { sub2, Vec, zeroes -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { Attribs, Cubic, diff --git a/packages/geom/src/ctors/points.ts b/packages/geom/src/ctors/points.ts index 009deeab40..a53c656773 100644 --- a/packages/geom/src/ctors/points.ts +++ b/packages/geom/src/ctors/points.ts @@ -1,5 +1,5 @@ import { Attribs, Points } from "../api"; -import { Vec } from "@thi.ng/vectors3"; +import { Vec } from "@thi.ng/vectors"; export const points = (pts?: Vec[], attribs?: Attribs) => new Points(pts, attribs); diff --git a/packages/geom/src/ctors/polygon.ts b/packages/geom/src/ctors/polygon.ts index 8576ddffc3..a77f6c987e 100644 --- a/packages/geom/src/ctors/polygon.ts +++ b/packages/geom/src/ctors/polygon.ts @@ -7,7 +7,7 @@ import { transduce, tuples } from "@thi.ng/transducers"; -import { cartesian2, Vec } from "@thi.ng/vectors3"; +import { cartesian2, Vec } from "@thi.ng/vectors"; import { Attribs, Polygon } from "../api"; export const polygon = diff --git a/packages/geom/src/ctors/polyline.ts b/packages/geom/src/ctors/polyline.ts index 0634359ee4..ec16a1e6da 100644 --- a/packages/geom/src/ctors/polyline.ts +++ b/packages/geom/src/ctors/polyline.ts @@ -1,4 +1,4 @@ -import { Vec } from "@thi.ng/vectors3"; +import { Vec } from "@thi.ng/vectors"; import { Attribs, Polyline } from "../api"; export const polyline = diff --git a/packages/geom/src/ctors/quad.ts b/packages/geom/src/ctors/quad.ts index 8b9c3aacf0..5ead1128c5 100644 --- a/packages/geom/src/ctors/quad.ts +++ b/packages/geom/src/ctors/quad.ts @@ -1,4 +1,4 @@ -import { Vec } from "@thi.ng/vectors3"; +import { Vec } from "@thi.ng/vectors"; import { Attribs, Quad } from "../api"; import { argAttribs } from "../internal/args"; diff --git a/packages/geom/src/ctors/quadratic.ts b/packages/geom/src/ctors/quadratic.ts index 1a3c3ff1d3..dc99330542 100644 --- a/packages/geom/src/ctors/quadratic.ts +++ b/packages/geom/src/ctors/quadratic.ts @@ -1,4 +1,4 @@ -import { mixN, Vec } from "@thi.ng/vectors3"; +import { mixN, Vec } from "@thi.ng/vectors"; import { Attribs, Quadratic } from "../api"; import { argAttribs } from "../internal/args"; diff --git a/packages/geom/src/ctors/ray.ts b/packages/geom/src/ctors/ray.ts index ce19dcc41b..a7a2e8ac12 100644 --- a/packages/geom/src/ctors/ray.ts +++ b/packages/geom/src/ctors/ray.ts @@ -1,4 +1,4 @@ -import { normalize as _norm, Vec } from "@thi.ng/vectors3"; +import { normalize as _norm, Vec } from "@thi.ng/vectors"; import { Attribs, Ray } from "../api"; export const ray = diff --git a/packages/geom/src/ctors/rect.ts b/packages/geom/src/ctors/rect.ts index 789a985316..52db20475e 100644 --- a/packages/geom/src/ctors/rect.ts +++ b/packages/geom/src/ctors/rect.ts @@ -1,4 +1,4 @@ -import { sub2, Vec } from "@thi.ng/vectors3"; +import { sub2, Vec } from "@thi.ng/vectors"; import { Attribs, Rect } from "../api"; import { argsVV } from "../internal/args"; diff --git a/packages/geom/src/ctors/triangle.ts b/packages/geom/src/ctors/triangle.ts index 55cc9b0e9c..d24312f251 100644 --- a/packages/geom/src/ctors/triangle.ts +++ b/packages/geom/src/ctors/triangle.ts @@ -6,7 +6,7 @@ import { perpendicularLeft2, sub2, Vec -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { Attribs, Triangle } from "../api"; import { argAttribs } from "../internal/args"; diff --git a/packages/geom/src/internal/arc-point.ts b/packages/geom/src/internal/arc-point.ts index 63a7df49e2..0986f8113c 100644 --- a/packages/geom/src/internal/arc-point.ts +++ b/packages/geom/src/internal/arc-point.ts @@ -5,7 +5,7 @@ import { ReadonlyVec, rotateZ, Vec -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; export const arcPointAt = ( pos: ReadonlyVec, diff --git a/packages/geom/src/internal/barycentric.ts b/packages/geom/src/internal/barycentric.ts index 6e756627f9..0d31c5462a 100644 --- a/packages/geom/src/internal/barycentric.ts +++ b/packages/geom/src/internal/barycentric.ts @@ -6,7 +6,7 @@ import { setC3, sub, Vec -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; export const toBarycentric = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, p: ReadonlyVec, out: Vec = []) => { diff --git a/packages/geom/src/internal/bounds.ts b/packages/geom/src/internal/bounds.ts index fa3e198284..b4060e4349 100644 --- a/packages/geom/src/internal/bounds.ts +++ b/packages/geom/src/internal/bounds.ts @@ -1,13 +1,13 @@ import { Fn } from "@thi.ng/api"; import { clamp01, mixCubic as _mixCubic } from "@thi.ng/math"; -import { max, min, Vec } from "@thi.ng/vectors3"; +import { max, min, Vec } from "@thi.ng/vectors"; import { max2, max3, min2, min3, ReadonlyVec -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { VecPair } from "../api"; import { AABBLike, IShape } from "../api"; import { unionBounds } from "./union-bounds"; @@ -15,7 +15,7 @@ import { unionBounds } from "./union-bounds"; /** * Computes the nD bounds of given vectors. `vmin` should be initialized * to `+Infinity` and `vmax` to `-Infinity` (e.g. use copies of `MIN*` / - * `MAX*` constants defined in thi.ng/vectors3). + * `MAX*` constants defined in thi.ng/vectors). * * Returns 2-tuple of modified `[vmin, vmax]`. * diff --git a/packages/geom/src/internal/centroid.ts b/packages/geom/src/internal/centroid.ts index cffe402581..bdb15b9a1d 100644 --- a/packages/geom/src/internal/centroid.ts +++ b/packages/geom/src/internal/centroid.ts @@ -5,7 +5,7 @@ import { empty, ReadonlyVec, Vec -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; export const centroidRaw = (pts: ReadonlyVec[], out?: Vec) => { diff --git a/packages/geom/src/internal/circumcenter.ts b/packages/geom/src/internal/circumcenter.ts index a5ccca08c7..ddb8986c7c 100644 --- a/packages/geom/src/internal/circumcenter.ts +++ b/packages/geom/src/internal/circumcenter.ts @@ -1,5 +1,5 @@ import { EPS } from "@thi.ng/math"; -import { ReadonlyVec } from "@thi.ng/vectors3"; +import { ReadonlyVec } from "@thi.ng/vectors"; export const circumCenter = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, eps = EPS) => { diff --git a/packages/geom/src/internal/clockwise.ts b/packages/geom/src/internal/clockwise.ts index 13dbf51623..a19299b57f 100644 --- a/packages/geom/src/internal/clockwise.ts +++ b/packages/geom/src/internal/clockwise.ts @@ -1,4 +1,4 @@ -import { ReadonlyVec, signedArea2 } from "@thi.ng/vectors3"; +import { ReadonlyVec, signedArea2 } from "@thi.ng/vectors"; export const clockwise2 = (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec) => diff --git a/packages/geom/src/internal/closest-point.ts b/packages/geom/src/internal/closest-point.ts index 55b6e149ff..dfe42ced2c 100644 --- a/packages/geom/src/internal/closest-point.ts +++ b/packages/geom/src/internal/closest-point.ts @@ -13,7 +13,7 @@ import { set, sub, Vec -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { arcPointAtTheta } from "./arc-point"; export const closestPointArray = diff --git a/packages/geom/src/internal/collate.ts b/packages/geom/src/internal/collate.ts index 7a3d47726f..4de74bc651 100644 --- a/packages/geom/src/internal/collate.ts +++ b/packages/geom/src/internal/collate.ts @@ -1,4 +1,4 @@ -import { Vec, StridedVec } from "@thi.ng/vectors3"; +import { Vec, StridedVec } from "@thi.ng/vectors"; export interface CollateOpts { buf: Vec; diff --git a/packages/geom/src/internal/copy-points.ts b/packages/geom/src/internal/copy-points.ts index 6fab8e9922..619e082842 100644 --- a/packages/geom/src/internal/copy-points.ts +++ b/packages/geom/src/internal/copy-points.ts @@ -1,4 +1,4 @@ -import { ReadonlyVec, set } from "@thi.ng/vectors3"; +import { ReadonlyVec, set } from "@thi.ng/vectors"; export const copyPoints = (pts: ReadonlyVec[]) => pts.map((p) => set([], p)); diff --git a/packages/geom/src/internal/corner.ts b/packages/geom/src/internal/corner.ts index cfea7cf3d1..5bee360c37 100644 --- a/packages/geom/src/internal/corner.ts +++ b/packages/geom/src/internal/corner.ts @@ -1,5 +1,5 @@ import { EPS, sign } from "@thi.ng/math"; -import { ReadonlyVec, signedArea2 } from "@thi.ng/vectors3"; +import { ReadonlyVec, signedArea2 } from "@thi.ng/vectors"; /** * Syntax sugar for `sign(signedArea2(a,b,c))`. diff --git a/packages/geom/src/internal/direction.ts b/packages/geom/src/internal/direction.ts index 9c521ab5d0..50c1ed205e 100644 --- a/packages/geom/src/internal/direction.ts +++ b/packages/geom/src/internal/direction.ts @@ -4,7 +4,7 @@ import { perpendicularRight2, ReadonlyVec, sub -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; export const direction = (a: ReadonlyVec, b: ReadonlyVec, n = 1) => diff --git "a/packages/geom/src/internal/douglas\342\200\223peucker.ts" "b/packages/geom/src/internal/douglas\342\200\223peucker.ts" index 3051fc747d..fe57791efb 100644 --- "a/packages/geom/src/internal/douglas\342\200\223peucker.ts" +++ "b/packages/geom/src/internal/douglas\342\200\223peucker.ts" @@ -1,6 +1,6 @@ import { EPS } from "@thi.ng/math"; import { peek } from "@thi.ng/transducers"; -import { eqDelta, Vec } from "@thi.ng/vectors3"; +import { eqDelta, Vec } from "@thi.ng/vectors"; import { farthestPointSegment } from "./closest-point"; // https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm diff --git a/packages/geom/src/internal/edges.ts b/packages/geom/src/internal/edges.ts index b8b21d2b92..7885d613ec 100644 --- a/packages/geom/src/internal/edges.ts +++ b/packages/geom/src/internal/edges.ts @@ -1,5 +1,5 @@ import { partition, wrap } from "@thi.ng/transducers"; -import { ReadonlyVec } from "@thi.ng/vectors3"; +import { ReadonlyVec } from "@thi.ng/vectors"; import { VecPair } from "../api"; export const edgeIterator = diff --git a/packages/geom/src/internal/graham-scan.ts b/packages/geom/src/internal/graham-scan.ts index 76ede164c0..dabb288107 100644 --- a/packages/geom/src/internal/graham-scan.ts +++ b/packages/geom/src/internal/graham-scan.ts @@ -1,5 +1,5 @@ import { EPS } from "@thi.ng/math"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors"; /** * Returns array of points defining the 2D Convex Hull of `pts` using @@ -52,7 +52,7 @@ export const grahamScan2 = * Returns true, if triangle defined by ABC is NOT counter clockwise, * i.e. clockwise or colinear. * - * @see thi.ng/vectors3/signedArea2 + * @see thi.ng/vectors/signedArea2 * * @param ax * @param ay diff --git a/packages/geom/src/internal/liang-barsky.ts b/packages/geom/src/internal/liang-barsky.ts index f30ffcc3da..8caa3e02c0 100644 --- a/packages/geom/src/internal/liang-barsky.ts +++ b/packages/geom/src/internal/liang-barsky.ts @@ -1,5 +1,5 @@ import { EPS } from "@thi.ng/math"; -import { Vec } from "@thi.ng/vectors3"; +import { Vec } from "@thi.ng/vectors"; /** * Performs Liang-Barsky clipping with given line endpoints `la`, `lb` diff --git a/packages/geom/src/internal/point-in-array.ts b/packages/geom/src/internal/point-in-array.ts index 08caa22f43..28f6683105 100644 --- a/packages/geom/src/internal/point-in-array.ts +++ b/packages/geom/src/internal/point-in-array.ts @@ -1,5 +1,5 @@ import { EPS } from "@thi.ng/math"; -import { eqDelta, ReadonlyVec } from "@thi.ng/vectors3"; +import { eqDelta, ReadonlyVec } from "@thi.ng/vectors"; export const pointInArray = (points: ReadonlyVec[], p: ReadonlyVec, eps = EPS) => { diff --git a/packages/geom/src/internal/poly-arc-length.ts b/packages/geom/src/internal/poly-arc-length.ts index bbf27764d3..83405f5f09 100644 --- a/packages/geom/src/internal/poly-arc-length.ts +++ b/packages/geom/src/internal/poly-arc-length.ts @@ -1,4 +1,4 @@ -import { ReadonlyVec, dist } from "@thi.ng/vectors3"; +import { ReadonlyVec, dist } from "@thi.ng/vectors"; export const polyArcLength = (pts: ReadonlyVec[], num = pts.length, closed = false) => { diff --git a/packages/geom/src/internal/poly-area.ts b/packages/geom/src/internal/poly-area.ts index ed09f0e527..197f9c19fa 100644 --- a/packages/geom/src/internal/poly-area.ts +++ b/packages/geom/src/internal/poly-area.ts @@ -1,4 +1,4 @@ -import { cross2, ReadonlyVec } from "@thi.ng/vectors3"; +import { cross2, ReadonlyVec } from "@thi.ng/vectors"; /** * Interprets given points as closed 2D polygon and computes signed diff --git a/packages/geom/src/internal/poly-centroid.ts b/packages/geom/src/internal/poly-centroid.ts index fc7800e277..7479b496ac 100644 --- a/packages/geom/src/internal/poly-centroid.ts +++ b/packages/geom/src/internal/poly-centroid.ts @@ -1,4 +1,4 @@ -import { cross2, ReadonlyVec, Vec } from "@thi.ng/vectors3"; +import { cross2, ReadonlyVec, Vec } from "@thi.ng/vectors"; export const polyCentroid = (pts: ReadonlyVec[], c: Vec = []) => { diff --git a/packages/geom/src/internal/poly-point-inside.ts b/packages/geom/src/internal/poly-point-inside.ts index d8c0f96f07..d90a2af5a4 100644 --- a/packages/geom/src/internal/poly-point-inside.ts +++ b/packages/geom/src/internal/poly-point-inside.ts @@ -1,4 +1,4 @@ -import { ReadonlyVec } from "@thi.ng/vectors3"; +import { ReadonlyVec } from "@thi.ng/vectors"; export const polyPointInside = (pts: ReadonlyVec[], { 0: px, 1: py }: ReadonlyVec) => { diff --git a/packages/geom/src/internal/sampler.ts b/packages/geom/src/internal/sampler.ts index ef377963f0..88e8fc69af 100644 --- a/packages/geom/src/internal/sampler.ts +++ b/packages/geom/src/internal/sampler.ts @@ -10,7 +10,7 @@ import { eqDelta, set, distSq -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { DEFAULT_SAMPLES, SamplingOpts, VecPair } from "../api"; import { copyPoints } from "./copy-points"; import { closestPointSegment, closestCoeff } from "./closest-point"; diff --git a/packages/geom/src/internal/split.ts b/packages/geom/src/internal/split.ts index f8bc9940df..a8400c0b1e 100644 --- a/packages/geom/src/internal/split.ts +++ b/packages/geom/src/internal/split.ts @@ -1,4 +1,4 @@ -import { mixN, set, Vec, ReadonlyVec, mixCubic, mixQuadratic } from "@thi.ng/vectors3"; +import { mixN, set, Vec, ReadonlyVec, mixCubic, mixQuadratic } from "@thi.ng/vectors"; import { VecPair } from "../api"; import { partial } from "@thi.ng/compose"; import { findClosestT } from "./closest-point"; diff --git a/packages/geom/src/internal/subdiv-curve.ts b/packages/geom/src/internal/subdiv-curve.ts index c7c669a2c6..d0cf194d86 100644 --- a/packages/geom/src/internal/subdiv-curve.ts +++ b/packages/geom/src/internal/subdiv-curve.ts @@ -12,7 +12,7 @@ import { addW5, ReadonlyVec, Vec -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { SubdivKernel } from "../api"; export const subdivKernel2 = diff --git a/packages/geom/src/internal/sutherland-hodgeman.ts b/packages/geom/src/internal/sutherland-hodgeman.ts index 967481a32e..48e3d15ef2 100644 --- a/packages/geom/src/internal/sutherland-hodgeman.ts +++ b/packages/geom/src/internal/sutherland-hodgeman.ts @@ -1,4 +1,4 @@ -import { ReadonlyVec } from "@thi.ng/vectors3"; +import { ReadonlyVec } from "@thi.ng/vectors"; import { corner } from "./corner"; import { intersectLineLine } from "../isec/line-line"; diff --git a/packages/geom/src/internal/tessellate.ts b/packages/geom/src/internal/tessellate.ts index 50055afe98..ee68e24c15 100644 --- a/packages/geom/src/internal/tessellate.ts +++ b/packages/geom/src/internal/tessellate.ts @@ -19,7 +19,7 @@ import { ReadonlyVec, signedArea2, Vec -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { Tessellator } from "../api"; import { centroidRaw } from "../internal/centroid"; import { pointInTriangle2 } from "../internal/triangle-point-inside"; diff --git a/packages/geom/src/internal/transform-points.ts b/packages/geom/src/internal/transform-points.ts index 5a093f95e3..21b6988e7b 100644 --- a/packages/geom/src/internal/transform-points.ts +++ b/packages/geom/src/internal/transform-points.ts @@ -1,5 +1,5 @@ import { mulV, ReadonlyMat } from "@thi.ng/matrices"; -import { ReadonlyVec } from "@thi.ng/vectors3"; +import { ReadonlyVec } from "@thi.ng/vectors"; export const transformPoints = (pts: ReadonlyVec[], mat: ReadonlyMat) => diff --git a/packages/geom/src/internal/translate-points.ts b/packages/geom/src/internal/translate-points.ts index 760bab4290..946768b7ef 100644 --- a/packages/geom/src/internal/translate-points.ts +++ b/packages/geom/src/internal/translate-points.ts @@ -1,4 +1,4 @@ -import { add, ReadonlyVec } from "@thi.ng/vectors3"; +import { add, ReadonlyVec } from "@thi.ng/vectors"; export const translatedPoints = (pts: ReadonlyVec[], delta: ReadonlyVec) => diff --git a/packages/geom/src/internal/triangle-point-inside.ts b/packages/geom/src/internal/triangle-point-inside.ts index 1047c3c290..b959efb9cb 100644 --- a/packages/geom/src/internal/triangle-point-inside.ts +++ b/packages/geom/src/internal/triangle-point-inside.ts @@ -1,5 +1,5 @@ import { EPS, sign } from "@thi.ng/math"; -import { ReadonlyVec, signedArea2 } from "@thi.ng/vectors3"; +import { ReadonlyVec, signedArea2 } from "@thi.ng/vectors"; import { clockwise2 } from "./clockwise"; export const classifyPointInTriangle2 = diff --git a/packages/geom/src/internal/union-bounds.ts b/packages/geom/src/internal/union-bounds.ts index d396dcd0d3..d0dd42cb08 100644 --- a/packages/geom/src/internal/union-bounds.ts +++ b/packages/geom/src/internal/union-bounds.ts @@ -4,7 +4,7 @@ import { min, ReadonlyVec, sub -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { VecPair } from "../api"; /** diff --git a/packages/geom/src/isec/circle-circle.ts b/packages/geom/src/isec/circle-circle.ts index 3057af4433..548285d71d 100644 --- a/packages/geom/src/isec/circle-circle.ts +++ b/packages/geom/src/isec/circle-circle.ts @@ -1,4 +1,4 @@ -import { ReadonlyVec, distSq, mag, sub, maddN, perpendicularLeft2, mulN, add } from "@thi.ng/vectors3"; +import { ReadonlyVec, distSq, mag, sub, maddN, perpendicularLeft2, mulN, add } from "@thi.ng/vectors"; import { eqDeltaFixed } from "@thi.ng/math"; import { IntersectionType } from "../api"; diff --git a/packages/geom/src/isec/line-line.ts b/packages/geom/src/isec/line-line.ts index d9dd2b3c6e..9ce5f369c6 100644 --- a/packages/geom/src/isec/line-line.ts +++ b/packages/geom/src/isec/line-line.ts @@ -1,5 +1,5 @@ import { EPS, eqDeltaFixed } from "@thi.ng/math"; -import { mixN2, ReadonlyVec } from "@thi.ng/vectors3"; +import { mixN2, ReadonlyVec } from "@thi.ng/vectors"; import { IntersectionType, LineIntersection } from "../api"; import { closestPointSegment } from "../internal/closest-point"; diff --git a/packages/geom/src/isec/ray-circle.ts b/packages/geom/src/isec/ray-circle.ts index cb34004ed2..4094683e31 100644 --- a/packages/geom/src/isec/ray-circle.ts +++ b/packages/geom/src/isec/ray-circle.ts @@ -1,4 +1,4 @@ -import { sub, dot, magSq, maddN, ReadonlyVec } from "@thi.ng/vectors3"; +import { sub, dot, magSq, maddN, ReadonlyVec } from "@thi.ng/vectors"; export const intersectRayCircle = (rpos: ReadonlyVec, dir: ReadonlyVec, spos: ReadonlyVec, r: number) => { diff --git a/packages/geom/src/isec/ray-line.ts b/packages/geom/src/isec/ray-line.ts index ce8ae58dd8..e5ff243470 100644 --- a/packages/geom/src/isec/ray-line.ts +++ b/packages/geom/src/isec/ray-line.ts @@ -1,5 +1,5 @@ import { eqDeltaFixed } from "@thi.ng/math"; -import { ReadonlyVec } from "@thi.ng/vectors3"; +import { ReadonlyVec } from "@thi.ng/vectors"; export const intersectRayLine = (rpos: ReadonlyVec, dir: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec) => { diff --git a/packages/geom/src/isec/ray-poly.ts b/packages/geom/src/isec/ray-poly.ts index 4604f129ed..c9ef8134b2 100644 --- a/packages/geom/src/isec/ray-poly.ts +++ b/packages/geom/src/isec/ray-poly.ts @@ -1,4 +1,4 @@ -import { maddN2, ReadonlyVec } from "@thi.ng/vectors3"; +import { maddN2, ReadonlyVec } from "@thi.ng/vectors"; import { IntersectionType } from "../api"; import { intersectRayLine } from "./ray-line"; diff --git a/packages/geom/src/ops/arc-length.ts b/packages/geom/src/ops/arc-length.ts index 57d1a5ac65..2f273f03fe 100644 --- a/packages/geom/src/ops/arc-length.ts +++ b/packages/geom/src/ops/arc-length.ts @@ -1,6 +1,6 @@ import { defmulti, MultiFn1 } from "@thi.ng/defmulti"; import { PI, TAU } from "@thi.ng/math"; -import { dist } from "@thi.ng/vectors3"; +import { dist } from "@thi.ng/vectors"; import { Circle, Ellipse, diff --git a/packages/geom/src/ops/area.ts b/packages/geom/src/ops/area.ts index 4488a574fc..844c0dc648 100644 --- a/packages/geom/src/ops/area.ts +++ b/packages/geom/src/ops/area.ts @@ -1,6 +1,6 @@ import { defmulti, MultiFn1O } from "@thi.ng/defmulti"; import { PI } from "@thi.ng/math"; -import { signedArea2, Vec } from "@thi.ng/vectors3"; +import { signedArea2, Vec } from "@thi.ng/vectors"; import { AABB, Circle, diff --git a/packages/geom/src/ops/as-cubic.ts b/packages/geom/src/ops/as-cubic.ts index a22a452a5e..766c6c5086 100644 --- a/packages/geom/src/ops/as-cubic.ts +++ b/packages/geom/src/ops/as-cubic.ts @@ -6,7 +6,7 @@ import { sincos } from "@thi.ng/math"; import { mapcat } from "@thi.ng/transducers"; -import { add2, magSq2 } from "@thi.ng/vectors3"; +import { add2, magSq2 } from "@thi.ng/vectors"; import { Arc, Cubic, diff --git a/packages/geom/src/ops/bounds.ts b/packages/geom/src/ops/bounds.ts index f6a1072daf..477a3eccf7 100644 --- a/packages/geom/src/ops/bounds.ts +++ b/packages/geom/src/ops/bounds.ts @@ -20,7 +20,7 @@ import { sub2, subN2, Vec -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { AABBLike, Arc, diff --git a/packages/geom/src/ops/center.ts b/packages/geom/src/ops/center.ts index 8c5884736e..4f7efec67b 100644 --- a/packages/geom/src/ops/center.ts +++ b/packages/geom/src/ops/center.ts @@ -6,7 +6,7 @@ import { submN, ZERO2, ZERO3 -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { Arc, Circle, diff --git a/packages/geom/src/ops/centroid.ts b/packages/geom/src/ops/centroid.ts index eb5625704c..8781fd4187 100644 --- a/packages/geom/src/ops/centroid.ts +++ b/packages/geom/src/ops/centroid.ts @@ -6,7 +6,7 @@ import { mixN, set, Vec -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { AABBLike, Circle, diff --git a/packages/geom/src/ops/classify-point.ts b/packages/geom/src/ops/classify-point.ts index d35efcae38..6c0b28b2f2 100644 --- a/packages/geom/src/ops/classify-point.ts +++ b/packages/geom/src/ops/classify-point.ts @@ -1,6 +1,6 @@ import { defmulti, MultiFn2O } from "@thi.ng/defmulti"; import { EPS, sign } from "@thi.ng/math"; -import { ReadonlyVec, distSq } from "@thi.ng/vectors3"; +import { ReadonlyVec, distSq } from "@thi.ng/vectors"; import { Circle, IShape, Type, Triangle } from "../api"; import { dispatch } from "../internal/dispatch"; import { classifyPointInTriangle2 } from "../internal/triangle-point-inside"; diff --git a/packages/geom/src/ops/closest-point.ts b/packages/geom/src/ops/closest-point.ts index ea75b47d0d..0817e4963a 100644 --- a/packages/geom/src/ops/closest-point.ts +++ b/packages/geom/src/ops/closest-point.ts @@ -6,7 +6,7 @@ import { set, sub, Vec -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { Arc, Circle, diff --git a/packages/geom/src/ops/fit-into-bounds.ts b/packages/geom/src/ops/fit-into-bounds.ts index 0b55168cee..7ef4e0765b 100644 --- a/packages/geom/src/ops/fit-into-bounds.ts +++ b/packages/geom/src/ops/fit-into-bounds.ts @@ -4,7 +4,7 @@ import { scale23, translation23 } from "@thi.ng/matrices"; -import { div2, neg, ReadonlyVec } from "@thi.ng/vectors3"; +import { div2, neg, ReadonlyVec } from "@thi.ng/vectors"; import { IShape, Rect } from "../api"; import { collBounds } from "../internal/bounds"; import { bounds } from "./bounds"; diff --git a/packages/geom/src/ops/flip.ts b/packages/geom/src/ops/flip.ts index 9731cc3338..b1b3c19263 100644 --- a/packages/geom/src/ops/flip.ts +++ b/packages/geom/src/ops/flip.ts @@ -1,5 +1,5 @@ import { DEFAULT, defmulti } from "@thi.ng/defmulti"; -import { neg } from "@thi.ng/vectors3"; +import { neg } from "@thi.ng/vectors"; import { Arc, Group, diff --git a/packages/geom/src/ops/map-point.ts b/packages/geom/src/ops/map-point.ts index 60ea6bc072..7a03dc00c5 100644 --- a/packages/geom/src/ops/map-point.ts +++ b/packages/geom/src/ops/map-point.ts @@ -4,7 +4,7 @@ import { Vec, sub, div -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { IShape, Rect, Type } from "../api"; import { dispatch } from "../internal/dispatch"; diff --git a/packages/geom/src/ops/point-at.ts b/packages/geom/src/ops/point-at.ts index 1cf22cbd1b..3025afef8b 100644 --- a/packages/geom/src/ops/point-at.ts +++ b/packages/geom/src/ops/point-at.ts @@ -8,7 +8,7 @@ import { mixN2, mixQuadratic, Vec -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { Arc, Circle, diff --git a/packages/geom/src/ops/point-inside.ts b/packages/geom/src/ops/point-inside.ts index 9522738e51..a4086ef9ef 100644 --- a/packages/geom/src/ops/point-inside.ts +++ b/packages/geom/src/ops/point-inside.ts @@ -1,5 +1,5 @@ import { defmulti } from "@thi.ng/defmulti"; -import { distSq, ReadonlyVec, Vec } from "@thi.ng/vectors3"; +import { distSq, ReadonlyVec, Vec } from "@thi.ng/vectors"; import { AABB, Circle, diff --git a/packages/geom/src/ops/scatter.ts b/packages/geom/src/ops/scatter.ts index 72d9f79d66..45331f8991 100644 --- a/packages/geom/src/ops/scatter.ts +++ b/packages/geom/src/ops/scatter.ts @@ -1,5 +1,5 @@ import { IShape } from "../api"; -import { Vec, randMinMax } from "@thi.ng/vectors3"; +import { Vec, randMinMax } from "@thi.ng/vectors"; import { SYSTEM } from "@thi.ng/random"; import { bounds } from "./bounds"; import { pointInside } from "./point-inside"; diff --git a/packages/geom/src/ops/simplify.ts b/packages/geom/src/ops/simplify.ts index 26f5ee69a8..b623550177 100644 --- a/packages/geom/src/ops/simplify.ts +++ b/packages/geom/src/ops/simplify.ts @@ -1,6 +1,6 @@ import { defmulti } from "@thi.ng/defmulti"; import { peek } from "@thi.ng/transducers"; -import { Vec } from "@thi.ng/vectors3"; +import { Vec } from "@thi.ng/vectors"; import { IShape, Path, diff --git a/packages/geom/src/ops/split-at.ts b/packages/geom/src/ops/split-at.ts index a950cdce4f..ba7f1cc601 100644 --- a/packages/geom/src/ops/split-at.ts +++ b/packages/geom/src/ops/split-at.ts @@ -1,6 +1,6 @@ import { defmulti } from "@thi.ng/defmulti"; import { fit01 } from "@thi.ng/math"; -import { set } from "@thi.ng/vectors3"; +import { set } from "@thi.ng/vectors"; import { Arc, Cubic, diff --git a/packages/geom/src/ops/split-near.ts b/packages/geom/src/ops/split-near.ts index 6fbaeac2e2..51c08647b8 100644 --- a/packages/geom/src/ops/split-near.ts +++ b/packages/geom/src/ops/split-near.ts @@ -1,6 +1,6 @@ import { defmulti } from "@thi.ng/defmulti"; import { clamp01 } from "@thi.ng/math"; -import { ReadonlyVec } from "@thi.ng/vectors3"; +import { ReadonlyVec } from "@thi.ng/vectors"; import { Cubic, IShape, diff --git a/packages/geom/src/ops/subdiv-curve.ts b/packages/geom/src/ops/subdiv-curve.ts index 593ca0a08c..2ba9bf7416 100644 --- a/packages/geom/src/ops/subdiv-curve.ts +++ b/packages/geom/src/ops/subdiv-curve.ts @@ -1,6 +1,6 @@ import { defmulti, MultiFn2O } from "@thi.ng/defmulti"; import { wrap } from "@thi.ng/transducers"; -import { mixN, ReadonlyVec } from "@thi.ng/vectors3"; +import { mixN, ReadonlyVec } from "@thi.ng/vectors"; import { IShape, Polygon, diff --git a/packages/geom/src/ops/tangent-at.ts b/packages/geom/src/ops/tangent-at.ts index bfe6ec07b4..53c0d7b066 100644 --- a/packages/geom/src/ops/tangent-at.ts +++ b/packages/geom/src/ops/tangent-at.ts @@ -1,6 +1,6 @@ import { defmulti } from "@thi.ng/defmulti"; import { cossin, HALF_PI, TAU } from "@thi.ng/math"; -import { Vec } from "@thi.ng/vectors3"; +import { Vec } from "@thi.ng/vectors"; import { IShape, Line, diff --git a/packages/geom/src/ops/tessellate.ts b/packages/geom/src/ops/tessellate.ts index d87ac7a27c..966a207191 100644 --- a/packages/geom/src/ops/tessellate.ts +++ b/packages/geom/src/ops/tessellate.ts @@ -1,5 +1,5 @@ import { DEFAULT, defmulti } from "@thi.ng/defmulti"; -import { Vec } from "@thi.ng/vectors3"; +import { Vec } from "@thi.ng/vectors"; import { IShape, Tessellator } from "../api"; import { dispatch } from "../internal/dispatch"; import { tessellatePoints } from "../internal/tessellate"; diff --git a/packages/geom/src/ops/translate.ts b/packages/geom/src/ops/translate.ts index 107dfe6a73..a600ca716c 100644 --- a/packages/geom/src/ops/translate.ts +++ b/packages/geom/src/ops/translate.ts @@ -5,7 +5,7 @@ import { ReadonlyVec, set2, set3 -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { AABB, Arc, diff --git a/packages/geom/src/ops/unmap-point.ts b/packages/geom/src/ops/unmap-point.ts index e2f134315a..4f1750e7c2 100644 --- a/packages/geom/src/ops/unmap-point.ts +++ b/packages/geom/src/ops/unmap-point.ts @@ -4,7 +4,7 @@ import { mixBilinear, ReadonlyVec, Vec -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { IShape, Quad, diff --git a/packages/geom/src/ops/vertices.ts b/packages/geom/src/ops/vertices.ts index 967b54dec0..f56ef58e48 100644 --- a/packages/geom/src/ops/vertices.ts +++ b/packages/geom/src/ops/vertices.ts @@ -9,7 +9,7 @@ import { mixQuadratic, set2, Vec -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { Arc, Circle, diff --git a/packages/geom/src/ops/warp-points.ts b/packages/geom/src/ops/warp-points.ts index 414c5bd3a4..e5665fb95d 100644 --- a/packages/geom/src/ops/warp-points.ts +++ b/packages/geom/src/ops/warp-points.ts @@ -1,4 +1,4 @@ -import { ReadonlyVec, Vec } from "@thi.ng/vectors3"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors"; import { IShape } from "../api"; import { mapPoint } from "./map-point"; import { unmapPoint } from "./unmap-point"; diff --git a/packages/matrices/package.json b/packages/matrices/package.json index 855ec8ebc1..c7a3ac197a 100644 --- a/packages/matrices/package.json +++ b/packages/matrices/package.json @@ -16,7 +16,7 @@ "scripts": { "build": "yarn clean && yarn build:es6 && yarn build:bundle", "build:es6": "tsc --declaration", - "build:bundle": "../../scripts/bundle-module matrices api checks math vectors3", + "build:bundle": "../../scripts/bundle-module matrices api checks math vectors", "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", @@ -35,7 +35,7 @@ "@thi.ng/api": "^4.2.4", "@thi.ng/checks": "^1.5.14", "@thi.ng/math": "^0.2.2", - "@thi.ng/vectors3": "^0.0.1" + "@thi.ng/vectors": "^1.4.12" }, "keywords": [ "2D", diff --git a/packages/matrices/src/add.ts b/packages/matrices/src/add.ts index 914ba6b432..4a704f8eb7 100644 --- a/packages/matrices/src/add.ts +++ b/packages/matrices/src/add.ts @@ -1,4 +1,4 @@ -import { add as _add, add4 } from "@thi.ng/vectors3"; +import { add as _add, add4 } from "@thi.ng/vectors"; import { MatOpMM, MultiMatOpMM } from "./api"; import { defMath } from "./internal/codegen"; diff --git a/packages/matrices/src/addn.ts b/packages/matrices/src/addn.ts index ee1e8f954f..4b4da795bb 100644 --- a/packages/matrices/src/addn.ts +++ b/packages/matrices/src/addn.ts @@ -1,4 +1,4 @@ -import { addN as _addN, addN4 } from "@thi.ng/vectors3"; +import { addN as _addN, addN4 } from "@thi.ng/vectors"; import { MatOpMN, MultiMatOpMN } from "./api"; import { defMathN } from "./internal/codegen"; diff --git a/packages/matrices/src/alignment-quat.ts b/packages/matrices/src/alignment-quat.ts index e70bb85315..53ee7ca13a 100644 --- a/packages/matrices/src/alignment-quat.ts +++ b/packages/matrices/src/alignment-quat.ts @@ -4,7 +4,7 @@ import { mag, normalize as _normalize, ReadonlyVec -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { quatFromAxisAngle } from "./quat-axis-angle"; /** diff --git a/packages/matrices/src/api.ts b/packages/matrices/src/api.ts index a769b7959c..04b1fc68ba 100644 --- a/packages/matrices/src/api.ts +++ b/packages/matrices/src/api.ts @@ -1,4 +1,4 @@ -import { Vec, ReadonlyVec, IVector, MultiVecOp } from "@thi.ng/vectors3"; +import { Vec, ReadonlyVec, IVector, MultiVecOp } from "@thi.ng/vectors"; export type Mat = Vec; export type ReadonlyMat = ReadonlyVec; diff --git a/packages/matrices/src/column.ts b/packages/matrices/src/column.ts index 0d4db5d221..5d334c226e 100644 --- a/packages/matrices/src/column.ts +++ b/packages/matrices/src/column.ts @@ -3,7 +3,7 @@ import { setS3, setS4, vop -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { MultiVecOpMN, VecOpMN } from "./api"; /** diff --git a/packages/matrices/src/conjugate.ts b/packages/matrices/src/conjugate.ts index 2b28ca7532..bcc893ac42 100644 --- a/packages/matrices/src/conjugate.ts +++ b/packages/matrices/src/conjugate.ts @@ -1,4 +1,4 @@ -import { ReadonlyVec, setC4, Vec } from "@thi.ng/vectors3"; +import { ReadonlyVec, setC4, Vec } from "@thi.ng/vectors"; export const conjugateQ = (out: Vec, a: ReadonlyVec) => diff --git a/packages/matrices/src/determinant.ts b/packages/matrices/src/determinant.ts index 3eda23b170..5bec25d4f6 100644 --- a/packages/matrices/src/determinant.ts +++ b/packages/matrices/src/determinant.ts @@ -1,4 +1,4 @@ -import { dotC4, dotC6 } from "@thi.ng/vectors3"; +import { dotC4, dotC6 } from "@thi.ng/vectors"; import { ReadonlyMat } from "./api"; const dp4 = dotC4; diff --git a/packages/matrices/src/diag.ts b/packages/matrices/src/diag.ts index cc01ebc051..46ff4affc3 100644 --- a/packages/matrices/src/diag.ts +++ b/packages/matrices/src/diag.ts @@ -1,4 +1,4 @@ -import { vop, setS2, setS3, setS4 } from "@thi.ng/vectors3"; +import { vop, setS2, setS3, setS4 } from "@thi.ng/vectors"; import { MultiVecOpM } from "./api"; /** diff --git a/packages/matrices/src/div.ts b/packages/matrices/src/div.ts index 405f54cc7d..3174d93880 100644 --- a/packages/matrices/src/div.ts +++ b/packages/matrices/src/div.ts @@ -1,4 +1,4 @@ -import { div as _div, div4 } from "@thi.ng/vectors3"; +import { div as _div, div4 } from "@thi.ng/vectors"; import { MatOpMM, MultiMatOpMM } from "./api"; import { defMath } from "./internal/codegen"; diff --git a/packages/matrices/src/divn.ts b/packages/matrices/src/divn.ts index cf34f6bd6b..244a36b3d9 100644 --- a/packages/matrices/src/divn.ts +++ b/packages/matrices/src/divn.ts @@ -1,4 +1,4 @@ -import { divN as _divN, divN4 } from "@thi.ng/vectors3"; +import { divN as _divN, divN4 } from "@thi.ng/vectors"; import { MatOpMN, MultiMatOpMN } from "./api"; import { defMathN } from "./internal/codegen"; diff --git a/packages/matrices/src/frustum.ts b/packages/matrices/src/frustum.ts index c84e7310d9..59d273fc5d 100644 --- a/packages/matrices/src/frustum.ts +++ b/packages/matrices/src/frustum.ts @@ -1,5 +1,5 @@ import { DEG2RAD } from "@thi.ng/math"; -import { setC } from "@thi.ng/vectors3"; +import { setC } from "@thi.ng/vectors"; import { Mat } from "./api"; /** diff --git a/packages/matrices/src/identity.ts b/packages/matrices/src/identity.ts index 734de8e481..406a42610d 100644 --- a/packages/matrices/src/identity.ts +++ b/packages/matrices/src/identity.ts @@ -1,4 +1,4 @@ -import { vop } from "@thi.ng/vectors3"; +import { vop } from "@thi.ng/vectors"; import { IDENT22, IDENT23, diff --git a/packages/matrices/src/internal/codegen.ts b/packages/matrices/src/internal/codegen.ts index b94cf8e38d..c6436e5528 100644 --- a/packages/matrices/src/internal/codegen.ts +++ b/packages/matrices/src/internal/codegen.ts @@ -5,7 +5,7 @@ import { DEFAULT_OUT, MATH, MATH_N -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { MultiMatOpMM, MultiMatOpMN } from "../api"; const DEFAULT_SIZES = [6, 9, 16]; diff --git a/packages/matrices/src/invert.ts b/packages/matrices/src/invert.ts index 72128a32ee..7085e37457 100644 --- a/packages/matrices/src/invert.ts +++ b/packages/matrices/src/invert.ts @@ -8,7 +8,7 @@ import { setC6, Vec, vop -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { MatOpM, MultiMatOpM } from "./api"; import { det44FromCoeffs, detCoeffs44 } from "./determinant"; diff --git a/packages/matrices/src/lookat.ts b/packages/matrices/src/lookat.ts index f806c98bca..e1eb49f9f4 100644 --- a/packages/matrices/src/lookat.ts +++ b/packages/matrices/src/lookat.ts @@ -5,7 +5,7 @@ import { ReadonlyVec, setC, sub3 -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { Mat } from "./api"; /** diff --git a/packages/matrices/src/m22-m23.ts b/packages/matrices/src/m22-m23.ts index 5df4b293eb..c35b2a4ac2 100644 --- a/packages/matrices/src/m22-m23.ts +++ b/packages/matrices/src/m22-m23.ts @@ -1,4 +1,4 @@ -import { set4 } from "@thi.ng/vectors3"; +import { set4 } from "@thi.ng/vectors"; import { MatOpM } from "./api"; /** diff --git a/packages/matrices/src/m23-m22.ts b/packages/matrices/src/m23-m22.ts index 16bd1b8285..d2e7b0f2b2 100644 --- a/packages/matrices/src/m23-m22.ts +++ b/packages/matrices/src/m23-m22.ts @@ -1,4 +1,4 @@ -import { set4 } from "@thi.ng/vectors3"; +import { set4 } from "@thi.ng/vectors"; import { MatOpM } from "./api"; /** diff --git a/packages/matrices/src/m33-m44.ts b/packages/matrices/src/m33-m44.ts index fd8a8896ad..fb5863b65b 100644 --- a/packages/matrices/src/m33-m44.ts +++ b/packages/matrices/src/m33-m44.ts @@ -1,4 +1,4 @@ -import { setS3, setS4, ZERO4 } from "@thi.ng/vectors3"; +import { setS3, setS4, ZERO4 } from "@thi.ng/vectors"; import { MatOpM } from "./api"; /** diff --git a/packages/matrices/src/m44-m33.ts b/packages/matrices/src/m44-m33.ts index 09e8d8c42e..4185a2e036 100644 --- a/packages/matrices/src/m44-m33.ts +++ b/packages/matrices/src/m44-m33.ts @@ -1,4 +1,4 @@ -import { setS3 } from "@thi.ng/vectors3"; +import { setS3 } from "@thi.ng/vectors"; import { MatOpM } from "./api"; /** diff --git a/packages/matrices/src/mixq.ts b/packages/matrices/src/mixq.ts index 4f93f96b2e..1aac7433a7 100644 --- a/packages/matrices/src/mixq.ts +++ b/packages/matrices/src/mixq.ts @@ -5,7 +5,7 @@ import { ReadonlyVec, set4, Vec -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; /** * Interpolates quaternion `a` to `b` by given amount `t`, using SLERP. diff --git a/packages/matrices/src/mul.ts b/packages/matrices/src/mul.ts index 047f8f50d9..c9fe8fbca6 100644 --- a/packages/matrices/src/mul.ts +++ b/packages/matrices/src/mul.ts @@ -1,4 +1,4 @@ -import { mul as _mul, mul4 } from "@thi.ng/vectors3"; +import { mul as _mul, mul4 } from "@thi.ng/vectors"; import { MatOpMM, MultiMatOpMM } from "./api"; import { defMath } from "./internal/codegen"; diff --git a/packages/matrices/src/mulm.ts b/packages/matrices/src/mulm.ts index 65880d34b9..f7ba591fd0 100644 --- a/packages/matrices/src/mulm.ts +++ b/packages/matrices/src/mulm.ts @@ -6,7 +6,7 @@ import { setC4, setC6, vop -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { MultiMatOpMM } from "./api"; /** diff --git a/packages/matrices/src/muln.ts b/packages/matrices/src/muln.ts index 8c21724e5e..72b7224ce9 100644 --- a/packages/matrices/src/muln.ts +++ b/packages/matrices/src/muln.ts @@ -1,4 +1,4 @@ -import { mulN as _mulN, mulN4 } from "@thi.ng/vectors3"; +import { mulN as _mulN, mulN4 } from "@thi.ng/vectors"; import { MatOpMN, MultiMatOpMN } from "./api"; import { defMathN } from "./internal/codegen"; diff --git a/packages/matrices/src/mulq.ts b/packages/matrices/src/mulq.ts index 81e48eafcc..d3841f4d9b 100644 --- a/packages/matrices/src/mulq.ts +++ b/packages/matrices/src/mulq.ts @@ -1,4 +1,4 @@ -import { ReadonlyVec, setC4, Vec } from "@thi.ng/vectors3"; +import { ReadonlyVec, setC4, Vec } from "@thi.ng/vectors"; /** * Performs quaternion multiplication of `a` and `b` and writes result diff --git a/packages/matrices/src/mulv.ts b/packages/matrices/src/mulv.ts index 16ee80de8d..c145b2338c 100644 --- a/packages/matrices/src/mulv.ts +++ b/packages/matrices/src/mulv.ts @@ -8,7 +8,7 @@ import { setC4, Vec, vop -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { MatOpMV, MultiMatOpMV } from "./api"; /** diff --git a/packages/matrices/src/ortho.ts b/packages/matrices/src/ortho.ts index 00836ba568..e9567572ca 100644 --- a/packages/matrices/src/ortho.ts +++ b/packages/matrices/src/ortho.ts @@ -1,4 +1,4 @@ -import { setC } from "@thi.ng/vectors3"; +import { setC } from "@thi.ng/vectors"; import { Mat } from "./api"; /** diff --git a/packages/matrices/src/project.ts b/packages/matrices/src/project.ts index b2786f9c82..2281004a21 100644 --- a/packages/matrices/src/project.ts +++ b/packages/matrices/src/project.ts @@ -4,7 +4,7 @@ import { fromHomogeneous4, ReadonlyVec, Vec -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { ReadonlyMat } from "./api"; import { invert23, invert44 } from "./invert"; import { mulV23, mulV344, mulV44 } from "./mulv"; diff --git a/packages/matrices/src/quat-axis-angle.ts b/packages/matrices/src/quat-axis-angle.ts index 97a32f2d2f..a0d6215dd0 100644 --- a/packages/matrices/src/quat-axis-angle.ts +++ b/packages/matrices/src/quat-axis-angle.ts @@ -1,5 +1,5 @@ import { EPS } from "@thi.ng/math"; -import { normalize, ReadonlyVec } from "@thi.ng/vectors3"; +import { normalize, ReadonlyVec } from "@thi.ng/vectors"; /** * Computes a quaternion representing the rotation `theta` around diff --git a/packages/matrices/src/quat-euler.ts b/packages/matrices/src/quat-euler.ts index 2c12feebc7..8a9227efd2 100644 --- a/packages/matrices/src/quat-euler.ts +++ b/packages/matrices/src/quat-euler.ts @@ -1,4 +1,4 @@ -import { X3, Y3, Z3 } from "@thi.ng/vectors3"; +import { X3, Y3, Z3 } from "@thi.ng/vectors"; import { mulQ } from "./mulq"; import { quatFromAxisAngle } from "./quat-axis-angle"; diff --git a/packages/matrices/src/quat-m33.ts b/packages/matrices/src/quat-m33.ts index 22a4ac6e5a..e28d1a7a6f 100644 --- a/packages/matrices/src/quat-m33.ts +++ b/packages/matrices/src/quat-m33.ts @@ -1,4 +1,4 @@ -import { ReadonlyVec, setC, Vec } from "@thi.ng/vectors3"; +import { ReadonlyVec, setC, Vec } from "@thi.ng/vectors"; /** * Converts quaternion into M33 and writes result to `out`. diff --git a/packages/matrices/src/quat-m44.ts b/packages/matrices/src/quat-m44.ts index 3cfe60f23b..9b95a8c35e 100644 --- a/packages/matrices/src/quat-m44.ts +++ b/packages/matrices/src/quat-m44.ts @@ -3,7 +3,7 @@ import { setC, Vec, ZERO3 -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; /** * Converts quaternion into M44 with optional translation offset `t`, diff --git a/packages/matrices/src/rotation-around-axis.ts b/packages/matrices/src/rotation-around-axis.ts index cf7d134e61..eca484859d 100644 --- a/packages/matrices/src/rotation-around-axis.ts +++ b/packages/matrices/src/rotation-around-axis.ts @@ -1,4 +1,4 @@ -import { normalize as _normalize, ReadonlyVec, setC } from "@thi.ng/vectors3"; +import { normalize as _normalize, ReadonlyVec, setC } from "@thi.ng/vectors"; import { Mat } from "./api"; import { mat33to44 } from "./m33-m44"; diff --git a/packages/matrices/src/rotation.ts b/packages/matrices/src/rotation.ts index 57db32b88e..d2f75545a2 100644 --- a/packages/matrices/src/rotation.ts +++ b/packages/matrices/src/rotation.ts @@ -1,5 +1,5 @@ import { sincos } from "@thi.ng/math"; -import { setC, setC4, setC6 } from "@thi.ng/vectors3"; +import { setC, setC4, setC6 } from "@thi.ng/vectors"; import { Mat } from "./api"; /** diff --git a/packages/matrices/src/row.ts b/packages/matrices/src/row.ts index df5344a440..c15c8621c4 100644 --- a/packages/matrices/src/row.ts +++ b/packages/matrices/src/row.ts @@ -3,7 +3,7 @@ import { setS3, setS4, vop -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { MultiVecOpMN } from "./api"; /** diff --git a/packages/matrices/src/scale-center.ts b/packages/matrices/src/scale-center.ts index 012cdef0cd..97a5098dc5 100644 --- a/packages/matrices/src/scale-center.ts +++ b/packages/matrices/src/scale-center.ts @@ -1,4 +1,4 @@ -import { neg, ReadonlyVec } from "@thi.ng/vectors3"; +import { neg, ReadonlyVec } from "@thi.ng/vectors"; import { Mat } from "./api"; import { concat } from "./concat"; import { scale23, scale44 } from "./scale"; diff --git a/packages/matrices/src/scale.ts b/packages/matrices/src/scale.ts index 2e1baf9709..f66d91c6ee 100644 --- a/packages/matrices/src/scale.ts +++ b/packages/matrices/src/scale.ts @@ -4,7 +4,7 @@ import { setC, setC4, setC6 -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { Mat } from "./api"; /** diff --git a/packages/matrices/src/set.ts b/packages/matrices/src/set.ts index cec967a5cf..3743920377 100644 --- a/packages/matrices/src/set.ts +++ b/packages/matrices/src/set.ts @@ -3,7 +3,7 @@ import { set as _set, SET, set4 -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; import { MatOpM } from "./api"; const $ = (dim) => _set.add(dim, compile(dim, SET, "o,a")); diff --git a/packages/matrices/src/sub.ts b/packages/matrices/src/sub.ts index 634ed5dc0e..65935210a4 100644 --- a/packages/matrices/src/sub.ts +++ b/packages/matrices/src/sub.ts @@ -1,4 +1,4 @@ -import { sub as _sub, sub4 } from "@thi.ng/vectors3"; +import { sub as _sub, sub4 } from "@thi.ng/vectors"; import { MatOpMM, MultiMatOpMM } from "./api"; import { defMath } from "./internal/codegen"; diff --git a/packages/matrices/src/subn.ts b/packages/matrices/src/subn.ts index 6a3a19d5bd..b8243f7546 100644 --- a/packages/matrices/src/subn.ts +++ b/packages/matrices/src/subn.ts @@ -1,4 +1,4 @@ -import { subN as _subN, subN4 } from "@thi.ng/vectors3"; +import { subN as _subN, subN4 } from "@thi.ng/vectors"; import { MatOpMN, MultiMatOpMN } from "./api"; import { defMathN } from "./internal/codegen"; diff --git a/packages/matrices/src/trace.ts b/packages/matrices/src/trace.ts index 8ecd948769..e25257df39 100644 --- a/packages/matrices/src/trace.ts +++ b/packages/matrices/src/trace.ts @@ -1,4 +1,4 @@ -import { sum } from "@thi.ng/vectors3"; +import { sum } from "@thi.ng/vectors"; import { diag } from "./diag"; import { ReadonlyMat } from "./api"; diff --git a/packages/matrices/src/translation.ts b/packages/matrices/src/translation.ts index dfe44d8054..76078636fe 100644 --- a/packages/matrices/src/translation.ts +++ b/packages/matrices/src/translation.ts @@ -1,4 +1,4 @@ -import { ReadonlyVec, setC, setC6 } from "@thi.ng/vectors3"; +import { ReadonlyVec, setC, setC6 } from "@thi.ng/vectors"; import { Mat } from "./api"; /** diff --git a/packages/matrices/src/transpose.ts b/packages/matrices/src/transpose.ts index 5aa6bb6c54..6dbaff5029 100644 --- a/packages/matrices/src/transpose.ts +++ b/packages/matrices/src/transpose.ts @@ -1,4 +1,4 @@ -import { setC, setC4 } from "@thi.ng/vectors3"; +import { setC, setC4 } from "@thi.ng/vectors"; import { MatOpM } from "./api"; /** diff --git a/packages/vector-pools/package.json b/packages/vector-pools/package.json index 43fc58712c..c28aa251e5 100644 --- a/packages/vector-pools/package.json +++ b/packages/vector-pools/package.json @@ -16,7 +16,7 @@ "scripts": { "build": "yarn clean && yarn build:es6 && yarn build:bundle", "build:es6": "tsc --declaration", - "build:bundle": "../../scripts/bundle-module vectorPools api malloc vectors3", + "build:bundle": "../../scripts/bundle-module vectorPools api malloc vectors", "test": "rimraf build && tsc -p test/tsconfig.json && nyc mocha build/test/*.js", "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", "cover": "yarn test && nyc report --reporter=lcov", @@ -34,7 +34,7 @@ "dependencies": { "@thi.ng/api": "^4.2.4", "@thi.ng/malloc": "^0.2.1", - "@thi.ng/vectors3": "^0.0.1" + "@thi.ng/vectors": "^1.4.12" }, "keywords": [ "ES6", diff --git a/packages/vector-pools/src/alist.ts b/packages/vector-pools/src/alist.ts index 773c41a237..251fb77304 100644 --- a/packages/vector-pools/src/alist.ts +++ b/packages/vector-pools/src/alist.ts @@ -1,4 +1,4 @@ -import { StridedVec, Vec } from "@thi.ng/vectors3"; +import { StridedVec, Vec } from "@thi.ng/vectors"; import { VecFactory } from "./api"; import { wrap } from "./wrap"; diff --git a/packages/vector-pools/src/api.ts b/packages/vector-pools/src/api.ts index 3216be17cb..ca0025c537 100644 --- a/packages/vector-pools/src/api.ts +++ b/packages/vector-pools/src/api.ts @@ -1,6 +1,6 @@ import { IRelease, TypedArray } from "@thi.ng/api"; import { Type, MemPoolOpts } from "@thi.ng/malloc"; -import { StridedVec, Vec, ReadonlyVec } from "@thi.ng/vectors3"; +import { StridedVec, Vec, ReadonlyVec } from "@thi.ng/vectors"; export interface AttribSpec { type: GLType | Type; diff --git a/packages/vector-pools/src/array-list.ts b/packages/vector-pools/src/array-list.ts index e337a0a4b5..237080fe3d 100644 --- a/packages/vector-pools/src/array-list.ts +++ b/packages/vector-pools/src/array-list.ts @@ -1,4 +1,4 @@ -import { StridedVec, Vec } from "@thi.ng/vectors3"; +import { StridedVec, Vec } from "@thi.ng/vectors"; import { AVecList } from "./alist"; import { VecFactory } from "./api"; diff --git a/packages/vector-pools/src/attrib-pool.ts b/packages/vector-pools/src/attrib-pool.ts index 85c80d02d5..0b47bccb79 100644 --- a/packages/vector-pools/src/attrib-pool.ts +++ b/packages/vector-pools/src/attrib-pool.ts @@ -7,7 +7,7 @@ import { import { align, Pow2 } from "@thi.ng/binary"; import { MemPool, SIZEOF, wrap } from "@thi.ng/malloc"; import { range } from "@thi.ng/transducers"; -import { ReadonlyVec, Vec } from "@thi.ng/vectors3"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors"; import { asNativeType } from "./convert"; import { AttribPoolOpts, diff --git a/packages/vector-pools/src/linked-list.ts b/packages/vector-pools/src/linked-list.ts index 56b826742a..7155d7a0f4 100644 --- a/packages/vector-pools/src/linked-list.ts +++ b/packages/vector-pools/src/linked-list.ts @@ -1,4 +1,4 @@ -import { StridedVec, Vec } from "@thi.ng/vectors3"; +import { StridedVec, Vec } from "@thi.ng/vectors"; import { AVecList } from "./alist"; import { VecFactory } from "./api"; diff --git a/packages/vector-pools/src/vec-pool.ts b/packages/vector-pools/src/vec-pool.ts index c8a2064e18..1351e6d61f 100644 --- a/packages/vector-pools/src/vec-pool.ts +++ b/packages/vector-pools/src/vec-pool.ts @@ -6,7 +6,7 @@ import { MemPoolStats, Type } from "@thi.ng/malloc"; -import { IVector } from "@thi.ng/vectors3"; +import { IVector } from "@thi.ng/vectors"; import { GLType, IVecPool } from "./api"; import { asNativeType } from "./convert"; import { wrap } from "./wrap"; diff --git a/packages/vector-pools/src/wrap.ts b/packages/vector-pools/src/wrap.ts index 65ca5be087..5c8f62e366 100644 --- a/packages/vector-pools/src/wrap.ts +++ b/packages/vector-pools/src/wrap.ts @@ -5,7 +5,7 @@ import { Vec2, Vec3, Vec4 -} from "@thi.ng/vectors3"; +} from "@thi.ng/vectors"; export const wrap = (buf: Vec, size: number, idx: number, stride: number): IVector => { diff --git a/packages/vectors/test/index.ts b/packages/vectors/test/index.ts index 2b933e91ec..d099875f10 100644 --- a/packages/vectors/test/index.ts +++ b/packages/vectors/test/index.ts @@ -1,6 +1,6 @@ // import * as assert from "assert"; // import * as v from "../src/index"; -describe("vectors3", () => { +describe("vectors", () => { it("tests pending"); }); From 74b7a38a7d8c6714cfa384d4e67d0a898576755b Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 20 Jan 2019 22:34:12 +0000 Subject: [PATCH 326/333] build(vectors): refix version to previous --- packages/vectors/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vectors/package.json b/packages/vectors/package.json index 124bed314d..68d7a33b2f 100644 --- a/packages/vectors/package.json +++ b/packages/vectors/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/vectors", - "version": "0.0.1", + "version": "1.4.12", "description": "Optimized 2d/3d/4d and arbitrary length vector operations", "module": "./index.js", "main": "./lib/index.js", From b5842fa7f898d67c78fa31728279ff99220f4a49 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 20 Jan 2019 22:43:52 +0000 Subject: [PATCH 327/333] docs(geom): update readme --- packages/geom/README.md | 85 ++++++++++------------------------------- 1 file changed, 21 insertions(+), 64 deletions(-) diff --git a/packages/geom/README.md b/packages/geom/README.md index 61c8f20ce5..296526de6e 100644 --- a/packages/geom/README.md +++ b/packages/geom/README.md @@ -1,6 +1,8 @@ # @thi.ng/geom [![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/geom.svg)](https://www.npmjs.com/package/@thi.ng/geom) +![npm downloads](https://img.shields.io/npm/dm/@thi.ng/geom.svg) +[![Twitter Follow](https://img.shields.io/twitter/follow/thing_umbrella.svg?style=flat-square&label=twitter)](https://twitter.com/thing_umbrella) This project is part of the [@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo. @@ -8,11 +10,9 @@ This project is part of the - [About](#about) -- [Status](#status) - [Installation](#installation) +- [Dependencies](#dependencies) - [Usage examples](#usage-examples) - - [Tessellations](#tessellations) - - [Subdivision curves](#subdivision-curves) - [Authors](#authors) - [License](#license) @@ -20,19 +20,7 @@ This project is part of the ## About -This package is a partial WIP port of selected features of the -[Clojure/ClojureScript version of -thi.ng/geom](https://github.com/thi-ng/geom), as well as -[c.thi.ng](https://github.com/thi-ng/c-thing). Currently only 2D shapes -& operations are supported. - -**This package will soon be replaced by the currently still unreleased -[@thi.ng/geom2](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/geom2) -package** - -## Status - -ALPHA - major breaking changes forthcoming... +[up-to-date feature matrix spreadsheet](https://docs.google.com/spreadsheets/d/1GxJm-zOQaGECui2MJUmy3gQPTF-T6BJ6vhNlUnPsmDs/edit?usp=sharing) ## Installation @@ -40,57 +28,26 @@ ALPHA - major breaking changes forthcoming... yarn add @thi.ng/geom ``` -## Usage examples - -### Tessellations +## Dependencies + +- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/master/packages/api) +- [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/master/packages/checks) +- [@thi.ng/compose](https://github.com/thi-ng/umbrella/tree/master/packages/compose) +- [@thi.ng/defmulti](https://github.com/thi-ng/umbrella/tree/master/packages/defmulti) +- [@thi.ng/equiv](https://github.com/thi-ng/umbrella/tree/master/packages/equiv) +- [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/master/packages/errors) +- [@thi.ng/hiccup](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup) +- [@thi.ng/hiccup-svg](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup-svg) +- [@thi.ng/math](https://github.com/thi-ng/umbrella/tree/master/packages/math) +- [@thi.ng/matrices](https://github.com/thi-ng/umbrella/tree/master/packages/matrices) +- [@thi.ng/random](https://github.com/thi-ng/umbrella/tree/master/packages/random) +- [@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/master/packages/transducers) +- [@thi.ng/vectors](https://github.com/thi-ng/umbrella/tree/master/packages/vectors) -![sample output](../../assets/geom/tessel.svg) +## Usage examples ```ts import * as g from "@thi.ng/geom"; -import * as v from "@thi.ng/vectors"; -import * as h from "@thi.ng/hiccup"; -import * as svg from "@thi.ng/hiccup-svg"; -import * as fs from "fs"; - -const tintedPoly = (points) => { - const p = g.polygon2(points); - const c = p.centroid().toPolar(); - p.attribs = { fill: `hsl(${v.deg(c.y)},${c.x}%,${100-c.x/2}%)` }; - return p; -}; - -fs.writeFileSync( - "tessel.svg", - h.serialize( - svg.svg( - { - width: 1000, height: 1000, - viewBox: "-100 -100 200 200", - fill: "none", - stroke: "#000", - "stroke-width": 0.5, - }, - svg.convertTree( - g.circle2(100) - .toPolygon(6) - .tessellate([g.quadFan, g.triFan, g.edgeSplit, g.quadFan]) - .map((pts) => tintedPoly(pts).toHiccup()) - ) - ) - ) -); -``` - -### Subdivision curves - -| Chaikin (closed) | Chaikin (open) | -|---------------------------------------------------------|-----------------------------------------------------| -| ![chaikin closed](../../assets/geom/chaikin-closed.svg) | ![chaikin open](../../assets/geom/chaikin-open.svg) | - -```ts -g.polygon2([-100,-100, 0,100, 100,-100, 0,0]).subdivide(g.CHAIKIN_CLOSED, 4); -g.polyline2([-100,100, -100,-100, 0,0, 100,-100, 100,100]).subdivide(g.CHAIKIN_OPEN, 4); ``` ## Authors @@ -99,4 +56,4 @@ g.polyline2([-100,100, -100,-100, 0,0, 100,-100, 100,100]).subdivide(g.CHAIKIN_O ## License -© 2013 - 2018 Karsten Schmidt // Apache Software License 2.0 +© 2018 Karsten Schmidt // Apache Software License 2.0 From 51723f99916aa0959316fbf931ba042e254c977d Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 20 Jan 2019 22:51:12 +0000 Subject: [PATCH 328/333] build(pointfree-lang): fix UMD identifier --- packages/pointfree-lang/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pointfree-lang/package.json b/packages/pointfree-lang/package.json index 5a1eb51432..2d3c2d3c3d 100644 --- a/packages/pointfree-lang/package.json +++ b/packages/pointfree-lang/package.json @@ -16,7 +16,7 @@ "scripts": { "build": "yarn clean && yarn build:es6 && yarn build:bundle", "build:es6": "tsc --declaration && yarn peg", - "build:bundle": "../../scripts/bundle-module pointfree-lang api errors pointfree", + "build:bundle": "../../scripts/bundle-module pointfreeLang api errors pointfree", "test": "rimraf build && tsc -p test/tsconfig.json && yarn pegtest && nyc mocha build/test/*.js", "peg": "pegjs -f es -o parser.js src/grammar.pegjs", "pegtest": "pegjs -o build/src/parser.js src/grammar.pegjs", From 822d8fba3f69c28845ddfc434eff90c1d7a940bc Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 21 Jan 2019 04:05:00 +0000 Subject: [PATCH 329/333] docs: update readme links / package names --- README.md | 57 ++++++++++++++++----------------- packages/color/README.md | 22 ++++++------- packages/defmulti/README.md | 2 +- packages/matrices/README.md | 12 +++---- packages/vector-pools/README.md | 6 ++-- packages/vectors/README.md | 44 ++++++++++++------------- 6 files changed, 70 insertions(+), 73 deletions(-) diff --git a/README.md b/README.md index 37c5b93bfd..a41e91fac3 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,8 @@ All / most packages: - have detailed, individual README files w/ small usage examples - are versioned independently -- distributed in ES6 syntax (as CommonJS modules) with doc comments - (incl. example code snippets), bundled TypeScript typings & changelogs +- distributed in ES6 syntax and multiple format (ESM, CommonJS, UMD) + with TypeScript typings & changelogs - highly modular with largely only a few closely related functions or single function / class per file to help w/ tree shaking - provide re-exports of all their publics for full library imports @@ -31,8 +31,8 @@ All / most packages: - auto-generated online documentation at [docs.thi.ng](http://docs.thi.ng) - licensed under Apache Software License 2.0 -There's a steadily growing number (~40) of standalone examples -(different difficulties, many combining functionality from several +There's a steadily growing number (40+) of standalone examples +(different complexities, many combining functionality from several packages) in the [examples](./examples) directory. ## Projects @@ -113,26 +113,29 @@ packages) in the [examples](./examples) directory. ### Geometry & visualization -| Project | Version | Changelog | Description | -|-----------------------------------------------|---------------------------------------------------------------------------------------------------------------------|-------------------------------------------------|------------------------------------------| -| [`@thi.ng/dot`](./packages/dot) | [![version](https://img.shields.io/npm/v/@thi.ng/dot.svg)](https://www.npmjs.com/package/@thi.ng/dot) | [changelog](./packages/dot/CHANGELOG.md) | Graphviz DOM & export | -| [`@thi.ng/geom`](./packages/geom) | [![version](https://img.shields.io/npm/v/@thi.ng/geom.svg)](https://www.npmjs.com/package/@thi.ng/geom) | [changelog](./packages/geom/CHANGELOG.md) | 2D geometry types & operations | -| [`@thi.ng/geom-accel`](./packages/geom-accel) | [![version](https://img.shields.io/npm/v/@thi.ng/geom-accel.svg)](https://www.npmjs.com/package/@thi.ng/geom-accel) | [changelog](./packages/geom-accel/CHANGELOG.md) | Spatial indexing data structures | -| [`@thi.ng/iges`](./packages/iges) | [![version](https://img.shields.io/npm/v/@thi.ng/iges.svg)](https://www.npmjs.com/package/@thi.ng/iges) | [changelog](./packages/iges/CHANGELOG.md) | IGES format geometry serialization | -| [`@thi.ng/vectors`](./packages/vectors) | [![version](https://img.shields.io/npm/v/@thi.ng/vectors.svg)](https://www.npmjs.com/package/@thi.ng/vectors) | [changelog](./packages/vectors/CHANGELOG.md) | Memory-mapped vector & matrix operations | +| Project | Version | Changelog | Description | +|-----------------------------------------------|---------------------------------------------------------------------------------------------------------------------|-------------------------------------------------|-------------------------------------| +| [`@thi.ng/color`](./packages/color) | [![version](https://img.shields.io/npm/v/@thi.ng/color.svg)](https://www.npmjs.com/package/@thi.ng/color) | [changelog](./packages/color/CHANGELOG.md) | Color | +| [`@thi.ng/dot`](./packages/dot) | [![version](https://img.shields.io/npm/v/@thi.ng/dot.svg)](https://www.npmjs.com/package/@thi.ng/dot) | [changelog](./packages/dot/CHANGELOG.md) | Graphviz DOM & export | +| [`@thi.ng/geom`](./packages/geom) | [![version](https://img.shields.io/npm/v/@thi.ng/geom.svg)](https://www.npmjs.com/package/@thi.ng/geom) | [changelog](./packages/geom/CHANGELOG.md) | 2D geometry types & operations | +| [`@thi.ng/geom-accel`](./packages/geom-accel) | [![version](https://img.shields.io/npm/v/@thi.ng/geom-accel.svg)](https://www.npmjs.com/package/@thi.ng/geom-accel) | [changelog](./packages/geom-accel/CHANGELOG.md) | Spatial indexing data structures | +| [`@thi.ng/iges`](./packages/iges) | [![version](https://img.shields.io/npm/v/@thi.ng/iges.svg)](https://www.npmjs.com/package/@thi.ng/iges) | [changelog](./packages/iges/CHANGELOG.md) | IGES format geometry serialization | +| [`@thi.ng/matrices`](./packages/matrices) | [![version](https://img.shields.io/npm/v/@thi.ng/matrices.svg)](https://www.npmjs.com/package/@thi.ng/matrices) | [changelog](./packages/matrices/CHANGELOG.md) | Matrix operations | +| [`@thi.ng/vectors`](./packages/vectors) | [![version](https://img.shields.io/npm/v/@thi.ng/vectors.svg)](https://www.npmjs.com/package/@thi.ng/vectors) | [changelog](./packages/vectors/CHANGELOG.md) | Fixed & arbitrary-length vector ops | ### Low-level, binary, memory management -| Project | Version | Changelog | Description | -|-------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|--------------------------------------------------|-------------------------------------------| -| [`@thi.ng/binary`](./packages/binary) | [![version](https://img.shields.io/npm/v/@thi.ng/binary.svg)](https://www.npmjs.com/package/@thi.ng/binary) | [changelog](./packages/binary/CHANGELOG.md) | Assorted binary / bitwise ops, utilities | -| [`@thi.ng/bitstream`](./packages/bitstream) | [![version](https://img.shields.io/npm/v/@thi.ng/bitstream.svg)](https://www.npmjs.com/package/@thi.ng/bitstream) | [changelog](./packages/bitstream/CHANGELOG.md) | Bitwise input / output streams | -| [`@thi.ng/dlogic`](./packages/dlogic) | [![version](https://img.shields.io/npm/v/@thi.ng/dlogic.svg)](https://www.npmjs.com/package/@thi.ng/dlogic) | [changelog](./packages/dlogic/CHANGELOG.md) | Digital logic ops / constructs | -| [`@thi.ng/malloc`](./packages/malloc) | [![version](https://img.shields.io/npm/v/@thi.ng/malloc.svg)](https://www.npmjs.com/package/@thi.ng/malloc) | [changelog](./packages/malloc/CHANGELOG.md) | Raw & typed array memory pool & allocator | -| [`@thi.ng/morton`](./packages/morton) | [![version](https://img.shields.io/npm/v/@thi.ng/morton.svg)](https://www.npmjs.com/package/@thi.ng/morton) | [changelog](./packages/morton/CHANGELOG.md) | Z-order-curve / Morton coding | -| [`@thi.ng/range-coder`](./packages/range-coder) | [![version](https://img.shields.io/npm/v/@thi.ng/range-coder.svg)](https://www.npmjs.com/package/@thi.ng/range-coder) | [changelog](./packages/range-coder/CHANGELOG.md) | Binary data Range encoder / decoder | -| [`@thi.ng/rle-pack`](./packages/rle-pack) | [![version](https://img.shields.io/npm/v/@thi.ng/rle-pack.svg)](https://www.npmjs.com/package/@thi.ng/rle-pack) | [changelog](./packages/rle-pack/CHANGELOG.md) | Run-length encoding data compression | -| [`@thi.ng/unionstruct`](./packages/unionstruct) | [![version](https://img.shields.io/npm/v/@thi.ng/unionstruct.svg)](https://www.npmjs.com/package/@thi.ng/unionstruct) | [changelog](./packages/unionstruct/CHANGELOG.md) | Wrapper for C-like structs / unions | +| Project | Version | Changelog | Description | +|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------|-------------------------------------------| +| [`@thi.ng/binary`](./packages/binary) | [![version](https://img.shields.io/npm/v/@thi.ng/binary.svg)](https://www.npmjs.com/package/@thi.ng/binary) | [changelog](./packages/binary/CHANGELOG.md) | Assorted binary / bitwise ops, utilities | +| [`@thi.ng/bitstream`](./packages/bitstream) | [![version](https://img.shields.io/npm/v/@thi.ng/bitstream.svg)](https://www.npmjs.com/package/@thi.ng/bitstream) | [changelog](./packages/bitstream/CHANGELOG.md) | Bitwise input / output streams | +| [`@thi.ng/dlogic`](./packages/dlogic) | [![version](https://img.shields.io/npm/v/@thi.ng/dlogic.svg)](https://www.npmjs.com/package/@thi.ng/dlogic) | [changelog](./packages/dlogic/CHANGELOG.md) | Digital logic ops / constructs | +| [`@thi.ng/malloc`](./packages/malloc) | [![version](https://img.shields.io/npm/v/@thi.ng/malloc.svg)](https://www.npmjs.com/package/@thi.ng/malloc) | [changelog](./packages/malloc/CHANGELOG.md) | Raw & typed array memory pool & allocator | +| [`@thi.ng/morton`](./packages/morton) | [![version](https://img.shields.io/npm/v/@thi.ng/morton.svg)](https://www.npmjs.com/package/@thi.ng/morton) | [changelog](./packages/morton/CHANGELOG.md) | Z-order-curve / Morton coding | +| [`@thi.ng/range-coder`](./packages/range-coder) | [![version](https://img.shields.io/npm/v/@thi.ng/range-coder.svg)](https://www.npmjs.com/package/@thi.ng/range-coder) | [changelog](./packages/range-coder/CHANGELOG.md) | Binary data Range encoder / decoder | +| [`@thi.ng/rle-pack`](./packages/rle-pack) | [![version](https://img.shields.io/npm/v/@thi.ng/rle-pack.svg)](https://www.npmjs.com/package/@thi.ng/rle-pack) | [changelog](./packages/rle-pack/CHANGELOG.md) | Run-length encoding data compression | +| [`@thi.ng/unionstruct`](./packages/unionstruct) | [![version](https://img.shields.io/npm/v/@thi.ng/unionstruct.svg)](https://www.npmjs.com/package/@thi.ng/unionstruct) | [changelog](./packages/unionstruct/CHANGELOG.md) | Wrapper for C-like structs / unions | +| [`@thi.ng/vector-pools`](./packages/vector-pools) | [![version](https://img.shields.io/npm/v/@thi.ng/vector-pools.svg)](https://www.npmjs.com/package/@thi.ng/vector-pools) | [changelog](./packages/vector-pools/CHANGELOG.md) | data structures for memory mapped vectors | ### DSLs @@ -141,19 +144,13 @@ packages) in the [examples](./examples) directory. | [`@thi.ng/pointfree`](./packages/pointfree) | [![version](https://img.shields.io/npm/v/@thi.ng/pointfree.svg)](https://www.npmjs.com/package/@thi.ng/pointfree) | [changelog](./packages/pointfree/CHANGELOG.md) | Stack-based DSL & functional composition | | [`@thi.ng/pointfree-lang`](./packages/pointfree-lang) | [![version](https://img.shields.io/npm/v/@thi.ng/pointfree-lang.svg)](https://www.npmjs.com/package/@thi.ng/pointfree-lang) | [changelog](./packages/pointfree-lang/CHANGELOG.md) | Forth-like syntax layer for @thi.ng/pointfree | -### Experimental packages (WIP / unreleased) - -- [@thi.ng/color](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/color) -- [@thi.ng/geom3](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/geom3) -- [@thi.ng/matrices](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/matrices) -- [@thi.ng/vector-pools](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vector-pools) -- [@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3) - ## Building ```bash git clone https://github.com/thi-ng/umbrella.git cd umbrella + +yarn install yarn build ``` @@ -181,7 +178,7 @@ yarn build ### Testing -(TODO most but not all packages have tests) +(most, but not all packages have tests) ```bash yarn test diff --git a/packages/color/README.md b/packages/color/README.md index 8332e3f226..21c12fa897 100644 --- a/packages/color/README.md +++ b/packages/color/README.md @@ -29,7 +29,7 @@ This project is part of the Raw, array-based, color operations, conversions and optional type wrappers. The functions provided by this package are largely using the same calling convention as those in the -[@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3) +[@thi.ng/vectors](https://github.com/thi-ng/umbrella/tree/master/packages/vectors) package. ### Color spaces / modes @@ -62,7 +62,7 @@ below). The package provides lightweight class wrappers for each color mode / space. These wrappers act similarly to the `Vec2/3/4` wrappers in -[@thi.ng/vectors](https://github.com/thi-ng/umbrella/tree/master/packages/vectors3), +[@thi.ng/vectors](https://github.com/thi-ng/umbrella/tree/master/packages/vectors), support striding (for mapped memory views), named channel accessor aliases (in addition to array indexing) and are fully compatible with all functions (and act as syntax sugar for generic conversion @@ -71,7 +71,7 @@ functions). Wrapper factory functions are provided for convenience. ### RGBA transformations RGBA [color matrix -transformations](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/color/src/matrix.ts), +transformations](https://github.com/thi-ng/umbrella/tree/master/packages/color/src/matrix.ts), including parametric preset transforms: - brightness @@ -92,11 +92,11 @@ concatenation (`concat()`) for more efficient application. ### RGBA Porter-Duff compositing The package provides all 12 basic -[Porter-Duff](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/color/src/porter-duff.ts) +[Porter-Duff](https://github.com/thi-ng/umbrella/tree/master/packages/color/src/porter-duff.ts) compositing / blending operators, both for colors with pre-multiplied alpha and without. -![porter-duff compositing modes](https://raw.githubusercontent.com/thi-ng/umbrella/feature/vec-refactor/assets/porter-duff.png) +![porter-duff compositing modes](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/porter-duff.png) ([Image source](http://www.svgopen.org/2005/papers/abstractsvgopen/#PorterDuffMap)) @@ -105,7 +105,7 @@ alpha and without. - [Original article](http://www.iquilezles.org/www/articles/palettes/palettes.htm) - [Gradient generator](http://dev.thi.ng/gradients/) -The following presets are bundled (in [`cosine-gradients.ts`](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/color/src/cosine-gradients.ts)): +The following presets are bundled (in [`cosine-gradients.ts`](https://github.com/thi-ng/umbrella/tree/master/packages/color/src/cosine-gradients.ts)): | | | |----------------------------------------------------------------|------------------------------------------------------------------| @@ -165,10 +165,10 @@ col.multiCosineGradient( ALPHA - work in progress -- [@thi.ng/geom2](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/geom2) - 2D/3D geometry types & operations -- [@thi.ng/matrices](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/matrices) - 2x2, 2x3, 3x3, 4x4 matrix & quaternion ops -- [@thi.ng/vectors](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3) - optimized 2d/3d/4d and arbitrary length vector ops -- [@thi.ng/vector-pools](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vector-pools) - operations on memory mapped data +- [@thi.ng/geom](https://github.com/thi-ng/umbrella/tree/master/packages/geom) - 2D/3D geometry types & operations +- [@thi.ng/matrices](https://github.com/thi-ng/umbrella/tree/master/packages/matrices) - 2x2, 2x3, 3x3, 4x4 matrix & quaternion ops +- [@thi.ng/vectors](https://github.com/thi-ng/umbrella/tree/master/packages/vectors) - optimized 2d/3d/4d and arbitrary length vector ops +- [@thi.ng/vector-pools](https://github.com/thi-ng/umbrella/tree/master/packages/vector-pools) - operations on memory mapped data ## Installation @@ -184,7 +184,7 @@ yarn add @thi.ng/color - [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/master/packages/errors) - [@thi.ng/strings](https://github.com/thi-ng/umbrella/tree/master/packages/strings) - [@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/master/packages/transducers) -- [@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3) +- [@thi.ng/vectors](https://github.com/thi-ng/umbrella/tree/master/packages/vectors) ## Usage examples diff --git a/packages/defmulti/README.md b/packages/defmulti/README.md index 95653d4f55..e1ec641b64 100644 --- a/packages/defmulti/README.md +++ b/packages/defmulti/README.md @@ -174,7 +174,7 @@ baz.impls(); // Set { "c", "a", "b" } ``` Also see the WIP package -[@thi.ng/geom2](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/geom2) +[@thi.ng/geom](https://github.com/thi-ng/umbrella/tree/master/packages/geom) for a concreate realworld usage example. ### defmultiN() diff --git a/packages/matrices/README.md b/packages/matrices/README.md index 960d9de3d7..5820f86cc6 100644 --- a/packages/matrices/README.md +++ b/packages/matrices/README.md @@ -36,7 +36,7 @@ This project is part of the This package provides 160+ matrix & quaternion operations for 2D/3D geometry processing and acts as companion package for -[@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3). +[@thi.ng/vectors](https://github.com/thi-ng/umbrella/tree/master/packages/vectors). Like with the vectors package, most functions are defined as multi-method dispatching to optimized implementations based on matrix size (which themselves are exposed for direct use too). @@ -48,10 +48,10 @@ sensible). ### Related packages -- [@thi.ng/color](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/color) - vector based color operations / conversions -- [@thi.ng/geom2](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/geom2) - 2D/3D geometry types & operations -- [@thi.ng/vectors](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3) - optimized 2d/3d/4d and arbitrary length vector ops -- [@thi.ng/vector-pools](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vector-pools) - operations on memory mapped data +- [@thi.ng/color](https://github.com/thi-ng/umbrella/tree/master/packages/color) - vector based color operations / conversions +- [@thi.ng/geom](https://github.com/thi-ng/umbrella/tree/master/packages/geom) - 2D/3D geometry types & operations +- [@thi.ng/vectors](https://github.com/thi-ng/umbrella/tree/master/packages/vectors) - optimized 2d/3d/4d and arbitrary length vector ops +- [@thi.ng/vector-pools](https://github.com/thi-ng/umbrella/tree/master/packages/vector-pools) - operations on memory mapped data ## Installation @@ -64,7 +64,7 @@ yarn add @thi.ng/matrices - [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/master/packages/api) - [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/master/packages/checks) - [@thi.ng/math](https://github.com/thi-ng/umbrella/tree/master/packages/math) -- [@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3) +- [@thi.ng/vectors](https://github.com/thi-ng/umbrella/tree/master/packages/vectors) ## Usage examples diff --git a/packages/vector-pools/README.md b/packages/vector-pools/README.md index 5cc54f3582..d58fcfa567 100644 --- a/packages/vector-pools/README.md +++ b/packages/vector-pools/README.md @@ -24,7 +24,7 @@ This project is part of the This still unreleased package provides various data structures for managing & working with memory mapped vectors. Together with -[@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3) +[@thi.ng/vectors](https://github.com/thi-ng/umbrella/tree/master/packages/vectors) (also still unreleased) these structures enable high-level, zero-copy* manipulation of the underlying memory region and are largely intended for WebGL & WASM use cases, e.g. to provide JS @@ -43,7 +43,7 @@ yarn add @thi.ng/vector-pools - [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/master/packages/api) - [@thi.ng/malloc](https://github.com/thi-ng/umbrella/tree/master/packages/malloc) -- [@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3) +- [@thi.ng/vectors](https://github.com/thi-ng/umbrella/tree/master/packages/vectors) ## Usage examples @@ -51,7 +51,7 @@ yarn add @thi.ng/vector-pools ```ts import { AttribPool, GLType } from "@thi.ng/vector-pools"; -import * as v from "@thi.ng/vectors3"; +import * as v from "@thi.ng/vectors"; import * as tx from "@thi.ng/transducers"; // ...Webgl boilerplate omitted diff --git a/packages/vectors/README.md b/packages/vectors/README.md index a2492a17c8..faeb318420 100644 --- a/packages/vectors/README.md +++ b/packages/vectors/README.md @@ -1,7 +1,7 @@ -# @thi.ng/vectors3 +# @thi.ng/vectors -[![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/vectors3.svg)](https://www.npmjs.com/package/@thi.ng/vectors3) -![npm downloads](https://img.shields.io/npm/dm/@thi.ng/vectors3.svg) +[![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/vectors.svg)](https://www.npmjs.com/package/@thi.ng/vectors) +![npm downloads](https://img.shields.io/npm/dm/@thi.ng/vectors.svg) [![Twitter Follow](https://img.shields.io/twitter/follow/thing_umbrella.svg?style=flat-square&label=twitter)](https://twitter.com/thing_umbrella) This project is part of the @@ -61,62 +61,62 @@ layouts). - Highly modular: Each function is defined in its own submodule / file. In addition to each generic multi-method base function, all fixed-length optimized versions are exported too. E.g. If - [`add`](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/add.ts) + [`add`](https://github.com/thi-ng/umbrella/tree/master/packages/vectors/src/add.ts) performs vector addition on arbitrary-length vectors, `add2`, `add3`, `add4` are the optimized version for fixed-length vectors... - Extensible: Custom vector ops can be defined in a similar manner using the provided code generation helpers (see - [vop.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/vop.ts) + [vop.ts](https://github.com/thi-ng/umbrella/tree/master/packages/vectors/src/internal/vop.ts) and - [codegen.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/codegen.ts) + [codegen.ts](https://github.com/thi-ng/umbrella/tree/master/packages/vectors/src/internal/codegen.ts) for details). - Immutable by default: Each operation producing a vector result takes an output vector as first argument. If `null`, the vector given as 2nd argument will be used as output (i.e. for mutation). - Strided vector support is handled via the lightweight - [`Vec2/3/4`](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/vec2.ts) + [`Vec2/3/4`](https://github.com/thi-ng/umbrella/tree/master/packages/vectors/src/vec2.ts) class wrappers and the - [`gvec()`](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/gvec.ts) + [`gvec()`](https://github.com/thi-ng/umbrella/tree/master/packages/vectors/src/gvec.ts) proxy (for generic, arbitrary-length vectors). These types behave like normal arrays (for read/write operations) and are also iterable. A subset of functions (suffixed with `S`, e.g. - [`addS`](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/adds.ts) + [`addS`](https://github.com/thi-ng/umbrella/tree/master/packages/vectors/src/adds.ts) vs. `add`) also support striding without the need for extra class wrappers. This is handled via additional index and stride arguments for each input/output vector. These functions are only available for sizes 2 / 3 / 4, though. - Random vector functions support the `IRandom` interface defined by - [@thi.ng/random](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/random) + [@thi.ng/random](https://github.com/thi-ng/umbrella/tree/master/packages/random) to work with custom (P)RNGs. If omitted, the built-in `Math.random()` will be used. ### Related packages -- [@thi.ng/color](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/color) - vector based color operations / conversions -- [@thi.ng/geom2](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/geom2) - 2D/3D geometry types & operations -- [@thi.ng/matrices](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/matrices) - 2x2, 2x3, 3x3, 4x4 matrix & quaternion ops -- [@thi.ng/vector-pools](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vector-pools) - operations on memory mapped data +- [@thi.ng/color](https://github.com/thi-ng/umbrella/tree/master/packages/color) - vector based color operations / conversions +- [@thi.ng/geom](https://github.com/thi-ng/umbrella/tree/master/packages/geom) - 2D/3D geometry types & operations +- [@thi.ng/matrices](https://github.com/thi-ng/umbrella/tree/master/packages/matrices) - 2x2, 2x3, 3x3, 4x4 matrix & quaternion ops +- [@thi.ng/vector-pools](https://github.com/thi-ng/umbrella/tree/master/packages/vector-pools) - operations on memory mapped data ## Installation ```bash -yarn add @thi.ng/vectors3 +yarn add @thi.ng/vectors ``` ## Dependencies -- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/api) +- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/master/packages/api) - [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/master/packages/checks) - [@thi.ng/equiv](https://github.com/thi-ng/umbrella/tree/master/packages/equiv) - [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/master/packages/errors) -- [@thi.ng/math](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/math) +- [@thi.ng/math](https://github.com/thi-ng/umbrella/tree/master/packages/math) - [@thi.ng/random](https://github.com/thi-ng/umbrella/tree/master/packages/random) - [@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/master/packages/transducers) ## Usage examples ```ts -import * as v from "@thi.ng/vectors3"; +import * as v from "@thi.ng/vectors"; // immutable vector addition (1st arg is result) v.add([], [1, 2, 3, 4], [10, 20, 30, 40]) @@ -313,7 +313,7 @@ Functions for memory mapped, strided vectors (without requiring wrappers): ### Rotations (Also see rotation matrices provided by -[@thi.ng/matrices](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/matrices)) +[@thi.ng/matrices](https://github.com/thi-ng/umbrella/tree/master/packages/matrices)) - `rotateAroundAxis3` - `rotateAroundPoint2` @@ -384,9 +384,9 @@ Functions to transform flat / strided buffers w/ vector operations: For more information about the code generator see: -- [codegen.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/codegen.ts) -- [templates.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/templates.ts) -- [vop.ts](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3/src/internal/vop.ts) +- [codegen.ts](https://github.com/thi-ng/umbrella/tree/master/packages/vectors/src/internal/codegen.ts) +- [templates.ts](https://github.com/thi-ng/umbrella/tree/master/packages/vectors/src/internal/templates.ts) +- [vop.ts](https://github.com/thi-ng/umbrella/tree/master/packages/vectors/src/internal/vop.ts) ## Authors From 7c1bf047cd44ed17588634843276cbbfea22274a Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 21 Jan 2019 04:05:25 +0000 Subject: [PATCH 330/333] refactor(examples): update gesture-analysis demo --- examples/gesture-analysis/src/config.ts | 7 ++-- examples/gesture-analysis/src/index.ts | 48 ++++++++++++------------- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/examples/gesture-analysis/src/config.ts b/examples/gesture-analysis/src/config.ts index 8d88e6e8bc..6739761ec3 100644 --- a/examples/gesture-analysis/src/config.ts +++ b/examples/gesture-analysis/src/config.ts @@ -1,4 +1,4 @@ -import { mul2, transformVectors1, Vec2 } from "@thi.ng/vectors"; +import { Vec2 } from "@thi.ng/vectors"; // initial call to action gesture // (recorded handwriting) @@ -63,7 +63,4 @@ const raw = [ ]; // downscale & transform into memory mapped Vec2 array -export const CTA = Vec2.mapBuffer( - transformVectors1(mul2, raw, [0.75, 0.75], raw.length / 2, 2), - raw.length / 2 -); +export const CTA = Vec2.mapBuffer(raw, raw.length / 2); diff --git a/examples/gesture-analysis/src/index.ts b/examples/gesture-analysis/src/index.ts index 4e01ed0c27..a050fb83dc 100644 --- a/examples/gesture-analysis/src/index.ts +++ b/examples/gesture-analysis/src/index.ts @@ -1,9 +1,11 @@ -import { resample, vertices } from "@thi.ng/geom2/api"; -import { polyline as _polyline } from "@thi.ng/geom2/polyline"; -import { circle } from "@thi.ng/hiccup-svg/circle"; -import { group } from "@thi.ng/hiccup-svg/group"; -import { polyline } from "@thi.ng/hiccup-svg/polyline"; -import { svg } from "@thi.ng/hiccup-svg/svg"; +import { polyline as gPolyline, resample, vertices } from "@thi.ng/geom"; +import { + circle, + group, + polyline, + svg +} from "@thi.ng/hiccup-svg"; +import { fromIterable, merge, sync } from "@thi.ng/rstream"; import { GestureEvent, gestureStream, GestureType } from "@thi.ng/rstream-gestures"; import { comp, @@ -17,19 +19,12 @@ import { transduce } from "@thi.ng/transducers"; import { updateDOM } from "@thi.ng/transducers-hdom"; -import { comp } from "@thi.ng/transducers/func/comp"; -import { identity } from "@thi.ng/transducers/func/identity"; -import { peek } from "@thi.ng/transducers/func/peek"; -import { push } from "@thi.ng/transducers/rfn/push"; -import { transduce } from "@thi.ng/transducers/transduce"; -import { filter } from "@thi.ng/transducers/xform/filter"; -import { map } from "@thi.ng/transducers/xform/map"; -import { multiplexObj } from "@thi.ng/transducers/xform/multiplex-obj"; -import { partition } from "@thi.ng/transducers/xform/partition"; -import { angleBetween } from "@thi.ng/vectors/angle-between"; -import { Vec } from "@thi.ng/vectors/api"; -import { mixN2 } from "@thi.ng/vectors/mixn"; -import { sub2 } from "@thi.ng/vectors/sub"; +import { + angleBetween2, + mixN2, + sub2, + Vec +} from "@thi.ng/vectors"; import { CTA } from "./config"; /** @@ -87,7 +82,7 @@ const path = */ const sampleUniform = (step: number, pts: Vec[]) => - vertices(resample(_polyline(pts), { dist: step })); + vertices(resample(gPolyline(pts), { dist: step })); /** * Applies low-pass filter to given polyline. I.e. Each point in the @@ -112,11 +107,9 @@ const smoothPath = * @param thresh normalized angle threshold */ const isCorner = - (thresh: number) => { - thresh = Math.PI * (1 - thresh); - return ([a, b, c]: Vec[]) => - angleBetween(sub2([], b, a), sub2([], b, c), true) < thresh; - }; + (thresh: number) => + ([a, b, c]: Vec[]) => + angleBetween2(sub2([], b, a), sub2([], b, c), true) < thresh; /** * Gesture event processor. Collects gesture event positions into an @@ -176,7 +169,7 @@ sync({ (pts) => transduce( comp( partition(3, 1), - filter(isCorner(1 / 4)), + filter(isCorner(Math.PI * 2 / 3)), map((x) => x[1]) ), push(), @@ -193,3 +186,6 @@ sync({ // update UI diff updateDOM() ); + +window["v"] = require("@thi.ng/vectors"); +window["m"] = require("@thi.ng/math"); \ No newline at end of file From a78bd87b80df34536c5317c763b7278ab37410f1 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 21 Jan 2019 04:07:54 +0000 Subject: [PATCH 331/333] feat(math): add absInnerAngle() --- packages/math/src/angle.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/math/src/angle.ts b/packages/math/src/angle.ts index 67c3313240..538d2aa628 100644 --- a/packages/math/src/angle.ts +++ b/packages/math/src/angle.ts @@ -16,13 +16,13 @@ export const absTheta = (theta: number) => (theta %= TAU, theta < 0 ? TAU + theta : theta); +export const absInnerAngle = + (x: number) => + (x = Math.abs(x), x > PI ? TAU - x : x); + export const angleDist = - (a: number, b: number) => ( - a = absTheta((b % TAU) - (a % TAU)), - a > PI ? - TAU - a : - a - ); + (a: number, b: number) => + absInnerAngle(absTheta((b % TAU) - (a % TAU))); export const atan2Abs = (y: number, x: number) => From b9cea8cc981702caf6d69dc46d5f01ab5af2aa5f Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 21 Jan 2019 04:08:38 +0000 Subject: [PATCH 332/333] refactor(vectors): update angleBetween*() fns, add absInner opt arg --- packages/vectors/src/angle-between.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/vectors/src/angle-between.ts b/packages/vectors/src/angle-between.ts index 2cbc44ce41..50e8558291 100644 --- a/packages/vectors/src/angle-between.ts +++ b/packages/vectors/src/angle-between.ts @@ -1,18 +1,23 @@ +import { absInnerAngle } from "@thi.ng/math"; import { ReadonlyVec } from "./api"; +import { cross2 } from "./cross"; import { dot } from "./dot"; import { mag } from "./mag"; -import { cross2 } from "./cross"; export const angleRatio = (a: ReadonlyVec, b: ReadonlyVec) => dot(a, b) / (mag(a) * mag(b)); export const angleBetween2 = - (a: ReadonlyVec, b: ReadonlyVec) => - Math.atan2(cross2(a, b), dot(a, b)); + (a: ReadonlyVec, b: ReadonlyVec, absInner = false) => { + const t = Math.atan2(cross2(a, b), dot(a, b)); + return absInner ? absInnerAngle(t) : t; + }; export const angleBetween3 = - (a: ReadonlyVec, b: ReadonlyVec, normalize = true) => - normalize ? + (a: ReadonlyVec, b: ReadonlyVec, normalize = true, absInner = false) => { + const t = normalize ? Math.acos(angleRatio(a, b)) : Math.acos(dot(a, b)); + return absInner ? absInnerAngle(t) : t; + }; From 348e7303b8b4d2749a02dd43e3f78d711242e4fe Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 21 Jan 2019 04:34:03 +0000 Subject: [PATCH 333/333] Publish - @thi.ng/api@5.0.0 - @thi.ng/associative@1.0.0 - @thi.ng/atom@2.0.0 - @thi.ng/bench@1.0.0 - @thi.ng/binary@1.0.0 - @thi.ng/bitstream@1.0.0 - @thi.ng/cache@1.0.0 - @thi.ng/checks@2.0.0 - @thi.ng/color@0.1.0 - @thi.ng/compare@1.0.0 - @thi.ng/compose@1.0.0 - @thi.ng/csp@1.0.0 - @thi.ng/dcons@2.0.0 - @thi.ng/defmulti@1.0.0 - @thi.ng/dgraph@1.0.0 - @thi.ng/diff@3.0.0 - @thi.ng/dlogic@1.0.0 - @thi.ng/dot@1.0.0 - @thi.ng/dsp@1.0.0 - @thi.ng/equiv@1.0.0 - @thi.ng/errors@1.0.0 - @thi.ng/fsm@1.0.0 - @thi.ng/geom-accel@1.0.0 - @thi.ng/geom@1.0.0 - @thi.ng/hdom-canvas@1.0.0 - @thi.ng/hdom-components@3.0.0 - @thi.ng/hdom-mock@1.0.0 - @thi.ng/hdom@7.0.0 - @thi.ng/heaps@1.0.0 - @thi.ng/hiccup-carbon-icons@1.0.0 - @thi.ng/hiccup-css@1.0.0 - @thi.ng/hiccup-markdown@1.0.0 - @thi.ng/hiccup-svg@3.0.0 - @thi.ng/hiccup@3.0.0 - @thi.ng/iges@1.0.0 - @thi.ng/interceptors@2.0.0 - @thi.ng/intervals@1.0.0 - @thi.ng/iterators@5.0.0 - @thi.ng/malloc@1.0.0 - @thi.ng/math@1.0.0 - @thi.ng/matrices@0.1.0 - @thi.ng/memoize@1.0.0 - @thi.ng/morton@1.0.0 - @thi.ng/paths@2.0.0 - @thi.ng/pointfree-lang@1.0.0 - @thi.ng/pointfree@1.0.0 - @thi.ng/random@1.0.0 - @thi.ng/range-coder@1.0.0 - @thi.ng/resolve-map@4.0.0 - @thi.ng/rle-pack@2.0.0 - @thi.ng/router@1.0.0 - @thi.ng/rstream-csp@1.0.0 - @thi.ng/rstream-dot@1.0.0 - @thi.ng/rstream-gestures@1.0.0 - @thi.ng/rstream-graph@3.0.0 - @thi.ng/rstream-log@2.0.0 - @thi.ng/rstream-query@1.0.0 - @thi.ng/rstream@2.0.0 - @thi.ng/sax@1.0.0 - @thi.ng/strings@1.0.0 - @thi.ng/transducers-fsm@1.0.0 - @thi.ng/transducers-hdom@2.0.0 - @thi.ng/transducers-stats@1.0.0 - @thi.ng/transducers@3.0.0 - @thi.ng/unionstruct@1.0.0 - @thi.ng/vector-pools@0.1.0 - @thi.ng/vectors@2.0.0 --- packages/api/CHANGELOG.md | 29 +++++++++++++++++ packages/api/package.json | 6 ++-- packages/associative/CHANGELOG.md | 22 +++++++++++++ packages/associative/package.json | 18 +++++------ packages/atom/CHANGELOG.md | 22 +++++++++++++ packages/atom/package.json | 14 ++++----- packages/bench/CHANGELOG.md | 22 +++++++++++++ packages/bench/package.json | 4 +-- packages/binary/CHANGELOG.md | 22 +++++++++++++ packages/binary/package.json | 4 +-- packages/bitstream/CHANGELOG.md | 22 +++++++++++++ packages/bitstream/package.json | 6 ++-- packages/cache/CHANGELOG.md | 27 ++++++++++++++++ packages/cache/package.json | 10 +++--- packages/checks/CHANGELOG.md | 22 +++++++++++++ packages/checks/package.json | 4 +-- packages/color/CHANGELOG.md | 32 +++++++++++++++++++ packages/color/package.json | 20 ++++++------ packages/compare/CHANGELOG.md | 22 +++++++++++++ packages/compare/package.json | 4 +-- packages/compose/CHANGELOG.md | 22 +++++++++++++ packages/compose/package.json | 8 ++--- packages/csp/CHANGELOG.md | 27 ++++++++++++++++ packages/csp/package.json | 14 ++++----- packages/dcons/CHANGELOG.md | 22 +++++++++++++ packages/dcons/package.json | 16 +++++----- packages/defmulti/CHANGELOG.md | 29 +++++++++++++++++ packages/defmulti/package.json | 8 ++--- packages/dgraph/CHANGELOG.md | 22 +++++++++++++ packages/dgraph/package.json | 14 ++++----- packages/diff/CHANGELOG.md | 22 +++++++++++++ packages/diff/package.json | 8 ++--- packages/dlogic/CHANGELOG.md | 22 +++++++++++++ packages/dlogic/package.json | 4 +-- packages/dot/CHANGELOG.md | 22 +++++++++++++ packages/dot/package.json | 8 ++--- packages/dsp/CHANGELOG.md | 22 +++++++++++++ packages/dsp/package.json | 6 ++-- packages/equiv/CHANGELOG.md | 22 +++++++++++++ packages/equiv/package.json | 4 +-- packages/errors/CHANGELOG.md | 22 +++++++++++++ packages/errors/package.json | 4 +-- packages/fsm/CHANGELOG.md | 22 +++++++++++++ packages/fsm/package.json | 12 +++---- packages/geom-accel/CHANGELOG.md | 22 +++++++++++++ packages/geom-accel/package.json | 14 ++++----- packages/geom/CHANGELOG.md | 22 +++++++++++++ packages/geom/package.json | 30 +++++++++--------- packages/hdom-canvas/CHANGELOG.md | 27 ++++++++++++++++ packages/hdom-canvas/package.json | 12 +++---- packages/hdom-components/CHANGELOG.md | 22 +++++++++++++ packages/hdom-components/package.json | 14 ++++----- packages/hdom-mock/CHANGELOG.md | 22 +++++++++++++ packages/hdom-mock/package.json | 10 +++--- packages/hdom/CHANGELOG.md | 22 +++++++++++++ packages/hdom/package.json | 18 +++++------ packages/heaps/CHANGELOG.md | 22 +++++++++++++ packages/heaps/package.json | 8 ++--- packages/hiccup-carbon-icons/CHANGELOG.md | 22 +++++++++++++ packages/hiccup-carbon-icons/package.json | 6 ++-- packages/hiccup-css/CHANGELOG.md | 22 +++++++++++++ packages/hiccup-css/package.json | 12 +++---- packages/hiccup-markdown/CHANGELOG.md | 27 ++++++++++++++++ packages/hiccup-markdown/package.json | 18 +++++------ packages/hiccup-svg/CHANGELOG.md | 38 +++++++++++++++++++++++ packages/hiccup-svg/package.json | 8 ++--- packages/hiccup/CHANGELOG.md | 22 +++++++++++++ packages/hiccup/package.json | 10 +++--- packages/iges/CHANGELOG.md | 22 +++++++++++++ packages/iges/package.json | 12 +++---- packages/interceptors/CHANGELOG.md | 22 +++++++++++++ packages/interceptors/package.json | 14 ++++----- packages/intervals/CHANGELOG.md | 22 +++++++++++++ packages/intervals/package.json | 8 ++--- packages/iterators/CHANGELOG.md | 22 +++++++++++++ packages/iterators/package.json | 10 +++--- packages/malloc/CHANGELOG.md | 22 +++++++++++++ packages/malloc/package.json | 12 +++---- packages/math/CHANGELOG.md | 30 ++++++++++++++++++ packages/math/package.json | 4 +-- packages/matrices/CHANGELOG.md | 33 ++++++++++++++++++++ packages/matrices/package.json | 12 +++---- packages/memoize/CHANGELOG.md | 22 +++++++++++++ packages/memoize/package.json | 6 ++-- packages/morton/CHANGELOG.md | 22 +++++++++++++ packages/morton/package.json | 10 +++--- packages/paths/CHANGELOG.md | 22 +++++++++++++ packages/paths/package.json | 8 ++--- packages/pointfree-lang/CHANGELOG.md | 27 ++++++++++++++++ packages/pointfree-lang/package.json | 10 +++--- packages/pointfree/CHANGELOG.md | 22 +++++++++++++ packages/pointfree/package.json | 14 ++++----- packages/random/CHANGELOG.md | 22 +++++++++++++ packages/random/package.json | 6 ++-- packages/range-coder/CHANGELOG.md | 22 +++++++++++++ packages/range-coder/package.json | 8 ++--- packages/resolve-map/CHANGELOG.md | 22 +++++++++++++ packages/resolve-map/package.json | 12 +++---- packages/rle-pack/CHANGELOG.md | 22 +++++++++++++ packages/rle-pack/package.json | 8 ++--- packages/router/CHANGELOG.md | 22 +++++++++++++ packages/router/package.json | 12 +++---- packages/rstream-csp/CHANGELOG.md | 22 +++++++++++++ packages/rstream-csp/package.json | 8 ++--- packages/rstream-dot/CHANGELOG.md | 22 +++++++++++++ packages/rstream-dot/package.json | 6 ++-- packages/rstream-gestures/CHANGELOG.md | 27 ++++++++++++++++ packages/rstream-gestures/package.json | 10 +++--- packages/rstream-graph/CHANGELOG.md | 22 +++++++++++++ packages/rstream-graph/package.json | 18 +++++------ packages/rstream-log/CHANGELOG.md | 27 ++++++++++++++++ packages/rstream-log/package.json | 14 ++++----- packages/rstream-query/CHANGELOG.md | 22 +++++++++++++ packages/rstream-query/package.json | 20 ++++++------ packages/rstream/CHANGELOG.md | 28 +++++++++++++++++ packages/rstream/package.json | 18 +++++------ packages/sax/CHANGELOG.md | 22 +++++++++++++ packages/sax/package.json | 10 +++--- packages/strings/CHANGELOG.md | 27 ++++++++++++++++ packages/strings/package.json | 8 ++--- packages/transducers-fsm/CHANGELOG.md | 22 +++++++++++++ packages/transducers-fsm/package.json | 8 ++--- packages/transducers-hdom/CHANGELOG.md | 30 ++++++++++++++++++ packages/transducers-hdom/package.json | 10 +++--- packages/transducers-stats/CHANGELOG.md | 22 +++++++++++++ packages/transducers-stats/package.json | 12 +++---- packages/transducers/CHANGELOG.md | 27 ++++++++++++++++ packages/transducers/package.json | 18 +++++------ packages/unionstruct/CHANGELOG.md | 22 +++++++++++++ packages/unionstruct/package.json | 4 +-- packages/vector-pools/CHANGELOG.md | 14 +++++++++ packages/vector-pools/package.json | 10 +++--- packages/vectors/CHANGELOG.md | 27 ++++++++++++++++ packages/vectors/package.json | 20 ++++++------ 134 files changed, 1947 insertions(+), 358 deletions(-) create mode 100644 packages/color/CHANGELOG.md create mode 100644 packages/matrices/CHANGELOG.md create mode 100644 packages/vector-pools/CHANGELOG.md diff --git a/packages/api/CHANGELOG.md b/packages/api/CHANGELOG.md index 1444cf4943..2178f99fa2 100644 --- a/packages/api/CHANGELOG.md +++ b/packages/api/CHANGELOG.md @@ -3,6 +3,35 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/api@4.2.4...@thi.ng/api@5.0.0) (2019-01-21) + + +### Bug Fixes + +* **api:** update assert(), re-export mixin() ([9f91cfa](https://github.com/thi-ng/umbrella/commit/9f91cfa)) + + +### Build System + +* **api:** update package build scripts / outputs ([f913d7b](https://github.com/thi-ng/umbrella/commit/f913d7b)) + + +### Features + +* **api:** add assert() ([d381ace](https://github.com/thi-ng/umbrella/commit/d381ace)) + + +### BREAKING CHANGES + +* **api:** rename mixins to avoid name clashes, update decorators + +- append `Mixin` suffix to all mixins (i.e. `INotify` => `INotifyMixin`) +- update re-exports of mixins & decorators (no more nested child namespace) + + + + + ## [4.2.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/api@4.2.3...@thi.ng/api@4.2.4) (2018-12-15) **Note:** Version bump only for package @thi.ng/api diff --git a/packages/api/package.json b/packages/api/package.json index 91def34a86..e2710f0403 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/api", - "version": "4.2.4", + "version": "5.0.0", "description": "Common, generic types & interfaces for thi.ng projects", "module": "./index.js", "main": "./lib/index.js", @@ -32,7 +32,7 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/errors": "^0.1.12" + "@thi.ng/errors": "^1.0.0" }, "keywords": [ "compare", @@ -55,4 +55,4 @@ "setTimeout": false }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/associative/CHANGELOG.md b/packages/associative/CHANGELOG.md index 5025bb1ccb..d0ce9e38d4 100644 --- a/packages/associative/CHANGELOG.md +++ b/packages/associative/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/associative@0.6.23...@thi.ng/associative@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.6.23](https://github.com/thi-ng/umbrella/compare/@thi.ng/associative@0.6.22...@thi.ng/associative@0.6.23) (2019-01-02) **Note:** Version bump only for package @thi.ng/associative diff --git a/packages/associative/package.json b/packages/associative/package.json index 240c201b25..e3583eac37 100644 --- a/packages/associative/package.json +++ b/packages/associative/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/associative", - "version": "0.6.23", + "version": "1.0.0", "description": "Alternative Set & Map data type implementations with customizable equality semantics & supporting operations", "module": "./index.js", "main": "./lib/index.js", @@ -32,13 +32,13 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/compare": "^0.1.12", - "@thi.ng/dcons": "^1.1.23", - "@thi.ng/equiv": "^0.1.15", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/transducers": "^2.3.2" + "@thi.ng/api": "^5.0.0", + "@thi.ng/checks": "^2.0.0", + "@thi.ng/compare": "^1.0.0", + "@thi.ng/dcons": "^2.0.0", + "@thi.ng/equiv": "^1.0.0", + "@thi.ng/errors": "^1.0.0", + "@thi.ng/transducers": "^3.0.0" }, "keywords": [ "data structures", @@ -59,4 +59,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/atom/CHANGELOG.md b/packages/atom/CHANGELOG.md index 1f538c4f99..39b501ce7e 100644 --- a/packages/atom/CHANGELOG.md +++ b/packages/atom/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/atom@1.5.8...@thi.ng/atom@2.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [1.5.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/atom@1.5.7...@thi.ng/atom@1.5.8) (2018-12-15) **Note:** Version bump only for package @thi.ng/atom diff --git a/packages/atom/package.json b/packages/atom/package.json index 5b0e55f4ee..51444b2515 100644 --- a/packages/atom/package.json +++ b/packages/atom/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/atom", - "version": "1.5.8", + "version": "2.0.0", "description": "Mutable wrappers for nested immutable values w/ optional undo/redo history", "module": "./index.js", "main": "./lib/index.js", @@ -32,11 +32,11 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/equiv": "^0.1.15", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/paths": "^1.6.6" + "@thi.ng/api": "^5.0.0", + "@thi.ng/checks": "^2.0.0", + "@thi.ng/equiv": "^1.0.0", + "@thi.ng/errors": "^1.0.0", + "@thi.ng/paths": "^2.0.0" }, "keywords": [ "derived views", @@ -60,4 +60,4 @@ "setTimeout": false }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/bench/CHANGELOG.md b/packages/bench/CHANGELOG.md index d2954fe76d..f71a907dde 100644 --- a/packages/bench/CHANGELOG.md +++ b/packages/bench/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/bench@0.3.1...@thi.ng/bench@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.3.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/bench@0.3.0...@thi.ng/bench@0.3.1) (2018-12-15) **Note:** Version bump only for package @thi.ng/bench diff --git a/packages/bench/package.json b/packages/bench/package.json index 66cf9cbf82..67bdd0fbf8 100644 --- a/packages/bench/package.json +++ b/packages/bench/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/bench", - "version": "0.3.1", + "version": "1.0.0", "description": "Basic benchmarking helpers", "module": "./index.js", "main": "./lib/index.js", @@ -51,4 +51,4 @@ "setTimeout": false }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/binary/CHANGELOG.md b/packages/binary/CHANGELOG.md index 004f0956bd..69bac0ea7c 100644 --- a/packages/binary/CHANGELOG.md +++ b/packages/binary/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/binary@0.1.2...@thi.ng/binary@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.1.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/binary@0.1.1...@thi.ng/binary@0.1.2) (2018-12-15) **Note:** Version bump only for package @thi.ng/binary diff --git a/packages/binary/package.json b/packages/binary/package.json index 1dce3e0718..66e07c70d2 100644 --- a/packages/binary/package.json +++ b/packages/binary/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/binary", - "version": "0.1.2", + "version": "1.0.0", "description": "Assorted binary / bitwise operations, conversions, utilities.", "module": "./index.js", "main": "./lib/index.js", @@ -48,4 +48,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/bitstream/CHANGELOG.md b/packages/bitstream/CHANGELOG.md index 0faacd0794..e7ba152bc0 100644 --- a/packages/bitstream/CHANGELOG.md +++ b/packages/bitstream/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/bitstream@0.4.21...@thi.ng/bitstream@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.4.21](https://github.com/thi-ng/umbrella/compare/@thi.ng/bitstream@0.4.20...@thi.ng/bitstream@0.4.21) (2018-12-15) **Note:** Version bump only for package @thi.ng/bitstream diff --git a/packages/bitstream/package.json b/packages/bitstream/package.json index 99ba9fd229..42522c8ead 100644 --- a/packages/bitstream/package.json +++ b/packages/bitstream/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/bitstream", - "version": "0.4.21", + "version": "1.0.0", "description": "ES6 iterator based read/write bit streams & support for variable word widths", "module": "./index.js", "main": "./lib/index.js", @@ -24,7 +24,7 @@ "pub": "yarn build && yarn publish --access public" }, "dependencies": { - "@thi.ng/errors": "^0.1.12" + "@thi.ng/errors": "^1.0.0" }, "devDependencies": { "@types/mocha": "^5.2.5", @@ -47,4 +47,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/cache/CHANGELOG.md b/packages/cache/CHANGELOG.md index f91c90b5fc..17076ddc29 100644 --- a/packages/cache/CHANGELOG.md +++ b/packages/cache/CHANGELOG.md @@ -3,6 +3,33 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/cache@0.2.40...@thi.ng/cache@1.0.0) (2019-01-21) + + +### Bug Fixes + +* **cache:** TLRU: expected behavior on getSet() ([c3762e9](https://github.com/thi-ng/umbrella/commit/c3762e9)) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.2.40](https://github.com/thi-ng/umbrella/compare/@thi.ng/cache@0.2.39...@thi.ng/cache@0.2.40) (2019-01-02) **Note:** Version bump only for package @thi.ng/cache diff --git a/packages/cache/package.json b/packages/cache/package.json index fcbd6c3d34..42f2c2bee5 100644 --- a/packages/cache/package.json +++ b/packages/cache/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/cache", - "version": "0.2.40", + "version": "1.0.0", "description": "In-memory cache implementations with ES6 Map-like API and different eviction strategies", "module": "./index.js", "main": "./lib/index.js", @@ -32,9 +32,9 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/dcons": "^1.1.23", - "@thi.ng/transducers": "^2.3.2" + "@thi.ng/api": "^5.0.0", + "@thi.ng/dcons": "^2.0.0", + "@thi.ng/transducers": "^3.0.0" }, "keywords": [ "cache", @@ -51,4 +51,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/checks/CHANGELOG.md b/packages/checks/CHANGELOG.md index c837a26f87..708cc1d107 100644 --- a/packages/checks/CHANGELOG.md +++ b/packages/checks/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/checks@1.5.14...@thi.ng/checks@2.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [1.5.14](https://github.com/thi-ng/umbrella/compare/@thi.ng/checks@1.5.13...@thi.ng/checks@1.5.14) (2018-12-15) **Note:** Version bump only for package @thi.ng/checks diff --git a/packages/checks/package.json b/packages/checks/package.json index 691204453a..c6cc85562d 100644 --- a/packages/checks/package.json +++ b/packages/checks/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/checks", - "version": "1.5.14", + "version": "2.0.0", "description": "Single-function sub-modules for type, feature & value checks", "module": "./index.js", "main": "./lib/index.js", @@ -52,4 +52,4 @@ "setTimeout": false }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/color/CHANGELOG.md b/packages/color/CHANGELOG.md new file mode 100644 index 0000000000..124aabcebf --- /dev/null +++ b/packages/color/CHANGELOG.md @@ -0,0 +1,32 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# 0.1.0 (2019-01-21) + + +### Bug Fixes + +* **color:** add/update conversions ([a5c53c3](https://github.com/thi-ng/umbrella/commit/a5c53c3)) +* **color:** HCYA field names ([1c28c22](https://github.com/thi-ng/umbrella/commit/1c28c22)) + + +### Features + +* **color:** add alpha()/setAlpha(), add docs, re-exports, update readme ([b849bd1](https://github.com/thi-ng/umbrella/commit/b849bd1)) +* **color:** add convert() fallback, minor other updates ([aa30344](https://github.com/thi-ng/umbrella/commit/aa30344)) +* **color:** add HSI converters, add clampH(), minor refactors ([404ac54](https://github.com/thi-ng/umbrella/commit/404ac54)) +* **color:** add Hue enum, closestHue*() fns, namedHueRgba() ([e7bb46b](https://github.com/thi-ng/umbrella/commit/e7bb46b)) +* **color:** add luminance defmulti ([445b8c1](https://github.com/thi-ng/umbrella/commit/445b8c1)) +* **color:** add more color spaces, refactor, rename, simplify ([e930d73](https://github.com/thi-ng/umbrella/commit/e930d73)) +* **color:** add multiCosineGradient() ([dbbb26c](https://github.com/thi-ng/umbrella/commit/dbbb26c)) +* **color:** add new package ([0b51ef1](https://github.com/thi-ng/umbrella/commit/0b51ef1)) +* **color:** add Porter-Duff ops, pre/post-multiply, update types ([a5d2f98](https://github.com/thi-ng/umbrella/commit/a5d2f98)) +* **color:** add RGBA/HSLA wrapper types, update convert ([610699a](https://github.com/thi-ng/umbrella/commit/610699a)) +* **color:** add/update class wrappers ([5788646](https://github.com/thi-ng/umbrella/commit/5788646)) + + +### Performance Improvements + +* **color:** refactor porterDiff as HOF, update all PD ops, add docs ([714381d](https://github.com/thi-ng/umbrella/commit/714381d)) diff --git a/packages/color/package.json b/packages/color/package.json index abac0592f5..4178733dd0 100644 --- a/packages/color/package.json +++ b/packages/color/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/color", - "version": "0.0.1", + "version": "0.1.0", "description": "TODO", "module": "./index.js", "main": "./lib/index.js", @@ -32,14 +32,14 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/compose": "^0.3.0", - "@thi.ng/defmulti": "^0.7.0", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/math": "^0.2.2", - "@thi.ng/strings": "^0.7.1", - "@thi.ng/transducers": "^2.3.2", - "@thi.ng/vectors": "^1.4.12" + "@thi.ng/api": "^5.0.0", + "@thi.ng/compose": "^1.0.0", + "@thi.ng/defmulti": "^1.0.0", + "@thi.ng/errors": "^1.0.0", + "@thi.ng/math": "^1.0.0", + "@thi.ng/strings": "^1.0.0", + "@thi.ng/transducers": "^3.0.0", + "@thi.ng/vectors": "^2.0.0" }, "keywords": [ "alpha", @@ -75,4 +75,4 @@ "setTimeout": false }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/compare/CHANGELOG.md b/packages/compare/CHANGELOG.md index 7ffe761e26..11965f328f 100644 --- a/packages/compare/CHANGELOG.md +++ b/packages/compare/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/compare@0.1.12...@thi.ng/compare@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.1.12](https://github.com/thi-ng/umbrella/compare/@thi.ng/compare@0.1.11...@thi.ng/compare@0.1.12) (2018-12-15) **Note:** Version bump only for package @thi.ng/compare diff --git a/packages/compare/package.json b/packages/compare/package.json index 981f7a6b36..150f858bea 100644 --- a/packages/compare/package.json +++ b/packages/compare/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/compare", - "version": "0.1.12", + "version": "1.0.0", "description": "Comparator with optional delegation for types implementing @thi.ng/api/ICompare interface", "module": "./index.js", "main": "./lib/index.js", @@ -40,4 +40,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/compose/CHANGELOG.md b/packages/compose/CHANGELOG.md index 4a20608f4a..cace3b7b1d 100644 --- a/packages/compose/CHANGELOG.md +++ b/packages/compose/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/compose@0.3.0...@thi.ng/compose@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + # [0.3.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/compose@0.2.2...@thi.ng/compose@0.3.0) (2018-12-27) diff --git a/packages/compose/package.json b/packages/compose/package.json index a81361a813..29e5d1bd99 100644 --- a/packages/compose/package.json +++ b/packages/compose/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/compose", - "version": "0.3.0", + "version": "1.0.0", "description": "Arity-optimized functional composition helpers", "module": "./index.js", "main": "./lib/index.js", @@ -32,8 +32,8 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/errors": "^0.1.12" + "@thi.ng/api": "^5.0.0", + "@thi.ng/errors": "^1.0.0" }, "keywords": [ "composition", @@ -45,4 +45,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/csp/CHANGELOG.md b/packages/csp/CHANGELOG.md index bd988ac80e..f0b4a64cc0 100644 --- a/packages/csp/CHANGELOG.md +++ b/packages/csp/CHANGELOG.md @@ -3,6 +3,33 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/csp@0.3.79...@thi.ng/csp@1.0.0) (2019-01-21) + + +### Bug Fixes + +* **csp:** disable __State reverse enum lookup ([3b8576f](https://github.com/thi-ng/umbrella/commit/3b8576f)) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.3.79](https://github.com/thi-ng/umbrella/compare/@thi.ng/csp@0.3.78...@thi.ng/csp@0.3.79) (2019-01-02) **Note:** Version bump only for package @thi.ng/csp diff --git a/packages/csp/package.json b/packages/csp/package.json index ab3b139512..2c60fe129a 100644 --- a/packages/csp/package.json +++ b/packages/csp/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/csp", - "version": "0.3.79", + "version": "1.0.0", "description": "ES6 promise based CSP implementation", "module": "./index.js", "main": "./lib/index.js", @@ -36,11 +36,11 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/dcons": "^1.1.23", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/transducers": "^2.3.2" + "@thi.ng/api": "^5.0.0", + "@thi.ng/checks": "^2.0.0", + "@thi.ng/dcons": "^2.0.0", + "@thi.ng/errors": "^1.0.0", + "@thi.ng/transducers": "^3.0.0" }, "keywords": [ "async", @@ -59,4 +59,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/dcons/CHANGELOG.md b/packages/dcons/CHANGELOG.md index f2779c8b8a..292515d22c 100644 --- a/packages/dcons/CHANGELOG.md +++ b/packages/dcons/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/dcons@1.1.23...@thi.ng/dcons@2.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [1.1.23](https://github.com/thi-ng/umbrella/compare/@thi.ng/dcons@1.1.22...@thi.ng/dcons@1.1.23) (2019-01-02) **Note:** Version bump only for package @thi.ng/dcons diff --git a/packages/dcons/package.json b/packages/dcons/package.json index 3695f10345..b82571e97d 100644 --- a/packages/dcons/package.json +++ b/packages/dcons/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/dcons", - "version": "1.1.23", + "version": "2.0.0", "description": "Comprehensive doubly linked list structure w/ iterator support", "module": "./index.js", "main": "./lib/index.js", @@ -32,12 +32,12 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/compare": "^0.1.12", - "@thi.ng/equiv": "^0.1.15", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/transducers": "^2.3.2" + "@thi.ng/api": "^5.0.0", + "@thi.ng/checks": "^2.0.0", + "@thi.ng/compare": "^1.0.0", + "@thi.ng/equiv": "^1.0.0", + "@thi.ng/errors": "^1.0.0", + "@thi.ng/transducers": "^3.0.0" }, "keywords": [ "datastructure", @@ -54,4 +54,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/defmulti/CHANGELOG.md b/packages/defmulti/CHANGELOG.md index 58f149726d..9e6b30d57b 100644 --- a/packages/defmulti/CHANGELOG.md +++ b/packages/defmulti/CHANGELOG.md @@ -3,6 +3,35 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/defmulti@0.7.0...@thi.ng/defmulti@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### Features + +* **defmulti:** add callable() & implementations(), update readme ([fde2db2](https://github.com/thi-ng/umbrella/commit/fde2db2)) +* **defmulti:** add relations() ([4066c80](https://github.com/thi-ng/umbrella/commit/4066c80)) +* **defmulti:** add versions w/ 1 optional typed arg, add .impls() ([125c784](https://github.com/thi-ng/umbrella/commit/125c784)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + # [0.7.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/defmulti@0.6.0...@thi.ng/defmulti@0.7.0) (2019-01-02) diff --git a/packages/defmulti/package.json b/packages/defmulti/package.json index eddf10edd7..9f12d45b34 100644 --- a/packages/defmulti/package.json +++ b/packages/defmulti/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/defmulti", - "version": "0.7.0", + "version": "1.0.0", "description": "Dynamically extensible multiple dispatch via user supplied dispatch function.", "module": "./index.js", "main": "./lib/index.js", @@ -32,8 +32,8 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/errors": "^0.1.12" + "@thi.ng/api": "^5.0.0", + "@thi.ng/errors": "^1.0.0" }, "keywords": [ "ES6", @@ -43,4 +43,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/dgraph/CHANGELOG.md b/packages/dgraph/CHANGELOG.md index edff25c8d2..39bfa51e92 100644 --- a/packages/dgraph/CHANGELOG.md +++ b/packages/dgraph/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/dgraph@0.2.35...@thi.ng/dgraph@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.2.35](https://github.com/thi-ng/umbrella/compare/@thi.ng/dgraph@0.2.34...@thi.ng/dgraph@0.2.35) (2019-01-02) **Note:** Version bump only for package @thi.ng/dgraph diff --git a/packages/dgraph/package.json b/packages/dgraph/package.json index d03047aa40..376cd79d26 100644 --- a/packages/dgraph/package.json +++ b/packages/dgraph/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/dgraph", - "version": "0.2.35", + "version": "1.0.0", "description": "Type-agnostic directed acyclic graph (DAG) & graph operations", "module": "./index.js", "main": "./lib/index.js", @@ -32,11 +32,11 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/associative": "^0.6.23", - "@thi.ng/equiv": "^0.1.15", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/transducers": "^2.3.2" + "@thi.ng/api": "^5.0.0", + "@thi.ng/associative": "^1.0.0", + "@thi.ng/equiv": "^1.0.0", + "@thi.ng/errors": "^1.0.0", + "@thi.ng/transducers": "^3.0.0" }, "keywords": [ "data structure", @@ -50,4 +50,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/diff/CHANGELOG.md b/packages/diff/CHANGELOG.md index 6792f21ef6..44a346679b 100644 --- a/packages/diff/CHANGELOG.md +++ b/packages/diff/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [3.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/diff@2.0.2...@thi.ng/diff@3.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [2.0.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/diff@2.0.1...@thi.ng/diff@2.0.2) (2018-12-15) **Note:** Version bump only for package @thi.ng/diff diff --git a/packages/diff/package.json b/packages/diff/package.json index bbe005f914..cd50811b88 100644 --- a/packages/diff/package.json +++ b/packages/diff/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/diff", - "version": "2.0.2", + "version": "3.0.0", "description": "Array & object Diff", "module": "./index.js", "main": "./lib/index.js", @@ -31,8 +31,8 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/equiv": "^0.1.15" + "@thi.ng/api": "^5.0.0", + "@thi.ng/equiv": "^1.0.0" }, "keywords": [ "additions", @@ -48,4 +48,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/dlogic/CHANGELOG.md b/packages/dlogic/CHANGELOG.md index 3310957fe2..3bdaf3c143 100644 --- a/packages/dlogic/CHANGELOG.md +++ b/packages/dlogic/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/dlogic@0.1.2...@thi.ng/dlogic@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.1.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/dlogic@0.1.1...@thi.ng/dlogic@0.1.2) (2018-12-15) **Note:** Version bump only for package @thi.ng/dlogic diff --git a/packages/dlogic/package.json b/packages/dlogic/package.json index ea427b895b..56e827cf98 100644 --- a/packages/dlogic/package.json +++ b/packages/dlogic/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/dlogic", - "version": "0.1.2", + "version": "1.0.0", "description": "Assorted digital logic ops / constructs.", "module": "./index.js", "main": "./lib/index.js", @@ -45,4 +45,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/dot/CHANGELOG.md b/packages/dot/CHANGELOG.md index 9ed32e593f..29da389568 100644 --- a/packages/dot/CHANGELOG.md +++ b/packages/dot/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/dot@0.1.18...@thi.ng/dot@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.1.18](https://github.com/thi-ng/umbrella/compare/@thi.ng/dot@0.1.17...@thi.ng/dot@0.1.18) (2018-12-15) **Note:** Version bump only for package @thi.ng/dot diff --git a/packages/dot/package.json b/packages/dot/package.json index 0696a6097f..a3f4f66c9a 100644 --- a/packages/dot/package.json +++ b/packages/dot/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/dot", - "version": "0.1.18", + "version": "1.0.0", "description": "Graphviz DOM abstraction as vanilla JS objects & serialization to DOT format", "module": "./index.js", "main": "./lib/index.js", @@ -32,8 +32,8 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14" + "@thi.ng/api": "^5.0.0", + "@thi.ng/checks": "^2.0.0" }, "keywords": [ "ES6", @@ -43,4 +43,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/dsp/CHANGELOG.md b/packages/dsp/CHANGELOG.md index 399f140bd2..9bbeccc5a1 100644 --- a/packages/dsp/CHANGELOG.md +++ b/packages/dsp/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/dsp@0.1.3...@thi.ng/dsp@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.1.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/dsp@0.1.2...@thi.ng/dsp@0.1.3) (2018-12-15) **Note:** Version bump only for package @thi.ng/dsp diff --git a/packages/dsp/package.json b/packages/dsp/package.json index 83d1da83ea..fbb1cf77b2 100644 --- a/packages/dsp/package.json +++ b/packages/dsp/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/dsp", - "version": "0.1.3", + "version": "1.0.0", "description": "Assorted DSP utils, oscillators etc.", "module": "./index.js", "main": "./lib/index.js", @@ -32,7 +32,7 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/math": "^0.2.2" + "@thi.ng/math": "^1.0.0" }, "keywords": [ "additive", @@ -50,4 +50,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/equiv/CHANGELOG.md b/packages/equiv/CHANGELOG.md index 8187f2ab41..b378f3fdad 100644 --- a/packages/equiv/CHANGELOG.md +++ b/packages/equiv/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/equiv@0.1.15...@thi.ng/equiv@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.1.15](https://github.com/thi-ng/umbrella/compare/@thi.ng/equiv@0.1.14...@thi.ng/equiv@0.1.15) (2018-12-15) **Note:** Version bump only for package @thi.ng/equiv diff --git a/packages/equiv/package.json b/packages/equiv/package.json index a3cd21fe3e..0f0fc26c4c 100644 --- a/packages/equiv/package.json +++ b/packages/equiv/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/equiv", - "version": "0.1.15", + "version": "1.0.0", "description": "Extensible deep equivalence checking for any data types", "module": "./index.js", "main": "./lib/index.js", @@ -53,4 +53,4 @@ "setTimeout": false }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/errors/CHANGELOG.md b/packages/errors/CHANGELOG.md index bc2a63cf79..bf519236a3 100644 --- a/packages/errors/CHANGELOG.md +++ b/packages/errors/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/errors@0.1.12...@thi.ng/errors@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.1.12](https://github.com/thi-ng/umbrella/compare/@thi.ng/errors@0.1.11...@thi.ng/errors@0.1.12) (2018-12-15) **Note:** Version bump only for package @thi.ng/errors diff --git a/packages/errors/package.json b/packages/errors/package.json index bc85cb9123..86dd0db302 100644 --- a/packages/errors/package.json +++ b/packages/errors/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/errors", - "version": "0.1.12", + "version": "1.0.0", "description": "Custom error types and helper fns.", "module": "./index.js", "main": "./lib/index.js", @@ -47,4 +47,4 @@ "setTimeout": false }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/fsm/CHANGELOG.md b/packages/fsm/CHANGELOG.md index 423ac08263..f938776a5d 100644 --- a/packages/fsm/CHANGELOG.md +++ b/packages/fsm/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/fsm@0.1.0...@thi.ng/fsm@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + # 0.1.0 (2019-01-04) diff --git a/packages/fsm/package.json b/packages/fsm/package.json index 1d03346c8d..608a0d2882 100644 --- a/packages/fsm/package.json +++ b/packages/fsm/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/fsm", - "version": "0.1.0", + "version": "1.0.0", "description": "Composable primitives for building declarative, transducer based Finite-State machines & parsers for arbitrary data streams", "module": "./index.js", "main": "./lib/index.js", @@ -32,10 +32,10 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/equiv": "^0.1.15", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/transducers": "^2.3.2" + "@thi.ng/api": "^5.0.0", + "@thi.ng/equiv": "^1.0.0", + "@thi.ng/errors": "^1.0.0", + "@thi.ng/transducers": "^3.0.0" }, "keywords": [ "ES6", @@ -55,4 +55,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/geom-accel/CHANGELOG.md b/packages/geom-accel/CHANGELOG.md index e358ad5f98..b3623efc00 100644 --- a/packages/geom-accel/CHANGELOG.md +++ b/packages/geom-accel/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-accel@0.1.11...@thi.ng/geom-accel@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.1.11](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-accel@0.1.10...@thi.ng/geom-accel@0.1.11) (2019-01-02) **Note:** Version bump only for package @thi.ng/geom-accel diff --git a/packages/geom-accel/package.json b/packages/geom-accel/package.json index 6c51e80c8f..3e9e9b0c08 100644 --- a/packages/geom-accel/package.json +++ b/packages/geom-accel/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/geom-accel", - "version": "0.1.11", + "version": "1.0.0", "description": "TODO", "module": "./index.js", "main": "./lib/index.js", @@ -32,11 +32,11 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/heaps": "^0.3.1", - "@thi.ng/math": "^0.2.2", - "@thi.ng/transducers": "^2.3.2", - "@thi.ng/vectors": "^1.4.12" + "@thi.ng/api": "^5.0.0", + "@thi.ng/heaps": "^1.0.0", + "@thi.ng/math": "^1.0.0", + "@thi.ng/transducers": "^3.0.0", + "@thi.ng/vectors": "^2.0.0" }, "keywords": [ "ES6", @@ -52,4 +52,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/geom/CHANGELOG.md b/packages/geom/CHANGELOG.md index 75e96a8045..879213da37 100644 --- a/packages/geom/CHANGELOG.md +++ b/packages/geom/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom@0.2.11...@thi.ng/geom@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.2.11](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom@0.2.10...@thi.ng/geom@0.2.11) (2019-01-02) **Note:** Version bump only for package @thi.ng/geom diff --git a/packages/geom/package.json b/packages/geom/package.json index db7df7b2c6..37ebbee985 100644 --- a/packages/geom/package.json +++ b/packages/geom/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/geom", - "version": "0.0.1", + "version": "1.0.0", "description": "TODO", "module": "./index.js", "main": "./lib/index.js", @@ -32,19 +32,19 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/compose": "^0.3.0", - "@thi.ng/defmulti": "^0.7.0", - "@thi.ng/equiv": "^0.1.15", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/hiccup": "^2.7.2", - "@thi.ng/hiccup-svg": "^2.0.10", - "@thi.ng/math": "^0.2.2", - "@thi.ng/matrices": "^0.0.1", - "@thi.ng/random": "^0.1.1", - "@thi.ng/transducers": "^2.3.2", - "@thi.ng/vectors": "^1.4.12" + "@thi.ng/api": "^5.0.0", + "@thi.ng/checks": "^2.0.0", + "@thi.ng/compose": "^1.0.0", + "@thi.ng/defmulti": "^1.0.0", + "@thi.ng/equiv": "^1.0.0", + "@thi.ng/errors": "^1.0.0", + "@thi.ng/hiccup": "^3.0.0", + "@thi.ng/hiccup-svg": "^3.0.0", + "@thi.ng/math": "^1.0.0", + "@thi.ng/matrices": "^0.1.0", + "@thi.ng/random": "^1.0.0", + "@thi.ng/transducers": "^3.0.0", + "@thi.ng/vectors": "^2.0.0" }, "keywords": [ "ES6", @@ -54,4 +54,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/hdom-canvas/CHANGELOG.md b/packages/hdom-canvas/CHANGELOG.md index ab27843848..0b5b916dc7 100644 --- a/packages/hdom-canvas/CHANGELOG.md +++ b/packages/hdom-canvas/CHANGELOG.md @@ -3,6 +3,33 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-canvas@0.1.20...@thi.ng/hdom-canvas@1.0.0) (2019-01-21) + + +### Build System + +* update package scripts, outputs, imports in remaining packages ([f912a84](https://github.com/thi-ng/umbrella/commit/f912a84)) + + +### Features + +* **hdom-canvas:** add ellipse() / ellipticArc(), update readme ([9a50769](https://github.com/thi-ng/umbrella/commit/9a50769)) + + +### BREAKING CHANGES + +* enable multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols + + + + + ## [0.1.20](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-canvas@0.1.19...@thi.ng/hdom-canvas@0.1.20) (2018-12-21) **Note:** Version bump only for package @thi.ng/hdom-canvas diff --git a/packages/hdom-canvas/package.json b/packages/hdom-canvas/package.json index 505d1a67f5..278631c758 100644 --- a/packages/hdom-canvas/package.json +++ b/packages/hdom-canvas/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hdom-canvas", - "version": "0.1.20", + "version": "1.0.0", "description": "Declarative canvas scenegraph & visualization for @thi.ng/hdom", "module": "./index.js", "main": "./lib/index.js", @@ -32,10 +32,10 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/diff": "^2.0.2", - "@thi.ng/hdom": "^6.1.0" + "@thi.ng/api": "^5.0.0", + "@thi.ng/checks": "^2.0.0", + "@thi.ng/diff": "^3.0.0", + "@thi.ng/hdom": "^7.0.0" }, "keywords": [ "ES6", @@ -52,4 +52,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/hdom-components/CHANGELOG.md b/packages/hdom-components/CHANGELOG.md index 1de99ff2fd..526aa9657e 100644 --- a/packages/hdom-components/CHANGELOG.md +++ b/packages/hdom-components/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [3.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-components@2.4.6...@thi.ng/hdom-components@3.0.0) (2019-01-21) + + +### Build System + +* update package scripts, outputs, imports in remaining packages ([f912a84](https://github.com/thi-ng/umbrella/commit/f912a84)) + + +### BREAKING CHANGES + +* enable multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols + + + + + ## [2.4.6](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-components@2.4.5...@thi.ng/hdom-components@2.4.6) (2019-01-02) **Note:** Version bump only for package @thi.ng/hdom-components diff --git a/packages/hdom-components/package.json b/packages/hdom-components/package.json index d246a91ec6..296dd44b78 100644 --- a/packages/hdom-components/package.json +++ b/packages/hdom-components/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hdom-components", - "version": "2.4.6", + "version": "3.0.0", "description": "Raw, skinnable UI & SVG components for @thi.ng/hdom", "module": "./index.js", "main": "./lib/index.js", @@ -32,11 +32,11 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/math": "^0.2.2", - "@thi.ng/transducers": "^2.3.2", - "@thi.ng/transducers-stats": "^0.4.23", + "@thi.ng/api": "^5.0.0", + "@thi.ng/checks": "^2.0.0", + "@thi.ng/math": "^1.0.0", + "@thi.ng/transducers": "^3.0.0", + "@thi.ng/transducers-stats": "^1.0.0", "@types/webgl2": "^0.0.4" }, "keywords": [ @@ -47,4 +47,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/hdom-mock/CHANGELOG.md b/packages/hdom-mock/CHANGELOG.md index 5d9850d6e6..3d5c4f982b 100644 --- a/packages/hdom-mock/CHANGELOG.md +++ b/packages/hdom-mock/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-mock@0.1.5...@thi.ng/hdom-mock@1.0.0) (2019-01-21) + + +### Build System + +* update package scripts, outputs, imports in remaining packages ([f912a84](https://github.com/thi-ng/umbrella/commit/f912a84)) + + +### BREAKING CHANGES + +* enable multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols + + + + + ## [0.1.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-mock@0.1.4...@thi.ng/hdom-mock@0.1.5) (2018-12-21) **Note:** Version bump only for package @thi.ng/hdom-mock diff --git a/packages/hdom-mock/package.json b/packages/hdom-mock/package.json index acadd78cdc..71156c44df 100644 --- a/packages/hdom-mock/package.json +++ b/packages/hdom-mock/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hdom-mock", - "version": "0.1.5", + "version": "1.0.0", "description": "Mock base implementation for @thi.ng/hdom API", "module": "./index.js", "main": "./lib/index.js", @@ -32,9 +32,9 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/hdom": "^6.1.0" + "@thi.ng/api": "^5.0.0", + "@thi.ng/checks": "^2.0.0", + "@thi.ng/hdom": "^7.0.0" }, "keywords": [ "ES6", @@ -44,4 +44,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/hdom/CHANGELOG.md b/packages/hdom/CHANGELOG.md index ae3cc921ba..3ae0dec008 100644 --- a/packages/hdom/CHANGELOG.md +++ b/packages/hdom/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [7.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom@6.1.0...@thi.ng/hdom@7.0.0) (2019-01-21) + + +### Build System + +* update package scripts, outputs, imports in remaining packages ([f912a84](https://github.com/thi-ng/umbrella/commit/f912a84)) + + +### BREAKING CHANGES + +* enable multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols + + + + + # [6.1.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom@6.0.4...@thi.ng/hdom@6.1.0) (2018-12-21) diff --git a/packages/hdom/package.json b/packages/hdom/package.json index 78b605829c..3b3e6b5d58 100644 --- a/packages/hdom/package.json +++ b/packages/hdom/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hdom", - "version": "6.1.0", + "version": "7.0.0", "description": "Lightweight vanilla ES6 UI component trees with customizable branch-local behaviors", "module": "./index.js", "main": "./lib/index.js", @@ -24,7 +24,7 @@ "pub": "yarn build && yarn publish --access public" }, "devDependencies": { - "@thi.ng/atom": "^1.5.8", + "@thi.ng/atom": "^2.0.0", "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", @@ -33,12 +33,12 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/diff": "^2.0.2", - "@thi.ng/equiv": "^0.1.15", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/hiccup": "^2.7.2" + "@thi.ng/api": "^5.0.0", + "@thi.ng/checks": "^2.0.0", + "@thi.ng/diff": "^3.0.0", + "@thi.ng/equiv": "^1.0.0", + "@thi.ng/errors": "^1.0.0", + "@thi.ng/hiccup": "^3.0.0" }, "keywords": [ "browser", @@ -60,4 +60,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/heaps/CHANGELOG.md b/packages/heaps/CHANGELOG.md index 056704c073..fa1d779d45 100644 --- a/packages/heaps/CHANGELOG.md +++ b/packages/heaps/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/heaps@0.3.1...@thi.ng/heaps@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.3.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/heaps@0.3.0...@thi.ng/heaps@0.3.1) (2018-12-15) **Note:** Version bump only for package @thi.ng/heaps diff --git a/packages/heaps/package.json b/packages/heaps/package.json index 80b1811122..e0f21658dd 100644 --- a/packages/heaps/package.json +++ b/packages/heaps/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/heaps", - "version": "0.3.1", + "version": "1.0.0", "description": "Generic binary heap & d-ary heap implementations with customizable ordering", "module": "./index.js", "main": "./lib/index.js", @@ -32,8 +32,8 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/compare": "^0.1.12" + "@thi.ng/api": "^5.0.0", + "@thi.ng/compare": "^1.0.0" }, "keywords": [ "data structure", @@ -48,4 +48,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/hiccup-carbon-icons/CHANGELOG.md b/packages/hiccup-carbon-icons/CHANGELOG.md index d42079d733..7239c89aab 100644 --- a/packages/hiccup-carbon-icons/CHANGELOG.md +++ b/packages/hiccup-carbon-icons/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-carbon-icons@0.1.2...@thi.ng/hiccup-carbon-icons@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.1.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-carbon-icons@0.1.1...@thi.ng/hiccup-carbon-icons@0.1.2) (2018-12-20) **Note:** Version bump only for package @thi.ng/hiccup-carbon-icons diff --git a/packages/hiccup-carbon-icons/package.json b/packages/hiccup-carbon-icons/package.json index 636cab1374..0e4d36efd3 100644 --- a/packages/hiccup-carbon-icons/package.json +++ b/packages/hiccup-carbon-icons/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hiccup-carbon-icons", - "version": "0.1.2", + "version": "1.0.0", "description": "TODO", "module": "./index.js", "main": "./lib/index.js", @@ -24,7 +24,7 @@ "pub": "yarn build && yarn publish --access public" }, "devDependencies": { - "@thi.ng/hiccup": "^2.7.2", + "@thi.ng/hiccup": "^3.0.0", "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", @@ -48,4 +48,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/hiccup-css/CHANGELOG.md b/packages/hiccup-css/CHANGELOG.md index 83c82328a8..aadbde1d55 100644 --- a/packages/hiccup-css/CHANGELOG.md +++ b/packages/hiccup-css/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-css@0.3.5...@thi.ng/hiccup-css@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.3.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-css@0.3.4...@thi.ng/hiccup-css@0.3.5) (2019-01-02) **Note:** Version bump only for package @thi.ng/hiccup-css diff --git a/packages/hiccup-css/package.json b/packages/hiccup-css/package.json index 18f9f4d00c..7c7c2c4a78 100644 --- a/packages/hiccup-css/package.json +++ b/packages/hiccup-css/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hiccup-css", - "version": "0.3.5", + "version": "1.0.0", "description": "CSS from nested JS data structures", "module": "./index.js", "main": "./lib/index.js", @@ -32,10 +32,10 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/transducers": "^2.3.2" + "@thi.ng/api": "^5.0.0", + "@thi.ng/checks": "^2.0.0", + "@thi.ng/errors": "^1.0.0", + "@thi.ng/transducers": "^3.0.0" }, "keywords": [ "clojure", @@ -55,4 +55,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/hiccup-markdown/CHANGELOG.md b/packages/hiccup-markdown/CHANGELOG.md index 7c428c670c..36d8250a46 100644 --- a/packages/hiccup-markdown/CHANGELOG.md +++ b/packages/hiccup-markdown/CHANGELOG.md @@ -3,6 +3,33 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-markdown@0.2.0...@thi.ng/hiccup-markdown@1.0.0) (2019-01-21) + + +### Bug Fixes + +* **hiccup-markdown:** re-export TagFactories interface ([b198c19](https://github.com/thi-ng/umbrella/commit/b198c19)) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + # [0.2.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-markdown@0.1.2...@thi.ng/hiccup-markdown@0.2.0) (2019-01-04) diff --git a/packages/hiccup-markdown/package.json b/packages/hiccup-markdown/package.json index 8f5fd411bc..6e37750985 100644 --- a/packages/hiccup-markdown/package.json +++ b/packages/hiccup-markdown/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hiccup-markdown", - "version": "0.2.0", + "version": "1.0.0", "description": "Markdown serialization of hiccup DOM trees", "module": "./index.js", "main": "./lib/index.js", @@ -32,13 +32,13 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/checks": "^1.5.14", - "@thi.ng/defmulti": "^0.7.0", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/fsm": "^0.1.0", - "@thi.ng/hiccup": "^2.7.2", - "@thi.ng/strings": "^0.7.1", - "@thi.ng/transducers": "^2.3.2" + "@thi.ng/checks": "^2.0.0", + "@thi.ng/defmulti": "^1.0.0", + "@thi.ng/errors": "^1.0.0", + "@thi.ng/fsm": "^1.0.0", + "@thi.ng/hiccup": "^3.0.0", + "@thi.ng/strings": "^1.0.0", + "@thi.ng/transducers": "^3.0.0" }, "keywords": [ "ES6", @@ -56,4 +56,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/hiccup-svg/CHANGELOG.md b/packages/hiccup-svg/CHANGELOG.md index e131eaa00a..84f6e8a32b 100644 --- a/packages/hiccup-svg/CHANGELOG.md +++ b/packages/hiccup-svg/CHANGELOG.md @@ -3,6 +3,44 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [3.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-svg@2.0.10...@thi.ng/hiccup-svg@3.0.0) (2019-01-21) + + +### Bug Fixes + +* **hiccup-svg:** convert path arc segment axis theta to degrees ([370f928](https://github.com/thi-ng/umbrella/commit/370f928)) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### Features + +* **hiccup-svg:** add ellipse shape type, update convert() ([a39811c](https://github.com/thi-ng/umbrella/commit/a39811c)) +* **hiccup-svg:** add toHiccup() support in convertTree() ([e197f90](https://github.com/thi-ng/umbrella/commit/e197f90)) + + +### Reverts + +* **hiccup-svg:** undo merge mistake in convert.ts ([82f8ef2](https://github.com/thi-ng/umbrella/commit/82f8ef2)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [2.0.10](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-svg@2.0.9...@thi.ng/hiccup-svg@2.0.10) (2018-12-20) **Note:** Version bump only for package @thi.ng/hiccup-svg diff --git a/packages/hiccup-svg/package.json b/packages/hiccup-svg/package.json index 92088159b3..1bc10d8ca2 100644 --- a/packages/hiccup-svg/package.json +++ b/packages/hiccup-svg/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hiccup-svg", - "version": "2.0.10", + "version": "3.0.0", "description": "SVG element functions for @thi.ng/hiccup & @thi.ng/hdom", "module": "./index.js", "main": "./lib/index.js", @@ -32,8 +32,8 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/checks": "^1.5.14", - "@thi.ng/hiccup": "^2.7.2" + "@thi.ng/checks": "^2.0.0", + "@thi.ng/hiccup": "^3.0.0" }, "keywords": [ "components", @@ -52,4 +52,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/hiccup/CHANGELOG.md b/packages/hiccup/CHANGELOG.md index 177698e40f..ff3a004dac 100644 --- a/packages/hiccup/CHANGELOG.md +++ b/packages/hiccup/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [3.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup@2.7.2...@thi.ng/hiccup@3.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [2.7.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup@2.7.1...@thi.ng/hiccup@2.7.2) (2018-12-20) **Note:** Version bump only for package @thi.ng/hiccup diff --git a/packages/hiccup/package.json b/packages/hiccup/package.json index 4f22894840..8abd498f15 100644 --- a/packages/hiccup/package.json +++ b/packages/hiccup/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hiccup", - "version": "2.7.2", + "version": "3.0.0", "description": "HTML/SVG/XML serialization of nested data structures, iterables & closures", "module": "./index.js", "main": "./lib/index.js", @@ -24,7 +24,7 @@ "pub": "yarn build && yarn publish --access public" }, "devDependencies": { - "@thi.ng/atom": "^1.5.8", + "@thi.ng/atom": "^2.0.0", "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", @@ -33,8 +33,8 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/checks": "^1.5.14", - "@thi.ng/errors": "^0.1.12" + "@thi.ng/checks": "^2.0.0", + "@thi.ng/errors": "^1.0.0" }, "keywords": [ "clojure", @@ -54,4 +54,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/iges/CHANGELOG.md b/packages/iges/CHANGELOG.md index 0a66d5283c..c7855c10f5 100644 --- a/packages/iges/CHANGELOG.md +++ b/packages/iges/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/iges@0.2.30...@thi.ng/iges@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.2.30](https://github.com/thi-ng/umbrella/compare/@thi.ng/iges@0.2.29...@thi.ng/iges@0.2.30) (2019-01-02) **Note:** Version bump only for package @thi.ng/iges diff --git a/packages/iges/package.json b/packages/iges/package.json index 7d1d7e824d..b488c84179 100644 --- a/packages/iges/package.json +++ b/packages/iges/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/iges", - "version": "0.2.30", + "version": "1.0.0", "description": "IGES 5.3 serializer for (currently only) polygonal geometry, both open & closed", "module": "./index.js", "main": "./lib/index.js", @@ -32,10 +32,10 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/defmulti": "^0.7.0", - "@thi.ng/strings": "^0.7.1", - "@thi.ng/transducers": "^2.3.2" + "@thi.ng/api": "^5.0.0", + "@thi.ng/defmulti": "^1.0.0", + "@thi.ng/strings": "^1.0.0", + "@thi.ng/transducers": "^3.0.0" }, "keywords": [ "CAD", @@ -50,4 +50,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/interceptors/CHANGELOG.md b/packages/interceptors/CHANGELOG.md index 1422eddafe..7402e9341d 100644 --- a/packages/interceptors/CHANGELOG.md +++ b/packages/interceptors/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/interceptors@1.9.2...@thi.ng/interceptors@2.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [1.9.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/interceptors@1.9.1...@thi.ng/interceptors@1.9.2) (2018-12-15) **Note:** Version bump only for package @thi.ng/interceptors diff --git a/packages/interceptors/package.json b/packages/interceptors/package.json index 0df9b10a38..ab184f010d 100644 --- a/packages/interceptors/package.json +++ b/packages/interceptors/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/interceptors", - "version": "1.9.2", + "version": "2.0.0", "description": "Interceptor based event bus, side effect & immutable state handling", "module": "./index.js", "main": "./lib/index.js", @@ -32,11 +32,11 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/atom": "^1.5.8", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/paths": "^1.6.6" + "@thi.ng/api": "^5.0.0", + "@thi.ng/atom": "^2.0.0", + "@thi.ng/checks": "^2.0.0", + "@thi.ng/errors": "^1.0.0", + "@thi.ng/paths": "^2.0.0" }, "keywords": [ "ES6", @@ -46,4 +46,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/intervals/CHANGELOG.md b/packages/intervals/CHANGELOG.md index 85cca15c44..423e18d0f7 100644 --- a/packages/intervals/CHANGELOG.md +++ b/packages/intervals/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/intervals@0.2.0...@thi.ng/intervals@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + # [0.2.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/intervals@0.1.0...@thi.ng/intervals@0.2.0) (2018-12-19) diff --git a/packages/intervals/package.json b/packages/intervals/package.json index 5def147018..5a24e48e5f 100644 --- a/packages/intervals/package.json +++ b/packages/intervals/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/intervals", - "version": "0.2.0", + "version": "1.0.0", "description": "Closed/open/semi-open interval data type, queries & operations", "module": "./index.js", "main": "./lib/index.js", @@ -32,8 +32,8 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/errors": "^0.1.12" + "@thi.ng/api": "^5.0.0", + "@thi.ng/errors": "^1.0.0" }, "keywords": [ "ES6", @@ -51,4 +51,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/iterators/CHANGELOG.md b/packages/iterators/CHANGELOG.md index d3189930c0..d9d7574138 100644 --- a/packages/iterators/CHANGELOG.md +++ b/packages/iterators/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/iterators@4.2.4...@thi.ng/iterators@5.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [4.2.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/iterators@4.2.3...@thi.ng/iterators@4.2.4) (2019-01-02) **Note:** Version bump only for package @thi.ng/iterators diff --git a/packages/iterators/package.json b/packages/iterators/package.json index c367001ae8..f59521f120 100644 --- a/packages/iterators/package.json +++ b/packages/iterators/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/iterators", - "version": "4.2.4", + "version": "5.0.0", "description": "clojure.core inspired, composable ES6 iterators & generators", "module": "./index.js", "main": "./lib/index.js", @@ -32,9 +32,9 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/dcons": "^1.1.23", - "@thi.ng/errors": "^0.1.12" + "@thi.ng/api": "^5.0.0", + "@thi.ng/dcons": "^2.0.0", + "@thi.ng/errors": "^1.0.0" }, "keywords": [ "clojure", @@ -51,4 +51,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/malloc/CHANGELOG.md b/packages/malloc/CHANGELOG.md index 0a1c97fe9a..91990e02f5 100644 --- a/packages/malloc/CHANGELOG.md +++ b/packages/malloc/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/malloc@0.2.1...@thi.ng/malloc@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.2.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/malloc@0.2.0...@thi.ng/malloc@0.2.1) (2018-12-15) **Note:** Version bump only for package @thi.ng/malloc diff --git a/packages/malloc/package.json b/packages/malloc/package.json index 2fff668e8a..91825e72a9 100644 --- a/packages/malloc/package.json +++ b/packages/malloc/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/malloc", - "version": "0.2.1", + "version": "1.0.0", "description": "ArrayBuffer based malloc() impl for hybrid JS/WASM use cases, based on thi.ng/tinyalloc", "module": "./index.js", "main": "./lib/index.js", @@ -32,10 +32,10 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/binary": "^0.1.2", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/errors": "^0.1.12" + "@thi.ng/api": "^5.0.0", + "@thi.ng/binary": "^1.0.0", + "@thi.ng/checks": "^2.0.0", + "@thi.ng/errors": "^1.0.0" }, "keywords": [ "ES6", @@ -45,4 +45,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/math/CHANGELOG.md b/packages/math/CHANGELOG.md index d038224957..b8aeb22b22 100644 --- a/packages/math/CHANGELOG.md +++ b/packages/math/CHANGELOG.md @@ -3,6 +3,36 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/math@0.2.2...@thi.ng/math@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### Features + +* **math:** add absInnerAngle() ([a78bd87](https://github.com/thi-ng/umbrella/commit/a78bd87)) +* **math:** add constants ([8fa05c3](https://github.com/thi-ng/umbrella/commit/8fa05c3)) +* **math:** add cossin(), add opt scale arg for sincos() ([0043fb5](https://github.com/thi-ng/umbrella/commit/0043fb5)) +* **math:** update eqDelta w/ adaptive eps, rename old => eqDeltaFixed ([5018009](https://github.com/thi-ng/umbrella/commit/5018009)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.2.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/math@0.2.1...@thi.ng/math@0.2.2) (2018-12-15) **Note:** Version bump only for package @thi.ng/math diff --git a/packages/math/package.json b/packages/math/package.json index a7becea398..34d4ff5bde 100644 --- a/packages/math/package.json +++ b/packages/math/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/math", - "version": "0.2.2", + "version": "1.0.0", "description": "Assorted common math functions & utilities", "module": "./index.js", "main": "./lib/index.js", @@ -44,4 +44,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/matrices/CHANGELOG.md b/packages/matrices/CHANGELOG.md new file mode 100644 index 0000000000..7ec878a352 --- /dev/null +++ b/packages/matrices/CHANGELOG.md @@ -0,0 +1,33 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# 0.1.0 (2019-01-21) + + +### Bug Fixes + +* **matrices:** inject default output handling code ([0b07ac8](https://github.com/thi-ng/umbrella/commit/0b07ac8)) +* **matrices:** re-add persp divide in mulV344() ([4c6fe06](https://github.com/thi-ng/umbrella/commit/4c6fe06)) +* **matrices:** scaleWithCenter* (add missing concat() arg) ([4f02491](https://github.com/thi-ng/umbrella/commit/4f02491)) + + +### Features + +* **matrices:** add cwise matrix multiply, rename mul* => mulM*, move mulQ ([ae7a039](https://github.com/thi-ng/umbrella/commit/ae7a039)) +* **matrices:** add m22 & m23 matrix converters ([2aceab9](https://github.com/thi-ng/umbrella/commit/2aceab9)) +* **matrices:** add M44 factories ([f1a5cf1](https://github.com/thi-ng/umbrella/commit/f1a5cf1)) +* **matrices:** add more matrix ops ([35babfc](https://github.com/thi-ng/umbrella/commit/35babfc)) +* **matrices:** add more matrix ops, optimize & simplify ([f04e79e](https://github.com/thi-ng/umbrella/commit/f04e79e)) +* **matrices:** add quaternion fns ([b03b919](https://github.com/thi-ng/umbrella/commit/b03b919)) +* **matrices:** add quatToMat33, update readme ([52fb939](https://github.com/thi-ng/umbrella/commit/52fb939)) +* **matrices:** add rotationAroundAxis33/44() ([27f65f9](https://github.com/thi-ng/umbrella/commit/27f65f9)) +* **matrices:** add trace() ([16d56a3](https://github.com/thi-ng/umbrella/commit/16d56a3)) +* **matrices:** add viewport(), project/unproject(), update invert() ([d9e1b2e](https://github.com/thi-ng/umbrella/commit/d9e1b2e)) +* **matrices:** extract matrix ops to own package ([f940672](https://github.com/thi-ng/umbrella/commit/f940672)) + + +### Performance Improvements + +* **matrices:** use setC6() for M23 ops ([d462ae0](https://github.com/thi-ng/umbrella/commit/d462ae0)) diff --git a/packages/matrices/package.json b/packages/matrices/package.json index c7a3ac197a..94d7fbbf9b 100644 --- a/packages/matrices/package.json +++ b/packages/matrices/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/matrices", - "version": "0.0.1", + "version": "0.1.0", "description": "Matrix & quaternion operations for 2D/3D geometry processing", "module": "./index.js", "main": "./lib/index.js", @@ -32,10 +32,10 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/math": "^0.2.2", - "@thi.ng/vectors": "^1.4.12" + "@thi.ng/api": "^5.0.0", + "@thi.ng/checks": "^2.0.0", + "@thi.ng/math": "^1.0.0", + "@thi.ng/vectors": "^2.0.0" }, "keywords": [ "2D", @@ -78,4 +78,4 @@ "setTimeout": false }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/memoize/CHANGELOG.md b/packages/memoize/CHANGELOG.md index 0ff46c457b..3c66f548a1 100644 --- a/packages/memoize/CHANGELOG.md +++ b/packages/memoize/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/memoize@0.2.6...@thi.ng/memoize@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.2.6](https://github.com/thi-ng/umbrella/compare/@thi.ng/memoize@0.2.5...@thi.ng/memoize@0.2.6) (2018-12-15) **Note:** Version bump only for package @thi.ng/memoize diff --git a/packages/memoize/package.json b/packages/memoize/package.json index c3743dea12..82e5631915 100644 --- a/packages/memoize/package.json +++ b/packages/memoize/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/memoize", - "version": "0.2.6", + "version": "1.0.0", "description": "Function memoization with configurable caches", "module": "./index.js", "main": "./lib/index.js", @@ -32,7 +32,7 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4" + "@thi.ng/api": "^5.0.0" }, "keywords": [ "cache", @@ -45,4 +45,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/morton/CHANGELOG.md b/packages/morton/CHANGELOG.md index 9d7c059b4b..c18e39cfe8 100644 --- a/packages/morton/CHANGELOG.md +++ b/packages/morton/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/morton@0.2.2...@thi.ng/morton@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.2.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/morton@0.2.1...@thi.ng/morton@0.2.2) (2018-12-15) **Note:** Version bump only for package @thi.ng/morton diff --git a/packages/morton/package.json b/packages/morton/package.json index 9e51bf51b3..823c9196e0 100644 --- a/packages/morton/package.json +++ b/packages/morton/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/morton", - "version": "0.2.2", + "version": "1.0.0", "description": "Z-order-curve / Morton encoding & decoding for 1D, 2D, 3D", "module": "./index.js", "main": "./lib/index.js", @@ -32,9 +32,9 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/binary": "^0.1.2", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/math": "^0.2.2" + "@thi.ng/binary": "^1.0.0", + "@thi.ng/errors": "^1.0.0", + "@thi.ng/math": "^1.0.0" }, "keywords": [ "binary", @@ -49,4 +49,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/paths/CHANGELOG.md b/packages/paths/CHANGELOG.md index e72a2d9f58..91168ca78a 100644 --- a/packages/paths/CHANGELOG.md +++ b/packages/paths/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/paths@1.6.6...@thi.ng/paths@2.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [1.6.6](https://github.com/thi-ng/umbrella/compare/@thi.ng/paths@1.6.5...@thi.ng/paths@1.6.6) (2018-12-15) **Note:** Version bump only for package @thi.ng/paths diff --git a/packages/paths/package.json b/packages/paths/package.json index 4812cd6513..546413873c 100644 --- a/packages/paths/package.json +++ b/packages/paths/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/paths", - "version": "1.6.6", + "version": "2.0.0", "description": "immutable, optimized path-based object property / array accessors", "module": "./index.js", "main": "./lib/index.js", @@ -32,8 +32,8 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/checks": "^1.5.14", - "@thi.ng/errors": "^0.1.12" + "@thi.ng/checks": "^2.0.0", + "@thi.ng/errors": "^1.0.0" }, "keywords": [ "accessors", @@ -61,4 +61,4 @@ "setTimeout": false }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/pointfree-lang/CHANGELOG.md b/packages/pointfree-lang/CHANGELOG.md index b8854e36b3..c65c889e0f 100644 --- a/packages/pointfree-lang/CHANGELOG.md +++ b/packages/pointfree-lang/CHANGELOG.md @@ -3,6 +3,33 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/pointfree-lang@0.2.27...@thi.ng/pointfree-lang@1.0.0) (2019-01-21) + + +### Bug Fixes + +* **pointfree-lang:** update NodeType handling ([227be4b](https://github.com/thi-ng/umbrella/commit/227be4b)) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.2.27](https://github.com/thi-ng/umbrella/compare/@thi.ng/pointfree-lang@0.2.26...@thi.ng/pointfree-lang@0.2.27) (2018-12-27) **Note:** Version bump only for package @thi.ng/pointfree-lang diff --git a/packages/pointfree-lang/package.json b/packages/pointfree-lang/package.json index 2d3c2d3c3d..a4b69be362 100644 --- a/packages/pointfree-lang/package.json +++ b/packages/pointfree-lang/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/pointfree-lang", - "version": "0.2.27", + "version": "1.0.0", "description": "Forth style syntax layer/compiler for the @thi.ng/pointfree DSL", "module": "./index.js", "main": "./lib/index.js", @@ -34,9 +34,9 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/pointfree": "^0.8.15" + "@thi.ng/api": "^5.0.0", + "@thi.ng/errors": "^1.0.0", + "@thi.ng/pointfree": "^1.0.0" }, "keywords": [ "concatenative", @@ -55,4 +55,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/pointfree/CHANGELOG.md b/packages/pointfree/CHANGELOG.md index e8c495ec94..4fbff911cd 100644 --- a/packages/pointfree/CHANGELOG.md +++ b/packages/pointfree/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/pointfree@0.8.15...@thi.ng/pointfree@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.8.15](https://github.com/thi-ng/umbrella/compare/@thi.ng/pointfree@0.8.14...@thi.ng/pointfree@0.8.15) (2018-12-27) **Note:** Version bump only for package @thi.ng/pointfree diff --git a/packages/pointfree/package.json b/packages/pointfree/package.json index 1014a41bef..cb89eb2cb1 100644 --- a/packages/pointfree/package.json +++ b/packages/pointfree/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/pointfree", - "version": "0.8.15", + "version": "1.0.0", "description": "Pointfree functional composition / Forth style stack execution engine", "module": "./index.js", "main": "./lib/index.js", @@ -32,11 +32,11 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/compose": "^0.3.0", - "@thi.ng/equiv": "^0.1.15", - "@thi.ng/errors": "^0.1.12" + "@thi.ng/api": "^5.0.0", + "@thi.ng/checks": "^2.0.0", + "@thi.ng/compose": "^1.0.0", + "@thi.ng/equiv": "^1.0.0", + "@thi.ng/errors": "^1.0.0" }, "keywords": [ "composition", @@ -56,4 +56,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/random/CHANGELOG.md b/packages/random/CHANGELOG.md index 1dfc3f5d48..9330e00463 100644 --- a/packages/random/CHANGELOG.md +++ b/packages/random/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/random@0.1.1...@thi.ng/random@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.1.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/random@0.1.0...@thi.ng/random@0.1.1) (2018-12-15) **Note:** Version bump only for package @thi.ng/random diff --git a/packages/random/package.json b/packages/random/package.json index 0c917cb8f9..00ba040dbb 100644 --- a/packages/random/package.json +++ b/packages/random/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/random", - "version": "0.1.1", + "version": "1.0.0", "description": "Pseudo-random number generators w/ unified API", "module": "./index.js", "main": "./lib/index.js", @@ -32,7 +32,7 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4" + "@thi.ng/api": "^5.0.0" }, "keywords": [ "ES6", @@ -45,4 +45,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/range-coder/CHANGELOG.md b/packages/range-coder/CHANGELOG.md index 7d2972e050..b96cd8d8cb 100644 --- a/packages/range-coder/CHANGELOG.md +++ b/packages/range-coder/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/range-coder@0.1.28...@thi.ng/range-coder@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.1.28](https://github.com/thi-ng/umbrella/compare/@thi.ng/range-coder@0.1.27...@thi.ng/range-coder@0.1.28) (2019-01-02) **Note:** Version bump only for package @thi.ng/range-coder diff --git a/packages/range-coder/package.json b/packages/range-coder/package.json index 262d62bf26..6f82c68a65 100644 --- a/packages/range-coder/package.json +++ b/packages/range-coder/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/range-coder", - "version": "0.1.28", + "version": "1.0.0", "description": "Binary data range encoder / decoder", "module": "./index.js", "main": "./lib/index.js", @@ -24,7 +24,7 @@ "pub": "yarn build && yarn publish --access public" }, "devDependencies": { - "@thi.ng/transducers": "^2.3.2", + "@thi.ng/transducers": "^3.0.0", "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", "mocha": "^5.2.0", @@ -33,7 +33,7 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/bitstream": "^0.4.21" + "@thi.ng/bitstream": "^1.0.0" }, "keywords": [ "ES6", @@ -47,4 +47,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/resolve-map/CHANGELOG.md b/packages/resolve-map/CHANGELOG.md index f8a225ad7d..794844be41 100644 --- a/packages/resolve-map/CHANGELOG.md +++ b/packages/resolve-map/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [4.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/resolve-map@3.0.16...@thi.ng/resolve-map@4.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [3.0.16](https://github.com/thi-ng/umbrella/compare/@thi.ng/resolve-map@3.0.15...@thi.ng/resolve-map@3.0.16) (2018-12-15) **Note:** Version bump only for package @thi.ng/resolve-map diff --git a/packages/resolve-map/package.json b/packages/resolve-map/package.json index 164c9db410..68b0af4480 100644 --- a/packages/resolve-map/package.json +++ b/packages/resolve-map/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/resolve-map", - "version": "3.0.16", + "version": "4.0.0", "description": "DAG resolution of vanilla objects & arrays with internally linked values", "module": "./index.js", "main": "./lib/index.js", @@ -31,10 +31,10 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/paths": "^1.6.6" + "@thi.ng/api": "^5.0.0", + "@thi.ng/checks": "^2.0.0", + "@thi.ng/errors": "^1.0.0", + "@thi.ng/paths": "^2.0.0" }, "keywords": [ "configuration", @@ -49,4 +49,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/rle-pack/CHANGELOG.md b/packages/rle-pack/CHANGELOG.md index 25d8f4a30c..05593166a0 100644 --- a/packages/rle-pack/CHANGELOG.md +++ b/packages/rle-pack/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/rle-pack@1.0.8...@thi.ng/rle-pack@2.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [1.0.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/rle-pack@1.0.7...@thi.ng/rle-pack@1.0.8) (2018-12-15) **Note:** Version bump only for package @thi.ng/rle-pack diff --git a/packages/rle-pack/package.json b/packages/rle-pack/package.json index 2f89c6a710..5381489245 100644 --- a/packages/rle-pack/package.json +++ b/packages/rle-pack/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rle-pack", - "version": "1.0.8", + "version": "2.0.0", "description": "Binary run-length encoding packer w/ flexible repeat bit widths", "module": "./index.js", "main": "./lib/index.js", @@ -33,8 +33,8 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/bitstream": "^0.4.21", - "@thi.ng/errors": "^0.1.12" + "@thi.ng/bitstream": "^1.0.0", + "@thi.ng/errors": "^1.0.0" }, "keywords": [ "binary", @@ -52,4 +52,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/router/CHANGELOG.md b/packages/router/CHANGELOG.md index 1c2fc004a3..8d7d8be8b7 100644 --- a/packages/router/CHANGELOG.md +++ b/packages/router/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/router@0.1.30...@thi.ng/router@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.1.30](https://github.com/thi-ng/umbrella/compare/@thi.ng/router@0.1.29...@thi.ng/router@0.1.30) (2018-12-15) **Note:** Version bump only for package @thi.ng/router diff --git a/packages/router/package.json b/packages/router/package.json index d2eda13522..f0440281fe 100644 --- a/packages/router/package.json +++ b/packages/router/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/router", - "version": "0.1.30", + "version": "1.0.0", "description": "Generic router for browser & non-browser based applications", "module": "./index.js", "main": "./lib/index.js", @@ -32,10 +32,10 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/equiv": "^0.1.15", - "@thi.ng/errors": "^0.1.12" + "@thi.ng/api": "^5.0.0", + "@thi.ng/checks": "^2.0.0", + "@thi.ng/equiv": "^1.0.0", + "@thi.ng/errors": "^1.0.0" }, "keywords": [ "browser", @@ -54,4 +54,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/rstream-csp/CHANGELOG.md b/packages/rstream-csp/CHANGELOG.md index 14f10a5ea7..05bdacd7e2 100644 --- a/packages/rstream-csp/CHANGELOG.md +++ b/packages/rstream-csp/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-csp@0.1.125...@thi.ng/rstream-csp@1.0.0) (2019-01-21) + + +### Build System + +* update package scripts, outputs, imports in remaining packages ([f912a84](https://github.com/thi-ng/umbrella/commit/f912a84)) + + +### BREAKING CHANGES + +* enable multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols + + + + + ## [0.1.125](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-csp@0.1.124...@thi.ng/rstream-csp@0.1.125) (2019-01-02) **Note:** Version bump only for package @thi.ng/rstream-csp diff --git a/packages/rstream-csp/package.json b/packages/rstream-csp/package.json index e74935ac7d..d2f8c94792 100644 --- a/packages/rstream-csp/package.json +++ b/packages/rstream-csp/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-csp", - "version": "0.1.125", + "version": "1.0.0", "description": "@thi.ng/csp bridge module for @thi.ng/rstream", "module": "./index.js", "main": "./lib/index.js", @@ -32,8 +32,8 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/csp": "^0.3.79", - "@thi.ng/rstream": "^1.14.9" + "@thi.ng/csp": "^1.0.0", + "@thi.ng/rstream": "^2.0.0" }, "keywords": [ "bridge", @@ -47,4 +47,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/rstream-dot/CHANGELOG.md b/packages/rstream-dot/CHANGELOG.md index 618bc509fe..7ad2b3167c 100644 --- a/packages/rstream-dot/CHANGELOG.md +++ b/packages/rstream-dot/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-dot@0.2.64...@thi.ng/rstream-dot@1.0.0) (2019-01-21) + + +### Build System + +* update package scripts, outputs, imports in remaining packages ([f912a84](https://github.com/thi-ng/umbrella/commit/f912a84)) + + +### BREAKING CHANGES + +* enable multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols + + + + + ## [0.2.64](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-dot@0.2.63...@thi.ng/rstream-dot@0.2.64) (2019-01-02) **Note:** Version bump only for package @thi.ng/rstream-dot diff --git a/packages/rstream-dot/package.json b/packages/rstream-dot/package.json index 5681c72eee..3309c2ec81 100644 --- a/packages/rstream-dot/package.json +++ b/packages/rstream-dot/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-dot", - "version": "0.2.64", + "version": "1.0.0", "description": "Graphviz DOT conversion of @thi.ng/rstream dataflow graph topologies", "module": "./index.js", "main": "./lib/index.js", @@ -32,7 +32,7 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/rstream": "^1.14.9" + "@thi.ng/rstream": "^2.0.0" }, "keywords": [ "conversion", @@ -50,4 +50,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/rstream-gestures/CHANGELOG.md b/packages/rstream-gestures/CHANGELOG.md index 5557393977..70ce0b736f 100644 --- a/packages/rstream-gestures/CHANGELOG.md +++ b/packages/rstream-gestures/CHANGELOG.md @@ -3,6 +3,33 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-gestures@0.6.9...@thi.ng/rstream-gestures@1.0.0) (2019-01-21) + + +### Bug Fixes + +* **rstream-gestures:** disable __GestureType reverse enum export ([19449e8](https://github.com/thi-ng/umbrella/commit/19449e8)) + + +### Build System + +* update package scripts, outputs, imports in remaining packages ([f912a84](https://github.com/thi-ng/umbrella/commit/f912a84)) + + +### BREAKING CHANGES + +* enable multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols + + + + + ## [0.6.9](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-gestures@0.6.8...@thi.ng/rstream-gestures@0.6.9) (2019-01-02) **Note:** Version bump only for package @thi.ng/rstream-gestures diff --git a/packages/rstream-gestures/package.json b/packages/rstream-gestures/package.json index 145d3532a0..2351cc9a48 100644 --- a/packages/rstream-gestures/package.json +++ b/packages/rstream-gestures/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-gestures", - "version": "0.6.9", + "version": "1.0.0", "description": "Unified mouse, mouse wheel & single-touch event stream abstraction", "module": "./index.js", "main": "./lib/index.js", @@ -32,9 +32,9 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/rstream": "^1.14.9", - "@thi.ng/transducers": "^2.3.2" + "@thi.ng/api": "^5.0.0", + "@thi.ng/rstream": "^2.0.0", + "@thi.ng/transducers": "^3.0.0" }, "keywords": [ "dataflow", @@ -52,4 +52,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/rstream-graph/CHANGELOG.md b/packages/rstream-graph/CHANGELOG.md index 2390a3c8b8..551b351348 100644 --- a/packages/rstream-graph/CHANGELOG.md +++ b/packages/rstream-graph/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [3.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-graph@2.1.50...@thi.ng/rstream-graph@3.0.0) (2019-01-21) + + +### Build System + +* update package scripts, outputs, imports in remaining packages ([f912a84](https://github.com/thi-ng/umbrella/commit/f912a84)) + + +### BREAKING CHANGES + +* enable multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols + + + + + ## [2.1.50](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-graph@2.1.49...@thi.ng/rstream-graph@2.1.50) (2019-01-02) **Note:** Version bump only for package @thi.ng/rstream-graph diff --git a/packages/rstream-graph/package.json b/packages/rstream-graph/package.json index 1bc3c62df1..925b56d1eb 100644 --- a/packages/rstream-graph/package.json +++ b/packages/rstream-graph/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-graph", - "version": "2.1.50", + "version": "3.0.0", "description": "Declarative dataflow graph construction for @thi.ng/rstream", "module": "./index.js", "main": "./lib/index.js", @@ -32,13 +32,13 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/paths": "^1.6.6", - "@thi.ng/resolve-map": "^3.0.16", - "@thi.ng/rstream": "^1.14.9", - "@thi.ng/transducers": "^2.3.2" + "@thi.ng/api": "^5.0.0", + "@thi.ng/checks": "^2.0.0", + "@thi.ng/errors": "^1.0.0", + "@thi.ng/paths": "^2.0.0", + "@thi.ng/resolve-map": "^4.0.0", + "@thi.ng/rstream": "^2.0.0", + "@thi.ng/transducers": "^3.0.0" }, "keywords": [ "compute", @@ -54,4 +54,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/rstream-log/CHANGELOG.md b/packages/rstream-log/CHANGELOG.md index 4eb3af9058..17115dae94 100644 --- a/packages/rstream-log/CHANGELOG.md +++ b/packages/rstream-log/CHANGELOG.md @@ -3,6 +3,33 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-log@1.0.76...@thi.ng/rstream-log@2.0.0) (2019-01-21) + + +### Bug Fixes + +* **rstream-log:** remove __Level reverse enum lookup, update Level (non const) ([d89f28f](https://github.com/thi-ng/umbrella/commit/d89f28f)) + + +### Build System + +* update package scripts, outputs, imports in remaining packages ([f912a84](https://github.com/thi-ng/umbrella/commit/f912a84)) + + +### BREAKING CHANGES + +* enable multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols + + + + + ## [1.0.76](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-log@1.0.75...@thi.ng/rstream-log@1.0.76) (2019-01-02) **Note:** Version bump only for package @thi.ng/rstream-log diff --git a/packages/rstream-log/package.json b/packages/rstream-log/package.json index 399c00a7be..876eb6901b 100644 --- a/packages/rstream-log/package.json +++ b/packages/rstream-log/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-log", - "version": "1.0.76", + "version": "2.0.0", "description": "Structured, multilevel & hierarchical loggers based on @thi.ng/rstream", "module": "./index.js", "main": "./lib/index.js", @@ -32,11 +32,11 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/rstream": "^1.14.9", - "@thi.ng/transducers": "^2.3.2" + "@thi.ng/api": "^5.0.0", + "@thi.ng/checks": "^2.0.0", + "@thi.ng/errors": "^1.0.0", + "@thi.ng/rstream": "^2.0.0", + "@thi.ng/transducers": "^3.0.0" }, "keywords": [ "ES6", @@ -53,4 +53,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/rstream-query/CHANGELOG.md b/packages/rstream-query/CHANGELOG.md index e2fd70cf23..2a865e7ffa 100644 --- a/packages/rstream-query/CHANGELOG.md +++ b/packages/rstream-query/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-query@0.3.63...@thi.ng/rstream-query@1.0.0) (2019-01-21) + + +### Build System + +* update package scripts, outputs, imports in remaining packages ([f912a84](https://github.com/thi-ng/umbrella/commit/f912a84)) + + +### BREAKING CHANGES + +* enable multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols + + + + + ## [0.3.63](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-query@0.3.62...@thi.ng/rstream-query@0.3.63) (2019-01-02) **Note:** Version bump only for package @thi.ng/rstream-query diff --git a/packages/rstream-query/package.json b/packages/rstream-query/package.json index acadeea0b0..6a3dde0402 100644 --- a/packages/rstream-query/package.json +++ b/packages/rstream-query/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-query", - "version": "0.3.63", + "version": "1.0.0", "description": "@thi.ng/rstream based triple store & reactive query engine", "module": "./index.js", "main": "./lib/index.js", @@ -32,14 +32,14 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/associative": "^0.6.23", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/equiv": "^0.1.15", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/rstream": "^1.14.9", - "@thi.ng/rstream-dot": "^0.2.64", - "@thi.ng/transducers": "^2.3.2" + "@thi.ng/api": "^5.0.0", + "@thi.ng/associative": "^1.0.0", + "@thi.ng/checks": "^2.0.0", + "@thi.ng/equiv": "^1.0.0", + "@thi.ng/errors": "^1.0.0", + "@thi.ng/rstream": "^2.0.0", + "@thi.ng/rstream-dot": "^1.0.0", + "@thi.ng/transducers": "^3.0.0" }, "keywords": [ "dataflow", @@ -59,4 +59,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/rstream/CHANGELOG.md b/packages/rstream/CHANGELOG.md index c0e403426e..3b4934736d 100644 --- a/packages/rstream/CHANGELOG.md +++ b/packages/rstream/CHANGELOG.md @@ -3,6 +3,34 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream@1.14.9...@thi.ng/rstream@2.0.0) (2019-01-21) + + +### Bug Fixes + +* **rstream:** avoid Subscription ctor to workaround parceljs build issue ([d1e275b](https://github.com/thi-ng/umbrella/commit/d1e275b)) +* **rstream:** disable __State reverse enum lookups ([b238a3a](https://github.com/thi-ng/umbrella/commit/b238a3a)) + + +### Build System + +* update package scripts, outputs, imports in remaining packages ([f912a84](https://github.com/thi-ng/umbrella/commit/f912a84)) + + +### BREAKING CHANGES + +* enable multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols + + + + + ## [1.14.9](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream@1.14.8...@thi.ng/rstream@1.14.9) (2019-01-02) **Note:** Version bump only for package @thi.ng/rstream diff --git a/packages/rstream/package.json b/packages/rstream/package.json index 9d394ddab7..f10f1088fc 100644 --- a/packages/rstream/package.json +++ b/packages/rstream/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream", - "version": "1.14.9", + "version": "2.0.0", "description": "Reactive multi-tap streams, dataflow & transformation pipeline constructs", "module": "./index.js", "main": "./lib/index.js", @@ -32,13 +32,13 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/associative": "^0.6.23", - "@thi.ng/atom": "^1.5.8", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/paths": "^1.6.6", - "@thi.ng/transducers": "^2.3.2" + "@thi.ng/api": "^5.0.0", + "@thi.ng/associative": "^1.0.0", + "@thi.ng/atom": "^2.0.0", + "@thi.ng/checks": "^2.0.0", + "@thi.ng/errors": "^1.0.0", + "@thi.ng/paths": "^2.0.0", + "@thi.ng/transducers": "^3.0.0" }, "keywords": [ "datastructure", @@ -56,4 +56,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/sax/CHANGELOG.md b/packages/sax/CHANGELOG.md index 79a8d76398..0542f5a143 100644 --- a/packages/sax/CHANGELOG.md +++ b/packages/sax/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/sax@0.5.13...@thi.ng/sax@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.5.13](https://github.com/thi-ng/umbrella/compare/@thi.ng/sax@0.5.12...@thi.ng/sax@0.5.13) (2019-01-02) **Note:** Version bump only for package @thi.ng/sax diff --git a/packages/sax/package.json b/packages/sax/package.json index 0b655adc84..a9df3ddc8f 100644 --- a/packages/sax/package.json +++ b/packages/sax/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/sax", - "version": "0.5.13", + "version": "1.0.0", "description": "Transducer-based, SAX-like, non-validating, speedy & tiny XML parser", "module": "./index.js", "main": "./lib/index.js", @@ -32,9 +32,9 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/transducers": "^2.3.2", - "@thi.ng/transducers-fsm": "^0.2.36" + "@thi.ng/api": "^5.0.0", + "@thi.ng/transducers": "^3.0.0", + "@thi.ng/transducers-fsm": "^1.0.0" }, "keywords": [ "ES6", @@ -49,4 +49,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/strings/CHANGELOG.md b/packages/strings/CHANGELOG.md index b69a89447a..679025e833 100644 --- a/packages/strings/CHANGELOG.md +++ b/packages/strings/CHANGELOG.md @@ -3,6 +3,33 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/strings@0.7.1...@thi.ng/strings@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### Features + +* **strings:** add floatFixedWidth(), update float() ([816c9c0](https://github.com/thi-ng/umbrella/commit/816c9c0)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.7.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/strings@0.7.0...@thi.ng/strings@0.7.1) (2018-12-15) **Note:** Version bump only for package @thi.ng/strings diff --git a/packages/strings/package.json b/packages/strings/package.json index d3a8ec684d..de96ca6b62 100644 --- a/packages/strings/package.json +++ b/packages/strings/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/strings", - "version": "0.7.1", + "version": "1.0.0", "description": "Various string formatting & utility functions", "module": "./index.js", "main": "./lib/index.js", @@ -32,8 +32,8 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/errors": "^0.1.12", - "@thi.ng/memoize": "^0.2.6" + "@thi.ng/errors": "^1.0.0", + "@thi.ng/memoize": "^1.0.0" }, "keywords": [ "composition", @@ -60,4 +60,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/transducers-fsm/CHANGELOG.md b/packages/transducers-fsm/CHANGELOG.md index 883ac11343..f2580daaaf 100644 --- a/packages/transducers-fsm/CHANGELOG.md +++ b/packages/transducers-fsm/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers-fsm@0.2.36...@thi.ng/transducers-fsm@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.2.36](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers-fsm@0.2.35...@thi.ng/transducers-fsm@0.2.36) (2019-01-02) **Note:** Version bump only for package @thi.ng/transducers-fsm diff --git a/packages/transducers-fsm/package.json b/packages/transducers-fsm/package.json index 115c279295..20326b8274 100644 --- a/packages/transducers-fsm/package.json +++ b/packages/transducers-fsm/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/transducers-fsm", - "version": "0.2.36", + "version": "1.0.0", "description": "Transducer-based Finite State Machine transformer", "module": "./index.js", "main": "./lib/index.js", @@ -32,8 +32,8 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/transducers": "^2.3.2" + "@thi.ng/api": "^5.0.0", + "@thi.ng/transducers": "^3.0.0" }, "keywords": [ "ES6", @@ -46,4 +46,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/transducers-hdom/CHANGELOG.md b/packages/transducers-hdom/CHANGELOG.md index 13d4c60f6f..9a8944f8a2 100644 --- a/packages/transducers-hdom/CHANGELOG.md +++ b/packages/transducers-hdom/CHANGELOG.md @@ -3,6 +3,36 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers-hdom@1.2.16...@thi.ng/transducers-hdom@2.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) +* update package scripts, outputs, imports in remaining packages ([f912a84](https://github.com/thi-ng/umbrella/commit/f912a84)) + + +### BREAKING CHANGES + +* enable multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [1.2.16](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers-hdom@1.2.15...@thi.ng/transducers-hdom@1.2.16) (2019-01-02) **Note:** Version bump only for package @thi.ng/transducers-hdom diff --git a/packages/transducers-hdom/package.json b/packages/transducers-hdom/package.json index 7013d62553..b54c177d7f 100644 --- a/packages/transducers-hdom/package.json +++ b/packages/transducers-hdom/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/transducers-hdom", - "version": "1.2.16", + "version": "2.0.0", "description": "Transducer based UI updater for @thi.ng/hdom", "module": "./index.js", "main": "./lib/index.js", @@ -32,9 +32,9 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/hdom": "^6.1.0", - "@thi.ng/hiccup": "^2.7.2", - "@thi.ng/transducers": "^2.3.2" + "@thi.ng/hdom": "^7.0.0", + "@thi.ng/hiccup": "^3.0.0", + "@thi.ng/transducers": "^3.0.0" }, "keywords": [ "diff", @@ -50,4 +50,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/transducers-stats/CHANGELOG.md b/packages/transducers-stats/CHANGELOG.md index f0f70418fb..e01918bd68 100644 --- a/packages/transducers-stats/CHANGELOG.md +++ b/packages/transducers-stats/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers-stats@0.4.23...@thi.ng/transducers-stats@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.4.23](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers-stats@0.4.22...@thi.ng/transducers-stats@0.4.23) (2019-01-02) **Note:** Version bump only for package @thi.ng/transducers-stats diff --git a/packages/transducers-stats/package.json b/packages/transducers-stats/package.json index 852f154157..71af756db3 100644 --- a/packages/transducers-stats/package.json +++ b/packages/transducers-stats/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/transducers-stats", - "version": "0.4.23", + "version": "1.0.0", "description": "Transducers for statistical / technical analysis", "module": "./index.js", "main": "./lib/index.js", @@ -32,10 +32,10 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/checks": "^1.5.14", - "@thi.ng/dcons": "^1.1.23", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/transducers": "^2.3.2" + "@thi.ng/checks": "^2.0.0", + "@thi.ng/dcons": "^2.0.0", + "@thi.ng/errors": "^1.0.0", + "@thi.ng/transducers": "^3.0.0" }, "keywords": [ "ES6", @@ -45,4 +45,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/transducers/CHANGELOG.md b/packages/transducers/CHANGELOG.md index 2b7203f00c..af434166ff 100644 --- a/packages/transducers/CHANGELOG.md +++ b/packages/transducers/CHANGELOG.md @@ -3,6 +3,33 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [3.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers@2.3.2...@thi.ng/transducers@3.0.0) (2019-01-21) + + +### Bug Fixes + +* **transducers:** update juxt re-export ([a894a24](https://github.com/thi-ng/umbrella/commit/a894a24)) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [2.3.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers@2.3.1...@thi.ng/transducers@2.3.2) (2019-01-02) diff --git a/packages/transducers/package.json b/packages/transducers/package.json index 420e44a7fa..3f641ce017 100644 --- a/packages/transducers/package.json +++ b/packages/transducers/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/transducers", - "version": "2.3.2", + "version": "3.0.0", "description": "Lightweight transducer implementations for ES6 / TypeScript", "module": "./index.js", "main": "./lib/index.js", @@ -32,13 +32,13 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/compare": "^0.1.12", - "@thi.ng/compose": "^0.3.0", - "@thi.ng/equiv": "^0.1.15", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/strings": "^0.7.1" + "@thi.ng/api": "^5.0.0", + "@thi.ng/checks": "^2.0.0", + "@thi.ng/compare": "^1.0.0", + "@thi.ng/compose": "^1.0.0", + "@thi.ng/equiv": "^1.0.0", + "@thi.ng/errors": "^1.0.0", + "@thi.ng/strings": "^1.0.0" }, "keywords": [ "array", @@ -58,4 +58,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/unionstruct/CHANGELOG.md b/packages/unionstruct/CHANGELOG.md index 1f20a14953..cb8cf93eff 100644 --- a/packages/unionstruct/CHANGELOG.md +++ b/packages/unionstruct/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/unionstruct@0.1.19...@thi.ng/unionstruct@1.0.0) (2019-01-21) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [0.1.19](https://github.com/thi-ng/umbrella/compare/@thi.ng/unionstruct@0.1.18...@thi.ng/unionstruct@0.1.19) (2018-12-15) **Note:** Version bump only for package @thi.ng/unionstruct diff --git a/packages/unionstruct/package.json b/packages/unionstruct/package.json index 58ec64ef70..0c79c08c05 100644 --- a/packages/unionstruct/package.json +++ b/packages/unionstruct/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/unionstruct", - "version": "0.1.19", + "version": "1.0.0", "description": "C-style struct, union and bitfield views of ArrayBuffers", "module": "./index.js", "main": "./lib/index.js", @@ -47,4 +47,4 @@ "access": "public" }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/vector-pools/CHANGELOG.md b/packages/vector-pools/CHANGELOG.md new file mode 100644 index 0000000000..974160cdd1 --- /dev/null +++ b/packages/vector-pools/CHANGELOG.md @@ -0,0 +1,14 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# 0.1.0 (2019-01-21) + + +### Features + +* **vector-pools:** add AttribPool, refactor lists ([019c0af](https://github.com/thi-ng/umbrella/commit/019c0af)) +* **vector-pools:** add GLType alias, AttribPoolOpts, update pool impls ([4fe2047](https://github.com/thi-ng/umbrella/commit/4fe2047)) +* **vector-pools:** add VecPool, VecArrayList & VecLinkedList ([48d5d57](https://github.com/thi-ng/umbrella/commit/48d5d57)) +* **vector-pools:** update readme, add examples ([fd54d32](https://github.com/thi-ng/umbrella/commit/fd54d32)) diff --git a/packages/vector-pools/package.json b/packages/vector-pools/package.json index c28aa251e5..1d0131c72f 100644 --- a/packages/vector-pools/package.json +++ b/packages/vector-pools/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/vector-pools", - "version": "0.0.1", + "version": "0.1.0", "description": "TODO", "module": "./index.js", "main": "./lib/index.js", @@ -32,9 +32,9 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/malloc": "^0.2.1", - "@thi.ng/vectors": "^1.4.12" + "@thi.ng/api": "^5.0.0", + "@thi.ng/malloc": "^1.0.0", + "@thi.ng/vectors": "^2.0.0" }, "keywords": [ "ES6", @@ -57,4 +57,4 @@ "setTimeout": false }, "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/vectors/CHANGELOG.md b/packages/vectors/CHANGELOG.md index b4a0581c72..9bdfcb3e20 100644 --- a/packages/vectors/CHANGELOG.md +++ b/packages/vectors/CHANGELOG.md @@ -3,6 +3,33 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/vectors@1.4.12...@thi.ng/vectors@2.0.0) (2019-01-21) + + +### Bug Fixes + +* **vectors:** fix NaNs in Mat23.scaleWithCenter ([92bce73](https://github.com/thi-ng/umbrella/commit/92bce73)) + + +### Build System + +* update package build scripts & outputs, imports in ~50 packages ([b54b703](https://github.com/thi-ng/umbrella/commit/b54b703)) + + +### BREAKING CHANGES + +* enabled multi-outputs (ES6 modules, CJS, UMD) + +- build scripts now first build ES6 modules in package root, then call + `scripts/bundle-module` to build minified CJS & UMD bundles in `/lib` +- all imports MUST be updated to only refer to package level + (not individual files anymore). tree shaking in user land will get rid of + all unused imported symbols. + + + + + ## [1.4.12](https://github.com/thi-ng/umbrella/compare/@thi.ng/vectors@1.4.11...@thi.ng/vectors@1.4.12) (2019-01-02) **Note:** Version bump only for package @thi.ng/vectors diff --git a/packages/vectors/package.json b/packages/vectors/package.json index 68d7a33b2f..7eb66d60e2 100644 --- a/packages/vectors/package.json +++ b/packages/vectors/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/vectors", - "version": "1.4.12", + "version": "2.0.0", "description": "Optimized 2d/3d/4d and arbitrary length vector operations", "module": "./index.js", "main": "./lib/index.js", @@ -32,14 +32,14 @@ "typescript": "^3.2.2" }, "dependencies": { - "@thi.ng/api": "^4.2.4", - "@thi.ng/checks": "^1.5.14", - "@thi.ng/equiv": "^0.1.15", - "@thi.ng/errors": "^0.1.12", - "@thi.ng/math": "^0.2.2", - "@thi.ng/memoize": "^0.2.6", - "@thi.ng/random": "^0.1.1", - "@thi.ng/transducers": "^2.3.2" + "@thi.ng/api": "^5.0.0", + "@thi.ng/checks": "^2.0.0", + "@thi.ng/equiv": "^1.0.0", + "@thi.ng/errors": "^1.0.0", + "@thi.ng/math": "^1.0.0", + "@thi.ng/memoize": "^1.0.0", + "@thi.ng/random": "^1.0.0", + "@thi.ng/transducers": "^3.0.0" }, "keywords": [ "2D", @@ -98,4 +98,4 @@ "setTimeout": false }, "sideEffects": false -} \ No newline at end of file +}