@ncfour-us/stats 0.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.
- package/LICENSE +19 -0
- package/README.md +1 -0
- package/lib/components/normal-sample-set.d.ts +36 -0
- package/lib/components/normal-sample-set.js +43 -0
- package/lib/components/normal-set.d.ts +11 -0
- package/lib/components/normal-set.js +18 -0
- package/lib/components/sample-set.d.ts +172 -0
- package/lib/components/sample-set.js +429 -0
- package/lib/components/uniform-sample-set.d.ts +35 -0
- package/lib/components/uniform-sample-set.js +27 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +6 -0
- package/package.json +139 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2026 Tim Hahn
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# replace this
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ILogger } from '@ncfour-us/logging';
|
|
2
|
+
import { SampleSet } from './sample-set.js';
|
|
3
|
+
/**
|
|
4
|
+
* The options for instantiating a Normal distribution SampleSet.
|
|
5
|
+
*/
|
|
6
|
+
export interface NormalSampleSetOptions {
|
|
7
|
+
/**
|
|
8
|
+
* number of smaples to generate, default 1000
|
|
9
|
+
*/
|
|
10
|
+
numSamples?: number;
|
|
11
|
+
/**
|
|
12
|
+
* optional mean value, default 0
|
|
13
|
+
*/
|
|
14
|
+
mean?: number;
|
|
15
|
+
/**
|
|
16
|
+
* optional standard deviation value, default 1
|
|
17
|
+
*/
|
|
18
|
+
stddev?: number;
|
|
19
|
+
/**
|
|
20
|
+
* optional logger to use.
|
|
21
|
+
*/
|
|
22
|
+
logger?: ILogger;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Class to create a Normal distribution SampleSet
|
|
26
|
+
* with values in the range (-infinity,infinity),
|
|
27
|
+
* with default mean 0 and default standard deviation 1.
|
|
28
|
+
*/
|
|
29
|
+
export declare class NormalSampleSet extends SampleSet {
|
|
30
|
+
/**
|
|
31
|
+
* Create a new NormalSampleSet instance.
|
|
32
|
+
*
|
|
33
|
+
* @param options See {@link NormalSampleSetOptions}
|
|
34
|
+
*/
|
|
35
|
+
constructor(options: NormalSampleSetOptions);
|
|
36
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Copyright (c) 2026 Tim Hahn
|
|
2
|
+
import { SampleSet } from './sample-set.js';
|
|
3
|
+
import { UniformSampleSet } from './uniform-sample-set.js';
|
|
4
|
+
;
|
|
5
|
+
/**
|
|
6
|
+
* Class to create a Normal distribution SampleSet
|
|
7
|
+
* with values in the range (-infinity,infinity),
|
|
8
|
+
* with default mean 0 and default standard deviation 1.
|
|
9
|
+
*/
|
|
10
|
+
export class NormalSampleSet extends SampleSet {
|
|
11
|
+
/**
|
|
12
|
+
* Create a new NormalSampleSet instance.
|
|
13
|
+
*
|
|
14
|
+
* @param options See {@link NormalSampleSetOptions}
|
|
15
|
+
*/
|
|
16
|
+
constructor(options) {
|
|
17
|
+
super({
|
|
18
|
+
logger: options.logger,
|
|
19
|
+
});
|
|
20
|
+
// Create a Normal distribution using the Box-Muller transform method.
|
|
21
|
+
//
|
|
22
|
+
// For information on this method, refer to: https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform
|
|
23
|
+
const U1 = new UniformSampleSet({
|
|
24
|
+
numSamples: options.numSamples ?? 1000,
|
|
25
|
+
});
|
|
26
|
+
const U2 = new UniformSampleSet({
|
|
27
|
+
numSamples: options.numSamples ?? 1000,
|
|
28
|
+
});
|
|
29
|
+
const u1 = U1.getValues();
|
|
30
|
+
const u2 = U2.getValues();
|
|
31
|
+
const z0 = u1.map((u1Value, index) => {
|
|
32
|
+
return Math.sqrt(-2.0 * Math.log(u1Value)) * Math.cos(2.0 * Math.PI * u2[index]);
|
|
33
|
+
});
|
|
34
|
+
// const z1 = u1.map( (u1Value, index) => {
|
|
35
|
+
// return Math.sqrt(-2.0*Math.log(u1Value))*Math.sin(2.0*Math.PI*u2[index])
|
|
36
|
+
// });
|
|
37
|
+
const mean = options.mean ?? 0;
|
|
38
|
+
const stddev = options.stddev ?? 1;
|
|
39
|
+
this.addValues(z0.map((value) => mean + (value) * (stddev)));
|
|
40
|
+
this.logger?.trace(`NormalSampleSet.constructor: numSamples: ${this.getNumSamples()}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9ybWFsLXNhbXBsZS1zZXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29tcG9uZW50cy9ub3JtYWwtc2FtcGxlLXNldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw4QkFBOEI7QUFHOUIsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzVDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBMkIxRCxDQUFDO0FBRUY7Ozs7R0FJRztBQUNILE1BQU0sT0FBTyxlQUFnQixTQUFRLFNBQVM7SUFFNUM7Ozs7T0FJRztJQUNILFlBQVksT0FBK0I7UUFFekMsS0FBSyxDQUFDO1lBQ0osTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNO1NBQ3ZCLENBQUMsQ0FBQztRQUVILHNFQUFzRTtRQUN0RSxFQUFFO1FBQ0YsdUdBQXVHO1FBRXZHLE1BQU0sRUFBRSxHQUFHLElBQUksZ0JBQWdCLENBQUM7WUFDOUIsVUFBVSxFQUFFLE9BQU8sQ0FBQyxVQUFVLElBQUksSUFBSTtTQUN2QyxDQUFDLENBQUM7UUFDSCxNQUFNLEVBQUUsR0FBRyxJQUFJLGdCQUFnQixDQUFDO1lBQzlCLFVBQVUsRUFBRSxPQUFPLENBQUMsVUFBVSxJQUFJLElBQUk7U0FDdkMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLFNBQVMsRUFBYyxDQUFDO1FBQ3RDLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxTQUFTLEVBQWMsQ0FBQztRQUV0QyxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFFLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxFQUFFO1lBQ3BDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsR0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUMsSUFBSSxDQUFDLEVBQUUsR0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUMzRSxDQUFDLENBQUMsQ0FBQztRQUVILDJDQUEyQztRQUMzQyw2RUFBNkU7UUFDN0UsTUFBTTtRQUNOLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDO1FBQy9CLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDO1FBRW5DLElBQUksQ0FBQyxTQUFTLENBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFFLENBQUM7UUFFN0QsSUFBSSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsNENBQTRDLElBQUksQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFFekYsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSAyMDI2IFRpbSBIYWhuXG5cbmltcG9ydCB7IElMb2dnZXIgfSBmcm9tICdAbmNmb3VyLXVzL2xvZ2dpbmcnO1xuaW1wb3J0IHsgU2FtcGxlU2V0IH0gZnJvbSAnLi9zYW1wbGUtc2V0LmpzJztcbmltcG9ydCB7IFVuaWZvcm1TYW1wbGVTZXQgfSBmcm9tICcuL3VuaWZvcm0tc2FtcGxlLXNldC5qcyc7XG5cbi8qKlxuICogVGhlIG9wdGlvbnMgZm9yIGluc3RhbnRpYXRpbmcgYSBOb3JtYWwgZGlzdHJpYnV0aW9uIFNhbXBsZVNldC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBOb3JtYWxTYW1wbGVTZXRPcHRpb25zIHtcblxuICAvKipcbiAgICogbnVtYmVyIG9mIHNtYXBsZXMgdG8gZ2VuZXJhdGUsIGRlZmF1bHQgMTAwMFxuICAgKi9cbiAgbnVtU2FtcGxlcz86IG51bWJlcjtcblxuICAvKipcbiAgICogb3B0aW9uYWwgbWVhbiB2YWx1ZSwgZGVmYXVsdCAwXG4gICAqL1xuICBtZWFuPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBvcHRpb25hbCBzdGFuZGFyZCBkZXZpYXRpb24gdmFsdWUsIGRlZmF1bHQgMVxuICAgKi9cbiAgc3RkZGV2PzogbnVtYmVyO1xuXG4gIC8vIGRlcGVuZGVuY2llc1xuICAvKipcbiAgICogb3B0aW9uYWwgbG9nZ2VyIHRvIHVzZS5cbiAgICovXG4gIGxvZ2dlcj86IElMb2dnZXI7XG59O1xuXG4vKipcbiAqIENsYXNzIHRvIGNyZWF0ZSBhIE5vcm1hbCBkaXN0cmlidXRpb24gU2FtcGxlU2V0XG4gKiB3aXRoIHZhbHVlcyBpbiB0aGUgcmFuZ2UgKC1pbmZpbml0eSxpbmZpbml0eSksXG4gKiB3aXRoIGRlZmF1bHQgbWVhbiAwIGFuZCBkZWZhdWx0IHN0YW5kYXJkIGRldmlhdGlvbiAxLlxuICovXG5leHBvcnQgY2xhc3MgTm9ybWFsU2FtcGxlU2V0IGV4dGVuZHMgU2FtcGxlU2V0IHtcblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IE5vcm1hbFNhbXBsZVNldCBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIG9wdGlvbnMgU2VlIHtAbGluayBOb3JtYWxTYW1wbGVTZXRPcHRpb25zfVxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9uczogTm9ybWFsU2FtcGxlU2V0T3B0aW9ucykge1xuXG4gICAgc3VwZXIoe1xuICAgICAgbG9nZ2VyOiBvcHRpb25zLmxvZ2dlcixcbiAgICB9KTtcblxuICAgIC8vIENyZWF0ZSBhIE5vcm1hbCBkaXN0cmlidXRpb24gdXNpbmcgdGhlIEJveC1NdWxsZXIgdHJhbnNmb3JtIG1ldGhvZC5cbiAgICAvL1xuICAgIC8vIEZvciBpbmZvcm1hdGlvbiBvbiB0aGlzIG1ldGhvZCwgcmVmZXIgdG86IGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0JveCVFMiU4MCU5M011bGxlcl90cmFuc2Zvcm1cblxuICAgIGNvbnN0IFUxID0gbmV3IFVuaWZvcm1TYW1wbGVTZXQoe1xuICAgICAgbnVtU2FtcGxlczogb3B0aW9ucy5udW1TYW1wbGVzID8/IDEwMDAsXG4gICAgfSk7XG4gICAgY29uc3QgVTIgPSBuZXcgVW5pZm9ybVNhbXBsZVNldCh7XG4gICAgICBudW1TYW1wbGVzOiBvcHRpb25zLm51bVNhbXBsZXMgPz8gMTAwMCxcbiAgICB9KTtcblxuICAgIGNvbnN0IHUxID0gVTEuZ2V0VmFsdWVzKCkgYXMgbnVtYmVyW107XG4gICAgY29uc3QgdTIgPSBVMi5nZXRWYWx1ZXMoKSBhcyBudW1iZXJbXTtcblxuICAgIGNvbnN0IHowID0gdTEubWFwKCAodTFWYWx1ZSwgaW5kZXgpID0+IHtcbiAgICAgIHJldHVybiBNYXRoLnNxcnQoLTIuMCpNYXRoLmxvZyh1MVZhbHVlKSkqTWF0aC5jb3MoMi4wKk1hdGguUEkqdTJbaW5kZXhdKTtcbiAgICB9KTtcblxuICAgIC8vIGNvbnN0IHoxID0gdTEubWFwKCAodTFWYWx1ZSwgaW5kZXgpID0+IHtcbiAgICAvLyAgIHJldHVybiBNYXRoLnNxcnQoLTIuMCpNYXRoLmxvZyh1MVZhbHVlKSkqTWF0aC5zaW4oMi4wKk1hdGguUEkqdTJbaW5kZXhdKVxuICAgIC8vIH0pO1xuICAgIGNvbnN0IG1lYW4gPSBvcHRpb25zLm1lYW4gPz8gMDtcbiAgICBjb25zdCBzdGRkZXYgPSBvcHRpb25zLnN0ZGRldiA/PyAxO1xuXG4gICAgdGhpcy5hZGRWYWx1ZXMoIHowLm1hcCgodmFsdWUpID0+IG1lYW4gKyAodmFsdWUpKihzdGRkZXYpKSApO1xuXG4gICAgdGhpcy5sb2dnZXI/LnRyYWNlKGBOb3JtYWxTYW1wbGVTZXQuY29uc3RydWN0b3I6IG51bVNhbXBsZXM6ICR7dGhpcy5nZXROdW1TYW1wbGVzKCl9YCk7XG5cbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ILogger } from '@ncfour-us/logging';
|
|
2
|
+
import { SampleSet } from './sample-set.js';
|
|
3
|
+
export interface NormalSetOptions {
|
|
4
|
+
numSamples?: number;
|
|
5
|
+
min?: number;
|
|
6
|
+
max?: number;
|
|
7
|
+
logger?: ILogger;
|
|
8
|
+
}
|
|
9
|
+
export declare class NormalSet extends SampleSet {
|
|
10
|
+
constructor(options: NormalSetOptions);
|
|
11
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Copyright (c) 2026 Tim Hahn
|
|
2
|
+
import { SampleSet } from './sample-set.js';
|
|
3
|
+
;
|
|
4
|
+
export class NormalSet extends SampleSet {
|
|
5
|
+
constructor(options) {
|
|
6
|
+
super({
|
|
7
|
+
logger: options.logger,
|
|
8
|
+
});
|
|
9
|
+
this.addValues(Array.from({ length: options.numSamples ?? 1000 }, (_element, _index) => {
|
|
10
|
+
const min = options.min ?? 0;
|
|
11
|
+
const max = options.max ?? 1;
|
|
12
|
+
const newVal = min + (max - min) * Math.random();
|
|
13
|
+
return newVal;
|
|
14
|
+
}));
|
|
15
|
+
this.logger?.trace(`NormalSet.constructor: numSamples: ${this.getNumSamples()}`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9ybWFsLXNldC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21wb25lbnRzL25vcm1hbC1zZXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsOEJBQThCO0FBRzlCLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQVMzQyxDQUFDO0FBRUYsTUFBTSxPQUFPLFNBQVUsU0FBUSxTQUFTO0lBRXRDLFlBQVksT0FBeUI7UUFFbkMsS0FBSyxDQUFDO1lBQ0osTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNO1NBQ3ZCLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsVUFBVSxJQUFJLElBQUksRUFBRSxFQUFFLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3JGLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO1lBQzdCLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO1lBRTdCLE1BQU0sTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBQyxHQUFHLENBQUMsR0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFFN0MsT0FBTyxNQUFNLENBQUM7UUFDaEIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVKLElBQUksQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLHNDQUFzQyxJQUFJLENBQUMsYUFBYSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBRW5GLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAoYykgMjAyNiBUaW0gSGFoblxuXG5pbXBvcnQgeyBJTG9nZ2VyIH0gZnJvbSAnQG5jZm91ci11cy9sb2dnaW5nJztcbmltcG9ydCB7IFNhbXBsZVNldCB9IGZyb20gJy4vc2FtcGxlLXNldC5qcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTm9ybWFsU2V0T3B0aW9ucyB7XG4gIG51bVNhbXBsZXM/OiBudW1iZXI7XG4gIG1pbj86IG51bWJlcjtcbiAgbWF4PzogbnVtYmVyO1xuXG4gIC8vIGRlcGVuZGVuY2llc1xuICBsb2dnZXI/OiBJTG9nZ2VyO1xufTtcblxuZXhwb3J0IGNsYXNzIE5vcm1hbFNldCBleHRlbmRzIFNhbXBsZVNldCB7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogTm9ybWFsU2V0T3B0aW9ucykge1xuXG4gICAgc3VwZXIoe1xuICAgICAgbG9nZ2VyOiBvcHRpb25zLmxvZ2dlcixcbiAgICB9KTtcblxuICAgIHRoaXMuYWRkVmFsdWVzKEFycmF5LmZyb20oeyBsZW5ndGg6IG9wdGlvbnMubnVtU2FtcGxlcyA/PyAxMDAwIH0sIChfZWxlbWVudCwgX2luZGV4KSA9PiB7XG4gICAgICBjb25zdCBtaW4gPSBvcHRpb25zLm1pbiA/PyAwO1xuICAgICAgY29uc3QgbWF4ID0gb3B0aW9ucy5tYXggPz8gMTtcblxuICAgICAgY29uc3QgbmV3VmFsID0gbWluICsgKG1heC1taW4pKk1hdGgucmFuZG9tKCk7XG5cbiAgICAgIHJldHVybiBuZXdWYWw7XG4gICAgfSkpO1xuXG4gICAgdGhpcy5sb2dnZXI/LnRyYWNlKGBOb3JtYWxTZXQuY29uc3RydWN0b3I6IG51bVNhbXBsZXM6ICR7dGhpcy5nZXROdW1TYW1wbGVzKCl9YCk7XG5cbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { ILogger } from '@ncfour-us/logging';
|
|
2
|
+
/**
|
|
3
|
+
* SampleBucket is used to represent the calculated
|
|
4
|
+
* distribution for the SampleSet.
|
|
5
|
+
*/
|
|
6
|
+
export declare class SampleBucket {
|
|
7
|
+
min: number;
|
|
8
|
+
max: number;
|
|
9
|
+
midPoint: number;
|
|
10
|
+
count: number;
|
|
11
|
+
constructor(min: number, max: number, count: number);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The type of values stored in the SampleSet
|
|
15
|
+
*/
|
|
16
|
+
export type SampleSetValue = number | string;
|
|
17
|
+
/**
|
|
18
|
+
* SampleSetPercentiles represents the calculated percentiles
|
|
19
|
+
* for the values in the SampleSet.
|
|
20
|
+
*/
|
|
21
|
+
export interface SampleSetPercentiles {
|
|
22
|
+
0: SampleSetValue;
|
|
23
|
+
25: SampleSetValue;
|
|
24
|
+
50: SampleSetValue;
|
|
25
|
+
75: SampleSetValue;
|
|
26
|
+
100: SampleSetValue;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The options for instantiating the SampleSet.
|
|
30
|
+
*/
|
|
31
|
+
export interface SampleSetOptions {
|
|
32
|
+
/**
|
|
33
|
+
* optional initial set of values to put into the SampleSet
|
|
34
|
+
*/
|
|
35
|
+
initialValues?: SampleSetValue[];
|
|
36
|
+
/**
|
|
37
|
+
* optional logger to use.
|
|
38
|
+
*/
|
|
39
|
+
logger?: ILogger;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Base class to represent samples of a random variable
|
|
43
|
+
* in the stats package.
|
|
44
|
+
*
|
|
45
|
+
* Other calculated distributions are based on this base
|
|
46
|
+
* class. However, instances of the base class can be
|
|
47
|
+
* created as well, if a set of random values exists to
|
|
48
|
+
* initialize the SampleSet.
|
|
49
|
+
*/
|
|
50
|
+
export declare class SampleSet {
|
|
51
|
+
protected logger?: ILogger;
|
|
52
|
+
private valuesNumeric;
|
|
53
|
+
private values;
|
|
54
|
+
private dictionary;
|
|
55
|
+
private recalculate;
|
|
56
|
+
private mean;
|
|
57
|
+
private median;
|
|
58
|
+
private mode;
|
|
59
|
+
private variance;
|
|
60
|
+
private stddev;
|
|
61
|
+
private max;
|
|
62
|
+
private min;
|
|
63
|
+
private percentile25;
|
|
64
|
+
private percentile75;
|
|
65
|
+
private distribution;
|
|
66
|
+
/**
|
|
67
|
+
* Create a new SampleSet instance.
|
|
68
|
+
*
|
|
69
|
+
* @param options See {@link SampleSetOptions}
|
|
70
|
+
*/
|
|
71
|
+
constructor(options: SampleSetOptions);
|
|
72
|
+
/**
|
|
73
|
+
* get the array of values held in the SampleSet.
|
|
74
|
+
*
|
|
75
|
+
* @returns SampleSetValue[] - array of SampleSetValue
|
|
76
|
+
*/
|
|
77
|
+
getValues(): SampleSetValue[];
|
|
78
|
+
/**
|
|
79
|
+
* get a specific value, by index, held in the SampleSet.
|
|
80
|
+
*
|
|
81
|
+
* @returns SampleSetValue
|
|
82
|
+
*/
|
|
83
|
+
getValue(index: number): SampleSetValue | undefined;
|
|
84
|
+
/**
|
|
85
|
+
* Replace the set of values held in the SampleSet
|
|
86
|
+
*/
|
|
87
|
+
setValues(values: SampleSetValue[]): void;
|
|
88
|
+
/**
|
|
89
|
+
* Add values to the SampleSet
|
|
90
|
+
*
|
|
91
|
+
* @param values values to add to the SampleSet
|
|
92
|
+
*/
|
|
93
|
+
addValues(values: SampleSetValue[]): void;
|
|
94
|
+
/**
|
|
95
|
+
* Add a single value to the SampleSet
|
|
96
|
+
*
|
|
97
|
+
* @param value value to add to the SampleSet
|
|
98
|
+
*/
|
|
99
|
+
addValue(value: SampleSetValue): void;
|
|
100
|
+
/**
|
|
101
|
+
* Get the mean value of the SampleSet. For string
|
|
102
|
+
* values, this is ordered by string sorting rules.
|
|
103
|
+
*
|
|
104
|
+
* @returns SampleSetValue - mean value of the SampleSet
|
|
105
|
+
*/
|
|
106
|
+
getMean(): SampleSetValue;
|
|
107
|
+
/**
|
|
108
|
+
* Get the median value of the SampleSet. For string
|
|
109
|
+
* values, this is ordered by string sorting rules.
|
|
110
|
+
*
|
|
111
|
+
* @returns SampleSetValue - median value of the SampleSet
|
|
112
|
+
*/
|
|
113
|
+
getMedian(): SampleSetValue;
|
|
114
|
+
/**
|
|
115
|
+
* Get the mode value of the SampleSet. For string
|
|
116
|
+
* values, this is ordered by string sorting rules.
|
|
117
|
+
*
|
|
118
|
+
* @returns SampleSetValue - mode value of the SampleSet
|
|
119
|
+
*/
|
|
120
|
+
getMode(): SampleSetValue;
|
|
121
|
+
/**
|
|
122
|
+
* Get the minimum value of the SampleSet. For string
|
|
123
|
+
* values, this is ordered by string sorting rules.
|
|
124
|
+
*
|
|
125
|
+
* @returns SampleSetValue - minimum value of the SampleSet
|
|
126
|
+
*/
|
|
127
|
+
getMin(): SampleSetValue;
|
|
128
|
+
/**
|
|
129
|
+
* Get the maximum value of the SampleSet. For string
|
|
130
|
+
* values, this is ordered by string sorting rules.
|
|
131
|
+
*
|
|
132
|
+
* @returns SampleSetValue - maximum value of the SampleSet
|
|
133
|
+
*/
|
|
134
|
+
getMax(): SampleSetValue;
|
|
135
|
+
/**
|
|
136
|
+
* Get the variance value of the SampleSet. For string
|
|
137
|
+
* values, this is the variance across the size of the SampleSet [0,sampleSet.getNumSamples()-1].
|
|
138
|
+
*
|
|
139
|
+
* @returns number - Calculated variance of the SampleSet
|
|
140
|
+
*/
|
|
141
|
+
getVariance(): number;
|
|
142
|
+
/**
|
|
143
|
+
* Get the percentiles values for the SampleSet.
|
|
144
|
+
*
|
|
145
|
+
* @returns sampleSetPercentiles - the 0, 25, 50, 75, and 100th percential values for the SampleSet.
|
|
146
|
+
*/
|
|
147
|
+
getPercentiles(): SampleSetPercentiles;
|
|
148
|
+
/**
|
|
149
|
+
* Get the standard deviation value of the SampleSet. For string
|
|
150
|
+
* values, this is the standard deviation across the size of the
|
|
151
|
+
* SampleSet [0,sampleSet.getNumSamples()-1].
|
|
152
|
+
*
|
|
153
|
+
* @returns number - Calculated standard deviation of the SampleSet
|
|
154
|
+
*/
|
|
155
|
+
getStddev(): number;
|
|
156
|
+
/**
|
|
157
|
+
* Get the type of values in the SampleSet
|
|
158
|
+
*
|
|
159
|
+
* @returns true if numeric values, false if string values
|
|
160
|
+
*/
|
|
161
|
+
isNumeric(): boolean;
|
|
162
|
+
/**
|
|
163
|
+
* Get the number of values in the SampleSet
|
|
164
|
+
*
|
|
165
|
+
* @returns number of samples in the SampleSet
|
|
166
|
+
*/
|
|
167
|
+
getNumSamples(): number;
|
|
168
|
+
private recalculateStats;
|
|
169
|
+
private calcMean;
|
|
170
|
+
private calcVariance;
|
|
171
|
+
private calcFromSortedValues;
|
|
172
|
+
}
|
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
// Copyright (c) 2026 Tim Hahn
|
|
2
|
+
/**
|
|
3
|
+
* SampleBucket is used to represent the calculated
|
|
4
|
+
* distribution for the SampleSet.
|
|
5
|
+
*/
|
|
6
|
+
export class SampleBucket {
|
|
7
|
+
min;
|
|
8
|
+
max;
|
|
9
|
+
midPoint;
|
|
10
|
+
count;
|
|
11
|
+
constructor(min, max, count) {
|
|
12
|
+
this.min = min;
|
|
13
|
+
this.max = max;
|
|
14
|
+
this.midPoint = this.min + (this.max - this.min) / 2;
|
|
15
|
+
this.count = count;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
;
|
|
19
|
+
/**
|
|
20
|
+
* Base class to represent samples of a random variable
|
|
21
|
+
* in the stats package.
|
|
22
|
+
*
|
|
23
|
+
* Other calculated distributions are based on this base
|
|
24
|
+
* class. However, instances of the base class can be
|
|
25
|
+
* created as well, if a set of random values exists to
|
|
26
|
+
* initialize the SampleSet.
|
|
27
|
+
*/
|
|
28
|
+
export class SampleSet {
|
|
29
|
+
// dependencies
|
|
30
|
+
logger;
|
|
31
|
+
// sample data
|
|
32
|
+
valuesNumeric;
|
|
33
|
+
values;
|
|
34
|
+
dictionary;
|
|
35
|
+
// calculated items
|
|
36
|
+
recalculate; // sets whether or not re-calculation is needed
|
|
37
|
+
mean;
|
|
38
|
+
median;
|
|
39
|
+
mode;
|
|
40
|
+
variance;
|
|
41
|
+
stddev;
|
|
42
|
+
max;
|
|
43
|
+
min;
|
|
44
|
+
percentile25;
|
|
45
|
+
percentile75;
|
|
46
|
+
distribution;
|
|
47
|
+
/**
|
|
48
|
+
* Create a new SampleSet instance.
|
|
49
|
+
*
|
|
50
|
+
* @param options See {@link SampleSetOptions}
|
|
51
|
+
*/
|
|
52
|
+
constructor(options) {
|
|
53
|
+
// dependencies
|
|
54
|
+
this.logger = options.logger;
|
|
55
|
+
// intialize information
|
|
56
|
+
this.recalculate = true;
|
|
57
|
+
this.mean = 0;
|
|
58
|
+
this.median = 0;
|
|
59
|
+
this.mode = 0;
|
|
60
|
+
this.variance = 0;
|
|
61
|
+
this.stddev = 0;
|
|
62
|
+
this.min = 0;
|
|
63
|
+
this.max = 0;
|
|
64
|
+
this.percentile25 = 0;
|
|
65
|
+
this.percentile75 = 0;
|
|
66
|
+
this.distribution = [];
|
|
67
|
+
// initialize values
|
|
68
|
+
this.valuesNumeric = true;
|
|
69
|
+
this.values = [];
|
|
70
|
+
this.dictionary = [];
|
|
71
|
+
if (options.initialValues) {
|
|
72
|
+
this.setValues(options.initialValues);
|
|
73
|
+
}
|
|
74
|
+
this.logger?.trace(`SampleSet.constructor: numSamples: ${this.values.length}`);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* get the array of values held in the SampleSet.
|
|
78
|
+
*
|
|
79
|
+
* @returns SampleSetValue[] - array of SampleSetValue
|
|
80
|
+
*/
|
|
81
|
+
getValues() {
|
|
82
|
+
let retVals;
|
|
83
|
+
if (this.valuesNumeric) {
|
|
84
|
+
retVals = this.values.map((value) => value);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
retVals = this.values.map((value) => this.dictionary[value]);
|
|
88
|
+
}
|
|
89
|
+
return retVals;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* get a specific value, by index, held in the SampleSet.
|
|
93
|
+
*
|
|
94
|
+
* @returns SampleSetValue
|
|
95
|
+
*/
|
|
96
|
+
getValue(index) {
|
|
97
|
+
let retVal;
|
|
98
|
+
if (index < 0 || index >= this.values.length) {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
if (this.valuesNumeric) {
|
|
102
|
+
retVal = this.values[index];
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
retVal = this.dictionary[this.values[index]];
|
|
106
|
+
}
|
|
107
|
+
return retVal;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Replace the set of values held in the SampleSet
|
|
111
|
+
*/
|
|
112
|
+
setValues(values) {
|
|
113
|
+
this.values = [];
|
|
114
|
+
this.dictionary = [];
|
|
115
|
+
this.logger?.trace(`SampleSet.setValues: typeof value: ${typeof values[0]}`);
|
|
116
|
+
if (values.length > 0 && typeof values[0] === 'string') {
|
|
117
|
+
this.valuesNumeric = false;
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
this.valuesNumeric = true;
|
|
121
|
+
}
|
|
122
|
+
this.addValues(values);
|
|
123
|
+
this.recalculate = true;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Add values to the SampleSet
|
|
127
|
+
*
|
|
128
|
+
* @param values values to add to the SampleSet
|
|
129
|
+
*/
|
|
130
|
+
addValues(values) {
|
|
131
|
+
if (this.values.length > 0 &&
|
|
132
|
+
(typeof values[0] === 'string' && this.valuesNumeric) ||
|
|
133
|
+
(typeof values[0] === 'number' && !this.valuesNumeric)) {
|
|
134
|
+
// type mismatch on values being added - quietly IGNORE
|
|
135
|
+
this.logger?.error(`SampleSet.addValues: type mismatch on values added, valuesNumeric: ${this.valuesNumeric}, values type: ${typeof values[0]}`);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (values.length > 0 && typeof values[0] === 'string') {
|
|
139
|
+
this.valuesNumeric = false;
|
|
140
|
+
values.forEach((value) => {
|
|
141
|
+
const existingItemIndex = this.dictionary.findIndex((dictItem) => dictItem === value);
|
|
142
|
+
if (existingItemIndex >= 0) {
|
|
143
|
+
// item found in dictionary
|
|
144
|
+
this.values.push(existingItemIndex);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
// add to dictionary
|
|
148
|
+
this.dictionary.push(value);
|
|
149
|
+
this.values.push(this.dictionary.length - 1);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
this.logger?.trace(`SampleSet.addValues: resulting dictionary: ${this.dictionary}`);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
// number values
|
|
156
|
+
this.valuesNumeric = true;
|
|
157
|
+
this.values = values.map((value) => value);
|
|
158
|
+
}
|
|
159
|
+
this.logger?.trace(`SampleSet.addValues: new numSamples: ${this.values.length}`);
|
|
160
|
+
this.recalculate = true;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Add a single value to the SampleSet
|
|
164
|
+
*
|
|
165
|
+
* @param value value to add to the SampleSet
|
|
166
|
+
*/
|
|
167
|
+
addValue(value) {
|
|
168
|
+
if (this.values.length > 0 &&
|
|
169
|
+
(typeof value === 'string' && this.valuesNumeric) ||
|
|
170
|
+
(typeof value === 'number' && !this.valuesNumeric)) {
|
|
171
|
+
// type mismatch on values being added - quietly IGNORE
|
|
172
|
+
this.logger?.error(`SampleSet.addValue: type mismatch on value added, valuesNumeric: ${this.valuesNumeric}, values type: ${typeof value}`);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if (typeof value === 'string') {
|
|
176
|
+
const existingItemIndex = this.dictionary.findIndex((dictItem) => dictItem === value);
|
|
177
|
+
if (existingItemIndex > 0) {
|
|
178
|
+
// item found in dictionary
|
|
179
|
+
this.values.push(existingItemIndex);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
// add to dictionary
|
|
183
|
+
this.dictionary.push(value);
|
|
184
|
+
this.values.push(this.dictionary.length - 1);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
this.values.push(value);
|
|
189
|
+
}
|
|
190
|
+
this.recalculate = true;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Get the mean value of the SampleSet. For string
|
|
194
|
+
* values, this is ordered by string sorting rules.
|
|
195
|
+
*
|
|
196
|
+
* @returns SampleSetValue - mean value of the SampleSet
|
|
197
|
+
*/
|
|
198
|
+
getMean() {
|
|
199
|
+
if (this.recalculate) {
|
|
200
|
+
this.recalculateStats();
|
|
201
|
+
}
|
|
202
|
+
return this.valuesNumeric ? this.mean : this.dictionary[this.mean];
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Get the median value of the SampleSet. For string
|
|
206
|
+
* values, this is ordered by string sorting rules.
|
|
207
|
+
*
|
|
208
|
+
* @returns SampleSetValue - median value of the SampleSet
|
|
209
|
+
*/
|
|
210
|
+
getMedian() {
|
|
211
|
+
if (this.recalculate) {
|
|
212
|
+
this.recalculateStats();
|
|
213
|
+
}
|
|
214
|
+
return this.valuesNumeric ? this.median : this.dictionary[this.median];
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Get the mode value of the SampleSet. For string
|
|
218
|
+
* values, this is ordered by string sorting rules.
|
|
219
|
+
*
|
|
220
|
+
* @returns SampleSetValue - mode value of the SampleSet
|
|
221
|
+
*/
|
|
222
|
+
getMode() {
|
|
223
|
+
if (this.recalculate) {
|
|
224
|
+
this.recalculateStats();
|
|
225
|
+
}
|
|
226
|
+
return this.valuesNumeric ? this.mode : this.dictionary[this.mode];
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Get the minimum value of the SampleSet. For string
|
|
230
|
+
* values, this is ordered by string sorting rules.
|
|
231
|
+
*
|
|
232
|
+
* @returns SampleSetValue - minimum value of the SampleSet
|
|
233
|
+
*/
|
|
234
|
+
getMin() {
|
|
235
|
+
if (this.recalculate) {
|
|
236
|
+
this.recalculateStats();
|
|
237
|
+
}
|
|
238
|
+
return this.valuesNumeric ? this.min : this.dictionary[this.min];
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Get the maximum value of the SampleSet. For string
|
|
242
|
+
* values, this is ordered by string sorting rules.
|
|
243
|
+
*
|
|
244
|
+
* @returns SampleSetValue - maximum value of the SampleSet
|
|
245
|
+
*/
|
|
246
|
+
getMax() {
|
|
247
|
+
if (this.recalculate) {
|
|
248
|
+
this.recalculateStats();
|
|
249
|
+
}
|
|
250
|
+
return this.valuesNumeric ? this.max : this.dictionary[this.max];
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Get the variance value of the SampleSet. For string
|
|
254
|
+
* values, this is the variance across the size of the SampleSet [0,sampleSet.getNumSamples()-1].
|
|
255
|
+
*
|
|
256
|
+
* @returns number - Calculated variance of the SampleSet
|
|
257
|
+
*/
|
|
258
|
+
getVariance() {
|
|
259
|
+
if (this.recalculate) {
|
|
260
|
+
this.recalculateStats();
|
|
261
|
+
}
|
|
262
|
+
return this.variance;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Get the percentiles values for the SampleSet.
|
|
266
|
+
*
|
|
267
|
+
* @returns sampleSetPercentiles - the 0, 25, 50, 75, and 100th percential values for the SampleSet.
|
|
268
|
+
*/
|
|
269
|
+
getPercentiles() {
|
|
270
|
+
if (this.recalculate) {
|
|
271
|
+
this.recalculateStats();
|
|
272
|
+
}
|
|
273
|
+
return {
|
|
274
|
+
0: this.valuesNumeric ? this.min : this.dictionary[this.min],
|
|
275
|
+
25: this.valuesNumeric ? this.percentile25 : this.dictionary[this.percentile25],
|
|
276
|
+
50: this.valuesNumeric ? this.median : this.dictionary[this.median],
|
|
277
|
+
75: this.valuesNumeric ? this.percentile75 : this.dictionary[this.percentile75],
|
|
278
|
+
100: this.valuesNumeric ? this.max : this.dictionary[this.max],
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Get the standard deviation value of the SampleSet. For string
|
|
283
|
+
* values, this is the standard deviation across the size of the
|
|
284
|
+
* SampleSet [0,sampleSet.getNumSamples()-1].
|
|
285
|
+
*
|
|
286
|
+
* @returns number - Calculated standard deviation of the SampleSet
|
|
287
|
+
*/
|
|
288
|
+
getStddev() {
|
|
289
|
+
if (this.recalculate) {
|
|
290
|
+
this.recalculateStats();
|
|
291
|
+
}
|
|
292
|
+
return this.stddev;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Get the type of values in the SampleSet
|
|
296
|
+
*
|
|
297
|
+
* @returns true if numeric values, false if string values
|
|
298
|
+
*/
|
|
299
|
+
isNumeric() {
|
|
300
|
+
return this.valuesNumeric;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Get the number of values in the SampleSet
|
|
304
|
+
*
|
|
305
|
+
* @returns number of samples in the SampleSet
|
|
306
|
+
*/
|
|
307
|
+
getNumSamples() {
|
|
308
|
+
return this.values.length;
|
|
309
|
+
}
|
|
310
|
+
recalculateStats() {
|
|
311
|
+
this.calcMean();
|
|
312
|
+
this.calcVariance();
|
|
313
|
+
this.calcFromSortedValues();
|
|
314
|
+
this.recalculate = false;
|
|
315
|
+
}
|
|
316
|
+
calcMean() {
|
|
317
|
+
this.mean = this.values.reduce((sum, value) => sum + value, 0) / this.values.length;
|
|
318
|
+
this.mean = this.valuesNumeric ? this.mean : Math.round(this.mean);
|
|
319
|
+
}
|
|
320
|
+
// Calculates the variance and standard deviation
|
|
321
|
+
// NOTE - this function ASSUMES that the mean has already been recalculated
|
|
322
|
+
calcVariance() {
|
|
323
|
+
this.variance = this.values.reduce((sum, value) => sum + ((value - this.mean) * (value - this.mean)), 0) / this.values.length;
|
|
324
|
+
this.stddev = Math.sqrt(this.variance);
|
|
325
|
+
}
|
|
326
|
+
// Calculates median, mode, and distribution
|
|
327
|
+
calcFromSortedValues() {
|
|
328
|
+
// sort the values
|
|
329
|
+
let sortedValues;
|
|
330
|
+
if (this.valuesNumeric) {
|
|
331
|
+
// the default sort function is appropriate
|
|
332
|
+
sortedValues = this.values.toSorted((a, b) => a < b ?
|
|
333
|
+
-1 :
|
|
334
|
+
a > b ?
|
|
335
|
+
1 :
|
|
336
|
+
0);
|
|
337
|
+
this.logger?.trace(`SampleSet.calcFromSortedValues: sortedValues: ${sortedValues}`);
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
// need to sort based on dictionary lookup
|
|
341
|
+
sortedValues = this.values.toSorted((a, b) => this.dictionary[a] < this.dictionary[b] ?
|
|
342
|
+
-1 :
|
|
343
|
+
(this.dictionary[a] > this.dictionary[b] ?
|
|
344
|
+
1 :
|
|
345
|
+
0));
|
|
346
|
+
this.logger?.trace(`SampleSet.calcFromSortedValues: sortedValues: ${sortedValues.map((value) => this.dictionary[value])}`);
|
|
347
|
+
}
|
|
348
|
+
// get the median
|
|
349
|
+
const midPointIndex = Math.trunc((this.values.length - 1) / 2);
|
|
350
|
+
this.median = sortedValues[midPointIndex];
|
|
351
|
+
this.logger?.trace(`SampleSet.calcFromSortedValues: midPointIndex: ${midPointIndex}`);
|
|
352
|
+
// get the min and max values
|
|
353
|
+
this.min = sortedValues[0];
|
|
354
|
+
this.max = sortedValues[sortedValues.length - 1];
|
|
355
|
+
// get the percentile25 and percentile50 values
|
|
356
|
+
let percentileIndex = Math.trunc((this.values.length - 1) / 4);
|
|
357
|
+
this.percentile25 = sortedValues[percentileIndex];
|
|
358
|
+
percentileIndex = Math.trunc((this.values.length - 1) * (3 / 4));
|
|
359
|
+
this.percentile75 = sortedValues[percentileIndex];
|
|
360
|
+
// create the distribution histogram/table
|
|
361
|
+
this.distribution = [];
|
|
362
|
+
if (this.valuesNumeric) {
|
|
363
|
+
// in this case, create buckets of equal size which span the range [min, max)
|
|
364
|
+
// and count the number of values in each range
|
|
365
|
+
// Use the sqrt(numSamples) rule of thumb for calculating the number of buckets
|
|
366
|
+
const numBuckets = Math.trunc(Math.sqrt(this.values.length) + 1);
|
|
367
|
+
const bucketSize = (this.max - this.min) / numBuckets;
|
|
368
|
+
let currentMin = sortedValues[0];
|
|
369
|
+
let currentMax = currentMin + bucketSize;
|
|
370
|
+
if (currentMax === this.max) {
|
|
371
|
+
// VERY unlikely - but just in case, add a very small amount so as not to have a
|
|
372
|
+
// bucket of one with only the max value at the end.
|
|
373
|
+
currentMax += 1e-10;
|
|
374
|
+
}
|
|
375
|
+
let count = 0;
|
|
376
|
+
for (let i = 0; i < sortedValues.length; i++) {
|
|
377
|
+
if (sortedValues[i] >= currentMin && sortedValues[i] < currentMax) {
|
|
378
|
+
count++;
|
|
379
|
+
}
|
|
380
|
+
else {
|
|
381
|
+
this.distribution.push(new SampleBucket(currentMin, currentMax, count));
|
|
382
|
+
currentMin += bucketSize;
|
|
383
|
+
currentMax = currentMin + bucketSize;
|
|
384
|
+
if (currentMax === this.max) {
|
|
385
|
+
// VERY unlikely - but just in case, add a very small amount so as not to have a
|
|
386
|
+
// bucket of one with only the max value at the end.
|
|
387
|
+
currentMax += 1e-10;
|
|
388
|
+
}
|
|
389
|
+
count = 1;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
this.distribution.push(new SampleBucket(currentMin, currentMax, count));
|
|
393
|
+
// numBuckets and distribution.length should match
|
|
394
|
+
this.logger?.trace(`SampleSet.calcFromSortedValues: numeric data, numBuckets: ${numBuckets}, distribution.length: ${this.distribution.length}`);
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
// in this case, the number of buckets matches the number of strings in the SampleSet
|
|
398
|
+
// which is the size of the dictionary
|
|
399
|
+
let currentValue = sortedValues[0];
|
|
400
|
+
let count = 0;
|
|
401
|
+
for (let i = 0; i < sortedValues.length; i++) {
|
|
402
|
+
if (sortedValues[i] === currentValue) {
|
|
403
|
+
count++;
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
this.distribution.push(new SampleBucket(currentValue, currentValue, count));
|
|
407
|
+
currentValue = sortedValues[i];
|
|
408
|
+
count = 1;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
this.distribution.push(new SampleBucket(currentValue, currentValue, count));
|
|
412
|
+
// dictionary.length and distribution.length should match
|
|
413
|
+
this.logger?.trace(`SampleSet.calcFromSortedValues: string data, dictionary.length: ${this.dictionary.length}, distribution.length: ${this.distribution.length}`);
|
|
414
|
+
this.logger?.trace(`SampleSet.calcFromSortedValues: dictionary: ${this.dictionary}`);
|
|
415
|
+
}
|
|
416
|
+
this.logger?.trace(`SampleSet.calcFromSortedValues: numeric: ${this.valuesNumeric}, distribution details: ${JSON.stringify(this.distribution, null, 2)}`);
|
|
417
|
+
// calculate the mode
|
|
418
|
+
const maxDistributionBucketIndex = this.distribution.reduce((curMaxIndex, bucket, index) => bucket.count > this.distribution[curMaxIndex].count ? index : curMaxIndex, 0);
|
|
419
|
+
if (this.valuesNumeric) {
|
|
420
|
+
this.mode = this.distribution[maxDistributionBucketIndex].min +
|
|
421
|
+
(this.distribution[maxDistributionBucketIndex].max - this.distribution[maxDistributionBucketIndex].min) / 2;
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
this.mode = this.distribution[maxDistributionBucketIndex].min;
|
|
425
|
+
}
|
|
426
|
+
this.logger?.trace(`SampleSet.calcFromSortedValues: mode: ${this.mode}`);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2FtcGxlLXNldC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21wb25lbnRzL3NhbXBsZS1zZXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsOEJBQThCO0FBSTlCOzs7R0FHRztBQUNILE1BQU0sT0FBTyxZQUFZO0lBQ2hCLEdBQUcsQ0FBUztJQUNaLEdBQUcsQ0FBUztJQUNaLFFBQVEsQ0FBUztJQUNqQixLQUFLLENBQVM7SUFFckIsWUFBWSxHQUFXLEVBQUUsR0FBVyxFQUFFLEtBQWE7UUFDakQsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUM7UUFDZixJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztRQUNmLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFDLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztJQUNyQixDQUFDO0NBQ0Y7QUFrQ0EsQ0FBQztBQUVGOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxPQUFPLFNBQVM7SUFDcEIsZUFBZTtJQUNMLE1BQU0sQ0FBVztJQUUzQixjQUFjO0lBQ04sYUFBYSxDQUFVO0lBQ3ZCLE1BQU0sQ0FBVztJQUNqQixVQUFVLENBQVc7SUFFN0IsbUJBQW1CO0lBQ1gsV0FBVyxDQUFVLENBQUMsK0NBQStDO0lBQ3JFLElBQUksQ0FBUztJQUNiLE1BQU0sQ0FBUztJQUNmLElBQUksQ0FBUztJQUNiLFFBQVEsQ0FBUztJQUNqQixNQUFNLENBQVM7SUFDZixHQUFHLENBQVM7SUFDWixHQUFHLENBQVM7SUFDWixZQUFZLENBQVM7SUFDckIsWUFBWSxDQUFTO0lBQ3JCLFlBQVksQ0FBaUI7SUFFckM7Ozs7T0FJRztJQUNILFlBQVksT0FBeUI7UUFDbkMsZUFBZTtRQUNmLElBQUksQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLE1B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KSAyMDI2IFRpbSBIYWhuXG5cbmltcG9ydCB7IElMb2dnZXIgfSBmcm9tICdAbmNmb3VyLXVzL2xvZ2dpbmcnO1xuXG4vKipcbiAqIFNhbXBsZUJ1Y2tldCBpcyB1c2VkIHRvIHJlcHJlc2VudCB0aGUgY2FsY3VsYXRlZFxuICogZGlzdHJpYnV0aW9uIGZvciB0aGUgU2FtcGxlU2V0LlxuICovXG5leHBvcnQgY2xhc3MgU2FtcGxlQnVja2V0IHtcbiAgcHVibGljIG1pbjogbnVtYmVyO1xuICBwdWJsaWMgbWF4OiBudW1iZXI7XG4gIHB1YmxpYyBtaWRQb2ludDogbnVtYmVyO1xuICBwdWJsaWMgY291bnQ6IG51bWJlcjtcblxuICBjb25zdHJ1Y3RvcihtaW46IG51bWJlciwgbWF4OiBudW1iZXIsIGNvdW50OiBudW1iZXIpIHtcbiAgICB0aGlzLm1pbiA9IG1pbjtcbiAgICB0aGlzLm1heCA9IG1heDtcbiAgICB0aGlzLm1pZFBvaW50ID0gdGhpcy5taW4gKyAodGhpcy5tYXgtdGhpcy5taW4pLzI7XG4gICAgdGhpcy5jb3VudCA9IGNvdW50O1xuICB9XG59XG5cbi8qKlxuICogVGhlIHR5cGUgb2YgdmFsdWVzIHN0b3JlZCBpbiB0aGUgU2FtcGxlU2V0XG4gKi9cbmV4cG9ydCB0eXBlIFNhbXBsZVNldFZhbHVlID0gbnVtYmVyIHwgc3RyaW5nO1xuXG4vKipcbiAqIFNhbXBsZVNldFBlcmNlbnRpbGVzIHJlcHJlc2VudHMgdGhlIGNhbGN1bGF0ZWQgcGVyY2VudGlsZXNcbiAqIGZvciB0aGUgdmFsdWVzIGluIHRoZSBTYW1wbGVTZXQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2FtcGxlU2V0UGVyY2VudGlsZXMge1xuICAwOiBTYW1wbGVTZXRWYWx1ZTtcbiAgMjU6IFNhbXBsZVNldFZhbHVlO1xuICA1MDogU2FtcGxlU2V0VmFsdWU7XG4gIDc1OiBTYW1wbGVTZXRWYWx1ZTtcbiAgMTAwOiBTYW1wbGVTZXRWYWx1ZTtcbn1cblxuLyoqXG4gKiBUaGUgb3B0aW9ucyBmb3IgaW5zdGFudGlhdGluZyB0aGUgU2FtcGxlU2V0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNhbXBsZVNldE9wdGlvbnMge1xuXG4gIC8qKlxuICAgKiBvcHRpb25hbCBpbml0aWFsIHNldCBvZiB2YWx1ZXMgdG8gcHV0IGludG8gdGhlIFNhbXBsZVNldFxuICAgKi9cbiAgaW5pdGlhbFZhbHVlcz86IFNhbXBsZVNldFZhbHVlW107XG5cbiAgLy8gZGVwZW5kZW5jaWVzXG4gIC8qKlxuICAgKiBvcHRpb25hbCBsb2dnZXIgdG8gdXNlLlxuICAgKi9cbiAgbG9nZ2VyPzogSUxvZ2dlcjtcbn07XG5cbi8qKlxuICogQmFzZSBjbGFzcyB0byByZXByZXNlbnQgc2FtcGxlcyBvZiBhIHJhbmRvbSB2YXJpYWJsZVxuICogaW4gdGhlIHN0YXRzIHBhY2thZ2UuXG4gKlxuICogT3RoZXIgY2FsY3VsYXRlZCBkaXN0cmlidXRpb25zIGFyZSBiYXNlZCBvbiB0aGlzIGJhc2VcbiAqIGNsYXNzLiAgSG93ZXZlciwgaW5zdGFuY2VzIG9mIHRoZSBiYXNlIGNsYXNzIGNhbiBiZVxuICogY3JlYXRlZCBhcyB3ZWxsLCBpZiBhIHNldCBvZiByYW5kb20gdmFsdWVzIGV4aXN0cyB0b1xuICogaW5pdGlhbGl6ZSB0aGUgU2FtcGxlU2V0LlxuICovXG5leHBvcnQgY2xhc3MgU2FtcGxlU2V0IHtcbiAgLy8gZGVwZW5kZW5jaWVzXG4gIHByb3RlY3RlZCBsb2dnZXI/OiBJTG9nZ2VyO1xuXG4gIC8vIHNhbXBsZSBkYXRhXG4gIHByaXZhdGUgdmFsdWVzTnVtZXJpYzogYm9vbGVhbjtcbiAgcHJpdmF0ZSB2YWx1ZXM6IG51bWJlcltdO1xuICBwcml2YXRlIGRpY3Rpb25hcnk6IHN0cmluZ1tdO1xuXG4gIC8vIGNhbGN1bGF0ZWQgaXRlbXNcbiAgcHJpdmF0ZSByZWNhbGN1bGF0ZTogYm9vbGVhbjsgLy8gc2V0cyB3aGV0aGVyIG9yIG5vdCByZS1jYWxjdWxhdGlvbiBpcyBuZWVkZWRcbiAgcHJpdmF0ZSBtZWFuOiBudW1iZXI7XG4gIHByaXZhdGUgbWVkaWFuOiBudW1iZXI7XG4gIHByaXZhdGUgbW9kZTogbnVtYmVyO1xuICBwcml2YXRlIHZhcmlhbmNlOiBudW1iZXI7XG4gIHByaXZhdGUgc3RkZGV2OiBudW1iZXI7XG4gIHByaXZhdGUgbWF4OiBudW1iZXI7XG4gIHByaXZhdGUgbWluOiBudW1iZXI7XG4gIHByaXZhdGUgcGVyY2VudGlsZTI1OiBudW1iZXI7XG4gIHByaXZhdGUgcGVyY2VudGlsZTc1OiBudW1iZXI7XG4gIHByaXZhdGUgZGlzdHJpYnV0aW9uOiBTYW1wbGVCdWNrZXRbXTtcblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IFNhbXBsZVNldCBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIG9wdGlvbnMgU2VlIHtAbGluayBTYW1wbGVTZXRPcHRpb25zfVxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9uczogU2FtcGxlU2V0T3B0aW9ucykge1xuICAgIC8vIGRlcGVuZGVuY2llc1xuICAgIHRoaXMubG9nZ2VyID0gb3B0aW9ucy5sb2dnZXI7XG5cbiAgICAvLyBpbnRpYWxpemUgaW5mb3JtYXRpb25cbiAgICB0aGlzLnJlY2FsY3VsYXRlID0gdHJ1ZTtcbiAgICB0aGlzLm1lYW4gPSAwO1xuICAgIHRoaXMubWVkaWFuID0gMDtcbiAgICB0aGlzLm1vZGUgPSAwO1xuICAgIHRoaXMudmFyaWFuY2UgPSAwO1xuICAgIHRoaXMuc3RkZGV2ID0gMDtcbiAgICB0aGlzLm1pbiA9IDA7XG4gICAgdGhpcy5tYXggPSAwO1xuICAgIHRoaXMucGVyY2VudGlsZTI1ID0gMDtcbiAgICB0aGlzLnBlcmNlbnRpbGU3NSA9IDA7XG4gICAgdGhpcy5kaXN0cmlidXRpb24gPSBbXTtcblxuICAgIC8vIGluaXRpYWxpemUgdmFsdWVzXG4gICAgdGhpcy52YWx1ZXNOdW1lcmljID0gdHJ1ZTtcbiAgICB0aGlzLnZhbHVlcyA9IChbXSBhcyBudW1iZXJbXSk7XG4gICAgdGhpcy5kaWN0aW9uYXJ5ID0gKFtdIGFzIHN0cmluZ1tdKTtcbiAgICBpZiAob3B0aW9ucy5pbml0aWFsVmFsdWVzKSB7XG4gICAgICB0aGlzLnNldFZhbHVlcyhvcHRpb25zLmluaXRpYWxWYWx1ZXMpO1xuICAgIH1cblxuICAgIHRoaXMubG9nZ2VyPy50cmFjZShgU2FtcGxlU2V0LmNvbnN0cnVjdG9yOiBudW1TYW1wbGVzOiAke3RoaXMudmFsdWVzLmxlbmd0aH1gKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIGdldCB0aGUgYXJyYXkgb2YgdmFsdWVzIGhlbGQgaW4gdGhlIFNhbXBsZVNldC5cbiAgICpcbiAgICogQHJldHVybnMgU2FtcGxlU2V0VmFsdWVbXSAtIGFycmF5IG9mIFNhbXBsZVNldFZhbHVlXG4gICAqL1xuICBwdWJsaWMgZ2V0VmFsdWVzKCk6IFNhbXBsZVNldFZhbHVlW10ge1xuICAgIGxldCByZXRWYWxzOiBTYW1wbGVTZXRWYWx1ZVtdO1xuICAgIGlmICh0aGlzLnZhbHVlc051bWVyaWMpIHtcbiAgICAgIHJldFZhbHMgPSB0aGlzLnZhbHVlcy5tYXAoKHZhbHVlKSA9PiB2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldFZhbHMgPSB0aGlzLnZhbHVlcy5tYXAoKHZhbHVlKSA9PiB0aGlzLmRpY3Rpb25hcnlbdmFsdWVdKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmV0VmFscztcbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgYSBzcGVjaWZpYyB2YWx1ZSwgYnkgaW5kZXgsIGhlbGQgaW4gdGhlIFNhbXBsZVNldC5cbiAgICpcbiAgICogQHJldHVybnMgU2FtcGxlU2V0VmFsdWVcbiAgICovXG4gIHB1YmxpYyBnZXRWYWx1ZShpbmRleDogbnVtYmVyKTogU2FtcGxlU2V0VmFsdWUgfCB1bmRlZmluZWQge1xuICAgIGxldCByZXRWYWw6IFNhbXBsZVNldFZhbHVlO1xuXG4gICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSB0aGlzLnZhbHVlcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudmFsdWVzTnVtZXJpYykge1xuICAgICAgcmV0VmFsID0gdGhpcy52YWx1ZXNbaW5kZXhdO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXRWYWwgPSB0aGlzLmRpY3Rpb25hcnlbdGhpcy52YWx1ZXNbaW5kZXhdXTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmV0VmFsO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcGxhY2UgdGhlIHNldCBvZiB2YWx1ZXMgaGVsZCBpbiB0aGUgU2FtcGxlU2V0XG4gICAqL1xuICBwdWJsaWMgc2V0VmFsdWVzKHZhbHVlczogU2FtcGxlU2V0VmFsdWVbXSk6IHZvaWQge1xuICAgIHRoaXMudmFsdWVzID0gW10gYXMgbnVtYmVyW107XG4gICAgdGhpcy5kaWN0aW9uYXJ5ID0gW10gYXMgc3RyaW5nW107XG5cbiAgICB0aGlzLmxvZ2dlcj8udHJhY2UoYFNhbXBsZVNldC5zZXRWYWx1ZXM6IHR5cGVvZiB2YWx1ZTogJHt0eXBlb2YgdmFsdWVzWzBdfWApO1xuXG4gICAgaWYgKHZhbHVlcy5sZW5ndGggPiAwICYmIHR5cGVvZiB2YWx1ZXNbMF0gPT09ICdzdHJpbmcnKSB7XG4gICAgICB0aGlzLnZhbHVlc051bWVyaWMgPSBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy52YWx1ZXNOdW1lcmljID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB0aGlzLmFkZFZhbHVlcyh2YWx1ZXMpO1xuXG4gICAgdGhpcy5yZWNhbGN1bGF0ZSA9IHRydWU7XG4gIH1cblxuICAvKipcbiAgICogQWRkIHZhbHVlcyB0byB0aGUgU2FtcGxlU2V0XG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZXMgdmFsdWVzIHRvIGFkZCB0byB0aGUgU2FtcGxlU2V0XG4gICAqL1xuICBwdWJsaWMgYWRkVmFsdWVzKHZhbHVlczogU2FtcGxlU2V0VmFsdWVbXSApOiB2b2lkIHtcbiAgICBpZiAoIHRoaXMudmFsdWVzLmxlbmd0aCA+IDAgJiZcbiAgICAgICAgKCB0eXBlb2YgdmFsdWVzWzBdID09PSAnc3RyaW5nJyAmJiB0aGlzLnZhbHVlc051bWVyaWMgKSB8fFxuICAgICAgICAoIHR5cGVvZiB2YWx1ZXNbMF0gPT09ICdudW1iZXInICYmICF0aGlzLnZhbHVlc051bWVyaWMgKSApIHtcbiAgICAgIC8vIHR5cGUgbWlzbWF0Y2ggb24gdmFsdWVzIGJlaW5nIGFkZGVkIC0gcXVpZXRseSBJR05PUkVcbiAgICAgIHRoaXMubG9nZ2VyPy5lcnJvcihgU2FtcGxlU2V0LmFkZFZhbHVlczogdHlwZSBtaXNtYXRjaCBvbiB2YWx1ZXMgYWRkZWQsIHZhbHVlc051bWVyaWM6ICR7dGhpcy52YWx1ZXNOdW1lcmljfSwgdmFsdWVzIHR5cGU6ICR7dHlwZW9mIHZhbHVlc1swXX1gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodmFsdWVzLmxlbmd0aCA+IDAgJiYgdHlwZW9mIHZhbHVlc1swXSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRoaXMudmFsdWVzTnVtZXJpYyA9IGZhbHNlO1xuXG4gICAgICAodmFsdWVzIGFzIHN0cmluZ1tdKS5mb3JFYWNoKCh2YWx1ZSkgPT4ge1xuICAgICAgICBjb25zdCBleGlzdGluZ0l0ZW1JbmRleCA9IHRoaXMuZGljdGlvbmFyeS5maW5kSW5kZXgoKGRpY3RJdGVtKSA9PiBkaWN0SXRlbSA9PT0gdmFsdWUpO1xuICAgICAgICBpZiAoZXhpc3RpbmdJdGVtSW5kZXggPj0gMCkge1xuICAgICAgICAgIC8vIGl0ZW0gZm91bmQgaW4gZGljdGlvbmFyeVxuICAgICAgICAgIHRoaXMudmFsdWVzLnB1c2goZXhpc3RpbmdJdGVtSW5kZXgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGFkZCB0byBkaWN0aW9uYXJ5XG4gICAgICAgICAgdGhpcy5kaWN0aW9uYXJ5LnB1c2godmFsdWUpO1xuICAgICAgICAgIHRoaXMudmFsdWVzLnB1c2godGhpcy5kaWN0aW9uYXJ5Lmxlbmd0aC0xKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMubG9nZ2VyPy50cmFjZShgU2FtcGxlU2V0LmFkZFZhbHVlczogcmVzdWx0aW5nIGRpY3Rpb25hcnk6ICR7dGhpcy5kaWN0aW9uYXJ5fWApO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBudW1iZXIgdmFsdWVzXG4gICAgICB0aGlzLnZhbHVlc051bWVyaWMgPSB0cnVlO1xuICAgICAgdGhpcy52YWx1ZXMgPSAodmFsdWVzIGFzIG51bWJlcltdKS5tYXAoKHZhbHVlKSA9PiB2YWx1ZSkgYXMgbnVtYmVyW107XG4gICAgfVxuXG4gICAgdGhpcy5sb2dnZXI/LnRyYWNlKGBTYW1wbGVTZXQuYWRkVmFsdWVzOiBuZXcgbnVtU2FtcGxlczogJHt0aGlzLnZhbHVlcy5sZW5ndGh9YCk7XG5cbiAgICB0aGlzLnJlY2FsY3VsYXRlID0gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYSBzaW5nbGUgdmFsdWUgdG8gdGhlIFNhbXBsZVNldFxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgdmFsdWUgdG8gYWRkIHRvIHRoZSBTYW1wbGVTZXRcbiAgICovXG4gIHB1YmxpYyBhZGRWYWx1ZSh2YWx1ZTogU2FtcGxlU2V0VmFsdWUpIHtcbiAgICBpZiAoIHRoaXMudmFsdWVzLmxlbmd0aCA+IDAgJiZcbiAgICAgICAgKCB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnICYmIHRoaXMudmFsdWVzTnVtZXJpYyApIHx8XG4gICAgICAgICggdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiAhdGhpcy52YWx1ZXNOdW1lcmljICkgKSB7XG4gICAgICAvLyB0eXBlIG1pc21hdGNoIG9uIHZhbHVlcyBiZWluZyBhZGRlZCAtIHF1aWV0bHkgSUdOT1JFXG4gICAgICB0aGlzLmxvZ2dlcj8uZXJyb3IoYFNhbXBsZVNldC5hZGRWYWx1ZTogdHlwZSBtaXNtYXRjaCBvbiB2YWx1ZSBhZGRlZCwgdmFsdWVzTnVtZXJpYzogJHt0aGlzLnZhbHVlc051bWVyaWN9LCB2YWx1ZXMgdHlwZTogJHt0eXBlb2YgdmFsdWV9YCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGNvbnN0IGV4aXN0aW5nSXRlbUluZGV4ID0gdGhpcy5kaWN0aW9uYXJ5LmZpbmRJbmRleCgoZGljdEl0ZW0pID0+IGRpY3RJdGVtID09PSB2YWx1ZSk7XG4gICAgICBpZiAoZXhpc3RpbmdJdGVtSW5kZXggPiAwKSB7XG4gICAgICAgIC8vIGl0ZW0gZm91bmQgaW4gZGljdGlvbmFyeVxuICAgICAgICB0aGlzLnZhbHVlcy5wdXNoKGV4aXN0aW5nSXRlbUluZGV4KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGFkZCB0byBkaWN0aW9uYXJ5XG4gICAgICAgIHRoaXMuZGljdGlvbmFyeS5wdXNoKHZhbHVlKTtcbiAgICAgICAgdGhpcy52YWx1ZXMucHVzaCh0aGlzLmRpY3Rpb25hcnkubGVuZ3RoLTEpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnZhbHVlcy5wdXNoKHZhbHVlKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlY2FsY3VsYXRlID0gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIG1lYW4gdmFsdWUgb2YgdGhlIFNhbXBsZVNldC4gIEZvciBzdHJpbmdcbiAgICogdmFsdWVzLCB0aGlzIGlzIG9yZGVyZWQgYnkgc3RyaW5nIHNvcnRpbmcgcnVsZXMuXG4gICAqXG4gICAqIEByZXR1cm5zIFNhbXBsZVNldFZhbHVlIC0gbWVhbiB2YWx1ZSBvZiB0aGUgU2FtcGxlU2V0XG4gICAqL1xuICBwdWJsaWMgZ2V0TWVhbigpOiBTYW1wbGVTZXRWYWx1ZSB7XG4gICAgaWYgKHRoaXMucmVjYWxjdWxhdGUpIHtcbiAgICAgIHRoaXMucmVjYWxjdWxhdGVTdGF0cygpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy52YWx1ZXNOdW1lcmljID8gdGhpcy5tZWFuIDogdGhpcy5kaWN0aW9uYXJ5W3RoaXMubWVhbl07XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBtZWRpYW4gdmFsdWUgb2YgdGhlIFNhbXBsZVNldC4gIEZvciBzdHJpbmdcbiAgICogdmFsdWVzLCB0aGlzIGlzIG9yZGVyZWQgYnkgc3RyaW5nIHNvcnRpbmcgcnVsZXMuXG4gICAqXG4gICAqIEByZXR1cm5zIFNhbXBsZVNldFZhbHVlIC0gbWVkaWFuIHZhbHVlIG9mIHRoZSBTYW1wbGVTZXRcbiAgICovXG4gIHB1YmxpYyBnZXRNZWRpYW4oKTogU2FtcGxlU2V0VmFsdWUge1xuICAgIGlmICh0aGlzLnJlY2FsY3VsYXRlKSB7XG4gICAgICB0aGlzLnJlY2FsY3VsYXRlU3RhdHMoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudmFsdWVzTnVtZXJpYyA/IHRoaXMubWVkaWFuIDogdGhpcy5kaWN0aW9uYXJ5W3RoaXMubWVkaWFuXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIG1vZGUgdmFsdWUgb2YgdGhlIFNhbXBsZVNldC4gIEZvciBzdHJpbmdcbiAgICogdmFsdWVzLCB0aGlzIGlzIG9yZGVyZWQgYnkgc3RyaW5nIHNvcnRpbmcgcnVsZXMuXG4gICAqXG4gICAqIEByZXR1cm5zIFNhbXBsZVNldFZhbHVlIC0gbW9kZSB2YWx1ZSBvZiB0aGUgU2FtcGxlU2V0XG4gICAqL1xuICBwdWJsaWMgZ2V0TW9kZSgpOiBTYW1wbGVTZXRWYWx1ZSB7XG4gICAgaWYgKHRoaXMucmVjYWxjdWxhdGUpIHtcbiAgICAgIHRoaXMucmVjYWxjdWxhdGVTdGF0cygpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy52YWx1ZXNOdW1lcmljID8gdGhpcy5tb2RlIDogdGhpcy5kaWN0aW9uYXJ5W3RoaXMubW9kZV07XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBtaW5pbXVtIHZhbHVlIG9mIHRoZSBTYW1wbGVTZXQuICBGb3Igc3RyaW5nXG4gICAqIHZhbHVlcywgdGhpcyBpcyBvcmRlcmVkIGJ5IHN0cmluZyBzb3J0aW5nIHJ1bGVzLlxuICAgKlxuICAgKiBAcmV0dXJucyBTYW1wbGVTZXRWYWx1ZSAtIG1pbmltdW0gdmFsdWUgb2YgdGhlIFNhbXBsZVNldFxuICAgKi9cbiAgcHVibGljIGdldE1pbigpOiBTYW1wbGVTZXRWYWx1ZSB7XG4gICAgaWYgKHRoaXMucmVjYWxjdWxhdGUpIHtcbiAgICAgIHRoaXMucmVjYWxjdWxhdGVTdGF0cygpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy52YWx1ZXNOdW1lcmljID8gdGhpcy5taW4gOiB0aGlzLmRpY3Rpb25hcnlbdGhpcy5taW5dO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgbWF4aW11bSB2YWx1ZSBvZiB0aGUgU2FtcGxlU2V0LiAgRm9yIHN0cmluZ1xuICAgKiB2YWx1ZXMsIHRoaXMgaXMgb3JkZXJlZCBieSBzdHJpbmcgc29ydGluZyBydWxlcy5cbiAgICpcbiAgICogQHJldHVybnMgU2FtcGxlU2V0VmFsdWUgLSBtYXhpbXVtIHZhbHVlIG9mIHRoZSBTYW1wbGVTZXRcbiAgICovXG4gIHB1YmxpYyBnZXRNYXgoKTogU2FtcGxlU2V0VmFsdWUge1xuICAgIGlmICh0aGlzLnJlY2FsY3VsYXRlKSB7XG4gICAgICB0aGlzLnJlY2FsY3VsYXRlU3RhdHMoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudmFsdWVzTnVtZXJpYyA/IHRoaXMubWF4IDogdGhpcy5kaWN0aW9uYXJ5W3RoaXMubWF4XTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIHZhcmlhbmNlIHZhbHVlIG9mIHRoZSBTYW1wbGVTZXQuICBGb3Igc3RyaW5nXG4gICAqIHZhbHVlcywgdGhpcyBpcyB0aGUgdmFyaWFuY2UgYWNyb3NzIHRoZSBzaXplIG9mIHRoZSBTYW1wbGVTZXQgWzAsc2FtcGxlU2V0LmdldE51bVNhbXBsZXMoKS0xXS5cbiAgICpcbiAgICogQHJldHVybnMgbnVtYmVyIC0gQ2FsY3VsYXRlZCB2YXJpYW5jZSBvZiB0aGUgU2FtcGxlU2V0XG4gICAqL1xuICBwdWJsaWMgZ2V0VmFyaWFuY2UoKTogbnVtYmVyIHtcbiAgICBpZiAodGhpcy5yZWNhbGN1bGF0ZSkge1xuICAgICAgdGhpcy5yZWNhbGN1bGF0ZVN0YXRzKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnZhcmlhbmNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgcGVyY2VudGlsZXMgdmFsdWVzIGZvciB0aGUgU2FtcGxlU2V0LlxuICAgKlxuICAgKiBAcmV0dXJucyBzYW1wbGVTZXRQZXJjZW50aWxlcyAtIHRoZSAwLCAyNSwgNTAsIDc1LCBhbmQgMTAwdGggcGVyY2VudGlhbCB2YWx1ZXMgZm9yIHRoZSBTYW1wbGVTZXQuXG4gICAqL1xuICBwdWJsaWMgZ2V0UGVyY2VudGlsZXMoKTogU2FtcGxlU2V0UGVyY2VudGlsZXMge1xuICAgIGlmICh0aGlzLnJlY2FsY3VsYXRlKSB7XG4gICAgICB0aGlzLnJlY2FsY3VsYXRlU3RhdHMoKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIDA6IHRoaXMudmFsdWVzTnVtZXJpYyA/IHRoaXMubWluIDogdGhpcy5kaWN0aW9uYXJ5W3RoaXMubWluXSxcbiAgICAgIDI1OiB0aGlzLnZhbHVlc051bWVyaWMgPyB0aGlzLnBlcmNlbnRpbGUyNSA6IHRoaXMuZGljdGlvbmFyeVt0aGlzLnBlcmNlbnRpbGUyNV0sXG4gICAgICA1MDogdGhpcy52YWx1ZXNOdW1lcmljID8gdGhpcy5tZWRpYW4gOiB0aGlzLmRpY3Rpb25hcnlbdGhpcy5tZWRpYW5dLFxuICAgICAgNzU6IHRoaXMudmFsdWVzTnVtZXJpYyA/IHRoaXMucGVyY2VudGlsZTc1IDogdGhpcy5kaWN0aW9uYXJ5W3RoaXMucGVyY2VudGlsZTc1XSxcbiAgICAgIDEwMDogdGhpcy52YWx1ZXNOdW1lcmljID8gdGhpcy5tYXggOiB0aGlzLmRpY3Rpb25hcnlbdGhpcy5tYXhdLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gdmFsdWUgb2YgdGhlIFNhbXBsZVNldC4gIEZvciBzdHJpbmdcbiAgICogdmFsdWVzLCB0aGlzIGlzIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gYWNyb3NzIHRoZSBzaXplIG9mIHRoZVxuICAgKiBTYW1wbGVTZXQgWzAsc2FtcGxlU2V0LmdldE51bVNhbXBsZXMoKS0xXS5cbiAgICpcbiAgICogQHJldHVybnMgbnVtYmVyIC0gQ2FsY3VsYXRlZCBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIFNhbXBsZVNldFxuICAgKi9cbiAgcHVibGljIGdldFN0ZGRldigpOiBudW1iZXIge1xuICAgIGlmICh0aGlzLnJlY2FsY3VsYXRlKSB7XG4gICAgICB0aGlzLnJlY2FsY3VsYXRlU3RhdHMoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc3RkZGV2O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgdHlwZSBvZiB2YWx1ZXMgaW4gdGhlIFNhbXBsZVNldFxuICAgKlxuICAgKiBAcmV0dXJucyB0cnVlIGlmIG51bWVyaWMgdmFsdWVzLCBmYWxzZSBpZiBzdHJpbmcgdmFsdWVzXG4gICAqL1xuICBwdWJsaWMgaXNOdW1lcmljKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnZhbHVlc051bWVyaWM7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBudW1iZXIgb2YgdmFsdWVzIGluIHRoZSBTYW1wbGVTZXRcbiAgICpcbiAgICogQHJldHVybnMgbnVtYmVyIG9mIHNhbXBsZXMgaW4gdGhlIFNhbXBsZVNldFxuICAgKi9cbiAgcHVibGljIGdldE51bVNhbXBsZXMoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy52YWx1ZXMubGVuZ3RoO1xuICB9XG5cbiAgcHJpdmF0ZSByZWNhbGN1bGF0ZVN0YXRzKCkge1xuXG4gICAgdGhpcy5jYWxjTWVhbigpO1xuICAgIHRoaXMuY2FsY1ZhcmlhbmNlKCk7XG4gICAgdGhpcy5jYWxjRnJvbVNvcnRlZFZhbHVlcygpO1xuXG4gICAgdGhpcy5yZWNhbGN1bGF0ZSA9IGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBjYWxjTWVhbigpIHtcbiAgICB0aGlzLm1lYW4gPSB0aGlzLnZhbHVlcy5yZWR1Y2UoKHN1bSwgdmFsdWUpID0+IHN1bSt2YWx1ZSwgMCkgLyB0aGlzLnZhbHVlcy5sZW5ndGg7XG4gICAgdGhpcy5tZWFuID0gdGhpcy52YWx1ZXNOdW1lcmljID8gdGhpcy5tZWFuIDogTWF0aC5yb3VuZCh0aGlzLm1lYW4pO1xuICB9XG5cbiAgLy8gQ2FsY3VsYXRlcyB0aGUgdmFyaWFuY2UgYW5kIHN0YW5kYXJkIGRldmlhdGlvblxuICAvLyBOT1RFIC0gdGhpcyBmdW5jdGlvbiBBU1NVTUVTIHRoYXQgdGhlIG1lYW4gaGFzIGFscmVhZHkgYmVlbiByZWNhbGN1bGF0ZWRcbiAgcHJpdmF0ZSBjYWxjVmFyaWFuY2UoKSB7XG4gICAgdGhpcy52YXJpYW5jZSA9IHRoaXMudmFsdWVzLnJlZHVjZSgoc3VtLCB2YWx1ZSkgPT4gc3VtKygodmFsdWUtdGhpcy5tZWFuKSoodmFsdWUtdGhpcy5tZWFuKSksIDApIC8gdGhpcy52YWx1ZXMubGVuZ3RoO1xuICAgIHRoaXMuc3RkZGV2ID0gTWF0aC5zcXJ0KHRoaXMudmFyaWFuY2UpO1xuICB9XG5cbiAgLy8gQ2FsY3VsYXRlcyBtZWRpYW4sIG1vZGUsIGFuZCBkaXN0cmlidXRpb25cbiAgcHJpdmF0ZSBjYWxjRnJvbVNvcnRlZFZhbHVlcygpIHtcbiAgICAvLyBzb3J0IHRoZSB2YWx1ZXNcbiAgICBsZXQgc29ydGVkVmFsdWVzOiBudW1iZXJbXTtcblxuICAgIGlmICggdGhpcy52YWx1ZXNOdW1lcmljICkge1xuICAgICAgLy8gdGhlIGRlZmF1bHQgc29ydCBmdW5jdGlvbiBpcyBhcHByb3ByaWF0ZVxuICAgICAgc29ydGVkVmFsdWVzID0gdGhpcy52YWx1ZXMudG9Tb3J0ZWQoIChhLCBiKSA9PlxuICAgICAgICBhIDwgYiA/XG4gICAgICAgICAgLTEgOlxuICAgICAgICAgIGEgPiBiID9cbiAgICAgICAgICAgIDEgOlxuICAgICAgICAgICAgMCxcbiAgICAgICk7XG5cbiAgICAgIHRoaXMubG9nZ2VyPy50cmFjZShgU2FtcGxlU2V0LmNhbGNGcm9tU29ydGVkVmFsdWVzOiBzb3J0ZWRWYWx1ZXM6ICR7c29ydGVkVmFsdWVzfWApO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBuZWVkIHRvIHNvcnQgYmFzZWQgb24gZGljdGlvbmFyeSBsb29rdXBcbiAgICAgIHNvcnRlZFZhbHVlcyA9IHRoaXMudmFsdWVzLnRvU29ydGVkKCAoYSwgYikgPT5cbiAgICAgICAgdGhpcy5kaWN0aW9uYXJ5W2FdIDwgdGhpcy5kaWN0aW9uYXJ5W2JdID9cbiAgICAgICAgICAtMSA6XG4gICAgICAgICAgKHRoaXMuZGljdGlvbmFyeVthXSA+IHRoaXMuZGljdGlvbmFyeVtiXSA/XG4gICAgICAgICAgICAxIDpcbiAgICAgICAgICAgIDAgKSxcbiAgICAgICk7XG5cbiAgICAgIHRoaXMubG9nZ2VyPy50cmFjZShgU2FtcGxlU2V0LmNhbGNGcm9tU29ydGVkVmFsdWVzOiBzb3J0ZWRWYWx1ZXM6ICR7c29ydGVkVmFsdWVzLm1hcCgodmFsdWUpID0+IHRoaXMuZGljdGlvbmFyeVt2YWx1ZV0pfWApO1xuICAgIH1cblxuXG4gICAgLy8gZ2V0IHRoZSBtZWRpYW5cbiAgICBjb25zdCBtaWRQb2ludEluZGV4ID0gTWF0aC50cnVuYygodGhpcy52YWx1ZXMubGVuZ3RoLTEpLzIpO1xuICAgIHRoaXMubWVkaWFuID0gc29ydGVkVmFsdWVzW21pZFBvaW50SW5kZXhdO1xuICAgIHRoaXMubG9nZ2VyPy50cmFjZShgU2FtcGxlU2V0LmNhbGNGcm9tU29ydGVkVmFsdWVzOiBtaWRQb2ludEluZGV4OiAke21pZFBvaW50SW5kZXh9YCk7XG5cbiAgICAvLyBnZXQgdGhlIG1pbiBhbmQgbWF4IHZhbHVlc1xuICAgIHRoaXMubWluID0gc29ydGVkVmFsdWVzWzBdO1xuICAgIHRoaXMubWF4ID0gc29ydGVkVmFsdWVzW3NvcnRlZFZhbHVlcy5sZW5ndGgtMV07XG5cbiAgICAvLyBnZXQgdGhlIHBlcmNlbnRpbGUyNSBhbmQgcGVyY2VudGlsZTUwIHZhbHVlc1xuICAgIGxldCBwZXJjZW50aWxlSW5kZXggPSBNYXRoLnRydW5jKCh0aGlzLnZhbHVlcy5sZW5ndGgtMSkvNCk7XG4gICAgdGhpcy5wZXJjZW50aWxlMjUgPSBzb3J0ZWRWYWx1ZXNbcGVyY2VudGlsZUluZGV4XTtcbiAgICBwZXJjZW50aWxlSW5kZXggPSBNYXRoLnRydW5jKCh0aGlzLnZhbHVlcy5sZW5ndGgtMSkqKDMvNCkpO1xuICAgIHRoaXMucGVyY2VudGlsZTc1ID0gc29ydGVkVmFsdWVzW3BlcmNlbnRpbGVJbmRleF07XG5cbiAgICAvLyBjcmVhdGUgdGhlIGRpc3RyaWJ1dGlvbiBoaXN0b2dyYW0vdGFibGVcbiAgICB0aGlzLmRpc3RyaWJ1dGlvbiA9IFtdO1xuICAgIGlmICggdGhpcy52YWx1ZXNOdW1lcmljICkge1xuICAgICAgLy8gaW4gdGhpcyBjYXNlLCBjcmVhdGUgYnVja2V0cyBvZiBlcXVhbCBzaXplIHdoaWNoIHNwYW4gdGhlIHJhbmdlIFttaW4sIG1heClcbiAgICAgIC8vIGFuZCBjb3VudCB0aGUgbnVtYmVyIG9mIHZhbHVlcyBpbiBlYWNoIHJhbmdlXG5cbiAgICAgIC8vIFVzZSB0aGUgc3FydChudW1TYW1wbGVzKSBydWxlIG9mIHRodW1iIGZvciBjYWxjdWxhdGluZyB0aGUgbnVtYmVyIG9mIGJ1Y2tldHNcbiAgICAgIGNvbnN0IG51bUJ1Y2tldHM6IG51bWJlciA9IE1hdGgudHJ1bmMoTWF0aC5zcXJ0KHRoaXMudmFsdWVzLmxlbmd0aCkrMSk7XG4gICAgICBjb25zdCBidWNrZXRTaXplOiBudW1iZXIgPSAodGhpcy5tYXgtdGhpcy5taW4pL251bUJ1Y2tldHM7XG5cbiAgICAgIGxldCBjdXJyZW50TWluOiBudW1iZXIgPSBzb3J0ZWRWYWx1ZXNbMF07XG4gICAgICBsZXQgY3VycmVudE1heDogbnVtYmVyID0gY3VycmVudE1pbiArIGJ1Y2tldFNpemU7XG4gICAgICBpZiAoY3VycmVudE1heCA9PT0gdGhpcy5tYXgpIHtcbiAgICAgICAgLy8gVkVSWSB1bmxpa2VseSAtIGJ1dCBqdXN0IGluIGNhc2UsIGFkZCBhIHZlcnkgc21hbGwgYW1vdW50IHNvIGFzIG5vdCB0byBoYXZlIGFcbiAgICAgICAgLy8gYnVja2V0IG9mIG9uZSB3aXRoIG9ubHkgdGhlIG1heCB2YWx1ZSBhdCB0aGUgZW5kLlxuICAgICAgICBjdXJyZW50TWF4ICs9IDFlLTEwO1xuICAgICAgfVxuICAgICAgbGV0IGNvdW50OiBudW1iZXIgPSAwO1xuXG4gICAgICBmb3IgKGxldCBpPTA7IGk8c29ydGVkVmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChzb3J0ZWRWYWx1ZXNbaV0gPj0gY3VycmVudE1pbiAmJiBzb3J0ZWRWYWx1ZXNbaV0gPCBjdXJyZW50TWF4KSB7XG4gICAgICAgICAgY291bnQrKztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmRpc3RyaWJ1dGlvbi5wdXNoKG5ldyBTYW1wbGVCdWNrZXQoY3VycmVudE1pbiwgY3VycmVudE1heCwgY291bnQpKTtcbiAgICAgICAgICBjdXJyZW50TWluICs9IGJ1Y2tldFNpemU7XG4gICAgICAgICAgY3VycmVudE1heCA9IGN1cnJlbnRNaW4rYnVja2V0U2l6ZTtcbiAgICAgICAgICBpZiAoY3VycmVudE1heCA9PT0gdGhpcy5tYXgpIHtcbiAgICAgICAgICAgIC8vIFZFUlkgdW5saWtlbHkgLSBidXQganVzdCBpbiBjYXNlLCBhZGQgYSB2ZXJ5IHNtYWxsIGFtb3VudCBzbyBhcyBub3QgdG8gaGF2ZSBhXG4gICAgICAgICAgICAvLyBidWNrZXQgb2Ygb25lIHdpdGggb25seSB0aGUgbWF4IHZhbHVlIGF0IHRoZSBlbmQuXG4gICAgICAgICAgICBjdXJyZW50TWF4ICs9IDFlLTEwO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb3VudCA9IDE7XG4gICAgICAgIH1cblxuICAgICAgfVxuICAgICAgdGhpcy5kaXN0cmlidXRpb24ucHVzaChuZXcgU2FtcGxlQnVja2V0KGN1cnJlbnRNaW4sIGN1cnJlbnRNYXgsIGNvdW50KSk7XG5cbiAgICAgIC8vIG51bUJ1Y2tldHMgYW5kIGRpc3RyaWJ1dGlvbi5sZW5ndGggc2hvdWxkIG1hdGNoXG4gICAgICB0aGlzLmxvZ2dlcj8udHJhY2UoYFNhbXBsZVNldC5jYWxjRnJvbVNvcnRlZFZhbHVlczogbnVtZXJpYyBkYXRhLCBudW1CdWNrZXRzOiAke251bUJ1Y2tldHN9LCBkaXN0cmlidXRpb24ubGVuZ3RoOiAke3RoaXMuZGlzdHJpYnV0aW9uLmxlbmd0aH1gKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gaW4gdGhpcyBjYXNlLCB0aGUgbnVtYmVyIG9mIGJ1Y2tldHMgbWF0Y2hlcyB0aGUgbnVtYmVyIG9mIHN0cmluZ3MgaW4gdGhlIFNhbXBsZVNldFxuICAgICAgLy8gd2hpY2ggaXMgdGhlIHNpemUgb2YgdGhlIGRpY3Rpb25hcnlcblxuICAgICAgbGV0IGN1cnJlbnRWYWx1ZTogbnVtYmVyID0gc29ydGVkVmFsdWVzWzBdO1xuICAgICAgbGV0IGNvdW50OiBudW1iZXIgPSAwO1xuXG4gICAgICBmb3IgKGxldCBpPTA7IGk8c29ydGVkVmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChzb3J0ZWRWYWx1ZXNbaV0gPT09IGN1cnJlbnRWYWx1ZSkge1xuICAgICAgICAgIGNvdW50Kys7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5kaXN0cmlidXRpb24ucHVzaChuZXcgU2FtcGxlQnVja2V0KGN1cnJlbnRWYWx1ZSwgY3VycmVudFZhbHVlLCBjb3VudCkpO1xuICAgICAgICAgIGN1cnJlbnRWYWx1ZSA9IHNvcnRlZFZhbHVlc1tpXTtcbiAgICAgICAgICBjb3VudCA9IDE7XG4gICAgICAgIH1cblxuICAgICAgfVxuICAgICAgdGhpcy5kaXN0cmlidXRpb24ucHVzaChuZXcgU2FtcGxlQnVja2V0KGN1cnJlbnRWYWx1ZSwgY3VycmVudFZhbHVlLCBjb3VudCkpO1xuXG4gICAgICAvLyBkaWN0aW9uYXJ5Lmxlbmd0aCBhbmQgZGlzdHJpYnV0aW9uLmxlbmd0aCBzaG91bGQgbWF0Y2hcbiAgICAgIHRoaXMubG9nZ2VyPy50cmFjZShgU2FtcGxlU2V0LmNhbGNGcm9tU29ydGVkVmFsdWVzOiBzdHJpbmcgZGF0YSwgZGljdGlvbmFyeS5sZW5ndGg6ICR7dGhpcy5kaWN0aW9uYXJ5Lmxlbmd0aH0sIGRpc3RyaWJ1dGlvbi5sZW5ndGg6ICR7dGhpcy5kaXN0cmlidXRpb24ubGVuZ3RofWApO1xuICAgICAgdGhpcy5sb2dnZXI/LnRyYWNlKGBTYW1wbGVTZXQuY2FsY0Zyb21Tb3J0ZWRWYWx1ZXM6IGRpY3Rpb25hcnk6ICR7dGhpcy5kaWN0aW9uYXJ5fWApO1xuICAgIH1cblxuICAgIHRoaXMubG9nZ2VyPy50cmFjZShgU2FtcGxlU2V0LmNhbGNGcm9tU29ydGVkVmFsdWVzOiBudW1lcmljOiAke3RoaXMudmFsdWVzTnVtZXJpY30sIGRpc3RyaWJ1dGlvbiBkZXRhaWxzOiAke0pTT04uc3RyaW5naWZ5KHRoaXMuZGlzdHJpYnV0aW9uLCBudWxsLCAyKX1gKTtcblxuICAgIC8vIGNhbGN1bGF0ZSB0aGUgbW9kZVxuICAgIGNvbnN0IG1heERpc3RyaWJ1dGlvbkJ1Y2tldEluZGV4ID0gdGhpcy5kaXN0cmlidXRpb24ucmVkdWNlKFxuICAgICAgKGN1ck1heEluZGV4LCBidWNrZXQsIGluZGV4KSA9PiBidWNrZXQuY291bnQgPiB0aGlzLmRpc3RyaWJ1dGlvbltjdXJNYXhJbmRleF0uY291bnQgPyBpbmRleCA6IGN1ck1heEluZGV4LFxuICAgICAgMCxcbiAgICApO1xuICAgIGlmICggdGhpcy52YWx1ZXNOdW1lcmljICkge1xuICAgICAgdGhpcy5tb2RlID0gdGhpcy5kaXN0cmlidXRpb25bbWF4RGlzdHJpYnV0aW9uQnVja2V0SW5kZXhdLm1pbiArXG4gICAgICAgICh0aGlzLmRpc3RyaWJ1dGlvblttYXhEaXN0cmlidXRpb25CdWNrZXRJbmRleF0ubWF4IC0gdGhpcy5kaXN0cmlidXRpb25bbWF4RGlzdHJpYnV0aW9uQnVja2V0SW5kZXhdLm1pbikvMjtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5tb2RlID0gdGhpcy5kaXN0cmlidXRpb25bbWF4RGlzdHJpYnV0aW9uQnVja2V0SW5kZXhdLm1pbjtcbiAgICB9XG5cbiAgICB0aGlzLmxvZ2dlcj8udHJhY2UoYFNhbXBsZVNldC5jYWxjRnJvbVNvcnRlZFZhbHVlczogbW9kZTogJHt0aGlzLm1vZGV9YCk7XG5cbiAgfVxuXG59XG4iXX0=
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ILogger } from '@ncfour-us/logging';
|
|
2
|
+
import { SampleSet } from './sample-set.js';
|
|
3
|
+
/**
|
|
4
|
+
* The options for instantiating a Uniform distribution SampleSet.
|
|
5
|
+
*/
|
|
6
|
+
export interface UniformSampleSetOptions {
|
|
7
|
+
/**
|
|
8
|
+
* number of smaples to generate, default 1000
|
|
9
|
+
*/
|
|
10
|
+
numSamples?: number;
|
|
11
|
+
/**
|
|
12
|
+
* optional minimum value, default 0
|
|
13
|
+
*/
|
|
14
|
+
min?: number;
|
|
15
|
+
/**
|
|
16
|
+
* optional maximum value, default 1
|
|
17
|
+
*/
|
|
18
|
+
max?: number;
|
|
19
|
+
/**
|
|
20
|
+
* optional logger to use.
|
|
21
|
+
*/
|
|
22
|
+
logger?: ILogger;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Class to create a Uniform distribution SampleSet
|
|
26
|
+
* with values in the range [0,1).
|
|
27
|
+
*/
|
|
28
|
+
export declare class UniformSampleSet extends SampleSet {
|
|
29
|
+
/**
|
|
30
|
+
* Create a new UniformSampleSet instance.
|
|
31
|
+
*
|
|
32
|
+
* @param options See {@link UniformSampleSetOptions}
|
|
33
|
+
*/
|
|
34
|
+
constructor(options: UniformSampleSetOptions);
|
|
35
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Copyright (c) 2026 Tim Hahn
|
|
2
|
+
import { SampleSet } from './sample-set.js';
|
|
3
|
+
;
|
|
4
|
+
/**
|
|
5
|
+
* Class to create a Uniform distribution SampleSet
|
|
6
|
+
* with values in the range [0,1).
|
|
7
|
+
*/
|
|
8
|
+
export class UniformSampleSet extends SampleSet {
|
|
9
|
+
/**
|
|
10
|
+
* Create a new UniformSampleSet instance.
|
|
11
|
+
*
|
|
12
|
+
* @param options See {@link UniformSampleSetOptions}
|
|
13
|
+
*/
|
|
14
|
+
constructor(options) {
|
|
15
|
+
super({
|
|
16
|
+
logger: options.logger,
|
|
17
|
+
});
|
|
18
|
+
this.addValues(Array.from({ length: options.numSamples ?? 1000 }, (_element, _index) => {
|
|
19
|
+
const min = options.min ?? 0;
|
|
20
|
+
const max = options.max ?? 1;
|
|
21
|
+
const newVal = min + (max - min) * Math.random();
|
|
22
|
+
return newVal;
|
|
23
|
+
}));
|
|
24
|
+
this.logger?.trace(`UniformSampleSet.constructor: numSamples: ${this.getNumSamples()}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5pZm9ybS1zYW1wbGUtc2V0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbXBvbmVudHMvdW5pZm9ybS1zYW1wbGUtc2V0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhCQUE4QjtBQUc5QixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUEyQjNDLENBQUM7QUFFRjs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sZ0JBQWlCLFNBQVEsU0FBUztJQUU3Qzs7OztPQUlHO0lBQ0gsWUFBWSxPQUFnQztRQUUxQyxLQUFLLENBQUM7WUFDSixNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07U0FDdkIsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxVQUFVLElBQUksSUFBSSxFQUFFLEVBQUUsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDckYsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUM7WUFDN0IsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUM7WUFFN0IsTUFBTSxNQUFNLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFDLEdBQUcsQ0FBQyxHQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUU3QyxPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRUosSUFBSSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsNkNBQTZDLElBQUksQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFFMUYsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSAyMDI2IFRpbSBIYWhuXG5cbmltcG9ydCB7IElMb2dnZXIgfSBmcm9tICdAbmNmb3VyLXVzL2xvZ2dpbmcnO1xuaW1wb3J0IHsgU2FtcGxlU2V0IH0gZnJvbSAnLi9zYW1wbGUtc2V0LmpzJztcblxuLyoqXG4gKiBUaGUgb3B0aW9ucyBmb3IgaW5zdGFudGlhdGluZyBhIFVuaWZvcm0gZGlzdHJpYnV0aW9uIFNhbXBsZVNldC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBVbmlmb3JtU2FtcGxlU2V0T3B0aW9ucyB7XG5cbiAgLyoqXG4gICAqIG51bWJlciBvZiBzbWFwbGVzIHRvIGdlbmVyYXRlLCBkZWZhdWx0IDEwMDBcbiAgICovXG4gIG51bVNhbXBsZXM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIG9wdGlvbmFsIG1pbmltdW0gdmFsdWUsIGRlZmF1bHQgMFxuICAgKi9cbiAgbWluPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBvcHRpb25hbCBtYXhpbXVtIHZhbHVlLCBkZWZhdWx0IDFcbiAgICovXG4gIG1heD86IG51bWJlcjtcblxuICAvLyBkZXBlbmRlbmNpZXNcbiAgLyoqXG4gICAqIG9wdGlvbmFsIGxvZ2dlciB0byB1c2UuXG4gICAqL1xuICBsb2dnZXI/OiBJTG9nZ2VyO1xufTtcblxuLyoqXG4gKiBDbGFzcyB0byBjcmVhdGUgYSBVbmlmb3JtIGRpc3RyaWJ1dGlvbiBTYW1wbGVTZXRcbiAqIHdpdGggdmFsdWVzIGluIHRoZSByYW5nZSBbMCwxKS5cbiAqL1xuZXhwb3J0IGNsYXNzIFVuaWZvcm1TYW1wbGVTZXQgZXh0ZW5kcyBTYW1wbGVTZXQge1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgVW5pZm9ybVNhbXBsZVNldCBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIG9wdGlvbnMgU2VlIHtAbGluayBVbmlmb3JtU2FtcGxlU2V0T3B0aW9uc31cbiAgICovXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFVuaWZvcm1TYW1wbGVTZXRPcHRpb25zKSB7XG5cbiAgICBzdXBlcih7XG4gICAgICBsb2dnZXI6IG9wdGlvbnMubG9nZ2VyLFxuICAgIH0pO1xuXG4gICAgdGhpcy5hZGRWYWx1ZXMoQXJyYXkuZnJvbSh7IGxlbmd0aDogb3B0aW9ucy5udW1TYW1wbGVzID8/IDEwMDAgfSwgKF9lbGVtZW50LCBfaW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IG1pbiA9IG9wdGlvbnMubWluID8/IDA7XG4gICAgICBjb25zdCBtYXggPSBvcHRpb25zLm1heCA/PyAxO1xuXG4gICAgICBjb25zdCBuZXdWYWwgPSBtaW4gKyAobWF4LW1pbikqTWF0aC5yYW5kb20oKTtcblxuICAgICAgcmV0dXJuIG5ld1ZhbDtcbiAgICB9KSk7XG5cbiAgICB0aGlzLmxvZ2dlcj8udHJhY2UoYFVuaWZvcm1TYW1wbGVTZXQuY29uc3RydWN0b3I6IG51bVNhbXBsZXM6ICR7dGhpcy5nZXROdW1TYW1wbGVzKCl9YCk7XG5cbiAgfVxufVxuIl19
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { NormalSampleSet, NormalSampleSetOptions } from './components/normal-sample-set.js';
|
|
2
|
+
import { SampleBucket, SampleSet, SampleSetValue, SampleSetPercentiles, SampleSetOptions } from './components/sample-set.js';
|
|
3
|
+
import { UniformSampleSet, UniformSampleSetOptions } from './components/uniform-sample-set.js';
|
|
4
|
+
export type { SampleSetValue, SampleSetOptions, SampleSetPercentiles, UniformSampleSetOptions, NormalSampleSetOptions };
|
|
5
|
+
export { SampleBucket, SampleSet, UniformSampleSet, NormalSampleSet };
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Copyright (c) 2026 Tim Hahn
|
|
2
|
+
import { NormalSampleSet } from './components/normal-sample-set.js';
|
|
3
|
+
import { SampleBucket, SampleSet } from './components/sample-set.js';
|
|
4
|
+
import { UniformSampleSet } from './components/uniform-sample-set.js';
|
|
5
|
+
export { SampleBucket, SampleSet, UniformSampleSet, NormalSampleSet };
|
|
6
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsOEJBQThCO0FBRTlCLE9BQU8sRUFBRSxlQUFlLEVBQTBCLE1BQU0sbUNBQW1DLENBQUM7QUFDNUYsT0FBTyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQTBELE1BQU0sNEJBQTRCLENBQUM7QUFDN0gsT0FBTyxFQUFFLGdCQUFnQixFQUEyQixNQUFNLG9DQUFvQyxDQUFDO0FBSS9GLE9BQU8sRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFLGVBQWUsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSAyMDI2IFRpbSBIYWhuXG5cbmltcG9ydCB7IE5vcm1hbFNhbXBsZVNldCwgTm9ybWFsU2FtcGxlU2V0T3B0aW9ucyB9IGZyb20gJy4vY29tcG9uZW50cy9ub3JtYWwtc2FtcGxlLXNldC5qcyc7XG5pbXBvcnQgeyBTYW1wbGVCdWNrZXQsIFNhbXBsZVNldCwgU2FtcGxlU2V0VmFsdWUsIFNhbXBsZVNldFBlcmNlbnRpbGVzLCBTYW1wbGVTZXRPcHRpb25zIH0gZnJvbSAnLi9jb21wb25lbnRzL3NhbXBsZS1zZXQuanMnO1xuaW1wb3J0IHsgVW5pZm9ybVNhbXBsZVNldCwgVW5pZm9ybVNhbXBsZVNldE9wdGlvbnMgfSBmcm9tICcuL2NvbXBvbmVudHMvdW5pZm9ybS1zYW1wbGUtc2V0LmpzJztcblxuZXhwb3J0IHR5cGUgeyBTYW1wbGVTZXRWYWx1ZSwgU2FtcGxlU2V0T3B0aW9ucywgU2FtcGxlU2V0UGVyY2VudGlsZXMsIFVuaWZvcm1TYW1wbGVTZXRPcHRpb25zLCBOb3JtYWxTYW1wbGVTZXRPcHRpb25zIH07XG5cbmV4cG9ydCB7IFNhbXBsZUJ1Y2tldCwgU2FtcGxlU2V0LCBVbmlmb3JtU2FtcGxlU2V0LCBOb3JtYWxTYW1wbGVTZXQgfTtcbiJdfQ==
|
package/package.json
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ncfour-us/stats",
|
|
3
|
+
"description": "A set of basic statistics classes and utility functions",
|
|
4
|
+
"author": {
|
|
5
|
+
"name": "Tim Hahn",
|
|
6
|
+
"email": "hahntj@gmail.com",
|
|
7
|
+
"organization": false
|
|
8
|
+
},
|
|
9
|
+
"devDependencies": {
|
|
10
|
+
"@eslint/compat": "^2.1.1",
|
|
11
|
+
"@eslint/eslintrc": "^3.3.7",
|
|
12
|
+
"@eslint/js": "^9.39.5",
|
|
13
|
+
"@jest/globals": "^30.5.1",
|
|
14
|
+
"@ncfour-us/projen-utils": "^0.3.5",
|
|
15
|
+
"@stylistic/eslint-plugin": "^2",
|
|
16
|
+
"@types/jest": "^30.0.0",
|
|
17
|
+
"@types/node": "^24",
|
|
18
|
+
"@typescript-eslint/eslint-plugin": "^8",
|
|
19
|
+
"@typescript-eslint/parser": "^8",
|
|
20
|
+
"commit-and-tag-version": "^12",
|
|
21
|
+
"constructs": "^10.0.0",
|
|
22
|
+
"eslint": "^9",
|
|
23
|
+
"eslint-import-resolver-typescript": "^4.4.5",
|
|
24
|
+
"eslint-plugin-import": "^2.32.0",
|
|
25
|
+
"globals": "^14.0.0",
|
|
26
|
+
"jest": "^30.5.1",
|
|
27
|
+
"jest-junit": "^17",
|
|
28
|
+
"jiti": "^2.7.0",
|
|
29
|
+
"prettier": "^3.9.6",
|
|
30
|
+
"projen": "^0.103.23",
|
|
31
|
+
"ts-jest": "^29.4.12",
|
|
32
|
+
"ts-node": "^10.9.2",
|
|
33
|
+
"tsx": "^4.23.13",
|
|
34
|
+
"typedoc": "^0.28.20",
|
|
35
|
+
"typedoc-plugin-markdown": "^4.13.0",
|
|
36
|
+
"typescript": "^6.0.3"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@ncfour-us/logging": "^0.1.0"
|
|
40
|
+
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">= 24.0.0"
|
|
43
|
+
},
|
|
44
|
+
"devEngines": {
|
|
45
|
+
"packageManager": {
|
|
46
|
+
"name": "pnpm",
|
|
47
|
+
"version": ">=10",
|
|
48
|
+
"onFail": "ignore"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"main": "lib/index.js",
|
|
52
|
+
"license": "MIT",
|
|
53
|
+
"version": "0.0.0",
|
|
54
|
+
"jest": {
|
|
55
|
+
"coverageProvider": "v8",
|
|
56
|
+
"testMatch": [
|
|
57
|
+
"<rootDir>/@(src|test)/**/*(*.)@(spec|test).ts?(x)",
|
|
58
|
+
"<rootDir>/@(src|test)/**/__tests__/**/*.ts?(x)",
|
|
59
|
+
"<rootDir>/@(projenrc)/**/*(*.)@(spec|test).ts?(x)",
|
|
60
|
+
"<rootDir>/@(projenrc)/**/__tests__/**/*.ts?(x)"
|
|
61
|
+
],
|
|
62
|
+
"clearMocks": true,
|
|
63
|
+
"collectCoverage": true,
|
|
64
|
+
"coverageReporters": [
|
|
65
|
+
"json",
|
|
66
|
+
"lcov",
|
|
67
|
+
"clover",
|
|
68
|
+
"cobertura",
|
|
69
|
+
"text"
|
|
70
|
+
],
|
|
71
|
+
"coverageDirectory": "coverage",
|
|
72
|
+
"coveragePathIgnorePatterns": [
|
|
73
|
+
"/node_modules/"
|
|
74
|
+
],
|
|
75
|
+
"testPathIgnorePatterns": [
|
|
76
|
+
"/node_modules/"
|
|
77
|
+
],
|
|
78
|
+
"watchPathIgnorePatterns": [
|
|
79
|
+
"/node_modules/"
|
|
80
|
+
],
|
|
81
|
+
"reporters": [
|
|
82
|
+
"default",
|
|
83
|
+
[
|
|
84
|
+
"jest-junit",
|
|
85
|
+
{
|
|
86
|
+
"outputDirectory": "test-reports"
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
],
|
|
90
|
+
"transform": {
|
|
91
|
+
"^.+\\.(mt|t|cj|j)s$": [
|
|
92
|
+
"ts-jest",
|
|
93
|
+
{
|
|
94
|
+
"useESM": true,
|
|
95
|
+
"tsconfig": "test/tsconfig.json"
|
|
96
|
+
}
|
|
97
|
+
]
|
|
98
|
+
},
|
|
99
|
+
"extensionsToTreatAsEsm": [
|
|
100
|
+
".ts"
|
|
101
|
+
],
|
|
102
|
+
"moduleNameMapper": {
|
|
103
|
+
"^(\\.{1,2}/.*)\\.js$": "$1"
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
"types": "lib/index.d.ts",
|
|
107
|
+
"type": "module",
|
|
108
|
+
"exports": {
|
|
109
|
+
".": "./lib/index.js"
|
|
110
|
+
},
|
|
111
|
+
"//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"pnpm exec projen\".",
|
|
112
|
+
"scripts": {
|
|
113
|
+
"build": "projen build",
|
|
114
|
+
"build:tag": "projen build:tag",
|
|
115
|
+
"build:tag:env": "projen build:tag:env",
|
|
116
|
+
"bump": "projen bump",
|
|
117
|
+
"bump:releasable-commits": "projen bump:releasable-commits",
|
|
118
|
+
"clobber": "projen clobber",
|
|
119
|
+
"compile": "projen compile",
|
|
120
|
+
"compile:examples": "projen compile:examples",
|
|
121
|
+
"default": "projen default",
|
|
122
|
+
"eject": "projen eject",
|
|
123
|
+
"eslint": "projen eslint",
|
|
124
|
+
"package": "projen package",
|
|
125
|
+
"post-compile": "projen post-compile",
|
|
126
|
+
"post-upgrade": "projen post-upgrade",
|
|
127
|
+
"pre-compile": "projen pre-compile",
|
|
128
|
+
"publish:git": "projen publish:git",
|
|
129
|
+
"publish:local": "projen publish:local",
|
|
130
|
+
"release": "projen release",
|
|
131
|
+
"test": "projen test",
|
|
132
|
+
"test:watch": "projen test:watch",
|
|
133
|
+
"unbump": "projen unbump",
|
|
134
|
+
"upgrade": "projen upgrade",
|
|
135
|
+
"watch": "projen watch",
|
|
136
|
+
"projen": "projen",
|
|
137
|
+
"build:docs": "pnpm typedoc"
|
|
138
|
+
}
|
|
139
|
+
}
|