@dra2020/district-analytics 3.3.0 → 4.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/dist/cli.js +284 -102
- package/dist/cli.js.map +1 -1
- package/dist/district-analytics.js +24 -7
- package/dist/district-analytics.js.map +1 -1
- package/dist/src/types.d.ts +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -89797,10 +89797,10 @@ exports.scorePolsbyPopper = scorePolsbyPopper;
|
|
|
89797
89797
|
/*!*************************!*\
|
|
89798
89798
|
!*** ./src/config.json ***!
|
|
89799
89799
|
\*************************/
|
|
89800
|
-
/*! exports provided: partisan, traditionalPrinciples, default */
|
|
89800
|
+
/*! exports provided: partisan, minority, traditionalPrinciples, default */
|
|
89801
89801
|
/***/ (function(module) {
|
|
89802
89802
|
|
|
89803
|
-
module.exports = JSON.parse("{\"partisan\":{\"bias\":{\"range\":[0,0.2],\"weight\":[50,80]},\"impact\":{\"weight\":[50,0],\"threshold\":4},\"competitiveness\":{\"overall\":{\"range\":[0,0.67],\"weight\":25},\"marginal\":{\"range\":[0,0.85],\"weight\":75},\"range\":[0.45,0.55],\"distribution\":[0.25,0.75],\"weight\":[0,20]},\"weight\":[100,80]},\"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,1.71],\"allowableSplitsMultiplier\":1.5,\"weight\":50},\"district\":{\"range\":[1,1.5],\"weight\":50},\"weight\":[0,50]},\"popdev\":{\"range\":[[0.0075,0.002],[0.1,-1]],\"weight\":[0,0]},\"weight\":[0,20]}}");
|
|
89803
|
+
module.exports = JSON.parse("{\"partisan\":{\"bias\":{\"range\":[0,0.2],\"weight\":[50,80]},\"impact\":{\"weight\":[50,0],\"threshold\":4},\"competitiveness\":{\"overall\":{\"range\":[0,0.67],\"weight\":25},\"marginal\":{\"range\":[0,0.85],\"weight\":75},\"range\":[0.45,0.55],\"distribution\":[0.25,0.75],\"weight\":[0,20]},\"weight\":[100,80]},\"minority\":{\"range\":[0.37,0.5],\"distribution\":[0.25,0.75],\"shift\":0.12,\"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,1.71],\"allowableSplitsMultiplier\":1.5,\"weight\":50},\"district\":{\"range\":[1,1.5],\"weight\":50},\"weight\":[0,50]},\"popdev\":{\"range\":[[0.0075,0.002],[0.1,-1]],\"weight\":[0,0]},\"weight\":[0,20]}}");
|
|
89804
89804
|
|
|
89805
89805
|
/***/ }),
|
|
89806
89806
|
|
|
@@ -89883,6 +89883,32 @@ function overallCompetitivenessWeight(overridesJSON) {
|
|
|
89883
89883
|
return ocW;
|
|
89884
89884
|
}
|
|
89885
89885
|
exports.overallCompetitivenessWeight = overallCompetitivenessWeight;
|
|
89886
|
+
// MINORITY
|
|
89887
|
+
function minorityOpportunityRange(overridesJSON) {
|
|
89888
|
+
const range = config_json_1.default.minority.range;
|
|
89889
|
+
return range;
|
|
89890
|
+
}
|
|
89891
|
+
exports.minorityOpportunityRange = minorityOpportunityRange;
|
|
89892
|
+
function minorityOpportunityDistribution(overridesJSON) {
|
|
89893
|
+
const dist = config_json_1.default.minority.distribution;
|
|
89894
|
+
return dist;
|
|
89895
|
+
}
|
|
89896
|
+
exports.minorityOpportunityDistribution = minorityOpportunityDistribution;
|
|
89897
|
+
function minorityShift(overridesJSON) {
|
|
89898
|
+
const shift = config_json_1.default.minority.shift;
|
|
89899
|
+
return shift;
|
|
89900
|
+
}
|
|
89901
|
+
exports.minorityShift = minorityShift;
|
|
89902
|
+
function opportunityDistrictBonus(overridesJSON) {
|
|
89903
|
+
const bonus = config_json_1.default.minority.bonus;
|
|
89904
|
+
return bonus;
|
|
89905
|
+
}
|
|
89906
|
+
exports.opportunityDistrictBonus = opportunityDistrictBonus;
|
|
89907
|
+
function minorityBonus(overridesJSON) {
|
|
89908
|
+
const bonus = config_json_1.default.minority.bonus;
|
|
89909
|
+
return bonus;
|
|
89910
|
+
}
|
|
89911
|
+
exports.minorityBonus = minorityBonus;
|
|
89886
89912
|
// TRADITIONAL DISTRICTING PRINCIPLES
|
|
89887
89913
|
function compactnessWeight(context, overridesJSON) {
|
|
89888
89914
|
const cW = config_json_1.default.traditionalPrinciples.compactness.weight[context];
|
|
@@ -90068,8 +90094,136 @@ function __export(m) {
|
|
|
90068
90094
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
90069
90095
|
__export(__webpack_require__(/*! ./_api */ "./src/_api.ts"));
|
|
90070
90096
|
var types_1 = __webpack_require__(/*! ./types */ "./src/types.ts");
|
|
90071
|
-
exports.sampleProfile = types_1.sampleProfile;
|
|
90072
90097
|
exports.sampleScorecard = types_1.sampleScorecard;
|
|
90098
|
+
exports.sampleProfile = types_1.sampleProfile;
|
|
90099
|
+
|
|
90100
|
+
|
|
90101
|
+
/***/ }),
|
|
90102
|
+
|
|
90103
|
+
/***/ "./src/minority.ts":
|
|
90104
|
+
/*!*************************!*\
|
|
90105
|
+
!*** ./src/minority.ts ***!
|
|
90106
|
+
\*************************/
|
|
90107
|
+
/*! no static exports found */
|
|
90108
|
+
/***/ (function(module, exports, __webpack_require__) {
|
|
90109
|
+
|
|
90110
|
+
"use strict";
|
|
90111
|
+
|
|
90112
|
+
//
|
|
90113
|
+
// SCORING FOR MINORITY OPPORTUNITY
|
|
90114
|
+
//
|
|
90115
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
90116
|
+
if (mod && mod.__esModule) return mod;
|
|
90117
|
+
var result = {};
|
|
90118
|
+
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
|
90119
|
+
result["default"] = mod;
|
|
90120
|
+
return result;
|
|
90121
|
+
};
|
|
90122
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
90123
|
+
const U = __importStar(__webpack_require__(/*! ./utils */ "./src/utils.ts"));
|
|
90124
|
+
const C = __importStar(__webpack_require__(/*! ./config */ "./src/config.ts"));
|
|
90125
|
+
const normalize_1 = __webpack_require__(/*! ./normalize */ "./src/normalize.ts");
|
|
90126
|
+
const partisan_1 = __webpack_require__(/*! ./partisan */ "./src/partisan.ts");
|
|
90127
|
+
function evalMinorityOpportunity(p, bLog = false) {
|
|
90128
|
+
// Calculate average Democratic win share
|
|
90129
|
+
const VfArray = p.partisanProfile.vfArray;
|
|
90130
|
+
const DWins = VfArray.filter(x => x > 0.5);
|
|
90131
|
+
const averageDVf = (DWins.length > 0) ? U.avgArray(DWins) : undefined;
|
|
90132
|
+
// Determine proportional minority districts by demographic (ignore 'White')
|
|
90133
|
+
const districtsByDemo = calcDistrictsByDemo(p.demographicProfile.stateMfArray.slice(1), p.nDistricts);
|
|
90134
|
+
// Initialize arrays for results
|
|
90135
|
+
let offset = 1; // Don't process 'White'
|
|
90136
|
+
let nDemos = 6 /* Native */ + 1 - offset; // Ditto
|
|
90137
|
+
let nBuckets = 2; // 37–50% and > 50%
|
|
90138
|
+
const demosByDistrict = p.demographicProfile.mfArrayByDistrict;
|
|
90139
|
+
let bucketsByDemo = new Array(nDemos);
|
|
90140
|
+
for (let j = 0; j < nDemos; j++) {
|
|
90141
|
+
bucketsByDemo[j] = [0, 0];
|
|
90142
|
+
}
|
|
90143
|
+
let opptyByDemo = U.initArray(nDemos, 0.0);
|
|
90144
|
+
// For each district
|
|
90145
|
+
for (let i = 0; i < p.nDistricts; i++) {
|
|
90146
|
+
// Find the opportunities for minority representation
|
|
90147
|
+
for (let j = 0; j < nDemos; j++) {
|
|
90148
|
+
const proportion = U.deepCopy(demosByDistrict[i][j + offset]);
|
|
90149
|
+
if (exceedsMinimumThreshold(proportion)) {
|
|
90150
|
+
// Bucket opportunity districts
|
|
90151
|
+
const bucket = (exceedsMaximumThreshold(proportion)) ? 1 : 0;
|
|
90152
|
+
bucketsByDemo[j][bucket] += 1;
|
|
90153
|
+
// Accumulate seat probabilities
|
|
90154
|
+
opptyByDemo[j] += estMinorityOpportunity(proportion);
|
|
90155
|
+
}
|
|
90156
|
+
}
|
|
90157
|
+
}
|
|
90158
|
+
// Sum the # of level 1 (37–50%) and level 2 (> 50%) opportunity districts - ignore total minority
|
|
90159
|
+
let l1 = 0;
|
|
90160
|
+
let l2 = 0;
|
|
90161
|
+
bucketsByDemo.slice(1).forEach(function (buckets) {
|
|
90162
|
+
l1 += buckets[0 /* Level1 */];
|
|
90163
|
+
l2 += buckets[1 /* Level2 */];
|
|
90164
|
+
});
|
|
90165
|
+
// Sum the # of opportunity districts - ignore total minority
|
|
90166
|
+
const oD = U.sumArray(opptyByDemo.slice(1));
|
|
90167
|
+
// Sum the # of proportion districts - ignore total minority
|
|
90168
|
+
const pD = U.sumArray(districtsByDemo.slice(1));
|
|
90169
|
+
// Score opportunity
|
|
90170
|
+
const score = scoreMinority(oD, pD);
|
|
90171
|
+
let mS = {
|
|
90172
|
+
report: {
|
|
90173
|
+
averageDVf: averageDVf,
|
|
90174
|
+
bucketsByDemographic: bucketsByDemo
|
|
90175
|
+
},
|
|
90176
|
+
nOpportunity1: l1,
|
|
90177
|
+
nOpportunity2: l2,
|
|
90178
|
+
nProportional: pD,
|
|
90179
|
+
opportunityDistricts: oD,
|
|
90180
|
+
score: score
|
|
90181
|
+
};
|
|
90182
|
+
return mS;
|
|
90183
|
+
}
|
|
90184
|
+
exports.evalMinorityOpportunity = evalMinorityOpportunity;
|
|
90185
|
+
function scoreMinority(oD, pD) {
|
|
90186
|
+
const bonus = C.minorityBonus();
|
|
90187
|
+
const score = (pD > 0) ? Math.round((Math.min(oD, pD) / pD) * bonus) : 0;
|
|
90188
|
+
return score;
|
|
90189
|
+
}
|
|
90190
|
+
exports.scoreMinority = scoreMinority;
|
|
90191
|
+
function calcDistrictsByDemo(MfArray, N) {
|
|
90192
|
+
const districtsByDemo = MfArray.map(v => calcProportionalDistricts(v, N));
|
|
90193
|
+
return districtsByDemo;
|
|
90194
|
+
}
|
|
90195
|
+
exports.calcDistrictsByDemo = calcDistrictsByDemo;
|
|
90196
|
+
function estMinorityOpportunity(Mf) {
|
|
90197
|
+
const _normalizer = new normalize_1.Normalizer(Mf);
|
|
90198
|
+
// NOTE - Shift proportions, so 37% minority scores like 49% partisan
|
|
90199
|
+
const shift = C.minorityShift();
|
|
90200
|
+
_normalizer.wipNum += shift;
|
|
90201
|
+
const range = C.minorityOpportunityDistribution();
|
|
90202
|
+
const distBeg = range[C.BEG];
|
|
90203
|
+
const distEnd = range[C.END];
|
|
90204
|
+
_normalizer.clip(distBeg, distEnd);
|
|
90205
|
+
_normalizer.unitize(distBeg, distEnd);
|
|
90206
|
+
const oppty = partisan_1.estSeatProbability(_normalizer.wipNum, range);
|
|
90207
|
+
return oppty;
|
|
90208
|
+
}
|
|
90209
|
+
exports.estMinorityOpportunity = estMinorityOpportunity;
|
|
90210
|
+
// HELPERS
|
|
90211
|
+
function exceedsMinimumThreshold(Mf) {
|
|
90212
|
+
const threshold = C.minorityOpportunityRange()[C.BEG];
|
|
90213
|
+
return Mf >= threshold;
|
|
90214
|
+
}
|
|
90215
|
+
function exceedsMaximumThreshold(Mf) {
|
|
90216
|
+
const threshold = C.minorityOpportunityRange()[C.END];
|
|
90217
|
+
return Mf > threshold;
|
|
90218
|
+
}
|
|
90219
|
+
function calcProportionalDistricts(proportion, nDistricts) {
|
|
90220
|
+
// TODO - Bump up to get a statewide proportion on the bubble to rate one district?
|
|
90221
|
+
const roundUp = 0.0;
|
|
90222
|
+
const fractional = proportion * nDistricts;
|
|
90223
|
+
const integral = Math.round(fractional + roundUp);
|
|
90224
|
+
return integral;
|
|
90225
|
+
}
|
|
90226
|
+
exports.calcProportionalDistricts = calcProportionalDistricts;
|
|
90073
90227
|
|
|
90074
90228
|
|
|
90075
90229
|
/***/ }),
|
|
@@ -90196,85 +90350,88 @@ const normalize_1 = __webpack_require__(/*! ./normalize */ "./src/normalize.ts")
|
|
|
90196
90350
|
// NOTE - I'm passing T.VfArray's into everything. District indices = array indices.
|
|
90197
90351
|
// NOTE - I do not (cannot) assume that the values are sorted.
|
|
90198
90352
|
// SCORE BIAS & COMPETITIVENESS
|
|
90199
|
-
/* SCORECARD FIELDS
|
|
90200
|
-
|
|
90201
|
-
* ^S# [
|
|
90202
|
-
* ^S% [
|
|
90203
|
-
* S! [
|
|
90204
|
-
* S# [
|
|
90205
|
-
* S% [
|
|
90206
|
-
*
|
|
90207
|
-
* B
|
|
90208
|
-
|
|
90209
|
-
|
|
90210
|
-
*
|
|
90211
|
-
|
|
90212
|
-
*
|
|
90213
|
-
|
|
90214
|
-
*
|
|
90215
|
-
|
|
90216
|
-
*
|
|
90217
|
-
*
|
|
90218
|
-
*
|
|
90219
|
-
*
|
|
90220
|
-
*
|
|
90221
|
-
|
|
90222
|
-
*
|
|
90353
|
+
/* SCORECARD FIELDS
|
|
90354
|
+
|
|
90355
|
+
* ^S# [bestS] = the Democratic seats closest to proportional
|
|
90356
|
+
* ^S% [bestSf] = the corresponding Democratic seat share
|
|
90357
|
+
* S! [fptpS] = the estimated number of Democratic seats using first past the post
|
|
90358
|
+
* S# [probableS] = the estimated Democratic seats, using seat probabilities
|
|
90359
|
+
* S% [probableSf] = the estimated Democratic seat share fraction, calculated as S# / N
|
|
90360
|
+
* B% [bias]= the bias calculated as S% – ^S%
|
|
90361
|
+
* B$ [bias.score] = the bias score normalized [0–100]
|
|
90362
|
+
|
|
90363
|
+
* UE# [unearnedS] = the number of unearned seats (R = positive; D = negative)
|
|
90364
|
+
* I$ [impact.score] -- the unearned seats normalized [0–100] as impact
|
|
90365
|
+
|
|
90366
|
+
* R# [r] = the responsiveness at V%
|
|
90367
|
+
* rD [rD] = the estimated # of responsive districts (using probabilities)
|
|
90368
|
+
* rD% [rDf] = the estimated # of responsive districts, as a fraction of N
|
|
90369
|
+
|
|
90370
|
+
* C [c] = the number of districts that fall into the range [45–55%]
|
|
90371
|
+
* cD [cD] = the estimated # of competitive districts, using probabilities & a narrower [0.25–0.75] range
|
|
90372
|
+
* cD% [cDf] = the estimated # of competitive districts, as a fraction of N
|
|
90373
|
+
* beg/end [mRange] = the 1–N indices for the first and last district that separate the likely result and the proportional result
|
|
90374
|
+
* Md [mD] = the competitiveness of the marginal districts
|
|
90375
|
+
* Md% [mDf] = the probability that the marginal seats will flip, so S% => ^S%
|
|
90376
|
+
* C$ [competitiveness.score] = the competitiveness score normalized [0–100]
|
|
90377
|
+
|
|
90378
|
+
* <P$ [score] = the combined partisan score used to compare plans *across* states
|
|
90379
|
+
* >P$ [score2] = the combined partisan score used to compare plans *within* a state, along with traditional districting principles
|
|
90223
90380
|
|
|
90224
90381
|
*/
|
|
90225
90382
|
function scorePartisan(Vf, VfArray, bAll = false, bConstrained = true) {
|
|
90226
90383
|
const N = VfArray.length;
|
|
90227
|
-
const
|
|
90228
|
-
const
|
|
90229
|
-
const
|
|
90384
|
+
const bestS = bestSeats(N, Vf);
|
|
90385
|
+
const bestSf = bestSeatShare(bestS, N);
|
|
90386
|
+
const fptpS = bAll ? estFPTPSeats(VfArray) : undefined;
|
|
90230
90387
|
const range = bConstrained ? C.competitiveDistribution() : undefined;
|
|
90231
|
-
const
|
|
90232
|
-
const
|
|
90233
|
-
const
|
|
90234
|
-
const biasScore =
|
|
90235
|
-
const
|
|
90236
|
-
const impactScore = scoreImpact(
|
|
90388
|
+
const probableS = estprobableSeats(VfArray, range);
|
|
90389
|
+
const probableSf = estprobableSeatShare(probableS, N);
|
|
90390
|
+
const bias = estbias(probableSf, bestSf);
|
|
90391
|
+
const biasScore = scorebias(bias, Vf, probableSf, N);
|
|
90392
|
+
const unearnedS = estunearnedSeats(bestS, probableS);
|
|
90393
|
+
const impactScore = scoreImpact(unearnedS);
|
|
90237
90394
|
const bInferSV = (bAll || (!bConstrained));
|
|
90238
90395
|
const inferredSVpoints = bInferSV ? inferSVpoints(Vf, VfArray, range) : undefined;
|
|
90239
90396
|
const R = bInferSV ? estResponsiveness(Vf, inferredSVpoints) : undefined;
|
|
90240
|
-
const
|
|
90241
|
-
const
|
|
90397
|
+
const rD = bInferSV ? estResponsiveDistricts(VfArray) : undefined;
|
|
90398
|
+
const rDf = bInferSV ? estResponsiveDistrictsShare(rD, N) : undefined;
|
|
90242
90399
|
const Cn = countCompetitiveDistricts(VfArray);
|
|
90243
|
-
const
|
|
90244
|
-
const
|
|
90400
|
+
const cD = bConstrained ? estCompetitiveDistricts(VfArray) : rD;
|
|
90401
|
+
const cDf = estCompetitiveDistrictsShare(cD, N);
|
|
90245
90402
|
const Mrange = findMarginalDistricts(Vf, VfArray, N);
|
|
90246
90403
|
const Md = estMarginalCompetitiveDistricts(Mrange, VfArray);
|
|
90247
90404
|
const Mdf = estMarginalCompetitiveShare(Md, Mrange);
|
|
90248
|
-
const competitivenessScore = scoreCompetitiveness(Mdf,
|
|
90405
|
+
const competitivenessScore = scoreCompetitiveness(Mdf, cDf);
|
|
90249
90406
|
const biasScoring = {
|
|
90250
|
-
|
|
90251
|
-
|
|
90252
|
-
|
|
90253
|
-
|
|
90254
|
-
|
|
90255
|
-
|
|
90407
|
+
bestS: bestS,
|
|
90408
|
+
bestSf: bestSf,
|
|
90409
|
+
fptpS: fptpS,
|
|
90410
|
+
probableS: probableS,
|
|
90411
|
+
probableSf: probableSf,
|
|
90412
|
+
bias: bias,
|
|
90256
90413
|
score: biasScore
|
|
90257
90414
|
};
|
|
90258
90415
|
const impactScoring = {
|
|
90259
|
-
|
|
90416
|
+
unearnedS: unearnedS,
|
|
90260
90417
|
score: impactScore
|
|
90261
90418
|
};
|
|
90262
90419
|
let competitiveScoring = {
|
|
90263
|
-
|
|
90264
|
-
|
|
90265
|
-
|
|
90266
|
-
|
|
90267
|
-
|
|
90268
|
-
|
|
90269
|
-
|
|
90270
|
-
|
|
90271
|
-
|
|
90420
|
+
r: R,
|
|
90421
|
+
rD: rD,
|
|
90422
|
+
rDf: rDf,
|
|
90423
|
+
c: Cn,
|
|
90424
|
+
cD: cD,
|
|
90425
|
+
cDf: cDf,
|
|
90426
|
+
mRange: Mrange,
|
|
90427
|
+
mD: Md,
|
|
90428
|
+
mDf: Mdf,
|
|
90272
90429
|
score: competitivenessScore
|
|
90273
90430
|
};
|
|
90274
90431
|
if (bAll) {
|
|
90275
|
-
competitiveScoring.
|
|
90276
|
-
competitiveScoring.
|
|
90277
|
-
competitiveScoring.
|
|
90432
|
+
competitiveScoring.r = R;
|
|
90433
|
+
competitiveScoring.rD = rD;
|
|
90434
|
+
competitiveScoring.rDf = rDf;
|
|
90278
90435
|
}
|
|
90279
90436
|
// Weight bias, impact, and competitiveness into partisan scores to compare
|
|
90280
90437
|
// plans across states and within a state.
|
|
@@ -90306,15 +90463,15 @@ function printPartisanScorecardHeader() {
|
|
|
90306
90463
|
}
|
|
90307
90464
|
exports.printPartisanScorecardHeader = printPartisanScorecardHeader;
|
|
90308
90465
|
function printPartisanScorecardRow(xx, name, N, Vf, s) {
|
|
90309
|
-
console.log('%s, %s, %i, %f, %f, %i, %f, %i, %f, %f, %f, %i, %f, %i, %f, %f, %f, %i, %f, %f, %i, %i, %f, %f, %i, %i, %i', xx, name, N, U.trim(1 / N), Vf, s.bias.
|
|
90466
|
+
console.log('%s, %s, %i, %f, %f, %i, %f, %i, %f, %f, %f, %i, %f, %i, %f, %f, %f, %i, %f, %f, %i, %i, %f, %f, %i, %i, %i', xx, name, N, U.trim(1 / N), Vf, s.bias.bestS, s.bias.bestSf, s.bias.fptpS, s.bias.probableS, s.bias.probableSf, s.bias.bias, s.bias.score, s.impact.unearnedS, s.impact.score, s.competitiveness.r, s.competitiveness.rD, s.competitiveness.rDf, s.competitiveness.c, s.competitiveness.cD, s.competitiveness.cDf, s.competitiveness.mRange[C.BEG], s.competitiveness.mRange[C.END], s.competitiveness.mD, s.competitiveness.mDf, s.competitiveness.score, s.score, s.score2);
|
|
90310
90467
|
}
|
|
90311
90468
|
exports.printPartisanScorecardRow = printPartisanScorecardRow;
|
|
90312
|
-
function
|
|
90469
|
+
function scorebias(rawbias, Vf, Sf, N) {
|
|
90313
90470
|
if (isAntimajoritarian(Vf, Sf)) {
|
|
90314
90471
|
return 0;
|
|
90315
90472
|
}
|
|
90316
90473
|
else {
|
|
90317
|
-
const _normalizer = new normalize_1.Normalizer(
|
|
90474
|
+
const _normalizer = new normalize_1.Normalizer(rawbias);
|
|
90318
90475
|
const worst = C.biasRange()[C.BEG];
|
|
90319
90476
|
const best = C.biasRange()[C.END];
|
|
90320
90477
|
_normalizer.clip(worst, best);
|
|
@@ -90326,7 +90483,7 @@ function scoreBias(rawBias, Vf, Sf, N) {
|
|
|
90326
90483
|
return score;
|
|
90327
90484
|
}
|
|
90328
90485
|
}
|
|
90329
|
-
exports.
|
|
90486
|
+
exports.scorebias = scorebias;
|
|
90330
90487
|
// Normalize unearned seats
|
|
90331
90488
|
function scoreImpact(rawUE) {
|
|
90332
90489
|
const _normalizer = new normalize_1.Normalizer(rawUE);
|
|
@@ -90412,7 +90569,7 @@ function inferSVpoints(Vf, VfArray, range) {
|
|
|
90412
90569
|
let SVpoints = [];
|
|
90413
90570
|
for (let shiftedVf of shiftRange()) {
|
|
90414
90571
|
const shiftedVPI = shiftDistricts(Vf, VfArray, shiftedVf);
|
|
90415
|
-
const shiftedSf =
|
|
90572
|
+
const shiftedSf = estprobableSeats(shiftedVPI, range) / nDistricts;
|
|
90416
90573
|
SVpoints.push({ v: shiftedVf, s: shiftedSf });
|
|
90417
90574
|
}
|
|
90418
90575
|
return SVpoints;
|
|
@@ -90461,16 +90618,16 @@ function bestSeatShare(bestS, N) {
|
|
|
90461
90618
|
}
|
|
90462
90619
|
exports.bestSeatShare = bestSeatShare;
|
|
90463
90620
|
// S# - The estimated # of Democratic seats @ statewide Vf, using seat probabilities
|
|
90464
|
-
function
|
|
90621
|
+
function estprobableSeats(VfArray, range) {
|
|
90465
90622
|
// Python: sum([est_seat_probability(vpi) for vpi in vpi_by_district])
|
|
90466
90623
|
return U.trim(U.sumArray(VfArray.map(v => estSeatProbability(v, range))));
|
|
90467
90624
|
}
|
|
90468
|
-
exports.
|
|
90625
|
+
exports.estprobableSeats = estprobableSeats;
|
|
90469
90626
|
// S% - The estimated Democratic seat share fraction @ statewide Vf
|
|
90470
|
-
function
|
|
90627
|
+
function estprobableSeatShare(probableS, N) {
|
|
90471
90628
|
return U.trim(probableS / N);
|
|
90472
90629
|
}
|
|
90473
|
-
exports.
|
|
90630
|
+
exports.estprobableSeatShare = estprobableSeatShare;
|
|
90474
90631
|
// F# - The estimated number of Democratic seats using first past the post
|
|
90475
90632
|
function estFPTPSeats(VfArray) {
|
|
90476
90633
|
// Python: sum([1.0 for vpi in vpi_by_district if (vpi > 0.5)])
|
|
@@ -90485,17 +90642,17 @@ function estFPTPSeats(VfArray) {
|
|
|
90485
90642
|
}
|
|
90486
90643
|
exports.estFPTPSeats = estFPTPSeats;
|
|
90487
90644
|
// B% - Tthe bias calculated as S% – ^S%
|
|
90488
|
-
function
|
|
90645
|
+
function estbias(estSeatShare, bestSeatShare) {
|
|
90489
90646
|
return U.trim(Math.abs(estSeatShare - bestSeatShare));
|
|
90490
90647
|
}
|
|
90491
|
-
exports.
|
|
90648
|
+
exports.estbias = estbias;
|
|
90492
90649
|
// UE# - The estimated # of unearned seats
|
|
90493
90650
|
// UE_# from http://bit.ly/2Fcuf4q
|
|
90494
|
-
function
|
|
90651
|
+
function estunearnedSeats(best, probable) {
|
|
90495
90652
|
// NOTE - + values = unearned R seats; – values = unearned D seats
|
|
90496
90653
|
return U.trim(best - probable);
|
|
90497
90654
|
}
|
|
90498
|
-
exports.
|
|
90655
|
+
exports.estunearnedSeats = estunearnedSeats;
|
|
90499
90656
|
// ESTIMATE RESPONSIVENESS ("COMPETITIVE")
|
|
90500
90657
|
// R# - Estimate responsiveness at the statewide vote share
|
|
90501
90658
|
function estResponsiveness(Vf, inferredSVpoints) {
|
|
@@ -90538,15 +90695,15 @@ function findUpperBracket(Vf, inferredSVpoints) {
|
|
|
90538
90695
|
}
|
|
90539
90696
|
return upperPt;
|
|
90540
90697
|
}
|
|
90541
|
-
//
|
|
90698
|
+
// rD - Estimate the number of responsive districts, given a set of Vf's
|
|
90542
90699
|
function estResponsiveDistricts(VfArray) {
|
|
90543
90700
|
// Python: sum([est_district_responsiveness(vpi) for vpi in vpi_by_district])
|
|
90544
90701
|
return U.trim(U.sumArray(VfArray.map(v => estDistrictResponsiveness(v))));
|
|
90545
90702
|
}
|
|
90546
90703
|
exports.estResponsiveDistricts = estResponsiveDistricts;
|
|
90547
|
-
//
|
|
90548
|
-
function estResponsiveDistrictsShare(
|
|
90549
|
-
return U.trim(
|
|
90704
|
+
// rD% - The estimated # of responsive districts, as a fraction of N
|
|
90705
|
+
function estResponsiveDistrictsShare(rD, N) {
|
|
90706
|
+
return U.trim(rD / N);
|
|
90550
90707
|
}
|
|
90551
90708
|
exports.estResponsiveDistrictsShare = estResponsiveDistrictsShare;
|
|
90552
90709
|
// ESTIMATE COMPETITIVENESS (ENHANCED)
|
|
@@ -90558,7 +90715,7 @@ exports.countCompetitiveDistricts = countCompetitiveDistricts;
|
|
|
90558
90715
|
function isCompetitive(v) {
|
|
90559
90716
|
return ((v >= C.competitiveRange()[C.BEG]) && (v <= C.competitiveRange()[C.END])) ? 1 : 0;
|
|
90560
90717
|
}
|
|
90561
|
-
//
|
|
90718
|
+
// cD - The estimated # of competitive districts
|
|
90562
90719
|
function estCompetitiveDistricts(VfArray) {
|
|
90563
90720
|
return U.trim(U.sumArray(VfArray.map(v => estDistrictCompetitiveness(v))));
|
|
90564
90721
|
}
|
|
@@ -90578,9 +90735,9 @@ function estDistrictCompetitiveness(Vf) {
|
|
|
90578
90735
|
return dC;
|
|
90579
90736
|
}
|
|
90580
90737
|
exports.estDistrictCompetitiveness = estDistrictCompetitiveness;
|
|
90581
|
-
//
|
|
90582
|
-
function estCompetitiveDistrictsShare(
|
|
90583
|
-
return U.trim(
|
|
90738
|
+
// cD% - The estimated # of competitive districts, as a fraction of N
|
|
90739
|
+
function estCompetitiveDistrictsShare(cD, N) {
|
|
90740
|
+
return U.trim(cD / N);
|
|
90584
90741
|
}
|
|
90585
90742
|
exports.estCompetitiveDistrictsShare = estCompetitiveDistrictsShare;
|
|
90586
90743
|
// Md - The estimated # of "marginal" districts in and around the likely FPTP
|
|
@@ -90653,17 +90810,18 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
90653
90810
|
};
|
|
90654
90811
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
90655
90812
|
const U = __importStar(__webpack_require__(/*! ./utils */ "./src/utils.ts"));
|
|
90813
|
+
const S = __importStar(__webpack_require__(/*! ./settings */ "./src/settings.ts"));
|
|
90656
90814
|
const C = __importStar(__webpack_require__(/*! ./config */ "./src/config.ts"));
|
|
90657
90815
|
const compact_1 = __webpack_require__(/*! ./compact */ "./src/compact.ts");
|
|
90658
90816
|
const cohesive_1 = __webpack_require__(/*! ./cohesive */ "./src/cohesive.ts");
|
|
90659
90817
|
const equal_1 = __webpack_require__(/*! ./equal */ "./src/equal.ts");
|
|
90660
90818
|
const partisan_1 = __webpack_require__(/*! ./partisan */ "./src/partisan.ts");
|
|
90661
|
-
|
|
90819
|
+
const minority_1 = __webpack_require__(/*! ./minority */ "./src/minority.ts");
|
|
90662
90820
|
function scorePlan(p, overridesJSON) {
|
|
90663
90821
|
// TRADITIONAL DISTRICTING PRINCIPLES ("best") subcategories - compactness, splitting, population deviation
|
|
90664
90822
|
// Compactness
|
|
90665
|
-
const reockM = compact_1.doReock(p.compactnessProfile.
|
|
90666
|
-
const polsbyM = compact_1.doPolsbyPopper(p.compactnessProfile.
|
|
90823
|
+
const reockM = compact_1.doReock(p.compactnessProfile.geometryByDistrict);
|
|
90824
|
+
const polsbyM = compact_1.doPolsbyPopper(p.compactnessProfile.geometryByDistrict);
|
|
90667
90825
|
const compactnessScore = weightCompactness(reockM.normalized, polsbyM.normalized);
|
|
90668
90826
|
const cS = {
|
|
90669
90827
|
score: compactnessScore,
|
|
@@ -90671,7 +90829,7 @@ function scorePlan(p, overridesJSON) {
|
|
|
90671
90829
|
polsby: polsbyM
|
|
90672
90830
|
};
|
|
90673
90831
|
// Splitting
|
|
90674
|
-
const CxD = p.splittingProfile.
|
|
90832
|
+
const CxD = p.splittingProfile.countyPopByDistrict;
|
|
90675
90833
|
const dT = cohesive_1.totalDistricts(CxD);
|
|
90676
90834
|
const cT = cohesive_1.totalCounties(CxD);
|
|
90677
90835
|
const countyM = cohesive_1.doCountySplittingReduced(CxD, dT, cT);
|
|
@@ -90683,7 +90841,7 @@ function scorePlan(p, overridesJSON) {
|
|
|
90683
90841
|
district: districtM
|
|
90684
90842
|
};
|
|
90685
90843
|
// Population deviation
|
|
90686
|
-
const pdS = equal_1.doPopulationDeviation(p.populationProfile.
|
|
90844
|
+
const pdS = equal_1.doPopulationDeviation(p.populationProfile.totalPopByDistrict, p.populationProfile.targetSize, p.legislativeDistricts);
|
|
90687
90845
|
// Combine traditional principles into a score to compare plans w/in a state
|
|
90688
90846
|
const tpScore = weightTradtionalPrinciples(cS.score, sS.score, pdS.normalized, 1 /* WithinAState */);
|
|
90689
90847
|
// Populate the "best" traditional principles scorecard
|
|
@@ -90694,13 +90852,17 @@ function scorePlan(p, overridesJSON) {
|
|
|
90694
90852
|
populationDeviation: pdS
|
|
90695
90853
|
};
|
|
90696
90854
|
// PARTISAN ("fair") subcategories - bias, impact, & competitiveness (plus lots of supporting measures)
|
|
90697
|
-
const pS = partisan_1.scorePartisan(p.partisanProfile.statewideVf, p.partisanProfile.
|
|
90855
|
+
const pS = partisan_1.scorePartisan(p.partisanProfile.statewideVf, p.partisanProfile.vfArray);
|
|
90698
90856
|
// Combine the partisan/partisan & traditional principles/best scores into an overall
|
|
90699
90857
|
// score for comparing plans w/in a state
|
|
90700
|
-
|
|
90858
|
+
let score = weightOverall(pS.score2, tpS.score, 1 /* WithinAState */);
|
|
90859
|
+
const mS = minority_1.evalMinorityOpportunity(p);
|
|
90860
|
+
// Add minority bonus, keeping score it to the range [0–100]
|
|
90861
|
+
score = mixinMinorityBonus(score, mS.score);
|
|
90701
90862
|
// Roll up an overall scorecard
|
|
90702
90863
|
const scorecard = {
|
|
90703
90864
|
partisan: pS,
|
|
90865
|
+
minority: mS,
|
|
90704
90866
|
traditionalPrinciples: tpS,
|
|
90705
90867
|
score: score
|
|
90706
90868
|
};
|
|
@@ -90730,19 +90892,24 @@ function weightTradtionalPrinciples(cS, sS, pdS, context) {
|
|
|
90730
90892
|
return score;
|
|
90731
90893
|
}
|
|
90732
90894
|
exports.weightTradtionalPrinciples = weightTradtionalPrinciples;
|
|
90733
|
-
function
|
|
90895
|
+
function weightOverall(pS, tpS, context) {
|
|
90734
90896
|
const pW = C.partisanWeight(context);
|
|
90735
90897
|
const tpW = C.traditionalPrinciplesWeight(context);
|
|
90736
90898
|
const score = Math.round(((pS * pW) + (tpS * tpW)) / (pW + tpW));
|
|
90737
90899
|
return score;
|
|
90738
90900
|
}
|
|
90739
|
-
exports.
|
|
90901
|
+
exports.weightOverall = weightOverall;
|
|
90902
|
+
function mixinMinorityBonus(score, minorityBonus) {
|
|
90903
|
+
const modifiedScore = Math.min(score + minorityBonus, S.NORMALIZED_RANGE);
|
|
90904
|
+
return modifiedScore;
|
|
90905
|
+
}
|
|
90906
|
+
exports.mixinMinorityBonus = mixinMinorityBonus;
|
|
90740
90907
|
function printScorecardHeader() {
|
|
90741
|
-
console.log('XX, Name, N, V%, ^S#, S#, B%, B$, UE#, I$, C#, Cd, Md, C$, <P$, >P$, Rc, Rc$, Pc, Pc$, G$, Cs, Cs$, Ds, Ds$, S$, Eq, Eq$, T$, $$$');
|
|
90908
|
+
console.log('XX, Name, N, V%, ^S#, S#, B%, B$, UE#, I$, C#, Cd, Md, C$, <P$, >P$, Rc, Rc$, Pc, Pc$, G$, Cs, Cs$, Ds, Ds$, S$, Eq, Eq$, T$, O1, O2, Od, Pd, M$, $$$');
|
|
90742
90909
|
}
|
|
90743
90910
|
exports.printScorecardHeader = printScorecardHeader;
|
|
90744
90911
|
function printScorecardRow(xx, name, N, Vf, s) {
|
|
90745
|
-
console.log('%s, %s, %i, %f, %i, %f, %f, %i, %f, %i, %i, %f, %f, %i, %i, %i, %f, %i, %f, %i, %i, %f, %i, %f, %i, %i, %f, %i, %i, %i', xx, name, N, U.trim(Vf), s.partisan.bias.
|
|
90912
|
+
console.log('%s, %s, %i, %f, %i, %f, %f, %i, %f, %i, %i, %f, %f, %i, %i, %i, %f, %i, %f, %i, %i, %f, %i, %f, %i, %i, %f, %i, %i, %i, %i, %f, %i, %i, %i', xx, name, N, U.trim(Vf), s.partisan.bias.bestS, s.partisan.bias.probableS, s.partisan.bias.bias, s.partisan.bias.score, s.partisan.impact.unearnedS, s.partisan.impact.score, s.partisan.competitiveness.c, s.partisan.competitiveness.cD, s.partisan.competitiveness.mD, s.partisan.competitiveness.score, s.partisan.score, s.partisan.score2, 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.nOpportunity1, s.minority.nOpportunity2, s.minority.opportunityDistricts, s.minority.nProportional, s.minority.score, s.score);
|
|
90746
90913
|
}
|
|
90747
90914
|
exports.printScorecardRow = printScorecardRow;
|
|
90748
90915
|
|
|
@@ -90886,7 +91053,7 @@ exports.deepCopy = deepCopy;
|
|
|
90886
91053
|
/*! exports provided: state, planName, nDistricts, nCounties, legislativeDistricts, populationProfile, compactnessProfile, splittingProfile, partisanProfile, demographicProfile, default */
|
|
90887
91054
|
/***/ (function(module) {
|
|
90888
91055
|
|
|
90889
|
-
module.exports = JSON.parse("{\"state\":\"NC\",\"planName\":\"
|
|
91056
|
+
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]]}}");
|
|
90890
91057
|
|
|
90891
91058
|
/***/ }),
|
|
90892
91059
|
|
|
@@ -90894,10 +91061,10 @@ module.exports = JSON.parse("{\"state\":\"NC\",\"planName\":\"Sample profile\",\
|
|
|
90894
91061
|
/*!************************************************!*\
|
|
90895
91062
|
!*** ./testdata/samples/sample-scorecard.json ***!
|
|
90896
91063
|
\************************************************/
|
|
90897
|
-
/*! exports provided: score,
|
|
91064
|
+
/*! exports provided: score, partisan, minority, traditionalPrinciples, default */
|
|
90898
91065
|
/***/ (function(module) {
|
|
90899
91066
|
|
|
90900
|
-
module.exports = JSON.parse("{\"score\":5,\"
|
|
91067
|
+
module.exports = JSON.parse("{\"score\":5,\"partisan\":{\"bias\":{\"bestS\":7,\"bestSf\":0.5385,\"probableS\":4.1925,\"probableSf\":0.3225,\"bias\":0.216,\"score\":0},\"impact\":{\"unearnedS\":2.8075,\"score\":0},\"competitiveness\":{\"c\":6,\"cD\":0.7266,\"cDf\":0.0559,\"mRange\":[5,11],\"mD\":0.7134,\"mDf\":0.1019,\"score\":10},\"score\":3,\"score2\":2},\"minority\":{\"report\":{\"bucketsByDemographic\":[[10,14],[3,0],[1,9],[0,0],[0,0],[0,0]],\"averageDVf\":0.6737588682747838},\"nOpportunity1\":4,\"nOpportunity2\":9,\"nProportional\":18,\"opportunityDistricts\":12.9424,\"score\":14},\"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}}}}");
|
|
90901
91068
|
|
|
90902
91069
|
/***/ })
|
|
90903
91070
|
|
|
@@ -103143,7 +103310,8 @@ function profilePlan(s, bLog = false) {
|
|
|
103143
103310
|
const summaryRow = s.districts.numberOfRows() - 1;
|
|
103144
103311
|
const statewideVf = U.trim(s.districts.statistics[D.DistrictField.DemPct][summaryRow], 6);
|
|
103145
103312
|
const vpiArray = U.deepCopy(s.districts.statistics[D.DistrictField.DemPct].slice(1, -1));
|
|
103146
|
-
const
|
|
103313
|
+
const statewideDemographics = getStatewideDemographics(s);
|
|
103314
|
+
const demographicsByDistrict = getDemographicsByDistrict(s);
|
|
103147
103315
|
const profile = {
|
|
103148
103316
|
state: state,
|
|
103149
103317
|
planName: planName,
|
|
@@ -103151,21 +103319,22 @@ function profilePlan(s, bLog = false) {
|
|
|
103151
103319
|
nCounties: nCounties,
|
|
103152
103320
|
legislativeDistricts: s.legislativeDistricts,
|
|
103153
103321
|
populationProfile: {
|
|
103154
|
-
|
|
103322
|
+
totalPopByDistrict: popByDistrict,
|
|
103155
103323
|
targetSize: targetSize
|
|
103156
103324
|
},
|
|
103157
103325
|
compactnessProfile: {
|
|
103158
|
-
|
|
103326
|
+
geometryByDistrict: geoPropsByDistrict
|
|
103159
103327
|
},
|
|
103160
103328
|
splittingProfile: {
|
|
103161
|
-
|
|
103329
|
+
countyPopByDistrict: splits
|
|
103162
103330
|
},
|
|
103163
103331
|
partisanProfile: {
|
|
103164
103332
|
statewideVf: statewideVf,
|
|
103165
|
-
|
|
103333
|
+
vfArray: vpiArray
|
|
103166
103334
|
},
|
|
103167
103335
|
demographicProfile: {
|
|
103168
|
-
|
|
103336
|
+
stateMfArray: statewideDemographics,
|
|
103337
|
+
mfArrayByDistrict: demographicsByDistrict
|
|
103169
103338
|
}
|
|
103170
103339
|
};
|
|
103171
103340
|
return profile;
|
|
@@ -103199,7 +103368,7 @@ function makeArrayOfGeoProps(s, bLog = false) {
|
|
|
103199
103368
|
}
|
|
103200
103369
|
return geometryByDistrict;
|
|
103201
103370
|
}
|
|
103202
|
-
function
|
|
103371
|
+
function getDemographicsByDistrict(s, bLog = false) {
|
|
103203
103372
|
let demographicsArray = [];
|
|
103204
103373
|
// Remove the unassigned & total dummy "districts"
|
|
103205
103374
|
for (let districtID = 1; districtID <= s.state.nDistricts; districtID++) {
|
|
@@ -103216,6 +103385,19 @@ function makeArrayOfDemographics(s, bLog = false) {
|
|
|
103216
103385
|
}
|
|
103217
103386
|
return demographicsArray;
|
|
103218
103387
|
}
|
|
103388
|
+
function getStatewideDemographics(s, bLog = false) {
|
|
103389
|
+
const summaryRow = s.districts.numberOfRows() - 1;
|
|
103390
|
+
const demographicsArray = [
|
|
103391
|
+
U.deepCopy(s.districts.statistics[D.DistrictField.WhitePct][summaryRow]),
|
|
103392
|
+
U.deepCopy(s.districts.statistics[D.DistrictField.MinorityPct][summaryRow]),
|
|
103393
|
+
U.deepCopy(s.districts.statistics[D.DistrictField.BlackPct][summaryRow]),
|
|
103394
|
+
U.deepCopy(s.districts.statistics[D.DistrictField.HispanicPct][summaryRow]),
|
|
103395
|
+
U.deepCopy(s.districts.statistics[D.DistrictField.PacificPct][summaryRow]),
|
|
103396
|
+
U.deepCopy(s.districts.statistics[D.DistrictField.AsianPct][summaryRow]),
|
|
103397
|
+
U.deepCopy(s.districts.statistics[D.DistrictField.NativePct][summaryRow])
|
|
103398
|
+
];
|
|
103399
|
+
return demographicsArray;
|
|
103400
|
+
}
|
|
103219
103401
|
// SCORE A PLAN
|
|
103220
103402
|
function scorePlan(s, p, bLog = false, overridesJSON) {
|
|
103221
103403
|
let scorer = new Score.Scorer();
|