@dra2020/district-analytics 6.0.0 → 6.2.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/dist/cli.js +195 -153
- package/dist/cli.js.map +1 -1
- package/dist/district-analytics.js +11 -0
- package/dist/district-analytics.js.map +1 -1
- package/dist/src/_api.d.ts +1 -0
- package/dist/src/types.d.ts +7 -0
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -89102,7 +89102,7 @@ exports.scorePolsbyPopper = scorePolsbyPopper;
|
|
|
89102
89102
|
/*! exports provided: partisan, minority, traditionalPrinciples, default */
|
|
89103
89103
|
/***/ (function(module) {
|
|
89104
89104
|
|
|
89105
|
-
module.exports = JSON.parse("{\"partisan\":{\"bias\":{\"range\":[0,0.2],\"weight\":[50,80]},\"impact\":{\"weight\":[50,0],\"threshold\":4},\"competitiveness\":{\"
|
|
89105
|
+
module.exports = JSON.parse("{\"partisan\":{\"bias\":{\"range\":[0,0.2],\"weight\":[50,80]},\"impact\":{\"weight\":[50,0],\"threshold\":4},\"competitiveness\":{\"range\":[0,0.75],\"distribution\":[0.25,0.75],\"simpleRange\":[0.45,0.55],\"weight\":[0,20]},\"bonus\":2,\"weight\":[100,80]},\"minority\":{\"range\":[0.37,0.5],\"distribution\":[0.25,0.75],\"shift\":0.15,\"coalition\":{\"weight\":0.5},\"bonus\":20},\"traditionalPrinciples\":{\"compactness\":{\"reock\":{\"range\":[0.25,0.5],\"weight\":50},\"polsby\":{\"range\":[0.1,0.5],\"weight\":50},\"weight\":[0,50]},\"splitting\":{\"county\":{\"range\":[[1.26,1.68],[1.09,1.45]],\"weight\":50},\"district\":{\"range\":[[1.26,1.68],[1.09,1.45]],\"weight\":50},\"weight\":[0,50]},\"popdev\":{\"range\":[[0.0075,0.002],[0.1,-1]],\"weight\":[0,0]},\"weight\":[0,20]}}");
|
|
89106
89106
|
|
|
89107
89107
|
/***/ }),
|
|
89108
89108
|
|
|
@@ -89160,8 +89160,9 @@ function competitivenessWeight(context, overridesJSON) {
|
|
|
89160
89160
|
return cW;
|
|
89161
89161
|
}
|
|
89162
89162
|
exports.competitivenessWeight = competitivenessWeight;
|
|
89163
|
+
// COMPETITIVENESS - The simple user-facing range, i.e., 45–55%.
|
|
89163
89164
|
function competitiveRange(overridesJSON) {
|
|
89164
|
-
const range = config_json_1.default.partisan.competitiveness.
|
|
89165
|
+
const range = config_json_1.default.partisan.competitiveness.simpleRange;
|
|
89165
89166
|
return range;
|
|
89166
89167
|
}
|
|
89167
89168
|
exports.competitiveRange = competitiveRange;
|
|
@@ -89170,26 +89171,29 @@ function competitiveDistribution(overridesJSON) {
|
|
|
89170
89171
|
return dist;
|
|
89171
89172
|
}
|
|
89172
89173
|
exports.competitiveDistribution = competitiveDistribution;
|
|
89174
|
+
// COMPETITIVENESS - The more complex internal range for normalizing Cdf.
|
|
89175
|
+
// COMPETITIVENESS - 06/23/2020 - As part of relaxing the competitive range, I
|
|
89176
|
+
// I changed this max from 0.67 to 0.75.
|
|
89173
89177
|
function overallCompetitivenessRange(overridesJSON) {
|
|
89174
|
-
const range = config_json_1.default.partisan.competitiveness.
|
|
89178
|
+
const range = config_json_1.default.partisan.competitiveness.range;
|
|
89175
89179
|
return range;
|
|
89176
89180
|
}
|
|
89177
89181
|
exports.overallCompetitivenessRange = overallCompetitivenessRange;
|
|
89178
|
-
function marginalCompetitivenessRange(overridesJSON)
|
|
89179
|
-
|
|
89180
|
-
|
|
89181
|
-
|
|
89182
|
-
|
|
89183
|
-
function marginalCompetitivenessWeight(overridesJSON)
|
|
89184
|
-
|
|
89185
|
-
|
|
89186
|
-
|
|
89187
|
-
|
|
89188
|
-
function overallCompetitivenessWeight(overridesJSON)
|
|
89189
|
-
|
|
89190
|
-
|
|
89191
|
-
|
|
89192
|
-
|
|
89182
|
+
// export function marginalCompetitivenessRange(overridesJSON?: any): number[]
|
|
89183
|
+
// {
|
|
89184
|
+
// const range = config.partisan.competitiveness.marginal.range;
|
|
89185
|
+
// return range;
|
|
89186
|
+
// }
|
|
89187
|
+
// export function marginalCompetitivenessWeight(overridesJSON?: any): number
|
|
89188
|
+
// {
|
|
89189
|
+
// const mcW = config.partisan.competitiveness.marginal.weight;
|
|
89190
|
+
// return mcW;
|
|
89191
|
+
// }
|
|
89192
|
+
// export function overallCompetitivenessWeight(overridesJSON?: any): number
|
|
89193
|
+
// {
|
|
89194
|
+
// const ocW = config.partisan.competitiveness.overall.weight;
|
|
89195
|
+
// return ocW;
|
|
89196
|
+
// }
|
|
89193
89197
|
// MINORITY
|
|
89194
89198
|
function minorityOpportunityRange(overridesJSON) {
|
|
89195
89199
|
const range = config_json_1.default.minority.range;
|
|
@@ -89206,11 +89210,11 @@ function minorityShift(overridesJSON) {
|
|
|
89206
89210
|
return shift;
|
|
89207
89211
|
}
|
|
89208
89212
|
exports.minorityShift = minorityShift;
|
|
89209
|
-
function
|
|
89210
|
-
const
|
|
89211
|
-
return
|
|
89213
|
+
function coalitionDistrictWeight(overridesJSON) {
|
|
89214
|
+
const weight = config_json_1.default.minority.coalition.weight;
|
|
89215
|
+
return weight;
|
|
89212
89216
|
}
|
|
89213
|
-
exports.
|
|
89217
|
+
exports.coalitionDistrictWeight = coalitionDistrictWeight;
|
|
89214
89218
|
function minorityBonus(overridesJSON) {
|
|
89215
89219
|
const bonus = config_json_1.default.minority.bonus;
|
|
89216
89220
|
return bonus;
|
|
@@ -89396,9 +89400,8 @@ function __export(m) {
|
|
|
89396
89400
|
}
|
|
89397
89401
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
89398
89402
|
__export(__webpack_require__(/*! ./_api */ "./src/_api.ts"));
|
|
89399
|
-
var
|
|
89400
|
-
exports.
|
|
89401
|
-
exports.sampleProfile = types_1.sampleProfile;
|
|
89403
|
+
var partisan_1 = __webpack_require__(/*! ./partisan */ "./src/partisan.ts");
|
|
89404
|
+
exports.estSeatProbability = partisan_1.estSeatProbability;
|
|
89402
89405
|
|
|
89403
89406
|
|
|
89404
89407
|
/***/ }),
|
|
@@ -89434,57 +89437,91 @@ function evalMinorityOpportunity(p, bLog = false) {
|
|
|
89434
89437
|
const RWins = VfArray.filter(x => x <= 0.5); // Ties credited to R's
|
|
89435
89438
|
const averageDVf = (DWins.length > 0) ? U.avgArray(DWins) : undefined;
|
|
89436
89439
|
const averageRVf = (RWins.length > 0) ? U.avgArray(RWins) : undefined;
|
|
89437
|
-
// Determine proportional minority districts by demographic (ignore 'White')
|
|
89438
|
-
const districtsByDemo = calcDistrictsByDemo(p.demographicProfile.stateMfArray.slice(1), p.nDistricts);
|
|
89439
89440
|
// Initialize arrays for results
|
|
89440
89441
|
const offset = 1; // Don't process 'White'
|
|
89441
89442
|
const nDemos = 6 /* Native */ + 1 - offset; // Ditto
|
|
89442
|
-
const nBuckets = 2; // 37–50% and > 50%
|
|
89443
89443
|
const demosByDistrict = p.demographicProfile.mfArrayByDistrict;
|
|
89444
89444
|
// Initialize the demographic buckets
|
|
89445
|
-
|
|
89445
|
+
// COMPETITIVENESS - 06/23/2020 - And populate the statewide values.
|
|
89446
|
+
// Get the statewide minority VAP/CVAP % (ignore 'White')
|
|
89447
|
+
const vapPctArray = p.demographicProfile.stateMfArray.slice(1);
|
|
89448
|
+
// Determine proportional minority districts by demographic (ignoring'White')
|
|
89449
|
+
const districtsByDemo = calcDistrictsByDemo(vapPctArray, p.nDistricts);
|
|
89450
|
+
let bucketsByDemo = new Array(nDemos + 1); // Add a row for the 'Total' row
|
|
89451
|
+
let totalProportional = 0;
|
|
89446
89452
|
for (let j = 0; j < nDemos; j++) {
|
|
89447
|
-
|
|
89448
|
-
|
|
89449
|
-
|
|
89453
|
+
const vapPct = vapPctArray[j];
|
|
89454
|
+
const prop = districtsByDemo[j];
|
|
89455
|
+
// Accumulate the proportional values for each demographic, ignoring the first
|
|
89456
|
+
// all Minority demographic.
|
|
89457
|
+
if (j > 0)
|
|
89458
|
+
totalProportional += prop;
|
|
89459
|
+
bucketsByDemo[j] = [0, 0, 0, vapPct, prop]; // Five conceptual columns for each demographic
|
|
89460
|
+
}
|
|
89461
|
+
// Add a 'Total' row
|
|
89462
|
+
bucketsByDemo[nDemos] = [0, 0, 0, 0, totalProportional];
|
|
89463
|
+
let opptyByDemo = U.initArray(nDemos, 0.0); // A state-level value
|
|
89450
89464
|
// For each district
|
|
89451
89465
|
for (let i = 0; i < p.nDistricts; i++) {
|
|
89452
89466
|
// Find the opportunities for minority representation
|
|
89453
89467
|
for (let j = 0; j < nDemos; j++) {
|
|
89454
|
-
const proportion = U.deepCopy(demosByDistrict[i][j + offset]);
|
|
89468
|
+
const proportion = U.deepCopy(demosByDistrict[i][j + offset]); // Skip the 'White' entries
|
|
89455
89469
|
if (exceedsMinimumThreshold(proportion)) {
|
|
89456
|
-
// Bucket opportunity districts
|
|
89470
|
+
// Bucket opportunity districts for each demographic
|
|
89457
89471
|
const bucket = (exceedsMaximumThreshold(proportion)) ? 1 : 0;
|
|
89458
89472
|
bucketsByDemo[j][bucket] += 1;
|
|
89473
|
+
bucketsByDemo[j][2 /* Total */] += 1;
|
|
89459
89474
|
// Accumulate seat probabilities
|
|
89460
89475
|
opptyByDemo[j] += estMinorityOpportunity(proportion);
|
|
89476
|
+
// Also accumulate the 'Total' row summing the opportunities for each demographic,
|
|
89477
|
+
// ignoring the first all Minority demographic.
|
|
89478
|
+
if (j > 0) {
|
|
89479
|
+
bucketsByDemo[nDemos][bucket] += 1;
|
|
89480
|
+
bucketsByDemo[nDemos][2 /* Total */] += 1;
|
|
89481
|
+
}
|
|
89461
89482
|
}
|
|
89462
89483
|
}
|
|
89463
89484
|
}
|
|
89464
|
-
//
|
|
89465
|
-
const oD = U.sumArray(opptyByDemo.slice(1));
|
|
89466
|
-
|
|
89467
|
-
|
|
89485
|
+
// The # of opportunity districts for each separate demographic and all minorities
|
|
89486
|
+
const oD = U.sumArray(opptyByDemo.slice(1)); // Sum individual demos, skipping all minorities
|
|
89487
|
+
const cD = opptyByDemo[1 /* Minority */ - offset]; // All minorities
|
|
89488
|
+
// The # of proportional districts for each separate demographic and all minorities
|
|
89489
|
+
const pOd = bucketsByDemo[7 /* Total */ - 1][4 /* PropSeats */];
|
|
89490
|
+
const pCd = bucketsByDemo[1 /* Minority */ - 1][4 /* PropSeats */];
|
|
89491
|
+
// const pOd: number = U.sumArray(districtsByDemo.slice(1)); // Sum individual demos, skipping all minorities
|
|
89492
|
+
// const pCd: number = districtsByDemo[0]; // All minorities
|
|
89468
89493
|
// Score opportunity
|
|
89469
|
-
const score = scoreMinority(oD,
|
|
89494
|
+
const score = scoreMinority(oD, pOd, cD, pCd);
|
|
89470
89495
|
let mS = {
|
|
89471
89496
|
report: {
|
|
89472
89497
|
averageDVf: averageDVf,
|
|
89473
89498
|
averageRVf: averageRVf,
|
|
89474
89499
|
bucketsByDemographic: bucketsByDemo
|
|
89475
89500
|
},
|
|
89476
|
-
|
|
89501
|
+
// proportionalOpportunities: pOd,
|
|
89477
89502
|
opportunityDistricts: oD,
|
|
89503
|
+
// proportionalCoalitions: pCd,
|
|
89504
|
+
coalitionDistricts: cD,
|
|
89478
89505
|
score: score,
|
|
89479
89506
|
details: {}
|
|
89480
89507
|
};
|
|
89481
89508
|
return mS;
|
|
89482
89509
|
}
|
|
89483
89510
|
exports.evalMinorityOpportunity = evalMinorityOpportunity;
|
|
89484
|
-
|
|
89511
|
+
// NOTE - The probable # of opportunity & coalition districts can be *larger* than
|
|
89512
|
+
// what would be a proportional # based on the statewide percentage, because of
|
|
89513
|
+
// how minority opportunities are estimated (so that 37% minority shares score
|
|
89514
|
+
// like 52% share).
|
|
89515
|
+
function scoreMinority(oD, pOd, cD, pCd) {
|
|
89485
89516
|
// Score minority opportunity [0–100] here; weight it later
|
|
89486
89517
|
const bonus = 100; // C.minorityBonus();
|
|
89487
|
-
const
|
|
89518
|
+
const cDWeight = C.coalitionDistrictWeight();
|
|
89519
|
+
// Cap opportunity & coalition districts
|
|
89520
|
+
const oDCapped = Math.min(oD, pOd);
|
|
89521
|
+
const cdCapped = Math.min(cD, pCd);
|
|
89522
|
+
const opportunityScore = (pOd > 0) ? Math.round((oDCapped / pOd) * bonus) : 0;
|
|
89523
|
+
const coalitionScore = (pCd > 0) ? Math.round((cdCapped / pCd) * bonus) : 0;
|
|
89524
|
+
const score = Math.round(Math.min(opportunityScore + cDWeight * Math.max(coalitionScore - opportunityScore, 0), 100));
|
|
89488
89525
|
return score;
|
|
89489
89526
|
}
|
|
89490
89527
|
exports.scoreMinority = scoreMinority;
|
|
@@ -89510,7 +89547,7 @@ function estMinorityOpportunity(Mf) {
|
|
|
89510
89547
|
_normalizer.wipNum += shift;
|
|
89511
89548
|
_normalizer.clip(dist[C.BEG], dist[C.END]);
|
|
89512
89549
|
_normalizer.unitize(dist[C.BEG], dist[C.END]);
|
|
89513
|
-
const oppty = (Mf < range[C.BEG]) ? 0.0 : partisan_1.estSeatProbability(_normalizer.wipNum, dist);
|
|
89550
|
+
const oppty = (Mf < range[C.BEG]) ? 0.0 : Math.min(partisan_1.estSeatProbability(_normalizer.wipNum, dist), 1.0);
|
|
89514
89551
|
return oppty;
|
|
89515
89552
|
}
|
|
89516
89553
|
exports.estMinorityOpportunity = estMinorityOpportunity;
|
|
@@ -89719,6 +89756,7 @@ function scorePartisan(Vf, VfArray, options) {
|
|
|
89719
89756
|
const bestS = bestSeats(N, Vf);
|
|
89720
89757
|
const bestSf = bestSeatShare(bestS, N);
|
|
89721
89758
|
const fptpS = bAlternateMetrics ? estFPTPSeats(VfArray) : undefined;
|
|
89759
|
+
// NOTE - When not constrained, use the full probability distribution to calc metrics.
|
|
89722
89760
|
const range = bConstrained ? C.competitiveDistribution() : undefined;
|
|
89723
89761
|
const estS = estSeats(VfArray, range);
|
|
89724
89762
|
const estSf = estSeatShare(estS, N);
|
|
@@ -89728,35 +89766,41 @@ function scorePartisan(Vf, VfArray, options) {
|
|
|
89728
89766
|
const impactScore = scoreImpact(unearnedS, Vf, estSf, N);
|
|
89729
89767
|
// Calculate additional alternate metrics for reference
|
|
89730
89768
|
// NOTE - Use the uncompressed seat probability function
|
|
89731
|
-
const
|
|
89769
|
+
const dSVpoints = inferSVpoints(Vf, VfArray, shift);
|
|
89770
|
+
const rSVpoints = invertSVPoints(dSVpoints);
|
|
89771
|
+
// const dSVpoints = bAlternateMetrics ? inferSVpoints(Vf, VfArray, shift) : undefined;
|
|
89732
89772
|
const TOf = bAlternateMetrics ? calcTurnoutBias(Vf, VfArray) : undefined;
|
|
89733
|
-
const Bs50 = bAlternateMetrics ? estPartisanBias(
|
|
89773
|
+
const Bs50 = bAlternateMetrics ? estPartisanBias(dSVpoints, N) : undefined;
|
|
89734
89774
|
const Bs50f = (!(Bs50 === undefined)) ? U.trim(Bs50 / N) : undefined;
|
|
89735
|
-
const Bv50f = bAlternateMetrics ? estVotesBias(
|
|
89775
|
+
const Bv50f = bAlternateMetrics ? estVotesBias(dSVpoints, N) : undefined;
|
|
89736
89776
|
const rvPoints = bAlternateMetrics ? keyRVpoints(VfArray) : undefined;
|
|
89737
89777
|
const decl = bAlternateMetrics ? calcDeclination(VfArray) : undefined;
|
|
89738
|
-
const gSym = bAlternateMetrics ? calcGlobalSymmetry(
|
|
89778
|
+
const gSym = bAlternateMetrics ? calcGlobalSymmetry(dSVpoints, rSVpoints, Bs50f) : undefined;
|
|
89739
89779
|
const EG = bAlternateMetrics ? calcEfficiencyGap(Vf, estSf) : undefined;
|
|
89740
|
-
const BsGf = bAlternateMetrics ? estGeometricSeatsBias(Vf,
|
|
89780
|
+
const BsGf = bAlternateMetrics ? estGeometricSeatsBias(Vf, dSVpoints, rSVpoints) : undefined;
|
|
89741
89781
|
const prop = bAlternateMetrics ? calcDisproportionality(Vf, estSf) : undefined;
|
|
89742
89782
|
const mMs = bAlternateMetrics ? estMeanMedianDifference(VfArray, Vf) : undefined;
|
|
89743
89783
|
const mMd = bAlternateMetrics ? estMeanMedianDifference(VfArray) : undefined;
|
|
89744
89784
|
const LO = bAlternateMetrics ? calcLopsidedOutcomes(VfArray) : undefined;
|
|
89745
89785
|
// Calculate alternate responsiveness metrics for reference
|
|
89746
89786
|
const bigR = bAlternateMetrics ? calcBigR(Vf, estSf) : undefined;
|
|
89747
|
-
const littleR = bAlternateMetrics ? estResponsiveness(Vf,
|
|
89787
|
+
const littleR = bAlternateMetrics ? estResponsiveness(Vf, dSVpoints) : undefined;
|
|
89748
89788
|
const MIR = (bAlternateMetrics && littleR) ? calcMinimalInverseResponsiveness(Vf, littleR) : undefined;
|
|
89749
89789
|
const rD = (!bConstrained || bAlternateMetrics) ? estResponsiveDistricts(VfArray) : undefined;
|
|
89750
89790
|
const rDf = bAlternateMetrics ? estResponsiveDistrictsShare(rD, N) : undefined;
|
|
89751
89791
|
const gamma = (bAlternateMetrics && littleR) ? calcGamma(Vf, estSf, littleR) : undefined;
|
|
89752
89792
|
const Cn = countCompetitiveDistricts(VfArray);
|
|
89753
|
-
|
|
89793
|
+
// NOTE - Cd by definition uses a *possibly* different (more narrow) probability
|
|
89794
|
+
// distribution than Rd.
|
|
89795
|
+
const cD = estCompetitiveDistricts(VfArray);
|
|
89754
89796
|
// const cD = bConstrained ? estCompetitiveDistricts(VfArray) : rD as number;
|
|
89755
89797
|
const cDf = estCompetitiveDistrictsShare(cD, N);
|
|
89756
|
-
const
|
|
89757
|
-
|
|
89758
|
-
const
|
|
89759
|
-
const
|
|
89798
|
+
const competitivenessScore = scoreCompetitiveness(cDf);
|
|
89799
|
+
// NOTE: Original version:
|
|
89800
|
+
// const Mrange = findMarginalDistricts(Vf, VfArray, N);
|
|
89801
|
+
// const Md = estMarginalCompetitiveDistricts(Mrange, VfArray);
|
|
89802
|
+
// const Mdf = estMarginalCompetitiveShare(Md, Mrange);
|
|
89803
|
+
// const competitivenessScore = scoreCompetitiveness(Mdf, cDf);
|
|
89760
89804
|
let biasScoring = {
|
|
89761
89805
|
bestS: bestS,
|
|
89762
89806
|
bestSf: bestSf,
|
|
@@ -89773,9 +89817,9 @@ function scorePartisan(Vf, VfArray, options) {
|
|
|
89773
89817
|
cSimple: Cn,
|
|
89774
89818
|
cD: cD,
|
|
89775
89819
|
cDf: cDf,
|
|
89776
|
-
mRange: Mrange,
|
|
89777
|
-
mD: Md,
|
|
89778
|
-
mDf: Mdf,
|
|
89820
|
+
// mRange: Mrange,
|
|
89821
|
+
// mD: Md,
|
|
89822
|
+
// mDf: Mdf,
|
|
89779
89823
|
score: competitivenessScore
|
|
89780
89824
|
};
|
|
89781
89825
|
if (bAlternateMetrics) {
|
|
@@ -89810,6 +89854,8 @@ function scorePartisan(Vf, VfArray, options) {
|
|
|
89810
89854
|
bias: biasScoring,
|
|
89811
89855
|
impact: impactScoring,
|
|
89812
89856
|
competitiveness: competitiveScoring,
|
|
89857
|
+
dSVpoints: dSVpoints,
|
|
89858
|
+
rSVpoints: rSVpoints,
|
|
89813
89859
|
score: acrossStatesPartisanScore,
|
|
89814
89860
|
score2: withinStatesPartisanScore,
|
|
89815
89861
|
details: {}
|
|
@@ -89891,32 +89937,59 @@ function isAntimajoritarian(Vf, Sf) {
|
|
|
89891
89937
|
return bDem || bRep;
|
|
89892
89938
|
}
|
|
89893
89939
|
exports.isAntimajoritarian = isAntimajoritarian;
|
|
89894
|
-
|
|
89895
|
-
|
|
89896
|
-
|
|
89897
|
-
|
|
89898
|
-
|
|
89940
|
+
// COMPETITIVENESS - Revised 06/23/2020
|
|
89941
|
+
// Normalize overall competitiveness - Raw values are in the range [0.0–1.0].
|
|
89942
|
+
// But the practical max is more like 2/3's, so unitize that range to [0.0–1.0].
|
|
89943
|
+
// Then scale the values to [0–100].
|
|
89944
|
+
function scoreCompetitiveness(Cdf) {
|
|
89945
|
+
const _normalizer = new normalize_1.Normalizer(Cdf);
|
|
89899
89946
|
let worst = C.overallCompetitivenessRange()[C.BEG];
|
|
89900
89947
|
let best = C.overallCompetitivenessRange()[C.END];
|
|
89901
|
-
|
|
89902
|
-
|
|
89903
|
-
|
|
89904
|
-
const
|
|
89905
|
-
// Normalize marginal competitiveness
|
|
89906
|
-
const _marginal = new normalize_1.Normalizer(rawMarginal);
|
|
89907
|
-
worst = C.marginalCompetitivenessRange()[C.BEG];
|
|
89908
|
-
best = C.marginalCompetitivenessRange()[C.END];
|
|
89909
|
-
_marginal.clip(worst, best);
|
|
89910
|
-
_marginal.unitize(worst, best);
|
|
89911
|
-
_marginal.rescale();
|
|
89912
|
-
const mcS = _marginal.normalizedNum;
|
|
89913
|
-
const mcW = C.marginalCompetitivenessWeight();
|
|
89914
|
-
const ocW = C.overallCompetitivenessWeight();
|
|
89915
|
-
// Then combine the results
|
|
89916
|
-
const score = ((mcW + ocW) > 0) ? Math.round(((mcW * mcS) + (ocW * ocS)) / (mcW + ocW)) : 0;
|
|
89948
|
+
_normalizer.clip(worst, best);
|
|
89949
|
+
_normalizer.unitize(worst, best);
|
|
89950
|
+
_normalizer.rescale();
|
|
89951
|
+
const score = _normalizer.normalizedNum;
|
|
89917
89952
|
return score;
|
|
89918
89953
|
}
|
|
89919
89954
|
exports.scoreCompetitiveness = scoreCompetitiveness;
|
|
89955
|
+
/* NOTE - Original version:
|
|
89956
|
+
export function scoreCompetitiveness(rawMarginal: number, rawOverall: number): number
|
|
89957
|
+
{
|
|
89958
|
+
// Normalize overall competitiveness - Raw values are in the range [0.0–1.0].
|
|
89959
|
+
// But the practical max is more like 2/3's, so unitize that range to [0.0–1.0].
|
|
89960
|
+
// Then scale the values to [0–100].
|
|
89961
|
+
const _overall = new Normalizer(rawOverall);
|
|
89962
|
+
|
|
89963
|
+
let worst = C.overallCompetitivenessRange()[C.BEG];
|
|
89964
|
+
let best = C.overallCompetitivenessRange()[C.END];
|
|
89965
|
+
|
|
89966
|
+
_overall.clip(worst, best);
|
|
89967
|
+
_overall.unitize(worst, best);
|
|
89968
|
+
_overall.rescale();
|
|
89969
|
+
|
|
89970
|
+
const ocS = _overall.normalizedNum as number;
|
|
89971
|
+
|
|
89972
|
+
|
|
89973
|
+
// Normalize marginal competitiveness
|
|
89974
|
+
const _marginal = new Normalizer(rawMarginal);
|
|
89975
|
+
|
|
89976
|
+
worst = C.marginalCompetitivenessRange()[C.BEG];
|
|
89977
|
+
best = C.marginalCompetitivenessRange()[C.END];
|
|
89978
|
+
|
|
89979
|
+
_marginal.clip(worst, best);
|
|
89980
|
+
_marginal.unitize(worst, best);
|
|
89981
|
+
_marginal.rescale();
|
|
89982
|
+
const mcS = _marginal.normalizedNum as number;
|
|
89983
|
+
|
|
89984
|
+
const mcW = C.marginalCompetitivenessWeight();
|
|
89985
|
+
const ocW = C.overallCompetitivenessWeight();
|
|
89986
|
+
|
|
89987
|
+
// Then combine the results
|
|
89988
|
+
const score = ((mcW + ocW) > 0) ? Math.round(((mcW * mcS) + (ocW * ocS)) / (mcW + ocW)) : 0;
|
|
89989
|
+
|
|
89990
|
+
return score;
|
|
89991
|
+
}
|
|
89992
|
+
*/
|
|
89920
89993
|
// CORE CAPABILITIES FROM JOHN NAGLE'S METHOD
|
|
89921
89994
|
const { erf } = __webpack_require__(/*! mathjs */ "./node_modules/mathjs/main/esm/index.js");
|
|
89922
89995
|
// console.log("erf(0.2) =", erf(0.2)); // returns 0.22270258921047847
|
|
@@ -90150,19 +90223,20 @@ function isCompetitive(v) {
|
|
|
90150
90223
|
return ((v >= C.competitiveRange()[C.BEG]) && (v <= C.competitiveRange()[C.END])) ? 1 : 0;
|
|
90151
90224
|
}
|
|
90152
90225
|
// cD - The estimated # of competitive districts
|
|
90153
|
-
function estCompetitiveDistricts(VfArray) {
|
|
90154
|
-
return U.trim(U.sumArray(VfArray.map(v => estDistrictCompetitiveness(v))));
|
|
90226
|
+
function estCompetitiveDistricts(VfArray, bCompress = false) {
|
|
90227
|
+
return U.trim(U.sumArray(VfArray.map(v => estDistrictCompetitiveness(v, bCompress))));
|
|
90155
90228
|
}
|
|
90156
90229
|
exports.estCompetitiveDistricts = estCompetitiveDistricts;
|
|
90230
|
+
// COMPETITIVENESS - Modified 06/22/2020
|
|
90157
90231
|
// Re-scale a Democratic vote share to the competitive range (e.g., 45–55%).
|
|
90158
|
-
function estDistrictCompetitiveness(Vf) {
|
|
90232
|
+
function estDistrictCompetitiveness(Vf, bCompress = false) {
|
|
90159
90233
|
const _normalizer = new normalize_1.Normalizer(Vf);
|
|
90160
90234
|
// The end points of a compressed probability distribution
|
|
90161
90235
|
// NOTE - These aren't the points where races start or stop being contested,
|
|
90162
90236
|
// just the end points of a distribution that yields the desired behavior
|
|
90163
90237
|
// in the typical competitive range [45-55%].
|
|
90164
|
-
const distBeg = C.competitiveDistribution()[C.BEG];
|
|
90165
|
-
const distEnd = C.competitiveDistribution()[C.END];
|
|
90238
|
+
const distBeg = bCompress ? C.competitiveDistribution()[C.BEG] : 0.0;
|
|
90239
|
+
const distEnd = bCompress ? C.competitiveDistribution()[C.END] : 1.0;
|
|
90166
90240
|
_normalizer.clip(distBeg, distEnd);
|
|
90167
90241
|
_normalizer.unitize(distBeg, distEnd);
|
|
90168
90242
|
const dC = estDistrictResponsiveness(_normalizer.wipNum);
|
|
@@ -90176,14 +90250,14 @@ function estCompetitiveDistrictsShare(cD, N) {
|
|
|
90176
90250
|
exports.estCompetitiveDistrictsShare = estCompetitiveDistrictsShare;
|
|
90177
90251
|
// Md - The estimated # of "marginal" districts in and around the likely FPTP
|
|
90178
90252
|
// seats & the best seat split that are competitive.
|
|
90179
|
-
function estMarginalCompetitiveDistricts(Mrange, VfArray) {
|
|
90253
|
+
function estMarginalCompetitiveDistricts(Mrange, VfArray, bCompress = false) {
|
|
90180
90254
|
const minId = Mrange[C.BEG];
|
|
90181
90255
|
const maxId = Mrange[C.END];
|
|
90182
90256
|
// Sort the array values, and subset it to those districts
|
|
90183
90257
|
// NOTE - I'm *not* keeping track of the district indexes right now
|
|
90184
90258
|
let subsetVfArray = U.deepCopy(VfArray).sort().slice(minId - 1, maxId);
|
|
90185
90259
|
// Est. competitive districts on that array
|
|
90186
|
-
const Md = U.sumArray(subsetVfArray.map((v) => estDistrictCompetitiveness(v)));
|
|
90260
|
+
const Md = U.sumArray(subsetVfArray.map((v) => estDistrictCompetitiveness(v, bCompress)));
|
|
90187
90261
|
return U.trim(Md);
|
|
90188
90262
|
}
|
|
90189
90263
|
exports.estMarginalCompetitiveDistricts = estMarginalCompetitiveDistricts;
|
|
@@ -90281,9 +90355,9 @@ function estVotesBias(inferredSVpoints, nDistricts) {
|
|
|
90281
90355
|
}
|
|
90282
90356
|
exports.estVotesBias = estVotesBias;
|
|
90283
90357
|
// GEOMETRIC SEATS BIAS (@ V = statewide vote share)
|
|
90284
|
-
function estGeometricSeatsBias(Vf,
|
|
90358
|
+
function estGeometricSeatsBias(Vf, dSVpoints, rSVpoints) {
|
|
90285
90359
|
let BsGf = undefined;
|
|
90286
|
-
const bgsSVpoints = inferGeometricSeatsBiasPoints(
|
|
90360
|
+
const bgsSVpoints = inferGeometricSeatsBiasPoints(dSVpoints, rSVpoints);
|
|
90287
90361
|
// Interpolate the seat fraction @ Vf
|
|
90288
90362
|
const lowerPt = findBracketingLowerVf(Vf, bgsSVpoints);
|
|
90289
90363
|
const upperPt = findBracketingUpperVf(Vf, bgsSVpoints);
|
|
@@ -90296,14 +90370,13 @@ function estGeometricSeatsBias(Vf, inferredSVpoints) {
|
|
|
90296
90370
|
return BsGf;
|
|
90297
90371
|
}
|
|
90298
90372
|
exports.estGeometricSeatsBias = estGeometricSeatsBias;
|
|
90299
|
-
function inferGeometricSeatsBiasPoints(
|
|
90300
|
-
const nPoints =
|
|
90301
|
-
const inverseSVpoints = invertSVPoints(inferredSVpoints);
|
|
90373
|
+
function inferGeometricSeatsBiasPoints(dSVpoints, rSVpoints) {
|
|
90374
|
+
const nPoints = dSVpoints.length;
|
|
90302
90375
|
let bgsSVpoints = [];
|
|
90303
90376
|
for (let i = 0; i < nPoints; i++) {
|
|
90304
|
-
const Vf =
|
|
90305
|
-
const sD =
|
|
90306
|
-
const sR =
|
|
90377
|
+
const Vf = dSVpoints[i].v;
|
|
90378
|
+
const sD = dSVpoints[i].s;
|
|
90379
|
+
const sR = rSVpoints[i].s;
|
|
90307
90380
|
const BsGf = 0.5 * (sR - sD);
|
|
90308
90381
|
bgsSVpoints.push({ v: Vf, s: BsGf });
|
|
90309
90382
|
}
|
|
@@ -90462,11 +90535,10 @@ function calcLopsidedOutcomes(VfArray) {
|
|
|
90462
90535
|
}
|
|
90463
90536
|
exports.calcLopsidedOutcomes = calcLopsidedOutcomes;
|
|
90464
90537
|
// GLOBAL SYMMETRY - Fig. 17 in Section 5.1
|
|
90465
|
-
function calcGlobalSymmetry(
|
|
90466
|
-
const invertedSVpoints = invertSVPoints(inferredSVpoints);
|
|
90538
|
+
function calcGlobalSymmetry(dSVpoints, rSVpoints, S50V) {
|
|
90467
90539
|
let gSym = 0.0;
|
|
90468
|
-
for (let i in
|
|
90469
|
-
gSym += Math.abs(
|
|
90540
|
+
for (let i in dSVpoints) {
|
|
90541
|
+
gSym += Math.abs(dSVpoints[i].s - rSVpoints[i].s) / 2;
|
|
90470
90542
|
}
|
|
90471
90543
|
const sign = (S50V < 0) ? -1 : 1;
|
|
90472
90544
|
gSym *= sign;
|
|
@@ -90526,7 +90598,7 @@ function calcGamma(Vf, Sf, r) {
|
|
|
90526
90598
|
exports.calcGamma = calcGamma;
|
|
90527
90599
|
// HELPERS
|
|
90528
90600
|
function printPartisanScorecardHeader() {
|
|
90529
|
-
console.log('XX, Name, N, V%, ^S#, S#, B%, B$, UE#, I$, C#, Cd,
|
|
90601
|
+
console.log('XX, Name, N, V%, ^S#, S#, B%, B$, UE#, I$, C#, Cd, Cdf, C$, <P$');
|
|
90530
90602
|
}
|
|
90531
90603
|
exports.printPartisanScorecardHeader = printPartisanScorecardHeader;
|
|
90532
90604
|
function printPartisanScorecardRow(xx, name, N, Vf, s) {
|
|
@@ -90539,21 +90611,24 @@ function printPartisanScorecardRow(xx, name, N, Vf, s) {
|
|
|
90539
90611
|
s.bias.bias, // 7
|
|
90540
90612
|
s.bias.score, s.impact.unearnedS, // 9
|
|
90541
90613
|
s.impact.score, s.competitiveness.cSimple, // 11
|
|
90542
|
-
s.competitiveness.cD, s.competitiveness.
|
|
90614
|
+
s.competitiveness.cD, s.competitiveness.cDf,
|
|
90615
|
+
// s.competitiveness.mD,
|
|
90616
|
+
s.competitiveness.score, s.score // 15
|
|
90543
90617
|
);
|
|
90544
90618
|
}
|
|
90545
90619
|
exports.printPartisanScorecardRow = printPartisanScorecardRow;
|
|
90546
90620
|
// Generate partisan details (Table 1)
|
|
90547
90621
|
function printPartisanDetailsHeader() {
|
|
90548
|
-
console.log('XX, <V>, S(<V>), B%, BS_50, BV_50, Decl, GS, EG, Beta, PR, MM, TO, MM\', LO, Rd, R, r, MIR');
|
|
90622
|
+
console.log('XX, <V>, S(<V>), B%, BS_50, BV_50, Decl, GS, EG, Beta, PR, MM, TO, MM\', LO, Rd, R, r, MIR, Cd, Cdf');
|
|
90549
90623
|
}
|
|
90550
90624
|
exports.printPartisanDetailsHeader = printPartisanDetailsHeader;
|
|
90551
90625
|
function printPartisanDetailsRow(xx, name, N, Vf, s) {
|
|
90552
|
-
console.log('%s, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f', xx, Vf, s.bias.estSf, s.bias.bias, // Simple bias
|
|
90626
|
+
console.log('%s, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f', xx, Vf, s.bias.estSf, s.bias.bias, // Simple bias
|
|
90553
90627
|
s.bias.bS50, s.bias.bV50, s.bias.decl, s.bias.gSym, s.bias.eG, s.bias.bSV, // Beta
|
|
90554
90628
|
s.bias.prop, // PR
|
|
90555
|
-
s.bias.mMs, s.bias.tOf, s.bias.mMd, s.bias.lO, s.competitiveness.rD, s.competitiveness.bigR, s.competitiveness.littleR, s.competitiveness.mIR // Zeta
|
|
90556
|
-
|
|
90629
|
+
s.bias.mMs, s.bias.tOf, s.bias.mMd, s.bias.lO, s.competitiveness.rD, s.competitiveness.bigR, s.competitiveness.littleR, s.competitiveness.mIR, // Zeta
|
|
90630
|
+
s.competitiveness.cD, // COMPETITIVENESS - Temporary to confirm new calc
|
|
90631
|
+
s.competitiveness.cDf);
|
|
90557
90632
|
}
|
|
90558
90633
|
exports.printPartisanDetailsRow = printPartisanDetailsRow;
|
|
90559
90634
|
|
|
@@ -90683,11 +90758,11 @@ function mixinMinorityBonus(score, minorityBonus) {
|
|
|
90683
90758
|
}
|
|
90684
90759
|
exports.mixinMinorityBonus = mixinMinorityBonus;
|
|
90685
90760
|
function printScorecardHeader() {
|
|
90686
|
-
console.log('XX, Name, N, V%, ^S#, S#, B%, B$, UE#, I$, C#, Cd,
|
|
90761
|
+
console.log('XX, Name, N, V%, ^S#, S#, B%, B$, UE#, I$, C#, Cd, Cdf, C$, >P$, Rc, Rc$, Pc, Pc$, G$, Cs, Cs$, Ds, Ds$, S$, Eq, Eq$, T$, Od, Md, M$, $$$');
|
|
90687
90762
|
}
|
|
90688
90763
|
exports.printScorecardHeader = printScorecardHeader;
|
|
90689
90764
|
function printScorecardRow(xx, name, N, Vf, s) {
|
|
90690
|
-
console.log('%s, %s, %i, %f, %i, %f, %f, %i, %f, %i, %i, %f, %f, %i, %i, %f, %i, %f, %i, %i, %f, %i, %f, %i, %i, %f, %i, %i, %f, %i, %i', xx, // 1
|
|
90765
|
+
console.log('%s, %s, %i, %f, %i, %f, %f, %i, %f, %i, %i, %f, %f, %i, %i, %f, %i, %f, %i, %i, %f, %i, %f, %i, %i, %f, %i, %i, %f, %f, %i, %i', xx, // 1
|
|
90691
90766
|
name, // 2
|
|
90692
90767
|
N, // 3
|
|
90693
90768
|
Vf, // 4
|
|
@@ -90696,8 +90771,10 @@ function printScorecardRow(xx, name, N, Vf, s) {
|
|
|
90696
90771
|
s.partisan.bias.bias, // 7
|
|
90697
90772
|
s.partisan.bias.score, s.partisan.impact.unearnedS, // 9
|
|
90698
90773
|
s.partisan.impact.score, s.partisan.competitiveness.cSimple, // 11
|
|
90699
|
-
s.partisan.competitiveness.cD, s.partisan.competitiveness.
|
|
90700
|
-
|
|
90774
|
+
s.partisan.competitiveness.cD, s.partisan.competitiveness.cDf,
|
|
90775
|
+
// s.partisan.competitiveness.mD,
|
|
90776
|
+
s.partisan.competitiveness.score, s.partisan.score2, // 15
|
|
90777
|
+
s.traditionalPrinciples.compactness.reock.raw, s.traditionalPrinciples.compactness.reock.normalized, s.traditionalPrinciples.compactness.polsby.raw, s.traditionalPrinciples.compactness.polsby.normalized, s.traditionalPrinciples.compactness.score, s.traditionalPrinciples.splitting.county.raw, s.traditionalPrinciples.splitting.county.normalized, s.traditionalPrinciples.splitting.district.raw, s.traditionalPrinciples.splitting.district.normalized, s.traditionalPrinciples.splitting.score, s.traditionalPrinciples.populationDeviation.raw, s.traditionalPrinciples.populationDeviation.normalized, s.traditionalPrinciples.score, s.minority.opportunityDistricts, s.minority.coalitionDistricts, s.minority.score, s.score);
|
|
90701
90778
|
}
|
|
90702
90779
|
exports.printScorecardRow = printScorecardRow;
|
|
90703
90780
|
|
|
@@ -90732,30 +90809,6 @@ exports.AVERAGE_BLOCK_SIZE = 30;
|
|
|
90732
90809
|
exports.EQUAL_TOLERANCE = exports.AVERAGE_BLOCK_SIZE / 2;
|
|
90733
90810
|
|
|
90734
90811
|
|
|
90735
|
-
/***/ }),
|
|
90736
|
-
|
|
90737
|
-
/***/ "./src/types.ts":
|
|
90738
|
-
/*!**********************!*\
|
|
90739
|
-
!*** ./src/types.ts ***!
|
|
90740
|
-
\**********************/
|
|
90741
|
-
/*! no static exports found */
|
|
90742
|
-
/***/ (function(module, exports, __webpack_require__) {
|
|
90743
|
-
|
|
90744
|
-
"use strict";
|
|
90745
|
-
|
|
90746
|
-
//
|
|
90747
|
-
// TYPE DEFINITIONS
|
|
90748
|
-
//
|
|
90749
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
90750
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
90751
|
-
};
|
|
90752
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
90753
|
-
const sample_profile_json_1 = __importDefault(__webpack_require__(/*! ../testdata/samples/sample-profile.json */ "./testdata/samples/sample-profile.json"));
|
|
90754
|
-
exports.sampleProfile = sample_profile_json_1.default;
|
|
90755
|
-
const sample_scorecard_json_1 = __importDefault(__webpack_require__(/*! ../testdata/samples/sample-scorecard.json */ "./testdata/samples/sample-scorecard.json"));
|
|
90756
|
-
exports.sampleScorecard = sample_scorecard_json_1.default;
|
|
90757
|
-
|
|
90758
|
-
|
|
90759
90812
|
/***/ }),
|
|
90760
90813
|
|
|
90761
90814
|
/***/ "./src/utils.ts":
|
|
@@ -90854,28 +90907,6 @@ function deepCopy(src) {
|
|
|
90854
90907
|
exports.deepCopy = deepCopy;
|
|
90855
90908
|
|
|
90856
90909
|
|
|
90857
|
-
/***/ }),
|
|
90858
|
-
|
|
90859
|
-
/***/ "./testdata/samples/sample-profile.json":
|
|
90860
|
-
/*!**********************************************!*\
|
|
90861
|
-
!*** ./testdata/samples/sample-profile.json ***!
|
|
90862
|
-
\**********************************************/
|
|
90863
|
-
/*! exports provided: state, planName, nDistricts, nCounties, legislativeDistricts, populationProfile, compactnessProfile, splittingProfile, partisanProfile, demographicProfile, default */
|
|
90864
|
-
/***/ (function(module) {
|
|
90865
|
-
|
|
90866
|
-
module.exports = JSON.parse("{\"state\":\"NC\",\"planName\":\"NC 116th Congressional\",\"nDistricts\":13,\"nCounties\":100,\"legislativeDistricts\":false,\"populationProfile\":{\"totalPopByDistrict\":[733499,733499,733498,733499,733499,733498,733499,733499,733498,733499,733499,733498,733499],\"targetSize\":733499},\"compactnessProfile\":{\"geometryByDistrict\":[[1.577393519870778,10.159603194222512,2.6574239327900613],[0.7058443860242223,7.806818205304456,1.7632772181381422],[2.9200833695730037,9.972779463090355,2.733997011824872],[0.1913918462294299,3.5460738146162076,0.9224411598627837],[1.039017192939366,6.4920493759205495,2.1060599512212406],[1.0334601456545682,6.466840626614781,1.6394147493749138],[1.6241884494008865,7.988593581066711,1.9529170345835551],[0.7706777049448708,6.980189925133433,2.188634395661598],[0.9976766364327585,8.350880983965949,2.5604199958307654],[0.6762837622380331,5.8543721706585545,1.7264608756890525],[1.719230725216499,10.37139670690812,3.1586859214584764],[0.11329839503948308,2.2954988975477066,0.5379072920877442],[0.48371245467321944,5.3384017624136435,1.4517375375301198]]},\"splittingProfile\":{\"countyPopByDistrict\":[[0,0,0,0,0,0,0,21282,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240299,56552,0,0,0,12197,0,59916,0,0,54691,0,0,0,24669,0,0,0,0,0,0,0,0,0,0,0,0,24505,0,0,0,0,0,0,22099,0,0,0,0,0,0,0,80880,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,45422,0,20972,13228,0,0,0,56787,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60619,0,0,0,0,0,0,0,114678,0,0,0,0,0,0,0,109332,0,0,0,0,0,0,0,0,0,0,0,0,95840,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,328583,0,0,0,0,0,24447,0,0],[0,0,0,0,0,0,47759,0,0,0,0,0,0,0,9980,66469,0,0,0,0,14793,0,0,0,103505,0,23547,33920,0,0,0,0,0,0,0,0,0,0,0,21362,0,0,0,0,0,0,0,5810,0,0,0,10153,0,59495,0,0,0,0,0,0,0,0,0,0,0,0,177772,0,13144,40661,0,13453,0,87268,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4407,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27288,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,133801,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,572410,0,0,0,0,0,0,0,0],[0,37198,11155,0,27281,17797,0,0,0,0,0,0,0,0,0,0,0,9499,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,350670,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,47401,73673,0,0,0,0,0,0,0,0,51079,0,69340,0,38406,0],[151131,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23719,0,63505,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,162418,0,0,0,0,0,0,0,0,0,0,0,57866,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,39464,0,0,141752,0,0,93643,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,8981,107431,0,0,0,0,0,0,0,0,0,0,0,0,0,58098,0,0,0,0,0,0,58505,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59546,0,0,0,0,0,0,0,0,0,0,0,0,0,202667,0,0,0,0,0,52217,0,0,0,0,0,0,0,0,0,0,63431,0,0,0,0,0,0,0,0,0,0,0,0,0,122623,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,178011,0,0,0,0,0,0,0,0,0,0,0,0,243476,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,46952,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27798,88247,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,88430,0,0,0,60585,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,26948,0,0,0,0,26209,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75955,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,186130,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,46639,134168,0,0,0,0,36157,0,0,0,0,0,0,201292,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,111849,0,0,0,0,0,0,144859,0,0,0,0,98078,0,0,0,0,0,0,0,0,0,0,0,0,206086,0,0,0,0,0,0,0,0,0,0,0,0,6042,0,0,0,0,0,78265,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20510,0,0,0,0,0,67810,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,126469,90912,0,83029,0,0,0,0,0,27444,0,10587,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8861,0,0,0,0,0,59036,106740,0,0,0,0,40271,0,0,0,0,0,44996,33922,20764,0,0,15579,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13981,33090,0,0,0,0,0,0,0,0,0,0,0,17818],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,733498,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,162878,41240,0,0,0,0,0,0,0,0,0,0,325988,0,0,0,0,0,0,0,153395,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,49998,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]},\"partisanProfile\":{\"statewideVf\":0.488799,\"vfArray\":[0.38133475250631976,0.3849820112175976,0.3932778243643098,0.4232536822067312,0.42479562842958446,0.43309446651496813,0.43760621455968074,0.43980028165892326,0.4545677480810613,0.4642133701735491,0.6853270858231137,0.6938881738049054,0.6953207231271951]},\"demographicProfile\":{\"stateMfArray\":[0.684371246819619,0.31562875318038097,0.21168281993226215,0.06787156278984616,0.0012540930000187486,0.024136155044881008,0.017483272326632705],\"mfArrayByDistrict\":[[0.46201994876162167,0.5379800512383783,0.44446912914151915,0.065885219684988,0.0009221497550043815,0.0218600624522836,0.01298238746863721],[0.7062964810448031,0.2937035189551968,0.19676408791341676,0.07140508797387993,0.0009787472035794184,0.02027027027027027,0.011283934941653062],[0.7125415968218078,0.2874584031781921,0.21181863608495496,0.05374539732717163,0.002106863519897368,0.01628256424250371,0.010404964330393058],[0.6162003899079305,0.3837996100920695,0.22386087117385056,0.08687191382180923,0.0012060108434249284,0.07153885560599377,0.010091002234143982],[0.7766842620090415,0.22331573799095852,0.14015703622760559,0.06690518783542039,0.0007790124871119258,0.013001753659331847,0.007680851626320752],[0.7111584046318987,0.2888415953681012,0.19851813634865356,0.07148666466027488,0.0008061395588804333,0.013621967123837368,0.010186021181764765],[0.7086112059348308,0.2913887940651691,0.20229594619799895,0.06953648210647081,0.001149028868250555,0.009700759801937688,0.014166663733974303],[0.6697822118227867,0.33021778817721326,0.2240088599271958,0.07249565635824667,0.002909229825482943,0.022877125445843145,0.01884938491094157],[0.6406346877484486,0.35936531225155144,0.19622106825202063,0.059419121439330605,0.0010389455633486816,0.02217720538538736,0.08616917683114156],[0.8192767260107778,0.18072327398922214,0.11582505713398979,0.045060025957170666,0.0006806703721468273,0.014117738340433936,0.008000521964844963],[0.8956213645578734,0.1043786354421266,0.032662784268536554,0.04329373425036473,0.0012436075643032956,0.010267513422177209,0.019651410943402076],[0.46574079494234033,0.5342592050576597,0.36183998712169996,0.12151883451384417,0.001650032195750161,0.050651598079962536,0.010997775566352515],[0.6979595109954735,0.3020404890045265,0.21171009017357523,0.0572352710553516,0.0008767865416830024,0.028566846063370996,0.009525252165235058]]}}");
|
|
90867
|
-
|
|
90868
|
-
/***/ }),
|
|
90869
|
-
|
|
90870
|
-
/***/ "./testdata/samples/sample-scorecard.json":
|
|
90871
|
-
/*!************************************************!*\
|
|
90872
|
-
!*** ./testdata/samples/sample-scorecard.json ***!
|
|
90873
|
-
\************************************************/
|
|
90874
|
-
/*! exports provided: score, partisan, minority, traditionalPrinciples, details, default */
|
|
90875
|
-
/***/ (function(module) {
|
|
90876
|
-
|
|
90877
|
-
module.exports = JSON.parse("{\"score\":5,\"partisan\":{\"bias\":{\"bestS\":7,\"bestSf\":0.5385,\"estS\":4.1925,\"estSf\":0.3225,\"bias\":0.216,\"tOf\":-0.0023,\"fptpS\":3,\"bS50\":0.2172,\"bV50\":0.045,\"decl\":36.5164,\"gSym\":0.066602,\"gamma\":0.0123,\"eG\":0.2846,\"bSV\":0.2098,\"prop\":0.2695,\"mMd\":0.0593,\"mMs\":0.057,\"lO\":0.1106,\"score\":0},\"impact\":{\"unearnedS\":2.8075,\"score\":0},\"competitiveness\":{\"bigR\":-16.926,\"littleR\":4.3523,\"mIR\":0.1298,\"rD\":4.0207,\"rDf\":0.3093,\"cSimple\":6,\"cD\":0.7266,\"cDf\":0.0559,\"mRange\":[5,11],\"mD\":0.7134,\"mDf\":0.1019,\"score\":10},\"score\":3,\"score2\":2,\"details\":{\"election\":\"2016 Presidential, US Senate, Governor, and AG election results\"}},\"minority\":{\"report\":{\"bucketsByDemographic\":[[10,14],[3,0],[1,9],[0,0],[0,0],[0,0]],\"averageDVf\":0.6737588682747838},\"nProportional\":18,\"opportunityDistricts\":12.9424,\"score\":14,\"details\":{\"vap\":\"2010 Voting Age Population\"}},\"traditionalPrinciples\":{\"score\":18,\"compactness\":{\"score\":35,\"reock\":{\"raw\":0.3373,\"normalized\":35,\"notes\":{}},\"polsby\":{\"raw\":0.2418,\"normalized\":35,\"notes\":{}}},\"splitting\":{\"score\":0,\"county\":{\"raw\":1.1474,\"normalized\":0,\"notes\":{}},\"district\":{\"raw\":1.4839,\"normalized\":3,\"notes\":{}}},\"populationDeviation\":{\"raw\":0.016,\"normalized\":0,\"notes\":{\"maxDeviation\":11693}},\"details\":{\"countiesSplitUnexpectedly\":[\"Bladen\",\"Buncombe\",\"Catawba\",\"Cumberland\",\"Durham\",\"Guilford\",\"Iredell\",\"Johnston\",\"Pitt\",\"Rowan\",\"Wilson\"],\"unexpectedAffected\":0.3096,\"nSplitVTDs\":12,\"splitVTDs\":[\"VTD-01\",\"VTD-02\",\"VTD-03\",\"VTD-04\",\"VTD-05\",\"VTD-06\",\"VTD-07\",\"VTD-08\",\"VTD-09\",\"VTD-10\",\"VTD-11\",\"VTD-12\"],\"shapes\":\"2010 VTD shapes\",\"census\":\"2010 Census Total Population\"}},\"details\":{}}");
|
|
90878
|
-
|
|
90879
90910
|
/***/ })
|
|
90880
90911
|
|
|
90881
90912
|
/******/ });
|
|
@@ -102888,6 +102919,17 @@ class AnalyticsSession {
|
|
|
102888
102919
|
getPlanScorecard(bLog = false) {
|
|
102889
102920
|
return this._scorecard;
|
|
102890
102921
|
}
|
|
102922
|
+
getRatings(bLog = false) {
|
|
102923
|
+
const scorecard = this._scorecard;
|
|
102924
|
+
const r = {
|
|
102925
|
+
proportionality: scorecard.partisan.bias.score,
|
|
102926
|
+
competitiveness: scorecard.partisan.competitiveness.score,
|
|
102927
|
+
minorityRights: scorecard.minority.score,
|
|
102928
|
+
compactness: scorecard.traditionalPrinciples.compactness.score,
|
|
102929
|
+
splitting: scorecard.traditionalPrinciples.splitting.score
|
|
102930
|
+
};
|
|
102931
|
+
return r;
|
|
102932
|
+
}
|
|
102891
102933
|
// NOTE - This assumes that analyzePlan() has been run!
|
|
102892
102934
|
getRequirementsChecklist(bLog = false) {
|
|
102893
102935
|
return results_2.prepareRequirementsChecklist(this, bLog);
|