vehicle-path2 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +160 -0
  2. package/dist/animation-loop-bZEm2pMN.js +37 -0
  3. package/dist/animation-loop-fC2LjxCd.cjs +1 -0
  4. package/dist/core/algorithms/math.d.ts +35 -0
  5. package/dist/core/algorithms/pathFinding.d.ts +62 -0
  6. package/dist/core/algorithms/vehicleMovement.d.ts +174 -0
  7. package/dist/core/index.d.ts +20 -0
  8. package/dist/core/types/api.d.ts +185 -0
  9. package/dist/core/types/config.d.ts +9 -0
  10. package/dist/core/types/geometry.d.ts +26 -0
  11. package/dist/core/types/movement.d.ts +56 -0
  12. package/dist/core/types/vehicle.d.ts +65 -0
  13. package/dist/core.cjs +1 -0
  14. package/dist/core.js +551 -0
  15. package/dist/index.d.ts +45 -0
  16. package/dist/react/dsl-hooks/useInitialMovement.d.ts +24 -0
  17. package/dist/react/dsl-hooks/useMovementSequence.d.ts +27 -0
  18. package/dist/react/dsl-hooks/useSceneDefinition.d.ts +22 -0
  19. package/dist/react/hooks/useAnimation.d.ts +43 -0
  20. package/dist/react/hooks/useMovementQueue.d.ts +52 -0
  21. package/dist/react/hooks/useScene.d.ts +78 -0
  22. package/dist/react/hooks/useVehicleSimulation.d.ts +126 -0
  23. package/dist/react/hooks/useVehicles.d.ts +55 -0
  24. package/dist/react/index.d.ts +48 -0
  25. package/dist/react/providers/useVehicleEvents.d.ts +78 -0
  26. package/dist/react.cjs +1 -0
  27. package/dist/react.js +18 -0
  28. package/dist/useVehicleEvents-B2JQFNjc.js +923 -0
  29. package/dist/useVehicleEvents-CBymulau.cjs +3 -0
  30. package/dist/utils/animation-loop.d.ts +105 -0
  31. package/dist/utils/dsl-parser.d.ts +152 -0
  32. package/dist/utils/event-emitter.d.ts +94 -0
  33. package/dist/utils/index.d.ts +15 -0
  34. package/dist/utils/type-converters.d.ts +38 -0
  35. package/dist/utils/vehicle-helpers.d.ts +8 -0
  36. package/dist/utils.cjs +1 -0
  37. package/dist/utils.js +17 -0
  38. package/dist/vehicle-helpers-DIcksrtO.cjs +7 -0
  39. package/dist/vehicle-helpers-_72KxCqO.js +276 -0
  40. package/dist/vehicle-path.cjs +1 -0
  41. package/dist/vehicle-path.js +62 -0
  42. package/package.json +103 -0
@@ -0,0 +1,276 @@
1
+ import { distance as g, getPointOnLineByOffset as $, calculateInitialFrontPosition as I } from "./core.js";
2
+ class S {
3
+ listeners = /* @__PURE__ */ new Map();
4
+ /**
5
+ * Subscribe to an event
6
+ * @param event - The event type to listen for
7
+ * @param callback - Function to call when event is emitted
8
+ * @returns Unsubscribe function
9
+ */
10
+ on(t, e) {
11
+ return this.listeners.has(t) || this.listeners.set(t, /* @__PURE__ */ new Set()), this.listeners.get(t).add(e), () => {
12
+ this.listeners.get(t)?.delete(e);
13
+ };
14
+ }
15
+ /**
16
+ * Emit an event to all subscribers
17
+ * @param event - The event type to emit
18
+ * @param data - The event data
19
+ */
20
+ emit(t, e) {
21
+ this.listeners.get(t)?.forEach((s) => {
22
+ try {
23
+ s(e);
24
+ } catch (o) {
25
+ console.error(`Error in event listener for "${t}":`, o);
26
+ }
27
+ });
28
+ }
29
+ /**
30
+ * Remove all listeners for a specific event, or all events if no event specified
31
+ * @param event - Optional event type to clear listeners for
32
+ */
33
+ off(t) {
34
+ t ? this.listeners.delete(t) : this.listeners.clear();
35
+ }
36
+ /**
37
+ * Get the number of listeners for a specific event
38
+ * @param event - The event type
39
+ * @returns Number of listeners
40
+ */
41
+ listenerCount(t) {
42
+ return this.listeners.get(t)?.size ?? 0;
43
+ }
44
+ }
45
+ function P(i) {
46
+ const t = [], e = [], s = [], o = i.trim().split(`
47
+ `);
48
+ let h = 0;
49
+ for (const n of o) {
50
+ h++;
51
+ const r = n.trim();
52
+ if (!r || r.startsWith("#")) continue;
53
+ const a = r.match(/^(\w+)\s*:\s*\((-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)\)\s*->\s*\((-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)\)/);
54
+ if (a) {
55
+ t.push({
56
+ id: a[1],
57
+ start: [parseFloat(a[2]), parseFloat(a[3])],
58
+ end: [parseFloat(a[4]), parseFloat(a[5])]
59
+ });
60
+ continue;
61
+ }
62
+ const c = r.match(/^(\w+)(?:\s+(\d+(?:\.\d+)?)(%?))??\s*->\s*(\w+)(?:\s+(\d+(?:\.\d+)?)(%?))?/);
63
+ if (c) {
64
+ const l = {
65
+ from: c[1],
66
+ to: c[4]
67
+ };
68
+ if (c[2]) {
69
+ const f = parseFloat(c[2]);
70
+ l.fromPosition = (c[3] === "%", f / 100);
71
+ }
72
+ if (c[5]) {
73
+ const f = parseFloat(c[5]);
74
+ l.toPosition = (c[6] === "%", f / 100);
75
+ }
76
+ e.push(l);
77
+ continue;
78
+ }
79
+ r.match(/^\w+\s+start\s+/) || r.match(/^\w+\s+goto\s+/) || s.push(`Line ${h}: Unable to parse "${r}"`);
80
+ }
81
+ return {
82
+ data: {
83
+ lines: t,
84
+ connections: e.length > 0 ? e : void 0
85
+ },
86
+ errors: s
87
+ };
88
+ }
89
+ function v(i) {
90
+ const t = [], e = [], s = i.trim().split(`
91
+ `);
92
+ let o = 0;
93
+ for (const h of s) {
94
+ o++;
95
+ const n = h.trim();
96
+ if (!n || n.startsWith("#")) continue;
97
+ const r = n.match(/^(\w+)\s+start\s+(\w+)\s+(\d+(?:\.\d+)?)(%?)/);
98
+ if (r) {
99
+ const a = parseFloat(r[3]), c = r[4] === "%";
100
+ t.push({
101
+ id: r[1],
102
+ lineId: r[2],
103
+ // API uses 0-1 for percentage, DSL uses 0-100
104
+ position: c ? a / 100 : a,
105
+ isPercentage: c
106
+ });
107
+ continue;
108
+ }
109
+ n.match(/^\w+\s*:\s*\(/) || n.match(/^\w+.*->\s*\w+/) || n.match(/^\w+\s+goto\s+/) || n.match(/^\w+\s+start/) && e.push(`Line ${o}: Invalid vehicle start format "${n}"`);
110
+ }
111
+ return {
112
+ data: t,
113
+ errors: e
114
+ };
115
+ }
116
+ function w(i) {
117
+ const t = [], e = [], s = i.trim().split(`
118
+ `);
119
+ let o = 0;
120
+ for (const h of s) {
121
+ o++;
122
+ const n = h.trim();
123
+ if (!n || n.startsWith("#")) continue;
124
+ const r = n.match(/^(\w+)\s+goto\s+(\w+)\s+(\d+(?:\.\d+)?)(%?)/);
125
+ if (r) {
126
+ const a = n.slice(r[0].length), c = a.includes("--wait");
127
+ let l;
128
+ const f = a.match(/--payload\s+(\{.*\})/);
129
+ if (f)
130
+ try {
131
+ l = JSON.parse(f[1]);
132
+ } catch {
133
+ e.push(`Line ${o}: Invalid JSON payload "${f[1]}"`);
134
+ }
135
+ const d = parseFloat(r[3]), u = r[4] === "%";
136
+ t.push({
137
+ vehicleId: r[1],
138
+ targetLineId: r[2],
139
+ // API uses 0-1 for percentage, DSL uses 0-100
140
+ // For absolute offsets, keep the raw value
141
+ targetPosition: u ? d / 100 : d,
142
+ isPercentage: u,
143
+ wait: c || void 0,
144
+ payload: l
145
+ });
146
+ continue;
147
+ }
148
+ n.match(/^\w+\s*:\s*\(/) || n.match(/^\w+.*->\s*\w+/) || n.match(/^\w+\s+start\s+/) || n.match(/^\w+\s+goto/) && e.push(`Line ${o}: Invalid goto command format "${n}"`);
149
+ }
150
+ return {
151
+ data: t,
152
+ errors: e
153
+ };
154
+ }
155
+ function y(i) {
156
+ return {
157
+ scene: P(i),
158
+ vehicles: v(i),
159
+ movements: w(i)
160
+ };
161
+ }
162
+ function m(i) {
163
+ return Array.isArray(i) ? { x: i[0], y: i[1] } : i;
164
+ }
165
+ function M(i) {
166
+ const t = [];
167
+ for (const e of i.lines) {
168
+ const s = m(e.start), o = m(e.end);
169
+ t.push(`${e.id} : (${Math.round(s.x)}, ${Math.round(s.y)}) -> (${Math.round(o.x)}, ${Math.round(o.y)})`);
170
+ }
171
+ if (i.lines.length > 0 && i.connections && i.connections.length > 0 && t.push(""), i.connections)
172
+ for (const e of i.connections) {
173
+ let s = e.from;
174
+ e.fromPosition !== void 0 && (e.fromIsPercentage !== !1 ? s += ` ${e.fromPosition * 100}%` : s += ` ${e.fromPosition}`), s += " -> ", s += e.to, e.toPosition !== void 0 && (e.toIsPercentage !== !1 ? s += ` ${e.toPosition * 100}%` : s += ` ${e.toPosition}`), t.push(s);
175
+ }
176
+ return t.join(`
177
+ `);
178
+ }
179
+ function x(i) {
180
+ return i.map((t) => {
181
+ const e = t.position ?? 0;
182
+ return t.isPercentage !== !1 ? `${t.id} start ${t.lineId} ${e * 100}%` : `${t.id} start ${t.lineId} ${e}`;
183
+ }).join(`
184
+ `);
185
+ }
186
+ function V(i) {
187
+ return i.map((t) => {
188
+ const e = t.targetPosition ?? 1, s = t.isPercentage !== !1;
189
+ let o = t.vehicleId;
190
+ return o += ` goto ${t.targetLineId}`, s ? o += ` ${e * 100}%` : o += ` ${e}`, t.wait && (o += " --wait"), t.payload !== void 0 && (o += ` --payload ${JSON.stringify(t.payload)}`), o;
191
+ }).join(`
192
+ `);
193
+ }
194
+ function N(i, t, e = 0) {
195
+ const s = [], o = [], h = /* @__PURE__ */ new Set();
196
+ for (const n of i) {
197
+ if (h.has(n.vehicleId)) {
198
+ o.push(`Duplicate vehicle ID: ${n.vehicleId}`);
199
+ continue;
200
+ }
201
+ h.add(n.vehicleId);
202
+ const r = t.find((p) => p.id === n.lineId);
203
+ if (!r) {
204
+ o.push(`Vehicle ${n.vehicleId}: Line "${n.lineId}" not found`);
205
+ continue;
206
+ }
207
+ const a = g(r.start, r.end), c = Math.max(0, a - e);
208
+ let l;
209
+ if (n.isPercentage) {
210
+ if (n.offset < 0 || n.offset > 100) {
211
+ o.push(`Vehicle ${n.vehicleId}: Offset ${n.offset}% must be between 0% and 100%`);
212
+ continue;
213
+ }
214
+ l = n.offset / 100 * c;
215
+ } else {
216
+ if (n.offset < 0 || n.offset > a) {
217
+ o.push(`Vehicle ${n.vehicleId}: Offset ${n.offset} exceeds line length ${a.toFixed(2)}`);
218
+ continue;
219
+ }
220
+ l = Math.min(n.offset, c);
221
+ }
222
+ const f = $(r, l, !1), d = {
223
+ lineId: n.lineId,
224
+ position: f,
225
+ absoluteOffset: l
226
+ }, u = I(
227
+ n.lineId,
228
+ l,
229
+ e,
230
+ r
231
+ );
232
+ s.push({
233
+ id: n.vehicleId,
234
+ lineId: n.lineId,
235
+ offset: n.offset,
236
+ isPercentage: n.isPercentage,
237
+ state: "idle",
238
+ rear: d,
239
+ front: u
240
+ });
241
+ }
242
+ return { vehicles: s, errors: o };
243
+ }
244
+ function b(i) {
245
+ const t = i.map((s) => {
246
+ const o = s.vehicleId.match(/^v(\d+)$/);
247
+ return o ? parseInt(o[1]) : 0;
248
+ }).filter((s) => s > 0);
249
+ return `v${(t.length > 0 ? Math.max(...t) : 0) + 1}`;
250
+ }
251
+ function F(i, t) {
252
+ if (t.length === 0) return null;
253
+ if (i.length === 0)
254
+ return t[0].id;
255
+ const e = /* @__PURE__ */ new Map();
256
+ for (const s of t)
257
+ e.set(s.id, 0);
258
+ for (const s of i) {
259
+ const o = e.get(s.vehicleId) || 0;
260
+ e.set(s.vehicleId, o + 1);
261
+ }
262
+ return t[0].id;
263
+ }
264
+ export {
265
+ S as V,
266
+ M as a,
267
+ x as b,
268
+ F as c,
269
+ b as d,
270
+ w as e,
271
+ P as f,
272
+ V as g,
273
+ v as h,
274
+ y as p,
275
+ N as v
276
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./core.cjs"),i=require("./vehicle-helpers-DIcksrtO.cjs"),n=require("./animation-loop-fC2LjxCd.cjs"),t=require("./useVehicleEvents-CBymulau.cjs");exports.arcLengthToSegmentPosition=e.arcLengthToSegmentPosition;exports.buildArcLengthTable=e.buildArcLengthTable;exports.buildGraph=e.buildGraph;exports.calculateBezierArcLength=e.calculateBezierArcLength;exports.calculateFrontAxlePosition=e.calculateFrontAxlePosition;exports.calculateInitialFrontPosition=e.calculateInitialFrontPosition;exports.calculatePositionOnCurve=e.calculatePositionOnCurve;exports.calculatePositionOnLine=e.calculatePositionOnLine;exports.createBezierCurve=e.createBezierCurve;exports.createInitialMovementState=e.createInitialMovementState;exports.distance=e.distance;exports.distanceToT=e.distanceToT;exports.findPath=e.findPath;exports.getArcLength=e.getArcLength;exports.getCumulativeArcLength=e.getCumulativeArcLength;exports.getLineLength=e.getLineLength;exports.getPointOnBezier=e.getPointOnBezier;exports.getPointOnLine=e.getPointOnLine;exports.getPointOnLineByOffset=e.getPointOnLineByOffset;exports.getPositionFromOffset=e.getPositionFromOffset;exports.handleArrival=e.handleArrival;exports.initializeAllVehicles=e.initializeAllVehicles;exports.initializeMovingVehicle=e.initializeMovingVehicle;exports.normalize=e.normalize;exports.prepareCommandPath=e.prepareCommandPath;exports.resolveFromLineOffset=e.resolveFromLineOffset;exports.resolveToLineOffset=e.resolveToLineOffset;exports.updateAxlePosition=e.updateAxlePosition;exports.VehicleEventEmitter=i.VehicleEventEmitter;exports.generateMovementDSL=i.generateMovementDSL;exports.generateSceneDSL=i.generateSceneDSL;exports.generateVehiclesDSL=i.generateVehiclesDSL;exports.getNextGotoVehicleId=i.getNextGotoVehicleId;exports.getNextStartVehicleId=i.getNextStartVehicleId;exports.parseAllDSL=i.parseAllDSL;exports.parseMovementDSL=i.parseMovementDSL;exports.parseSceneDSL=i.parseSceneDSL;exports.parseVehiclesDSL=i.parseVehiclesDSL;exports.validateAndCreateVehicles=i.validateAndCreateVehicles;exports.createAnimationLoop=n.createAnimationLoop;exports.useAnimationLoop=n.useAnimationLoop;exports.VehicleEventContext=t.VehicleEventContext;exports.VehicleEventProvider=t.VehicleEventProvider;exports.useAnimation=t.useAnimation;exports.useCreateVehicleEventEmitter=t.useCreateVehicleEventEmitter;exports.useInitialMovement=t.useInitialMovement;exports.useMovement=t.useMovementQueue;exports.useMovementQueue=t.useMovementQueue;exports.useMovementSequence=t.useMovementSequence;exports.useScene=t.useScene;exports.useSceneDefinition=t.useSceneDefinition;exports.useVehicleEvent=t.useVehicleEvent;exports.useVehicleEventEmitter=t.useVehicleEventEmitter;exports.useVehicleMovement=t.useAnimation;exports.useVehicleSimulation=t.useVehicleSimulation;exports.useVehicles=t.useVehicles;
@@ -0,0 +1,62 @@
1
+ import { arcLengthToSegmentPosition as i, buildArcLengthTable as a, buildGraph as n, calculateBezierArcLength as s, calculateFrontAxlePosition as o, calculateInitialFrontPosition as l, calculatePositionOnCurve as r, calculatePositionOnLine as c, createBezierCurve as u, createInitialMovementState as h, distance as m, distanceToT as v, findPath as g, getArcLength as L, getCumulativeArcLength as V, getLineLength as d, getPointOnBezier as f, getPointOnLine as S, getPointOnLineByOffset as p, getPositionFromOffset as A, handleArrival as P, initializeAllVehicles as x, initializeMovingVehicle as E, normalize as M, prepareCommandPath as O, resolveFromLineOffset as D, resolveToLineOffset as C, updateAxlePosition as z } from "./core.js";
2
+ import { V as I, g as T, a as B, b as F, c as G, d as N, p as j, e as k, f as q, h as y, v as Q } from "./vehicle-helpers-_72KxCqO.js";
3
+ import { c as H, u as J } from "./animation-loop-bZEm2pMN.js";
4
+ import { V as R, a as U, u as W, b as X, c as Y, d as Z, d as _, e as $, f as ee, g as te, h as ie, i as ae, u as ne, j as se, k as oe } from "./useVehicleEvents-B2JQFNjc.js";
5
+ export {
6
+ R as VehicleEventContext,
7
+ I as VehicleEventEmitter,
8
+ U as VehicleEventProvider,
9
+ i as arcLengthToSegmentPosition,
10
+ a as buildArcLengthTable,
11
+ n as buildGraph,
12
+ s as calculateBezierArcLength,
13
+ o as calculateFrontAxlePosition,
14
+ l as calculateInitialFrontPosition,
15
+ r as calculatePositionOnCurve,
16
+ c as calculatePositionOnLine,
17
+ H as createAnimationLoop,
18
+ u as createBezierCurve,
19
+ h as createInitialMovementState,
20
+ m as distance,
21
+ v as distanceToT,
22
+ g as findPath,
23
+ T as generateMovementDSL,
24
+ B as generateSceneDSL,
25
+ F as generateVehiclesDSL,
26
+ L as getArcLength,
27
+ V as getCumulativeArcLength,
28
+ d as getLineLength,
29
+ G as getNextGotoVehicleId,
30
+ N as getNextStartVehicleId,
31
+ f as getPointOnBezier,
32
+ S as getPointOnLine,
33
+ p as getPointOnLineByOffset,
34
+ A as getPositionFromOffset,
35
+ P as handleArrival,
36
+ x as initializeAllVehicles,
37
+ E as initializeMovingVehicle,
38
+ M as normalize,
39
+ j as parseAllDSL,
40
+ k as parseMovementDSL,
41
+ q as parseSceneDSL,
42
+ y as parseVehiclesDSL,
43
+ O as prepareCommandPath,
44
+ D as resolveFromLineOffset,
45
+ C as resolveToLineOffset,
46
+ z as updateAxlePosition,
47
+ W as useAnimation,
48
+ J as useAnimationLoop,
49
+ X as useCreateVehicleEventEmitter,
50
+ Y as useInitialMovement,
51
+ Z as useMovement,
52
+ _ as useMovementQueue,
53
+ $ as useMovementSequence,
54
+ ee as useScene,
55
+ te as useSceneDefinition,
56
+ ie as useVehicleEvent,
57
+ ae as useVehicleEventEmitter,
58
+ ne as useVehicleMovement,
59
+ se as useVehicleSimulation,
60
+ oe as useVehicles,
61
+ Q as validateAndCreateVehicles
62
+ };
package/package.json ADDED
@@ -0,0 +1,103 @@
1
+ {
2
+ "name": "vehicle-path2",
3
+ "version": "1.0.0",
4
+ "description": "Vehicle motion simulator library for dual-axle vehicle movement along paths composed of lines and Bezier curves",
5
+ "type": "module",
6
+ "main": "./dist/vehicle-path.cjs",
7
+ "module": "./dist/vehicle-path.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/vehicle-path.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "default": "./dist/vehicle-path.cjs"
18
+ }
19
+ },
20
+ "./core": {
21
+ "import": {
22
+ "types": "./dist/core/index.d.ts",
23
+ "default": "./dist/core.js"
24
+ },
25
+ "require": {
26
+ "types": "./dist/core/index.d.cts",
27
+ "default": "./dist/core.cjs"
28
+ }
29
+ },
30
+ "./utils": {
31
+ "import": {
32
+ "types": "./dist/utils/index.d.ts",
33
+ "default": "./dist/utils.js"
34
+ },
35
+ "require": {
36
+ "types": "./dist/utils/index.d.cts",
37
+ "default": "./dist/utils.cjs"
38
+ }
39
+ },
40
+ "./react": {
41
+ "import": {
42
+ "types": "./dist/react/index.d.ts",
43
+ "default": "./dist/react.js"
44
+ },
45
+ "require": {
46
+ "types": "./dist/react/index.d.cts",
47
+ "default": "./dist/react.cjs"
48
+ }
49
+ }
50
+ },
51
+ "files": [
52
+ "dist"
53
+ ],
54
+ "scripts": {
55
+ "dev": "vite build --watch",
56
+ "build": "vite build && tsc -p tsconfig.build.json",
57
+ "prepublishOnly": "npm run build",
58
+ "lint": "eslint .",
59
+ "test": "vitest",
60
+ "test:ui": "vitest --ui",
61
+ "test:coverage": "vitest --coverage"
62
+ },
63
+ "peerDependencies": {
64
+ "react": "^18.0.0 || ^19.0.0",
65
+ "react-dom": "^18.0.0 || ^19.0.0"
66
+ },
67
+ "devDependencies": {
68
+ "@eslint/js": "^9.39.1",
69
+ "@testing-library/react": "^16.3.1",
70
+ "@types/node": "^24.10.1",
71
+ "@types/react": "^19.2.5",
72
+ "@types/react-dom": "^19.2.3",
73
+ "@vitejs/plugin-react": "^5.1.1",
74
+ "@vitest/coverage-v8": "^4.0.16",
75
+ "@vitest/ui": "^4.0.16",
76
+ "eslint": "^9.39.1",
77
+ "eslint-plugin-react-hooks": "^7.0.1",
78
+ "eslint-plugin-react-refresh": "^0.4.24",
79
+ "globals": "^16.5.0",
80
+ "happy-dom": "^20.0.11",
81
+ "react": "^19.2.0",
82
+ "react-dom": "^19.2.0",
83
+ "typescript": "~5.9.3",
84
+ "typescript-eslint": "^8.46.4",
85
+ "vite": "^7.2.4",
86
+ "vitest": "^4.0.16"
87
+ },
88
+ "keywords": [
89
+ "vehicle",
90
+ "path",
91
+ "bezier",
92
+ "simulation",
93
+ "animation",
94
+ "dual-axle",
95
+ "react"
96
+ ],
97
+ "author": "",
98
+ "license": "MIT",
99
+ "repository": {
100
+ "type": "git",
101
+ "url": ""
102
+ }
103
+ }