angular-three-cannon 2.14.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/body/lib/utils.d.ts +20 -20
- package/fesm2022/angular-three-cannon-body.mjs.map +1 -1
- package/fesm2022/angular-three-cannon-constraint.mjs.map +1 -1
- package/fesm2022/angular-three-cannon-debug.mjs +3 -3
- package/fesm2022/angular-three-cannon-debug.mjs.map +1 -1
- package/fesm2022/angular-three-cannon.mjs +3 -3
- package/fesm2022/angular-three-cannon.mjs.map +1 -1
- package/package.json +4 -12
- package/esm2022/angular-three-cannon.mjs +0 -5
- package/esm2022/body/angular-three-cannon-body.mjs +0 -5
- package/esm2022/body/index.mjs +0 -2
- package/esm2022/body/lib/body.mjs +0 -111
- package/esm2022/body/lib/types.mjs +0 -2
- package/esm2022/body/lib/utils.mjs +0 -193
- package/esm2022/constraint/angular-three-cannon-constraint.mjs +0 -5
- package/esm2022/constraint/index.mjs +0 -2
- package/esm2022/constraint/lib/constraint.mjs +0 -67
- package/esm2022/debug/angular-three-cannon-debug.mjs +0 -5
- package/esm2022/debug/index.mjs +0 -2
- package/esm2022/debug/lib/debug.mjs +0 -81
- package/esm2022/index.mjs +0 -2
- package/esm2022/lib/physics.mjs +0 -187
package/esm2022/lib/physics.mjs
DELETED
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
import { Directive, Injector, afterNextRender, effect, inject, input, signal, untracked } from '@angular/core';
|
|
2
|
-
import { CannonWorkerAPI, } from '@pmndrs/cannon-worker-api';
|
|
3
|
-
import { injectBeforeRender, injectStore, pick } from 'angular-three';
|
|
4
|
-
import { mergeInputs } from 'ngxtension/inject-inputs';
|
|
5
|
-
import { InstancedMesh, Matrix4, Quaternion, Vector3 } from 'three';
|
|
6
|
-
import * as i0 from "@angular/core";
|
|
7
|
-
const v = new Vector3();
|
|
8
|
-
const s = new Vector3(1, 1, 1);
|
|
9
|
-
const q = new Quaternion();
|
|
10
|
-
const m = new Matrix4();
|
|
11
|
-
function apply(index, positions, quaternions, scale = s, object) {
|
|
12
|
-
if (index !== undefined) {
|
|
13
|
-
m.compose(v.fromArray(positions, index * 3), q.fromArray(quaternions, index * 4), scale);
|
|
14
|
-
if (object) {
|
|
15
|
-
object.matrixAutoUpdate = false;
|
|
16
|
-
object.matrix.copy(m);
|
|
17
|
-
}
|
|
18
|
-
return m;
|
|
19
|
-
}
|
|
20
|
-
return m.identity();
|
|
21
|
-
}
|
|
22
|
-
function unique() {
|
|
23
|
-
const values = [];
|
|
24
|
-
return (value) => (values.includes(value) ? false : !!values.push(value));
|
|
25
|
-
}
|
|
26
|
-
const defaultOptions = {
|
|
27
|
-
allowSleep: false,
|
|
28
|
-
axisIndex: 0,
|
|
29
|
-
broadphase: 'Naive',
|
|
30
|
-
defaultContactMaterial: { contactEquationStiffness: 1e6 },
|
|
31
|
-
frictionGravity: null,
|
|
32
|
-
gravity: [0, -9.81, 0],
|
|
33
|
-
isPaused: false,
|
|
34
|
-
iterations: 5,
|
|
35
|
-
maxSubSteps: 10,
|
|
36
|
-
quatNormalizeFast: false,
|
|
37
|
-
quatNormalizeSkip: 0,
|
|
38
|
-
shouldInvalidate: true,
|
|
39
|
-
size: 1000,
|
|
40
|
-
solver: 'GS',
|
|
41
|
-
stepSize: 1 / 60,
|
|
42
|
-
tolerance: 0.001,
|
|
43
|
-
};
|
|
44
|
-
export class NgtcPhysics {
|
|
45
|
-
constructor() {
|
|
46
|
-
this.store = injectStore();
|
|
47
|
-
this.options = input(defaultOptions, { transform: mergeInputs(defaultOptions) });
|
|
48
|
-
this.axisIndex = pick(this.options, 'axisIndex');
|
|
49
|
-
this.broadphase = pick(this.options, 'broadphase');
|
|
50
|
-
this.gravity = pick(this.options, 'gravity');
|
|
51
|
-
this.iterations = pick(this.options, 'iterations');
|
|
52
|
-
this.tolerance = pick(this.options, 'tolerance');
|
|
53
|
-
this.invalidate = this.store.select('invalidate');
|
|
54
|
-
// @ts-expect-error - worker is not nullable, and we don't want to use ! operator.
|
|
55
|
-
this.cannonWorker = signal(null);
|
|
56
|
-
this.bodies = {};
|
|
57
|
-
this.events = {};
|
|
58
|
-
this.refs = {};
|
|
59
|
-
this.scaleOverrides = {};
|
|
60
|
-
this.subscriptions = {};
|
|
61
|
-
this.worker = this.cannonWorker.asReadonly();
|
|
62
|
-
const injector = inject(Injector);
|
|
63
|
-
// NOTE: set new cannonworker in afterNextRender
|
|
64
|
-
// - so inputs are resolved
|
|
65
|
-
// - so the worker is instantiated only once
|
|
66
|
-
// - effects are started after worker is instantiated
|
|
67
|
-
afterNextRender(() => {
|
|
68
|
-
this.cannonWorker.set(new CannonWorkerAPI(this.options()));
|
|
69
|
-
effect((onCleanup) => {
|
|
70
|
-
const cleanup = this.connectWorkerEffect();
|
|
71
|
-
onCleanup(() => cleanup?.());
|
|
72
|
-
}, { injector });
|
|
73
|
-
effect(() => {
|
|
74
|
-
this.updateWorkerStateEffect('axisIndex', this.axisIndex);
|
|
75
|
-
this.updateWorkerStateEffect('broadphase', this.broadphase);
|
|
76
|
-
this.updateWorkerStateEffect('gravity', this.gravity);
|
|
77
|
-
this.updateWorkerStateEffect('iterations', this.iterations);
|
|
78
|
-
this.updateWorkerStateEffect('tolerance', this.tolerance);
|
|
79
|
-
}, { injector });
|
|
80
|
-
});
|
|
81
|
-
let timeSinceLastCalled = 0;
|
|
82
|
-
injectBeforeRender(({ delta }) => {
|
|
83
|
-
const [{ isPaused, maxSubSteps, stepSize }, worker] = [this.options(), this.cannonWorker()];
|
|
84
|
-
if (isPaused || !worker || stepSize == null)
|
|
85
|
-
return;
|
|
86
|
-
timeSinceLastCalled += delta;
|
|
87
|
-
worker.step({ maxSubSteps, stepSize, timeSinceLastCalled });
|
|
88
|
-
timeSinceLastCalled = 0;
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
connectWorkerEffect() {
|
|
92
|
-
const worker = this.cannonWorker();
|
|
93
|
-
if (!worker)
|
|
94
|
-
return;
|
|
95
|
-
worker.connect();
|
|
96
|
-
worker.init();
|
|
97
|
-
worker.on('collide', this.collideHandler.bind(this));
|
|
98
|
-
worker.on('collideBegin', this.collideBeginHandler.bind(this));
|
|
99
|
-
worker.on('collideEnd', this.collideEndHandler.bind(this));
|
|
100
|
-
worker.on('frame', this.frameHandler.bind(this));
|
|
101
|
-
worker.on('rayhit', this.rayhitHandler.bind(this));
|
|
102
|
-
return () => {
|
|
103
|
-
worker.terminate();
|
|
104
|
-
worker.removeAllListeners();
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
updateWorkerStateEffect(key, option) {
|
|
108
|
-
const worker = this.cannonWorker();
|
|
109
|
-
if (!worker)
|
|
110
|
-
return;
|
|
111
|
-
Object.assign(worker, { [key]: option() });
|
|
112
|
-
}
|
|
113
|
-
collideHandler({ body, contact: { bi, bj, ...contactRest }, target, ...rest }) {
|
|
114
|
-
const { events, refs } = this;
|
|
115
|
-
const cb = events[target]?.collide;
|
|
116
|
-
if (cb) {
|
|
117
|
-
cb({ body: refs[body], contact: { bi: refs[bi], bj: refs[bj], ...contactRest }, target: refs[target], ...rest });
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
collideBeginHandler({ bodyA, bodyB }) {
|
|
121
|
-
const { events, refs } = this;
|
|
122
|
-
const cbA = events[bodyA]?.collideBegin;
|
|
123
|
-
if (cbA)
|
|
124
|
-
cbA({ body: refs[bodyB], op: 'event', target: refs[bodyA], type: 'collideBegin' });
|
|
125
|
-
const cbB = events[bodyB]?.collideBegin;
|
|
126
|
-
if (cbB)
|
|
127
|
-
cbB({ body: refs[bodyA], op: 'event', target: refs[bodyB], type: 'collideBegin' });
|
|
128
|
-
}
|
|
129
|
-
collideEndHandler({ bodyA, bodyB }) {
|
|
130
|
-
const { events, refs } = this;
|
|
131
|
-
const cbA = events[bodyA]?.collideEnd;
|
|
132
|
-
if (cbA)
|
|
133
|
-
cbA({ body: refs[bodyB], op: 'event', target: refs[bodyA], type: 'collideEnd' });
|
|
134
|
-
const cbB = events[bodyB]?.collideEnd;
|
|
135
|
-
if (cbB)
|
|
136
|
-
cbB({ body: refs[bodyA], op: 'event', target: refs[bodyB], type: 'collideEnd' });
|
|
137
|
-
}
|
|
138
|
-
frameHandler({ active, bodies: uuids = [], observations, positions, quaternions, }) {
|
|
139
|
-
const [{ shouldInvalidate }, { bodies, subscriptions, refs, scaleOverrides }, invalidate] = [
|
|
140
|
-
untracked(this.options),
|
|
141
|
-
this,
|
|
142
|
-
this.invalidate(),
|
|
143
|
-
];
|
|
144
|
-
for (let i = 0; i < uuids.length; i++) {
|
|
145
|
-
bodies[uuids[i]] = i;
|
|
146
|
-
}
|
|
147
|
-
observations.forEach(([id, value, type]) => {
|
|
148
|
-
const subscription = subscriptions[id] || {};
|
|
149
|
-
const cb = subscription[type];
|
|
150
|
-
// @ts-expect-error - We clearly know the type of the callback, but typescript can't deal with it
|
|
151
|
-
cb && cb(value);
|
|
152
|
-
});
|
|
153
|
-
if (!active)
|
|
154
|
-
return;
|
|
155
|
-
for (const ref of Object.values(refs).filter(unique())) {
|
|
156
|
-
if (ref instanceof InstancedMesh) {
|
|
157
|
-
for (let i = 0; i < ref.count; i++) {
|
|
158
|
-
const uuid = `${ref.uuid}/${i}`;
|
|
159
|
-
const index = bodies[uuid];
|
|
160
|
-
if (index !== undefined) {
|
|
161
|
-
ref.setMatrixAt(i, apply(index, positions, quaternions, scaleOverrides[uuid]));
|
|
162
|
-
ref.instanceMatrix.needsUpdate = true;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
const scale = scaleOverrides[ref.uuid] || ref.scale;
|
|
168
|
-
apply(bodies[ref.uuid], positions, quaternions, scale, ref);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
if (shouldInvalidate)
|
|
172
|
-
invalidate();
|
|
173
|
-
}
|
|
174
|
-
rayhitHandler({ body, ray: { uuid, ...rayRest }, ...rest }) {
|
|
175
|
-
const { events, refs } = this;
|
|
176
|
-
const cb = events[uuid]?.rayhit;
|
|
177
|
-
if (cb)
|
|
178
|
-
cb({ body: body ? refs[body] : null, ray: { uuid, ...rayRest }, ...rest });
|
|
179
|
-
}
|
|
180
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: NgtcPhysics, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
181
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.2.11", type: NgtcPhysics, isStandalone: true, selector: "ngtc-physics", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
|
|
182
|
-
}
|
|
183
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: NgtcPhysics, decorators: [{
|
|
184
|
-
type: Directive,
|
|
185
|
-
args: [{ selector: 'ngtc-physics', standalone: true }]
|
|
186
|
-
}], ctorParameters: () => [] });
|
|
187
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGh5c2ljcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYnMvY2Fubm9uL3NyYy9saWIvcGh5c2ljcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxlQUFlLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvRyxPQUFPLEVBQ04sZUFBZSxHQWFmLE1BQU0sMkJBQTJCLENBQUM7QUFDbkMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdEUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFZLFVBQVUsRUFBbUIsT0FBTyxFQUFFLE1BQU0sT0FBTyxDQUFDOztBQWUvRixNQUFNLENBQUMsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0FBQ3hCLE1BQU0sQ0FBQyxHQUFHLElBQUksT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDL0IsTUFBTSxDQUFDLEdBQUcsSUFBSSxVQUFVLEVBQUUsQ0FBQztBQUMzQixNQUFNLENBQUMsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0FBRXhCLFNBQVMsS0FBSyxDQUNiLEtBQWEsRUFDYixTQUE0QixFQUM1QixXQUE4QixFQUM5QixLQUFLLEdBQUcsQ0FBQyxFQUNULE1BQWlCO0lBRWpCLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQ3pCLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsS0FBSyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsV0FBOEIsRUFBRSxLQUFLLEdBQUcsQ0FB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LENBQUMsQ0FBQztJQUNwRixDQUFDOytHQTlKVyxXQUFXO21HQUFYLFdBQVc7OzRGQUFYLFdBQVc7a0JBRHZCLFNBQVM7bUJBQUMsRUFBRSxRQUFRLEVBQUUsY0FBYyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEaXJlY3RpdmUsIEluamVjdG9yLCBhZnRlck5leHRSZW5kZXIsIGVmZmVjdCwgaW5qZWN0LCBpbnB1dCwgc2lnbmFsLCB1bnRyYWNrZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG5cdENhbm5vbldvcmtlckFQSSxcblx0Q2Fubm9uV29ya2VyUHJvcHMsXG5cdENvbGxpZGVCZWdpbkV2ZW50LFxuXHRDb2xsaWRlRW5kRXZlbnQsXG5cdENvbGxpZGVFdmVudCxcblx0UmF5aGl0RXZlbnQsXG5cdFJlZnMsXG5cdFN1YnNjcmlwdGlvbnMsXG5cdFdvcmtlckNvbGxpZGVCZWdpbkV2ZW50LFxuXHRXb3JrZXJDb2xsaWRlRW5kRXZlbnQsXG5cdFdvcmtlckNvbGxpZGVFdmVudCxcblx0V29ya2VyRnJhbWVNZXNzYWdlLFxuXHRXb3JrZXJSYXloaXRFdmVudCxcbn0gZnJvbSAnQHBtbmRycy9jYW5ub24td29ya2VyLWFwaSc7XG5pbXBvcnQgeyBpbmplY3RCZWZvcmVSZW5kZXIsIGluamVjdFN0b3JlLCBwaWNrIH0gZnJvbSAnYW5ndWxhci10aHJlZSc7XG5pbXBvcnQgeyBtZXJnZUlucHV0cyB9IGZyb20gJ25neHRlbnNpb24vaW5qZWN0LWlucHV0cyc7XG5pbXBvcnQgeyBJbnN0YW5jZWRNZXNoLCBNYXRyaXg0LCBPYmplY3QzRCwgUXVhdGVybmlvbiwgUXVhdGVybmlvblR1cGxlLCBWZWN0b3IzIH0gZnJvbSAndGhyZWUnO1xuXG5leHBvcnQgaW50ZXJmYWNlIE5ndGNDYW5ub25Xb3JrZXJFdmVudHMge1xuXHRjb2xsaWRlOiBXb3JrZXJDb2xsaWRlRXZlbnQ7XG5cdGNvbGxpZGVCZWdpbjogV29ya2VyQ29sbGlkZUJlZ2luRXZlbnQ7XG5cdGNvbGxpZGVFbmQ6IFdvcmtlckNvbGxpZGVFbmRFdmVudDtcblx0ZnJhbWU6IFdvcmtlckZyYW1lTWVzc2FnZTtcblx0cmF5aGl0OiBXb3JrZXJSYXloaXRFdmVudDtcbn1cblxuZXhwb3J0IHR5cGUgTmd0Y0Nhbm5vbldvcmtlciA9IENhbm5vbldvcmtlckFQSSAmIHtcblx0b246IDxLIGV4dGVuZHMga2V5b2YgTmd0Y0Nhbm5vbldvcmtlckV2ZW50cz4oZXZlbnQ6IEssIGNiOiAoZGF0YTogTmd0Y0Nhbm5vbldvcmtlckV2ZW50c1tLXVsnZGF0YSddKSA9PiB2b2lkKSA9PiB2b2lkO1xuXHRyZW1vdmVBbGxMaXN0ZW5lcnM6ICgpID0+IHZvaWQ7XG59O1xuXG5jb25zdCB2ID0gbmV3IFZlY3RvcjMoKTtcbmNvbnN0IHMgPSBuZXcgVmVjdG9yMygxLCAxLCAxKTtcbmNvbnN0IHEgPSBuZXcgUXVhdGVybmlvbigpO1xuY29uc3QgbSA9IG5ldyBNYXRyaXg0KCk7XG5cbmZ1bmN0aW9uIGFwcGx5KFxuXHRpbmRleDogbnVtYmVyLFxuXHRwb3NpdGlvbnM6IEFycmF5TGlrZTxudW1iZXI+LFxuXHRxdWF0ZXJuaW9uczogQXJyYXlMaWtlPG51bWJlcj4sXG5cdHNjYWxlID0gcyxcblx0b2JqZWN0PzogT2JqZWN0M0QsXG4pIHtcblx0aWYgKGluZGV4ICE9PSB1bmRlZmluZWQpIHtcblx0XHRtLmNvbXBvc2Uodi5mcm9tQXJyYXkocG9zaXRpb25zLCBpbmRleCAqIDMpLCBxLmZyb21BcnJheShxdWF0ZXJuaW9ucyBhcyBRdWF0ZXJuaW9uVHVwbGUsIGluZGV4ICogNCksIHNjYWxlKTtcblx0XHRpZiAob2JqZWN0KSB7XG5cdFx0XHRvYmplY3QubWF0cml4QXV0b1VwZGF0ZSA9IGZhbHNlO1xuXHRcdFx0b2JqZWN0Lm1hdHJpeC5jb3B5KG0pO1xuXHRcdH1cblx0XHRyZXR1cm4gbTtcblx0fVxuXHRyZXR1cm4gbS5pZGVudGl0eSgpO1xufVxuXG5mdW5jdGlvbiB1bmlxdWUoKSB7XG5cdGNvbnN0IHZhbHVlczogdW5rbm93bltdID0gW107XG5cdHJldHVybiAodmFsdWU6IHVua25vd24pID0+ICh2YWx1ZXMuaW5jbHVkZXModmFsdWUpID8gZmFsc2UgOiAhIXZhbHVlcy5wdXNoKHZhbHVlKSk7XG59XG5cbnR5cGUgTmd0Y0Nhbm5vbkV2ZW50ID0gQ29sbGlkZUJlZ2luRXZlbnQgfCBDb2xsaWRlRW5kRXZlbnQgfCBDb2xsaWRlRXZlbnQgfCBSYXloaXRFdmVudDtcbnR5cGUgTmd0Y0NhbGxiYWNrQnlUeXBlPFQgZXh0ZW5kcyB7IHR5cGU6IHN0cmluZyB9PiA9IHtcblx0W0sgaW4gVFsndHlwZSddXT86IFQgZXh0ZW5kcyB7IHR5cGU6IEsgfSA/IChlOiBUKSA9PiB2b2lkIDogbmV2ZXI7XG59O1xuXG5leHBvcnQgdHlwZSBOZ3RjQ2Fubm9uRXZlbnRzID0gUmVjb3JkPHN0cmluZywgUGFydGlhbDxOZ3RjQ2FsbGJhY2tCeVR5cGU8Tmd0Y0Nhbm5vbkV2ZW50Pj4+O1xuXG5leHBvcnQgdHlwZSBTY2FsZU92ZXJyaWRlcyA9IFJlY29yZDxzdHJpbmcsIFZlY3RvcjM+O1xuXG5leHBvcnQgaW50ZXJmYWNlIE5ndGNQaHlzaWNzT3B0aW9ucyBleHRlbmRzIENhbm5vbldvcmtlclByb3BzIHtcblx0aXNQYXVzZWQ/OiBib29sZWFuO1xuXHRtYXhTdWJTdGVwcz86IG51bWJlcjtcblx0c2hvdWxkSW52YWxpZGF0ZT86IGJvb2xlYW47XG5cdHN0ZXBTaXplPzogbnVtYmVyO1xufVxuXG5jb25zdCBkZWZhdWx0T3B0aW9uczogTmd0Y1BoeXNpY3NPcHRpb25zID0ge1xuXHRhbGxvd1NsZWVwOiBmYWxzZSxcblx0YXhpc0luZGV4OiAwLFxuXHRicm9hZHBoYXNlOiAnTmFpdmUnLFxuXHRkZWZhdWx0Q29udGFjdE1hdGVyaWFsOiB7IGNvbnRhY3RFcXVhdGlvblN0aWZmbmVzczogMWU2IH0sXG5cdGZyaWN0aW9uR3Jhdml0eTogbnVsbCxcblx0Z3Jhdml0eTogWzAsIC05LjgxLCAwXSxcblx0aXNQYXVzZWQ6IGZhbHNlLFxuXHRpdGVyYXRpb25zOiA1LFxuXHRtYXhTdWJTdGVwczogMTAsXG5cdHF1YXROb3JtYWxpemVGYXN0OiBmYWxzZSxcblx0cXVhdE5vcm1hbGl6ZVNraXA6IDAsXG5cdHNob3VsZEludmFsaWRhdGU6IHRydWUsXG5cdHNpemU6IDEwMDAsXG5cdHNvbHZlcjogJ0dTJyxcblx0c3RlcFNpemU6IDEgLyA2MCxcblx0dG9sZXJhbmNlOiAwLjAwMSxcbn07XG5cbnR5cGUgTmd0c1BoeXNpY3NVcGRhdGFibGVPcHRpb25zID0gRXh0cmFjdDxcblx0a2V5b2YgTmd0Y1BoeXNpY3NPcHRpb25zLFxuXHQnZ3Jhdml0eScgfCAnaXRlcmF0aW9ucycgfCAndG9sZXJhbmNlJyB8ICdicm9hZHBoYXNlJyB8ICdheGlzSW5kZXgnXG4+O1xuXG5ARGlyZWN0aXZlKHsgc2VsZWN0b3I6ICduZ3RjLXBoeXNpY3MnLCBzdGFuZGFsb25lOiB0cnVlIH0pXG5leHBvcnQgY2xhc3MgTmd0Y1BoeXNpY3Mge1xuXHRwcml2YXRlIHN0b3JlID0gaW5qZWN0U3RvcmUoKTtcblxuXHRvcHRpb25zID0gaW5wdXQoZGVmYXVsdE9wdGlvbnMsIHsgdHJhbnNmb3JtOiBtZXJnZUlucHV0cyhkZWZhdWx0T3B0aW9ucykgfSk7XG5cblx0cHJpdmF0ZSBheGlzSW5kZXggPSBwaWNrKHRoaXMub3B0aW9ucywgJ2F4aXNJbmRleCcpO1xuXHRwcml2YXRlIGJyb2FkcGhhc2UgPSBwaWNrKHRoaXMub3B0aW9ucywgJ2Jyb2FkcGhhc2UnKTtcblx0cHJpdmF0ZSBncmF2aXR5ID0gcGljayh0aGlzLm9wdGlvbnMsICdncmF2aXR5Jyk7XG5cdHByaXZhdGUgaXRlcmF0aW9ucyA9IHBpY2sodGhpcy5vcHRpb25zLCAnaXRlcmF0aW9ucycpO1xuXHRwcml2YXRlIHRvbGVyYW5jZSA9IHBpY2sodGhpcy5vcHRpb25zLCAndG9sZXJhbmNlJyk7XG5cblx0cHJpdmF0ZSBpbnZhbGlkYXRlID0gdGhpcy5zdG9yZS5zZWxlY3QoJ2ludmFsaWRhdGUnKTtcblx0Ly8gQHRzLWV4cGVjdC1lcnJvciAtIHdvcmtlciBpcyBub3QgbnVsbGFibGUsIGFuZCB3ZSBkb24ndCB3YW50IHRvIHVzZSAhIG9wZXJhdG9yLlxuXHRwcml2YXRlIGNhbm5vbldvcmtlciA9IHNpZ25hbDxDYW5ub25Xb3JrZXJBUEk+KG51bGwpO1xuXG5cdGJvZGllczogeyBbdXVpZDogc3RyaW5nXTogbnVtYmVyIH0gPSB7fTtcblx0ZXZlbnRzOiBOZ3RjQ2Fubm9uRXZlbnRzID0ge307XG5cdHJlZnM6IFJlZnMgPSB7fTtcblx0c2NhbGVPdmVycmlkZXM6IFNjYWxlT3ZlcnJpZGVzID0ge307XG5cdHN1YnNjcmlwdGlvbnM6IFN1YnNjcmlwdGlvbnMgPSB7fTtcblx0d29ya2VyID0gdGhpcy5jYW5ub25Xb3JrZXIuYXNSZWFkb25seSgpO1xuXG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdGNvbnN0IGluamVjdG9yID0gaW5qZWN0KEluamVjdG9yKTtcblxuXHRcdC8vIE5PVEU6IHNldCBuZXcgY2Fubm9ud29ya2VyIGluIGFmdGVyTmV4dFJlbmRlclxuXHRcdC8vIC0gc28gaW5wdXRzIGFyZSByZXNvbHZlZFxuXHRcdC8vIC0gc28gdGhlIHdvcmtlciBpcyBpbnN0YW50aWF0ZWQgb25seSBvbmNlXG5cdFx0Ly8gLSBlZmZlY3RzIGFyZSBzdGFydGVkIGFmdGVyIHdvcmtlciBpcyBpbnN0YW50aWF0ZWRcblx0XHRhZnRlck5leHRSZW5kZXIoKCkgPT4ge1xuXHRcdFx0dGhpcy5jYW5ub25Xb3JrZXIuc2V0KG5ldyBDYW5ub25Xb3JrZXJBUEkodGhpcy5vcHRpb25zKCkpKTtcblxuXHRcdFx0ZWZmZWN0KFxuXHRcdFx0XHQob25DbGVhbnVwKSA9PiB7XG5cdFx0XHRcdFx0Y29uc3QgY2xlYW51cCA9IHRoaXMuY29ubmVjdFdvcmtlckVmZmVjdCgpO1xuXHRcdFx0XHRcdG9uQ2xlYW51cCgoKSA9PiBjbGVhbnVwPy4oKSk7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdHsgaW5qZWN0b3IgfSxcblx0XHRcdCk7XG5cblx0XHRcdGVmZmVjdChcblx0XHRcdFx0KCkgPT4ge1xuXHRcdFx0XHRcdHRoaXMudXBkYXRlV29ya2VyU3RhdGVFZmZlY3QoJ2F4aXNJbmRleCcsIHRoaXMuYXhpc0luZGV4KTtcblx0XHRcdFx0XHR0aGlzLnVwZGF0ZVdvcmtlclN0YXRlRWZmZWN0KCdicm9hZHBoYXNlJywgdGhpcy5icm9hZHBoYXNlKTtcblx0XHRcdFx0XHR0aGlzLnVwZGF0ZVdvcmtlclN0YXRlRWZmZWN0KCdncmF2aXR5JywgdGhpcy5ncmF2aXR5KTtcblx0XHRcdFx0XHR0aGlzLnVwZGF0ZVdvcmtlclN0YXRlRWZmZWN0KCdpdGVyYXRpb25zJywgdGhpcy5pdGVyYXRpb25zKTtcblx0XHRcdFx0XHR0aGlzLnVwZGF0ZVdvcmtlclN0YXRlRWZmZWN0KCd0b2xlcmFuY2UnLCB0aGlzLnRvbGVyYW5jZSk7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdHsgaW5qZWN0b3IgfSxcblx0XHRcdCk7XG5cdFx0fSk7XG5cblx0XHRsZXQgdGltZVNpbmNlTGFzdENhbGxlZCA9IDA7XG5cdFx0aW5qZWN0QmVmb3JlUmVuZGVyKCh7IGRlbHRhIH0pID0+IHtcblx0XHRcdGNvbnN0IFt7IGlzUGF1c2VkLCBtYXhTdWJTdGVwcywgc3RlcFNpemUgfSwgd29ya2VyXSA9IFt0aGlzLm9wdGlvbnMoKSwgdGhpcy5jYW5ub25Xb3JrZXIoKV07XG5cdFx0XHRpZiAoaXNQYXVzZWQgfHwgIXdvcmtlciB8fCBzdGVwU2l6ZSA9PSBudWxsKSByZXR1cm47XG5cdFx0XHR0aW1lU2luY2VMYXN0Q2FsbGVkICs9IGRlbHRhO1xuXHRcdFx0d29ya2VyLnN0ZXAoeyBtYXhTdWJTdGVwcywgc3RlcFNpemUsIHRpbWVTaW5jZUxhc3RDYWxsZWQgfSk7XG5cdFx0XHR0aW1lU2luY2VMYXN0Q2FsbGVkID0gMDtcblx0XHR9KTtcblx0fVxuXG5cdHByaXZhdGUgY29ubmVjdFdvcmtlckVmZmVjdCgpIHtcblx0XHRjb25zdCB3b3JrZXIgPSB0aGlzLmNhbm5vbldvcmtlcigpIGFzIE5ndGNDYW5ub25Xb3JrZXI7XG5cdFx0aWYgKCF3b3JrZXIpIHJldHVybjtcblxuXHRcdHdvcmtlci5jb25uZWN0KCk7XG5cdFx0d29ya2VyLmluaXQoKTtcblxuXHRcdHdvcmtlci5vbignY29sbGlkZScsIHRoaXMuY29sbGlkZUhhbmRsZXIuYmluZCh0aGlzKSk7XG5cdFx0d29ya2VyLm9uKCdjb2xsaWRlQmVnaW4nLCB0aGlzLmNvbGxpZGVCZWdpbkhhbmRsZXIuYmluZCh0aGlzKSk7XG5cdFx0d29ya2VyLm9uKCdjb2xsaWRlRW5kJywgdGhpcy5jb2xsaWRlRW5kSGFuZGxlci5iaW5kKHRoaXMpKTtcblx0XHR3b3JrZXIub24oJ2ZyYW1lJywgdGhpcy5mcmFtZUhhbmRsZXIuYmluZCh0aGlzKSk7XG5cdFx0d29ya2VyLm9uKCdyYXloaXQnLCB0aGlzLnJheWhpdEhhbmRsZXIuYmluZCh0aGlzKSk7XG5cblx0XHRyZXR1cm4gKCkgPT4ge1xuXHRcdFx0d29ya2VyLnRlcm1pbmF0ZSgpO1xuXHRcdFx0d29ya2VyLnJlbW92ZUFsbExpc3RlbmVycygpO1xuXHRcdH07XG5cdH1cblxuXHRwcml2YXRlIHVwZGF0ZVdvcmtlclN0YXRlRWZmZWN0PFRVcGRhdGFibGVLZXkgZXh0ZW5kcyBOZ3RzUGh5c2ljc1VwZGF0YWJsZU9wdGlvbnM+KFxuXHRcdGtleTogVFVwZGF0YWJsZUtleSxcblx0XHRvcHRpb246ICgpID0+IE5ndGNQaHlzaWNzT3B0aW9uc1tUVXBkYXRhYmxlS2V5XSxcblx0KSB7XG5cdFx0Y29uc3Qgd29ya2VyID0gdGhpcy5jYW5ub25Xb3JrZXIoKTtcblx0XHRpZiAoIXdvcmtlcikgcmV0dXJuO1xuXHRcdE9iamVjdC5hc3NpZ24od29ya2VyLCB7IFtrZXldOiBvcHRpb24oKSB9KTtcblx0fVxuXG5cdHByaXZhdGUgY29sbGlkZUhhbmRsZXIoeyBib2R5LCBjb250YWN0OiB7IGJpLCBiaiwgLi4uY29udGFjdFJlc3QgfSwgdGFyZ2V0LCAuLi5yZXN0IH06IFdvcmtlckNvbGxpZGVFdmVudFsnZGF0YSddKSB7XG5cdFx0Y29uc3QgeyBldmVudHMsIHJlZnMgfSA9IHRoaXM7XG5cdFx0Y29uc3QgY2IgPSBldmVudHNbdGFyZ2V0XT8uY29sbGlkZTtcblx0XHRpZiAoY2IpIHtcblx0XHRcdGNiKHsgYm9keTogcmVmc1tib2R5XSwgY29udGFjdDogeyBiaTogcmVmc1tiaV0sIGJqOiByZWZzW2JqXSwgLi4uY29udGFjdFJlc3QgfSwgdGFyZ2V0OiByZWZzW3RhcmdldF0sIC4uLnJlc3QgfSk7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBjb2xsaWRlQmVnaW5IYW5kbGVyKHsgYm9keUEsIGJvZHlCIH06IFdvcmtlckNvbGxpZGVCZWdpbkV2ZW50WydkYXRhJ10pIHtcblx0XHRjb25zdCB7IGV2ZW50cywgcmVmcyB9ID0gdGhpcztcblx0XHRjb25zdCBjYkEgPSBldmVudHNbYm9keUFdPy5jb2xsaWRlQmVnaW47XG5cdFx0aWYgKGNiQSkgY2JBKHsgYm9keTogcmVmc1tib2R5Ql0sIG9wOiAnZXZlbnQnLCB0YXJnZXQ6IHJlZnNbYm9keUFdLCB0eXBlOiAnY29sbGlkZUJlZ2luJyB9KTtcblx0XHRjb25zdCBjYkIgPSBldmVudHNbYm9keUJdPy5jb2xsaWRlQmVnaW47XG5cdFx0aWYgKGNiQikgY2JCKHsgYm9keTogcmVmc1tib2R5QV0sIG9wOiAnZXZlbnQnLCB0YXJnZXQ6IHJlZnNbYm9keUJdLCB0eXBlOiAnY29sbGlkZUJlZ2luJyB9KTtcblx0fVxuXG5cdHByaXZhdGUgY29sbGlkZUVuZEhhbmRsZXIoeyBib2R5QSwgYm9keUIgfTogV29ya2VyQ29sbGlkZUVuZEV2ZW50WydkYXRhJ10pIHtcblx0XHRjb25zdCB7IGV2ZW50cywgcmVmcyB9ID0gdGhpcztcblx0XHRjb25zdCBjYkEgPSBldmVudHNbYm9keUFdPy5jb2xsaWRlRW5kO1xuXHRcdGlmIChjYkEpIGNiQSh7IGJvZHk6IHJlZnNbYm9keUJdLCBvcDogJ2V2ZW50JywgdGFyZ2V0OiByZWZzW2JvZHlBXSwgdHlwZTogJ2NvbGxpZGVFbmQnIH0pO1xuXHRcdGNvbnN0IGNiQiA9IGV2ZW50c1tib2R5Ql0/LmNvbGxpZGVFbmQ7XG5cdFx0aWYgKGNiQikgY2JCKHsgYm9keTogcmVmc1tib2R5QV0sIG9wOiAnZXZlbnQnLCB0YXJnZXQ6IHJlZnNbYm9keUJdLCB0eXBlOiAnY29sbGlkZUVuZCcgfSk7XG5cdH1cblxuXHRwcml2YXRlIGZyYW1lSGFuZGxlcih7XG5cdFx0YWN0aXZlLFxuXHRcdGJvZGllczogdXVpZHMgPSBbXSxcblx0XHRvYnNlcnZhdGlvbnMsXG5cdFx0cG9zaXRpb25zLFxuXHRcdHF1YXRlcm5pb25zLFxuXHR9OiBXb3JrZXJGcmFtZU1lc3NhZ2VbJ2RhdGEnXSkge1xuXHRcdGNvbnN0IFt7IHNob3VsZEludmFsaWRhdGUgfSwgeyBib2RpZXMsIHN1YnNjcmlwdGlvbnMsIHJlZnMsIHNjYWxlT3ZlcnJpZGVzIH0sIGludmFsaWRhdGVdID0gW1xuXHRcdFx0dW50cmFja2VkKHRoaXMub3B0aW9ucyksXG5cdFx0XHR0aGlzLFxuXHRcdFx0dGhpcy5pbnZhbGlkYXRlKCksXG5cdFx0XTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHV1aWRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRib2RpZXNbdXVpZHNbaV1dID0gaTtcblx0XHR9XG5cdFx0b2JzZXJ2YXRpb25zLmZvckVhY2goKFtpZCwgdmFsdWUsIHR5cGVdKSA9PiB7XG5cdFx0XHRjb25zdCBzdWJzY3JpcHRpb24gPSBzdWJzY3JpcHRpb25zW2lkXSB8fCB7fTtcblx0XHRcdGNvbnN0IGNiID0gc3Vic2NyaXB0aW9uW3R5cGVdO1xuXHRcdFx0Ly8gQHRzLWV4cGVjdC1lcnJvciAtIFdlIGNsZWFybHkga25vdyB0aGUgdHlwZSBvZiB0aGUgY2FsbGJhY2ssIGJ1dCB0eXBlc2NyaXB0IGNhbid0IGRlYWwgd2l0aCBpdFxuXHRcdFx0Y2IgJiYgY2IodmFsdWUpO1xuXHRcdH0pO1xuXHRcdGlmICghYWN0aXZlKSByZXR1cm47XG5cdFx0Zm9yIChjb25zdCByZWYgb2YgT2JqZWN0LnZhbHVlcyhyZWZzKS5maWx0ZXIodW5pcXVlKCkpKSB7XG5cdFx0XHRpZiAocmVmIGluc3RhbmNlb2YgSW5zdGFuY2VkTWVzaCkge1xuXHRcdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHJlZi5jb3VudDsgaSsrKSB7XG5cdFx0XHRcdFx0Y29uc3QgdXVpZCA9IGAke3JlZi51dWlkfS8ke2l9YDtcblx0XHRcdFx0XHRjb25zdCBpbmRleCA9IGJvZGllc1t1dWlkXTtcblx0XHRcdFx0XHRpZiAoaW5kZXggIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRcdFx0cmVmLnNldE1hdHJpeEF0KGksIGFwcGx5KGluZGV4LCBwb3NpdGlvbnMsIHF1YXRlcm5pb25zLCBzY2FsZU92ZXJyaWRlc1t1dWlkXSkpO1xuXHRcdFx0XHRcdFx0cmVmLmluc3RhbmNlTWF0cml4Lm5lZWRzVXBkYXRlID0gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGNvbnN0IHNjYWxlID0gc2NhbGVPdmVycmlkZXNbcmVmLnV1aWRdIHx8IHJlZi5zY2FsZTtcblx0XHRcdFx0YXBwbHkoYm9kaWVzW3JlZi51dWlkXSwgcG9zaXRpb25zLCBxdWF0ZXJuaW9ucywgc2NhbGUsIHJlZik7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmIChzaG91bGRJbnZhbGlkYXRlKSBpbnZhbGlkYXRlKCk7XG5cdH1cblxuXHRwcml2YXRlIHJheWhpdEhhbmRsZXIoeyBib2R5LCByYXk6IHsgdXVpZCwgLi4ucmF5UmVzdCB9LCAuLi5yZXN0IH06IFdvcmtlclJheWhpdEV2ZW50WydkYXRhJ10pIHtcblx0XHRjb25zdCB7IGV2ZW50cywgcmVmcyB9ID0gdGhpcztcblx0XHRjb25zdCBjYiA9IGV2ZW50c1t1dWlkXT8ucmF5aGl0O1xuXHRcdGlmIChjYikgY2IoeyBib2R5OiBib2R5ID8gcmVmc1tib2R5XSA6IG51bGwsIHJheTogeyB1dWlkLCAuLi5yYXlSZXN0IH0sIC4uLnJlc3QgfSk7XG5cdH1cbn1cbiJdfQ==
|