@dra2020/district-analytics 7.1.7 → 8.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 +42 -34
- package/dist/cli.js.map +1 -1
- 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
|
@@ -89056,7 +89056,7 @@ exports.scorePolsbyPopper = scorePolsbyPopper;
|
|
|
89056
89056
|
/*! exports provided: partisan, minority, compactness, splitting, popdev, default */
|
|
89057
89057
|
/***/ (function(module) {
|
|
89058
89058
|
|
|
89059
|
-
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},\"minority\":{\"range\":[0.37,0.5],\"distribution\":[0.25,0.75],\"shift\":0.15,\"coalition\":{\"weight\":0.5}},\"compactness\":{\"reock\":{\"range\":[0.25,0.5],\"weight\":50},\"polsby\":{\"range\":[0.1,0.5],\"weight\":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}},\"popdev\":{\"range\":[[0.0075,0.002],[0.1,-1]]}}");
|
|
89059
|
+
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},\"minority\":{\"range\":[0.37,0.5],\"distribution\":[0.25,0.75],\"shift\":[0.15,0.5],\"coalition\":{\"weight\":0.5}},\"compactness\":{\"reock\":{\"range\":[0.25,0.5],\"weight\":50},\"polsby\":{\"range\":[0.1,0.5],\"weight\":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}},\"popdev\":{\"range\":[[0.0075,0.002],[0.1,-1]]}}");
|
|
89060
89060
|
|
|
89061
89061
|
/***/ }),
|
|
89062
89062
|
|
|
@@ -89160,11 +89160,20 @@ function minorityOpportunityDistribution(overridesJSON) {
|
|
|
89160
89160
|
return dist;
|
|
89161
89161
|
}
|
|
89162
89162
|
exports.minorityOpportunityDistribution = minorityOpportunityDistribution;
|
|
89163
|
+
// For Black VAP %
|
|
89163
89164
|
function minorityShift(overridesJSON) {
|
|
89164
|
-
const
|
|
89165
|
+
const BLACK = 0;
|
|
89166
|
+
const shift = config_json_1.default.minority.shift[BLACK];
|
|
89165
89167
|
return shift;
|
|
89166
89168
|
}
|
|
89167
89169
|
exports.minorityShift = minorityShift;
|
|
89170
|
+
// Dilution for other demos
|
|
89171
|
+
function minorityShiftDilution(overridesJSON) {
|
|
89172
|
+
const DILUTION = 1;
|
|
89173
|
+
const shift = config_json_1.default.minority.shift[DILUTION];
|
|
89174
|
+
return shift;
|
|
89175
|
+
}
|
|
89176
|
+
exports.minorityShiftDilution = minorityShiftDilution;
|
|
89168
89177
|
function coalitionDistrictWeight(overridesJSON) {
|
|
89169
89178
|
const weight = config_json_1.default.minority.coalition.weight;
|
|
89170
89179
|
return weight;
|
|
@@ -89357,47 +89366,36 @@ const normalize_1 = __webpack_require__(/*! ./normalize */ "./src/normalize.ts")
|
|
|
89357
89366
|
const partisan_1 = __webpack_require__(/*! ./partisan */ "./src/partisan.ts");
|
|
89358
89367
|
function evalMinorityOpportunity(p, bLog = false) {
|
|
89359
89368
|
// Initialize arrays for results
|
|
89360
|
-
const
|
|
89361
|
-
const
|
|
89362
|
-
// const nDemos = T.DemographicField.Native + 1 - offset; // Ditto
|
|
89369
|
+
const nDemos = 5 /* Native */ + 1; // Profile includes 'White'
|
|
89370
|
+
const offset = 1; // But don't process 'White'
|
|
89363
89371
|
const demosByDistrict = p.demographicProfile.mfArrayByDistrict;
|
|
89364
89372
|
// Initialize the demographic buckets
|
|
89365
89373
|
// Get the statewide minority VAP/CVAP % (ignore 'White')
|
|
89366
89374
|
const vapPctArray = p.demographicProfile.stateMfArray.slice(1);
|
|
89367
89375
|
// Determine proportional minority districts by demographic (ignoring'White')
|
|
89368
89376
|
const districtsByDemo = calcDistrictsByDemo(vapPctArray, p.nDistricts);
|
|
89369
|
-
let bucketsByDemo = new Array(nDemos
|
|
89377
|
+
let bucketsByDemo = new Array(nDemos);
|
|
89370
89378
|
let totalProportional = 0;
|
|
89371
89379
|
for (let j = 0; j < nDemos; j++) {
|
|
89372
89380
|
const vapPct = vapPctArray[j];
|
|
89373
89381
|
const prop = districtsByDemo[j];
|
|
89374
|
-
|
|
89375
|
-
//
|
|
89382
|
+
bucketsByDemo[j] = [0, 0, 0, 0, 0, 0, vapPct, prop];
|
|
89383
|
+
// Sum the prop for each individual race/ethnicity demographic
|
|
89376
89384
|
if (j > 0)
|
|
89377
89385
|
totalProportional += prop;
|
|
89378
|
-
bucketsByDemo[j] = [0, 0, 0, vapPct, prop]; // Five conceptual columns for each demographic
|
|
89379
89386
|
}
|
|
89380
|
-
// Add a 'Total' row
|
|
89381
|
-
bucketsByDemo[nDemos] = [0, 0, 0, 0, totalProportional];
|
|
89382
89387
|
let opptyByDemo = U.initArray(nDemos, 0.0); // A state-level value
|
|
89383
89388
|
// For each district
|
|
89384
89389
|
for (let i = 0; i < p.nDistricts; i++) {
|
|
89385
89390
|
// Find the opportunities for minority representation
|
|
89386
89391
|
for (let j = 0; j < nDemos; j++) {
|
|
89387
|
-
const
|
|
89388
|
-
|
|
89392
|
+
const Mf = demosByDistrict[i][j + offset]; // Skip the 'White' entries
|
|
89393
|
+
const bucket = bucketVAPPct(Mf);
|
|
89394
|
+
if (bucket > 0) {
|
|
89389
89395
|
// Bucket opportunity districts for each demographic
|
|
89390
|
-
|
|
89391
|
-
bucketsByDemo[j][bucket] += 1;
|
|
89392
|
-
bucketsByDemo[j][2 /* Total */] += 1;
|
|
89396
|
+
bucketsByDemo[j][bucket - 1] += 1; // Zero-based array
|
|
89393
89397
|
// Accumulate seat probabilities
|
|
89394
|
-
opptyByDemo[j] += estMinorityOpportunity(
|
|
89395
|
-
// Also accumulate the 'Total' row summing the opportunities for each demographic,
|
|
89396
|
-
// ignoring the first all Minority demographic.
|
|
89397
|
-
if (j > 0) {
|
|
89398
|
-
bucketsByDemo[nDemos][bucket] += 1;
|
|
89399
|
-
bucketsByDemo[nDemos][2 /* Total */] += 1;
|
|
89400
|
-
}
|
|
89398
|
+
opptyByDemo[j] += estMinorityOpportunity(Mf, j);
|
|
89401
89399
|
}
|
|
89402
89400
|
}
|
|
89403
89401
|
}
|
|
@@ -89405,8 +89403,8 @@ function evalMinorityOpportunity(p, bLog = false) {
|
|
|
89405
89403
|
const oD = U.sumArray(opptyByDemo.slice(1)); // Sum individual demos, skipping all minorities
|
|
89406
89404
|
const cD = opptyByDemo[0 /* Minority */]; // All minorities
|
|
89407
89405
|
// The # of proportional districts for each separate demographic and all minorities
|
|
89408
|
-
const pOd =
|
|
89409
|
-
const pCd = bucketsByDemo[0 /* Minority */][
|
|
89406
|
+
const pOd = totalProportional;
|
|
89407
|
+
const pCd = bucketsByDemo[0 /* Minority */][7 /* PropSeats */];
|
|
89410
89408
|
// Score opportunity
|
|
89411
89409
|
const score = scoreMinority(oD, pOd, cD, pCd);
|
|
89412
89410
|
let mS = {
|
|
@@ -89447,13 +89445,15 @@ exports.calcDistrictsByDemo = calcDistrictsByDemo;
|
|
|
89447
89445
|
// NOTE - Sam Wang suggest 90% probability for a 37% district. That seems a little
|
|
89448
89446
|
// too abrupt and all or nothing, so I backed off to the ~70%.
|
|
89449
89447
|
//
|
|
89450
|
-
function estMinorityOpportunity(Mf) {
|
|
89448
|
+
function estMinorityOpportunity(Mf, demo) {
|
|
89451
89449
|
// NOTE - Switch to compress the probability distribution
|
|
89452
89450
|
const bCompress = false;
|
|
89453
89451
|
const dist = bCompress ? C.minorityOpportunityDistribution() : [0.0, 1.0];
|
|
89454
89452
|
const range = C.minorityOpportunityRange();
|
|
89455
89453
|
const _normalizer = new normalize_1.Normalizer(Mf);
|
|
89456
|
-
|
|
89454
|
+
let shift = C.minorityShift(); // For Black VAP % (and Minority)
|
|
89455
|
+
if (demo && (demo > 1)) // For other non-Black demos,
|
|
89456
|
+
shift *= C.minorityShiftDilution(); // dilute the Black shift (by half)
|
|
89457
89457
|
_normalizer.wipNum += shift;
|
|
89458
89458
|
_normalizer.clip(dist[C.BEG], dist[C.END]);
|
|
89459
89459
|
_normalizer.unitize(dist[C.BEG], dist[C.END]);
|
|
@@ -89462,13 +89462,21 @@ function estMinorityOpportunity(Mf) {
|
|
|
89462
89462
|
}
|
|
89463
89463
|
exports.estMinorityOpportunity = estMinorityOpportunity;
|
|
89464
89464
|
// HELPERS
|
|
89465
|
-
function
|
|
89466
|
-
|
|
89467
|
-
|
|
89468
|
-
|
|
89469
|
-
|
|
89470
|
-
|
|
89471
|
-
|
|
89465
|
+
function bucketVAPPct(Mf) {
|
|
89466
|
+
if (Mf < 0.35)
|
|
89467
|
+
return 0;
|
|
89468
|
+
else if ((Mf >= 0.35) && (Mf < 0.40))
|
|
89469
|
+
return 1;
|
|
89470
|
+
else if ((Mf >= 0.40) && (Mf < 0.45))
|
|
89471
|
+
return 2;
|
|
89472
|
+
else if ((Mf >= 0.45) && (Mf < 0.50))
|
|
89473
|
+
return 3;
|
|
89474
|
+
else if ((Mf >= 0.50) && (Mf < 0.55))
|
|
89475
|
+
return 4;
|
|
89476
|
+
else if ((Mf >= 0.55) && (Mf < 0.60))
|
|
89477
|
+
return 5;
|
|
89478
|
+
else // Mf >= 0.60
|
|
89479
|
+
return 6;
|
|
89472
89480
|
}
|
|
89473
89481
|
function calcProportionalDistricts(proportion, nDistricts) {
|
|
89474
89482
|
const roundUp = 0.0;
|