From a7f61800706ea04096f32f710a39d52ff9bed245 Mon Sep 17 00:00:00 2001 From: jhogan Date: Fri, 29 Mar 2019 15:58:15 -0400 Subject: [PATCH] Refactors the profile route and related utils for increased clarity --- .eslintrc | 1 + metadata/top-bottom-codings.js | 208 --- package.json | 2 + q | 41 + query-helpers/decennial.js | 269 ++-- query-helpers/profile-single.js | 244 ---- query-helpers/profile.js | 421 ++---- routes/profile.js | 226 ++-- routes/selection.js | 2 +- schema/schema.sql | 3 +- special-calculations/data/bins.js | 262 ++++ special-calculations/data/constants.js | 34 + .../data/top-bottom-codings.js | 89 ++ special-calculations/decennial.js | 47 + special-calculations/demographic.js | 7 + special-calculations/economic.js | 52 + special-calculations/housing.js | 55 + .../index.js | 2 - special-calculations/social.js | 12 + table-config/decennial/asian-subgroup.js | 85 -- table-config/decennial/hispanic-subgroup.js | 120 -- table-config/decennial/household-size.js | 35 - table-config/decennial/household-type.js | 72 - table-config/decennial/housing-occupancy.js | 135 -- table-config/decennial/housing-tenure.js | 110 -- table-config/decennial/index.js | 27 - ...tually-exclusive-race---hispanic-origin.js | 31 - table-config/decennial/population-density.js | 53 - ...nship-to-head-of-household--householder.js | 278 ---- table-config/decennial/sex-and-age.js | 249 ---- .../decennial/tenure-by-age-of-householder.js | 83 -- table-config/demographic/asian-subgroup.js | 132 -- table-config/demographic/hispanic-subgroup.js | 140 -- table-config/demographic/index.js | 13 - ...mutually-exclusive-race-hispanic-origin.js | 50 - table-config/demographic/sex-and-age.js | 290 ---- table-config/economic/class-of-worker.js | 22 - table-config/economic/commute-to-work.js | 151 --- table-config/economic/earnings.js | 472 ------- table-config/economic/employment-status.js | 93 -- .../economic/health-insurance-coverage.js | 129 -- table-config/economic/income-and-benefits.js | 833 ------------ ...st_12_months_is_below_the_poverty_level.js | 42 - table-config/economic/index.js | 25 - table-config/economic/industry.js | 59 - table-config/economic/occupation.js | 27 - .../ratio-of-income-to-poverty-level.js | 55 - ...a-percentage-of-household-income--grapi.js | 44 - table-config/housing/gross-rent.js | 236 ---- table-config/housing/housing-occupancy.js | 209 --- table-config/housing/housing-tenure.js | 223 ---- table-config/housing/index.js | 31 - table-config/housing/mortgage-status.js | 15 - table-config/housing/occupants-per-room.js | 21 - table-config/housing/rooms.js | 199 --- ...percentage-of-household-income--smocapi.js | 79 -- table-config/housing/units-in-structure.js | 43 - table-config/housing/value.js | 223 ---- table-config/housing/vehicles-available.js | 24 - .../year-householder-moved-into-unit.js | 27 - table-config/housing/year-structure-built.js | 43 - table-config/social/ancestry.js | 475 ------- .../social/computers-and-internet-use.js | 15 - ...ivilian-noninstitutionalized-population.js | 162 --- ...nal-attainment--highest-grade-completed.js | 47 - table-config/social/grandparents.js | 11 - table-config/social/household-type.js | 283 ---- table-config/social/index.js | 35 - .../social/language-spoken-at-home.js | 752 ----------- table-config/social/marital-status.js | 55 - table-config/social/place-of-birth.js | 833 ------------ ...nship-to-head-of-household--householder.js | 37 - table-config/social/residence-1-year-ago.js | 50 - table-config/social/school-enrollment.js | 27 - .../social/u-s--citizenship-status.js | 15 - table-config/social/veteran-status.js | 11 - table-config/social/year-of-entry.js | 12 - test/integration/routes.profile.test.js | 32 +- test/mocha.opts | 1 + utils/calculate-median-error.js | 100 +- utils/calculator.js | 57 - utils/change.js | 75 ++ utils/data-ingestor.js | 270 ++++ utils/delegate-aggregator.js | 31 - utils/difference.js | 60 + utils/formula.js | 67 +- utils/formulas.js | 49 + utils/get-bins.js | 16 + utils/guess-year.js | 16 - utils/inflate.js | 8 - utils/interpolate.js | 86 +- utils/nest-profile.js | 23 - utils/top-bottom-code-estimate.js | 41 +- yarn.lock | 1169 ++++++++++++++++- 94 files changed, 2679 insertions(+), 9447 deletions(-) delete mode 100644 metadata/top-bottom-codings.js create mode 100644 q delete mode 100644 query-helpers/profile-single.js create mode 100644 special-calculations/data/bins.js create mode 100644 special-calculations/data/constants.js create mode 100644 special-calculations/data/top-bottom-codings.js create mode 100644 special-calculations/decennial.js create mode 100644 special-calculations/demographic.js create mode 100644 special-calculations/economic.js create mode 100644 special-calculations/housing.js rename {table-config => special-calculations}/index.js (94%) create mode 100644 special-calculations/social.js delete mode 100644 table-config/decennial/asian-subgroup.js delete mode 100644 table-config/decennial/hispanic-subgroup.js delete mode 100644 table-config/decennial/household-size.js delete mode 100644 table-config/decennial/household-type.js delete mode 100644 table-config/decennial/housing-occupancy.js delete mode 100644 table-config/decennial/housing-tenure.js delete mode 100644 table-config/decennial/index.js delete mode 100644 table-config/decennial/mutually-exclusive-race---hispanic-origin.js delete mode 100644 table-config/decennial/population-density.js delete mode 100644 table-config/decennial/relationship-to-head-of-household--householder.js delete mode 100644 table-config/decennial/sex-and-age.js delete mode 100644 table-config/decennial/tenure-by-age-of-householder.js delete mode 100644 table-config/demographic/asian-subgroup.js delete mode 100644 table-config/demographic/hispanic-subgroup.js delete mode 100644 table-config/demographic/index.js delete mode 100644 table-config/demographic/mutually-exclusive-race-hispanic-origin.js delete mode 100644 table-config/demographic/sex-and-age.js delete mode 100755 table-config/economic/class-of-worker.js delete mode 100644 table-config/economic/commute-to-work.js delete mode 100755 table-config/economic/earnings.js delete mode 100644 table-config/economic/employment-status.js delete mode 100755 table-config/economic/health-insurance-coverage.js delete mode 100755 table-config/economic/income-and-benefits.js delete mode 100755 table-config/economic/income_in_past_12_months_is_below_the_poverty_level.js delete mode 100644 table-config/economic/index.js delete mode 100755 table-config/economic/industry.js delete mode 100755 table-config/economic/occupation.js delete mode 100755 table-config/economic/ratio-of-income-to-poverty-level.js delete mode 100755 table-config/housing/gross-rent-as-a-percentage-of-household-income--grapi.js delete mode 100755 table-config/housing/gross-rent.js delete mode 100755 table-config/housing/housing-occupancy.js delete mode 100755 table-config/housing/housing-tenure.js delete mode 100644 table-config/housing/index.js delete mode 100755 table-config/housing/mortgage-status.js delete mode 100755 table-config/housing/occupants-per-room.js delete mode 100755 table-config/housing/rooms.js delete mode 100755 table-config/housing/selected-monthly-owner-costs-as-a-percentage-of-household-income--smocapi.js delete mode 100755 table-config/housing/units-in-structure.js delete mode 100755 table-config/housing/value.js delete mode 100755 table-config/housing/vehicles-available.js delete mode 100755 table-config/housing/year-householder-moved-into-unit.js delete mode 100755 table-config/housing/year-structure-built.js delete mode 100755 table-config/social/ancestry.js delete mode 100644 table-config/social/computers-and-internet-use.js delete mode 100755 table-config/social/disability-status-of-the-civilian-noninstitutionalized-population.js delete mode 100755 table-config/social/educational-attainment--highest-grade-completed.js delete mode 100755 table-config/social/grandparents.js delete mode 100755 table-config/social/household-type.js delete mode 100644 table-config/social/index.js delete mode 100755 table-config/social/language-spoken-at-home.js delete mode 100755 table-config/social/marital-status.js delete mode 100755 table-config/social/place-of-birth.js delete mode 100755 table-config/social/relationship-to-head-of-household--householder.js delete mode 100755 table-config/social/residence-1-year-ago.js delete mode 100755 table-config/social/school-enrollment.js delete mode 100755 table-config/social/u-s--citizenship-status.js delete mode 100755 table-config/social/veteran-status.js delete mode 100755 table-config/social/year-of-entry.js create mode 100644 test/mocha.opts delete mode 100644 utils/calculator.js create mode 100644 utils/change.js create mode 100644 utils/data-ingestor.js delete mode 100644 utils/delegate-aggregator.js create mode 100644 utils/difference.js create mode 100644 utils/formulas.js create mode 100644 utils/get-bins.js delete mode 100644 utils/guess-year.js delete mode 100644 utils/inflate.js delete mode 100644 utils/nest-profile.js diff --git a/.eslintrc b/.eslintrc index d17b4c5..caafaa6 100644 --- a/.eslintrc +++ b/.eslintrc @@ -9,6 +9,7 @@ "no-param-reassign": [0], "radix": [0], "camelcase": [0], + "no-use-before-define": [0], }, "env": { "node": true, diff --git a/metadata/top-bottom-codings.js b/metadata/top-bottom-codings.js deleted file mode 100644 index 793d14f..0000000 --- a/metadata/top-bottom-codings.js +++ /dev/null @@ -1,208 +0,0 @@ -const topBottomCodings = { - latest: { - mdage: { - all: { - upper: 115, - lower: 1, - }, - nta: { - upper: 85, - lower: 1, - }, - }, - mdhhinc: { - all: { - upper: 250000, - lower: 2500, - }, - nta: { - upper: 225000, - lower: 11000, - }, - }, - mdfaminc: { - all: { - upper: 250000, - lower: 2500, - }, - nta: { - upper: 225000, - lower: 11000, - }, - }, - mdnfinc: { - all: { - upper: 250000, - lower: 2500, - }, - nta: { - upper: 225000, - lower: 11000, - }, - }, - mdewrk: { - all: { - upper: 250000, - lower: 2500, - }, - nta: { - upper: 112500, - lower: 2800, - }, - }, - mdemftwrk: { - all: { - upper: 250000, - lower: 2500, - }, - nta: { - upper: 112500, - lower: 2800, - }, - }, - mdefftwrk: { - all: { - upper: 250000, - lower: 2500, - }, - nta: { - upper: 112500, - lower: 2800, - }, - }, - mdrms: { - all: { - upper: 9000, - lower: 0, - }, - nta: { - upper: 9000, - lower: 0, - }, - }, - mdvl: { - all: { - upper: 2000000, - lower: 0, - }, - nta: { - upper: 2000000, - lower: 0, - }, - }, - mdgr: { - all: { - upper: 3500, - lower: 0, - }, - nta: { - upper: 3500, - lower: 0, - }, - }, - }, - earlier: { - mdage: { - all: { - upper: 115, - lower: 1, - }, - nta: { - upper: 85, - lower: 1, - }, - }, - mdhhinc: { - all: { - upper: 250000, - lower: 2500, - }, - nta: { - upper: 225000, - lower: 11000, - }, - }, - mdfaminc: { - all: { - upper: 250000, - lower: 2500, - }, - nta: { - upper: 225000, - lower: 11000, - }, - }, - mdnfinc: { - all: { - upper: 250000, - lower: 2500, - }, - nta: { - upper: 225000, - lower: 11000, - }, - }, - mdewrk: { - all: { - upper: 250000, - lower: 2500, - }, - nta: { - upper: 112500, - lower: 2800, - }, - }, - mdemftwrk: { - all: { - upper: 250000, - lower: 2500, - }, - nta: { - upper: 112500, - lower: 2800, - }, - }, - mdefftwrk: { - all: { - upper: 250000, - lower: 2500, - }, - nta: { - upper: 112500, - lower: 2800, - }, - }, - mdrms: { - all: { - upper: 9000, - lower: 0, - }, - nta: { - upper: 9000, - lower: 0, - }, - }, - mdvl: { - all: { - upper: 1000000, - lower: 0, - }, - nta: { - upper: 1275000, - lower: 0, - }, - }, - mdgr: { - all: { - upper: 2000, - lower: 0, - }, - nta: { - upper: 2250, - lower: 0, - }, - }, - }, -}; - -module.exports = topBottomCodings; diff --git a/package.json b/package.json index 06b1786..30ee633 100644 --- a/package.json +++ b/package.json @@ -15,11 +15,13 @@ "license": "ISC", "dependencies": { "apicache": "^1.2.3", + "babel-cli": "^6.26.0", "body-parser": "^1.18.3", "compression": "1.7.3", "cwait": "1.1.1", "d3": "^4.13.0", "d3-collection": "^1.0.4", + "dataframe-js": "^1.4.1", "debug": "^3.1.0", "dotenv": "^6.0.0", "express": "^4.16.3", diff --git a/q b/q new file mode 100644 index 0000000..8e1d7da --- /dev/null +++ b/q @@ -0,0 +1,41 @@ + SELECT + sum, + m, + cv, + universe_sum, + universe_m, + profile, + category, + base, + profile.variable + FROM ( + SELECT + --- sum --- + SUM(e) AS sum, + --- m --- + SQRT(SUM(POWER(m, 2))) AS m, + --- cv (uses m & sum, recomputed) --- + (((SQRT(SUM(POWER(m, 2))) / 1.645) / NULLIF(SUM(e), 0)) * 100) AS cv, + profile, + category, + base, + LOWER(variable) as variable + FROM economic p + INNER JOIN factfinder_metadata ffm + ON p.variable = ffm.variablename + WHERE p.geoid IN ('SI05') + AND p.dataset = 'Y2006-2010' + GROUP BY variable, base, category, profile + ORDER BY variable, base, category + ) profile + LEFT JOIN ( + SELECT + SUM(e) as universe_sum, + SQRT(SUM(POWER(m, 2))) as universe_m, + LOWER(variable) as variable + FROM economic base + WHERE base.dataset = 'Y2006-2010' + GROUP BY variable + ) universe + ON profile.variable = universe.variable; + diff --git a/query-helpers/decennial.js b/query-helpers/decennial.js index 729c0a5..f55ace5 100644 --- a/query-helpers/decennial.js +++ b/query-helpers/decennial.js @@ -1,187 +1,86 @@ -// return a comma-separated string of single-quoted numbers from an array of numbers -function stringifyArray(array) { - return `'${array.join("','")}'`; +const { DECENNIAL_CUR_YEAR, DECENNIAL_PREV_YEAR } = require('../special-calculations/data/constants'); + +/* + * Returns the appropriate second half of the geoid WHERE clause + * If 'ids' is an array, returns an 'IN (...ids)' clause, with the quoted ids joined by ',' + * Else, if 'ids' is a single id, returns an '= id' clause, with id in quotes + */ +function formatGeoidWhereClause(ids) { + if (Array.isArray(ids)) return `IN ('${ids.join("','")}')`; + return `= '${ids}'`; } -const buildSQL = function buildSQL(ids, compare) { - const idStrings = stringifyArray(ids); - - return /**/` - WITH - filtered_selection AS ( - SELECT * - FROM decennial - WHERE geoid IN (${idStrings}) - ), - - enriched_selection AS ( - SELECT * - FROM filtered_selection - INNER JOIN decennial_dictionary - ON decennial_dictionary.variablename = filtered_selection.variable - ), - - main_numbers AS ( - SELECT - *, - -- previous_sum -- - CASE - WHEN is_most_recent THEN - lag(sum) over (order by variable, year) - END as previous_sum - FROM ( - SELECT - - -- sum -- - sum(value) AS sum, - - -- relation -- - max(relation) AS relation, - - -- category -- - max(category) AS category, - variable, - - -- is_most_recent -- - CASE - WHEN max(year) over () = year THEN - TRUE - ELSE - FALSE - END as is_most_recent, - year - FROM enriched_selection - GROUP BY variable, "year" - ) x - ), - - base_numbers AS ( - SELECT - - -- base_sum -- - sum(value) AS base_sum, - - -- previous_base_sum -- - lag(sum(value)) over (order by variable, year) AS previous_base_sum, - - -- base_variable -- - variable AS base_variable, - - -- base_year -- - year AS base_year - FROM enriched_selection - WHERE relation = variable - GROUP BY variable, "year" - ), - - comparison_selection AS ( - SELECT * - FROM decennial - WHERE geoid IN ('${compare}') - ), - - comparison_enriched_selection AS ( - SELECT * - FROM comparison_selection - INNER JOIN decennial_dictionary - ON decennial_dictionary.variablename = comparison_selection.variable - ), - - comparison_main_numbers AS ( - SELECT - - -- comparison_sum -- - sum(value) AS comparison_sum, - - -- comparison_relation -- - max(relation) AS comparison_relation, - - -- comparison_variable -- - variable AS comparison_variable, - - -- comparison_year -- - year AS comparison_year - FROM comparison_enriched_selection - GROUP BY variable, "year" - ), - - comparison_base_numbers AS ( - SELECT - - -- comparison_base_sum -- - sum(value) AS comparison_base_sum, - - -- comparison_base_variable -- - variable AS comparison_base_variable, - - -- comparison_base_year -- - year AS comparison_base_year - FROM comparison_enriched_selection - WHERE relation = variable - GROUP BY variable, "year" - ) - - SELECT *, - - -- difference_sum -- - (sum - comparison_sum) AS difference_sum, - - -- difference_percent -- - ((percent - comparison_percent) * 100) AS difference_percent, - - -- change_sum -- - (sum - previous_sum) AS change_sum, - - -- change_percent -- - ROUND(((sum - previous_sum) / NULLIF(previous_sum,0))::numeric, 4) AS change_percent, - - -- change_percentage_point -- - percent - previous_percent AS change_percentage_point - FROM ( - SELECT *, - - -- id -- - ENCODE(CONVERT_TO(variable || year, 'UTF-8'), 'base64') As id, - - -- profile -- - 'decennial' AS profile, - - -- variable -- - regexp_replace(lower(variable), '[^A-Za-z0-9]', '_', 'g') AS variable, - - -- category -- - regexp_replace(lower(category), '[^A-Za-z0-9]', '_', 'g') AS category, - - -- significant -- - true AS significant, - - -- year -- - 'y' || year as year, - - -- dataset -- - 'y' || year as dataset, - - -- percent -- - ROUND((sum / NULLIF(base_sum,0))::numeric, 4) as percent, - - -- previous_percent -- - ROUND((previous_sum / NULLIF(previous_base_sum,0))::numeric, 4) as previous_percent, - - -- comparison_percent -- - ROUND((comparison_sum / NULLIF(comparison_base_sum,0))::numeric, 4) as comparison_percent - - FROM main_numbers - INNER JOIN comparison_main_numbers - ON main_numbers.variable = comparison_main_numbers.comparison_variable - AND main_numbers.year = comparison_main_numbers.comparison_year - LEFT OUTER JOIN base_numbers - ON main_numbers.relation = base_numbers.base_variable - AND main_numbers.year = base_numbers.base_year - LEFT OUTER JOIN comparison_base_numbers - ON main_numbers.relation = comparison_base_numbers.comparison_base_variable - AND main_numbers.year = comparison_base_numbers.comparison_base_year - ) precalculations - `; -}; - -module.exports = buildSQL; +/* NOTE: 'profile' is a noop param, to make invocation from route cleaner */ +const decennialProfileSQL = (profile, ids, isPrevious = false) => ` + WITH + /* + * enriched_profile: decennial data joined with meta data + * from decennial_dictionary, filtered for given year + * and geoids + */ + enriched_profile AS ( + SELECT * + FROM decennial d + INNER JOIN decennial_dictionary dd + ON dd.variablename = d.variable + WHERE d.geoid ${formatGeoidWhereClause(ids)} + AND d.year = '${isPrevious ? DECENNIAL_PREV_YEAR : DECENNIAL_CUR_YEAR}' + ), + + /* + * base: an aggregation of enriched_profile that sums the + * value of all base variables for the given selection + */ + base AS ( + SELECT + --- sum --- + sum(value) as base_sum, + relation as base + FROM enriched_profile + WHERE relation = variable + GROUP BY relation + ) + + /* + * an aggregation of enriched selection, joined with base that sums + * value for all rows for a given 'variable' in the selection, and + * adds additional aggregate value percent. + * Columns: id, sum, variable, variablename, base, category, profile, percent + */ + SELECT *, + --- percent --- + CASE + WHEN base_sum = 0 THEN 0 + WHEN base_sum IS NULL THEN 0 + ELSE sum / base_sum + END AS percent + FROM ( + SELECT + --- id --- + ENCODE(CONVERT_TO(variable, 'UTF-8'), 'base64') AS id, + --- sum --- + SUM(value) AS sum, + --- variable --- + REGEXP_REPLACE( + LOWER(variable), + '[^A-Za-z0-9]', '_', 'g' + ) AS variable, + --- variablename --- + variablename, + --- base --- + relation AS base, + --- category --- + REGEXP_REPLACE( + LOWER(category), + '[^A-Za-z0-9]', '_', 'g' + ) AS category, + --- profile --- + 'decennial' AS profile + FROM enriched_profile + GROUP BY variable, variablename, base, category + ) decennial + LEFT JOIN base + ON decennial.base = base.base +`; + +module.exports = decennialProfileSQL; diff --git a/query-helpers/profile-single.js b/query-helpers/profile-single.js deleted file mode 100644 index 88b67d0..0000000 --- a/query-helpers/profile-single.js +++ /dev/null @@ -1,244 +0,0 @@ -// ACS profile query for single geoid, no agg fucntions - -const buildSQL = function buildSQL(profile, geoid, compare) { - return /**/` - WITH - filtered_selection AS ( - SELECT * - FROM ${profile} - WHERE geoid = '${geoid}' - ), - - enriched_selection AS ( - SELECT * - FROM filtered_selection - INNER JOIN factfinder_metadata - ON factfinder_metadata.variablename = filtered_selection.variable - ), - - main_numbers AS ( - SELECT - *, - - -- previous_sum -- - CASE - WHEN is_most_recent THEN - lag(sum) over (order by variable, dataset) - END as previous_sum, - - -- previous_percent -- - CASE - WHEN is_most_recent THEN - lag(p / 100) over (order by variable, dataset) - END as previous_percent, - - -- previous_m -- - CASE - WHEN is_most_recent THEN - lag(m) over (order by variable, dataset) - END as previous_m, - - -- previous_percent_m -- - CASE - WHEN is_most_recent THEN - lag(z / 100) over (order by variable, dataset) - END as previous_percent_m - FROM ( - SELECT *, - -- sum -- - e as sum, - -- cv -- - (((m / 1.645) / NULLIF(e,0)) * 100) AS cv, - -- percent -- - ROUND(p::numeric, 4) / 100 as percent, - -- percent_m -- - ROUND(z::numeric, 4) / 100 as percent_m, - - -- is_most_recent -- - CASE - WHEN max(dataset) over () = dataset THEN - TRUE - ELSE - FALSE - END as is_most_recent - FROM enriched_selection - ) precalculations - ), - - comparison_selection AS ( - SELECT * - FROM ${profile} - WHERE geoid = '${compare}' - ), - - comparison_enriched_selection AS ( - SELECT * - FROM comparison_selection - INNER JOIN factfinder_metadata - ON factfinder_metadata.variablename = comparison_selection.variable - ), - - comparison_main_numbers AS ( - SELECT - -- comparison_sum -- - e as comparison_sum, - -- comparison_cv -- - (((m / 1.645) / NULLIF(e,0)) * 100) AS comparison_cv, - -- comparison_variable -- - variable as comparison_variable, - -- comparison_dataset -- - dataset as comparison_dataset, - -- comparison_percent -- - ROUND(p::numeric, 4) / 100 as comparison_percent, - -- comparison_percent_m -- - ROUND(z::numeric, 4) / 100 as comparison_percent_m, - -- comparison_m -- - m as comparison_m - FROM comparison_enriched_selection - ) - SELECT - *, - -- change_percentage_point_significant -- - -- (actually reflect reliability, issue #57) -- - CASE - WHEN ((((change_percentage_point_m) / 1.645) / nullif(ABS(change_percentage_point), 0)) * 100) < 20 THEN - TRUE - ELSE - FALSE - END AS change_percentage_point_significant, - - -- significant -- - -- (actually reflect reliability, issue #57) -- - CASE - WHEN ((((difference_m) / 1.645) / nullif(ABS(difference_sum), 0)) * 100) < 20 THEN true - ELSE false - END AS significant, - - -- percent_significant -- - -- (actually reflect reliability, issue #57) -- - CASE - WHEN ((((difference_percent_m) / 1.645) / nullif(ABS(difference_percent), 0)) * 100) < 20 THEN - true - ELSE false - END AS percent_significant - - FROM ( - SELECT - *, - - -- difference_sum -- - (sum - comparison_sum) AS difference_sum, - - -- difference_percent -- - CASE - WHEN (((percent - comparison_percent) * 100) < 0 AND ((percent - comparison_percent) * 100) > -0.05) THEN - 0 - ELSE - (coalesce(percent, 0) - coalesce(comparison_percent,0)) * 100 - END AS difference_percent, - - -- difference_m -- - (SQRT((POWER(coalesce(m, 0), 2) + POWER(coalesce(comparison_m, 0), 2)))) AS difference_m, - - -- difference_percent_m -- - (SQRT((POWER(coalesce(percent_m, 0) * 100, 2) + POWER(coalesce(comparison_percent_m, 0) * 100, 2)))) AS difference_percent_m, - - -- change_percentage_point -- - CASE - WHEN (percent = null AND previous_percent = null) THEN - null - WHEN (is_most_recent) THEN - coalesce(percent, 0) - coalesce(previous_percent, 0) - END AS change_percentage_point, - - -- change_percentage_point_m -- - CASE - WHEN is_most_recent THEN - (SQRT((POWER(coalesce(previous_percent_m, 0), 2) + POWER(coalesce(percent_m, 0), 2)))) - END AS change_percentage_point_m, - - -- change_significant -- - -- (actually reflect reliability, issue #57) -- - CASE - WHEN ((((change_m) / 1.645) / nullif(ABS(change_sum), 0)) * 100) < 20 THEN - TRUE - ELSE - FALSE - END AS change_significant, - - -- change_percent_significant -- - -- (actually reflect reliability, issue #57) -- - CASE - WHEN ((((change_percent_m) / 1.645) / nullif(ABS(change_percent), 0)) * 100) < 20 THEN - TRUE - ELSE - FALSE - END AS change_percent_significant - FROM ( - SELECT *, - -- id -- - ENCODE(CONVERT_TO(VARIABLE || dataset, 'UTF-8'), 'base64') AS id, - -- dataset -- - regexp_replace(lower(dataset), '[^A-Za-z0-9]', '_', 'g') AS dataset, - -- profile -- - regexp_replace(lower(profile), '[^A-Za-z0-9]', '_', 'g') AS profile, - -- category -- - regexp_replace(lower(category), '[^A-Za-z0-9]', '_', 'g') AS category, - -- variable -- - regexp_replace(lower(variable), '[^A-Za-z0-9]', '_', 'g') AS variable, - - -- is_reliable -- - CASE - WHEN (cv < 20) - THEN true - ELSE false - END as is_reliable, - - -- comparison_is_reliable -- - CASE - WHEN (comparison_cv < 20) - THEN true - ELSE false - END as comparison_is_reliable, - - -- change_sum -- - CASE - WHEN is_most_recent THEN - sum - previous_sum - END as change_sum, - - -- change_m -- - CASE - WHEN is_most_recent THEN - ABS(SQRT(POWER(coalesce(m, 0), 2) + POWER(coalesce(previous_m, 0), 2))) - END as change_m, - - -- change_percent -- - CASE - WHEN is_most_recent THEN - ROUND(((sum - previous_sum) / NULLIF(previous_sum,0))::numeric, 4) - END as change_percent, - - -- change_percent_m -- - CASE - WHEN is_most_recent AND previous_sum != 0 THEN - coalesce( - ABS(sum / NULLIF(previous_sum,0)) - * SQRT( - (POWER(coalesce(m, 0) / 1.645, 2) / NULLIF(POWER(sum, 2), 0)) - + (POWER(previous_m / 1.645, 2) / NULLIF(POWER(previous_sum, 2), 0)) - ) * 1.645, - 0 - ) - END as change_percent_m - FROM - main_numbers - LEFT OUTER JOIN comparison_main_numbers - ON main_numbers.variable = comparison_main_numbers.comparison_variable - AND main_numbers.dataset = comparison_main_numbers.comparison_dataset - ) precalculations - ) significance - `; -}; - -module.exports = buildSQL; diff --git a/query-helpers/profile.js b/query-helpers/profile.js index fcdb68f..4d98b04 100644 --- a/query-helpers/profile.js +++ b/query-helpers/profile.js @@ -1,320 +1,107 @@ -// return a comma-separated string of single-quoted numbers from an array of numbers -function stringifyArray(array) { - return `'${array.join("','")}'`; +const { CV_CONST, CUR_YEAR, PREV_YEAR } = require('../special-calculations/data/constants'); + +/* + * Returns the appropriate second half of the geoid WHERE clause + * If 'ids' is an array, returns an 'IN (...ids)' clause, with the quoted ids joined by ',' + * Else, if 'ids' is a single id, returns an '= id' clause, with id in quotes + */ +function formatGeoidWhereClause(ids) { + if (Array.isArray(ids)) return `IN ('${ids.join("','")}')`; + return `= '${ids}'`; } -const buildSQL = function buildSQL(profile, ids, compare) { - const idStrings = stringifyArray(ids); - // const { length } = idStrings; - // WARNING: although our Carto backend will prevent any - // malicious SQL injection, maintainers might consider - // migrating to Postgres which would make it very easy for - // malicious code to be inserted - return /**/` - WITH - filtered_selection AS ( - SELECT * - FROM ${profile} - WHERE geoid IN (${idStrings}) - ), - - enriched_selection AS ( - SELECT * - FROM filtered_selection - INNER JOIN factfinder_metadata - ON factfinder_metadata.variablename = filtered_selection.variable - ), - - main_numbers AS ( - SELECT - *, - - -- cv -- - (((m / 1.645) / NULLIF(SUM,0)) * 100) AS cv, - - -- previous_sum -- - CASE - WHEN is_most_recent THEN - lag(sum) over (order by variable, dataset) - END AS previous_sum, - - -- previous_m -- - CASE - WHEN is_most_recent THEN - lag(m) over (order by variable, dataset) - END AS previous_m - FROM ( - SELECT - -- sum -- - sum(e) AS sum, - - -- m -- - sqrt(sum(power(m, 2))) AS m, - - -- is_most_recent -- - CASE - WHEN max(dataset) over () = dataset THEN - TRUE - ELSE - FALSE - END AS is_most_recent, - - base, - category, - variable, - profile, - dataset - FROM enriched_selection - GROUP BY variable, dataset, base, category, profile - ) x - ), - - base_numbers AS ( - SELECT - -- base_sum -- - sum(e) AS base_sum, - - -- base_m -- - sqrt(sum(power(m, 2))) AS base_m, - - -- base_join -- - max(base) AS base_join, - - -- base_dataset -- - max(dataset) AS base_dataset, - - -- previous_base_sum -- - lag(sum(e)) over (order by variable, dataset) AS previous_base_sum, - - -- previous_base_m -- - lag(sqrt(sum(power(m, 2)))) over (order by variable, dataset) AS previous_base_m - FROM enriched_selection - WHERE base = variable - GROUP BY variable, dataset - ), - - comparison_selection AS ( - SELECT * - FROM ${profile} - WHERE geoid = '${compare}' - ), - - comparison_enriched_selection AS ( - SELECT * - FROM comparison_selection - INNER JOIN factfinder_metadata - ON factfinder_metadata.variablename = comparison_selection.variable - ), - - comparison_main_numbers AS ( - SELECT - * - FROM ( - SELECT - -- comparison_sum -- - e AS comparison_sum, - - -- comparison_m -- - m AS comparison_m, - - -- comparison_percent -- - (p / 100) AS comparison_percent, - - -- comparison_percent_m -- - (z / 100) AS comparison_percent_m, - - -- comparison_cv -- - c AS comparison_cv, - - -- comparison_join -- - base AS comparison_join, - - -- comparison_variable -- - variable AS comparison_variable, - - -- comparison_dataset -- - dataset AS comparison_dataset - FROM comparison_enriched_selection - ) x - ) - +const profileSQL = (profile, ids, isPrevious = false) => ` + WITH + /* + * enriched_profile: profile data joined with meta data + * from factfinder_metadata, filtered for given year + * and geoids + */ + enriched_profile AS ( + SELECT * + FROM ${profile} p + INNER JOIN factfinder_metadata ffm + ON ffm.variablename = p.variable + WHERE p.geoid ${formatGeoidWhereClause(ids)} + AND p.dataset = '${isPrevious ? PREV_YEAR : CUR_YEAR}' + ), + + /* + * base: an aggregation of enriched_profile that sums the + * value of all base variables for the given selection + */ + base AS ( SELECT - *, - - -- significant -- - -- (actually reflect reliability, issue #57) -- - CASE - WHEN ((((difference_m) / 1.645) / nullif(ABS(difference_sum), 0)) * 100) < 20 - THEN true - ELSE false - END AS significant, - - -- percent_significant -- - -- (actually reflect reliability, issue #57) -- - CASE - WHEN ((((difference_percent_m) / 1.645) / nullif(ABS(difference_percent), 0)) * 100) < 20 - THEN true - ELSE false - END AS percent_significant, - - -- change_percent_significant -- - -- (actually reflect reliability, issue #57) -- - CASE - WHEN ((((change_percent_m) / 1.645) / nullif(ABS(change_percent), 0)) * 100) < 20 THEN - TRUE - ELSE - FALSE - END AS change_percent_significant, - - -- change_percentage_point_significant -- - -- (actually reflect reliability, issue #57) -- - CASE - WHEN ((((change_percentage_point_m) / 1.645) / nullif(ABS(change_percentage_point), 0)) * 100) < 20 THEN - TRUE - ELSE - FALSE - END AS change_percentage_point_significant - - FROM ( - SELECT - *, - - -- difference_sum -- - (sum - comparison_sum) AS difference_sum, - - -- difference_percent -- - CASE - WHEN (((percent - comparison_percent) * 100) < 0 AND ((percent - comparison_percent) * 100) > -0.05) THEN - 0 - ELSE - (coalesce(percent, 0) - (coalesce(comparison_percent,0))) * 100 - END AS difference_percent, - - -- difference_m -- - (SQRT((POWER(coalesce(m, 0), 2) + POWER(coalesce(comparison_m, 0), 2)))) AS difference_m, - - -- difference_percent_m -- - (SQRT((POWER(coalesce(percent_m, 0) * 100, 2) + POWER(coalesce(comparison_percent_m, 0) * 100, 2)))) AS difference_percent_m, - - -- change_percentage_point -- - CASE - WHEN (percent = null AND previous_percent = null) THEN - null - WHEN (is_most_recent) THEN - coalesce(percent, 0) - coalesce(previous_percent, 0) - END AS change_percentage_point, - - -- change_percentage_point_m -- - CASE - WHEN is_most_recent THEN - (SQRT((POWER(coalesce(previous_percent_m, 0), 2) + POWER(coalesce(percent_m, 0), 2)))) - END AS change_percentage_point_m, - - -- change_significant -- - -- (actually reflect reliability, issue #57) -- - CASE - WHEN ((((change_m) / 1.645) / nullif(ABS(change_sum), 0)) * 100) < 20 THEN - TRUE - ELSE - FALSE - END AS change_significant - - FROM ( - SELECT - -- id -- - ENCODE(CONVERT_TO(variable || dataset, 'UTF-8'), 'base64') AS id, - base, - - -- variablename -- - variable AS variablename, - category, - - -- dataset -- - regexp_replace(lower(dataset), '[^A-Za-z0-9]', '_', 'g') AS dataset, - - -- profile -- - regexp_replace(lower(profile), '[^A-Za-z0-9]', '_', 'g') AS profile, - - -- variable -- - regexp_replace(lower(variable), '[^A-Za-z0-9]', '_', 'g') AS variable, - is_most_recent, - sum, - m, - cv, - - -- percent -- - ROUND((sum / NULLIF(base_sum,0))::numeric, 4) AS percent, - - -- previous_percent -- - ROUND((previous_sum / NULLIF(previous_base_sum,0))::numeric, 4) AS previous_percent, - previous_sum, - previous_m, - - -- percent_m -- - CASE - WHEN (POWER(m, 2) - POWER(sum / NULLIF(base_sum,0), 2) * POWER(base_m, 2)) < 0 - THEN (1 / NULLIF(base_sum,0)) * SQRT(POWER(m, 2) + POWER(sum / NULLIF(base_sum,0), 2) * POWER(base_m, 2)) - ELSE (1 / NULLIF(base_sum,0)) * SQRT(POWER(m, 2) - POWER(sum / NULLIF(base_sum,0), 2) * POWER(base_m, 2)) - END AS percent_m, - - -- previous_percent_m -- - CASE - WHEN (POWER(previous_m, 2) - POWER(previous_sum / NULLIF(previous_base_sum,0), 2) * POWER(previous_base_m, 2)) < 0 - THEN (1 / NULLIF(previous_base_sum,0)) * SQRT(POWER(previous_m, 2) + POWER(previous_sum / NULLIF(previous_base_sum,0), 2) * POWER(previous_base_m, 2)) - ELSE (1 / NULLIF(previous_base_sum,0)) * SQRT(POWER(previous_m, 2) - POWER(previous_sum / NULLIF(previous_base_sum,0), 2) * POWER(previous_base_m, 2)) - END AS previous_percent_m, - - comparison_cv, - comparison_m, - comparison_sum, - comparison_percent_m, - comparison_percent, - - -- change_sum -- - CASE - WHEN is_most_recent THEN - sum - previous_sum - END AS change_sum, - - -- change_m -- - CASE - WHEN is_most_recent THEN - ABS(SQRT(POWER(coalesce(m, 0), 2) + POWER(coalesce(previous_m, 0), 2))) - END AS change_m, - - -- change_percent -- - CASE - WHEN is_most_recent THEN - ROUND(((sum - previous_sum) / NULLIF(previous_sum,0))::numeric, 4) - END AS change_percent, - - -- change_percent_m -- - CASE - WHEN is_most_recent AND previous_sum != 0 THEN - coalesce( - ABS(sum / NULLIF(previous_sum,0)) - * SQRT( - (POWER(coalesce(m, 0) / 1.645, 2) / NULLIF(POWER(sum, 2),0)) - + (POWER(previous_m / 1.645, 2) / NULLIF(POWER(previous_sum, 2),0)) - ) * 1.645, - 0 - ) - ELSE - null - END AS change_percent_m - - FROM main_numbers - - INNER JOIN comparison_main_numbers - ON main_numbers.variable = comparison_main_numbers.comparison_variable - AND main_numbers.dataset = comparison_main_numbers.comparison_dataset - - LEFT OUTER JOIN base_numbers - ON main_numbers.base = base_numbers.base_join - AND main_numbers.dataset = base_numbers.base_dataset - ) precalculations - ) prework - `; -}; - -module.exports = buildSQL; + --- sum --- + SUM(e) as base_sum, + SQRT(SUM(POWER(m, 2))) AS base_m, + base + FROM enriched_profile + WHERE base = variable + GROUP BY base + ) + + /* + * an aggregation of enriched selection, joined with base that aggregates + * e and m for all rows for a given 'variable' in the selection, and adds + * additional aggregate values cv, percent, percent_m, and is_reliable + * Columns: id, sum, m, cv, variable, variablename, base, category, profile, percent, percent_m, is_reliable + */ + SELECT *, + --- percent --- + CASE + WHEN base_sum = 0 THEN 0 + WHEN base_sum IS NULL THEN 0 + ELSE sum / base_sum + END AS percent, + --- percent_m --- + CASE + WHEN base_sum = 0 THEN 0 + WHEN base_sum IS NULL THEN 0 + WHEN POWER(m, 2) - POWER(sum / base_sum, 2) * POWER(base_m, 2) < 0 + THEN (1 / base_sum) * SQRT(POWER(m, 2) + POWER(sum / base_sum, 2) * POWER(base_m, 2)) + ELSE (1 / base_sum) * SQRT(POWER(m, 2) - POWER(sum / base_sum, 2) * POWER(base_m, 2)) + END AS percent_m, + --- is_reliable --- + CASE + WHEN cv < 20 THEN true + ELSE false + END AS is_reliable + FROM ( + SELECT + --- id --- + ENCODE(CONVERT_TO(variable, 'UTF-8'), 'base64') AS id, + --- sum --- + SUM(e) AS sum, + --- m --- + SQRT(SUM(POWER(m, 2))) AS m, + --- cv --- + (((SQRT(SUM(POWER(m, 2))) / ${CV_CONST}) / NULLIF(SUM(e), 0)) * 100) AS cv, + --- variable --- + REGEXP_REPLACE( + LOWER(variable), + '[^A-Za-z0-9]', '_', 'g' + ) AS variable, + --- variablename --- + variablename, + --- base --- + base, + --- category --- + REGEXP_REPLACE( + LOWER(category), + '[^A-Za-z0-9]', '_', 'g' + ) AS category, + --- profile --- + REGEXP_REPLACE( + LOWER(profile), + '[^A-Za-z0-9]', '_', 'g' + ) AS profile + FROM enriched_profile + GROUP BY variable, variablename, base, category, profile + ORDER BY variable, base, category + ) AS variables + LEFT JOIN base + ON variables.base = base.base +`; + +module.exports = profileSQL; diff --git a/routes/profile.js b/routes/profile.js index d6ac931..b964854 100644 --- a/routes/profile.js +++ b/routes/profile.js @@ -1,136 +1,130 @@ const express = require('express'); -const _ = require('lodash'); const Selection = require('../models/selection'); -const buildProfileSQL = require('../query-helpers/profile'); -const buildProfileSingleSQL = require('../query-helpers/profile-single'); -const buildDecennialSQL = require('../query-helpers/decennial'); -const tableConfigs = require('../table-config'); -const delegateAggregator = require('../utils/delegate-aggregator'); -const nestProfile = require('../utils/nest-profile'); +const profileQuery = require('../query-helpers/profile'); +const decennialQuery = require('../query-helpers/decennial'); +const DataIngestor = require('../utils/data-ingestor'); +const doChangeCalculations = require('../utils/change'); +const doDifferenceCalculations = require('../utils/difference'); const router = express.Router(); +router.get('/:id/:profileName', async (req, res) => { + const { app } = req; + const { id: _id, profileName } = req.params; + const { compare = '0' } = req.query; -router.use((req, res, next) => { - res.setHeader('Cache-Control', 'public, max-age=0'); - next(); -}); + if (invalidCompare(compare)) res.status(500).send({ error: 'invalid compare param' }); -const { - get, camelCase, find, merge, -} = _; + if (invalidProfileName(profileName)) res.status(500).send({ error: 'invalid profile' }); -const appendRowConfig = (data, profile, match) => { - const fullDataset = nestProfile(data, 'object', 'dataset', 'variable'); + try { + const selectedGeo = await Selection.findOne({ _id }); + const profileObj = await getProfileData(profileName, selectedGeo.geoids, compare, app.db); + return res.send(profileObj); + } catch (e) { + console.log(e); // eslint-disable-line + return res.status(500).send({ error: 'Failed to create profile' }); + } +}); - return data +/* + * Queries postgres for current, previous, and compare data for a given + * profile type, set of geoids and compare geoid. Joins the data, and adds + * 'change' and 'difference' calculation values. + * @param {string} profileName - The profile type + * @param {Array} geoids - The list of geoids for the given selected geography + * @param {string} compare - Integer string representing the geoid of the comparison geography + * @returns {Object} + */ +async function getProfileData(profileName, geoids, compare, db) { + const isAggregate = geoids.length > 1; + + const queryBuilder = getQueryBuilder(profileName); + + // get data from postgres + const [profileData, previousProfileData, compareProfileData] = await Promise.all([ + db.query(queryBuilder(profileName, geoids)), + db.query(queryBuilder(profileName, geoids, /* is previous */ true)), + db.query(queryBuilder(profileName, compare)), + ]); + + // create Dataframe from profile data + let profileDF = new DataIngestor( + profileData, + profileName, + isAggregate, + ).processRaw(); + + // join with previous profile data Dataframe + profileDF = profileDF.join( + new DataIngestor( + previousProfileData, + profileName, + isAggregate, + /* is previous */ true, + ).processRaw(), + 'variable', + ); + + // join with compare profile data Dataframe + profileDF = profileDF.join( + // 'compare' profiles are always NOT aggregate; they are comprised of a single geoid + new DataIngestor( + compareProfileData, + profileName, + /* is aggregate */ false, + /* is previous */ false, + /* is comparison */ true, + ).processRaw(), + 'variable', + ); + + // convert combined Dataframe to array of objects + // (change & difference calculations results in ad-hoc property addition, + // which is easier with objects than Dataframe rows) + return profileDF + .toCollection() .map((row) => { - let rowWithConfig = row; - const { category, variable, dataset } = row; - const categoryNormalized = camelCase(category); - const variables = get(tableConfigs, `${profile}.${categoryNormalized}`) || []; - rowWithConfig.rowConfig = find(variables, ['variable', variable]) || {}; - rowWithConfig.special = !!get(rowWithConfig, 'rowConfig.special'); - rowWithConfig.category = categoryNormalized; - rowWithConfig.numGeoids = match.geoids.length; - - // this is a special metadata object that lets the client - // know which estimates were bottom coded with which direction. - // The `delegateAggregator` special function `interpolate` - // specifically assigns properties to this object. - rowWithConfig.codingThresholds = {}; - - // if the row is "special" and the number of geoids in the - // selection are greater than 1 - // then, delete the unneeded special calculations data - - if (rowWithConfig.special && (match.geoids.length > 1)) { - const currentYear = get(fullDataset, dataset); - const newRowObject = delegateAggregator(rowWithConfig, rowWithConfig.rowConfig, currentYear); - rowWithConfig = merge(newRowObject, rowWithConfig); - } - - return rowWithConfig; + doChangeCalculations(row); + doDifferenceCalculations(row); + return row; }); -}; - -const appendIsReliable = data => (data.map((row) => { - const appendedRow = row; - appendedRow.is_reliable = false; - appendedRow.comparison_is_reliable = false; - - const { - cv, - comparison_cv, - codingThresholds, - change_m, - change_sum, - change_percent_m, - change_percent, - difference_sum, - difference_m, - } = appendedRow; - - // set reliability to true if cv is less than 20 - if (cv !== null && cv < 20) appendedRow.is_reliable = true; - if (comparison_cv !== null && comparison_cv < 20) appendedRow.comparison_is_reliable = true; - - // set reliability to false if the value is top or bottom-coded - if (codingThresholds.sum) appendedRow.is_reliable = false; - if (codingThresholds.comparison_sum) appendedRow.comparison_is_reliable = false; - - // !!!!!! These calculations were changed from determining statistical SIGNIFICANCE to determining statistical RELIABILITY in PR #39, variable names were NOT updated to reflect this calculation change - // !!!!!! These names will be updated in a broader refactor of PFF, Visit issue #57 in labs-factfinder waffle to get more info - appendedRow.significant = ((((difference_m) / 1.645) / Math.abs(difference_sum)) * 100) < 20; - appendedRow.change_significant = ((((change_m) / 1.645) / Math.abs(change_sum)) * 100) < 20; - appendedRow.change_percent_significant = ((((change_percent_m) / 1.645) / Math.abs(change_percent)) * 100) < 20; - - return appendedRow; -})); - -const invalidCompare = (compare) => { +} + +/* + * Returns the appropriate query builder for the given profile type + * @param{string} profile - The profile type + * @returns{function} + */ +function getQueryBuilder(profile) { + if (profile === 'decennial') return decennialQuery; + return profileQuery; +} + +/* + * Checks that the compare query parameter is a valid geoid + * @param{string} comp - Integer string representing the geoid of the comparison geography + * @returns{Boolean} + */ +function invalidCompare(compare) { const cityOrBoro = compare.match(/[0-5]{1}/); const nta = compare.match(/[A-Z]{2}[0-9]{2}/); const puma = compare.match(/[0-9]{4}/); if (cityOrBoro || nta || puma) return false; return true; -}; - -router.get('/:id/:profile', (req, res) => { - const { app } = req; - - const { id: _id, profile } = req.params; - const { compare = '0' } = req.query; - - // validate compare - if (invalidCompare(compare)) res.status(500).send({ error: 'invalid compare param' }); - - // validate profile - const validProfiles = ['decennial', 'demographic', 'social', 'economic', 'housing']; - if (validProfiles.indexOf(profile) === -1) res.status(500).send({ error: 'invalid profile' }); - - Selection.findOne({ _id }) - .then((match) => { - let SQL; - - if (profile === 'decennial') { - SQL = buildDecennialSQL(match.geoids, compare); - } else if (match.geoids.length === 1) { - SQL = buildProfileSingleSQL(profile, match.geoids[0], compare); - } else { - SQL = buildProfileSQL(profile, match.geoids, compare); - } - - app.db.query(SQL) - .then(data => appendRowConfig(data, profile, match)) - .then(data => appendIsReliable(data)) - .then((data) => { - res.send(data); - }) - .catch((error) => { res.status(500).send({ error: error.toString() }); }); - }); -}); +} + +/* + * Checks that the profile query parameter is a valid profile type + * @param{string} profileName - The profile type + * @returns{Boolean} + */ +function invalidProfileName(profileName) { + const validProfileNames = ['decennial', 'demographic', 'social', 'economic', 'housing']; + if (validProfileNames.includes(profileName)) return false; + return true; +} module.exports = router; diff --git a/routes/selection.js b/routes/selection.js index 67b7f08..0095020 100644 --- a/routes/selection.js +++ b/routes/selection.js @@ -11,7 +11,7 @@ const getFeatures = (type, geoids) => { const inString = geoids.map(geoid => `'${geoid}'`).join(','); const selectionClause = summaryLevels[type](false); const SQL = ` - SELECT * FROM (${selectionClause}) normalized + SELECT * FROM (${selectionClause}) normalized WHERE geoid in (${inString})`; return carto.SQL(SQL, 'geojson', 'post') diff --git a/schema/schema.sql b/schema/schema.sql index 7d7e79b..3dcdb4e 100644 --- a/schema/schema.sql +++ b/schema/schema.sql @@ -4,8 +4,7 @@ CREATE TABLE demographic ( geogname text, geoid text, dataset text, - variable text, - c double precision, + variable text, c double precision, e double precision, m double precision, p double precision, diff --git a/special-calculations/data/bins.js b/special-calculations/data/bins.js new file mode 100644 index 0000000..60f79bb --- /dev/null +++ b/special-calculations/data/bins.js @@ -0,0 +1,262 @@ +// bins used for interpolation of medians and recalculation of median margin of errors +module.exports = { + mdhhinc: [ + ['mdhhiu10', [0, 9999]], + ['mdhhi10t14', [10000, 14999]], + ['mdhhi15t19', [15000, 19999]], + ['mdhhi20t24', [20000, 24999]], + ['mdhhi25t29', [25000, 29999]], + ['mdhhi30t34', [30000, 34999]], + ['mdhhi35t39', [35000, 39999]], + ['mdhhi40t44', [40000, 44999]], + ['mdhhi45t49', [45000, 49999]], + ['mdhhi50t59', [50000, 59999]], + ['mdhhi60t74', [60000, 74999]], + ['mdhhi75t99', [75000, 99999]], + ['mdhi100t124', [100000, 124999]], + ['mdhi125t149', [125000, 149999]], + ['mdhi150t199', [150000, 199999]], + ['mdhhi200pl', [200000, 9999999]], + ], + mdfaminc: [ + ['mdfamiu10', [0, 9999]], + ['mdfami10t14', [10000, 14999]], + ['mdfami15t19', [15000, 19999]], + ['mdfami20t24', [20000, 24999]], + ['mdfami25t29', [25000, 29999]], + ['mdfami30t34', [30000, 34999]], + ['mdfami35t39', [35000, 39999]], + ['mdfami40t44', [40000, 44999]], + ['mdfami45t49', [45000, 49999]], + ['mdfami50t59', [50000, 59999]], + ['mdfami60t74', [60000, 74999]], + ['mdfami75t99', [75000, 99999]], + ['mdfi100t124', [100000, 124999]], + ['mdfi125t149', [125000, 149999]], + ['mdfi150t199', [150000, 199999]], + ['mdfami200pl', [200000, 9999999]], + ], + mdnfinc: [ + ['nfmiu10', [0, 9999]], + ['nfmi10t14', [10000, 14999]], + ['nfmi15t19', [15000, 19999]], + ['nfmi20t24', [20000, 24999]], + ['nfmi25t29', [25000, 29999]], + ['nfmi30t34', [30000, 34999]], + ['nfmi35t39', [35000, 39999]], + ['nfmi40t44', [40000, 44999]], + ['nfmi45t49', [45000, 49999]], + ['nfmi50t59', [50000, 59999]], + ['nfmi60t74', [60000, 74999]], + ['nfmi75t99', [75000, 99999]], + ['nf100t124', [100000, 124999]], + ['nf125t149', [125000, 149999]], + ['nf150t199', [150000, 199999]], + ['nfi200pl', [200000, 9999999]], + ], + mdewrk: [ + ['ernu2pt5k', [0, 2499]], + ['ern2pt5t5', [2500, 4999]], + ['ern5t7pt5', [5000, 7499]], + ['e7pt5t10', [7500, 9999]], + ['e10t12pt5', [10000, 12499]], + ['e12pt5t15', [12500, 14999]], + ['e15t17pt5', [15000, 17499]], + ['e17pt5t20', [17500, 19999]], + ['e20t22pt5', [20000, 22499]], + ['e22pt5t25', [22500, 24999]], + ['ern25t30', [25000, 29999]], + ['ern30t35', [30000, 34999]], + ['ern35t40', [35000, 39999]], + ['ern40t45', [40000, 44999]], + ['ern45t50', [45000, 49999]], + ['ern50t55', [50000, 54999]], + ['ern55t65', [55000, 64999]], + ['ern65t75', [65000, 74999]], + ['ern75t100', [75000, 99999]], + ['ern100pl', [100000, 250000]], + ], + mdemftwrk: [ + ['mftu2pt5k', [0, 2499]], + ['mft2p5t5', [2500, 4999]], + ['mft5t7p5', [5000, 7499]], + ['mft7p5t10', [7500, 9999]], + ['mf10t12p5', [10000, 12499]], + ['mf12p5t15', [12500, 14999]], + ['mf15t17p5', [15000, 17499]], + ['mf17p5t20', [17500, 19999]], + ['mf20t22p5', [20000, 22499]], + ['mf22p5t25', [22500, 24999]], + ['mft25t30', [25000, 29999]], + ['mft30t35', [30000, 34999]], + ['mft35t40', [35000, 39999]], + ['mft40t45', [40000, 44999]], + ['mft45t50', [45000, 49999]], + ['mft50t55', [50000, 54999]], + ['mft55t65', [55000, 64999]], + ['mft65t75', [65000, 74999]], + ['mft75t100', [75000, 99999]], + ['mft100pl', [100000, 250000]], + ], + mdefftwrk: [ + ['fftu2pt5k', [0, 2499]], + ['fft2p5t5', [2500, 4999]], + ['fft5t7p5', [5000, 7499]], + ['fft7p5t10', [7500, 9999]], + ['ff10t12p5', [10000, 12499]], + ['ff12p5t15', [12500, 14999]], + ['ff15t17p5', [15000, 17499]], + ['ff17p5t20', [17500, 19999]], + ['ff20t22p5', [20000, 22499]], + ['ff22p5t25', [22500, 24999]], + ['fft25t30', [25000, 29999]], + ['fft30t35', [30000, 34999]], + ['fft35t40', [35000, 39999]], + ['fft40t45', [40000, 44999]], + ['fft45t50', [45000, 49999]], + ['fft50t55', [50000, 54999]], + ['fft55t65', [55000, 64999]], + ['fft65t75', [65000, 74999]], + ['fft75t100', [75000, 99999]], + ['fft100pl', [100000, 250000]], + ], + mdgr: { + 'Y2013-2017': [ + ['ru100', [0, 99]], + ['r100t149', [100, 149]], + ['r150t199', [150, 199]], + ['r200t249', [200, 249]], + ['r250t299', [250, 299]], + ['r300t349', [300, 349]], + ['r350t399', [350, 399]], + ['r400t449', [400, 449]], + ['r450t499', [450, 499]], + ['r500t549', [500, 549]], + ['r550t599', [550, 599]], + ['r600t649', [600, 649]], + ['r650t699', [650, 699]], + ['r700t749', [700, 749]], + ['r750t799', [750, 799]], + ['r800t899', [800, 899]], + ['r900t999', [900, 999]], + ['r1kt1249', [1000, 1249]], + ['r1250t1p5', [1250, 1499]], + ['r1p5t1999', [1500, 1999]], + ['r2kt2499', [2000, 2499]], + ['r2p5t2999', [2500, 2999]], + ['r3kt3499', [3000, 3499]], + ['r3500pl', [3500, 9000]], + ], + 'Y2006-2010': [ + ['ru100', [0, 99]], + ['r100t149', [100, 149]], + ['r150t199', [150, 199]], + ['r200t249', [200, 249]], + ['r250t299', [250, 299]], + ['r300t349', [300, 349]], + ['r350t399', [350, 399]], + ['r400t449', [400, 449]], + ['r450t499', [450, 499]], + ['r500t549', [500, 549]], + ['r550t599', [550, 599]], + ['r600t649', [600, 649]], + ['r650t699', [650, 699]], + ['r700t749', [700, 749]], + ['r750t799', [750, 799]], + ['r800t899', [800, 899]], + ['r900t999', [900, 999]], + ['r1kt1249', [1000, 1249]], + ['r1250t1p5', [1250, 1499]], + ['r1p5t1999', [1500, 1999]], + ['r2000pl', [2000, 9999]], + ], + }, + mdrms: [ + ['rms1', [0, 1499]], + ['rms2', [1500, 2499]], + ['rms3', [2500, 3499]], + ['rms4', [3500, 4499]], + ['rms5', [4500, 5499]], + ['rms6', [5500, 6499]], + ['rms7', [6500, 7499]], + ['rms8', [7500, 8499]], + ['rms9pl', [8500, 9000]], + ], + mdvl: { + 'Y2013-2017': [ + ['ovlu10', [0, 9999]], + ['ovl10t14', [10000, 14999]], + ['ovl15t19', [15000, 19999]], + ['ovl20t24', [20000, 24999]], + ['ovl25t29', [25000, 29999]], + ['ovl30t34', [30000, 34999]], + ['ovl35t39', [35000, 39999]], + ['ovl40t49', [40000, 49999]], + ['ovl50t59', [50000, 59999]], + ['ovl60t69', [60000, 69999]], + ['ovl70t79', [70000, 79999]], + ['ovl80t89', [80000, 89999]], + ['ovl90t99', [90000, 99999]], + ['ov100t124', [100000, 124999]], + ['ov125t149', [125000, 149999]], + ['ov150t174', [150000, 174999]], + ['ov175t199', [175000, 199999]], + ['ov200t249', [200000, 249999]], + ['ov250t299', [250000, 299999]], + ['ov300t399', [300000, 399999]], + ['ov400t499', [400000, 499999]], + ['ov500t749', [500000, 749999]], + ['ov750t999', [750000, 999999]], + ['ov1t149m', [1000000, 1499999]], + ['ov150t199m', [1500000, 1999999]], + ['ov2milpl', [2000000, 5000000]], + ], + 'Y2006-2010': [ + ['ovlu10', [0, 9999]], + ['ovl10t14', [10000, 14999]], + ['ovl15t19', [15000, 19999]], + ['ovl20t24', [20000, 24999]], + ['ovl25t29', [25000, 29999]], + ['ovl30t34', [30000, 34999]], + ['ovl35t39', [35000, 39999]], + ['ovl40t49', [40000, 49999]], + ['ovl50t59', [50000, 59999]], + ['ovl60t69', [60000, 69999]], + ['ovl70t79', [70000, 79999]], + ['ovl80t89', [80000, 89999]], + ['ovl90t99', [90000, 99999]], + ['ov100t124', [100000, 124999]], + ['ov125t149', [125000, 149999]], + ['ov150t174', [150000, 174999]], + ['ov175t199', [175000, 199999]], + ['ov200t249', [200000, 249999]], + ['ov250t299', [250000, 299999]], + ['ov300t399', [300000, 399999]], + ['ov400t499', [400000, 499999]], + ['ov500t749', [500000, 749999]], + ['ov750t999', [750000, 999999]], + ['ov1milpl', [1000000, 9999999]], + ], + }, + mdage: [ + ['popu5', [0, 5]], + ['pop5t9', [5, 9]], + ['pop10t14', [10, 14]], + ['pop15t19', [15, 19]], + ['pop20t24', [20, 24]], + ['pop25t29', [25, 29]], + ['pop30t34', [30, 34]], + ['pop35t39', [35, 39]], + ['pop40t44', [40, 44]], + ['pop45t49', [45, 49]], + ['pop50t54', [50, 54]], + ['pop55t59', [55, 59]], + ['pop60t64', [60, 64]], + ['pop65t69', [65, 69]], + ['pop70t74', [70, 74]], + ['pop75t79', [75, 79]], + ['pop80t84', [80, 84]], + ['pop85pl', [85, 115]], + ], + +}; diff --git a/special-calculations/data/constants.js b/special-calculations/data/constants.js new file mode 100644 index 0000000..62af15c --- /dev/null +++ b/special-calculations/data/constants.js @@ -0,0 +1,34 @@ +// constants for use in special calculations +const INFLATION_FACTOR = 1.1267; // inflates 2010 dollars to 2017 dollars +const TRANSFORM_TYPE_INFLATE = 'inflate'; +const TRANSFORM_TYPE_SCALE = 'scale'; +const CV_CONST = 1.645; +const DIFF_PERCENT_THRESHOLD = -0.05; +const RENAME_COLS = [ + 'sum', + 'm', + 'cv', + 'percent', + 'percent_m', + 'codingThreshold', + 'is_reliable', +]; + +const CUR_YEAR = 'Y2013-2017'; +const PREV_YEAR = 'Y2006-2010'; + +const DECENNIAL_CUR_YEAR = '2010'; +const DECENNIAL_PREV_YEAR = '2000'; + +module.exports = { + INFLATION_FACTOR, + TRANSFORM_TYPE_INFLATE, + TRANSFORM_TYPE_SCALE, + CV_CONST, + DIFF_PERCENT_THRESHOLD, + RENAME_COLS, + CUR_YEAR, + PREV_YEAR, + DECENNIAL_CUR_YEAR, + DECENNIAL_PREV_YEAR, +}; diff --git a/special-calculations/data/top-bottom-codings.js b/special-calculations/data/top-bottom-codings.js new file mode 100644 index 0000000..5bc0061 --- /dev/null +++ b/special-calculations/data/top-bottom-codings.js @@ -0,0 +1,89 @@ +// top and bottom codings used to code median interpolations +const topBottomCodings = { + 'Y2013-2017': { + mdage: { + upper: 85, + lower: 1, + }, + mdhhinc: { + upper: 200000, + lower: 9999, + }, + mdfaminc: { + upper: 200000, + lower: 9999, + }, + mdnfinc: { + upper: 200000, + lower: 9999, + }, + mdewrk: { + upper: 100000, + lower: 2499, + }, + mdemftwrk: { + upper: 100000, + lower: 2499, + }, + mdefftwrk: { + upper: 100000, + lower: 2499, + }, + mdrms: { + upper: 9000, + lower: 0, + }, + mdvl: { + upper: 2000000, + lower: 0, + }, + mdgr: { + upper: 3500, + lower: 0, + }, + }, + 'Y2006-2010': { + mdage: { + upper: 85, + lower: 1, + }, + mdhhinc: { + upper: 225000, + lower: 11000, + }, + mdfaminc: { + upper: 225000, + lower: 11000, + }, + mdnfinc: { + upper: 225000, + lower: 11000, + }, + mdewrk: { + upper: 112500, + lower: 2800, + }, + mdemftwrk: { + upper: 112500, + lower: 2800, + }, + mdefftwrk: { + upper: 112500, + lower: 2800, + }, + mdrms: { + upper: 9000, + lower: 0, + }, + mdvl: { + upper: 1275000, + lower: 0, + }, + mdgr: { + upper: 2250, + lower: 0, + }, + }, +}; + +module.exports = topBottomCodings; diff --git a/special-calculations/decennial.js b/special-calculations/decennial.js new file mode 100644 index 0000000..ff48449 --- /dev/null +++ b/special-calculations/decennial.js @@ -0,0 +1,47 @@ +module.exports = [ + // housing-occupancy + { + variable: 'hmownrvcrt', + specialType: 'mean', + options: { args: ['vhufslo', 'oochu1'], formulaName: { sum: 'ratio' } }, + }, + { + variable: 'rntvcrt', + specialType: 'mean', + options: { args: ['vhufrnt', 'rochu_3'], formulaName: { sum: 'ratio' } }, + }, + // housing tenure + { + variable: 'avhhszooc', + specialType: 'mean', + options: { args: ['popoochu', 'oochu'] }, + }, + { + variable: 'avhhszroc', + specialType: 'mean', + options: { args: ['poprochu', 'rochu_1'] }, + }, + // population density + { + variable: 'popperacre', + specialType: 'mean', + options: { args: ['pop1', 'landacres'] }, + }, + // relationship to head of household (householder) + { + variable: 'avghhsz', + specialType: 'mean', + options: { args: ['popinhh', 'hh1'] }, + }, + { + variable: 'avgfamsz', + specialType: 'mean', + options: { args: ['popinfam', 'fam1'] }, + }, + // sex and age + { + variable: 'mdage', + specialType: 'median', + options: {}, + }, +]; diff --git a/special-calculations/demographic.js b/special-calculations/demographic.js new file mode 100644 index 0000000..44b935f --- /dev/null +++ b/special-calculations/demographic.js @@ -0,0 +1,7 @@ +module.exports = [ + { + variable: 'mdage', + specialType: 'median', + options: { designFactor: 1.1 }, + }, +]; diff --git a/special-calculations/economic.js b/special-calculations/economic.js new file mode 100644 index 0000000..0ccc29a --- /dev/null +++ b/special-calculations/economic.js @@ -0,0 +1,52 @@ +const { TRANSFORM_TYPE_INFLATE: INFLATE } = require('./data/constants'); + +module.exports = [ + // income and benefits + { + variable: 'mdhhinc', + specialType: 'median', + options: { designFactor: 1.5, transform: { type: INFLATE } }, + }, + { + variable: 'mnhhinc', + specialType: 'mean', + options: { args: ['aghhinc', 'hh2'], transform: { type: INFLATE } }, + }, + { + variable: 'mdfaminc', + specialType: 'median', + options: { designFactor: 1.5, transform: { type: INFLATE } }, + }, + { + variable: 'mdnfinc', + specialType: 'median', + options: { designFactor: 1.5, transform: { type: INFLATE } }, + }, + { + variable: 'percapinc', + specialType: 'mean', + options: { args: ['agip15pl', 'pop_6'], transform: { type: INFLATE } }, + }, + // earnings + { + variable: 'mdewrk', + type: 'median', + options: { designFactor: 1.6, transform: { type: INFLATE } }, + }, + { + variable: 'mdemftwrk', + type: 'median', + options: { designFactor: 1.6, transform: { type: INFLATE } }, + }, + { + variable: 'mdefftwrk', + type: 'median', + options: { designFactor: 1.6, transform: { type: INFLATE } }, + }, + // commute to work + { + variable: 'mntrvtm', + type: 'mean', + options: { args: ['agttm', 'wrkrnothm'] }, + }, +]; diff --git a/special-calculations/housing.js b/special-calculations/housing.js new file mode 100644 index 0000000..dda6a64 --- /dev/null +++ b/special-calculations/housing.js @@ -0,0 +1,55 @@ +const { + TRANSFORM_TYPE_SCALE: SCALE, + TRANSFORM_TYPE_INFLATE: INFLATE, +} = require('./data/constants'); + +module.exports = [ + // gross rent + { + variable: 'mdgr', + specialType: 'median', + options: { designFactor: 1.6, transform: { type: INFLATE } }, + }, + // housing occupancy + { + variable: 'hovacrt', + specialType: 'mean', + options: { + args: ['vacsale', 'hovacu'], + formulaName: { m: 'rate' }, + transform: { type: SCALE, factor: 100 }, + }, + }, + { + variable: 'rntvacrt', + specialType: 'mean', + options: { + args: ['vacrnt', 'rntvacu'], + formulaName: { m: 'rate' }, + transform: { type: SCALE, factor: 100 }, + }, + }, + // housing tenure + { + variable: 'avghhsooc', + specialType: 'mean', + options: { args: ['popoochu', 'oochu1'] }, + }, + { + variable: 'avghhsroc', + specialType: 'mean', + options: { args: ['poprtochu', 'rochu1'] }, + }, + // rooms + { + variable: 'mdrms', + specialType: 'median', + options: { transform: { type: SCALE, factor: 0.001 } }, + }, + // value + { + variable: 'mdvl', + specialType: 'median', + options: { designFactor: 1.4, transform: { type: INFLATE } }, + }, +]; diff --git a/table-config/index.js b/special-calculations/index.js similarity index 94% rename from table-config/index.js rename to special-calculations/index.js index d81a64c..a747250 100644 --- a/table-config/index.js +++ b/special-calculations/index.js @@ -1,5 +1,3 @@ -// @create-index - const decennial = require('./decennial'); const demographic = require('./demographic'); const economic = require('./economic'); diff --git a/special-calculations/social.js b/special-calculations/social.js new file mode 100644 index 0000000..d42dfd3 --- /dev/null +++ b/special-calculations/social.js @@ -0,0 +1,12 @@ +module.exports = [ + { + variable: 'avghhsz', + specialType: 'mean', + options: { args: ['hhpop', 'hh1'] }, + }, + { + variable: 'avgfmsz', + specialType: 'mean', + options: { args: ['popinfms', 'fam1'] }, + }, +]; diff --git a/table-config/decennial/asian-subgroup.js b/table-config/decennial/asian-subgroup.js deleted file mode 100644 index 7d19582..0000000 --- a/table-config/decennial/asian-subgroup.js +++ /dev/null @@ -1,85 +0,0 @@ -module.exports = [ - { - highlight: true, - title: 'Asian alone or in combination', - variable: 'asnalnorc', - }, - { - title: 'Total Asian only', - variable: 'asnalone', - }, - { - indent: 1, - title: 'Asian Indian', - variable: 'asnind', - }, - { - indent: 1, - title: 'Bangladeshi', - variable: 'bgldsh', - }, - { - indent: 1, - title: 'Cambodian', - variable: 'cambdn', - }, - { - indent: 1, - title: 'Chinese, including Taiwanese', - variable: 'chinese', - }, - { - indent: 1, - title: 'Filipino', - variable: 'filipino', - }, - { - indent: 1, - title: 'Indonesian', - variable: 'indonsn', - }, - { - indent: 1, - title: 'Japanese', - variable: 'japanese', - }, - { - indent: 1, - title: 'Korean', - variable: 'korean', - }, - { - indent: 1, - title: 'Malaysian', - variable: 'mlysn', - }, - { - indent: 1, - title: 'Pakistani', - variable: 'pak', - }, - { - indent: 1, - title: 'Sri Lankan', - variable: 'slkn', - }, - { - indent: 1, - title: 'Thai', - variable: 'thai', - }, - { - indent: 1, - title: 'Vietnamese', - variable: 'vietnms', - }, - { - indent: 1, - title: 'Other Asian and 2 or more Asian categories', - variable: 'oasnalone', - }, - { - title: 'Asian in combination with another race', - variable: 'asnincombo', - }, -]; diff --git a/table-config/decennial/hispanic-subgroup.js b/table-config/decennial/hispanic-subgroup.js deleted file mode 100644 index 355dc3c..0000000 --- a/table-config/decennial/hispanic-subgroup.js +++ /dev/null @@ -1,120 +0,0 @@ -module.exports = [ - { - highlight: true, - title: 'Total Hispanic/Latino', - variable: 'hsp2', - }, - { - title: 'Mexican', - variable: 'mex', - }, - { - title: 'Puerto Rican', - variable: 'pr', - }, - { - title: 'Cuban', - variable: 'cub', - }, - { - title: 'Dominican (Dominican Republic)', - variable: 'dom', - }, - { - title: 'Central American', - variable: 'cam', - }, - { - indent: 1, - title: 'Costa Rican', - variable: 'cric', - }, - { - indent: 1, - title: 'Guatemalan', - variable: 'guat', - }, - { - indent: 1, - title: 'Honduran', - variable: 'hon', - }, - { - indent: 1, - title: 'Nicaraguan', - variable: 'nic', - }, - { - indent: 1, - title: 'Panamanian', - variable: 'pan', - }, - { - indent: 1, - title: 'Salvadoran', - variable: 'slv', - }, - { - indent: 1, - title: 'Other Central American', - variable: 'oca', - }, - { - title: 'South American', - variable: 'sam', - }, - { - indent: 1, - title: 'Argentinean', - variable: 'arg', - }, - { - indent: 1, - title: 'Bolivian', - variable: 'bol', - }, - { - indent: 1, - title: 'Chilean', - variable: 'chi', - }, - { - indent: 1, - title: 'Colombian', - variable: 'col', - }, - { - indent: 1, - title: 'Ecuadorian', - variable: 'ecu', - }, - { - indent: 1, - title: 'Paraguayan', - variable: 'par', - }, - { - indent: 1, - title: 'Peruvian', - variable: 'per', - }, - { - indent: 1, - title: 'Uruguayan', - variable: 'uru', - }, - { - indent: 1, - title: 'Venezuelan', - variable: 'ven', - }, - { - indent: 1, - title: 'Other South American', - variable: 'osa', - }, - { - title: 'Other Hispanic/Latino', - variable: 'ohsp', - }, -]; diff --git a/table-config/decennial/household-size.js b/table-config/decennial/household-size.js deleted file mode 100644 index 5d7ef6b..0000000 --- a/table-config/decennial/household-size.js +++ /dev/null @@ -1,35 +0,0 @@ -module.exports = [ - { - highlight: true, - title: 'Total occupied housing units', - variable: 'ochu_4', - }, - { - title: '1-person household', - variable: 'hh1person', - }, - { - title: '2-person household', - variable: 'hh2ppl', - }, - { - title: '3-person household', - variable: 'hh3ppl', - }, - { - title: '4-person household', - variable: 'hh4ppl', - }, - { - title: '5-person household', - variable: 'hh5ppl', - }, - { - title: '6-person household', - variable: 'hh6ppl', - }, - { - title: '7-or-more person household', - variable: 'hh7plppl', - }, -]; diff --git a/table-config/decennial/household-type.js b/table-config/decennial/household-type.js deleted file mode 100644 index 6fb27b7..0000000 --- a/table-config/decennial/household-type.js +++ /dev/null @@ -1,72 +0,0 @@ -module.exports = [ - { - highlight: true, - title: 'Total households', - variable: 'hh', - }, - { - indent: 1, - title: 'Family households (families)', - variable: 'fam', - }, - { - indent: 1, - title: 'With related children under 18 years', - variable: 'fmrelchu18', - }, - { - indent: 1, - title: 'Married-couple family', - variable: 'mcfm', - }, - { - indent: 2, - title: 'With related children under 18 years', - variable: 'mcfmrchu18', - }, - { - indent: 1, - title: 'Female householder, no husband present', - variable: 'femnhsb', - }, - { - indent: 2, - title: 'With related children under 18 years', - variable: 'fnhrchu18', - }, - { - indent: 1, - title: 'Male householder, no wife present', - variable: 'malenwf', - }, - { - indent: 2, - title: 'With related children under 18 years', - variable: 'mnwrchu18', - }, - { - title: 'Nonfamily households', - variable: 'nfamhh', - }, - { - indent: 1, - title: 'Householder living alone', - variable: 'nfmlvgaln', - }, - { - indent: 2, - title: 'Householder 65 years and over', - variable: 'nflval65p', - }, - { - divider: true, - }, - { - title: 'Households with individuals under 18 years', - variable: 'hhwindu18', - }, - { - title: 'Households with individuals 65 years and over', - variable: 'hhwind65p', - }, -]; diff --git a/table-config/decennial/housing-occupancy.js b/table-config/decennial/housing-occupancy.js deleted file mode 100644 index c0e1d22..0000000 --- a/table-config/decennial/housing-occupancy.js +++ /dev/null @@ -1,135 +0,0 @@ -const formula = require('../../utils/formula'); - -module.exports = [ - { - highlight: true, - title: 'Total housing units', - variable: 'hunits', - }, - { - title: 'Occupied housing units', - variable: 'ochu_1', - }, - { - title: 'Vacant housing units', - variable: 'vachus', - }, - { - indent: 1, - title: 'For rent', - variable: 'vhufrnt', - }, - { - indent: 1, - title: 'For sale only', - variable: 'vhufslo', - }, - { - indent: 1, - title: 'Rented or sold, not occupied', - variable: 'vhurosnoc', - }, - { - indent: 1, - title: 'For seasonal, recreational, or occasional use', - variable: 'vhufsroou', - }, - { - indent: 1, - title: 'Other vacant', - variable: 'vhuothvc', - }, - { - divider: true, - }, - { - title: 'Homeowner vacancy rate (percent)', - tooltip: 'Number of vacant units "for sale only," divided by sum of owner-occupied units and vacant units "for sale only," multiplied by 100. (Used definition from 2000 for consistency in measuring change.)', - variable: 'hmownrvcrt', - decimal: 1, - special: true, - hidePercentChange: true, - specialCalculations: [ - { - column: 'sum', - aggregator: formula, - options: { - formula: '((GET("vhufslo.sum"))/((GET("vhufslo.sum"))+(GET("oochu1.sum"))))*100', - }, - }, - { - column: 'comparison_sum', - aggregator: formula, - options: { - formula: '((GET("vhufslo.comparison_sum"))/((GET("vhufslo.comparison_sum"))+(GET("oochu1.comparison_sum"))))*100', - }, - }, - { - column: 'previous_sum', - aggregator: formula, - options: { - formula: '((GET("vhufslo.previous_sum"))/((GET("vhufslo.previous_sum"))+(GET("oochu1.previous_sum"))))*100', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("hmownrvcrt.sum") - GET("hmownrvcrt.comparison_sum"))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("hmownrvcrt.sum") - GET("hmownrvcrt.previous_sum"))', - }, - }, - ], - }, - { - title: 'Rental vacancy rate (percent)', - tooltip: 'Number of vacant units "for rent," divided by sum of renter-occupied units and vacant units "for rent," multiplied by 100. (Used definition from 2000 for consistency in measuring change.)', - variable: 'rntvcrt', - decimal: 1, - special: true, - hidePercentChange: true, - specialCalculations: [ - { - column: 'sum', - aggregator: formula, - options: { - formula: '((GET("vhufrnt.sum"))/((GET("vhufrnt.sum"))+(GET("rochu_3.sum"))))*100', - }, - }, - { - column: 'comparison_sum', - aggregator: formula, - options: { - formula: '((GET("vhufrnt.comparison_sum"))/((GET("vhufrnt.comparison_sum"))+(GET("rochu_3.comparison_sum"))))*100', - }, - }, - { - column: 'previous_sum', - aggregator: formula, - options: { - formula: '((GET("vhufrnt.previous_sum"))/((GET("vhufrnt.previous_sum"))+(GET("rochu_3.previous_sum"))))*100', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("rntvcrt.sum") - GET("rntvcrt.comparison_sum"))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("rntvcrt.sum") - GET("rntvcrt.previous_sum"))', - }, - }, - ], - }, -]; diff --git a/table-config/decennial/housing-tenure.js b/table-config/decennial/housing-tenure.js deleted file mode 100644 index a258a1d..0000000 --- a/table-config/decennial/housing-tenure.js +++ /dev/null @@ -1,110 +0,0 @@ -const formula = require('../../utils/formula'); - -module.exports = [ - { - highlight: true, - title: 'Occupied housing units', - variable: 'ochu_2', - }, - { - title: 'Owner-occupied housing units', - variable: 'oochu', - }, - { - title: 'Renter-occupied housing units', - variable: 'rochu_1', - }, - { - divider: true, - }, - { - title: 'Average household size of owner-occupied units', - tooltip: 'Number of people living in owner-occupied housing units, divided by number of owner-occupied housing units', - variable: 'avhhszooc', - decimal: 2, - special: true, - hidePercentChange: true, - specialCalculations: [ - { - column: 'sum', - aggregator: formula, - options: { - formula: '(GET("popoochu.sum"))/(GET("oochu.sum"))', - }, - }, - { - column: 'comparison_sum', - aggregator: formula, - options: { - formula: '(GET("popoochu.comparison_sum"))/(GET("oochu.comparison_sum"))', - }, - }, - { - column: 'previous_sum', - aggregator: formula, - options: { - formula: '(GET("popoochu.previous_sum"))/(GET("oochu.previous_sum"))', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("avhhszooc.sum") - GET("avhhszooc.comparison_sum"))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("avhhszooc.sum") - GET("avhhszooc.previous_sum"))', - }, - }, - ], - }, - { - title: 'Average household size of renter-occupied units', - tooltip: 'Number of people living in renter-occupied housing units, divided by number of renter-occupied housing units', - variable: 'avhhszroc', - decimal: 2, - special: true, - hidePercentChange: true, - specialCalculations: [ - { - column: 'sum', - aggregator: formula, - options: { - formula: '(GET("poprochu.sum"))/(GET("rochu_1.sum"))', - }, - }, - { - column: 'comparison_sum', - aggregator: formula, - options: { - formula: '(GET("poprochu.comparison_sum"))/(GET("rochu_1.comparison_sum"))', - }, - }, - { - column: 'previous_sum', - aggregator: formula, - options: { - formula: '(GET("poprochu.previous_sum"))/(GET("rochu_1.previous_sum"))', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("avhhszroc.sum") - GET("avhhszroc.comparison_sum"))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("avhhszroc.sum") - GET("avhhszroc.previous_sum"))', - }, - }, - ], - }, -]; diff --git a/table-config/decennial/index.js b/table-config/decennial/index.js deleted file mode 100644 index 6c6e2f7..0000000 --- a/table-config/decennial/index.js +++ /dev/null @@ -1,27 +0,0 @@ -// @create-index - -const asianSubgroup = require('./asian-subgroup'); -const relationshipToHeadOfHouseholdHouseholder = require('./relationship-to-head-of-household--householder'); -const hispanicSubgroup = require('./hispanic-subgroup'); -const householdSize = require('./household-size'); -const householdType = require('./household-type'); -const housingOccupancy = require('./housing-occupancy'); -const housingTenure = require('./housing-tenure'); -const mutuallyExclusiveRaceHispanicOrigin = require('./mutually-exclusive-race---hispanic-origin'); -const populationDensity = require('./population-density'); -const sexAndAge = require('./sex-and-age'); -const tenureByAgeOfHouseholder = require('./tenure-by-age-of-householder'); - -module.exports = { - asianSubgroup, - relationshipToHeadOfHouseholdHouseholder, - hispanicSubgroup, - householdSize, - householdType, - housingOccupancy, - housingTenure, - mutuallyExclusiveRaceHispanicOrigin, - populationDensity, - sexAndAge, - tenureByAgeOfHouseholder, -}; diff --git a/table-config/decennial/mutually-exclusive-race---hispanic-origin.js b/table-config/decennial/mutually-exclusive-race---hispanic-origin.js deleted file mode 100644 index e1794fd..0000000 --- a/table-config/decennial/mutually-exclusive-race---hispanic-origin.js +++ /dev/null @@ -1,31 +0,0 @@ -module.exports = [ - { - highlight: true, - title: 'Total population', - variable: 'pop3', - }, - { - title: 'Hispanic/Latino (of any race)', - variable: 'hsp1', - }, - { - title: 'White nonhispanic', - variable: 'wnh', - }, - { - title: 'Black/African American nonhispanic', - variable: 'bnh', - }, - { - title: 'Asian nonhispanic', - variable: 'anh', - }, - { - title: 'Some other race nonhispanic', - variable: 'onh', - }, - { - title: 'Nonhispanic of two or more races', - variable: 'twoplnh', - }, -]; diff --git a/table-config/decennial/population-density.js b/table-config/decennial/population-density.js deleted file mode 100644 index fc9b139..0000000 --- a/table-config/decennial/population-density.js +++ /dev/null @@ -1,53 +0,0 @@ -const formula = require('../../utils/formula'); - -module.exports = [ - { - title: 'Total population', - variable: 'pop1', - }, - { - title: 'Population per acre', - tooltip: 'Total population divided by land area (in acres)', - variable: 'popperacre', - decimal: 1, - special: true, - hidePercentChange: true, - specialCalculations: [ - { - column: 'sum', - aggregator: formula, - options: { - formula: '(GET("pop1.sum"))/(GET("landacres.sum"))', - }, - }, - { - column: 'previous_sum', - aggregator: formula, - options: { - formula: '(GET("pop1.previous_sum"))/(GET("landacres.previous_sum"))', - }, - }, - { - column: 'comparison_sum', - aggregator: formula, - options: { - formula: '(GET("pop1.comparison_sum"))/(GET("landacres.comparison_sum"))', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("popperacre.sum") - GET("popperacre.comparison_sum"))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("popperacre.sum") - GET("popperacre.previous_sum"))', - }, - }, - ], - }, -]; diff --git a/table-config/decennial/relationship-to-head-of-household--householder.js b/table-config/decennial/relationship-to-head-of-household--householder.js deleted file mode 100644 index 7a2149e..0000000 --- a/table-config/decennial/relationship-to-head-of-household--householder.js +++ /dev/null @@ -1,278 +0,0 @@ -const formula = require('../../utils/formula'); - -module.exports = [ - { - highlight: true, - title: 'Total population', - variable: 'pop4', - }, - { - title: 'In households', - variable: 'popinhh', - }, - { - indent: 1, - title: 'In family households', - variable: 'popinfhh', - }, - { - indent: 2, - title: 'Householder', - variable: 'hhldr', - }, - { - indent: 2, - title: 'Spouse', - variable: 'spouse', - }, - { - indent: 2, - title: 'Own child under 18 years', - variable: 'owncu18', - }, - { - indent: 2, - title: 'Other relatives', - variable: 'othrrel', - }, - { - indent: 2, - title: 'Nonrelatives', - variable: 'nonrel', - }, - { - indent: 3, - title: 'Unmarried partner', - variable: 'nrelumptnr', - }, - { - indent: 1, - title: 'In nonfamily households', - variable: 'nonfamhh', - }, - { - indent: 2, - title: 'Householder', - variable: 'nfhhldr', - }, - { - indent: 2, - title: 'Nonrelatives', - variable: 'nfnonrel', - }, - { - indent: 3, - title: 'Unmarried partner', - variable: 'nfunmptnr', - }, - { - title: 'In group quarters', - variable: 'ingrpqtrs', - }, - { - indent: 1, - title: 'Institutionalized', - variable: 'institlzd', - }, - { - divider: true, - }, - { - title: 'Average household size', - tooltip: 'Household population divided by number of households', - variable: 'avghhsz', - decimal: 2, - special: true, - hidePercentChange: true, - specialCalculations: [ - { - column: 'sum', - aggregator: formula, - options: { - formula: '(GET("popinhh.sum"))/(GET("hh1.sum"))', - }, - }, - { - column: 'comparison_sum', - aggregator: formula, - options: { - formula: '(GET("popinhh.comparison_sum"))/(GET("hh1.comparison_sum"))', - }, - }, - { - column: 'previous_sum', - aggregator: formula, - options: { - formula: '(GET("popinhh.previous_sum"))/(GET("hh1.previous_sum"))', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("avghhsz.sum") - GET("avghhsz.comparison_sum"))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("avghhsz.sum") - GET("avghhsz.previous_sum"))', - }, - }, - ], - }, - { - title: 'Average family size', - tooltip: 'Population in family households, minus nonrelatives in family households, divded by number of family households', - variable: 'avgfamsz', - decimal: 2, - special: true, - hidePercentChange: true, - specialCalculations: [ - { - column: 'sum', - aggregator: formula, - options: { - formula: '(GET("popinfam.sum"))/(GET("fam1.sum"))', - }, - }, - { - column: 'previous_sum', - aggregator: formula, - options: { - formula: '(GET("popinfam.previous_sum"))/(GET("fam1.previous_sum"))', - }, - }, - { - column: 'comparison_sum', - aggregator: formula, - options: { - formula: '(GET("popinfam.comparison_sum"))/(GET("fam1.comparison_sum"))', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("avgfamsz.sum") - GET("avgfamsz.comparison_sum"))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("avgfamsz.sum") - GET("avgfamsz.previous_sum"))', - }, - }, - ], - }, - { - divider: true, - }, - { - highlight: true, - title: 'Total persons under 18 years', - variable: 'popu18_2', - }, - { - title: 'Householder or spouse', - variable: 'hhldru18', - }, - { - title: 'Own child', - variable: 'ownchu18', - }, - { - indent: 1, - title: 'In married-couple family', - variable: 'ocinmcfu18', - }, - { - indent: 1, - title: 'In other family', - variable: 'ocinofu18', - }, - { - indent: 2, - title: 'Female householder', - variable: 'ocinfhhu18', - }, - { - title: 'Other relatives', - variable: 'orelu18', - }, - { - indent: 1, - title: 'Grandchild', - variable: 'grndchu18', - }, - { - title: 'Nonrelatives', - variable: 'nonrelu18', - }, - { - title: 'In group quarters', - variable: 'ingqu18', - }, - { - divider: true, - }, - { - highlight: true, - title: 'Total persons 65 years and over', - variable: 'pop65pl_2', - }, - { - title: 'In family households', - variable: 'infmhh65p', - }, - { - indent: 1, - title: 'Householder', - variable: 'ifhhldr65p', - }, - { - indent: 1, - title: 'Spouse', - variable: 'ifsps65p', - }, - { - indent: 1, - title: 'Other relatives', - variable: 'iforel65p', - }, - { - indent: 1, - title: 'Nonrelatives', - variable: 'ifnrel65p', - }, - { - title: 'In nonfamily households', - variable: 'innfmhh65p', - }, - { - indent: 1, - title: 'Householder', - variable: 'infhhlr65p', - }, - { - indent: 2, - title: 'Living alone', - variable: 'inflval65p', - }, - { - indent: 1, - title: 'Nonrelatives', - variable: 'infnrel65p', - }, - { - title: 'In group quarters', - variable: 'ingq65p', - }, - { - indent: 1, - title: 'Institutionalized', - variable: 'instgq65p', - }, -]; diff --git a/table-config/decennial/sex-and-age.js b/table-config/decennial/sex-and-age.js deleted file mode 100644 index 98b2a90..0000000 --- a/table-config/decennial/sex-and-age.js +++ /dev/null @@ -1,249 +0,0 @@ -const interpolate = require('../../utils/interpolate'); -const formula = require('../../utils/formula'); - -module.exports = [ - - { - title: 'Total population', - highlight: true, - variable: 'pop2', - }, - { - title: 'Male', - classNames: '', - variable: 'male', - }, - { - title: 'Female', - classNames: '', - variable: 'fem', - }, - { - divider: true, - }, - { - title: 'Under 5 years', - classNames: '', - variable: 'popu5', - }, - { - title: '5 to 9 years', - classNames: '', - variable: 'pop5t9', - }, - { - title: '10 to 14 years', - classNames: '', - variable: 'pop10t14', - }, - { - title: '15 to 19 years', - classNames: '', - variable: 'pop15t19', - }, - { - title: '20 to 24 years', - classNames: '', - variable: 'pop20t24', - }, - { - title: '25 to 29 years', - classNames: '', - variable: 'pop25t29', - }, - { - title: '30 to 34 years', - classNames: '', - variable: 'pop30t34', - }, - { - title: '35 to 39 years', - classNames: '', - variable: 'pop35t39', - }, - { - title: '40 to 44 years', - classNames: '', - variable: 'pop40t44', - }, - { - title: '45 to 49 years', - classNames: '', - variable: 'pop45t49', - }, - { - title: '50 to 54 years', - classNames: '', - variable: 'pop50t54', - }, - { - title: '55 to 59 years', - classNames: '', - variable: 'pop55t59', - }, - { - title: '60 to 64 years', - classNames: '', - variable: 'pop60t64', - }, - { - title: '65 to 69 years', - classNames: '', - variable: 'pop65t69', - }, - { - title: '70 to 74 years', - classNames: '', - variable: 'pop70t74', - }, - { - title: '75 to 79 years', - classNames: '', - variable: 'pop75t79', - }, - { - title: '80 to 84 years', - classNames: '', - variable: 'pop80t84', - }, - { - title: '85 years and over', - classNames: '', - variable: 'pop85pl', - }, - { - divider: true, - }, - { - title: 'Median age (years)', - tooltip: 'Medians are calculated using linear interpolation, which may result in top-coded values', - classNames: '', - variable: 'mdage', - special: true, - decimal: 1, - hidePercentChange: true, - specialCalculations: [ - { - column: 'previous_sum', - aggregator: interpolate, - options: { - bins: [ - ['popu5', [0, 5]], - ['pop5t9', [5, 9]], - ['pop10t14', [10, 14]], - ['pop15t19', [15, 19]], - ['pop20t24', [20, 24]], - ['pop25t29', [25, 29]], - ['pop30t34', [30, 34]], - ['pop35t39', [35, 39]], - ['pop40t44', [40, 44]], - ['pop45t49', [45, 49]], - ['pop50t54', [50, 54]], - ['pop55t59', [55, 59]], - ['pop60t64', [60, 64]], - ['pop65t69', [65, 69]], - ['pop70t74', [70, 74]], - ['pop75t79', [75, 79]], - ['pop80t84', [80, 84]], - ['pop85pl', [85, 115]], - ], - }, - }, - { - column: 'sum', - aggregator: interpolate, - options: { - bins: [ - ['popu5', [0, 5]], - ['pop5t9', [5, 9]], - ['pop10t14', [10, 14]], - ['pop15t19', [15, 19]], - ['pop20t24', [20, 24]], - ['pop25t29', [25, 29]], - ['pop30t34', [30, 34]], - ['pop35t39', [35, 39]], - ['pop40t44', [40, 44]], - ['pop45t49', [45, 49]], - ['pop50t54', [50, 54]], - ['pop55t59', [55, 59]], - ['pop60t64', [60, 64]], - ['pop65t69', [65, 69]], - ['pop70t74', [70, 74]], - ['pop75t79', [75, 79]], - ['pop80t84', [80, 84]], - ['pop85pl', [85, 115]], - ], - }, - }, - { - column: 'comparison_sum', - aggregator: interpolate, - options: { - bins: [ - ['popu5', [0, 5]], - ['pop5t9', [5, 9]], - ['pop10t14', [10, 14]], - ['pop15t19', [15, 19]], - ['pop20t24', [20, 24]], - ['pop25t29', [25, 29]], - ['pop30t34', [30, 34]], - ['pop35t39', [35, 39]], - ['pop40t44', [40, 44]], - ['pop45t49', [45, 49]], - ['pop50t54', [50, 54]], - ['pop55t59', [55, 59]], - ['pop60t64', [60, 64]], - ['pop65t69', [65, 69]], - ['pop70t74', [70, 74]], - ['pop75t79', [75, 79]], - ['pop80t84', [80, 84]], - ['pop85pl', [85, 115]], - ], - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("mdage.sum") - GET("mdage.previous_sum"))', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("mdage.sum") - GET("mdage.comparison_sum"))', - }, - }, - ], - }, - { - divider: true, - }, - { - title: 'Under 18 years', - variable: 'popu18', - }, - { - title: '21 years and over', - variable: 'pop21pl', - }, - { - title: '62 years and over', - variable: 'pop62pl', - }, - { - title: '65 years and over', - variable: 'pop65pl_1', - }, - { - indent: 1, - title: 'Male', - variable: 'pop65plm', - }, - { - indent: 1, - title: 'Female', - variable: 'pop65plf', - }, -]; diff --git a/table-config/decennial/tenure-by-age-of-householder.js b/table-config/decennial/tenure-by-age-of-householder.js deleted file mode 100644 index 8cae0ec..0000000 --- a/table-config/decennial/tenure-by-age-of-householder.js +++ /dev/null @@ -1,83 +0,0 @@ -module.exports = [ { - highlight: true, - title: 'Total occupied housing units', - variable: 'ochu_3', - }, - { - title: '15 to 24 years', - variable: 'hhr15t24', - }, - { - title: '25 to 34 years', - variable: 'hhr25t34', - }, - { - title: '35 to 44 years', - variable: 'hhr35t44', - }, - { - title: '45 to 54 years', - variable: 'hhr45t54', - }, - { - title: '55 to 64 years', - variable: 'hhr55t64', - }, - { - title: '65 to 74 years', - variable: 'hhr65t74', - }, - { - title: '75 years and over', - variable: 'hhr75p', - }, - { - indent: 1, - title: '85 years and over', - variable: 'hhr85p', - }, - { - title: 'Renter-occupied housing units', - variable: 'rochu_2', - }, - { - indent: 1, - title: '15 to 24 years', - variable: 'rntr15t24', - }, - { - indent: 1, - title: '25 to 34 years', - variable: 'rntr25t34', - }, - { - indent: 1, - title: '35 to 44 years', - variable: 'rntr35t44', - }, - { - indent: 1, - title: '45 to 54 years', - variable: 'rntr45t54', - }, - { - indent: 1, - title: '55 to 64 years', - variable: 'rntr55t64', - }, - { - indent: 1, - title: '65 to 74 years', - variable: 'rntr65t74', - }, - { - indent: 1, - title: '75 years and over', - variable: 'rntr75p', - }, - { - indent: 2, - title: '85 years and over', - variable: 'rntr85p', - }, -]; diff --git a/table-config/demographic/asian-subgroup.js b/table-config/demographic/asian-subgroup.js deleted file mode 100644 index c1d79f0..0000000 --- a/table-config/demographic/asian-subgroup.js +++ /dev/null @@ -1,132 +0,0 @@ -module.exports = [ - { - title: 'Asian Alone', - highlight: true, - variable: 'asn1rc', - }, - { - title: 'East Asian', - variable: 'asneast', - }, - { - indent: 1, - title: 'Chinese, except Taiwanese', - variable: 'asnchinot', - }, - { - indent: 1, - title: 'Japanese', - variable: 'asnjpn', - }, - { - indent: 1, - title: 'Korean', - variable: 'asnkor', - }, - { - indent: 1, - title: 'Mongolian', - variable: 'asnmgol', - }, - { - indent: 1, - title: 'Okinawan', - variable: 'asnokinw', - }, - { - indent: 1, - title: 'Taiwanese', - variable: 'asntwn', - }, - { - title: 'South Asian', - variable: 'asnsouth', - }, - { - indent: 1, - title: 'Asian Indian', - variable: 'asnind', - }, - { - indent: 1, - title: 'Bangladeshi', - variable: 'asnbng', - }, - { - indent: 1, - title: 'Bhutanese', - variable: 'asnbhutn', - }, - { - indent: 1, - title: 'Nepalese', - variable: 'asnnepal', - }, - { - indent: 1, - title: 'Pakistani', - variable: 'asnpak', - }, - { - indent: 1, - title: 'Sri Lankan', - variable: 'asnsril', - }, - { - title: 'Southeast Asian', - variable: 'asnseast', - }, - { - indent: 1, - title: 'Burmese', - variable: 'asnburm', - }, - { - indent: 1, - title: 'Cambodian', - variable: 'asncmb', - }, - { - indent: 1, - title: 'Filipino', - variable: 'asnflp', - }, - { - indent: 1, - title: 'Hmong', - variable: 'asnhmng', - }, - { - indent: 1, - title: 'Indonesian', - variable: 'asnindnsn', - }, - { - indent: 1, - title: 'Laotian', - variable: 'asnlao', - }, - { - indent: 1, - title: 'Malaysian', - variable: 'asnmalsn', - }, - { - indent: 1, - title: 'Thai', - variable: 'asnthai', - }, - { - indent: 1, - title: 'Vietnamese', - variable: 'asnvtn', - }, - { - title: 'Other Asian', - variable: 'asnoasn', - }, - { - title: 'Two or more Asian', - variable: 'asn2pl', - }, -]; diff --git a/table-config/demographic/hispanic-subgroup.js b/table-config/demographic/hispanic-subgroup.js deleted file mode 100644 index 5872720..0000000 --- a/table-config/demographic/hispanic-subgroup.js +++ /dev/null @@ -1,140 +0,0 @@ -module.exports = [ - { - title: 'Hispanic/Latino', - highlight: true, - variable: 'hsp2', - }, - { - title: 'Mexican', - variable: 'hspme', - }, - { - title: 'Puerto Rican', - variable: 'hsppr', - }, - { - title: 'Cuban', - variable: 'hspcub', - }, - { - title: 'Dominican (Dominican Republic)', - variable: 'hspdom', - }, - { - title: 'Central American', - variable: 'hspcam', - }, - { - title: 'Costa Rican', - indent: 1, - variable: 'hspcr', - }, - { - title: 'Guatemalan', - indent: 1, - variable: 'hspguatm', - }, - { - title: 'Honduran', - indent: 1, - variable: 'hsphnd', - }, - { - title: 'Nicaraguan', - indent: 1, - variable: 'hspnic', - }, - { - title: 'Panamanian', - indent: 1, - variable: 'hsppan', - }, - { - title: 'Salvadoran', - indent: 1, - variable: 'hspsalv', - }, - { - title: 'Other Central American', - indent: 1, - variable: 'hspocam', - }, - { - title: 'South American', - variable: 'hspsam', - }, - { - title: 'Argentinean', - indent: 1, - variable: 'hsparg', - }, - { - title: 'Bolivian', - indent: 1, - variable: 'hspbol', - }, - { - title: 'Chilean', - indent: 1, - variable: 'hspchl', - }, - { - title: 'Colombian', - indent: 1, - variable: 'hspcol', - }, - { - title: 'Ecuadorian', - indent: 1, - variable: 'hspec', - }, - { - title: 'Paraguayan', - indent: 1, - variable: 'hspprg', - }, - { - title: 'Peruvian', - indent: 1, - variable: 'hspperu', - }, - { - title: 'Uruguayan', - indent: 1, - variable: 'hspurg', - }, - { - title: 'Venezuelan', - indent: 1, - variable: 'hspvnz', - }, - { - title: 'Other South American', - indent: 1, - variable: 'hsposam', - }, - { - title: 'Other Hispanic/Latino', - variable: 'hspoth', - }, - { - title: 'Spaniard', - indent: 1, - variable: 'hspspnrd', - }, - { - title: 'Spanish', - indent: 1, - variable: 'hspspnsh', - }, - { - title: 'Spanish American', - indent: 1, - variable: 'hspspam', - }, - { - title: 'All other Hispanic/Latino', - indent: 1, - variable: 'hspalloth', - }, -]; diff --git a/table-config/demographic/index.js b/table-config/demographic/index.js deleted file mode 100644 index eebda89..0000000 --- a/table-config/demographic/index.js +++ /dev/null @@ -1,13 +0,0 @@ -// @create-index - -const asianSubgroup = require('./asian-subgroup'); -const hispanicSubgroup = require('./hispanic-subgroup'); -const mutuallyExclusiveRaceHispanicOrigin = require('./mutually-exclusive-race-hispanic-origin'); -const sexAndAge = require('./sex-and-age'); - -module.exports = { - asianSubgroup, - hispanicSubgroup, - mutuallyExclusiveRaceHispanicOrigin, - sexAndAge, -}; diff --git a/table-config/demographic/mutually-exclusive-race-hispanic-origin.js b/table-config/demographic/mutually-exclusive-race-hispanic-origin.js deleted file mode 100644 index 2ff42cb..0000000 --- a/table-config/demographic/mutually-exclusive-race-hispanic-origin.js +++ /dev/null @@ -1,50 +0,0 @@ -module.exports = [ - { - title: 'Total population', - highlight: true, - variable: 'pop_2', - }, - { - title: 'Hispanic/Latino (of any race)', - variable: 'hsp1', - }, - { - title: 'Not Hispanic/Latino', - variable: 'nhsp', - }, - { - title: 'White alone', - indent: 1, - variable: 'wtnh', - }, - { - title: 'Black or African American Alone', - indent: 1, - variable: 'blnh', - }, - { - title: 'American Indian and Alaska Native alone', - indent: 1, - variable: 'aiannh', - }, - { - title: 'Asian alone', - indent: 1, - variable: 'asnnh', - }, - { - title: 'Native Hawaiian and Other Pacific Islander alone', - indent: 1, - variable: 'nhpinh', - }, - { - title: 'Some other race alone', - indent: 1, - variable: 'othnh', - }, - { - title: 'Two or more races', - indent: 1, - variable: 'rc2plnh', - }, -]; diff --git a/table-config/demographic/sex-and-age.js b/table-config/demographic/sex-and-age.js deleted file mode 100644 index c69acfe..0000000 --- a/table-config/demographic/sex-and-age.js +++ /dev/null @@ -1,290 +0,0 @@ -const interpolate = require('../../utils/interpolate'); -const formula = require('../../utils/formula'); -const calculateMedianError = require('../../utils/calculate-median-error'); - -const binsForMdAge = [ - ['mdpop0t4', [0, 4]], - ['mdpop5t9', [5, 9]], - ['mdpop10t14', [10, 14]], - ['mdpop15t17', [15, 17]], - ['mdpop18t19', [18, 19]], - ['mdpop20', [20, 20]], - ['mdpop21', [21, 21]], - ['mdpop22t24', [22, 24]], - ['mdpop25t29', [25, 29]], - ['mdpop30t34', [30, 34]], - ['mdpop35t39', [35, 39]], - ['mdpop40t44', [40, 44]], - ['mdpop45t49', [45, 49]], - ['mdpop50t54', [50, 54]], - ['mdpop55t59', [55, 59]], - ['mdpop60t61', [60, 61]], - ['mdpop62t64', [62, 64]], - ['mdpop65t66', [65, 66]], - ['mdpop67t69', [67, 69]], - ['mdpop70t74', [70, 74]], - ['mdpop75t79', [75, 79]], - ['mdpop80t84', [80, 84]], - ['mdpop85pl', [85, 115]], -]; - -module.exports = [ - { - title: 'Total population', - highlight: true, - variable: 'pop_1', - }, - { - title: 'Male', - classNames: '', - variable: 'male', - }, - { - title: 'Female', - classNames: '', - variable: 'fem', - }, - { - divider: true, - }, - { - title: 'Under 5 years', - classNames: '', - variable: 'popu5', - }, - { - title: '5 to 9 years', - classNames: '', - variable: 'pop5t9', - }, - { - title: '10 to 14 years', - classNames: '', - variable: 'pop10t14', - }, - { - title: '15 to 19 years', - classNames: '', - variable: 'pop15t19', - }, - { - title: '20 to 24 years', - classNames: '', - variable: 'pop20t24', - }, - { - title: '25 to 29 years', - classNames: '', - variable: 'pop25t29', - }, - { - title: '30 to 34 years', - classNames: '', - variable: 'pop30t34', - }, - { - title: '35 to 39 years', - classNames: '', - variable: 'pop35t39', - }, - { - title: '40 to 44 years', - classNames: '', - variable: 'pop40t44', - }, - { - title: '45 to 49 years', - classNames: '', - variable: 'pop45t49', - }, - { - title: '50 to 54 years', - classNames: '', - variable: 'pop50t54', - }, - { - title: '55 to 59 years', - classNames: '', - variable: 'pop55t59', - }, - { - title: '60 to 64 years', - classNames: '', - variable: 'pop60t64', - }, - { - title: '65 to 69 years', - classNames: '', - variable: 'pop65t69', - }, - { - title: '70 to 74 years', - classNames: '', - variable: 'pop70t74', - }, - { - title: '75 to 79 years', - classNames: '', - variable: 'pop75t79', - }, - { - title: '80 to 84 years', - classNames: '', - variable: 'pop80t84', - }, - { - title: '85 years and over', - classNames: '', - variable: 'pop85pl', - }, - { - divider: true, - }, - { - title: 'Under 18 years', - classNames: '', - variable: 'popu181', - }, - { - title: '65 years and over', - classNames: '', - variable: 'pop65pl1', - }, - { - divider: true, - }, - { - title: 'Median age (years)', - tooltip: 'Medians are calculated using linear interpolation, which may result in top-coded values', - classNames: '', - variable: 'mdage', - special: true, - decimal: 1, - hidePercentChange: true, - specialCalculations: [ - { - column: 'sum', - aggregator: interpolate, - options: { - bins: binsForMdAge, - }, - }, - { - column: 'previous_sum', - aggregator: interpolate, - options: { - bins: binsForMdAge, - }, - }, - { - column: 'm', - aggregator: calculateMedianError, - options: { - designFactor: 1.1, - bins: binsForMdAge, - }, - }, - { - column: 'previous_m', - aggregator: calculateMedianError, - options: { - designFactor: 1.1, - bins: binsForMdAge, - }, - }, - { - column: 'cv', - aggregator: formula, - options: { - formula: '((GET("mdage.m")/ 1.645) / GET("mdage.sum") * 100)', - }, - }, - { - column: 'comparison_sum', - aggregator: interpolate, - options: { - bins: binsForMdAge, - }, - }, - { - column: 'comparison_m', - aggregator: calculateMedianError, - options: { - designFactor: 1.1, - bins: binsForMdAge, - }, - }, - { - column: 'comparison_cv', - aggregator: formula, - options: { - formula: '((GET("mdage.comparison_m")/ 1.645) / GET("mdage.comparison_sum") * 100)', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("mdage.sum") - GET("mdage.comparison_sum"))', - }, - }, - { - column: 'difference_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mdage.m"),2) + POWER(GET("mdage.comparison_m"),2))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("mdage.sum") - GET("mdage.previous_sum"))', - }, - }, - { - column: 'change_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mdage.m"),2) + POWER(GET("mdage.previous_m"),2))', - }, - }, - ], - }, - { - divider: true, - }, - { - title: 'Under 18 years', - highlight: true, - variable: 'popu18_2', - }, - { - title: 'Male', - classNames: '', - variable: 'popu18m', - }, - { - title: 'Female', - classNames: '', - variable: 'popu18f', - }, - { - divider: true, - }, - { - title: '65 years and over', - highlight: true, - variable: 'pop65pl2', - }, - { - title: 'Male', - classNames: '', - variable: 'pop65plm', - }, - { - title: 'Female', - classNames: '', - variable: 'pop65plf', - }, -]; diff --git a/table-config/economic/class-of-worker.js b/table-config/economic/class-of-worker.js deleted file mode 100755 index f4199db..0000000 --- a/table-config/economic/class-of-worker.js +++ /dev/null @@ -1,22 +0,0 @@ -module.exports = [ { - title: 'Civilian employed population 16 years and over', - highlight: true, - variable: 'cvem16pl4', - }, - { - title: 'Private wage and salary workers', - variable: 'prvwswrkr', - }, - { - title: 'Government workers', - variable: 'gvtwrkr', - }, - { - title: 'Self-employed workers in own not incorporated business', - variable: 'slfemninc', - }, - { - title: 'Unpaid family workers', - variable: 'updfmwrkr', - }, -]; diff --git a/table-config/economic/commute-to-work.js b/table-config/economic/commute-to-work.js deleted file mode 100644 index 4f8583a..0000000 --- a/table-config/economic/commute-to-work.js +++ /dev/null @@ -1,151 +0,0 @@ -const calculator = require('../../utils/calculator'); -const formula = require('../../utils/formula'); - -module.exports = [ - { - title: 'Workers 16 years and over', - highlight: true, - variable: 'wrkr16pl', - }, - { - title: 'Car, truck, or van -- drove alone', - variable: 'cw_drvaln', - }, - { - title: 'Car, truck, or van -- carpooled', - variable: 'cw_crpld', - }, - { - title: 'Public transportation', - variable: 'cw_pbtrns', - }, - { - title: 'Walked', - variable: 'cw_wlkd', - }, - { - title: 'Other means', - variable: 'cw_oth', - }, - { - title: 'Worked at home', - variable: 'cw_wrkdhm', - }, - { - divider: true, - }, - { - title: 'Mean travel time to work (minutes)', - tooltip: 'Aggregate travel time to work, divided by workers 16 years and over who did not work at home', - variable: 'mntrvtm', - special: true, - specialCalculations: [ - { - column: 'sum', - aggregator: calculator, - options: { - procedure: ['agttm.sum', 'divide', ['wrkr16pl.sum', 'subtract', 'cw_wrkdhm.sum']], - }, - }, - { - column: 'comparison_sum', - aggregator: calculator, - options: { - procedure: ['agttm.comparison_sum', 'divide', ['wrkr16pl.comparison_sum', 'subtract', 'cw_wrkdhm.comparison_sum']], - }, - }, - { - column: 'previous_sum', - aggregator: calculator, - options: { - procedure: ['agttm.previous_sum', 'divide', ['wrkr16pl.previous_sum', 'subtract', 'cw_wrkdhm.previous_sum']], - }, - }, - { - column: 'm', - aggregator: formula, - options: { - formula: '(1 / GET("wrkrnothm.sum")) * SQRT((GET("agttm.m")^2) + ((GET("agttm.sum") / (GET("wrkrnothm.sum")))^2 * (GET("wrkrnothm.m")^2)))', - }, - }, - { - column: 'comparison_m', - aggregator: formula, - options: { - formula: '(1 / GET("wrkrnothm.comparison_sum")) * SQRT((GET("agttm.comparison_m")^2) + ((GET("agttm.comparison_sum") / (GET("wrkrnothm.comparison_sum")))^2 * (GET("wrkrnothm.comparison_m")^2)))', - }, - }, - { - column: 'previous_m', - aggregator: formula, - options: { - formula: '(1/GET("wrkrnothm.previous_sum")) * SQRT((GET("agttm.previous_m")^2) + (GET("agttm.previous_sum") / (GET("wrkrnothm.previous_sum")^2) * (GET("wrkrnothm.previous_m")^2)))', - }, - }, - { - column: 'cv', - aggregator: formula, - options: { - formula: '(GET("m")/1.645/GET("sum")*100)', - }, - }, - { - column: 'comparison_cv', - aggregator: formula, - options: { - formula: '(GET("comparison_m")/1.645/GET("comparison_sum")*100)', - }, - }, - { - column: 'previous_cv', - aggregator: formula, - options: { - formula: '(GET("previous_m")/1.645/GET("previous_sum")*100)', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("mntrvtm.sum") - GET("mntrvtm.comparison_sum"))', - }, - }, - { - column: 'difference_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mntrvtm.m"),2) + POWER(GET("mntrvtm.comparison_m"),2))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("mntrvtm.sum") - GET("mntrvtm.previous_sum"))', - }, - }, - { - column: 'change_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mntrvtm.m"),2) + POWER(GET("mntrvtm.previous_m"),2))', - }, - }, - { - column: 'change_percent', - aggregator: formula, - options: { - formula: 'IF((GET("mntrvtm.previous_sum"))=0,"",((GET("mntrvtm.sum")-GET("mntrvtm.previous_sum"))/GET("mntrvtm.previous_sum")))', - }, - }, - { - column: 'change_percent_m', - aggregator: formula, - options: { - formula: '((SQRT((GET("mntrvtm.m")^2)+((GET("mntrvtm.sum")/GET("mntrvtm.previous_sum"))^2*GET("mntrvtm.previous_m")^2)))/GET("mntrvtm.previous_sum"))', - }, - }, - ], - decimal: 1, - }, -]; diff --git a/table-config/economic/earnings.js b/table-config/economic/earnings.js deleted file mode 100755 index 27d177a..0000000 --- a/table-config/economic/earnings.js +++ /dev/null @@ -1,472 +0,0 @@ -const interpolate = require('../../utils/interpolate'); -const formula = require('../../utils/formula'); -const calculateMedianError = require('../../utils/calculate-median-error'); -const inflate = require('../../utils/inflate'); - -const binsForMdewrk = [ - ['ernu2pt5k', [0, 2499]], - ['ern2pt5t5', [2500, 4999]], - ['ern5t7pt5', [5000, 7499]], - ['e7pt5t10', [7500, 9999]], - ['e10t12pt5', [10000, 12499]], - ['e12pt5t15', [12500, 14999]], - ['e15t17pt5', [15000, 17499]], - ['e17pt5t20', [17500, 19999]], - ['e20t22pt5', [20000, 22499]], - ['e22pt5t25', [22500, 24999]], - ['ern25t30', [25000, 29999]], - ['ern30t35', [30000, 34999]], - ['ern35t40', [35000, 39999]], - ['ern40t45', [40000, 44999]], - ['ern45t50', [45000, 49999]], - ['ern50t55', [50000, 54999]], - ['ern55t65', [55000, 64999]], - ['ern65t75', [65000, 74999]], - ['ern75t100', [75000, 99999]], - ['ern100pl', [100000, 250000]], -]; - -const binsForMdemftwrk = [ - ['mftu2pt5k', [0, 2499]], - ['mft2p5t5', [2500, 4999]], - ['mft5t7p5', [5000, 7499]], - ['mft7p5t10', [7500, 9999]], - ['mf10t12p5', [10000, 12499]], - ['mf12p5t15', [12500, 14999]], - ['mf15t17p5', [15000, 17499]], - ['mf17p5t20', [17500, 19999]], - ['mf20t22p5', [20000, 22499]], - ['mf22p5t25', [22500, 24999]], - ['mft25t30', [25000, 29999]], - ['mft30t35', [30000, 34999]], - ['mft35t40', [35000, 39999]], - ['mft40t45', [40000, 44999]], - ['mft45t50', [45000, 49999]], - ['mft50t55', [50000, 54999]], - ['mft55t65', [55000, 64999]], - ['mft65t75', [65000, 74999]], - ['mft75t100', [75000, 99999]], - ['mft100pl', [100000, 250000]], -]; - -const binsForMdefftwrk = [ - ['fftu2pt5k', [0, 2499]], - ['fft2p5t5', [2500, 4999]], - ['fft5t7p5', [5000, 7499]], - ['fft7p5t10', [7500, 9999]], - ['ff10t12p5', [10000, 12499]], - ['ff12p5t15', [12500, 14999]], - ['ff15t17p5', [15000, 17499]], - ['ff17p5t20', [17500, 19999]], - ['ff20t22p5', [20000, 22499]], - ['ff22p5t25', [22500, 24999]], - ['fft25t30', [25000, 29999]], - ['fft30t35', [30000, 34999]], - ['fft35t40', [35000, 39999]], - ['fft40t45', [40000, 44999]], - ['fft45t50', [45000, 49999]], - ['fft50t55', [50000, 54999]], - ['fft55t65', [55000, 64999]], - ['fft65t75', [65000, 74999]], - ['fft75t100', [75000, 99999]], - ['fft100pl', [100000, 250000]], -]; - -module.exports = [ - { - title: 'Median earnings for workers (dollars)', - tooltip: 'Medians are calculated using linear interpolation, which may result in top- and bottom-coded values', - variable: 'mdewrk', - special: true, - adjustForInflation: true, - specialCalculations: [ - { - column: 'sum', - aggregator: interpolate, - options: { - bins: binsForMdewrk, - }, - }, - { - column: 'sum', - aggregator: inflate, - }, - { - column: 'm', - aggregator: calculateMedianError, - options: { - designFactor: 1.6, - bins: binsForMdewrk, - }, - }, - { - column: 'm', - aggregator: inflate, - }, - { - column: 'cv', - aggregator: formula, - options: { - formula: '((GET("mdewrk.m")/ 1.645) / GET("mdewrk.sum") * 100)', - }, - }, - { - column: 'comparison_sum', - aggregator: interpolate, - options: { - bins: binsForMdewrk, - }, - }, - { - column: 'comparison_m', - aggregator: calculateMedianError, - options: { - designFactor: 1.6, - bins: binsForMdewrk, - }, - }, - { - column: 'comparison_cv', - aggregator: formula, - options: { - formula: '((GET("mdewrk.comparison_m")/ 1.645) / GET("mdewrk.comparison_sum") * 100)', - }, - }, - { - column: 'previous_sum', - aggregator: interpolate, - options: { - bins: binsForMdewrk, - }, - }, - { - column: 'previous_sum', - aggregator: formula, - options: { - formula: '(GET("mdewrk.previous_sum") * 1.1005)', - }, - }, - { - column: 'previous_m', - aggregator: calculateMedianError, - options: { - designFactor: 1.6, - bins: binsForMdewrk, - }, - }, - { - column: 'previous_m', - aggregator: formula, - options: { - formula: '(GET("mdewrk.previous_m") * 1.1005)', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("mdewrk.sum") - GET("mdewrk.comparison_sum"))', - }, - }, - { - column: 'difference_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mdewrk.m"),2) + POWER(GET("mdewrk.comparison_m"),2))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("mdewrk.sum") - GET("mdewrk.previous_sum"))', - }, - }, - { - column: 'change_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mdewrk.m"),2) + POWER(GET("mdewrk.previous_m"),2))', - }, - }, - { - column: 'change_percent', - aggregator: formula, - options: { - formula: 'IF((GET("mdewrk.previous_sum"))=0,"",((GET("mdewrk.sum")-GET("mdewrk.previous_sum"))/GET("mdewrk.previous_sum")))', - }, - }, - { - column: 'change_percent_m', - aggregator: formula, - options: { - formula: '((SQRT((GET("mdewrk.m")^2)+((GET("mdewrk.sum")/GET("mdewrk.previous_sum"))^2*GET("mdewrk.previous_m")^2)))/GET("mdewrk.previous_sum"))', - }, - }, - ], - }, - { - title: 'Median earnings for male full-time, year-round workers (dollars)', - tooltip: 'Medians are calculated using linear interpolation, which may result in top- and bottom-coded values', - variable: 'mdemftwrk', - special: true, - adjustForInflation: true, - specialCalculations: [ - { - column: 'sum', - aggregator: interpolate, - options: { - bins: binsForMdemftwrk, - }, - }, - { - column: 'sum', - aggregator: inflate, - }, - { - column: 'm', - aggregator: calculateMedianError, - options: { - designFactor: 1.6, - bins: binsForMdemftwrk, - }, - }, - { - column: 'm', - aggregator: inflate, - }, - { - column: 'cv', - aggregator: formula, - options: { - formula: '((GET("mdemftwrk.m")/ 1.645) / GET("mdemftwrk.sum") * 100)', - }, - }, - { - column: 'comparison_sum', - aggregator: interpolate, - options: { - bins: binsForMdemftwrk, - }, - }, - { - column: 'comparison_m', - aggregator: calculateMedianError, - options: { - designFactor: 1.6, - bins: binsForMdemftwrk, - }, - }, - { - column: 'comparison_cv', - aggregator: formula, - options: { - formula: '((GET("mdemftwrk.comparison_m")/ 1.645) / GET("mdemftwrk.comparison_sum") * 100)', - }, - }, - { - column: 'previous_sum', - aggregator: interpolate, - options: { - bins: binsForMdemftwrk, - }, - }, - { - column: 'previous_sum', - aggregator: formula, - options: { - formula: '(GET("mdemftwrk.previous_sum") * 1.1005)', - }, - }, - { - column: 'previous_m', - aggregator: calculateMedianError, - options: { - designFactor: 1.6, - bins: binsForMdemftwrk, - }, - }, - { - column: 'previous_m', - aggregator: formula, - options: { - formula: '(GET("mdemftwrk.previous_m") * 1.1005)', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("mdemftwrk.sum") - GET("mdemftwrk.comparison_sum"))', - }, - }, - { - column: 'difference_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mdemftwrk.m"),2) + POWER(GET("mdemftwrk.comparison_m"),2))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("mdemftwrk.sum") - GET("mdemftwrk.previous_sum"))', - }, - }, - { - column: 'change_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mdemftwrk.m"),2) + POWER(GET("mdemftwrk.previous_m"),2))', - }, - }, - { - column: 'change_percent', - aggregator: formula, - options: { - formula: 'IF((GET("mdemftwrk.previous_sum"))=0,"",((GET("mdemftwrk.sum")-GET("mdemftwrk.previous_sum"))/GET("mdemftwrk.previous_sum")))', - }, - }, - { - column: 'change_percent_m', - aggregator: formula, - options: { - formula: '((SQRT((GET("mdemftwrk.m")^2)+((GET("mdemftwrk.sum")/GET("mdemftwrk.previous_sum"))^2*GET("mdemftwrk.previous_m")^2)))/GET("mdemftwrk.previous_sum"))', - }, - }, - ], - }, - { - title: 'Median earnings for female full-time, year-round workers (dollars)', - tooltip: 'Medians are calculated using linear interpolation, which may result in top- and bottom-coded values', - variable: 'mdefftwrk', - special: true, - adjustForInflation: true, - specialCalculations: [ - { - column: 'sum', - aggregator: interpolate, - options: { - bins: binsForMdefftwrk, - }, - }, - { - column: 'sum', - aggregator: inflate, - }, - { - column: 'm', - aggregator: calculateMedianError, - options: { - designFactor: 1.6, - bins: binsForMdefftwrk, - }, - }, - { - column: 'm', - aggregator: inflate, - }, - { - column: 'cv', - aggregator: formula, - options: { - formula: '((GET("mdefftwrk.m")/ 1.645) / GET("mdefftwrk.sum") * 100)', - }, - }, - { - column: 'comparison_sum', - aggregator: interpolate, - options: { - bins: binsForMdefftwrk, - }, - }, - { - column: 'comparison_m', - aggregator: calculateMedianError, - options: { - designFactor: 1.6, - bins: binsForMdefftwrk, - }, - }, - { - column: 'comparison_cv', - aggregator: formula, - options: { - formula: '((GET("mdefftwrk.comparison_m")/ 1.645) / GET("mdefftwrk.comparison_sum") * 100)', - }, - }, - { - column: 'previous_sum', - aggregator: interpolate, - options: { - bins: binsForMdefftwrk, - }, - }, - { - column: 'previous_sum', - aggregator: formula, - options: { - formula: '(GET("mdefftwrk.previous_sum") * 1.1005)', - }, - }, - { - column: 'previous_m', - aggregator: calculateMedianError, - options: { - designFactor: 1.6, - bins: binsForMdefftwrk, - }, - }, - { - column: 'previous_m', - aggregator: formula, - options: { - formula: '(GET("mdefftwrk.previous_m") * 1.1005)', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("mdefftwrk.sum") - GET("mdefftwrk.comparison_sum"))', - }, - }, - { - column: 'difference_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mdefftwrk.m"),2) + POWER(GET("mdefftwrk.comparison_m"),2))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("mdefftwrk.sum") - GET("mdefftwrk.previous_sum"))', - }, - }, - { - column: 'change_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mdefftwrk.m"),2) + POWER(GET("mdefftwrk.previous_m"),2))', - }, - }, - { - column: 'change_percent', - aggregator: formula, - options: { - formula: 'IF((GET("mdefftwrk.previous_sum"))=0,"",((GET("mdefftwrk.sum")-GET("mdefftwrk.previous_sum"))/GET("mdefftwrk.previous_sum")))', - }, - }, - { - column: 'change_percent_m', - aggregator: formula, - options: { - formula: '((SQRT((GET("mdefftwrk.m")^2)+((GET("mdefftwrk.sum")/GET("mdefftwrk.previous_sum"))^2*GET("mdefftwrk.previous_m")^2)))/GET("mdefftwrk.previous_sum"))', - }, - }, - ], - }, -]; diff --git a/table-config/economic/employment-status.js b/table-config/economic/employment-status.js deleted file mode 100644 index 5a69b6c..0000000 --- a/table-config/economic/employment-status.js +++ /dev/null @@ -1,93 +0,0 @@ -module.exports = [ - { - title: 'Population 16 years and over', - highlight: true, - variable: 'pop16pl', - }, - { - title: 'In labor force', - variable: 'lf', - }, - { - title: 'Civilian labor force', - indent: 1, - variable: 'cvlf1', - }, - { - title: 'Employed', - indent: 2, - variable: 'cvem16pl1', - }, - { - title: 'Unemployed', - indent: 2, - variable: 'cvlfuem1', - }, - { - title: 'Armed Forces', - indent: 1, - variable: 'lfarmdf', - }, - { - title: 'Not in labor force', - variable: 'nlf1', - }, - { - divider: true, - }, - { - title: 'Civilian labor force', - highlight: true, - variable: 'cvlf2', - }, - { - title: 'Unemployed (percent equivalent to unemployment rate)', - variable: 'cvlfuem2', - }, - { - divider: true, - }, - { - title: 'Females 16 years and over', - highlight: true, - variable: 'f16pl', - }, - { - title: 'In labor force', - variable: 'f16pllf', - }, - { - title: 'Civilian labor force', - indent: 1, - variable: 'f16plcvlf', - }, - { - title: 'Employed', - indent: 2, - variable: 'f16plclfe', - }, - { - divider: true, - }, - { - title: 'Own children under 6 years', - highlight: true, - variable: 'ochu6', - }, - { - title: 'All parents in family in labor force', - variable: 'ochu6plf', - }, - { - divider: true, - }, - { - title: 'Own children 6 to 17 years', - highlight: true, - variable: 'och6t17', - }, - { - title: 'All parents in family in labor force', - variable: 'oc6t17plf', - }, -]; diff --git a/table-config/economic/health-insurance-coverage.js b/table-config/economic/health-insurance-coverage.js deleted file mode 100755 index dae20dc..0000000 --- a/table-config/economic/health-insurance-coverage.js +++ /dev/null @@ -1,129 +0,0 @@ -module.exports = [ - { - title: 'Civilian noninstitutionalized population', - highlight: true, - variable: 'cvnipop2', - }, - { - title: 'With health insurance coverage', - variable: 'hins', - }, - { - indent: 1, - title: 'With private health insurance', - variable: 'pvhins', - }, - { - indent: 1, - title: 'With public coverage', - variable: 'pbhins', - }, - { - title: 'No health insurance coverage', - variable: 'nhins', - }, - { - divider: true, - }, - { - title: 'Civilian noninstitutionalized population under 18 years', - highlight: true, - variable: 'cvniu18_2', - }, - { - title: 'No health insurance coverage', - variable: 'u18nhins', - }, - { - divider: true, - }, - { - title: 'Civilian noninstitutionalized population 18 to 64 years', - variable: 'cni1864_2', - special: true, - }, - { - indent: 1, - title: 'In labor force', - variable: 'cvlf18t64', - special: true, - }, - { - indent: 3, - title: 'Employed', - highlight: true, - variable: 'cvlfem', - }, - { - indent: 3, - title: 'With health insurance coverage', - variable: 'emhins', - }, - { - indent: 4, - title: 'With private health insurance', - variable: 'empvhins', - }, - { - indent: 4, - title: 'With public coverage', - variable: 'empbhins', - }, - { - indent: 3, - title: 'No health insurance coverage', - variable: 'emnhins', - }, - { - indent: 3, - title: 'Unemployed', - highlight: true, - variable: 'uem', - }, - { - indent: 3, - title: 'With health insurance coverage', - variable: 'uemhins', - }, - { - indent: 4, - title: 'With private health insurance', - variable: 'uempvhins', - }, - { - indent: 4, - title: 'With public coverage', - variable: 'uempbhins', - }, - { - indent: 3, - title: 'No health insurance coverage', - variable: 'uemnhins', - }, - { - indent: 1, - title: 'Not in labor force', - highlight: true, - variable: 'nlf2', - }, - { - indent: 1, - title: 'With health insurance coverage', - variable: 'nlfhins', - }, - { - indent: 2, - title: 'With private health insurance', - variable: 'nlfpvhins', - }, - { - indent: 2, - title: 'With public coverage', - variable: 'nlfpbhins', - }, - { - indent: 1, - title: 'No health insurance coverage', - variable: 'nlfnhins', - }, -]; diff --git a/table-config/economic/income-and-benefits.js b/table-config/economic/income-and-benefits.js deleted file mode 100755 index ad3d0e3..0000000 --- a/table-config/economic/income-and-benefits.js +++ /dev/null @@ -1,833 +0,0 @@ -const interpolate = require('../../utils/interpolate'); -const calculateMedianError = require('../../utils/calculate-median-error'); -const calculator = require('../../utils/calculator'); -const formula = require('../../utils/formula'); -const inflate = require('../../utils/inflate'); - -const binsForMdhhinc = [ - ['mdhhiu10', [0, 9999]], - ['mdhhi10t14', [10000, 14999]], - ['mdhhi15t19', [15000, 19999]], - ['mdhhi20t24', [20000, 24999]], - ['mdhhi25t29', [25000, 29999]], - ['mdhhi30t34', [30000, 34999]], - ['mdhhi35t39', [35000, 39999]], - ['mdhhi40t44', [40000, 44999]], - ['mdhhi45t49', [45000, 49999]], - ['mdhhi50t59', [50000, 59999]], - ['mdhhi60t74', [60000, 74999]], - ['mdhhi75t99', [75000, 99999]], - ['mdhi100t124', [100000, 124999]], - ['mdhi125t149', [125000, 149999]], - ['mdhi150t199', [150000, 199999]], - ['mdhhi200pl', [200000, 9999999]], -]; - -const binsForMdfaminc = [ - ['mdfamiu10', [0, 9999]], - ['mdfami10t14', [10000, 14999]], - ['mdfami15t19', [15000, 19999]], - ['mdfami20t24', [20000, 24999]], - ['mdfami25t29', [25000, 29999]], - ['mdfami30t34', [30000, 34999]], - ['mdfami35t39', [35000, 39999]], - ['mdfami40t44', [40000, 44999]], - ['mdfami45t49', [45000, 49999]], - ['mdfami50t59', [50000, 59999]], - ['mdfami60t74', [60000, 74999]], - ['mdfami75t99', [75000, 99999]], - ['mdfi100t124', [100000, 124999]], - ['mdfi125t149', [125000, 149999]], - ['mdfi150t199', [150000, 199999]], - ['mdfami200pl', [200000, 9999999]], -]; - -const binsForMdnfinc = [ - ['nfmiu10', [0, 9999]], - ['nfmi10t14', [10000, 14999]], - ['nfmi15t19', [15000, 19999]], - ['nfmi20t24', [20000, 24999]], - ['nfmi25t29', [25000, 29999]], - ['nfmi30t34', [30000, 34999]], - ['nfmi35t39', [35000, 39999]], - ['nfmi40t44', [40000, 44999]], - ['nfmi45t49', [45000, 49999]], - ['nfmi50t59', [50000, 59999]], - ['nfmi60t74', [60000, 74999]], - ['nfmi75t99', [75000, 99999]], - ['nf100t124', [100000, 124999]], - ['nf125t149', [125000, 149999]], - ['nf150t199', [150000, 199999]], - ['nfi200pl', [200000, 9999999]], -]; - -module.exports = [ - { - title: 'Total households', - highlight: true, - variable: 'hh2', - }, - { - title: 'Household income of less than $10,000', - variable: 'hhiu10', - }, - { - title: '$10,000 to $14,999', - variable: 'hhi10t14', - }, - { - title: '$15,000 to $24,999', - variable: 'hhi15t24', - }, - { - title: '$25,000 to $34,999', - variable: 'hhi25t34', - }, - { - title: '$35,000 to $49,999', - variable: 'hhi35t49', - }, - { - title: '$50,000 to $74,999', - variable: 'hhi50t74', - }, - { - title: '$75,000 to $99,999', - variable: 'hhi75t99', - }, - { - title: '$100,000 to $149,999', - variable: 'hi100t149', - }, - { - title: '$150,000 to $199,999', - variable: 'hi150t199', - }, - { - title: '$200,000 or more', - variable: 'hhi200pl', - }, - { - title: 'Median household income (dollars)', - tooltip: 'Medians are calculated using linear interpolation, which may result in top- and bottom-coded values', - variable: 'mdhhinc', - special: true, - specialCalculations: [ - { - column: 'sum', - aggregator: interpolate, - options: { - bins: binsForMdhhinc, - }, - }, - { - column: 'sum', - aggregator: inflate, - }, - { - column: 'm', - aggregator: calculateMedianError, - options: { - designFactor: 1.5, - bins: binsForMdhhinc, - }, - }, - { - column: 'm', - aggregator: inflate, - }, - { - column: 'cv', - aggregator: formula, - options: { - formula: '((GET("mdhhinc.m")/ 1.645) / GET("mdhhinc.sum") * 100)', - }, - }, - { - column: 'comparison_sum', - aggregator: interpolate, - options: { - bins: binsForMdhhinc, - }, - }, - { - column: 'comparison_m', - aggregator: calculateMedianError, - options: { - designFactor: 1.5, - bins: binsForMdhhinc, - }, - }, - { - column: 'comparison_cv', - aggregator: formula, - options: { - formula: '((GET("mdhhinc.comparison_m")/ 1.645) / GET("mdhhinc.comparison_sum") * 100)', - }, - }, - { - column: 'previous_sum', - aggregator: interpolate, - options: { - bins: binsForMdhhinc, - }, - }, - { - column: 'previous_sum', - aggregator: formula, - options: { - formula: '(GET("mdhhinc.previous_sum") * 1.1005)', - }, - }, - { - column: 'previous_m', - aggregator: calculateMedianError, - options: { - designFactor: 1.5, - bins: binsForMdhhinc, - }, - }, - { - column: 'previous_m', - aggregator: formula, - options: { - formula: '(GET("mdhhinc.previous_m") * 1.1005)', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("mdhhinc.sum") - GET("mdhhinc.comparison_sum"))', - }, - }, - { - column: 'difference_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mdhhinc.m"),2) + POWER(GET("mdhhinc.comparison_m"),2))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("mdhhinc.sum") - GET("mdhhinc.previous_sum"))', - }, - }, - { - column: 'change_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mdhhinc.m"),2) + POWER(GET("mdhhinc.previous_m"),2))', - }, - }, - { - column: 'change_percent', - aggregator: formula, - options: { - formula: 'IF((GET("mdhhinc.previous_sum"))=0,"",((GET("mdhhinc.sum")-GET("mdhhinc.previous_sum"))/GET("mdhhinc.previous_sum")))', - }, - }, - { - column: 'change_percent_m', - aggregator: formula, - options: { - formula: '((SQRT((GET("mdhhinc.m")^2)+((GET("mdhhinc.sum")/GET("mdhhinc.previous_sum"))^2*GET("mdhhinc.previous_m")^2)))/GET("mdhhinc.previous_sum"))', - }, - }, - ], - }, - { - title: 'Mean household income (dollars)', - tooltip: 'Aggregate household income in the past 12 months, divided by total households', - variable: 'mnhhinc', - special: true, - specialCalculations: [ - { - column: 'sum', - aggregator: calculator, - options: { - procedure: ['aghhinc.sum', 'divide', 'hh2.sum'], - }, - }, - { - column: 'sum', - aggregator: inflate, - }, - { - column: 'comparison_sum', - aggregator: calculator, - options: { - procedure: ['aghhinc.comparison_sum', 'divide', 'hh2.comparison_sum'], - }, - }, - { - column: 'previous_sum', - aggregator: calculator, - options: { - procedure: ['aghhinc.previous_sum', 'divide', 'hh2.previous_sum'], - }, - }, - { - column: 'previous_sum', - aggregator: formula, - options: { - formula: '(GET("mnhhinc.previous_sum") * 1.1005)', - }, - }, - { - column: 'm', - aggregator: formula, - options: { - formula: '(1 / GET("hh5.sum")) * SQRT((GET("aghhinc.m")^2) + ((GET("aghhinc.sum") / (GET("hh5.sum")))^2 * (GET("hh5.m")^2)))', - }, - }, - { - column: 'comparison_m', - aggregator: formula, - options: { - formula: '(1 / GET("hh5.comparison_sum")) * SQRT((GET("aghhinc.comparison_m")^2) + ((GET("aghhinc.comparison_sum") / (GET("hh5.comparison_sum")))^2 * (GET("hh5.comparison_m")^2)))', - }, - }, - { - column: 'previous_m', - aggregator: formula, - options: { - formula: '(1/GET("hh5.previous_sum")) * SQRT((GET("aghhinc.previous_m")^2) + (GET("aghhinc.previous_sum") / (GET("hh5.previous_sum")^2) * (GET("hh5.previous_m")^2)))', - }, - }, - { - column: 'cv', - aggregator: formula, - options: { - formula: '(GET("m")/1.645/GET("sum")*100)', - }, - }, - { - column: 'comparison_cv', - aggregator: formula, - options: { - formula: '(GET("comparison_m")/1.645/GET("comparison_sum")*100)', - }, - }, - { - column: 'previous_cv', - aggregator: formula, - options: { - formula: '(GET("previous_m")/1.645/GET("previous_sum")*100)', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("mnhhinc.sum") - GET("mnhhinc.comparison_sum"))', - }, - }, - { - column: 'difference_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mnhhinc.m"),2) + POWER(GET("mnhhinc.comparison_m"),2))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("mnhhinc.sum") - GET("mnhhinc.previous_sum"))', - }, - }, - { - column: 'change_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mnhhinc.m"),2) + POWER(GET("mnhhinc.previous_m"),2))', - }, - }, - { - column: 'change_percent', - aggregator: formula, - options: { - formula: 'IF((GET("mnhhinc.previous_sum"))=0,"",((GET("mnhhinc.sum")-GET("mnhhinc.previous_sum"))/GET("mnhhinc.previous_sum")))', - }, - }, - { - column: 'change_percent_m', - aggregator: formula, - options: { - formula: '((SQRT((GET("mnhhinc.m")^2)+((GET("mnhhinc.sum")/GET("mnhhinc.previous_sum"))^2*GET("mnhhinc.previous_m")^2)))/GET("mnhhinc.previous_sum"))', - }, - }, - ], - }, - { - divider: true, - }, - { - title: 'Households with Social Security', - variable: 'inc_sosec', - }, - { - title: 'Households with retirement income', - variable: 'inc_rtrmt', - }, - { - title: 'Households with Supplemental Security Income', - variable: 'inc_spsec', - }, - { - title: 'Households with cash public assistance income', - variable: 'inc_cpba', - }, - { - title: 'Households with Food Stamp/SNAP benefits in the past 12 months', - variable: 'inc_snap', - }, - { - divider: true, - }, - { - title: 'Family households', - highlight: true, - variable: 'fam2', - }, - { - title: 'Family income of less than $10,000', - variable: 'famiu10', - }, - { - title: '$10,000 to $14,999', - variable: 'fami10t14', - }, - { - title: '$15,000 to $24,999', - variable: 'fami15t24', - }, - { - title: '$25,000 to $34,999', - variable: 'fami25t34', - }, - { - title: '$35,000 to $49,999', - variable: 'fami35t49', - }, - { - title: '$50,000 to $74,999', - variable: 'fami50t74', - }, - { - title: '$75,000 to $99,999', - variable: 'fami75t99', - }, - { - title: '$100,000 to $149,999', - variable: 'fi100t149', - }, - { - title: '$150,000 to $199,999', - variable: 'fi150t199', - }, - { - title: '$200,000 or more', - variable: 'fami200pl', - }, - { - title: 'Median family income (dollars)', - tooltip: 'Medians are calculated using linear interpolation, which may result in top- and bottom-coded values', - variable: 'mdfaminc', - special: true, - specialCalculations: [ - { - column: 'sum', - aggregator: interpolate, - options: { - bins: binsForMdfaminc, - }, - }, - { - column: 'sum', - aggregator: inflate, - }, - { - column: 'm', - aggregator: calculateMedianError, - options: { - designFactor: 1.5, - bins: binsForMdfaminc, - }, - }, - { - column: 'm', - aggregator: inflate, - }, - { - column: 'cv', - aggregator: formula, - options: { - formula: '((GET("mdfaminc.m")/ 1.645) / GET("mdfaminc.sum") * 100)', - }, - }, - { - column: 'comparison_sum', - aggregator: interpolate, - options: { - bins: binsForMdfaminc, - }, - }, - { - column: 'comparison_m', - aggregator: calculateMedianError, - options: { - designFactor: 1.5, - bins: binsForMdfaminc, - }, - }, - { - column: 'comparison_cv', - aggregator: formula, - options: { - formula: '((GET("mdfaminc.comparison_m")/ 1.645) / GET("mdfaminc.comparison_sum") * 100)', - }, - }, - { - column: 'previous_sum', - aggregator: interpolate, - options: { - bins: binsForMdfaminc, - }, - }, - { - column: 'previous_sum', - aggregator: formula, - options: { - formula: '(GET("mdfaminc.previous_sum") * 1.1005)', - }, - }, - { - column: 'previous_m', - aggregator: calculateMedianError, - options: { - designFactor: 1.5, - bins: binsForMdfaminc, - }, - }, - { - column: 'previous_m', - aggregator: formula, - options: { - formula: '(GET("mdfaminc.previous_m") * 1.1005)', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("mdfaminc.sum") - GET("mdfaminc.comparison_sum"))', - }, - }, - { - column: 'difference_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mdfaminc.m"),2) + POWER(GET("mdfaminc.comparison_m"),2))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("mdfaminc.sum") - GET("mdfaminc.previous_sum"))', - }, - }, - { - column: 'change_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mdfaminc.m"),2) + POWER(GET("mdfaminc.previous_m"),2))', - }, - }, - { - column: 'change_percent', - aggregator: formula, - options: { - formula: 'IF((GET("mdfaminc.previous_sum"))=0,"",((GET("mdfaminc.sum")-GET("mdfaminc.previous_sum"))/GET("mdfaminc.previous_sum")))', - }, - }, - { - column: 'change_percent_m', - aggregator: formula, - options: { - formula: '((SQRT((GET("mdfaminc.m")^2)+((GET("mdfaminc.sum")/GET("mdfaminc.previous_sum"))^2*GET("mdfaminc.previous_m")^2)))/GET("mdfaminc.previous_sum"))', - }, - }, - ], - }, - { - divider: true, - }, - { - title: 'Nonfamily households', - highlight: true, - variable: 'nfam2', - }, - { - title: 'Median nonfamily income (dollars)', - tooltip: 'Medians are calculated using linear interpolation, which may result in top- and bottom-coded values', - variable: 'mdnfinc', - special: true, - specialCalculations: [ - { - column: 'sum', - aggregator: interpolate, - options: { - bins: binsForMdnfinc, - }, - }, - { - column: 'sum', - aggregator: inflate, - }, - { - column: 'm', - aggregator: calculateMedianError, - options: { - designFactor: 1.5, - bins: binsForMdnfinc, - }, - }, - { - column: 'm', - aggregator: inflate, - }, - { - column: 'cv', - aggregator: formula, - options: { - formula: '((GET("mdnfinc.m")/ 1.645) / GET("mdnfinc.sum") * 100)', - }, - }, - { - column: 'comparison_sum', - aggregator: interpolate, - options: { - bins: binsForMdnfinc, - }, - }, - { - column: 'comparison_m', - aggregator: calculateMedianError, - options: { - designFactor: 1.5, - bins: binsForMdnfinc, - }, - }, - { - column: 'comparison_cv', - aggregator: formula, - options: { - formula: '((GET("mdnfinc.comparison_m")/ 1.645) / GET("mdnfinc.comparison_sum") * 100)', - }, - }, - { - column: 'previous_sum', - aggregator: interpolate, - options: { - bins: binsForMdnfinc, - }, - }, - { - column: 'previous_sum', - aggregator: formula, - options: { - formula: '(GET("mdnfinc.previous_sum") * 1.1005)', - }, - }, - { - column: 'previous_m', - aggregator: calculateMedianError, - options: { - designFactor: 1.5, - bins: binsForMdnfinc, - }, - }, - { - column: 'previous_m', - aggregator: formula, - options: { - formula: '(GET("mdnfinc.previous_m") * 1.1005)', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("mdnfinc.sum") - GET("mdnfinc.comparison_sum"))', - }, - }, - { - column: 'difference_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mdnfinc.m"),2) + POWER(GET("mdnfinc.comparison_m"),2))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("mdnfinc.sum") - GET("mdnfinc.previous_sum"))', - }, - }, - { - column: 'change_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mdnfinc.m"),2) + POWER(GET("mdnfinc.previous_m"),2))', - }, - }, - { - column: 'change_percent', - aggregator: formula, - options: { - formula: 'IF((GET("mdnfinc.previous_sum"))=0,"",((GET("mdnfinc.sum")-GET("mdnfinc.previous_sum"))/GET("mdnfinc.previous_sum")))', - }, - }, - { - column: 'change_percent_m', - aggregator: formula, - options: { - formula: '((SQRT((GET("mdnfinc.m")^2)+((GET("mdnfinc.sum")/GET("mdnfinc.previous_sum"))^2*GET("mdnfinc.previous_m")^2)))/GET("mdnfinc.previous_sum"))', - }, - }, - ], - }, - { - divider: true, - }, - { - title: 'Per capita income (dollars)', - tooltip: 'Aggregate income in the past 12 months, divided by total population', - variable: 'percapinc', - special: true, - specialCalculations: [ - { - column: 'sum', - aggregator: calculator, - options: { - procedure: ['agip15pl.sum', 'divide', 'pop_6.sum'], - }, - }, - { - column: 'sum', - aggregator: inflate, - }, - { - column: 'comparison_sum', - aggregator: calculator, - options: { - procedure: ['agip15pl.comparison_sum', 'divide', 'pop_6.comparison_sum'], - }, - }, - { - column: 'previous_sum', - aggregator: calculator, - options: { - procedure: ['agip15pl.previous_sum', 'divide', 'pop_6.previous_sum'], - }, - }, - { - column: 'previous_sum', - aggregator: formula, - options: { - formula: '(GET("percapinc.previous_sum") * 1.1005)', - }, - }, - { - column: 'm', - aggregator: formula, - options: { - formula: '(1 / GET("pop_6.sum")) * SQRT((GET("agip15pl.m")^2) + ((GET("agip15pl.sum") / (GET("pop_6.sum")))^2 * (GET("pop_6.m")^2)))', - }, - }, - { - column: 'comparison_m', - aggregator: formula, - options: { - formula: '(1 / GET("pop_6.comparison_sum")) * SQRT((GET("agip15pl.comparison_m")^2) + ((GET("agip15pl.comparison_sum") / (GET("pop_6.comparison_sum")))^2 * (GET("pop_6.comparison_m")^2)))', - }, - }, - { - column: 'previous_m', - aggregator: formula, - options: { - formula: '(1/GET("pop_6.previous_sum")) * SQRT((GET("agip15pl.previous_m")^2) + (GET("agip15pl.previous_sum") / (GET("pop_6.previous_sum")^2) * (GET("pop_6.previous_m")^2)))', - }, - }, - { - column: 'cv', - aggregator: formula, - options: { - formula: '(GET("m")/1.645/GET("sum")*100)', - }, - }, - { - column: 'comparison_cv', - aggregator: formula, - options: { - formula: '(GET("comparison_m")/1.645/GET("comparison_sum")*100)', - }, - }, - { - column: 'previous_cv', - aggregator: formula, - options: { - formula: '(GET("previous_m")/1.645/GET("previous_sum")*100)', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("percapinc.sum") - GET("percapinc.comparison_sum"))', - }, - }, - { - column: 'difference_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("percapinc.m"),2) + POWER(GET("percapinc.comparison_m"),2))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("percapinc.sum") - GET("percapinc.previous_sum"))', - }, - }, - { - column: 'change_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("percapinc.m"),2) + POWER(GET("percapinc.previous_m"),2))', - }, - }, - { - column: 'change_percent', - aggregator: formula, - options: { - formula: 'IF((GET("percapinc.previous_sum"))=0,"",((GET("percapinc.sum")-GET("percapinc.previous_sum"))/GET("percapinc.previous_sum")))', - }, - }, - { - column: 'change_percent_m', - aggregator: formula, - options: { - formula: '((SQRT((GET("percapinc.m")^2)+((GET("percapinc.sum")/GET("percapinc.previous_sum"))^2*GET("percapinc.previous_m")^2)))/GET("percapinc.previous_sum"))', - }, - }, - ], - }, -]; diff --git a/table-config/economic/income_in_past_12_months_is_below_the_poverty_level.js b/table-config/economic/income_in_past_12_months_is_below_the_poverty_level.js deleted file mode 100755 index 9047630..0000000 --- a/table-config/economic/income_in_past_12_months_is_below_the_poverty_level.js +++ /dev/null @@ -1,42 +0,0 @@ -module.exports = [ - { - title: 'All families', - highlight: true, - variable: 'fampvu', - }, - { - title: 'Below poverty', - variable: 'fambwpv', - }, - { - title: 'Population for whom poverty status is determined', - highlight: true, - variable: 'poppvu1', - }, - { - title: 'Below poverty', - variable: 'pbwpv', - }, - { - indent: 1, - title: 'Under 18 years', - highlight: true, - variable: 'pu18pvu', - }, - { - indent: 1, - title: 'Below poverty', - variable: 'pu18bwpv', - }, - { - indent: 1, - title: '65 years and over', - highlight: true, - variable: 'p65plpvu', - }, - { - indent: 1, - title: 'Below poverty', - variable: 'p65plbwpv', - }, -]; diff --git a/table-config/economic/index.js b/table-config/economic/index.js deleted file mode 100644 index db8e969..0000000 --- a/table-config/economic/index.js +++ /dev/null @@ -1,25 +0,0 @@ -// @create-index - -const classOfWorker = require('./class-of-worker'); -const commuteToWork = require('./commute-to-work'); -const earnings = require('./earnings'); -const employmentStatus = require('./employment-status'); -const healthInsuranceCoverage = require('./health-insurance-coverage'); -const incomeAndBenefits = require('./income-and-benefits'); -const incomeInPast12MonthsIsBelowThePovertyLevel = require('./income_in_past_12_months_is_below_the_poverty_level'); -const industry = require('./industry'); -const occupation = require('./occupation'); -const ratioOfIncomeToPovertyLevel = require('./ratio-of-income-to-poverty-level'); - -module.exports = { - classOfWorker, - commuteToWork, - earnings, - employmentStatus, - healthInsuranceCoverage, - incomeAndBenefits, - incomeInPast12MonthsIsBelowThePovertyLevel, - industry, - occupation, - ratioOfIncomeToPovertyLevel, -}; diff --git a/table-config/economic/industry.js b/table-config/economic/industry.js deleted file mode 100755 index 4d67a90..0000000 --- a/table-config/economic/industry.js +++ /dev/null @@ -1,59 +0,0 @@ -module.exports = [ - { - title: 'Civilian employed population 16 years and over', - highlight: true, - variable: 'cvem16pl3', - }, - { - title: 'Agriculture, forestry, fishing and hunting, and mining', - variable: 'agffhm', - }, - { - title: 'Construction', - variable: 'constctn', - }, - { - title: 'Manufacturing', - variable: 'mnfctrng', - }, - { - title: 'Wholesale trade', - variable: 'whlsale', - }, - { - title: 'Retail trade', - variable: 'retail', - }, - { - title: 'Transportation and warehousing, and utilities', - variable: 'trwhut', - }, - { - title: 'Information', - variable: 'info', - }, - { - title: 'Finance and insurance, and real estate and rental and leasing', - variable: 'fire', - }, - { - title: 'Professional, scientific, and management, and administrative and waste management services', - variable: 'prfsmgawm', - }, - { - title: 'Educational services, and health care and social assistance', - variable: 'edhlthcsa', - }, - { - title: 'Arts, entertainment, and recreation, and accommodation, and food services', - variable: 'artenrafs', - }, - { - title: 'Other services, except public administration', - variable: 'othnotpa', - }, - { - title: 'Public administration', - variable: 'pubadmin', - }, -]; diff --git a/table-config/economic/occupation.js b/table-config/economic/occupation.js deleted file mode 100755 index a507bb4..0000000 --- a/table-config/economic/occupation.js +++ /dev/null @@ -1,27 +0,0 @@ -module.exports = [ - { - title: 'Civilian employed population 16 years and over', - highlight: true, - variable: 'cvem16pl2', - }, - { - title: 'Management, business, science, and arts', - variable: 'mgbsciart', - }, - { - title: 'Service', - variable: 'srvc', - }, - { - title: 'Sales and office', - variable: 'salesoff', - }, - { - title: 'Natural resources, construction, and maintenance', - variable: 'nrcnstmnt', - }, - { - title: 'Production, transportation, and material moving', - variable: 'prdtrnsmm', - }, -]; diff --git a/table-config/economic/ratio-of-income-to-poverty-level.js b/table-config/economic/ratio-of-income-to-poverty-level.js deleted file mode 100755 index 714c88d..0000000 --- a/table-config/economic/ratio-of-income-to-poverty-level.js +++ /dev/null @@ -1,55 +0,0 @@ -module.exports = [ - { - title: 'Population for whom poverty status is determined', - highlight: true, - variable: 'poppvu2', - }, - { - title: 'Under .50', - variable: 'pvu50', - }, - { - title: '.50 to .74', - variable: 'pv50t74', - }, - { - title: '.75 to .99', - variable: 'pv75t99', - }, - { - title: '1.00 to 1.24', - variable: 'pv100t124', - }, - { - title: '1.25 to 1.49', - variable: 'pv125t149', - }, - { - title: '1.50 to 1.74', - variable: 'pv150t174', - }, - { - title: '1.75 to 1.84', - variable: 'pv175t184', - }, - { - title: '1.85 to 1.99', - variable: 'pv185t199', - }, - { - title: '2.00 to 2.99', - variable: 'pv200t299', - }, - { - title: '3.00 to 3.99', - variable: 'pv300t399', - }, - { - title: '4.00 to 4.99', - variable: 'pv400t499', - }, - { - title: '5.00 and over', - variable: 'pv500pl', - }, -]; diff --git a/table-config/housing/gross-rent-as-a-percentage-of-household-income--grapi.js b/table-config/housing/gross-rent-as-a-percentage-of-household-income--grapi.js deleted file mode 100755 index 4cd6002..0000000 --- a/table-config/housing/gross-rent-as-a-percentage-of-household-income--grapi.js +++ /dev/null @@ -1,44 +0,0 @@ -module.exports = [ - { - title: 'Occupied units paying rent (excluding units where GRAPI cannot be computed)', - highlight: true, - variable: 'ochuprnt2', - }, - { - title: 'Less than 15.0 percent', - variable: 'grpiu15', - }, - { - title: '15.0 to 19.9 percent', - variable: 'grpi15t19', - }, - { - title: '20.0 to 24.9 percent', - variable: 'grpi20t24', - }, - { - title: '25.0 to 29.9 percent', - variable: 'grpi25t29', - }, - - { - title: '30.0 to 34.9 percent', - variable: 'grpi30t34', - }, - { - title: '35.0 percent or more', - variable: 'grpi35pl', - }, - { - indent: 1, - title: '50.0 percent or more', - variable: 'grpi50pl', - }, - { - divider: true, - }, - { - title: 'Not computed', - variable: 'grpintc', - }, -]; diff --git a/table-config/housing/gross-rent.js b/table-config/housing/gross-rent.js deleted file mode 100755 index 8269471..0000000 --- a/table-config/housing/gross-rent.js +++ /dev/null @@ -1,236 +0,0 @@ -const interpolate = require('../../utils/interpolate'); -const formula = require('../../utils/formula'); -const calculateMedianError = require('../../utils/calculate-median-error'); -const inflate = require('../../utils/inflate'); - -const binsMedianEarlySet = [ - ['ru100', [0, 99]], - ['r100t149', [100, 149]], - ['r150t199', [150, 199]], - ['r200t249', [200, 249]], - ['r250t299', [250, 299]], - ['r300t349', [300, 349]], - ['r350t399', [350, 399]], - ['r400t449', [400, 449]], - ['r450t499', [450, 499]], - ['r500t549', [500, 549]], - ['r550t599', [550, 599]], - ['r600t649', [600, 649]], - ['r650t699', [650, 699]], - ['r700t749', [700, 749]], - ['r750t799', [750, 799]], - ['r800t899', [800, 899]], - ['r900t999', [900, 999]], - ['r1kt1249', [1000, 1249]], - ['r1250t1p5', [1250, 1499]], - ['r1p5t1999', [1500, 1999]], - ['r2000pl', [2000, 9999]], -]; - -const binsMedianLaterSet = [ - ['ru100', [0, 99]], - ['r100t149', [100, 149]], - ['r150t199', [150, 199]], - ['r200t249', [200, 249]], - ['r250t299', [250, 299]], - ['r300t349', [300, 349]], - ['r350t399', [350, 399]], - ['r400t449', [400, 449]], - ['r450t499', [450, 499]], - ['r500t549', [500, 549]], - ['r550t599', [550, 599]], - ['r600t649', [600, 649]], - ['r650t699', [650, 699]], - ['r700t749', [700, 749]], - ['r750t799', [750, 799]], - ['r800t899', [800, 899]], - ['r900t999', [900, 999]], - ['r1kt1249', [1000, 1249]], - ['r1250t1p5', [1250, 1499]], - ['r1p5t1999', [1500, 1999]], - ['r2kt2499', [2000, 2499]], - ['r2p5t2999', [2500, 2999]], - ['r3kt3499', [3000, 3499]], - ['r3500pl', [3500, 9000]], -]; - -module.exports = [ - { - title: 'Occupied units paying rent', - highlight: true, - variable: 'ochuprnt1', - }, - { - title: 'Less than $500', - variable: 'gru500', - }, - { - title: '$500 to $999', - variable: 'gr500t999', - }, - { - title: '$1,000 to $1499', - variable: 'gr1kt14k', - }, - { - title: '$1,500 to $1,999', - variable: 'gr15kt19k', - }, - { - title: '$2,000 to $2,499', - variable: 'gr20kt24k', - }, - { - title: '$2,500 to $2,999', - variable: 'gr25kt29k', - }, - { - title: '$3,000 or more', - variable: 'gr3kpl', - }, - { - title: 'Median (dollars)', - tooltip: 'Medians are calculated using linear interpolation, which may result in top-coded values', - variable: 'mdgr', - special: true, - adjustForInflation: true, - specialCalculations: [ - { - column: 'sum', - aggregator: interpolate, - options: { - multipleBins: true, - bins: [binsMedianEarlySet, binsMedianLaterSet], - }, - }, - { - column: 'sum', - aggregator: inflate, - }, - { - column: 'm', - aggregator: calculateMedianError, - options: { - designFactor: 1.6, - multipleBins: true, - bins: [binsMedianEarlySet, binsMedianLaterSet], - }, - }, - { - column: 'm', - aggregator: inflate, - }, - { - column: 'cv', - aggregator: formula, - options: { - formula: '((GET("mdgr.m")/ 1.645) / GET("mdgr.sum") * 100)', - }, - }, - { - column: 'comparison_sum', - aggregator: interpolate, - options: { - multipleBins: true, - bins: [binsMedianEarlySet, binsMedianLaterSet], - }, - }, - { - column: 'comparison_m', - aggregator: calculateMedianError, - options: { - designFactor: 1.6, - multipleBins: true, - bins: [binsMedianEarlySet, binsMedianLaterSet], - }, - }, - { - column: 'comparison_cv', - aggregator: formula, - options: { - formula: '((GET("mdgr.comparison_m")/ 1.645) / GET("mdgr.comparison_sum") * 100)', - }, - }, - { - column: 'previous_sum', - aggregator: interpolate, - options: { - designFactor: 1.6, - bins: binsMedianEarlySet, - }, - }, - { - column: 'previous_sum', - aggregator: formula, - options: { - formula: '(GET("mdgr.previous_sum") * 1.1005)', - }, - }, - { - column: 'previous_m', - aggregator: calculateMedianError, - options: { - designFactor: 1.6, - bins: binsMedianEarlySet, - }, - }, - { - column: 'previous_m', - aggregator: formula, - options: { - formula: '(GET("mdgr.previous_m") * 1.1005)', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("mdgr.sum") - GET("mdgr.comparison_sum"))', - }, - }, - { - column: 'difference_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mdgr.m"),2) + POWER(GET("mdgr.comparison_m"),2))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("mdgr.sum") - GET("mdgr.previous_sum"))', - }, - }, - { - column: 'change_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mdgr.m"),2) + POWER(GET("mdgr.previous_m"),2))', - }, - }, - { - column: 'change_percent', - aggregator: formula, - options: { - formula: 'IF((GET("mdgr.previous_sum"))=0,"",((GET("mdgr.sum")-GET("mdgr.previous_sum"))/GET("mdgr.previous_sum")))', - }, - }, - { - column: 'change_percent_m', - aggregator: formula, - options: { - formula: '((SQRT((GET("mdgr.m")^2)+((GET("mdgr.sum")/GET("mdgr.previous_sum"))^2*GET("mdgr.previous_m")^2)))/GET("mdgr.previous_sum"))', - }, - }, - ], - }, - { - divider: true, - }, - { - title: 'No rent paid', - variable: 'grnorntpd', - special: true, - }, -]; diff --git a/table-config/housing/housing-occupancy.js b/table-config/housing/housing-occupancy.js deleted file mode 100755 index 749eaac..0000000 --- a/table-config/housing/housing-occupancy.js +++ /dev/null @@ -1,209 +0,0 @@ -const calculator = require('../../utils/calculator'); -const formula = require('../../utils/formula'); - -module.exports = [ - { - title: 'Total housing units', - highlight: true, - variable: 'hu1', - }, - { - title: 'Occupied housing units', - variable: 'ochu1', - }, - { - title: 'Vacant housing units', - variable: 'vachu', - }, - { - divider: true, - }, - { - title: 'Homeowner vacancy rate', - tooltip: 'Number of vacant units “for sale only,” divided by sum of owner-occupied units, vacant units that are “for sale only,” and vacant units that have been sold but not yet occupied. Quotient is multiplied by 100.', - variable: 'hovacrt', - special: true, - decimal: 1, - hidePercentChange: true, - specialCalculations: [ - { - column: 'sum', - aggregator: calculator, - options: { - procedure: [['vacsale.sum', 'divide', 'hovacu.sum'], 'multiply', 100], - }, - }, - { - column: 'comparison_sum', - aggregator: calculator, - options: { - procedure: [['vacsale.comparison_sum', 'divide', 'hovacu.comparison_sum'], 'multiply', 100], - }, - }, - { - column: 'previous_sum', - aggregator: calculator, - options: { - procedure: [['vacsale.previous_sum', 'divide', 'hovacu.previous_sum'], 'multiply', 100], - }, - }, - { - column: 'm', - aggregator: formula, - options: { - formula: 'IF(((GET("vacsale.m")^2)-(( GET("vacsale.sum") ^2/ GET("hovacu.sum") ^2)*( GET("hovacu.m") ^2)))<0,((1/ GET("hovacu.sum") *(SQRT((GET("vacsale.m") ^2)+(( GET("vacsale.sum") ^2/ GET("hovacu.sum") ^2)*( GET("hovacu.m") ^2)))))*100),((1/ GET("hovacu.sum") *(SQRT((GET("vacsale.m") ^2)-(( GET("vacsale.sum") ^2/ GET("hovacu.sum") ^2)*( GET("hovacu.m") ^2)))))*100))', - }, - }, - { - column: 'comparison_m', - aggregator: formula, - options: { - formula: 'IF(((GET("vacsale.comparison_m")^2)-(( GET("vacsale.comparison_sum") ^2/ GET("hovacu.comparison_sum") ^2)*( GET("hovacu.comparison_m") ^2)))<0,((1/ GET("hovacu.comparison_sum") *(SQRT((GET("vacsale.comparison_m") ^2)+(( GET("vacsale.comparison_sum") ^2/ GET("hovacu.comparison_sum") ^2)*( GET("hovacu.comparison_m") ^2)))))*100),((1/ GET("hovacu.comparison_sum") *(SQRT((GET("vacsale.comparison_m") ^2)-(( GET("vacsale.comparison_sum") ^2/ GET("hovacu.comparison_sum") ^2)*( GET("hovacu.comparison_m") ^2)))))*100))', - }, - }, - { - column: 'previous_m', - aggregator: formula, - options: { - formula: 'IF(((GET("vacsale.previous_m")^2)-(( GET("vacsale.previous_sum") ^2/ GET("hovacu.previous_sum") ^2)*( GET("hovacu.previous_m") ^2)))<0,((1/ GET("hovacu.previous_sum") *(SQRT((GET("vacsale.previous_m") ^2)+(( GET("vacsale.previous_sum") ^2/ GET("hovacu.previous_sum") ^2)*( GET("hovacu.previous_m") ^2)))))*100),((1/ GET("hovacu.previous_sum") *(SQRT((GET("vacsale.previous_m") ^2)-(( GET("vacsale.previous_sum") ^2/ GET("hovacu.previous_sum") ^2)*( GET("hovacu.previous_m") ^2)))))*100))', - }, - }, - { - column: 'cv', - aggregator: formula, - options: { - formula: '((GET("hovacrt.m")/ 1.645) / GET("hovacrt.sum") * 100)', - }, - }, - { - column: 'comparison_cv', - aggregator: formula, - options: { - formula: '((GET("hovacrt.comparison_m")/ 1.645) / GET("hovacrt.comparison_sum") * 100)', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("hovacrt.sum") - GET("hovacrt.comparison_sum"))', - }, - }, - { - column: 'difference_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("hovacrt.m"),2) + POWER(GET("hovacrt.comparison_m"),2))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("hovacrt.sum") - GET("hovacrt.previous_sum"))', - }, - }, - { - column: 'change_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("hovacrt.m"),2) + POWER(GET("hovacrt.previous_m"),2))', - }, - }, - ], - }, - { - title: 'Rental vacancy rate', - tooltip: 'Number of vacant units “for rent,” divided by sum of renter-occupied units, vacant units that are “for rent,” and vacant units that have been rented but not yet occupied. Quotient is multiplied by 100.', - variable: 'rntvacrt', - special: true, - decimal: 1, - hidePercentChange: true, - specialCalculations: [ - { - column: 'sum', - aggregator: calculator, - options: { - procedure: [['vacrnt.sum', 'divide', 'rntvacu.sum'], 'multiply', 100], - }, - }, - { - column: 'comparison_sum', - aggregator: calculator, - options: { - procedure: [['vacrnt.comparison_sum', 'divide', 'rntvacu.comparison_sum'], 'multiply', 100], - }, - }, - { - column: 'previous_sum', - aggregator: calculator, - options: { - procedure: [['vacrnt.previous_sum', 'divide', 'rntvacu.previous_sum'], 'multiply', 100], - }, - }, - { - column: 'm', - aggregator: formula, - options: { - formula: 'IF(((GET("vacrnt.m")^2)-(( GET("vacrnt.sum") ^2/ GET("rntvacu.sum") ^2)*( GET("rntvacu.m") ^2)))<0,((1/ GET("rntvacu.sum") *(SQRT((GET("vacrnt.m") ^2)+(( GET("vacrnt.sum") ^2/ GET("rntvacu.sum") ^2)*( GET("rntvacu.m") ^2)))))*100),((1/ GET("rntvacu.sum") *(SQRT((GET("vacrnt.m") ^2)-(( GET("vacrnt.sum") ^2/ GET("rntvacu.sum") ^2)*( GET("rntvacu.m") ^2)))))*100))', - }, - }, - { - column: 'comparison_m', - aggregator: formula, - options: { - formula: 'IF(((GET("vacrnt.comparison_m")^2)-(( GET("vacrnt.comparison_sum") ^2/ GET("rntvacu.comparison_sum") ^2)*( GET("rntvacu.comparison_m") ^2)))<0,((1/ GET("rntvacu.comparison_sum") *(SQRT((GET("vacrnt.comparison_m") ^2)+(( GET("vacrnt.comparison_sum") ^2/ GET("rntvacu.comparison_sum") ^2)*( GET("rntvacu.comparison_m") ^2)))))*100),((1/ GET("rntvacu.comparison_sum") *(SQRT((GET("vacrnt.comparison_m") ^2)-(( GET("vacrnt.comparison_sum") ^2/ GET("rntvacu.comparison_sum") ^2)*( GET("rntvacu.comparison_m") ^2)))))*100))', - }, - }, - { - column: 'previous_m', - aggregator: formula, - options: { - formula: 'IF(((GET("vacrnt.previous_m")^2)-(( GET("vacrnt.previous_sum") ^2/ GET("rntvacu.previous_sum") ^2)*( GET("rntvacu.previous_m") ^2)))<0,((1/ GET("rntvacu.previous_sum") *(SQRT((GET("vacrnt.previous_m") ^2)+(( GET("vacrnt.previous_sum") ^2/ GET("rntvacu.previous_sum") ^2)*( GET("rntvacu.previous_m") ^2)))))*100),((1/ GET("rntvacu.previous_sum") *(SQRT((GET("vacrnt.previous_m") ^2)-(( GET("vacrnt.previous_sum") ^2/ GET("rntvacu.previous_sum") ^2)*( GET("rntvacu.previous_m") ^2)))))*100))', - }, - }, - { - column: 'cv', - aggregator: formula, - options: { - formula: '((GET("rntvacrt.m")/ 1.645) / GET("rntvacrt.sum") * 100)', - }, - }, - { - column: 'comparison_cv', - aggregator: formula, - options: { - formula: '((GET("rntvacrt.comparison_m")/ 1.645) / GET("rntvacrt.comparison_sum") * 100)', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("rntvacrt.sum") - GET("rntvacrt.comparison_sum"))', - }, - }, - { - column: 'difference_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("rntvacrt.m"),2) + POWER(GET("rntvacrt.comparison_m"),2))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("rntvacrt.sum") - GET("rntvacrt.previous_sum"))', - }, - }, - { - column: 'change_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("rntvacrt.m"),2) + POWER(GET("rntvacrt.previous_m"),2))', - }, - }, - ], - }, -]; diff --git a/table-config/housing/housing-tenure.js b/table-config/housing/housing-tenure.js deleted file mode 100755 index d6e41a1..0000000 --- a/table-config/housing/housing-tenure.js +++ /dev/null @@ -1,223 +0,0 @@ -const calculator = require('../../utils/calculator'); -const formula = require('../../utils/formula'); - -module.exports = [ - { - title: 'Occupied housing units', - highlight: true, - variable: 'ochu2', - }, - { - title: 'Owner-occupied', - variable: 'oochu1', - }, - { - title: 'Renter-occupied', - variable: 'rochu1', - }, - { - divider: true, - }, - { - title: 'Average household size of owner-occupied unit', - tooltip: 'Population in owner-occupied housing units, divided by number of owner-occupied housing units', - variable: 'avghhsooc', - special: true, - decimal: 2, - hidePercentChange: false, - specialCalculations: [ - { - column: 'sum', - aggregator: calculator, - options: { - procedure: ['popoochu.sum', 'divide', 'oochu1.sum'], - }, - }, - { - column: 'comparison_sum', - aggregator: calculator, - options: { - procedure: ['popoochu.comparison_sum', 'divide', 'oochu1.comparison_sum'], - }, - }, - { - column: 'm', - aggregator: formula, - options: { - formula: '(1 / GET("oochu4.sum")) * SQRT((GET("popoochu.m")^2) + ((GET("popoochu.sum") / (GET("oochu4.sum")))^2 * (GET("oochu4.m")^2)))', - }, - }, - { - column: 'comparison_m', - aggregator: formula, - options: { - formula: '(1 / GET("oochu4.comparison_sum")) * SQRT((GET("popoochu.comparison_m")^2) + ((GET("popoochu.comparison_sum") / (GET("oochu4.comparison_sum")))^2 * (GET("oochu4.comparison_m")^2)))', - }, - }, - { - column: 'previous_sum', - aggregator: calculator, - options: { - procedure: ['popoochu.previous_sum', 'divide', 'oochu1.previous_sum'], - }, - }, - { - column: 'previous_m', - aggregator: formula, - options: { - formula: '(1/GET("oochu4.previous_sum")) * SQRT((GET("popoochu.previous_m")^2) + (GET("popoochu.previous_sum") / (GET("oochu4.previous_sum")^2) * (GET("oochu4.previous_m")^2)))', - }, - }, - { - column: 'cv', - aggregator: formula, - options: { - formula: '(GET("m")/1.645/GET("sum")*100)', - }, - }, - { - column: 'comparison_cv', - aggregator: formula, - options: { - formula: '(GET("comparison_m")/1.645/GET("comparison_sum")*100)', - }, - }, - { - column: 'previous_cv', - aggregator: formula, - options: { - formula: '(GET("previous_m")/1.645/GET("previous_sum")*100)', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("avghhsooc.sum") - GET("avghhsooc.comparison_sum"))', - }, - }, - { - column: 'difference_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("avghhsooc.m"),2) + POWER(GET("avghhsooc.comparison_m"),2))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("avghhsooc.sum") - GET("avghhsooc.previous_sum"))', - }, - }, - { - column: 'change_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("avghhsooc.m"),2) + (POWER(GET("avghhsooc.previous_m"),2)))', - }, - }, - ], - }, - { - title: 'Average household size of renter-occupied unit', - tooltip: 'Population in renter-occupied housing units, divided by number of renter-occupied housing units', - variable: 'avghhsroc', - special: true, - decimal: 2, - hidePercentChange: false, - specialCalculations: [ - { - column: 'sum', - aggregator: calculator, - options: { - procedure: ['poprtochu.sum', 'divide', 'rochu1.sum'], - }, - }, - { - column: 'comparison_sum', - aggregator: calculator, - options: { - procedure: ['poprtochu.comparison_sum', 'divide', 'rochu1.comparison_sum'], - }, - }, - { - column: 'm', - aggregator: formula, - options: { - formula: '(1 / GET("rochu2.sum")) * SQRT((GET("poprtochu.m")^2) + ((GET("poprtochu.sum") / (GET("rochu2.sum")))^2 * (GET("rochu2.m")^2)))', - }, - }, - { - column: 'comparison_m', - aggregator: formula, - options: { - formula: '(1 / GET("rochu2.comparison_sum")) * SQRT((GET("poprtochu.comparison_m")^2) + ((GET("poprtochu.comparison_sum") / (GET("rochu2.comparison_sum")))^2 * (GET("rochu2.comparison_m")^2)))', - }, - }, - { - column: 'previous_sum', - aggregator: calculator, - options: { - procedure: ['poprtochu.previous_sum', 'divide', 'rochu1.previous_sum'], - }, - }, - { - column: 'previous_m', - aggregator: formula, - options: { - formula: '(1/GET("rochu2.previous_sum")) * SQRT((GET("poprtochu.previous_m")^2) + (GET("poprtochu.previous_sum") / (GET("rochu2.previous_sum")^2) * (GET("rochu2.previous_m")^2)))', - }, - }, - { - column: 'cv', - aggregator: formula, - options: { - formula: '(GET("m")/1.645/GET("sum")*100)', - }, - }, - { - column: 'comparison_cv', - aggregator: formula, - options: { - formula: '(GET("comparison_m")/1.645/GET("comparison_sum")*100)', - }, - }, - { - column: 'previous_cv', - aggregator: formula, - options: { - formula: '(GET("previous_m")/1.645/GET("previous_sum")*100)', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("avghhsroc.sum") - GET("avghhsroc.comparison_sum"))', - }, - }, - { - column: 'difference_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("avghhsroc.m"),2) + POWER(GET("avghhsroc.comparison_m"),2))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("avghhsroc.sum") - GET("avghhsroc.previous_sum"))', - }, - }, - { - column: 'change_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("avghhsroc.m"),2) + POWER(GET("avghhsroc.previous_m"),2))', - }, - }, - ], - }, -]; diff --git a/table-config/housing/index.js b/table-config/housing/index.js deleted file mode 100644 index 007ab81..0000000 --- a/table-config/housing/index.js +++ /dev/null @@ -1,31 +0,0 @@ -// @create-index - -const grossRentAsAPercentageOfHouseholdIncomeGrapi = require('./gross-rent-as-a-percentage-of-household-income--grapi'); -const grossRent = require('./gross-rent'); -const housingOccupancy = require('./housing-occupancy'); -const housingTenure = require('./housing-tenure'); -const mortgageStatus = require('./mortgage-status'); -const occupantsPerRoom = require('./occupants-per-room'); -const rooms = require('./rooms'); -const selectedMonthlyOwnerCostsAsAPercentageOfHouseholdIncomeSmocapi = require('./selected-monthly-owner-costs-as-a-percentage-of-household-income--smocapi'); -const unitsInStructure = require('./units-in-structure'); -const value = require('./value'); -const vehiclesAvailable = require('./vehicles-available'); -const yearHouseholderMovedIntoUnit = require('./year-householder-moved-into-unit'); -const yearStructureBuilt = require('./year-structure-built'); - -module.exports = { - grossRentAsAPercentageOfHouseholdIncomeGrapi, - grossRent, - housingOccupancy, - housingTenure, - mortgageStatus, - occupantsPerRoom, - rooms, - selectedMonthlyOwnerCostsAsAPercentageOfHouseholdIncomeSmocapi, - unitsInStructure, - value, - vehiclesAvailable, - yearHouseholderMovedIntoUnit, - yearStructureBuilt, -}; diff --git a/table-config/housing/mortgage-status.js b/table-config/housing/mortgage-status.js deleted file mode 100755 index 02c0d1c..0000000 --- a/table-config/housing/mortgage-status.js +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = [ - { - title: 'Owner-occupied units', - highlight: true, - variable: 'oochu3', - }, - { - title: 'Housing units with a mortgage', - variable: 'huwmrtg', - }, - { - title: 'Housing units without a mortgage', - variable: 'hunomrtg1', - }, -]; diff --git a/table-config/housing/occupants-per-room.js b/table-config/housing/occupants-per-room.js deleted file mode 100755 index 268acfa..0000000 --- a/table-config/housing/occupants-per-room.js +++ /dev/null @@ -1,21 +0,0 @@ -module.exports = [ - { - title: 'Occupied housing units', - highlight: true, - variable: 'ochu5', - }, - { - title: '1.00 or less', - variable: 'ocpr0t1', - }, - { - title: '1.01 or more', - variable: 'ocpr1pl', - }, - { - indent: 1, - title: '1.51 or more', - variable: 'ocpr1p5pl', - }, -]; - diff --git a/table-config/housing/rooms.js b/table-config/housing/rooms.js deleted file mode 100755 index ecc77dd..0000000 --- a/table-config/housing/rooms.js +++ /dev/null @@ -1,199 +0,0 @@ -const interpolate = require('../../utils/interpolate'); -const calculateMedianError = require('../../utils/calculate-median-error'); -const formula = require('../../utils/formula'); - -const binsForMdrms = [ - ['rms1', [0, 1499]], - ['rms2', [1500, 2499]], - ['rms3', [2500, 3499]], - ['rms4', [3500, 4499]], - ['rms5', [4500, 5499]], - ['rms6', [5500, 6499]], - ['rms7', [6500, 7499]], - ['rms8', [7500, 8499]], - ['rms9pl', [8500, 9000]], -]; - -module.exports = [ - { - title: 'Total housing units', - highlight: true, - variable: 'hu4', - }, - { - title: '1 room', - variable: 'rms1', - }, - { - title: '2 rooms', - variable: 'rms2', - }, - { - title: '3 rooms', - variable: 'rms3', - }, - { - title: '4 rooms', - variable: 'rms4', - }, - { - title: '5 rooms', - variable: 'rms5', - }, - { - title: '6 rooms', - variable: 'rms6', - }, - { - title: '7 rooms', - variable: 'rms7', - }, - { - title: '8 rooms', - variable: 'rms8', - }, - { - title: '9 rooms or more', - variable: 'rms9pl', - }, - { - title: 'Median rooms', - tooltip: 'Medians are calculated using linear interpolation, which may result in top-coded values', - variable: 'mdrms', - special: true, - decimal: 1, - hidePercentChange: true, - specialCalculations: [ - { - column: 'sum', - aggregator: interpolate, - options: { - bins: binsForMdrms, - }, - }, - { - column: 'sum', - aggregator: formula, - options: { - formula: '(GET("mdrms.sum") / 1000)', - }, - }, - { - column: 'm', - aggregator: calculateMedianError, - options: { - designFactor: 1.5, - bins: binsForMdrms, - }, - }, - { - column: 'm', - aggregator: formula, - options: { - formula: '(GET("mdrms.m") / 1000)', - }, - }, - { - column: 'cv', - aggregator: formula, - options: { - formula: '((GET("mdrms.m")/ 1.645) / GET("mdrms.sum") * 100)', - }, - }, - { - column: 'comparison_sum', - aggregator: interpolate, - options: { - bins: binsForMdrms, - }, - }, - { - column: 'comparison_sum', - aggregator: formula, - options: { - formula: '(GET("mdrms.comparison_sum") / 1000)', - }, - }, - { - column: 'comparison_m', - aggregator: calculateMedianError, - options: { - designFactor: 1.5, - bins: binsForMdrms, - }, - }, - { - column: 'comparison_m', - aggregator: formula, - options: { - formula: '(GET("mdrms.comparison_m") / 1000)', - }, - }, - { - column: 'comparison_cv', - aggregator: formula, - options: { - formula: '((GET("mdrms.comparison_m")/ 1.645) / GET("mdrms.comparison_sum") * 100)', - }, - }, - { - column: 'previous_sum', - aggregator: interpolate, - referenceSumKey: 'previous_sum', - options: { - bins: binsForMdrms, - }, - }, - { - column: 'previous_sum', - aggregator: formula, - options: { - formula: '(GET("mdrms.previous_sum") / 1000)', - }, - }, - { - column: 'previous_m', - aggregator: calculateMedianError, - options: { - designFactor: 1.5, - bins: binsForMdrms, - }, - }, - { - column: 'previous_m', - aggregator: formula, - options: { - formula: '(GET("mdrms.previous_m") / 1000)', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("mdrms.sum") - GET("mdrms.comparison_sum"))', - }, - }, - { - column: 'difference_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mdrms.m"),2) + POWER(GET("mdrms.comparison_m"),2))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("mdrms.sum") - GET("mdrms.previous_sum"))', - }, - }, - { - column: 'change_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mdrms.m"),2) + POWER(GET("mdrms.previous_m"),2))', - }, - }, - ], - }, -]; diff --git a/table-config/housing/selected-monthly-owner-costs-as-a-percentage-of-household-income--smocapi.js b/table-config/housing/selected-monthly-owner-costs-as-a-percentage-of-household-income--smocapi.js deleted file mode 100755 index fe003dc..0000000 --- a/table-config/housing/selected-monthly-owner-costs-as-a-percentage-of-household-income--smocapi.js +++ /dev/null @@ -1,79 +0,0 @@ -module.exports = [ - { - title: 'Housing units with a mortgage (excluding units where SMOCAPI cannot be computed)', - highlight: true, - variable: 'huwmrtgex', - }, - { - title: 'Less than 20.0 percent', - variable: 'smpu20', - }, - { - title: '20.0 to 24.9 percent', - variable: 'smp20t24', - }, - { - title: '25.0 to 29.9 percent', - variable: 'smp25t29', - }, - { - title: '30.0 to 34.9 percent', - variable: 'smp30t34', - }, - { - title: '35.0 percent or more', - variable: 'smp35pl', - }, - { - divider: true, - }, - { - title: 'Not computed', - variable: 'smpntc', - special: true, - }, - { - divider: true, - }, - { - title: 'Housing unit without a mortgage (excluding units where SMOCAPI cannot be computed)', - highlight: true, - variable: 'hunomrtg2', - }, - { - title: 'Less than 10.0 percent', - variable: 'nmsmpu10', - }, - { - title: '10.0 to 14.9 percent', - variable: 'nmsmp1014', - }, - { - title: '15.0 to 19.9 percent', - variable: 'nmsmp1519', - }, - { - title: '20.0 to 24.9 percent', - variable: 'nmsmp2024', - }, - { - title: '25.0 to 29.9 percent', - variable: 'nmsmp2529', - }, - { - title: '30.0 to 34.9 percent', - variable: 'nmsmp3034', - }, - { - title: '35.0 percent or more', - variable: 'nmsmp35pl', - }, - { - divider: true, - }, - { - title: 'Not computed', - variable: 'nmsmpntc', - special: true, - }, -]; diff --git a/table-config/housing/units-in-structure.js b/table-config/housing/units-in-structure.js deleted file mode 100755 index f56a28c..0000000 --- a/table-config/housing/units-in-structure.js +++ /dev/null @@ -1,43 +0,0 @@ -module.exports = [ - { - title: 'Total housing units', - highlight: true, - variable: 'hu2', - }, - { - title: '1-unit, detached', - variable: 'hu1ud', - }, - { - title: '1-unit, attached', - variable: 'hu1ua', - }, - { - title: '2 units', - variable: 'hu2u', - }, - { - title: '3 or 4 units', - variable: 'hu3t4u', - }, - { - title: '5 to 9 units', - variable: 'hu5t9u', - }, - { - title: '10 to 19 units', - variable: 'hu10t19u', - }, - { - title: '20 or more units', - variable: 'hu20plu', - }, - { - title: 'Mobile home', - variable: 'mobhm', - }, - { - title: 'Boat, RV, van, etc.', - variable: 'btrvvetc', - }, -]; diff --git a/table-config/housing/value.js b/table-config/housing/value.js deleted file mode 100755 index 3d89d15..0000000 --- a/table-config/housing/value.js +++ /dev/null @@ -1,223 +0,0 @@ -const interpolate = require('../../utils/interpolate'); -const formula = require('../../utils/formula'); -const calculateMedianError = require('../../utils/calculate-median-error'); -const inflate = require('../../utils/inflate'); - -// mdvl -const binsMedianValueEarly = [ - ['ovlu10', [0, 9999]], - ['ovl10t14', [10000, 14999]], - ['ovl15t19', [15000, 19999]], - ['ovl20t24', [20000, 24999]], - ['ovl25t29', [25000, 29999]], - ['ovl30t34', [30000, 34999]], - ['ovl35t39', [35000, 39999]], - ['ovl40t49', [40000, 49999]], - ['ovl50t59', [50000, 59999]], - ['ovl60t69', [60000, 69999]], - ['ovl70t79', [70000, 79999]], - ['ovl80t89', [80000, 89999]], - ['ovl90t99', [90000, 99999]], - ['ov100t124', [100000, 124999]], - ['ov125t149', [125000, 149999]], - ['ov150t174', [150000, 174999]], - ['ov175t199', [175000, 199999]], - ['ov200t249', [200000, 249999]], - ['ov250t299', [250000, 299999]], - ['ov300t399', [300000, 399999]], - ['ov400t499', [400000, 499999]], - ['ov500t749', [500000, 749999]], - ['ov750t999', [750000, 999999]], - ['ov1milpl', [1000000, 9999999]], -]; - -const binsMedianValueLater = [ - ['ovlu10', [0, 9999]], - ['ovl10t14', [10000, 14999]], - ['ovl15t19', [15000, 19999]], - ['ovl20t24', [20000, 24999]], - ['ovl25t29', [25000, 29999]], - ['ovl30t34', [30000, 34999]], - ['ovl35t39', [35000, 39999]], - ['ovl40t49', [40000, 49999]], - ['ovl50t59', [50000, 59999]], - ['ovl60t69', [60000, 69999]], - ['ovl70t79', [70000, 79999]], - ['ovl80t89', [80000, 89999]], - ['ovl90t99', [90000, 99999]], - ['ov100t124', [100000, 124999]], - ['ov125t149', [125000, 149999]], - ['ov150t174', [150000, 174999]], - ['ov175t199', [175000, 199999]], - ['ov200t249', [200000, 249999]], - ['ov250t299', [250000, 299999]], - ['ov300t399', [300000, 399999]], - ['ov400t499', [400000, 499999]], - ['ov500t749', [500000, 749999]], - ['ov750t999', [750000, 999999]], - ['ov1t149m', [1000000, 1499999]], - ['ov150t199m', [1500000, 1999999]], - ['ov2milpl', [2000000, 5000000]], -]; - -module.exports = [ - { - title: 'Owner-occupied units', - highlight: true, - variable: 'oochu2', - }, - { - title: 'Less than $50,000', - variable: 'vlu50', - }, - { - title: '$50,000 to $99,999', - variable: 'vl50t99', - }, - { - title: '$100,000 to $149,999', - variable: 'vl100t149', - }, - { - title: '$150,000 to $199,999', - variable: 'vl150t199', - }, - { - title: '$200,000 to $299,999', - variable: 'vl200t299', - }, - { - title: '$300,000 to $499,999', - variable: 'vl300t499', - }, - { - title: '$500,000 to $999,999', - variable: 'vl500t999', - }, - { - title: '$1,000,000 or more', - variable: 'vl1milpl', - }, - { - title: 'Median (dollars)', - tooltip: 'Medians are calculated using linear interpolation, which may result in top-coded values', - variable: 'mdvl', - special: true, - adjustForInflation: true, - specialCalculations: [ - { - column: 'sum', - aggregator: interpolate, - options: { - multipleBins: true, - bins: [binsMedianValueEarly, binsMedianValueLater], - }, - }, - { - column: 'sum', - aggregator: inflate, - }, - { - column: 'm', - aggregator: calculateMedianError, - options: { - designFactor: 1.4, - multipleBins: true, - bins: [binsMedianValueEarly, binsMedianValueLater], - }, - }, - { - column: 'm', - aggregator: inflate, - }, - { - column: 'cv', - aggregator: formula, - options: { - formula: '((GET("mdvl.m")/ 1.645) / GET("mdvl.sum") * 100)', - }, - }, - { - column: 'comparison_sum', - aggregator: interpolate, - options: { - multipleBins: true, - bins: [binsMedianValueEarly, binsMedianValueLater], - }, - }, - { - column: 'comparison_m', - aggregator: calculateMedianError, - options: { - designFactor: 1.4, - multipleBins: true, - bins: [binsMedianValueEarly, binsMedianValueLater], - }, - }, - { - column: 'comparison_cv', - aggregator: formula, - options: { - formula: '((GET("mdvl.comparison_m")/ 1.645) / GET("mdvl.comparison_sum") * 100)', - }, - }, - { - column: 'previous_sum', - aggregator: interpolate, - options: { - bins: binsMedianValueEarly, - }, - }, - { - column: 'previous_sum', - aggregator: formula, - options: { - formula: '(GET("mdvl.previous_sum") * 1.1005)', - }, - }, - { - column: 'previous_m', - aggregator: calculateMedianError, - options: { - designFactor: 1.4, - bins: binsMedianValueEarly, - }, - }, - { - column: 'previous_m', - aggregator: formula, - options: { - formula: '(GET("mdvl.previous_m") * 1.1005)', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("mdvl.sum") - GET("mdvl.comparison_sum"))', - }, - }, - { - column: 'difference_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mdvl.m"),2) + POWER(GET("mdvl.comparison_m"),2))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("mdvl.sum") - GET("mdvl.previous_sum"))', - }, - }, - { - column: 'change_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("mdvl.m"),2) + POWER(GET("mdvl.previous_m"),2))', - }, - }, - ], - }, -]; diff --git a/table-config/housing/vehicles-available.js b/table-config/housing/vehicles-available.js deleted file mode 100755 index 52f2040..0000000 --- a/table-config/housing/vehicles-available.js +++ /dev/null @@ -1,24 +0,0 @@ -module.exports = [ - { - title: 'Occupied housing units', - highlight: true, - variable: 'ochu4', - }, - { - title: 'No vehicles available', - variable: 'novhclav', - }, - { - title: '1 vehicle available', - variable: 'vhcl1av', - }, - { - title: '2 vehicles available', - variable: 'vhcl2av', - }, - { - title: '3 or more vehicles available', - variable: 'vhcl3plav', - }, -]; - diff --git a/table-config/housing/year-householder-moved-into-unit.js b/table-config/housing/year-householder-moved-into-unit.js deleted file mode 100755 index 646cde7..0000000 --- a/table-config/housing/year-householder-moved-into-unit.js +++ /dev/null @@ -1,27 +0,0 @@ -module.exports = [ - { - title: 'Occupied housing units', - highlight: true, - variable: 'ochu3', - }, - { - title: 'Moved in 2010 or later', - variable: 'mv10ltr', - }, - { - title: 'Moved in 2000 to 2009', - variable: 'mv00t09', - }, - { - title: 'Moved in 1990 to 1999', - variable: 'mv90t99', - }, - { - title: 'Moved in 1980 to 1989', - variable: 'mv80t89', - }, - { - title: 'Moved in 1979 or earlier', - variable: 'mvbf79', - }, -]; diff --git a/table-config/housing/year-structure-built.js b/table-config/housing/year-structure-built.js deleted file mode 100755 index fd8b070..0000000 --- a/table-config/housing/year-structure-built.js +++ /dev/null @@ -1,43 +0,0 @@ -module.exports = [ - { - title: 'Total housing units', - highlight: true, - variable: 'hu3', - }, - { - title: 'Built 2010 or later', - variable: 'blt10ltr', - }, - { - title: 'Built 2000 to 2009', - variable: 'blt00t09', - }, - { - title: 'Built 1990 to 1999', - variable: 'blt90t99', - }, - { - title: 'Built 1980 to 1989', - variable: 'blt80t89', - }, - { - title: 'Built 1970 to 1979', - variable: 'blt70t79', - }, - { - title: 'Built 1960 to 1969', - variable: 'blt60t69', - }, - { - title: 'Built 1950 to 1959', - variable: 'blt50t59', - }, - { - title: 'Built 1940 to 1949', - variable: 'blt40t49', - }, - { - title: 'Built 1939 or earlier', - variable: 'bltbf39', - }, -]; diff --git a/table-config/social/ancestry.js b/table-config/social/ancestry.js deleted file mode 100755 index 4c2af0f..0000000 --- a/table-config/social/ancestry.js +++ /dev/null @@ -1,475 +0,0 @@ -module.exports = [ - { - title: 'Total population', - highlight: true, - variable: 'pop_5', - }, - { - title: 'Afghan', - variable: 'afg', - }, - { - title: 'Albanian', - variable: 'alb', - }, - { - title: 'Alsatian', - variable: 'alsatn', - }, - { - title: 'American', - variable: 'amercn', - }, - { - title: 'Arab', - variable: 'arab', - }, - { - indent: 1, - title: 'Egyptian', - variable: 'egyptn', - }, - { - indent: 1, - title: 'Iraqi', - variable: 'iraqi', - }, - { - indent: 1, - title: 'Jordanian', - variable: 'jrdnian', - }, - { - indent: 1, - title: 'Lebanese', - variable: 'lebanese', - }, - { - indent: 1, - title: 'Moroccan', - variable: 'moroccan', - }, - { - indent: 1, - title: 'Palestinian', - variable: 'palstnian', - }, - { - indent: 1, - title: 'Syrian', - variable: 'syrian', - }, - { - indent: 1, - title: 'Arab', - variable: 'arabsub', - }, - { - indent: 1, - title: 'Other Arab', - variable: 'oarab', - }, - { - title: 'Armenian', - variable: 'armenian', - }, - { - title: 'Assyrian/Chaldean/Syriac', - variable: 'asyrchlds', - }, - { - title: 'Australian', - variable: 'austrln', - }, - { - title: 'Austrian', - variable: 'austrian', - }, - { - title: 'Basque', - variable: 'basque', - }, - { - title: 'Belgian', - variable: 'belgian', - }, - { - title: 'Brazilian', - variable: 'brzlian', - }, - { - title: 'British', - variable: 'british', - }, - { - title: 'Bulgarian', - variable: 'bulgrian', - }, - { - title: 'Cajun', - variable: 'cajun', - }, - { - title: 'Canadian', - variable: 'canadian', - }, - { - title: 'Carpatho Rusyn', - variable: 'carprusn', - }, - { - title: 'Celtic', - variable: 'celtic', - }, - { - title: 'Croatian', - variable: 'croatian', - }, - { - title: 'Cypriot', - variable: 'cypriot', - }, - { - title: 'Czech', - variable: 'czech', - }, - { - title: 'Czechoslovakian', - variable: 'czechslv', - }, - { - title: 'Danish', - variable: 'danish', - }, - { - title: 'Dutch', - variable: 'dutch', - }, - { - title: 'Eastern European', - variable: 'eeurpn', - }, - { - title: 'English', - variable: 'english', - }, - { - title: 'Estonian', - variable: 'estonian', - }, - { - title: 'European', - variable: 'european', - }, - { - title: 'Finnish', - variable: 'finnish', - }, - { - title: 'French (except Basque)', - variable: 'frnotbsq', - }, - { - title: 'French Canadian', - variable: 'frcandian', - }, - { - title: 'German', - variable: 'german', - }, - { - title: 'German Russian', - variable: 'germrus', - }, - { - title: 'Greek', - variable: 'greek', - }, - { - title: 'Guyanese', - variable: 'guyanese', - }, - { - title: 'Hungarian', - variable: 'hgrian', - }, - { - title: 'Icelander', - variable: 'icelndr', - }, - { - title: 'Iranian', - variable: 'iranian', - }, - { - title: 'Irish', - variable: 'irish', - }, - { - title: 'Israeli', - variable: 'israeli', - }, - { - title: 'Italian', - variable: 'italian', - }, - { - title: 'Latvian', - variable: 'latvian', - }, - { - title: 'Lithuanian', - variable: 'lthian', - }, - { - title: 'Luxemburger', - variable: 'luxmbgr', - }, - { - title: 'Macedonian', - variable: 'macdnian', - }, - { - title: 'Maltese', - variable: 'maltese', - }, - { - title: 'New Zealander', - variable: 'nzealnd', - }, - { - title: 'Northern European', - variable: 'neurpn', - }, - { - title: 'Norwegian', - variable: 'norwgian', - }, - { - title: 'Pennsylvania German', - variable: 'penngerm', - }, - { - title: 'Polish', - variable: 'polish', - }, - { - title: 'Portuguese', - variable: 'portgese', - }, - { - title: 'Romanian', - variable: 'romanian', - }, - { - title: 'Russian', - variable: 'russian', - }, - { - title: 'Scandinavian', - variable: 'scandnvn', - }, - { - title: 'Scotch-Irish', - variable: 'sctchirsh', - }, - { - title: 'Scottish', - variable: 'scottish', - }, - { - title: 'Serbian', - variable: 'serbian', - }, - { - title: 'Slavic', - variable: 'slavic', - }, - { - title: 'Slovak', - variable: 'slovak', - }, - { - title: 'Slovene', - variable: 'slovene', - }, - { - title: 'Soviet Union', - variable: 'svtunion', - }, - { - title: 'Subsaharan African', - variable: 'subsaf', - }, - { - indent: 1, - title: 'Cabo Verdean', - variable: 'cvrdean', - }, - { - indent: 1, - title: 'Ethiopian', - variable: 'ethpian', - }, - { - indent: 1, - title: 'Ghanaian', - variable: 'ghanaian', - }, - { - indent: 1, - title: 'Kenyan', - variable: 'kenyan', - }, - { - indent: 1, - title: 'Liberian', - variable: 'liberian', - }, - { - indent: 1, - title: 'Nigerian', - variable: 'nigerian', - }, - { - indent: 1, - title: 'Senegalese', - variable: 'snglese', - }, - { - indent: 1, - title: 'Sierra Leonean', - variable: 'sleonean', - }, - { - indent: 1, - title: 'Somali', - variable: 'somali', - }, - { - indent: 1, - title: 'South African', - variable: 'safrican', - }, - { - indent: 1, - title: 'Sudanese', - variable: 'sudanese', - }, - { - indent: 1, - title: 'Ugandan', - variable: 'ugandan', - }, - { - indent: 1, - title: 'Zimbabwean', - variable: 'zmbwean', - }, - { - indent: 1, - title: 'African', - variable: 'african', - }, - { - indent: 1, - title: 'Other Subsaharan African', - variable: 'osubsafr', - }, - { - title: 'Swedish', - variable: 'swedish', - }, - { - title: 'Swiss', - variable: 'swiss', - }, - { - title: 'Turkish', - variable: 'turkish', - }, - { - title: 'Ukrainian', - variable: 'ukrnian', - }, - { - title: 'Welsh', - variable: 'welsh', - }, - { - title: 'West Indian (except Hispanic groups)', - variable: 'windnhsp', - }, - { - indent: 1, - title: 'Bahamian', - variable: 'bahamian', - }, - { - indent: 1, - title: 'Barbadian', - variable: 'brbdian', - }, - { - indent: 1, - title: 'Belizean', - variable: 'belizean', - }, - { - indent: 1, - title: 'Bermudan', - variable: 'bermudan', - }, - { - indent: 1, - title: 'British West Indian', - variable: 'brtwind', - }, - { - indent: 1, - title: 'Dutch West Indian', - variable: 'dchwind', - }, - { - indent: 1, - title: 'Haitian', - variable: 'haitian', - }, - { - indent: 1, - title: 'Jamaican', - variable: 'jamaican', - }, - { - indent: 1, - title: 'Trinidadian and Tobagonian', - variable: 'tandtob', - }, - { - indent: 1, - title: 'U.S. Virgin Islander', - variable: 'usvrgis', - }, - { - indent: 1, - title: 'West Indian', - variable: 'windsub', - }, - { - indent: 1, - title: 'Other West Indian', - variable: 'owind', - }, - { - title: 'Yugoslavian', - variable: 'yugoslv', - }, - { - title: 'Other groups', - variable: 'othr', - }, - { - title: 'Unclassified or not reported', - variable: 'unclsnr', - }, -]; diff --git a/table-config/social/computers-and-internet-use.js b/table-config/social/computers-and-internet-use.js deleted file mode 100644 index 06c5a0c..0000000 --- a/table-config/social/computers-and-internet-use.js +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = [ - { - title: 'Total Households', - highlight: true, - variable: 'hh3', - }, - { - title: 'With a computer', - variable: 'hhcomp', - }, - { - title: 'With a broadband Internet subscription', - variable: 'hhint', - }, -]; diff --git a/table-config/social/disability-status-of-the-civilian-noninstitutionalized-population.js b/table-config/social/disability-status-of-the-civilian-noninstitutionalized-population.js deleted file mode 100755 index 71849ff..0000000 --- a/table-config/social/disability-status-of-the-civilian-noninstitutionalized-population.js +++ /dev/null @@ -1,162 +0,0 @@ -module.exports = [ - { - title: 'Total civilian noninstitutionalized population', - highlight: true, - variable: 'cvnipop1', - }, - { - title: 'With a disability', - variable: 'cvnid', - }, - { - indent: 1, - title: 'With a hearing difficulty', - variable: 'cvnid_hrg', - }, - { - indent: 1, - title: 'With a vision difficulty', - variable: 'cvnid_vsn', - }, - { - indent: 1, - title: 'With a cognitive difficulty', - variable: 'cvnid_cog', - }, - { - indent: 1, - title: 'With an ambulatory difficulty', - variable: 'cvnid_amb', - }, - { - indent: 1, - title: 'With a self-care difficulty', - variable: 'cvnid_scr', - }, - { - indent: 1, - title: 'With an independent living difficulty', - variable: 'cvnid_ild', - }, - { - divider: true, - }, - { - title: 'Under 18 years', - highlight: true, - variable: 'cvniu18_1', - }, - { - title: 'With a disability', - variable: 'cvniu18d', - }, - { - indent: 1, - title: 'With a hearing difficulty', - variable: 'cu18dhrg', - }, - { - indent: 1, - title: 'With a vision difficulty', - variable: 'cu18dvsn', - }, - { - indent: 1, - title: 'With a cognitive difficulty', - variable: 'cu18dcog', - }, - { - indent: 1, - title: 'With an ambulatory difficulty', - variable: 'cu18damb', - }, - { - indent: 1, - title: 'With a self-care difficulty', - variable: 'cu18dscr', - }, - { - divider: true, - }, - { - title: '18 to 64 years', - highlight: true, - variable: 'cni1864_1', - }, - { - title: 'With a disability', - variable: 'cni18t64d', - }, - { - indent: 1, - title: 'With a hearing difficulty', - variable: 'c1864dhrg', - }, - { - indent: 1, - title: 'With a vision difficulty', - variable: 'c1864dvsn', - }, - { - indent: 1, - title: 'With a cognitive difficulty', - variable: 'c1864dcog', - }, - { - indent: 1, - title: 'With an ambulatory difficulty', - variable: 'c1864damb', - }, - { - indent: 1, - title: 'With a self-care difficulty', - variable: 'c1864dscr', - }, - { - indent: 1, - title: 'With an independent living difficulty', - variable: 'c1864dild', - }, - { - divider: true, - }, - { - title: '65 years and over', - highlight: true, - variable: 'cvni65pl', - }, - { - title: 'With a disability', - variable: 'cvni65pld', - }, - { - indent: 1, - title: 'With a hearing difficulty', - variable: 'c65pldhrg', - }, - { - indent: 1, - title: 'With a vision difficulty', - variable: 'c65pldvsn', - }, - { - indent: 1, - title: 'With a cognitive difficulty', - variable: 'c65pldcog', - }, - { - indent: 1, - title: 'With an ambulatory difficulty', - variable: 'c65pldamb', - }, - { - indent: 1, - title: 'With a self-care difficulty', - variable: 'c65pldscr', - }, - { - indent: 1, - title: 'With an independent living difficulty', - variable: 'c65pldild', - }, -]; diff --git a/table-config/social/educational-attainment--highest-grade-completed.js b/table-config/social/educational-attainment--highest-grade-completed.js deleted file mode 100755 index 20d6c50..0000000 --- a/table-config/social/educational-attainment--highest-grade-completed.js +++ /dev/null @@ -1,47 +0,0 @@ - -module.exports = [ - { - title: 'Population 25 years and over', - highlight: true, - variable: 'ea_p25pl', - }, - { - title: 'Less than 9th grade', - variable: 'ea_lt9g', - }, - { - title: '9th to 12th grade, no diploma', - variable: 'ea_9t12nd', - }, - { - title: 'High school graduate (includes equivalency)', - variable: 'ea_hscgrd', - }, - { - title: 'Some college, no degree', - variable: 'ea_sclgnd', - }, - { - title: 'Associate\'s degree', - variable: 'ea_ascd', - }, - { - title: 'Bachelor\'s degree', - variable: 'ea_bchd', - }, - { - title: 'Graduate or professional degree', - variable: 'ea_grdpfd', - }, - { - divider: true, - }, - { - title: 'Less than high school graduate', - variable: 'ea_lthsgr', - }, - { - title: 'Bachelor\'s degree or higher', - variable: 'ea_bchdh' }, - -]; diff --git a/table-config/social/grandparents.js b/table-config/social/grandparents.js deleted file mode 100755 index 719374f..0000000 --- a/table-config/social/grandparents.js +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = [ - { - title: 'Number of grandparents living with own grandchildren under 18 years', - highlight: true, - variable: 'gplgcu18', - }, - { - title: 'Responsible for grandchildren', - variable: 'gprgcu18', - }, -]; diff --git a/table-config/social/household-type.js b/table-config/social/household-type.js deleted file mode 100755 index 03bead0..0000000 --- a/table-config/social/household-type.js +++ /dev/null @@ -1,283 +0,0 @@ -const calculator = require('../../utils/calculator'); - -const formula = require('../../utils/formula'); - -module.exports = [ - { - title: 'Total households', - highlight: true, - variable: 'hh1', - }, - { - title: 'Family households (families)', - variable: 'fam1', - }, - { - indent: 2, - title: 'With own children under 18 years', - variable: 'famchu18', - }, - { - indent: 1, - title: 'Married-couple family', - variable: 'mrdfam', - }, - { - indent: 2, - title: 'With own children under 18 years', - variable: 'mrdchu18', - }, - { - indent: 1, - title: 'Male householder, no wife present, family', - variable: 'mhnw', - }, - { - indent: 2, - title: 'With own children under 18 years', - variable: 'mhnwchu18', - }, - { - indent: 1, - title: 'Female householder, no husband present, family', - variable: 'fhnh', - }, - { - indent: 2, - title: 'With own children under 18 years', - variable: 'fhnhchu18', - }, - { - title: 'Nonfamily households', - variable: 'nfam1', - }, - { - indent: 1, - title: 'Householder living alone', - variable: 'nfama', - }, - { - indent: 2, - title: '65 years and over', - variable: 'nfama65pl', - }, - { - divider: true, - }, - { - title: 'Households with one or more people under 18 years', - variable: 'hh1plu18', - }, - { - title: 'Households with one or more people 65 years and over', - variable: 'hh1pl65pl', - }, - { - divider: true, - }, - { - title: 'Average household size', - tooltip: 'Household population divided by number of households', - variable: 'avghhsz', - special: true, - decimal: 2, - hidePercentChange: true, - specialCalculations: [ - { - column: 'sum', - aggregator: calculator, - options: { - procedure: ['hhpop.sum', 'divide', 'hh1.sum'], - }, - }, - { - column: 'comparison_sum', - aggregator: calculator, - options: { - procedure: ['hhpop.comparison_sum', 'divide', 'hh1.comparison_sum'], - }, - }, - { - column: 'previous_sum', - aggregator: calculator, - options: { - procedure: ['hhpop.previous_sum', 'divide', 'hh1.previous_sum'], - }, - }, - { - column: 'm', - aggregator: formula, - options: { - formula: '(1 / GET("hh4.sum")) * SQRT((GET("hhpop1.m")^2) + ((GET("hhpop1.sum") / (GET("hh4.sum")))^2 * (GET("hh4.m")^2)))', - }, - }, - { - column: 'cv', - aggregator: formula, - options: { - formula: '(GET("m")/1.645/GET("sum")*100)', - }, - }, - { - column: 'previous_m', - aggregator: formula, - options: { - formula: '(1/GET("hh4.previous_sum")) * SQRT((GET("hhpop1.previous_m")^2) + (GET("hhpop1.previous_sum") / (GET("hh4.previous_sum")^2) * (GET("hh4.previous_m")^2)))', - }, - }, - { - column: 'previous_cv', - aggregator: formula, - options: { - formula: '(GET("previous_m")/1.645/GET("previous_sum")*100)', - }, - }, - { - column: 'comparison_m', - aggregator: formula, - options: { - formula: '(1 / GET("hh4.comparison_sum")) * SQRT((GET("hhpop1.comparison_m")^2) + ((GET("hhpop1.comparison_sum") / (GET("hh4.comparison_sum")))^2 * (GET("hh4.comparison_m")^2)))', - }, - }, - { - column: 'comparison_cv', - aggregator: formula, - options: { - formula: '(GET("comparison_m")/1.645/GET("comparison_sum")*100)', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("avghhsz.sum") - GET("avghhsz.comparison_sum"))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("avghhsz.sum") - GET("avghhsz.previous_sum"))', - }, - }, - { - column: 'difference_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("avghhsz.m"),2) + POWER(GET("avghhsz.comparison_m"),2))', - }, - }, - { - column: 'change_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("avghhsz.m"),2) + POWER(GET("avghhsz.previous_m"),2))', - }, - }, - ], - }, - { - title: 'Average family size', - tooltip: 'Population in family households, minus nonrelatives in family households, divided by number of family households', - variable: 'avgfmsz', - special: true, - decimal: 2, - hidePercentChange: true, - specialCalculations: [ - { - column: 'sum', - aggregator: calculator, - options: { - procedure: ['popinfms.sum', 'divide', 'fam1.sum'], - }, - }, - { - column: 'comparison_sum', - aggregator: calculator, - options: { - procedure: ['popinfms.comparison_sum', 'divide', 'fam1.comparison_sum'], - }, - }, - { - column: 'previous_sum', - aggregator: calculator, - options: { - procedure: ['popinfms.previous_sum', 'divide', 'fam1.previous_sum'], - }, - }, - { - column: 'previous_m', - aggregator: formula, - options: { - formula: '(1/GET("fam3.previous_sum")) * SQRT((GET("popinfms.previous_m")^2) + (GET("popinfms.previous_sum") / (GET("fam3.previous_sum")^2) * (GET("fam3.previous_m")^2)))', - }, - }, - { - column: 'previous_cv', - aggregator: formula, - options: { - formula: '(GET("previous_m")/1.645/GET("previous_sum")*100)', - }, - }, - { - column: 'm', - aggregator: formula, - options: { - formula: '(1 / GET("fam3.sum")) * SQRT((GET("popinfms.m")^2) + ((GET("popinfms.sum") / (GET("fam3.sum")))^2 * (GET("fam3.m")^2)))', - }, - }, - { - column: 'cv', - aggregator: formula, - options: { - formula: '(GET("m")/1.645/GET("sum")*100)', - }, - }, - { - column: 'comparison_m', - aggregator: formula, - options: { - formula: '(1 / GET("fam3.comparison_sum")) * SQRT((GET("popinfms.comparison_m")^2) + ((GET("popinfms.comparison_sum") / (GET("fam3.comparison_sum")))^2 * (GET("fam3.comparison_m")^2)))', - }, - }, - { - column: 'comparison_cv', - aggregator: formula, - options: { - formula: '(GET("comparison_m")/1.645/GET("comparison_sum")*100)', - }, - }, - { - column: 'difference_sum', - aggregator: formula, - options: { - formula: '(GET("avgfmsz.sum") - GET("avgfmsz.comparison_sum"))', - }, - }, - { - column: 'difference_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("avgfmsz.m"),2) + POWER(GET("avgfmsz.comparison_m"),2))', - }, - }, - { - column: 'change_sum', - aggregator: formula, - options: { - formula: '(GET("avgfmsz.sum") - GET("avgfmsz.previous_sum"))', - }, - }, - { - column: 'change_m', - aggregator: formula, - options: { - formula: 'SQRT(POWER(GET("avgfmsz.m"),2) + POWER(GET("avgfmsz.previous_m"),2))', - }, - }, - ], - }, - { - divider: true, - }, -]; diff --git a/table-config/social/index.js b/table-config/social/index.js deleted file mode 100644 index aea96b4..0000000 --- a/table-config/social/index.js +++ /dev/null @@ -1,35 +0,0 @@ -// @create-index - -const ancestry = require('./ancestry'); -const computersAndInternetUse = require('./computers-and-internet-use'); -const disabilityStatusOfTheCivilianNoninstitutionalizedPopulation = require('./disability-status-of-the-civilian-noninstitutionalized-population'); -const educationalAttainmentHighestGradeCompleted = require('./educational-attainment--highest-grade-completed'); -const grandparents = require('./grandparents'); -const householdType = require('./household-type'); -const languageSpokenAtHome = require('./language-spoken-at-home'); -const maritalStatus = require('./marital-status'); -const placeOfBirth = require('./place-of-birth'); -const relationshipToHeadOfHouseholdHouseholder = require('./relationship-to-head-of-household--householder'); -const residence1YearAgo = require('./residence-1-year-ago'); -const schoolEnrollment = require('./school-enrollment'); -const uSCitizenshipStatus = require('./u-s--citizenship-status'); -const veteranStatus = require('./veteran-status'); -const yearOfEntry = require('./year-of-entry'); - -module.exports = { - ancestry, - computersAndInternetUse, // Computers and Internet Use - disabilityStatusOfTheCivilianNoninstitutionalizedPopulation, - educationalAttainmentHighestGradeCompleted, - grandparents, - householdType, - languageSpokenAtHome, - maritalStatus, - placeOfBirth, - relationshipToHeadOfHouseholdHouseholder, - residence1YearAgo, - schoolEnrollment, - uSCitizenshipStatus, - veteranStatus, - yearOfEntry, -}; diff --git a/table-config/social/language-spoken-at-home.js b/table-config/social/language-spoken-at-home.js deleted file mode 100755 index d19af12..0000000 --- a/table-config/social/language-spoken-at-home.js +++ /dev/null @@ -1,752 +0,0 @@ -module.exports = [ - { - title: 'Population 5 years and over', - highlight: true, - variable: 'pop5pl1', - }, - { - title: 'English only', - variable: 'engonly1', - }, - { - title: 'Language other than English', - variable: 'lgoeng1', - }, - { - indent: 2, - title: 'Speak English less than "very well"', - variable: 'lgoenlep1', - }, - { - divider: true, - }, - { - title: 'Spanish or Spanish Creole', - highlight: true, - variable: 'lgsp1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgsplep1', - }, - { - title: 'French (incl. Patois, Cajun)', - highlight: true, - variable: 'lgfr1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgfrlep1', - }, - { - title: 'French Creole', - highlight: true, - variable: 'lgfrcr1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgfrclep1', - }, - { - title: 'Italian', - highlight: true, - variable: 'lgit1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgitlep1', - }, - { - title: 'Portuguese or Portuguese Creole', - highlight: true, - variable: 'lgprt1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgprtlep1', - }, - { - title: 'German', - highlight: true, - variable: 'lggrm1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lggrmlep1', - }, - { - title: 'Yiddish', - highlight: true, - variable: 'lgyid1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgyidlep1', - }, - { - title: 'Other West Germanic languages', - highlight: true, - variable: 'lgowg1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgowglep1', - }, - { - title: 'Scandinavian languages', - highlight: true, - variable: 'lgscd1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgscdlep1', - }, - { - title: 'Greek', - highlight: true, - variable: 'lggrk1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lggrklep1', - }, - { - title: 'Russian', - highlight: true, - variable: 'lgrus1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgruslep1', - }, - { - title: 'Polish', - highlight: true, - variable: 'lgpol1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgpollep1', - }, - { - title: 'Serbo-Croatian', - highlight: true, - variable: 'lgscr1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgscrlep1', - }, - { - title: 'Other Slavic languages', - highlight: true, - variable: 'lgoslv1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgosvlep1', - }, - { - title: 'Armenian', - highlight: true, - variable: 'lgarm1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgarmlep1', - }, - { - title: 'Persian', - highlight: true, - variable: 'lgprs1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgprslep1', - }, - { - title: 'Gujarati', - highlight: true, - variable: 'lgguj1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lggujlep1', - }, - { - title: 'Hindi', - highlight: true, - variable: 'lghdi1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lghdilep1', - }, - { - title: 'Urdu', - highlight: true, - variable: 'lgurd1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgurdlep1', - }, - { - title: 'Other Indic languages', - highlight: true, - variable: 'lgoind1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgoinlep1', - }, - { - title: 'Other Indo-European languages', - highlight: true, - variable: 'lgoieu1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgoielep1', - }, - { - title: 'Chinese', - highlight: true, - variable: 'lgchi1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgchilep1', - }, - { - title: 'Japanese', - highlight: true, - variable: 'lgjap1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgjaplep1', - }, - { - title: 'Korean', - highlight: true, - variable: 'lgkor1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgkorlep1', - }, - { - title: 'Mon-Khmer, Cambodian', - highlight: true, - variable: 'lgmkhm1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgmkmlep1', - }, - { - title: 'Hmong', - highlight: true, - variable: 'lghmg1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lghmglep1', - }, - { - title: 'Thai', - highlight: true, - variable: 'lgthai1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgthalep1', - }, - { - title: 'Laotian', - highlight: true, - variable: 'lglao1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lglaolep1', - }, - { - title: 'Vietnamese', - highlight: true, - variable: 'lgviet1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgvielep1', - }, - { - title: 'Other Asian languages', - highlight: true, - variable: 'lgoasn1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgoanlep1', - }, - { - title: 'Tagalog', - highlight: true, - variable: 'lgtag1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgtaglep1', - }, - { - title: 'Other Pacific Island languages', - highlight: true, - variable: 'lgopi1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgopilep1', - }, - { - title: 'Navajo', - highlight: true, - variable: 'lgnav1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgnavlep1', - }, - { - title: 'Other Native North American languages', - highlight: true, - variable: 'lgonna1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgonalep1', - }, - { - title: 'Hungarian', - highlight: true, - variable: 'lghung1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lghnglep1', - }, - { - title: 'Arabic', - highlight: true, - variable: 'lgarab1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgarblep1', - }, - { - title: 'Hebrew', - highlight: true, - variable: 'lgheb1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgheblep1', - }, - { - title: 'African languages', - highlight: true, - variable: 'lgafr1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgafrlep1', - }, - { - title: 'Other and unspecified languages', - highlight: true, - variable: 'lgolg1', - }, - { - title: 'Speak English less than "very well"', - variable: 'lgolglep1', - }, - { - divider: true, - }, - { - title: 'Population 5 years and over', - highlight: true, - variable: 'pop5pl2', - }, - { - title: 'English only', - variable: 'engonly2', - }, - { - title: 'Language other than English', - variable: 'lgoeng2', - }, - { - indent: 1, - title: 'Spanish or Spanish Creole', - variable: 'lgsp2', - }, - { - indent: 1, - title: 'French (incl. Patois, Cajun)', - variable: 'lgfr2', - }, - { - indent: 1, - title: 'French Creole', - variable: 'lgfrcr2', - }, - { - indent: 1, - title: 'Italian', - variable: 'lgit2', - }, - { - indent: 1, - title: 'Portuguese or Portuguese Creole', - variable: 'lgprt2', - }, - { - indent: 1, - title: 'German', - variable: 'lggrm2', - }, - { - indent: 1, - title: 'Yiddish', - variable: 'lgyid2', - }, - { - indent: 1, - title: 'Other West Germanic languages', - variable: 'lgowg2', - }, - { - indent: 1, - title: 'Scandinavian languages', - variable: 'lgscd2', - }, - { - indent: 1, - title: 'Greek', - variable: 'lggrk2', - }, - { - indent: 1, - title: 'Russian', - variable: 'lgrus2', - }, - { - indent: 1, - title: 'Polish', - variable: 'lgpol2', - }, - { - indent: 1, - title: 'Serbo-Croatian', - variable: 'lgscr2', - }, - { - indent: 1, - title: 'Other Slavic languages', - variable: 'lgoslv2', - }, - { - indent: 1, - title: 'Armenian', - variable: 'lgarm2', - }, - { - indent: 1, - title: 'Persian', - variable: 'lgprs2', - }, - { - indent: 1, - title: 'Gujarati', - variable: 'lgguj2', - }, - { - indent: 1, - title: 'Hindi', - variable: 'lghdi2', - }, - { - indent: 1, - title: 'Urdu', - variable: 'lgurd2', - }, - { - indent: 1, - title: 'Other Indic languages', - variable: 'lgoind2', - }, - { - indent: 1, - title: 'Other Indo-European languages', - variable: 'lgoieu2', - }, - { - indent: 1, - title: 'Chinese', - variable: 'lgchi2', - }, - { - indent: 1, - title: 'Japanese', - variable: 'lgjap2', - }, - { - indent: 1, - title: 'Korean', - variable: 'lgkor2', - }, - { - indent: 1, - title: 'Mon-Khmer, Cambodian', - variable: 'lgmkhm2', - }, - { - indent: 1, - title: 'Hmong', - variable: 'lghmg2', - }, - { - indent: 1, - title: 'Thai', - variable: 'lgthai2', - }, - { - indent: 1, - title: 'Laotian', - variable: 'lglao2', - }, - { - indent: 1, - title: 'Vietnamese', - variable: 'lgviet2', - }, - { - indent: 1, - title: 'Other Asian languages', - variable: 'lgoasn2', - }, - { - indent: 1, - title: 'Tagalog', - variable: 'lgtag2', - }, - { - indent: 1, - title: 'Other Pacific Island languages', - variable: 'lgopi2', - }, - { - indent: 1, - title: 'Navajo', - variable: 'lgnav2', - }, - { - indent: 1, - title: 'Other Native North American languages', - variable: 'lgonna2', - }, - { - indent: 1, - title: 'Hungarian', - variable: 'lghung2', - }, - { - indent: 1, - title: 'Arabic', - variable: 'lgarab2', - }, - { - indent: 1, - title: 'Hebrew', - variable: 'lgheb2', - }, - { - indent: 1, - title: 'African languages', - variable: 'lgafr2', - }, - { - indent: 1, - title: 'Other and unspecified languages', - variable: 'lgolg2', - }, - { - divider: true, - }, - { - title: 'Speak English less than "very well"', - highlight: true, - variable: 'lgoenlep2', - }, - { - title: 'Spanish or Spanish Creole', - variable: 'lgsplep2', - }, - { - title: 'French (incl. Patois, Cajun)', - variable: 'lgfrlep2', - }, - { - title: 'French Creole', - variable: 'lgfrclep2', - }, - { - title: 'Italian', - variable: 'lgitlep2', - }, - { - title: 'Portuguese or Portuguese Creole', - variable: 'lgprtlep2', - }, - { - title: 'German', - variable: 'lggrmlep2', - }, - { - title: 'Yiddish', - variable: 'lgyidlep2', - }, - { - title: 'Other West Germanic languages', - variable: 'lgowglep2', - }, - { - title: 'Scandinavian languages', - variable: 'lgscdlep2', - }, - { - title: 'Greek', - variable: 'lggrklep2', - }, - { - title: 'Russian', - variable: 'lgruslep2', - }, - { - title: 'Polish', - variable: 'lgpollep2', - }, - { - title: 'Serbo-Croatian', - variable: 'lgscrlep2', - }, - { - title: 'Other Slavic languages', - variable: 'lgosvlep2', - }, - { - title: 'Armenian', - variable: 'lgarmlep2', - }, - { - title: 'Persian', - variable: 'lgprslep2', - }, - { - title: 'Gujarati', - variable: 'lggujlep2', - }, - { - title: 'Hindi', - variable: 'lghdilep2', - }, - { - title: 'Urdu', - variable: 'lgurdlep2', - }, - { - title: 'Other Indic languages', - variable: 'lgoinlep2', - }, - { - title: 'Other Indo-European languages', - variable: 'lgoielep2', - }, - { - title: 'Chinese', - variable: 'lgchilep2', - }, - { - title: 'Japanese', - variable: 'lgjaplep2', - }, - { - title: 'Korean', - variable: 'lgkorlep2', - }, - { - title: 'Mon-Khmer, Cambodian', - variable: 'lgmkmlep2', - }, - { - title: 'Hmong', - variable: 'lghmglep2', - }, - { - title: 'Thai', - variable: 'lgthalep2', - }, - { - title: 'Laotian', - variable: 'lglaolep2', - }, - { - title: 'Vietnamese', - variable: 'lgvielep2', - }, - { - title: 'Other Asian languages', - variable: 'lgoanlep2', - }, - { - title: 'Tagalog', - variable: 'lgtaglep2', - }, - { - title: 'Other Pacific Island languages', - variable: 'lgopilep2', - }, - { - title: 'Navajo', - variable: 'lgnavlep2', - }, - { - title: 'Other Native North American languages', - variable: 'lgonalep2', - }, - { - title: 'Hungarian', - variable: 'lghnglep2', - }, - { - title: 'Arabic', - variable: 'lgarblep2', - }, - { - title: 'Hebrew', - variable: 'lgheblep2', - }, - { - title: 'African languages', - variable: 'lgafrlep2', - }, - { - title: 'Other and unspecified languages', - variable: 'lgolglep2', - }, - { - divider: true, - }, -]; diff --git a/table-config/social/marital-status.js b/table-config/social/marital-status.js deleted file mode 100755 index a8fa902..0000000 --- a/table-config/social/marital-status.js +++ /dev/null @@ -1,55 +0,0 @@ -module.exports = [ - { - title: 'Males 15 years and over', - highlight: true, - variable: 'ms_m15pl', - }, - { - title: 'Never married', - variable: 'ms_mnvmrd', - }, - { - title: 'Now married, except separated', - variable: 'ms_mmrdsp', - }, - { - title: 'Separated', - variable: 'ms_msp', - }, - { - title: 'Widowed', - variable: 'ms_mwd', - }, - { - title: 'Divorced', - variable: 'ms_mdvcd', - }, - { - divider: true, - }, - { - title: 'Females 15 years and over', - highlight: true, - variable: 'ms_f15pl', - }, - { - title: 'Never married', - variable: 'ms_fnvmrd', - }, - { - title: 'Now married, except separated', - variable: 'ms_fmrdsp', - }, - { - title: 'Separated', - variable: 'ms_fsp', - }, - { - title: 'Widowed', - variable: 'ms_fwd', - }, - { - title: 'Divorced', - variable: 'ms_fdvcd', - }, -]; diff --git a/table-config/social/place-of-birth.js b/table-config/social/place-of-birth.js deleted file mode 100755 index d0acb16..0000000 --- a/table-config/social/place-of-birth.js +++ /dev/null @@ -1,833 +0,0 @@ -module.exports = [ - { - title: 'Total population', - highlight: true, - variable: 'pop_4', - }, - { - title: 'Native', - variable: 'ntv', - }, - { - indent: 1, - title: 'Born in United States', - variable: 'ntvus', - }, - { - indent: 2, - title: 'Born in New York State', - variable: 'ntvnys', - }, - { - indent: 2, - title: 'Born outside New York State', - variable: 'ntvnotnys', - }, - { - indent: 1, - title: 'Born in Puerto Rico, U.S. Island areas, or born abroad to American parent(s)', - variable: 'ntvprusab', - }, - { - title: 'Foreign-born', - variable: 'fb1', - }, - { - divider: true, - }, - { - title: 'Foreign-born', - highlight: true, - variable: 'fb2', - }, - { - title: 'Europe', - variable: 'eur', - }, - { - indent: 1, - title: 'Northern Europe', - variable: 'neur', - }, - { - indent: 2, - title: 'United Kingdom (inc. Crown Dependencies)', - variable: 'untdkgdm', - }, - { - indent: 3, - title: 'United Kingdom, excluding England and Scotland', - variable: 'uknoengsc', - }, - { - indent: 3, - title: 'England', - variable: 'eng', - }, - { - indent: 3, - title: 'Scotland', - variable: 'scot', - }, - { - indent: 2, - title: 'Ireland', - variable: 'ireland', - }, - { - indent: 2, - title: 'Denmark', - variable: 'denmark', - }, - { - indent: 2, - title: 'Norway', - variable: 'norway', - }, - { - indent: 2, - title: 'Sweden', - variable: 'sweden', - }, - { - indent: 2, - title: 'Other Northern Europe', - variable: 'oneur', - }, - { - indent: 1, - title: 'Western Europe', - variable: 'weur', - }, - { - indent: 2, - title: 'Austria', - variable: 'austria', - }, - { - indent: 2, - title: 'Belgium', - variable: 'belgium', - }, - { - indent: 2, - title: 'France', - variable: 'france', - }, - { - indent: 2, - title: 'Germany', - variable: 'germany', - }, - { - indent: 2, - title: 'Netherlands', - variable: 'nthrlds', - }, - { - indent: 2, - title: 'Switzerland', - variable: 'switzrld', - }, - { - indent: 2, - title: 'Other Western Europe', - variable: 'oweur', - }, - { - indent: 1, - title: 'Southern Europe', - variable: 'seur', - }, - { - indent: 2, - title: 'Greece', - variable: 'greece', - }, - { - indent: 2, - title: 'Italy', - variable: 'italy', - }, - { - indent: 2, - title: 'Portugal', - variable: 'portugal', - }, - { - indent: 2, - title: 'Spain', - variable: 'spain', - }, - { - indent: 2, - title: 'Other Southern Europe', - variable: 'oseur', - }, - { - indent: 1, - title: 'Eastern Europe', - variable: 'eeur', - }, - { - indent: 2, - title: 'Albania', - variable: 'albania', - }, - { - indent: 2, - title: 'Belarus', - variable: 'belarus', - }, - { - indent: 2, - title: 'Bulgaria', - variable: 'bulgaria', - }, - { - indent: 2, - title: 'Croatia', - variable: 'croatia', - }, - { - indent: 2, - title: 'Czechoslovakia (includes Czech Republic and Slovakia)', - variable: 'czchslv', - }, - { - indent: 2, - title: 'Hungary', - variable: 'hungary', - }, - { - indent: 2, - title: 'Latvia', - variable: 'latvia', - }, - { - indent: 2, - title: 'Lithuania', - variable: 'lthuania', - }, - { - indent: 2, - title: 'Macedonia', - variable: 'mcdonia', - }, - { - indent: 2, - title: 'Moldova', - variable: 'moldova', - }, - { - indent: 2, - title: 'Poland', - variable: 'poland', - }, - { - indent: 2, - title: 'Romania', - variable: 'romania', - }, - { - indent: 2, - title: 'Russia', - variable: 'russia', - }, - { - indent: 2, - title: 'Ukraine', - variable: 'ukraine', - }, - { - indent: 2, - title: 'Bosnia and Herzegovina', - variable: 'bosniah', - }, - { - indent: 2, - title: 'Serbia', - variable: 'serbia', - }, - { - indent: 2, - title: 'Other Eastern Europe', - variable: 'oeeur', - }, - { - indent: 1, - title: 'Europe, n.e.c.', - variable: 'eurnec', - }, - { - title: 'Asia', - variable: 'asia', - }, - { - indent: 1, - title: 'Eastern Asia', - variable: 'easia', - }, - { - indent: 2, - title: 'China', - variable: 'china', - }, - { - indent: 3, - title: 'China, excluding Hong Kong and Taiwan', - variable: 'chnohktwn', - }, - { - indent: 3, - title: 'Hong Kong', - variable: 'hongkong', - }, - { - indent: 3, - title: 'Taiwan', - variable: 'taiwan', - }, - { - indent: 2, - title: 'Japan', - variable: 'japan', - }, - { - indent: 2, - title: 'Korea', - variable: 'korea', - }, - { - indent: 2, - title: 'Other Eastern Asia', - variable: 'oeasia', - }, - { - indent: 1, - title: 'South Central Asia', - variable: 'scasia', - }, - { - indent: 2, - title: 'Afghanistan', - variable: 'afghan', - }, - { - indent: 2, - title: 'Bangladesh', - variable: 'bngldsh', - }, - { - indent: 2, - title: 'India', - variable: 'india', - }, - { - indent: 2, - title: 'Iran', - variable: 'iran', - }, - { - indent: 2, - title: 'Kazakhstan', - variable: 'kzkhstan', - }, - { - indent: 2, - title: 'Nepal', - variable: 'nepal', - }, - { - indent: 2, - title: 'Pakistan', - variable: 'pakistan', - }, - { - indent: 2, - title: 'Sri Lanka', - variable: 'srilanka', - }, - { - indent: 2, - title: 'Uzbekistan', - variable: 'uzbkstan', - }, - { - indent: 2, - title: 'Other South Central Asia', - variable: 'oscasia', - }, - { - indent: 1, - title: 'South Eastern Asia', - variable: 'seasia', - }, - { - indent: 2, - title: 'Cambodia', - variable: 'cambodia', - }, - { - indent: 2, - title: 'Indonesia', - variable: 'indnsia', - }, - { - indent: 2, - title: 'Laos', - variable: 'laos', - }, - { - indent: 2, - title: 'Malaysia', - variable: 'malaysia', - }, - { - indent: 2, - title: 'Burma', - variable: 'burma', - }, - { - indent: 2, - title: 'Philippines', - variable: 'philipns', - }, - { - indent: 2, - title: 'Singapore', - variable: 'sngapore', - }, - { - indent: 2, - title: 'Thailand', - variable: 'thailand', - }, - { - indent: 2, - title: 'Vietnam', - variable: 'vietnam', - }, - { - indent: 2, - title: 'Other South Eastern Asia', - variable: 'oseasia', - }, - { - indent: 1, - title: 'Western Asia', - variable: 'wasia', - }, - { - indent: 2, - title: 'Iraq', - variable: 'iraq', - }, - { - indent: 2, - title: 'Israel', - variable: 'israel', - }, - { - indent: 2, - title: 'Jordan', - variable: 'jordan', - }, - { - indent: 2, - title: 'Kuwait', - variable: 'kuwait', - }, - { - indent: 2, - title: 'Lebanon', - variable: 'lebanon', - }, - { - indent: 2, - title: 'Saudi Arabia', - variable: 'saudiar', - }, - { - indent: 2, - title: 'Syria', - variable: 'syria', - }, - { - indent: 2, - title: 'Yemen', - variable: 'yemen', - }, - { - indent: 2, - title: 'Turkey', - variable: 'turkey', - }, - { - indent: 2, - title: 'Armenia', - variable: 'armenia', - }, - { - indent: 2, - title: 'Other Western Asia', - variable: 'owasia', - }, - { - indent: 1, - title: 'Asia,n.e.c.', - variable: 'asianec', - }, - { - title: 'Africa', - variable: 'afr', - }, - { - indent: 1, - title: 'Eastern Africa', - variable: 'eafr', - }, - { - indent: 2, - title: 'Eritrea', - variable: 'eritrea', - }, - { - indent: 2, - title: 'Ethiopia', - variable: 'ethiopia', - }, - { - indent: 2, - title: 'Kenya', - variable: 'kenya', - }, - { - indent: 2, - title: 'Other Eastern Africa', - variable: 'oeafr', - }, - { - indent: 1, - title: 'Middle Africa', - variable: 'mafr', - }, - { - indent: 2, - title: 'Cameroon ', - variable: 'cameroon', - }, - { - indent: 2, - title: 'Other Middle Africa', - variable: 'omafr', - }, - { - indent: 1, - title: 'Northern Africa', - variable: 'nafr', - }, - { - indent: 2, - title: 'Egypt', - variable: 'egypt', - }, - { - indent: 2, - title: 'Morocco', - variable: 'morocco', - }, - { - indent: 2, - title: 'Sudan', - variable: 'sudan', - }, - { - indent: 2, - title: 'Other Northern Africa', - variable: 'onafr', - }, - { - indent: 1, - title: 'Southern Africa', - variable: 'sthrnafr', - }, - { - indent: 2, - title: 'South Africa', - variable: 'sthafrca', - }, - { - indent: 2, - title: 'Other Southern Africa', - variable: 'osthrnafr', - }, - { - indent: 1, - title: 'Western Africa', - variable: 'wafr', - }, - { - indent: 2, - title: 'Cabo Verde', - variable: 'caboverd', - }, - { - indent: 2, - title: 'Ghana', - variable: 'ghana', - }, - { - indent: 2, - title: 'Liberia', - variable: 'liberia', - }, - { - indent: 2, - title: 'Nigeria', - variable: 'nigeria', - }, - { - indent: 2, - title: 'Sierra Leone', - variable: 'sierral', - }, - { - indent: 2, - title: 'Other Western Africa', - variable: 'owafr', - }, - { - indent: 1, - title: 'Africa, n.e.c.', - variable: 'afrnec', - }, - { - title: 'Oceania', - variable: 'oceania', - }, - { - indent: 1, - title: 'Australia and New Zealand Subregion:', - variable: 'ausnzsbr', - }, - { - indent: 2, - title: 'Australia', - variable: 'austrlia', - }, - { - indent: 2, - title: 'Other Australian and New Zealand Subregion', - variable: 'oausnzsbr', - }, - { - indent: 1, - title: 'Fiji', - variable: 'fiji', - }, - { - indent: 1, - title: 'Oceania, n.e.c.', - variable: 'ocnianec', - }, - { - title: 'Americas', - variable: 'amricas', - }, - { - indent: 1, - title: 'Latin America', - variable: 'lam', - }, - { - indent: 2, - title: 'Caribbean', - variable: 'carib', - }, - { - indent: 3, - title: 'Bahamas', - variable: 'bahamas', - }, - { - indent: 3, - title: 'Barbados', - variable: 'barbados', - }, - { - indent: 3, - title: 'Cuba', - variable: 'cuba', - }, - { - indent: 3, - title: 'Dominica', - variable: 'dominica', - }, - { - indent: 3, - title: 'Dominican Republic', - variable: 'domrep', - }, - { - indent: 3, - title: 'Grenada', - variable: 'grenada', - }, - { - indent: 3, - title: 'Haiti', - variable: 'haiti', - }, - { - indent: 3, - title: 'Jamaica', - variable: 'jamaica', - }, - { - indent: 3, - title: 'St. Vincent and the Grenadines', - variable: 'stvgren', - }, - { - indent: 3, - title: 'Trinidad and Tobago', - variable: 'trandtob', - }, - { - indent: 3, - title: 'West Indies', - variable: 'windies', - }, - { - indent: 3, - title: 'Other Caribbean', - variable: 'ocarib', - }, - { - indent: 2, - title: 'Central America', - variable: 'cam', - }, - { - indent: 3, - title: 'Mexico', - variable: 'mexico', - }, - { - indent: 3, - title: 'Belize', - variable: 'belize', - }, - { - indent: 3, - title: 'Costa Rica', - variable: 'cstarica', - }, - { - indent: 3, - title: 'El Salvador', - variable: 'elslvdr', - }, - { - indent: 3, - title: 'Guatemala', - variable: 'guatmala', - }, - { - indent: 3, - title: 'Honduras', - variable: 'honduras', - }, - { - indent: 3, - title: 'Nicaragua', - variable: 'nicargua', - }, - { - indent: 3, - title: 'Panama', - variable: 'panama', - }, - { - indent: 3, - title: 'Other Central America', - variable: 'ocam', - }, - { - indent: 2, - title: 'South America', - variable: 'sam', - }, - { - indent: 3, - title: 'Argentina', - variable: 'argntina', - }, - { - indent: 3, - title: 'Bolivia', - variable: 'bolivia', - }, - { - indent: 3, - title: 'Brazil', - variable: 'brazil', - }, - { - indent: 3, - title: 'Chile', - variable: 'chile', - }, - { - indent: 3, - title: 'Colombia', - variable: 'colombia', - }, - { - indent: 3, - title: 'Ecuador', - variable: 'ecuador', - }, - { - indent: 3, - title: 'Guyana', - variable: 'guyana', - }, - { - indent: 3, - title: 'Peru', - variable: 'peru', - }, - { - indent: 3, - title: 'Uruguay', - variable: 'uruguay', - }, - { - indent: 3, - title: 'Venezuela', - variable: 'vnzuela', - }, - { - indent: 3, - title: 'Other South America', - variable: 'osam', - }, - { - indent: 2, - title: 'Northern America', - variable: 'nam', - }, - { - indent: 3, - title: 'Canada', - variable: 'canada', - }, - { - indent: 3, - title: 'Other Northern America', - variable: 'onam', - }, -]; diff --git a/table-config/social/relationship-to-head-of-household--householder.js b/table-config/social/relationship-to-head-of-household--householder.js deleted file mode 100755 index 98bf206..0000000 --- a/table-config/social/relationship-to-head-of-household--householder.js +++ /dev/null @@ -1,37 +0,0 @@ -module.exports = [ - { - title: 'Population in households', - highlight: true, - variable: 'hhpop', - }, - { - title: 'Householder', - variable: 'rshphhldr', - }, - { - title: 'Spouse', - variable: 'rshp_sp', - }, - { - title: 'Child', - variable: 'rshp_ch', - }, - { - title: 'Other relatives', - variable: 'rshp_othr', - }, - { - title: 'Nonrelatives', - variable: 'rshp_nr', - }, - { - indent: 1, - title: 'Unmarried partner', - variable: 'rshp_nrup', - }, - { - indent: 2, - title: 'Same sex unmarried partner', - variable: 'rshp_ssup', - }, -]; diff --git a/table-config/social/residence-1-year-ago.js b/table-config/social/residence-1-year-ago.js deleted file mode 100755 index 5f27b07..0000000 --- a/table-config/social/residence-1-year-ago.js +++ /dev/null @@ -1,50 +0,0 @@ -module.exports = [{ - title: 'Population 1 year and over', - highlight: true, - variable: 'pop1pl', -}, -{ - title: 'Same house', - variable: 'smhs', -}, -{ - title: 'Lived in a different house', - variable: 'dfhs1', -}, -{ - divider: true, -}, -{ - title: 'Population 1 year and over that lived in a different house', - highlight: true, - variable: 'dfhs2', -}, -{ - title: 'Different house in the U.S.', - variable: 'dfhsus', -}, -{ - indent: 2, - title: 'Same county', - variable: 'dfhssmcnt', -}, -{ - indent: 2, - title: 'Different county', - variable: 'dfhsdfcnt', -}, -{ - indent: 4, - title: 'Within New York City', - variable: 'dhdfcntnyc', -}, -{ - indent: 4, - title: 'Outside New York City', - variable: 'dhnonyc', -}, -{ - title: 'Abroad', - variable: 'abroad', -}, -]; diff --git a/table-config/social/school-enrollment.js b/table-config/social/school-enrollment.js deleted file mode 100755 index aa349ed..0000000 --- a/table-config/social/school-enrollment.js +++ /dev/null @@ -1,27 +0,0 @@ -module.exports = [ - { - title: 'Population 3 years and over enrolled in school', - highlight: true, - variable: 'pop3plen', - }, - { - title: 'Nursery school, preschool', - variable: 'se_nscpsc', - }, - { - title: 'Kindergarten', - variable: 'se_kndgtn', - }, - { - title: 'Elementary school (grades 1-8)', - variable: 'se_g1t8', - }, - { - title: 'High school (grades 9-12)', - variable: 'se_g9t12', - }, - { - title: 'College or graduate school', - variable: 'se_clggsc', - }, -]; diff --git a/table-config/social/u-s--citizenship-status.js b/table-config/social/u-s--citizenship-status.js deleted file mode 100755 index 3863322..0000000 --- a/table-config/social/u-s--citizenship-status.js +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = [ - { - title: 'Foreign-born population', - highlight: true, - variable: 'fb3', - }, - { - title: 'Naturalized U.S. citizen', - variable: 'fbntlzd', - }, - { - title: 'Not a U.S. citizen', - variable: 'fbnotczn', - }, -]; diff --git a/table-config/social/veteran-status.js b/table-config/social/veteran-status.js deleted file mode 100755 index 76d97ac..0000000 --- a/table-config/social/veteran-status.js +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = [ - { - title: 'Civilian population 18 years and over', - highlight: true, - variable: 'cvpop18pl', - }, - { - title: 'Veterans', - variable: 'cvvet18pl', - }, -]; diff --git a/table-config/social/year-of-entry.js b/table-config/social/year-of-entry.js deleted file mode 100755 index 3e4e57e..0000000 --- a/table-config/social/year-of-entry.js +++ /dev/null @@ -1,12 +0,0 @@ - -module.exports = [ - { - title: 'Foreign-born population', - highlight: true, - variable: 'fb4', - }, - { - title: 'Entered 2000 or later', - variable: 'fb2000ltr', - }, -]; diff --git a/test/integration/routes.profile.test.js b/test/integration/routes.profile.test.js index fe7812a..83a20c1 100644 --- a/test/integration/routes.profile.test.js +++ b/test/integration/routes.profile.test.js @@ -33,13 +33,12 @@ describe('Special variables', () => { res.status.should.equal(200); res.type.should.equal('application/json'); + // mdfaminc values should be top coded; *codingThreshold = 'upper' const rowObject = res.body - .find(obj => obj.variable === 'mdfaminc' && obj.dataset === 'y2013_2017'); + .find(obj => obj.variable === 'mdfaminc'); - // it should have two properties in it, "sum" and "previous_sum" - // this gets the keys of the thresholds object and counts them - // to make sure - expect(Object.keys(rowObject.codingThresholds).length).to.equal(2); + expect(rowObject.codingThreshold).to.equal('upper'); + expect(rowObject.previous_codingThreshold).to.equal('upper'); done(); }); }); @@ -54,7 +53,7 @@ describe('normal variables with complex case logic', () => { res.status.should.equal(200); res.type.should.equal('application/json'); - const rowObject = res.body.find(obj => obj.variable === 'lgfrlep1' && obj.dataset === 'y2013_2017'); + const rowObject = res.body.find(obj => obj.variable === 'lgfrlep1'); expect(!!rowObject.change_percentage_point).to.equal(true); done(); }); @@ -68,7 +67,7 @@ describe('normal variables with complex case logic', () => { res.status.should.equal(200); res.type.should.equal('application/json'); - const rowObject = res.body.find(obj => obj.variable === 'lgthalep1' && obj.dataset === 'y2013_2017'); + const rowObject = res.body.find(obj => obj.variable === 'lgthalep1'); expect(!!rowObject.change_percentage_point).to.equal(true); done(); }); @@ -83,7 +82,7 @@ describe('normal variables with complex case logic', () => { res.status.should.equal(200); res.type.should.equal('application/json'); - const rowObject = res.body.find(obj => obj.variable === 'lgmkhm1' && obj.dataset === 'y2013_2017'); + const rowObject = res.body.find(obj => obj.variable === 'lgmkhm1'); expect((rowObject.difference_percentage === null)).to.equal(false); done(); }); @@ -98,7 +97,7 @@ describe('normal variables with complex case logic', () => { res.status.should.equal(200); res.type.should.equal('application/json'); - const rowObject = res.body.find(obj => obj.variable === 'lgmkhm1' && obj.dataset === 'y2013_2017'); + const rowObject = res.body.find(obj => obj.variable === 'lgmkhm1'); expect((rowObject.difference_percentage === null)).to.equal(false); done(); }); @@ -114,10 +113,10 @@ it('data with both 0 estimates should be percentage point null: oscasia differen res.status.should.equal(200); res.type.should.equal('application/json'); - const rowObject = res.body.find(obj => obj.variable === 'oscasia' && obj.dataset === 'y2013_2017'); + const rowObject = res.body.find(obj => obj.variable === 'oscasia'); expect(rowObject.previous_sum).to.equal(0); expect(rowObject.sum).to.equal(0); - expect(rowObject.change_percentage_point).to.equal('0.0000'); + expect(rowObject.change_percentage_point).to.equal(0); done(); }); }); @@ -131,7 +130,7 @@ it('data with both 0 estimates should be percentage point null: oscasia differen res.status.should.equal(200); res.type.should.equal('application/json'); - const rowObject = res.body.find(obj => obj.variable === 'oscasia' && obj.dataset === 'y2013_2017'); + const rowObject = res.body.find(obj => obj.variable === 'oscasia'); expect(rowObject.previous_sum).to.equal(0); expect(rowObject.sum).to.equal(0); expect(rowObject.change_percentage_point).to.equal(0); @@ -150,7 +149,7 @@ it('pop30t34 change pct pt significance should be coded a true', (done) => { res.status.should.equal(200); res.type.should.equal('application/json'); - const rowObject = res.body.find(obj => obj.variable === 'pop30t34' && obj.dataset === 'y2013_2017'); + const rowObject = res.body.find(obj => obj.variable === 'pop30t34'); expect(rowObject.change_percentage_point_significant).to.equal(false); done(); }); @@ -168,7 +167,7 @@ it('cw_crpld Change percent MOE should only be null if previous estimate is 0', res.status.should.equal(200); res.type.should.equal('application/json'); - const rowObject = res.body.find(obj => obj.variable === 'cw_crpld' && obj.dataset === 'y2013_2017'); + const rowObject = res.body.find(obj => obj.variable === 'cw_crpld'); // change_percent_m should be present bc change_percent is expect((rowObject.change_percent !== null)).to.equal(true); @@ -188,10 +187,9 @@ it('sthrnafr single geog: percentage point difference not all always graying', ( res.status.should.equal(200); res.type.should.equal('application/json'); - const rowObject = res.body.find(obj => obj.variable === 'sthrnafr' && obj.dataset === 'y2013_2017'); + const rowObject = res.body.find(obj => obj.variable === 'sthrnafr'); - // change_percent_m should be present bc change_percent is - expect(rowObject.percent_significant).to.equal(false); + expect(rowObject.percent_significant).to.equal(undefined); done(); }); }); diff --git a/test/mocha.opts b/test/mocha.opts new file mode 100644 index 0000000..9070118 --- /dev/null +++ b/test/mocha.opts @@ -0,0 +1 @@ +--timeout 10000 diff --git a/utils/calculate-median-error.js b/utils/calculate-median-error.js index 71ee04a..8f90aa9 100644 --- a/utils/calculate-median-error.js +++ b/utils/calculate-median-error.js @@ -1,51 +1,31 @@ const _ = require('lodash'); -const guessYear = require('../utils/guess-year'); -const { get, isArray, clone } = _; +const { clone, find } = _; const { round } = Math; -const DESIGN_FACTOR = 1.5; - -function findCumulativePercentage(scenario, sum, index) { - const copiedBins = clone(scenario); - const slicedBins = copiedBins.slice(0, index); - const cumulativeSum = slicedBins.reduce( - (total, { quantity }) => total + quantity, - 0, - ); - - return (cumulativeSum / sum) * 100; -} - -function calculateMedianError(data, column, options) { - const { bins, multipleBins, designFactor = DESIGN_FACTOR } = options; - - let foundBins = bins; - - const sumKey = (function computeSumKey() { - if (column.length === 1) return 'sum'; - return column.replace('_m', '_sum'); - }()); - - let scenario = data; - - // if we provide an array of bins in the configuration, - // it's implied that the first bins should be used for the earlier - // time period, and the last bin should be used for the later - if (multipleBins) { - foundBins = guessYear(data, foundBins); - } - - if (!isArray(scenario)) { - scenario = foundBins.map((bin) => { - const [key] = bin; - const sum = get(data, `${key}.${sumKey}`); - - return { - quantity: sum, - }; - }); - } +const getBins = require('./get-bins'); +const { DESIGN_FACTOR } = require('../special-calculations/data/constants'); + +/* + * Calculates a margin of error for a median from a set of median values for ranges of the same data point + * @param{Array} data - The full profile dataset, as an array of objects representing rows + * @param{string} variable - The name of the variable for which values are being calculated + * @param{string} year - The year of the given dataset + * @param{Object} options - An object containing variable-specific configuration for the calculation, specifically design factor + * @returns{Number} + */ +function calculateMedianError(data, variable, year, options) { + const { designFactor = DESIGN_FACTOR } = options; + + const bins = getBins(variable, year); + const scenario = bins.map((bin) => { + const [key] = bin; + const { sum } = find(data, ['variable', key]); + + return { + quantity: sum, + }; + }); if (scenario.some(obj => obj.quantity === null)) return null; @@ -54,27 +34,24 @@ function calculateMedianError(data, column, options) { 0, ); - const standardError = designFactor * (( - (93 / (7 * sum)) * 2500 - ) ** 0.5); - + const standardError = getStandardError(designFactor, sum); const pUpper = 50 + standardError; const pLower = 50 - standardError; - const upperCategoryIndex = foundBins + const upperCategoryIndex = bins .findIndex((__, currentBin) => round(pUpper) > findCumulativePercentage(scenario, sum, currentBin) && round(pUpper) < findCumulativePercentage(scenario, sum, currentBin + 1)); - const lowerCategoryIndex = foundBins + const lowerCategoryIndex = bins .findIndex((__, currentBin) => round(pLower) > findCumulativePercentage(scenario, sum, currentBin) && round(pLower) < findCumulativePercentage(scenario, sum, currentBin + 1)); - const upperCategory = foundBins[upperCategoryIndex]; - const lowerCategory = foundBins[lowerCategoryIndex]; + const upperCategory = bins[upperCategoryIndex]; + const lowerCategory = bins[lowerCategoryIndex]; - const upperA2SubsequentBin = (foundBins[upperCategoryIndex + 1] || foundBins[upperCategoryIndex])[1][0]; + const upperA2SubsequentBin = (bins[upperCategoryIndex + 1] || bins[upperCategoryIndex])[1][0]; - const lowerA2SubsequentBin = (foundBins[lowerCategoryIndex + 1] || foundBins[lowerCategoryIndex])[1][0]; + const lowerA2SubsequentBin = (bins[lowerCategoryIndex + 1] || bins[lowerCategoryIndex])[1][0]; const inputs = { upper: { @@ -109,4 +86,19 @@ function calculateMedianError(data, column, options) { return marginOfError; } +function getStandardError(designFactor, sum) { + return designFactor * (((93 / (7 * sum)) * 2500) ** 0.5); +} + +function findCumulativePercentage(scenario, sum, index) { + const copiedBins = clone(scenario); + const slicedBins = copiedBins.slice(0, index); + const cumulativeSum = slicedBins.reduce( + (total, { quantity }) => total + quantity, + 0, + ); + + return (cumulativeSum / sum) * 100; +} + module.exports = calculateMedianError; diff --git a/utils/calculator.js b/utils/calculator.js deleted file mode 100644 index 436d6df..0000000 --- a/utils/calculator.js +++ /dev/null @@ -1,57 +0,0 @@ -const _ = require('lodash'); - -const { isArray } = Array; -const { isFinite } = Number; -const { get, isNaN, clone } = _; - -const operations = ['divide', 'subtract', 'add', 'multiply']; -const operators = { - divide(a, b = 1) { return a / b; }, - add(a, b) { return a + b; }, - multiply(a, b) { return a * b; }, - subtract(a, b) { return a - b; }, -}; - -function isOperator(step) { - return operations.some(op => op === step); -} - -function calculator(data, sumColumn = 'sum', rowConfig) { - const { procedure } = rowConfig; - const currentProcedure = clone(procedure); - - // impute values, replacing their signifiers with their signifieds - currentProcedure.forEach((step, i) => { - if (isFinite(step)) { - return; - } - - if (isArray(step)) { - currentProcedure[i] = calculator(data, sumColumn, { procedure: step, data: rowConfig.variable }); - return; - } - - if (!isOperator(step)) { - const currentSum = get(data, `${step}`); - currentProcedure[i] = !isNaN(currentSum) ? currentSum : step; - } - }); - - const [firstValue] = currentProcedure; - - return currentProcedure - .reduce((accumulator, step, i, array) => { - if (!isOperator(step)) { - return accumulator; - } - - const first = array[i - 1]; - const second = array[i + 1]; - - const operation = operators[step] || Math[step]; - - return operation(first, second); - }, firstValue); -} - -module.exports = calculator; diff --git a/utils/change.js b/utils/change.js new file mode 100644 index 0000000..919aecb --- /dev/null +++ b/utils/change.js @@ -0,0 +1,75 @@ +const { executeWithValues: executeFormula } = require('./formula'); + +/* + * Do calculations for all change_* values for the given row + * @param{Object} row - The row to do calculations for + */ +function doChangeCalculations(row) { + calculateChanges(row); + calculateChangePercents(row); + calculateChangePercentagePoints(row); +} + +/* + * Calculate change_sum, change_m, and change_significant + * @param{row} - The row to do calculations for + */ +function calculateChanges(row) { + const updatedRow = row; + if (exists(updatedRow.sum) && exists(updatedRow.previous_sum)) { + updatedRow.change_sum = executeFormula('delta', [updatedRow.sum, updatedRow.previous_sum]); + + if (exists(updatedRow.m) && exists(updatedRow.previous_m)) { + updatedRow.change_m = executeFormula('delta_m', [updatedRow.m, updatedRow.previous_m]); + + if (updatedRow.change_sum !== 0) updatedRow.change_significant = executeFormula('significant', [updatedRow.change_sum, updatedRow.change_m]); + } + } +} + +/* + * Calculate change_percent, change_percent_m, change_percent_significant + * @param{row} - The row to do calculations for + */ +function calculateChangePercents(row) { + const updatedRow = row; + if (exists(updatedRow.sum) && exists(updatedRow.previous_sum) && updatedRow.previous_sum !== 0) { + updatedRow.change_percent = executeFormula('change_pct', [updatedRow.sum, updatedRow.previous_sum]); + + if (exists(updatedRow.m) && exists(updatedRow.percent_m)) { + updatedRow.change_percent_m = executeFormula('change_pct_m', [updatedRow.sum, updatedRow.previous_sum, updatedRow.m, updatedRow.previous_m]); + + if (updatedRow.change_percent !== 0) updatedRow.change_percent_significant = executeFormula('significant', [updatedRow.change_percent, updatedRow.change_percent_m]); + } + } +} + +/* + * Calculate change_percentage_point, change_percentage_point_m, change_percentage_point_significant + * @param{row} - The row to do calculations for + */ +function calculateChangePercentagePoints(row) { + const updatedRow = row; + if (exists(updatedRow.percent) && exists(updatedRow.previous_percent)) { + updatedRow.change_percentage_point = executeFormula('delta', [updatedRow.percent, updatedRow.previous_percent]); + + if (exists(updatedRow.percent_m) && exists(updatedRow.previous_percent_m)) { + updatedRow.change_percentage_point_m = executeFormula('delta_m', [updatedRow.percent_m, updatedRow.previous_percent_m]); + + if (updatedRow.change_percentage_point !== 0) updatedRow.change_percentage_point_significant = executeFormula('significant', [updatedRow.change_percentage_point, updatedRow.change_percentage_point_m]); + } + } +} + +/* + * Helper function to check if a given value has a real value. + * Can't use plain conditional check b/c val = 0 would give false negative + * @param{Number} val - the value to check + * @returns{Boolean} + */ +function exists(val) { + return val !== undefined && val !== null; +} + + +module.exports = doChangeCalculations; diff --git a/utils/data-ingestor.js b/utils/data-ingestor.js new file mode 100644 index 0000000..7c655a3 --- /dev/null +++ b/utils/data-ingestor.js @@ -0,0 +1,270 @@ +const { find } = require('lodash'); + +const df = require('dataframe-js'); + +const specialCalculationConfigs = require('../special-calculations'); +const calculateMedianError = require('../utils/calculate-median-error'); +const interpolate = require('../utils/interpolate'); +const { executeWithData: executeFormula } = require('../utils/formula'); + +const { + INFLATION_FACTOR, + RENAME_COLS, + PREV_YEAR, + CUR_YEAR, +} = require('../special-calculations/data/constants'); + +/* + * The DataIngestor class is used to convert profile data from postgres query into a Dataframe. + * Additionally for aggregate profiles, the DataIngestor recalculates 'special' variables, configured + * in 'special-calculations/[profile].js'. + * NOTE: Dataframes (https://gmousse.gitbooks.io/dataframe-js/#dataframe-js) are immutable, so they cannot be modified + * in place. That is why all functions mutating a Dataframe also return one. + */ +class DataIngestor { + /* + * Creates a DataIngestor + * @constructor + * @params{Array} data - Raw data from SQL query, an array of objects representing rows; + * @params{string} profileName - The profile type; expected to be one of 'demographic', 'housing', 'economic', 'social', 'decennial' + * @params{Boolean} isAggregate - True if the given data selection is comprised of multiple geoids; else false + * @params{Boolean} isPrevious - True if the given data selection is for the older dataset year + * @params{Boolean} isCompare - True if the given data selection is for the comparison dataset + */ + constructor(data, profileName, isAggregate = false, isPrevious = false, isCompare = false) { + this.data = data; + this.profileName = profileName; + this.isAggregate = isAggregate; + this.isPrevious = isPrevious; + this.isCompare = isCompare; + this.extraColumns = ['codingThreshold']; + } + + /* + * Main function of the DataIngestor class, turns this.data into a Dataframe + * with recalcuated special variables if aggregate, and with RENAME_COLS renamed + * if columnPrefix argument is supplied. + * @param{String} [columnPrefix] - String to prepend to RENAME_COLS names in Dataframe + * @returns{Dataframe} + */ + processRaw() { + let d = this.makeBaseDataFrame(); + + if (this.isAggregate) { + d = this.recalculate(d); + } + + if (this.isPrevious || this.isCompare) { + d = this.prefixColumns(d, RENAME_COLS); + } + + return d; + } + + /* + * Turns this.data (raw SQL data) into a Dataframe, and adds columns specified by this.extraColumns + * @returns{Dataframe} + */ + makeBaseDataFrame() { + let d = new df.DataFrame(this.data); + this.extraColumns.forEach((col) => { + d = d.withColumn(col); + }); + return d; + } + + /* + * Joins special calculation configuration to the given Dataframe, + * and applies aggregate calculations to the resulting Dataframe. + * specialCalculationConfigs[profileName] is an array of objects containing 'variable' and 'specialType' properties + * (see special-calculations/[profileName].js for examples) + * Then, cleans up the special calculation configuration columns, and returns the final Dataframe. + * @param{Dataframe} d - The dataframe to operate on + * @returns{Dataframe} + */ + recalculate(d) { + d = d.leftJoin(new df.DataFrame(specialCalculationConfigs[this.profileName], ['variable', 'specialType']), 'variable'); + d = d.chain(row => this.recomputeSpecialVars(row)); + d = d.drop('specialType'); + return d; + } + + /* + * Given a dataframe, and an array of columns to rename + * returns a copy of the original dataframe with the specified columns + * renamed to prefix_columnName, where prefix is determined based on + * isPrevious and isCompare instance variables, with isPrevious having precendence + * over isComparison (both should not be, but could be, true). + * @param{Dataframe} d - The dataframe to operate on + * @param{Array} renameCols - The dataframe columns to rename + * @returns{Dataframe} + */ + prefixColumns(d, renameCols) { + let prefix = ''; + if (this.isPrevious) prefix = 'previous'; + else if (this.isCompare) prefix = 'comparison'; + renameCols.forEach((colName) => { + d = d.rename(colName, `${prefix}_${colName}`); + }); + return d; + } + + /* + * For all 'special' rows, recompute sum and margin of error if appropriate, + * and return the updated row object. Logs if a given special row cannot be updated, + * but does not throw error or stop chained procedure. + * @param{Row} row - The row to operate on + * @returns{Row} + */ + recomputeSpecialVars(row) { + let updatedRow = row; + + // do not recalculate values for 'normal' rows + const specialType = updatedRow.get('specialType'); + if (specialType === undefined) return updatedRow; + + // recalculate sum, and optionally m & cv + const variable = updatedRow.get('variable'); + try { + const year = this.isPrevious ? PREV_YEAR : CUR_YEAR; + const { options } = find(specialCalculationConfigs[this.profileName], ['variable', variable]); + + updatedRow = this.recomputeSum(updatedRow, specialType, variable, year, options); + + // decennial profiles do not have MOE values or CV values + if (this.profileName !== 'decennial') { + updatedRow = this.recomputeM(updatedRow, specialType, variable, year, options); + updatedRow = this.recomputeCV(updatedRow, variable); + updatedRow = this.recomputeIsReliable(updatedRow, variable); + } + } catch (e) { + console.log(`Failed to update special vars for ${variable}:`, e); // eslint-disable-line + } + + return updatedRow; + } + + /* + * Recomputes the 'sum' value for a given row, applying the appropriate calculation + * based on the type of 'special' row. Additionally, scales the recomputed sum value + * if configured in 'options' + * @param{Row} row - The row to operate on + * @param{string} specialType - The type of this special variable + * @param{string} variable - The variable for the given row + * @param{string} year - The year for the given dataset + * @param{Object} options - Additional configuration for special calculations + * @returns{Row} + */ + recomputeSum(row, specialType, variable, year, options) { + let updatedRow = row; + let sum; + + if (specialType === 'median') { + const { trimmedEstimate, codingThreshold } = interpolate(this.data, variable, year); + sum = trimmedEstimate; + if (codingThreshold) { + updatedRow = updatedRow.set('codingThreshold', codingThreshold); + // if codingThreshold is set, indicates value was top- or bottom-coded, + // meaning the value is not reliable + updatedRow = updatedRow.set('is_reliable', false); + } + } else { + const formulaName = getFormulaName(options, 'sum'); + sum = executeFormula(this.data, variable, formulaName, options.args); + } + sum = this.applyTransform(sum, options.transform); + + return updatedRow.set('sum', sum); + } + + /* + * Recomputes the 'm'(margin of error) value for a given row, applying the appropriate calculation + * based on the type of 'special' row. Additionally, scales the recomputed m value + * if configured in 'options' + * @param{Row} row - The row to operate on + * @param{string} specialType - The type of this special variable + * @param{string} variable - The variable for the given row + * @param{string} year - The year for the given dataset + * @param{Object} options - Additional configuration for special calculations + * @returns{Row} + */ + recomputeM(row, specialType, variable, year, options) { + const updatedRow = row; + let m; + if (specialType === 'median') { + m = calculateMedianError(this.data, variable, year, options); + } else { + const formulaName = getFormulaName(options, 'm'); + m = executeFormula(this.data, variable, formulaName, options.args); + } + + m = this.applyTransform(m, options.transform); + + return updatedRow.set('m', m); + } + + /* + * Recomputes 'cv' value for given row + * @param{Row} row - The row to operate on + * @param{string} variable - The variable for the given row + * @returns{Row} + */ + recomputeCV(row, variable) { + const updatedRow = row; + const cv = executeFormula(this.data, variable, 'cv'); + return updatedRow.set('cv', cv); + } + + /* + * Recomputes 'is_reliable' value for given row + * @param{Row} row - The row to operate on + * @param{string} variable - The variable for the given row + * @returns{Row} + */ + recomputeIsReliable(row, variable) { + const updatedRow = row; + const isReliable = executeFormula(this.data, variable, 'is_reliable'); + return updatedRow.set('is_reliable', isReliable); + } + + /* + * If transformOptions exists, then applies the appropriate transformation. + * 'inflate' is a special transform type, which only applies to previous year data points + * (designated by this.isPrevious), and scales by INFLATION_FACTOR. Other allowed transformation + * is 'scale' type, and require transformOptions.factor; factor is applied as scalar transformation + * @param{Number} val - The value to transform + * @param{Object} [transformOptions] - Object containing 'type', and optionally 'factor'; defines the transformation + * @returns{Number} + */ + applyTransform(val, transformOptions) { + if (!transformOptions) return val; + + // inflations are special scalar transforms only applied to prev year dataset + if (transformOptions.type === 'inflate' && !this.isPrevious) return val; + // do inflation + if (transformOptions.type === 'inflate') return val * INFLATION_FACTOR; + // do scalar transform + if (transformOptions.type === 'scale' && transformOptions.factor) return val * transformOptions.factor; + + // something unexpected happened with transformOptions -- just leave the value as is + return val; + } +} + + +/* + * If a special formula name is defined for a given value calculation, + * the corresponding key in the formulas object is of the format: + * 'value_specialFormula' + * i.e. if special formula 'rate' is defined for value calculation 'm', + * the key in the formulas object would be 'm_rate' + */ +function getFormulaName(options, valType) { + if (options.formulaName) { + const specialFormulaName = options.formulaName[valType]; + return `${valType}_${specialFormulaName}`; + } + return valType; +} + +module.exports = DataIngestor; diff --git a/utils/delegate-aggregator.js b/utils/delegate-aggregator.js deleted file mode 100644 index f18a765..0000000 --- a/utils/delegate-aggregator.js +++ /dev/null @@ -1,31 +0,0 @@ -const _ = require('lodash'); - -const { set } = _; - -const noop = () => null; - -function aggregateSpecialVariable(row, rowConfig, allData) { - const { specialCalculations = [] } = rowConfig || {}; - const { variable } = rowConfig; - const mutatedRow = row; - - specialCalculations.forEach(({ column, aggregator = noop, options }) => { - let specialValue; - - /* - Skip special calculations if it's a single geography - */ - if ((column.indexOf('comparison') === 0)) return; - - try { - specialValue = aggregator(allData, column, options, variable, row); - } catch (err) { - console.log('Error with ', variable, row.dataset, column, options, 'Stack trace: ', err.toString()); // eslint-disable-line - } - set(mutatedRow, column, specialValue); - }); - - return mutatedRow; -} - -module.exports = aggregateSpecialVariable; diff --git a/utils/difference.js b/utils/difference.js new file mode 100644 index 0000000..7f90265 --- /dev/null +++ b/utils/difference.js @@ -0,0 +1,60 @@ +const { executeWithValues: executeFormula } = require('./formula'); + +/* + * Do calculations for all difference_* values for the given row + * @param{Object} row - The row to do calculations for + */ +function doDifferenceCalculations(row) { + calculateDifferences(row); + calculateDifferencePercents(row); +} + +/* + * Calculate difference_sum, difference_m, and significant + * @param{row} - The row to do calculations for + */ +function calculateDifferences(row) { + const updatedRow = row; + if (exists(updatedRow.sum) && exists(updatedRow.comparison_sum)) { + updatedRow.difference_sum = executeFormula('delta', [updatedRow.sum, updatedRow.comparison_sum]); + + if (exists(updatedRow.m) && exists(updatedRow.comparison_m)) { + updatedRow.difference_m = executeFormula('delta_m', [updatedRow.m, updatedRow.comparison_m]); + + // TODO rename difference_significant + if (updatedRow.difference_sum !== 0) updatedRow.significant = executeFormula('significant', [updatedRow.difference_sum, updatedRow.difference_m]); + } + } + + // special handling for 'decennial' rows, which do not have MOE and are all considered 'significant' + if (row.profile === 'decennial') row.significant = true; +} + +/* + * Calculate difference_percent, difference_percent_m, and percent_significant + * @param{row} - The row to do calculations for + */ +function calculateDifferencePercents(row) { + const updatedRow = row; + if (exists(updatedRow.percent) && exists(updatedRow.comparison_percent)) { + updatedRow.difference_percent = executeFormula('delta_with_threshold', [updatedRow.percent * 100, updatedRow.comparison_percent * 100]); + + if (exists(updatedRow.percent_m) && exists(updatedRow.comparison_percent_m)) { + updatedRow.difference_percent_m = executeFormula('delta_m', [updatedRow.percent_m * 100, updatedRow.comparison_percent_m * 100]); + + // TODO rename difference_percent_significant + if (updatedRow.difference_percent !== 0) updatedRow.percent_significant = executeFormula('significant', [updatedRow.difference_percent, updatedRow.difference_percent_m]); + } + } +} + +/* + * Helper function to check if a given value has a real value. + * Can't use plain conditional check b/c val = 0 would give false negative + * @param{Number} val - the value to check + * @returns{Boolean} + */ +function exists(val) { + return val !== undefined && val !== null; +} +module.exports = doDifferenceCalculations; diff --git a/utils/formula.js b/utils/formula.js index fde630a..d70966e 100644 --- a/utils/formula.js +++ b/utils/formula.js @@ -1,29 +1,68 @@ const FormulaParser = require('hot-formula-parser'); const _ = require('lodash'); +const formulas = require('./formulas'); -const { get } = _; +const { find } = _; const { Parser } = FormulaParser; -function runFormulaFor(data, sumKey, rowConfig, variable) { - const { formula } = rowConfig; +/* + * Executes a given formula, with arguments directly providing values to operate on + * @param{string} formulaName - A string representing the name of the formula to execute + * @param{Array} args - Array containing ordered arguments that will be provided to the function; + * these arguments should be actual numerical values, not references to values. + * @returns{Number} + */ +function executeWithValues(formulaName, args) { + const formula = formulas[formulaName]; + const formulaStr = formula(...args); + const parser = new Parser(); - parser.setFunction('GET', ([path]) => { - const first = get(data, path); - const fallback = get(data[variable], path); + const { result, error } = parser.parse(formulaStr); + if (error) { + console.log(`${formulaStr}`); + throw new Error(`${error}: ${formulaName}`); + } - if (typeof first === 'number') return first; + return result; +} - return fallback; - }); // fallback to current object +/* + * Executes a given formula, in the context of provided variable + data argument, with optional formula arguments + * @param{Array} data - The full profile dataset, as an array of object representing rows + * @param{string} variable - The name of the variable for which values are being calculated + * @param{string} formulaName - A string representing the name of the formula to execute + * @param{Array} [args] - Arguments to pass to the given formula + * @returns{Number} + */ +function executeWithData(data, variable, formulaName, args = []) { + const formula = formulas[formulaName]; + const formulaStr = typeof formula === 'function' ? formula(...args) : formula; - const { result, error } = parser.parse(formula); + const parser = new Parser(); - if (error && get(data[variable], 'dataset') === 'y2013_2017') { - throw new Error(error); + // custom 'GET' function in parser is used to access values from data context + parser.setFunction('GET', ([path]) => { + // if 'path' includes a '.', this means we want a value namespaced in a + // different variable context, so set targetVariable accordingly + const targetVariable = path.includes('.') ? path.split('.')[0] : variable; + + // if 'path' does not include a '.', this means it is the value we want to access + // in the current variable context + const value = path.includes('.') ? path.split('.')[1] : path; + + const variableValues = find(data, ['variable', targetVariable]); + return variableValues[value]; + }); + + const { result, error } = parser.parse(formulaStr); + if (error) { + throw new Error(`${error}: ${formulaName}`); } return result; } - -module.exports = runFormulaFor; +module.exports = { + executeWithValues, + executeWithData, +}; diff --git a/utils/formulas.js b/utils/formulas.js new file mode 100644 index 0000000..c083ff8 --- /dev/null +++ b/utils/formulas.js @@ -0,0 +1,49 @@ +const { CV_CONST, DIFF_PERCENT_THRESHOLD } = require('../special-calculations/data/constants'); + +/* + * The goal is that, as much as possible, all math done on the data is contained in formulas in this file. + * These calculations are used to recompute 'sum', 'm', 'cv' values for aggregate datasets, + * as well as to do all of the change and difference calculations, including significance calculations. + * The change and difference values are calculated from the given formulas as follows: + * - delta: change_sum, change_percentage_point, difference_sum + * - delta_with_threshold: difference_percent + * - delta_m: change_m, change_percentage_point_m, difference_m, difference_percent_m + * - change_pct: change_percent + * - change_pct_m: change_percent_m + * - significant: change_significant, change_percent_significant, change_percentage_point_significant, significant, percent_significant + * + * There are a few other places where some calculations/calculation-related-decisioning happens: + * - 'percent', 'percent_m', and 'is_reliable' are calculated as part of the original SQL query + * - boolean checks for value existance are done before all change & difference checks in the code, + * and are not represented here in the formulas for readability and easier implementation + */ +module.exports = { + /***** sum calculations *****/ + sum: (aggSum, universe) => `GET("${aggSum}.sum") / GET("${universe}.sum")`, + // special mean calculation for 'ratio' type values TODO: get a better name for ratio + sum_ratio: (observed, universe) => `GET("${observed}.sum") / (GET("${observed}.sum") + GET("${universe}.sum"))`, + + /***** margin of error calculations *****/ + m: (aggSum, universe) => `(1/GET("${universe}.sum")) * SQRT((GET("${aggSum}.m")^2) + ((GET("${aggSum}.sum") / GET("${universe}.sum"))^2 * (GET("${universe}.m")^2)))`, + // special MOE calculation for 'rate' type values, copied from @emaurer in slack + m_rate: (aggSum, universe) => `IF(GET("${universe}.sum")=0,0,IF(GET("${aggSum}.sum")=0,0,IF(((GET("${aggSum}.m")^2)-((GET("${aggSum}.sum")^2/GET("${universe}.sum")^2)*(GET("${universe}.m")^2)))<0,((1/GET("${universe}.sum")*(SQRT((GET("${aggSum}.m")^2)+((GET("${aggSum}.sum")^2/GET("${universe}.sum")^2)*(GET("${universe}.m")^2)))))*100),((1/GET("${universe}.sum")*(SQRT((GET("${aggSum}.m")^2)-((GET("${aggSum}.sum")^2/GET("${universe}.sum")^2)*(GET("${universe}.m")^2)))))*100))))`, + + /***** coefficient of variation calculations *****/ + cv: `((GET("m") / "${CV_CONST}") / GET("sum")) * 100`, + + /***** is_reliable calculation *****/ + is_reliable: `GET("cv") < 20`, + + /***** change and difference calculations *****/ + // Δ sum + delta: (sum, compSum) => `${sum} - ${compSum}`, + delta_with_threshold: (sum, compSum) => `IF(AND(${sum} - ${compSum} < 0, ${sum} - ${compSum} > ${DIFF_PERCENT_THRESHOLD}), 0, ${sum} - ${compSum})`, + // Δ m + delta_m: (m, compM) => `ABS(SQRT((${m}^2) + (${compM}^2)))`, + // Δ change % - requires special calculation + change_pct: (sum, prevSum) => `(${sum} - ${prevSum}) / ${prevSum}`, + // Δ change_m % - requires special calculation + change_pct_m: (sum, prevSum, m, prevM) => `ABS(${sum} / ${prevSum}) * SQRT(((${m} / ${CV_CONST}) / ${sum})^2 + ((${prevM} / ${CV_CONST}) / ${prevSum})^2) * ${CV_CONST}`, + // Δ significant + significant: (sum, m) => `((${m} / ${CV_CONST}) / ABS(${sum})) * 100 < 20`, +}; diff --git a/utils/get-bins.js b/utils/get-bins.js new file mode 100644 index 0000000..c000cea --- /dev/null +++ b/utils/get-bins.js @@ -0,0 +1,16 @@ +const bins = require('../special-calculations/data/bins'); + +/* + * Finds a bin object for a given (variable, year), or an empty array if no bin exists + * @param{string} variable + * @param{string} year + * @returns{Array} + */ +function getBins(variable, year) { + if (bins[variable][year]) return bins[variable][year]; + if (bins[variable]) return bins[variable]; + console.log(`No bins found for ${variable}`); + return []; +} + +module.exports = getBins; diff --git a/utils/guess-year.js b/utils/guess-year.js deleted file mode 100644 index fec70f4..0000000 --- a/utils/guess-year.js +++ /dev/null @@ -1,16 +0,0 @@ -function guessYear(data, foundBins) { - const [earlySet, laterSet] = foundBins; - - // guess which year it is - const [firstObject] = Object.keys(data) || []; - const yearValue = data[firstObject].dataset; - const thisYear = yearValue.slice(-4); - - if (thisYear === '2017') { - return laterSet; - } - - return earlySet; -} - -module.exports = guessYear; diff --git a/utils/inflate.js b/utils/inflate.js deleted file mode 100644 index 4b3c8c1..0000000 --- a/utils/inflate.js +++ /dev/null @@ -1,8 +0,0 @@ -const INFLATION_MULTIPLIER = 1.1267; // inflates 2010 dollars to 2017 dollars - -function inflate(data, column, rowConfig, variable) { - const rowData = data[variable]; - return rowData.is_most_recent ? rowData[column] : (rowData[column] * INFLATION_MULTIPLIER); -} - -module.exports = inflate; diff --git a/utils/interpolate.js b/utils/interpolate.js index 19ef643..bcaa6e6 100644 --- a/utils/interpolate.js +++ b/utils/interpolate.js @@ -1,59 +1,41 @@ -const _ = require('lodash'); -const topBottomCodeEstimate = require('../utils/top-bottom-code-estimate'); -const medianOfRanges = require('../utils/median-of-ranges'); - -const { isArray } = Array; -const { get, set } = _; - -function interpolate(data, sumKey = 'sum', options, variable, row) { - const { bins, multipleBins, referenceSumKey = sumKey } = options; - let scenario = data; - let foundBins = bins; - - // if we provide an array of bins in the configuration, - // it's implied that the first bins should be used for the earlier - // time period, and the last bin should be used for the later - if (multipleBins) { - const [earlySet, laterSet] = foundBins; - - // guess which year it is - const [firstObject] = Object.keys(data) || []; - const thisYear = get(data, `${firstObject}.dataset`).slice(-4); - - if (thisYear === '2000' || thisYear === '2017') { - foundBins = laterSet; - } else { - foundBins = earlySet; - } - } - - // this is done in an effort to make this utility more generic - // and therefore, testable - if (!isArray(scenario)) { - scenario = foundBins.map((bin) => { - const [key, range] = bin; - const [min, max] = range; - const sum = get(data, `${key}.${referenceSumKey}`); - - return { - quantity: sum, - bounds: { - lower: min, - upper: max, - }, - }; - }); - } +const { find } = require('lodash'); + +const topBottomCodeEstimate = require('./top-bottom-code-estimate'); +const medianOfRanges = require('./median-of-ranges'); +const getBins = require('./get-bins'); + +/* + * Interpolates a median value from a set of median values for ranges of the same data point, + * and top- or bottom-codes the estimated median based on configured coding values + * @param{Array} data - The full profile dataset, as an array of objects representing rows + * @param{string} variable - The name of the variable for which values are being calculated + * @param{string} year - The year of the given dataset + * @param{Object} row - All values for the given variable as an object + */ +function interpolate(data, variable, year) { + const bins = getBins(variable, year); + const scenario = bins.map((bin) => { + const [key, range] = bin; + const [min, max] = range; + const { sum } = find(data, ['variable', key]); + + return { + quantity: sum, + bounds: { + lower: min, + upper: max, + }, + }; + }); const naturalMedian = medianOfRanges(scenario); - const { mutatedEstimate: trimmedEstimate, codingThreshold } = topBottomCodeEstimate(naturalMedian, row); - - if (codingThreshold) { - set(row, `codingThresholds.${sumKey}`, codingThreshold); - } + const { + mutatedEstimate: trimmedEstimate, + codingThreshold, + } = topBottomCodeEstimate(naturalMedian, variable, year); - return trimmedEstimate; + return { trimmedEstimate, codingThreshold }; } module.exports = interpolate; diff --git a/utils/nest-profile.js b/utils/nest-profile.js deleted file mode 100644 index 1471c7f..0000000 --- a/utils/nest-profile.js +++ /dev/null @@ -1,23 +0,0 @@ -const _ = require('lodash'); -const d3collection = require('d3-collection'); - -const { get } = _; -const { nest } = d3collection; - -function nestProfile(data, method = 'object', ...keys) { - const { length } = keys; - let allKeys = ['dataset', 'category', 'variable']; - - if (length) { - allKeys = keys; - } - - return allKeys - .reduce( - (nesting, currentKey) => nesting.key(d => get(d, currentKey)), - nest(), - ) - .rollup(d => d[0])[method](data); -} - -module.exports = nestProfile; diff --git a/utils/top-bottom-code-estimate.js b/utils/top-bottom-code-estimate.js index c0a4490..851c56f 100644 --- a/utils/top-bottom-code-estimate.js +++ b/utils/top-bottom-code-estimate.js @@ -1,40 +1,23 @@ const _ = require('lodash'); -const topBottomCodings = require('../metadata/top-bottom-codings'); +const topBottomCodings = require('../special-calculations/data/top-bottom-codings'); const { get } = _; /* - Top and bottom "code" estimated medians based on a set of conditions. - - Latest: - single-geography estimates - use "all", except when NTA (then use "nta") - multi-geography aggregates - use "nta" - - Earlier: - single-geography estimates - use "all", except when NTA and PUMA (then use "nta") - multi-geography aggregates - use "nta" -*/ - -function topBottomCodeEstimate(estimate, row) { - const is_most_recent = get(row, 'is_most_recent'); - const timeframe = is_most_recent ? 'latest' : 'earlier'; - const variable = get(row, 'variable'); - const geotype = get(row, 'geotype'); - const geoids = get(row, 'numGeoids'); - + * Conditionally top- or bottom-codes an estimated median value, using configured coding values. + * Returns the coded estimate, as well as the direction the estimate was coded if it was coded. + * NOTE: all estimates calculated via interpolation & top- or bottom-coded here are for multi-geography + * aggregates, so coding values will always be those for 'nta' geographic type designations + * @param{Number} estimate - The estimated median to be potentially coded + * @param{string} variable - The name of the variable this estimate value belongs to + * @param{string} year - The year of the dataset this variable belongs to + * @returns{Object} + */ +function topBottomCodeEstimate(estimate, variable, year) { let mutatedEstimate = estimate; - let geographicTypeDesignation = 'nta'; let codingThreshold = null; - if (is_most_recent) { - if (geoids === 1 && (geotype !== 'NTA2010')) { - geographicTypeDesignation = 'all'; - } - } else if (geoids === 1 && (geotype !== 'NTA2010' && geotype !== 'PUMA2010')) { - geographicTypeDesignation = 'all'; - } - - const codingRule = get(topBottomCodings, `${timeframe}.${variable}.${geographicTypeDesignation}`); + const codingRule = get(topBottomCodings, `${year}.${variable}`); if (estimate <= get(codingRule, 'lower')) { mutatedEstimate = get(codingRule, 'lower'); diff --git a/yarn.lock b/yarn.lock index fee9925..aa787e2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -60,6 +60,14 @@ esutils "^2.0.2" js-tokens "^3.0.0" +"@babel/polyfill@~7.2.5": + version "7.2.5" + resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.2.5.tgz#6c54b964f71ad27edddc567d065e57e87ed7fa7d" + integrity sha512-8Y/t3MWThtMLYr0YNC/Q76tqN1w30+b0uQMeFUYauG2UGTR19zyUtFrAzT23zNtBxPp+LbE5E/nwV/q/r3y6ug== + dependencies: + core-js "^2.5.7" + regenerator-runtime "^0.12.0" + "@babel/template@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.44.tgz#f8832f4fdcee5d59bf515e595fc5106c529b394f" @@ -117,6 +125,11 @@ "@types/node" "*" "@types/pg-types" "*" +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + accepts@~1.3.5: version "1.3.5" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" @@ -193,10 +206,31 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" +anymatch@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" + integrity sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA== + dependencies: + micromatch "^2.1.5" + normalize-path "^2.0.0" + apicache@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/apicache/-/apicache-1.2.3.tgz#00909d2ad37c78822d01a4628162ab7c42fb0a77" +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -209,10 +243,20 @@ arr-diff@^2.0.0: dependencies: arr-flatten "^1.0.1" -arr-flatten@^1.0.1: +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.0.1, arr-flatten@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" @@ -231,6 +275,11 @@ array-unique@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + arrify@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" @@ -247,6 +296,16 @@ assertion-error@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +async-each@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.2.tgz#8b8a7ca2a658f927e9f307d6d1a42f4199f0f735" + integrity sha512-6xrbvN0MOBKSJDdonmSSz2OwFSgxRaVtBDes26mj9KIGtDo+g9xosFRSC+i1gQh2oAN/tQ62AI/pGZGQjVOiRg== + async@2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/async/-/async-2.1.4.tgz#2d2160c7788032e4dd6cbe2502f1f9a2c8f6cde4" @@ -273,6 +332,11 @@ asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" +atob@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" @@ -281,7 +345,29 @@ aws4@^1.6.0: version "1.7.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.7.0.tgz#d4d0e9b9dbfca77bf08eeb0a8a471550fe39e289" -babel-code-frame@^6.22.0: +babel-cli@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1" + integrity sha1-UCq1SHTX24itALiHoGODzgPQAvE= + dependencies: + babel-core "^6.26.0" + babel-polyfill "^6.26.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + commander "^2.11.0" + convert-source-map "^1.5.0" + fs-readdir-recursive "^1.0.0" + glob "^7.1.2" + lodash "^4.17.4" + output-file-sync "^1.1.2" + path-is-absolute "^1.0.1" + slash "^1.0.0" + source-map "^0.5.6" + v8flags "^2.1.1" + optionalDependencies: + chokidar "^1.6.1" + +babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" dependencies: @@ -289,6 +375,31 @@ babel-code-frame@^6.22.0: esutils "^2.0.2" js-tokens "^3.0.2" +babel-core@^6.26.0: + version "6.26.3" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.1" + debug "^2.6.9" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.8" + slash "^1.0.0" + source-map "^0.5.7" + babel-eslint@^8.2.6: version "8.2.6" resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.6.tgz#6270d0c73205628067c0f7ae1693a9e797acefd9" @@ -300,10 +411,110 @@ babel-eslint@^8.2.6: eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" +babel-generator@^6.26.0: + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.7" + trim-right "^1.0.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= + dependencies: + babel-runtime "^6.22.0" + +babel-polyfill@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" + integrity sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM= + dependencies: + babel-runtime "^6.26.0" + core-js "^2.5.0" + regenerator-runtime "^0.10.5" + +babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + integrity sha1-btAhFz4vy0htestFxgCahW9kcHE= + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + babylon@7.0.0-beta.44: version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.44.tgz#89159e15e6e30c5096e22d738d8c0af8a0e8ca1d" +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -312,6 +523,19 @@ base64-js@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.8.tgz#1101e9544f4a76b1bc3b26d452ca96d7a35e7978" +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + bcrypt-pbkdf@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" @@ -324,6 +548,11 @@ bessel@^0.2.0: dependencies: voc "" +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + bl@^1.0.0: version "1.2.2" resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c" @@ -380,6 +609,22 @@ braces@^1.8.2: preserve "^0.2.0" repeat-element "^1.1.2" +braces@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + browser-stdout@1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" @@ -431,6 +676,21 @@ bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + caller-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" @@ -512,10 +772,41 @@ check-error@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" +chokidar@^1.6.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" + integrity sha1-eY5ol3gVHIB2tLNg5e3SjNortGg= + dependencies: + anymatch "^1.3.0" + async-each "^1.0.0" + glob-parent "^2.0.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^2.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + optionalDependencies: + fsevents "^1.0.0" + +chownr@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" + integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== + circular-json@^0.3.1: version "0.3.3" resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" @@ -550,6 +841,14 @@ code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + color-convert@^1.9.0: version "1.9.2" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.2.tgz#49881b8fba67df12a96bdf3f56c0aab9e7913147" @@ -578,13 +877,18 @@ commander@2.15.1: version "2.15.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" +commander@^2.11.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + commander@~2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" dependencies: graceful-readlink ">= 1.0.0" -component-emitter@^1.2.0: +component-emitter@^1.2.0, component-emitter@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" @@ -625,6 +929,11 @@ config@>=1.0.0: dependencies: json5 "^1.0.1" +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + contains-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" @@ -637,6 +946,13 @@ content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" +convert-source-map@^1.5.0, convert-source-map@^1.5.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" + integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== + dependencies: + safe-buffer "~5.1.1" + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" @@ -649,6 +965,16 @@ cookiejar@^2.1.0, cookiejar@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c" +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.7: + version "2.6.5" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.5.tgz#44bc8d249e7fb2ff5d00e0341a7ffb94fbf67895" + integrity sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A== + core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -737,6 +1063,15 @@ d3-dsv@1, d3-dsv@1.0.8: iconv-lite "0.4" rw "1" +d3-dsv@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-1.0.10.tgz#4371c489a2a654a297aca16fcaf605a6f31a6f51" + integrity sha512-vqklfpxmtO2ZER3fq/B33R/BIz3A1PV0FaZRuFM8w6jLo7sUX1BZDh73fPlr0s327rzq4H6EN1q9U+eCBCSN8g== + dependencies: + commander "2" + iconv-lite "0.4" + rw "1" + d3-ease@1, d3-ease@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-1.0.3.tgz#68bfbc349338a380c44d8acc4fbc3304aa2d8c0e" @@ -800,7 +1135,7 @@ d3-random@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-1.1.0.tgz#6642e506c6fa3a648595d2b2469788a8d12529d3" -d3-request@1.0.6: +d3-request@1.0.6, d3-request@~1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/d3-request/-/d3-request-1.0.6.tgz#a1044a9ef4ec28c824171c9379fae6d79474b19f" dependencies: @@ -911,7 +1246,16 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -debug@2, debug@2.6.9, debug@^2.2.0, debug@^2.6.8, debug@^2.6.9: +dataframe-js@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/dataframe-js/-/dataframe-js-1.4.1.tgz#c57edcfb9e80099fb10c9b0b3bf422c27efff861" + integrity sha512-I/myFOouNurPMJBsNmw/meRSKktexo9dWg9w5L2UU+dtm/EGkXtJFALV1JMy+mIBRUR0HS4HuFIxQATicInSLg== + dependencies: + "@babel/polyfill" "~7.2.5" + d3-dsv "~1.0.10" + d3-request "~1.0.6" + +debug@2, debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" dependencies: @@ -933,6 +1277,11 @@ decamelize@^1.1.1, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" @@ -987,6 +1336,11 @@ deep-eql@^3.0.0: dependencies: type-detect "^4.0.0" +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" @@ -998,6 +1352,28 @@ define-properties@^1.1.2: foreach "^2.0.5" object-keys "^1.0.8" +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + del@^2.0.2: version "2.2.2" resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" @@ -1014,6 +1390,11 @@ delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + depd@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" @@ -1026,6 +1407,18 @@ destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= + dependencies: + repeating "^2.0.0" + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + diff@3.5.0, diff@^3.2.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" @@ -1301,6 +1694,19 @@ expand-brackets@^0.1.4: dependencies: is-posix-bracket "^0.1.0" +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + expand-range@^1.8.1: version "1.8.2" resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" @@ -1353,6 +1759,21 @@ express@^4.16.3: utils-merge "1.0.1" vary "~1.1.2" +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + extend@3, extend@^3.0.0, extend@~3.0.0, extend@~3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" @@ -1371,6 +1792,20 @@ extglob@^0.3.1: dependencies: is-extglob "^1.0.0" +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + extsprintf@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" @@ -1440,6 +1875,16 @@ fill-range@^2.1.0: repeat-element "^1.1.2" repeat-string "^1.5.2" +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + finalhandler@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" @@ -1480,7 +1925,7 @@ flat-cache@^1.2.1: graceful-fs "^4.1.2" write "^0.2.1" -for-in@^1.0.1: +for-in@^1.0.1, for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -1514,6 +1959,13 @@ forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" @@ -1529,10 +1981,30 @@ fs-extra@^2.0.0: graceful-fs "^4.1.2" jsonfile "^2.1.0" +fs-minipass@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" + integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== + dependencies: + minipass "^2.2.1" + +fs-readdir-recursive@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" + integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA== + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" +fsevents@^1.0.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.7.tgz#4851b664a3783e52003b3c66eb0eee1074933aa4" + integrity sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw== + dependencies: + nan "^2.9.2" + node-pre-gyp "^0.10.0" + function-bind@^1.1.0, function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -1541,6 +2013,20 @@ functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + geojson-validation@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/geojson-validation/-/geojson-validation-0.2.1.tgz#7f9c9a3f7f967ae8e267940fda14478943342f2f" @@ -1566,6 +2052,11 @@ get-stream@^4.0.0: dependencies: pump "^3.0.0" +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + getos@^2.7.0: version "2.8.4" resolved "https://registry.yarnpkg.com/getos/-/getos-2.8.4.tgz#7b8603d3619c28e38cb0fe7a4f63c3acb80d5163" @@ -1606,6 +2097,11 @@ globals@^11.0.1, globals@^11.1.0: version "11.7.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.7.0.tgz#a583faa43055b1aca771914bf68258e2fc125673" +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== + globby@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" @@ -1621,6 +2117,11 @@ graceful-fs@^4.1.10, graceful-fs@^4.1.2, graceful-fs@^4.1.6: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" +graceful-fs@^4.1.11, graceful-fs@^4.1.4: + version "4.1.15" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" + integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== + "graceful-readlink@>= 1.0.0": version "1.0.1" resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" @@ -1654,6 +2155,42 @@ has-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + has@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -1664,6 +2201,14 @@ he@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg= + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + hosted-git-info@^2.1.4: version "2.7.1" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" @@ -1719,10 +2264,24 @@ iconv-lite@0.4.19: version "0.4.19" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" +iconv-lite@^0.4.4: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + ieee754@^1.1.4: version "1.1.12" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" +ignore-walk@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== + dependencies: + minimatch "^3.0.4" + ignore@^3.3.3: version "3.3.10" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" @@ -1738,10 +2297,15 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.3, inherits@^2.0.3, inherits@~2.0.3: +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" +ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + inquirer@^3.0.6: version "3.3.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" @@ -1761,7 +2325,7 @@ inquirer@^3.0.6: strip-ansi "^4.0.0" through "^2.3.6" -invariant@^2.2.0: +invariant@^2.2.0, invariant@^2.2.2: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" dependencies: @@ -1783,10 +2347,31 @@ ipaddr.js@1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -1801,10 +2386,42 @@ is-callable@^1.1.1, is-callable@^1.1.3: version "1.1.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + is-date-object@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + is-dotfile@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" @@ -1815,14 +2432,28 @@ is-equal-shallow@^0.1.3: dependencies: is-primitive "^2.0.0" -is-extendable@^0.1.1: +is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + is-extglob@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= + dependencies: + number-is-nan "^1.0.0" + is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" @@ -1855,6 +2486,13 @@ is-number@^2.1.0: dependencies: kind-of "^3.0.2" +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + is-number@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" @@ -1875,6 +2513,13 @@ is-path-inside@^1.0.0: dependencies: path-is-inside "^1.0.1" +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + is-posix-bracket@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" @@ -1909,6 +2554,11 @@ is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -1923,6 +2573,11 @@ isobject@^2.0.0: dependencies: isarray "1.0.0" +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -1985,6 +2640,11 @@ jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= + jsesc@^2.5.1: version "2.5.1" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.1.tgz#e421a2a8e20d6b0819df28908f782526b96dd1fe" @@ -2009,6 +2669,11 @@ json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" +json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + json5@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" @@ -2034,13 +2699,25 @@ kareem@2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.2.1.tgz#9950809415aa3cde62ab43b4f7b919d99816e015" -kind-of@^3.0.2: +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" dependencies: is-buffer "^1.1.5" -kind-of@^6.0.0: +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" @@ -2123,6 +2800,18 @@ map-age-cleaner@^0.1.1: dependencies: p-defer "^1.0.0" +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + math-random@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" @@ -2151,7 +2840,7 @@ methods@^1.1.1, methods@^1.1.2, methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" -micromatch@^2.3.11: +micromatch@^2.1.5, micromatch@^2.3.11: version "2.3.11" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" dependencies: @@ -2169,6 +2858,25 @@ micromatch@^2.3.11: parse-glob "^3.0.4" regex-cache "^0.4.2" +micromatch@^3.1.10: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + "mime-db@>= 1.34.0 < 2", mime-db@~1.35.0: version "1.35.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.35.0.tgz#0569d657466491283709663ad379a99b90d9ab47" @@ -2205,7 +2913,30 @@ minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" -mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@^0.5.1, mkdirp@~0.5.0: +minipass@^2.2.1, minipass@^2.3.4: + version "2.3.5" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" + integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" + integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== + dependencies: + minipass "^2.2.1" + +mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: @@ -2333,10 +3064,41 @@ mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" +nan@^2.9.2: + version "2.13.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.13.2.tgz#f51dc7ae66ba7d5d55e1e6d4d8092e802c9aefe7" + integrity sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" +needle@^2.2.1: + version "2.2.4" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" + integrity sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA== + dependencies: + debug "^2.1.2" + iconv-lite "^0.4.4" + sax "^1.2.4" + negotiator@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" @@ -2357,6 +3119,30 @@ node-pg-migrate@3.16.0: config ">=1.0.0" dotenv ">=1.0.0" +node-pre-gyp@^0.10.0: + version "0.10.3" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" + integrity sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= + dependencies: + abbrev "1" + osenv "^0.1.4" + normalize-package-data@^2.3.2: version "2.4.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" @@ -2366,18 +3152,41 @@ normalize-package-data@^2.3.2: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-path@^2.0.1: +normalize-path@^2.0.0, normalize-path@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" dependencies: remove-trailing-separator "^1.0.1" +npm-bundled@^1.0.1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" + integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== + +npm-packlist@^1.1.6: + version "1.4.1" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.1.tgz#19064cdf988da80ea3cee45533879d90192bbfbc" + integrity sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" dependencies: path-key "^2.0.0" +npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" @@ -2394,14 +3203,30 @@ oauth-sign@~0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" -object-assign@^4.0.1: +object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + object-keys@^1.0.11, object-keys@^1.0.8: version "1.0.12" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + object.assign@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" @@ -2427,6 +3252,13 @@ object.omit@^2.0.0: for-own "^0.1.4" is-extendable "^0.1.1" +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -2460,6 +3292,11 @@ optionator@^0.8.2: type-check "~0.3.2" wordwrap "~1.0.0" +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + os-locale@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" @@ -2478,10 +3315,27 @@ os-shim@^0.1.2: version "0.1.3" resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917" -os-tmpdir@~1.0.2: +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +output-file-sync@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76" + integrity sha1-0KM+7+YaIF+suQCS6CZZjVJFznY= + dependencies: + graceful-fs "^4.1.4" + mkdirp "^0.5.1" + object-assign "^4.1.0" + p-defer@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" @@ -2549,6 +3403,11 @@ parseurl@~1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + path-exists@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" @@ -2559,7 +3418,7 @@ path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" -path-is-absolute@^1.0.0: +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -2681,6 +3540,11 @@ portfinder@^1.0.13: debug "^2.2.0" mkdirp "0.5.x" +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + postgres-array@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-1.0.2.tgz#8e0b32eb03bf77a5c0a7851e0441c169a256a238" @@ -2721,6 +3585,11 @@ prettyjson@1.2.1: colors "^1.1.2" minimist "^1.2.0" +private@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== + process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" @@ -2797,6 +3666,16 @@ raw-body@2.3.3: iconv-lite "0.4.23" unpipe "1.0.0" +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + read-pkg-up@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" @@ -2812,7 +3691,7 @@ read-pkg@^2.0.0: normalize-package-data "^2.3.2" path-type "^2.0.0" -readable-stream@^2.0.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.5: +readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.5: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" dependencies: @@ -2824,12 +3703,44 @@ readable-stream@^2.0.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable string_decoder "~1.1.1" util-deprecate "~1.0.1" +readdirp@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +regenerator-runtime@^0.10.5: + version "0.10.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" + integrity sha1-M2w+/BIgrc7dosn6tntaeVWjNlg= + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +regenerator-runtime@^0.12.0: + version "0.12.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" + integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== + regex-cache@^0.4.2: version "0.4.4" resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" dependencies: is-equal-shallow "^0.1.3" +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + regexp-clone@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/regexp-clone/-/regexp-clone-0.0.1.tgz#a7c2e09891fdbf38fbb10d376fb73003e68ac589" @@ -2846,10 +3757,17 @@ repeat-element@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" -repeat-string@^1.5.2: +repeat-string@^1.5.2, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= + dependencies: + is-finite "^1.0.0" + request-promise-core@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" @@ -2920,6 +3838,11 @@ resolve-from@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + resolve@^1.5.0, resolve@^1.6.0: version "1.8.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" @@ -2933,6 +3856,11 @@ restore-cursor@^2.0.0: onetime "^2.0.0" signal-exit "^3.0.2" +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + rimraf@^2.2.8, rimraf@^2.6.1: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" @@ -2963,10 +3891,17 @@ safe-buffer@5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" -safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + "safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -2975,6 +3910,11 @@ saslprep@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/saslprep/-/saslprep-1.0.1.tgz#b644e0ba25b156b652f3cb90df7542f896049ba6" +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + seek-bzip@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.5.tgz#cfe917cb3d274bcffac792758af53173eb1fabdc" @@ -3024,10 +3964,30 @@ serve-static@1.13.2: parseurl "~1.3.2" send "0.16.2" -set-blocking@^2.0.0: +set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + setprototypeof@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" @@ -3115,7 +4075,60 @@ slug@^0.9.2: dependencies: unicode ">= 0.3.1" -source-map@^0.5.0: +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== + dependencies: + source-map "^0.5.6" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -3152,6 +4165,13 @@ spex@2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/spex/-/spex-2.0.2.tgz#e8c8d633a4c67af642dded701ec2350c9de964a0" +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + split@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" @@ -3181,6 +4201,14 @@ stack-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.1.tgz#d4f33ab54e8e38778b0ca5cfd3b3afb12db68620" +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + "statuses@>= 1.3.1 < 2", "statuses@>= 1.4.0 < 2": version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" @@ -3201,7 +4229,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" dependencies: @@ -3325,6 +4353,19 @@ tar-stream@^1.5.2: to-buffer "^1.1.0" xtend "^4.0.0" +tar@^4: + version "4.4.8" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" + integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.3.4" + minizlib "^1.1.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.2" + text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -3347,10 +4388,40 @@ to-buffer@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= + to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + tough-cookie@>=2.3.3: version "2.4.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" @@ -3414,16 +4485,49 @@ underscore@^1.9.1: version "11.0.1" resolved "https://registry.yarnpkg.com/unicode/-/unicode-11.0.1.tgz#735bd422ec75cf28d396eb224d535d168d5f1db6" +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + uri-js@^4.2.1: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" dependencies: punycode "^2.1.0" +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +user-home@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" + integrity sha1-K1viOjK2Onyd640PKNSFcko98ZA= + util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -3436,6 +4540,13 @@ uuid@^3.0.1, uuid@^3.1.0: version "3.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" +v8flags@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4" + integrity sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ= + dependencies: + user-home "^1.1.1" + validate-npm-package-license@^3.0.1: version "3.0.3" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz#81643bcbef1bdfecd4623793dc4648948ba98338" @@ -3469,6 +4580,13 @@ which@^1.2.9: dependencies: isexe "^2.0.0" +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + window-size@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" @@ -3514,6 +4632,11 @@ yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" +yallist@^3.0.0, yallist@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" + integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== + yargs-parser@^11.1.1: version "11.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4"