@dra2020/district-analytics 1.0.7 → 1.0.8
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/README.md +5 -5
- package/dist/district-analytics.js +1315 -1205
- package/package.json +6 -3
- package/.prettierrc +0 -5
- package/dist/_api.d.ts +0 -27
- package/dist/_data.d.ts +0 -130
- package/dist/analyze.d.ts +0 -4
- package/dist/cli.js +0 -12091
- package/dist/cli.js.map +0 -1
- package/dist/cohesive.d.ts +0 -4
- package/dist/compact.d.ts +0 -5
- package/dist/constants.d.ts +0 -6
- package/dist/district-analytics.js.map +0 -1
- package/dist/equal.d.ts +0 -4
- package/dist/geofeature.d.ts +0 -3
- package/dist/index.d.ts +0 -2
- package/dist/minority.d.ts +0 -3
- package/dist/political.d.ts +0 -8
- package/dist/preprocess.d.ts +0 -2
- package/dist/report.d.ts +0 -15
- package/dist/settings.d.ts +0 -5
- package/dist/src/_api.d.ts +0 -27
- package/dist/src/_data.d.ts +0 -130
- package/dist/src/analyze.d.ts +0 -4
- package/dist/src/cohesive.d.ts +0 -4
- package/dist/src/compact.d.ts +0 -5
- package/dist/src/constants.d.ts +0 -6
- package/dist/src/equal.d.ts +0 -4
- package/dist/src/geofeature.d.ts +0 -3
- package/dist/src/index.d.ts +0 -2
- package/dist/src/minority.d.ts +0 -3
- package/dist/src/political.d.ts +0 -8
- package/dist/src/preprocess.d.ts +0 -2
- package/dist/src/report.d.ts +0 -15
- package/dist/src/settings.d.ts +0 -5
- package/dist/src/types.d.ts +0 -110
- package/dist/src/utils.d.ts +0 -28
- package/dist/src/valid.d.ts +0 -8
- package/dist/test/_cli.d.ts +0 -5
- package/dist/types.d.ts +0 -110
- package/dist/utils.d.ts +0 -28
- package/dist/valid.d.ts +0 -8
- package/jestconfig.json +0 -14
- package/lib/HelloWorld.d.ts +0 -3
- package/lib/HelloWorld.js +0 -11
- package/lib/_api.js +0 -91
- package/lib/_api.js.map +0 -1
- package/lib/_cli.js +0 -434
- package/lib/_cli.js.map +0 -1
- package/lib/_data.js +0 -425
- package/lib/_data.js.map +0 -1
- package/lib/analyze.d.ts +0 -3
- package/lib/analyze.js +0 -69
- package/lib/analyze.js.map +0 -1
- package/lib/api.d.ts +0 -34
- package/lib/api.js +0 -117
- package/lib/api.js.map +0 -1
- package/lib/cli.d.ts +0 -1
- package/lib/cli.js +0 -386
- package/lib/cli.js.map +0 -1
- package/lib/cohesive.d.ts +0 -4
- package/lib/cohesive.js +0 -132
- package/lib/cohesive.js.map +0 -1
- package/lib/compact.d.ts +0 -4
- package/lib/compact.js +0 -183
- package/lib/compact.js.map +0 -1
- package/lib/constants.js +0 -367
- package/lib/constants.js.map +0 -1
- package/lib/data.js +0 -188
- package/lib/data.js.map +0 -1
- package/lib/equal.d.ts +0 -4
- package/lib/equal.js +0 -59
- package/lib/equal.js.map +0 -1
- package/lib/features.js +0 -19
- package/lib/features.js.map +0 -1
- package/lib/geofeature.js +0 -112
- package/lib/geofeature.js.map +0 -1
- package/lib/index.d.ts +0 -5
- package/lib/index.js +0 -11
- package/lib/index.js.map +0 -1
- package/lib/minority.d.ts +0 -3
- package/lib/minority.js +0 -61
- package/lib/minority.js.map +0 -1
- package/lib/political.d.ts +0 -7
- package/lib/political.js +0 -88
- package/lib/political.js.map +0 -1
- package/lib/preprocess.d.ts +0 -4
- package/lib/preprocess.js +0 -101
- package/lib/preprocess.js.map +0 -1
- package/lib/report.d.ts +0 -14
- package/lib/report.js +0 -817
- package/lib/report.js.map +0 -1
- package/lib/sample.d.ts +0 -1
- package/lib/sample.js +0 -32
- package/lib/sample.js.map +0 -1
- package/lib/scorecard.d.ts +0 -4
- package/lib/scorecard.js +0 -237
- package/lib/scorecard.js.map +0 -1
- package/lib/settings.d.ts +0 -5
- package/lib/settings.js +0 -18
- package/lib/settings.js.map +0 -1
- package/lib/types.d.ts +0 -125
- package/lib/types.js +0 -7
- package/lib/types.js.map +0 -1
- package/lib/utils.d.ts +0 -20
- package/lib/utils.js +0 -223
- package/lib/utils.js.map +0 -1
- package/lib/valid.d.ts +0 -5
- package/lib/valid.js +0 -230
- package/lib/valid.js.map +0 -1
- package/main.js +0 -4
- package/src/_api.ts +0 -121
- package/src/_data.ts +0 -595
- package/src/analyze.ts +0 -92
- package/src/cohesive.ts +0 -156
- package/src/compact.ts +0 -208
- package/src/constants.ts +0 -371
- package/src/equal.ts +0 -75
- package/src/geofeature.ts +0 -138
- package/src/index.ts +0 -6
- package/src/minority.ts +0 -70
- package/src/political.ts +0 -114
- package/src/preprocess.ts +0 -132
- package/src/report.ts +0 -1022
- package/src/settings.ts +0 -20
- package/src/types.ts +0 -185
- package/src/utils.ts +0 -245
- package/src/valid.ts +0 -275
- package/tsconfig.json +0 -25
- package/tslint.json +0 -3
- package/types/polygon-clipping/index.d.ts +0 -1
- package/webpack.config.js +0 -73
package/src/settings.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// GLOBAL CONSTANTS
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
// Keep four decimal places for fractions [0–1], i.e.,
|
|
6
|
-
// keep two decimal places for %'s [0–100].
|
|
7
|
-
export const PRECISION: number = 4;
|
|
8
|
-
|
|
9
|
-
// Normalized scores [0-100]
|
|
10
|
-
export const NORMALIZED_RANGE: number = 100;
|
|
11
|
-
|
|
12
|
-
// The dummy district ID for features not assigned districts yet
|
|
13
|
-
export const NOT_ASSIGNED: number = 0;
|
|
14
|
-
|
|
15
|
-
// TODO - Discuss w/ Dave & Terry
|
|
16
|
-
// # of items to report as problematic (e.g., features, districts, etc.)
|
|
17
|
-
export const NUMBER_OF_ITEMS_TO_REPORT: number = 10;
|
|
18
|
-
|
|
19
|
-
// The virtual geoID for "neighbors" in other states
|
|
20
|
-
export const OUT_OF_STATE: string = "OUT_OF_STATE";
|
package/src/types.ts
DELETED
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// TYPE DEFINITIONS
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import * as geojson from 'geojson';
|
|
6
|
-
|
|
7
|
-
// CONFIGURATION TYPES
|
|
8
|
-
|
|
9
|
-
// Sets of analytics, to enable them to be turned on/off by the host.
|
|
10
|
-
export const enum Suite {
|
|
11
|
-
Legal,
|
|
12
|
-
Fair,
|
|
13
|
-
Best
|
|
14
|
-
} // as in "best fair map"
|
|
15
|
-
|
|
16
|
-
// INPUT DATA TYPES
|
|
17
|
-
|
|
18
|
-
// The SessionRequest specifies an analytics session
|
|
19
|
-
export type SessionRequest = {
|
|
20
|
-
title: string;
|
|
21
|
-
stateXX: string;
|
|
22
|
-
nDistricts: number;
|
|
23
|
-
legislativeDistricts: boolean;
|
|
24
|
-
plan: PlanByGeoID;
|
|
25
|
-
data: GeoFeatureCollection;
|
|
26
|
-
districtShapes: GeoFeatureCollection;
|
|
27
|
-
districtProperties: DistrictProperties;
|
|
28
|
-
graph: ContiguityGraph;
|
|
29
|
-
countyNameLookup: FIPSCodeToCountyNameMap;
|
|
30
|
-
counties: GeoFeatureCollection;
|
|
31
|
-
config: {}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// A Plan is a dict of geoID-districtID pairs indexed by geoID
|
|
35
|
-
export type PlanByGeoID = {
|
|
36
|
-
[geoID: string]: number;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// A inverted Plan is a dict of districtID's with associated sets of geoID's
|
|
40
|
-
export type PlanByDistrictID = {
|
|
41
|
-
// TODO - Terry, why does this constructor need a <T> type specification?
|
|
42
|
-
[districtID: number]: Set<string>;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// A map of geoIDs to feature IDs
|
|
46
|
-
export type FeaturesByGeoID = {
|
|
47
|
-
[geoID: string]: number;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// The FIPS-codes-to-county-name map for a state
|
|
51
|
-
export type FIPSCodeToCountyNameMap = {
|
|
52
|
-
[FIPSCode: string]: string;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// The FIPS to array ordinal map
|
|
56
|
-
export type FIPSToOrdinalMap = {
|
|
57
|
-
[FIPSCode: string]: number;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Shapes - following the declarations in dra-client/redistrictdata.ts
|
|
61
|
-
export type GeoFeature = geojson.Feature;
|
|
62
|
-
export type GeoFeatureArray = GeoFeature[];
|
|
63
|
-
export type GeoFeatureCollection = geojson.FeatureCollection;
|
|
64
|
-
export interface GeoFeatureMap {
|
|
65
|
-
[geoID: string]: GeoFeature;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
// Contiguity graph
|
|
70
|
-
// - For each geoID, there's a dictionary of neighbors, and the value for each
|
|
71
|
-
// neighbor geoID key is the "weight" of that connection.
|
|
72
|
-
// - A simple connectivity matrix used a weight of 1.0. However, the "weight"
|
|
73
|
-
// can be overloaded with some other information, like the length of the shared
|
|
74
|
-
// border.
|
|
75
|
-
export type ContiguityGraph = {
|
|
76
|
-
[geoID: string]: Neighbors;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export type Neighbors = {
|
|
80
|
-
[geoID: string]: number;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// An election (model) captures three actual or composite vote totals:
|
|
84
|
-
// DEM votes, REP votes, and TOTal votes, where DEM + REP <= TOT, because
|
|
85
|
-
// of third-party candidates and write-in votes. IOW, the two-party vote is
|
|
86
|
-
// DEM + REP.
|
|
87
|
-
export type VoteTriple = [number, number, number];
|
|
88
|
-
|
|
89
|
-
// An index for accessing a vote triple
|
|
90
|
-
export const enum VoteType {
|
|
91
|
-
Democratic,
|
|
92
|
-
Republican,
|
|
93
|
-
Total
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// CONFIGURATION TYPES
|
|
97
|
-
|
|
98
|
-
// Scale config values for an individual test
|
|
99
|
-
export type TestScale = {
|
|
100
|
-
testScale: Array<number>,
|
|
101
|
-
testInvertp: boolean
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// The scales for all the analytics & validations
|
|
105
|
-
// Presently assigned as part of session initialization
|
|
106
|
-
// Use the Tests enum below as the test index
|
|
107
|
-
export type TestScales = {
|
|
108
|
-
[test: number]: TestScale;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
// RETURN TYPES
|
|
113
|
-
|
|
114
|
-
export type TestEntry = {
|
|
115
|
-
score?: number | boolean; // Specific to the test
|
|
116
|
-
details: Dict; // Additional details
|
|
117
|
-
normalizedScore?: number; // Normalized to [0–100] for graded tests
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// District WIP captures a district-level result, indexed by districtID
|
|
121
|
-
export type DistrictWIP = {
|
|
122
|
-
[districtID: number]: any;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// TODO - Revise this ...
|
|
126
|
-
// Analytics & validations
|
|
127
|
-
export const enum Test {
|
|
128
|
-
Complete,
|
|
129
|
-
Contiguous,
|
|
130
|
-
FreeOfHoles,
|
|
131
|
-
EqualPopulation, // This is the legal/not legal assessment of the population
|
|
132
|
-
PopulationDeviation, // deviation % (when legal, less is still better).
|
|
133
|
-
Reock,
|
|
134
|
-
PolsbyPopper,
|
|
135
|
-
CountySplits,
|
|
136
|
-
Complexity,
|
|
137
|
-
SeatsBias,
|
|
138
|
-
VotesBias,
|
|
139
|
-
Responsiveness,
|
|
140
|
-
ResponsiveDistricts,
|
|
141
|
-
EfficiencyGap,
|
|
142
|
-
MajorityMinorityDistricts
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// The analytics & validation entries for a plan
|
|
146
|
-
// Use the Tests enum above as the test index
|
|
147
|
-
export type TestEntries = {
|
|
148
|
-
[test: number]: TestEntry;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// DistrictProperties holds properties of district shapes, indexed by districtID
|
|
152
|
-
export type DistrictProperties = {
|
|
153
|
-
[districtID: number]: any;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// For compactness calculations, we need 3 properties of each district shape:
|
|
157
|
-
export type DistrictShapeProperties = [number, number, number];
|
|
158
|
-
|
|
159
|
-
// An index for accessing properties extracted from a district shape
|
|
160
|
-
export const enum DistrictShapeProperty {
|
|
161
|
-
Area,
|
|
162
|
-
Diameter,
|
|
163
|
-
Perimeter
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// HELPER TYPES
|
|
167
|
-
|
|
168
|
-
export type GeoIDParts = {
|
|
169
|
-
state?: string;
|
|
170
|
-
county?: string;
|
|
171
|
-
tract?: string;
|
|
172
|
-
bg?: string;
|
|
173
|
-
block?: string;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
export type GeoIDTotal = {
|
|
177
|
-
[geoID: string]: number;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// GENERIC TYPES
|
|
181
|
-
|
|
182
|
-
export type Dict = { [key: string]: any };
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
// END
|
package/src/utils.ts
DELETED
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// UTILITIES
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import * as T from './types'
|
|
6
|
-
import * as S from './settings';
|
|
7
|
-
|
|
8
|
-
// PLAN HELPERS
|
|
9
|
-
|
|
10
|
-
// Is a "neighbor" in state?
|
|
11
|
-
export function isInState(geoID: string): boolean {
|
|
12
|
-
return geoID != S.OUT_OF_STATE;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// Is a "neighbor" out of state?
|
|
16
|
-
export function isOutOfState(geoID: string): boolean {
|
|
17
|
-
return geoID == S.OUT_OF_STATE;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// Get the districtID to which a geoID is assigned
|
|
21
|
-
export function getDistrict(plan: T.PlanByGeoID, geoID: string): number | undefined {
|
|
22
|
-
// All geoIDs in a state *should be* assigned to a district (including the
|
|
23
|
-
// dummy "unassigned" district), but "water-only" features are sometimes missing
|
|
24
|
-
// from a map. This is also a guard against a bug in which a geoID has no district.
|
|
25
|
-
if (keyExists(geoID, plan)) {
|
|
26
|
-
return plan[geoID];
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
return undefined;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Invert a feature assignment structure to sets of ids by district
|
|
34
|
-
// NOTE - This is here vs. _data.ts, so it can also be used in cli.ts
|
|
35
|
-
export function invertPlan(plan: T.PlanByGeoID): T.PlanByDistrictID {
|
|
36
|
-
let invertedPlan = {} as T.PlanByDistrictID;
|
|
37
|
-
|
|
38
|
-
// Add a dummy 'unassigned' district
|
|
39
|
-
invertedPlan[S.NOT_ASSIGNED] = new Set();
|
|
40
|
-
|
|
41
|
-
for (let geoID in plan) {
|
|
42
|
-
let districtID = plan[geoID];
|
|
43
|
-
|
|
44
|
-
// Make sure the set for the districtID exists
|
|
45
|
-
if (!(objectContains(invertedPlan, districtID))) {
|
|
46
|
-
invertedPlan[districtID] = new Set();
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Add the geoID to the districtID's set
|
|
50
|
-
invertedPlan[districtID].add(geoID);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return invertedPlan;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// WORKING WITH GEOIDS
|
|
57
|
-
|
|
58
|
-
export function parseGeoID(geoID: string): T.GeoIDParts {
|
|
59
|
-
let parts: T.GeoIDParts = {};
|
|
60
|
-
|
|
61
|
-
parts['state'] = geoID.substring(0, 2);
|
|
62
|
-
parts['county'] = geoID.substring(0, 5);
|
|
63
|
-
|
|
64
|
-
let l: number = geoID.length;
|
|
65
|
-
|
|
66
|
-
if (l >= 11) {
|
|
67
|
-
parts['tract'] = geoID.substring(0, 11);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (l >= 12) {
|
|
71
|
-
parts['bg'] = geoID.substring(0, 12);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (l == 15) {
|
|
75
|
-
parts['block'] = geoID;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return parts;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export function getFIPSFromCountyGeoID(geoID: string): string {
|
|
82
|
-
return geoID.substring(2, 5);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
// NORMALIZING RESULTS
|
|
87
|
-
|
|
88
|
-
// Convert a raw score [0-1] into a normalized score [0-100]
|
|
89
|
-
export function normalize(rawScore: number, scale: Array<number>, invertp: boolean = false): number {
|
|
90
|
-
// Invert the axis if necessary to make bigger = better
|
|
91
|
-
if (invertp) {
|
|
92
|
-
rawScore = 1.0 - rawScore;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Coerce the value to be w/in the given range
|
|
96
|
-
let rangeMin: number = scale[0];
|
|
97
|
-
let rangeMax: number = scale[1];
|
|
98
|
-
let coercedValue = Math.min(Math.max(rawScore, rangeMin), rangeMax);
|
|
99
|
-
|
|
100
|
-
// Scale the bounded value w/in the range [0 - (rangeMax - rangeMin)]
|
|
101
|
-
let scaledValue = (coercedValue - rangeMin) / (rangeMax - rangeMin);
|
|
102
|
-
|
|
103
|
-
// Finally, make the range [0-100]
|
|
104
|
-
return Math.round(scaledValue * S.NORMALIZED_RANGE);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// Round a fractional number [0-1] to the desired level of PRECISION.
|
|
108
|
-
export function trim(fullFraction: number): number {
|
|
109
|
-
let shiftPlaces = 10 ** S.PRECISION;
|
|
110
|
-
|
|
111
|
-
return Math.round(fullFraction * shiftPlaces) / shiftPlaces;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// ARRAY HELPERS
|
|
115
|
-
|
|
116
|
-
export function sumArray(arr: number[]): number {
|
|
117
|
-
return arr.reduce((a, b) => a + b, 0);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export function avgArray(arr: number[]): number {
|
|
121
|
-
return (arr.reduce((a, b) => a + b, 0)) / arr.length;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export function minArray(arr: number[]): number {
|
|
125
|
-
return Math.min(...arr);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export function maxArray(arr: number[]): number {
|
|
129
|
-
return Math.max(...arr);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
export function initArray(n: number, value: any): any[] {
|
|
133
|
-
return Array.from(Array(n), () => value);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
export function andArray(arr: boolean[]): boolean {
|
|
137
|
-
return arr.reduce(function (a, b) { return a && b; }, true);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// WORKING WITH OBJECT KEYS/PROPERTIES
|
|
141
|
-
|
|
142
|
-
// TODO - Terry, is this copesetic?
|
|
143
|
-
// Does an object have a key/property?
|
|
144
|
-
export function keyExists(k: string, o: object): boolean {
|
|
145
|
-
return k in o;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// TODO - Terry, can these three be combined into a generic isEmpty() check?
|
|
149
|
-
// Does an object (dict) have any keys/properties?
|
|
150
|
-
export function isObjectEmpty(o: object): boolean {
|
|
151
|
-
return Object.keys(o).length === 0
|
|
152
|
-
}
|
|
153
|
-
// Does a Set have any members?
|
|
154
|
-
export function isSetEmpty(s: any): boolean {
|
|
155
|
-
return s.size === 0
|
|
156
|
-
}
|
|
157
|
-
// Does an array hold any items?
|
|
158
|
-
export function isArrayEmpty(a: any[]): boolean {
|
|
159
|
-
if (a === undefined || a.length == 0) {
|
|
160
|
-
// array empty or does not exist
|
|
161
|
-
return true;
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
return false;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// Get the keys for an object
|
|
169
|
-
export function getObjectKeys(o: object): string[] {
|
|
170
|
-
return Object.keys(o);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// TODO - Convert getNumericObjectKeys() idiom to for..of where possible
|
|
174
|
-
export function getNumericObjectKeys(o: object): number[] {
|
|
175
|
-
return Object.keys(o).map(Number);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
export function getSelectObjectKeys(o: T.Dict, v: any[]): string[] {
|
|
179
|
-
let selectKeys: string[] = [];
|
|
180
|
-
|
|
181
|
-
Object.keys(o).forEach(key => {
|
|
182
|
-
if (arrayContains(v, o[key])) {
|
|
183
|
-
selectKeys.push(key);
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
return selectKeys;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
export function arrayContains(a: any[], item: any): boolean {
|
|
191
|
-
return a.some(x => x === item);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
export function objectContains(o: object, key: any): boolean {
|
|
195
|
-
return (key in o);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
// ENUM HELPERS
|
|
200
|
-
|
|
201
|
-
// Source: https://stackoverflow.com/questions/38034673/determine-the-number-of-enum-elements-typescript
|
|
202
|
-
export function countEnumValues(enumName: any): number {
|
|
203
|
-
let count = 0
|
|
204
|
-
for (let item in enumName) {
|
|
205
|
-
if (isNaN(Number(item))) count++
|
|
206
|
-
}
|
|
207
|
-
return count
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// COPYING - Copied from dra-client/util.ts
|
|
211
|
-
|
|
212
|
-
export function shallowCopy(src: any): any {
|
|
213
|
-
if (Array.isArray(src))
|
|
214
|
-
return src.slice();
|
|
215
|
-
else if (typeof src === 'object') {
|
|
216
|
-
let dst: any = {};
|
|
217
|
-
for (var p in src) if (src.hasOwnProperty(p))
|
|
218
|
-
dst[p] = src[p];
|
|
219
|
-
return dst;
|
|
220
|
-
}
|
|
221
|
-
else
|
|
222
|
-
return src;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
export function deepCopy(src: any): any {
|
|
226
|
-
if (Array.isArray(src)) {
|
|
227
|
-
let dst: any[] = [];
|
|
228
|
-
|
|
229
|
-
for (let i: number = 0; i < src.length; i++)
|
|
230
|
-
dst.push(deepCopy(src[i]));
|
|
231
|
-
return dst;
|
|
232
|
-
}
|
|
233
|
-
else if (typeof src === 'object') {
|
|
234
|
-
let dst: any = {};
|
|
235
|
-
for (var p in src) if (src.hasOwnProperty(p))
|
|
236
|
-
dst[p] = deepCopy(src[p]);
|
|
237
|
-
return dst;
|
|
238
|
-
}
|
|
239
|
-
else
|
|
240
|
-
return src;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
// TODO - Terry: What is this the simple explanation of what this thing is doing?
|
|
245
|
-
export { depthof } from '@dra2020/util';
|