From 7586dbeb6dd9b4e31808dea012c072b2b76c41d5 Mon Sep 17 00:00:00 2001 From: bakodramane Date: Thu, 4 Jun 2026 15:04:11 +0200 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20Phase=206=20=E2=80=94=20documentati?= =?UTF-8?q?on,=20PNG=20icons,=20and=20PWA=20polish?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pre-tasks: - Install @vite-pwa/assets-generator; generate PNG icons (64, 192, 512, maskable-512, apple-touch-180, favicon.ico) from SVG source - Replace SVG icon references in vite.config.ts manifest and index.html with generated PNGs; add apple-touch-icon link - Add workflow_dispatch trigger to deploy.yml; enable GitHub Pages (repo made public per open-source requirement) - Lighthouse 11 PWA score: 100/100 (was 88 before PNG icons) Documentation (Phase 6 tasks): - README.md: full quick-start, project structure, deploy notes, links - CONTRIBUTING.md: code of conduct stub, PR guide, coding conventions - docs/adding-a-method.md: step-by-step guide with field reference table and worked example (spatio-temporal FH) - docs/stata-v14-notes.md: v14 compatibility for all 16 methods with fallback details and R alternatives Catalogue reference URLs (task 5): - Add DOI or stable URL to every reference entry across all 16 catalogue files where a URL could be confirmed Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/deploy.yml | 1 + CONTRIBUTING.md | 76 +++ README.md | 102 +++- docs/adding-a-method.md | 275 +++++++++ docs/stata-v14-notes.md | 171 ++++++ index.html | 4 +- package-lock.json | 710 ++++++++++++++++++++++ package.json | 4 + public/icons/apple-touch-icon-180x180.png | Bin 0 -> 521 bytes public/icons/favicon.ico | Bin 0 -> 490 bytes public/icons/maskable-icon-512x512.png | Bin 0 -> 1990 bytes public/icons/pwa-192x192.png | Bin 0 -> 659 bytes public/icons/pwa-512x512.png | Bin 0 -> 1856 bytes public/icons/pwa-64x64.png | Bin 0 -> 323 bytes src/catalogue/bhf-eblup.ts | 6 +- src/catalogue/direct.ts | 5 +- src/catalogue/ebp-censuseb.ts | 6 +- src/catalogue/ell.ts | 6 +- src/catalogue/fh-eblup.ts | 8 +- src/catalogue/glmm-binary.ts | 6 +- src/catalogue/glmm-count.ts | 4 +- src/catalogue/greg.ts | 4 +- src/catalogue/hb-fh.ts | 6 +- src/catalogue/hb-unit.ts | 6 +- src/catalogue/m-quantile.ts | 6 +- src/catalogue/mqgwr.ts | 4 +- src/catalogue/reblup.ts | 4 +- src/catalogue/robust-fh.ts | 6 +- src/catalogue/spatial-fh.ts | 8 +- src/catalogue/two-part-zinfl.ts | 6 +- vite.config.ts | 19 +- 31 files changed, 1400 insertions(+), 53 deletions(-) create mode 100644 CONTRIBUTING.md create mode 100644 docs/adding-a-method.md create mode 100644 docs/stata-v14-notes.md create mode 100644 public/icons/apple-touch-icon-180x180.png create mode 100644 public/icons/favicon.ico create mode 100644 public/icons/maskable-icon-512x512.png create mode 100644 public/icons/pwa-192x192.png create mode 100644 public/icons/pwa-512x512.png create mode 100644 public/icons/pwa-64x64.png diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 3e830ff..5f1d420 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -4,6 +4,7 @@ on: push: branches: - main + workflow_dispatch: permissions: contents: read diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..fe68ef0 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,76 @@ +# Contributing to SAE Syntax Generator + +Thank you for your interest in improving this tool. Contributions from statisticians, +developers, and domain experts are all welcome. + +--- + +## Code of conduct + +Be respectful and constructive. We follow the +[Contributor Covenant](https://www.contributor-covenant.org/version/2/1/code_of_conduct/) +(v2.1). Harassment of any kind will not be tolerated. + +--- + +## How to open an issue + +Go to [GitHub Issues](https://github.com/bakodramane/SAE_Syntax_Generator/issues) and choose +the most appropriate template: + +- **Bug report** — something does not work as documented. +- **Method correction** — a formula, reference, or caveat in a catalogue entry is wrong. +- **New method request** — a SAE method is missing from the catalogue. +- **Documentation improvement** — unclear or missing explanation. + +Please include: the browser and OS, the exact steps to reproduce (if a bug), and what you +expected vs. what happened. + +--- + +## How to submit a pull request + +1. Fork the repository and clone your fork. +2. Create a branch: `git checkout -b fix/my-fix` or `feat/my-feature`. +3. Make your changes (see *Coding conventions* below). +4. Run `npm run build`, `npm test`, and `npm run lint` — all must pass. +5. Open a pull request against `main` with a clear description of what changed and why. + +--- + +## Adding a new SAE method + +This is the most common type of contribution. See +[docs/adding-a-method.md](docs/adding-a-method.md) for a complete step-by-step guide. You +do not need to touch the engine code; you only create one TypeScript catalogue file. + +--- + +## Coding conventions + +- **TypeScript strict mode** — no `any` types; `tsc --noEmit` must pass. +- **Tailwind CSS** — use utility classes; do not add custom CSS unless unavoidable. +- **UK English** with the Oxford comma in all user-facing text and documentation. +- **No comments on obvious code** — only add a comment when the *why* is non-obvious. +- **Conventional commits** — `feat:`, `fix:`, `test:`, `docs:`, `chore:` prefixes. +- **No self-merging** — open a pull request and wait for review. + +--- + +## Local development + +```bash +npm install +npm run dev # development server with hot reload +npm test # Vitest unit tests +npx playwright test # end-to-end smoke test +npm run lint # ESLint +npm run build # production build +``` + +--- + +## Licence + +By contributing you agree that your work will be released under the +[MIT Licence](LICENSE). diff --git a/README.md b/README.md index 24086e7..5de79f7 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,105 @@ # SAE Syntax Generator -A browser-only, offline-capable expert system that recommends small area estimation (SAE) methods and generates ready-to-run R and Stata scripts from a description of your survey microdata. +A browser-only, offline-capable expert system that recommends small area estimation (SAE) +methods and generates ready-to-run R and Stata scripts from a description of your survey +microdata and auxiliary data. No data leaves your machine. **Live app:** https://bakodramane.github.io/SAE_Syntax_Generator/ -> Full setup instructions coming in Phase 6. +--- + +## What it does + +Small area estimation bridges the gap between nationally representative surveys and the need +for reliable estimates at district, county, or municipality level. This tool: + +1. Lets you describe your data (variable types, what auxiliary data you have, Stata version). +2. Recommends the most appropriate SAE method from a catalogue of 16 methods. +3. Generates a complete, commented R script and Stata `.do` file — ready to run with your + real variable names filled in. + +Target users: statisticians in national statistical offices and development organisations, +including those working in countries where Stata 14 is the installed standard. + +--- + +## Quick start (local development) + +```bash +git clone https://github.com/bakodramane/SAE_Syntax_Generator.git +cd SAE_Syntax_Generator +npm install +npm run dev # opens http://localhost:5173/SAE_Syntax_Generator/ +``` + +Requirements: Node.js ≥ 18. + +--- + +## Running tests + +```bash +npm test # Vitest unit tests (catalogue schema + engine logic) +npx playwright test # Playwright end-to-end smoke test +``` + +--- + +## Building for production + +```bash +npm run build # outputs to dist/ +npx vite preview # serve the built app locally +``` + +--- + +## Deployment + +The app deploys automatically to GitHub Pages on every merge to `main` via the +`.github/workflows/deploy.yml` workflow. No manual steps are required. + +To deploy a fork to your own GitHub Pages, enable Pages (Settings → Pages → Source: GitHub +Actions) and push to your `main` branch. + +--- + +## Adding a new SAE method + +See [docs/adding-a-method.md](docs/adding-a-method.md) for a step-by-step guide. No engine +code needs to change — you only create one TypeScript file in `src/catalogue/`. + +--- + +## Stata v14 compatibility + +See [docs/stata-v14-notes.md](docs/stata-v14-notes.md) for a full breakdown of which methods +work on Stata 14, which fall back to the `mixed` command, and which require R. + +--- + +## Project structure + +``` +src/ + catalogue/ # One .ts file per SAE method (human-editable) + engine/ # Recommender and code-generation logic + types/ # Shared TypeScript interfaces +docs/ + adding-a-method.md # Guide for contributing new methods + stata-v14-notes.md # Stata version compatibility reference + SAE-CATALOGUE.md # Full method taxonomy and design spec + PHASES.md # Build plan and acceptance criteria +``` + +--- + +## Contributing + +See [CONTRIBUTING.md](CONTRIBUTING.md). + +--- + +## Licence + +MIT — see [LICENSE](LICENSE). diff --git a/docs/adding-a-method.md b/docs/adding-a-method.md new file mode 100644 index 0000000..423fb93 --- /dev/null +++ b/docs/adding-a-method.md @@ -0,0 +1,275 @@ +# Adding a New SAE Method to the Catalogue + +This guide walks you through adding a new small area estimation method to the catalogue +without touching any engine code. All you need is one TypeScript file. + +--- + +## Overview + +Every SAE method lives in its own file under `src/catalogue/.ts`. The recommender +and code-generation engines read these files automatically — you do not need to register the +method anywhere else (except in `src/catalogue/index.ts`, as described below). + +The general workflow is: + +1. Copy an existing catalogue file. +2. Fill in every field. +3. Write R and Stata templates with `{{PLACEHOLDER}}` tokens. +4. Register the new entry in `src/catalogue/index.ts`. +5. Run `npm test` — the schema tests will catch any missing or invalid fields. +6. Open a pull request. + +--- + +## Step 1 — Choose a method ID + +Pick a short, lower-case kebab-case identifier, e.g. `calinski-eblup` or `spatio-temporal-fh`. +Avoid spaces and special characters. This ID is used in URLs and as an internal key. + +--- + +## Step 2 — Copy an existing file + +Copy a file that is similar to your new method. For an area-level method, start from +`src/catalogue/fh-eblup.ts`. For a unit-level method, start from `src/catalogue/bhf-eblup.ts`. + +```bash +cp src/catalogue/fh-eblup.ts src/catalogue/my-new-method.ts +``` + +--- + +## Step 3 — Fill in every field + +Open `src/catalogue/my-new-method.ts` and edit each field. The full schema is defined in +`src/types/index.ts`. Here is a description of every field: + +### Identification + +| Field | Type | Description | +|-------|------|-------------| +| `id` | `string` | Unique kebab-case identifier, e.g. `'my-new-method'` | +| `displayName` | `string` | Short human-readable name shown in the UI | +| `level` | `'area' \| 'unit' \| 'model-assisted'` | Whether the model operates on area aggregates or unit microdata | +| `inferenceType` | `'frequentist' \| 'bayesian' \| 'design-based'` | Statistical paradigm | + +### Data requirements + +| Field | Type | Description | +|-------|------|-------------| +| `targetTypes` | `DataAvailability['targetType'][]` | Variable types this method supports: `'continuous'`, `'binary'`, `'proportion'`, `'count'`, `'poverty'`, `'unknown'` | +| `requiredInputs.microdata` | `boolean` | Does the method need unit-level survey records? | +| `requiredInputs.areaAggregates` | `boolean` | Does the method need pre-computed direct estimates and their variances? | +| `requiredInputs.censusAuxiliaries` | `'unit' \| 'area' \| 'either' \| 'none'` | What level of auxiliary data is needed | +| `requiredInputs.weights` | `boolean` | Are sampling weights required? | +| `requiredInputs.contiguityMatrix` | `boolean` | Is a spatial adjacency or weight matrix needed? | +| `requiredInputs.coordinates` | `boolean` | Are geographic coordinates needed? | + +### Method properties + +| Field | Type | Description | +|-------|------|-------------| +| `spatial` | `boolean` | Does the method explicitly model spatial dependence? | +| `robust` | `boolean` | Is the method robust to outliers (M-estimation or similar)? | +| `mseMethod` | `'prasad-rao' \| 'bootstrap' \| 'both' \| 'posterior'` | How mean squared error is estimated | + +### Software + +| Field | Type | Description | +|-------|------|-------------| +| `rPackage` | `string` | Primary R package name, e.g. `'sae'` | +| `rFunction` | `string` | Main function(s) used, e.g. `'eblupFH / mseFH'` | +| `stataPackage` | `string` | Stata user-written package name, or `'base'` for built-in commands | +| `stataCommand` | `string` | Main Stata command(s) used | +| `stataMinVersion` | `number` | Minimum Stata version required (≥ 14). Use `14` if the method works on Stata 14. | +| `stataV14Fallback` | `string \| null` | If `stataMinVersion > 14`, provide a `.do` template using `mixed` / `meglm` that runs on Stata 14. Otherwise `null`. | + +### User-facing text + +| Field | Type | Description | +|-------|------|-------------| +| `plainDescription` | `string` | 2–3 sentences in plain English with no statistical jargon | +| `whyChooseThis` | `string` | When should a user pick this method? Shown in the "Why this method?" panel | +| `assumptions` | `string[]` | List of model assumptions surfaced before code generation. At least one is required. | +| `caveats` | `string[]` (optional) | Any extra warnings (computational cost, edge cases, etc.) | +| `references` | `string[]` | Full citations, each including a URL where possible. At least one is required. | + +### Code templates + +The `rTemplate` and `stataTemplate` fields contain complete, runnable scripts as template +literal strings. Use `{{PLACEHOLDER}}` tokens (uppercase, underscores) for values that will +be substituted from user input. + +**Standard tokens** (used by most methods): + +| Token | Substituted with | +|-------|-----------------| +| `{{DATE}}` | Generation date | +| `{{TARGET_VAR}}` | Target variable name | +| `{{AREA_ID}}` | Small area identifier variable | +| `{{WEIGHT_VAR}}` | Sampling weight variable | +| `{{AUX_VARS_R}}` | Auxiliary variables as `var1 + var2 + ...` (R formula syntax) | +| `{{AUX_VARS_STATA}}` | Auxiliary variables as `var1 var2 ...` (space-separated) | +| `{{AUX_VARS_R_VEC}}` | Auxiliary variables as `c("var1", "var2", ...)` (R vector) | +| `{{SURVEY_DATA}}` | Path to the survey CSV file | +| `{{AREA_DATA}}` | Path to the area-level CSV file | +| `{{CENSUS_DATA}}` | Path to the census CSV file | +| `{{DIRECT_EST_VAR}}` | Pre-computed direct estimate column | +| `{{DIRECT_VAR_VAR}}` | Sampling variance column | +| `{{N_SIMULATIONS}}` | Number of bootstrap replications | + +You may define additional tokens, but keep names descriptive and consistent with the style +above. + +--- + +## Step 4 — Register the entry + +Open `src/catalogue/index.ts` and add an import and entry for your new method: + +```typescript +import myNewMethod from './my-new-method.js' + +export const catalogue: CatalogueEntry[] = [ + // … existing entries … + myNewMethod, +] +``` + +Place the entry in a logical position (e.g., near related methods). + +--- + +## Step 5 — Run the tests + +```bash +npm test +``` + +The catalogue schema test (`src/catalogue/catalogue.test.ts`) verifies: +- All required fields are present and non-empty. +- `stataMinVersion` is ≥ 14. +- If `stataMinVersion > 14`, `stataV14Fallback` is non-null. +- `rTemplate` and `stataTemplate` each contain at least one `{{` token. +- `references` and `assumptions` each have at least one entry. + +Fix any failures before proceeding. + +--- + +## Step 6 — Open a pull request + +Push your branch and open a PR against `main`. In the PR description, include: + +- The method name and ID. +- A short summary of what it does and when it should be recommended. +- The key references you used. +- Confirmation that `npm run build`, `npm test`, and `npm run lint` all pass. + +--- + +## Worked example: Calinski spatio-temporal FH + +Suppose you want to add a spatio-temporal extension of the Fay–Herriot model. + +**File:** `src/catalogue/spatio-temporal-fh.ts` + +```typescript +import type { CatalogueEntry } from '../types/index.js' + +const entry: CatalogueEntry = { + id: 'spatio-temporal-fh', + displayName: 'Spatio-Temporal Fay–Herriot (Area-Level)', + level: 'area', + inferenceType: 'frequentist', + targetTypes: ['continuous', 'proportion'], + requiredInputs: { + microdata: false, + areaAggregates: true, + censusAuxiliaries: 'area', + weights: false, + contiguityMatrix: true, + coordinates: false, + }, + spatial: true, + robust: false, + mseMethod: 'bootstrap', + rPackage: 'sae2', + rFunction: 'eblupSTFH', + stataPackage: 'none', + stataCommand: 'N/A — use R', + stataMinVersion: 14, + stataV14Fallback: null, + plainDescription: + 'Extends the Fay–Herriot model to share strength across both space and time. ' + + 'Borrows information from neighbouring areas and from the same area in previous ' + + 'rounds. Requires area-level estimates for at least two time points.', + whyChooseThis: + 'Choose this when you have area-level data for multiple survey rounds and a spatial ' + + 'adjacency matrix. It typically produces smaller mean squared errors than a ' + + 'cross-sectional FH model.', + assumptions: [ + 'Sampling variances of the direct estimates are known for all areas and periods.', + 'The spatial and temporal correlation structure is correctly specified.', + 'Area random effects are normally distributed.', + ], + references: [ + 'Marhuenda, Y., Molina, I. & Morales, D. (2013). Computational Statistics & Data Analysis 58, 308–325. https://doi.org/10.1016/j.csda.2012.09.002', + 'sae2 package: CRAN. https://cran.r-project.org/package=sae2', + ], + rTemplate: `# ============================================================ +# Spatio-Temporal Fay–Herriot EBLUP (Area-Level) +# Generated by SAE Syntax Generator on {{DATE}} +# Reference: Marhuenda et al. (2013) +# R package: sae2 +# Area-level data: {{AREA_DATA}} +# ============================================================ + +if (!requireNamespace("sae2", quietly = TRUE)) install.packages("sae2") +library(sae2) + +area_data <- read.csv("{{AREA_DATA}}") +# Required columns: {{DIRECT_EST_VAR}}, {{DIRECT_VAR_VAR}}, {{AUX_VARS_R}}, +# {{AREA_ID}}, time (integer period index), proximity matrix + +# Load the spatial proximity matrix (rows/columns ordered as areas in area_data) +# W <- as.matrix(read.csv("proximity_matrix.csv", row.names = 1)) + +result <- eblupSTFH( + formula = {{DIRECT_EST_VAR}} ~ {{AUX_VARS_R}}, + vardir = area_data${{DIRECT_VAR_VAR}}, + proxmat = W, + data = area_data +) + +print(result$eblup) +`, + stataTemplate: `* ============================================================ +* Spatio-Temporal Fay–Herriot — not available in Stata +* Generated by SAE Syntax Generator on {{DATE}} +* Use the R script above with the sae2 package. +* ============================================================ + +* This method has no Stata implementation. +* Please switch to R and use the sae2 package. +`, +} + +export default entry +``` + +Register it in `src/catalogue/index.ts`, run `npm test`, and open a PR. + +--- + +## Tips + +- Keep `plainDescription` jargon-free. Imagine explaining it to a government statistician + who is a survey expert but not an SAE specialist. +- Always set `stataV14Fallback` when `stataMinVersion > 14`. A `null` value with + `stataMinVersion > 14` will fail the schema test. +- If the method has no Stata implementation, set `stataMinVersion: 14` and write a Stata + template that clearly says "Use R" rather than leaving the field blank. +- Use realistic variable names in the template comments (e.g. `income`, `area_id`) — they + help users orient themselves before filling in their own names. diff --git a/docs/stata-v14-notes.md b/docs/stata-v14-notes.md new file mode 100644 index 0000000..16b2463 --- /dev/null +++ b/docs/stata-v14-notes.md @@ -0,0 +1,171 @@ +# Stata v14 Compatibility Notes + +This document lists all 16 SAE methods in the catalogue, their Stata version requirements, +and what the generated script will do when you select Stata 14. + +--- + +## Quick reference + +| Method | Stata 14 status | Command / package | +|--------|----------------|-------------------| +| Direct Estimator | ✅ Full support | `svy: mean` (base Stata) | +| GREG | ✅ Full support | `svy: regress` (base Stata) | +| BHF EBLUP (unit-level) | ✅ Full support | `mixed` (base Stata) | +| GLMM-EBP Binary | ✅ Full support | `meglm` (base Stata) | +| GLMM-EBP Count | ✅ Full support | `meglm` (base Stata) | +| Two-Part / Zero-Inflated | ✅ Full support | `meglm` (base Stata) | +| Fay–Herriot EBLUP | ✅ With user package | `fhsae` or `fayherriot` | +| Spatial Fay–Herriot | ✅ With user package | `fhsae` (spatialcor option) | +| Robust Fay–Herriot | ✅ With user package | `fhsae` (robust option) | +| EBP / CensusEB | ⚠️ Fallback to `mixed` | Requires v17 for full World Bank sae package | +| ELL Census Method | ⚠️ Fallback to `mixed` | Requires v17 for full World Bank sae package | +| Hierarchical Bayes FH | ❌ R only | No Stata equivalent | +| Hierarchical Bayes Unit-Level | ❌ R only | No Stata equivalent | +| M-Quantile | ❌ R only | No standard Stata package | +| M-Quantile GWR | ❌ R only | No standard Stata package | +| REBLUP (Robust Unit-Level) | ❌ R only | No standard Stata package | + +--- + +## Fully supported on Stata 14 (base commands) + +These methods use commands that have been part of Stata since version 12 or earlier. +No additional installation is required. + +### Direct Estimator +- **Command:** `svy: mean` / `svy: proportion` / `svy: total` +- Uses the built-in survey prefix. Set your survey design with `svyset` first. +- **Note:** Direct estimation works well only when area sample sizes are large (n ≥ 25 per + area). It serves as a benchmark, not a replacement for model-based SAE. + +### GREG — Generalised Regression Estimator +- **Command:** `svy: regress` +- Calibration weights are computed post-estimation. The generated script shows how to + combine domain means to obtain GREG estimates. + +### BHF EBLUP (Battese–Harter–Fuller, Unit-Level) +- **Command:** `mixed` +- The `mixed` command (introduced in Stata 13) fits the nested-error regression model. + EBLUPs are recovered from the fitted random effects. The generated script extracts + small area predictions from `_b[...]` and `predict, reffects`. + +### GLMM-EBP Binary / Proportion +- **Command:** `meglm ... , family(binomial) link(logit)` +- `meglm` is available from Stata 14. The empirical best predictor is approximated from + the fitted model's random effects. + +### GLMM-EBP Count Data +- **Command:** `meglm ... , family(poisson) link(log)` +- Same as above with the Poisson link. + +### Two-Part / Zero-Inflated Model +- **Command:** `meglm` (binomial part) + `mixed` or `meglm` (positive part) +- Both parts use base Stata 14 commands. The script runs two models and combines their + predictions. + +--- + +## Supported with user-written packages (Stata 14) + +These methods require a user-written package to be installed. The generated script includes +the installation command. + +### Fay–Herriot EBLUP (Area-Level) +- **Package:** `fhsae` (Mehmetoglu & Jakobsen) or `fayherriot` (World Bank variant) +- **Install:** `net install fhsae, from("https://raw.github.com/jpazvd/fhsae/master/")` +- Fits the FH model with REML, ML, or FH estimators. Prasad–Rao analytic MSE and + parametric bootstrap MSE are both available. +- Works on Stata 14 without restrictions. + +### Spatial Fay–Herriot EBLUP +- **Package:** `fhsae` (with the `spatialcor` option) +- **Install:** same as above +- Requires a spatial weight matrix stored as a Stata matrix or external file. +- Works on Stata 14 without restrictions. + +### Robust Fay–Herriot +- **Package:** `fhsae` (with the `robust` option) +- **Install:** same as above +- Uses M-estimation to down-weight influential area-level observations. +- Works on Stata 14 without restrictions. + +--- + +## Require Stata 17+ — fallback provided + +These methods rely on the World Bank `sae` Stata package, which requires Stata 17 or later. +When you select Stata 14 in the wizard, the generated `.do` file automatically uses the +`mixed` command as a simpler unit-level alternative. + +### EBP / CensusEB (Poverty Mapping) +- **Requires:** Stata 17 + World Bank `sae` package +- **Package:** `ssc install sae` (Stata 17+) +- **World Bank notes:** https://github.com/pcorralrodas/SAE-Stata-Package +- **Stata 14 fallback:** The generated script uses `mixed` to fit the nested-error + regression model and computes area predictions from random effects. This approximation + does not perform the full Monte Carlo simulation used by the EBP; mean squared errors + are therefore only approximate. Use R with the `povmap` package for a complete + implementation on Stata 14 machines. +- **R alternative:** `povmap` (https://cran.r-project.org/package=povmap) or `emdi`. + +### ELL Census Method +- **Requires:** Stata 17 + World Bank `sae` package +- **Stata 14 fallback:** Same `mixed`-based approach as EBP above. Produces area-level + predictions but not the full household-level simulation. +- **R alternative:** `povmap` supports both EBP and ELL; use the R script generated + alongside the fallback `.do` file. + +--- + +## R only — no Stata implementation + +These methods have no standard Stata implementation. The generated `.do` file explains this +and directs you to the R script instead. + +### Hierarchical Bayes Fay–Herriot +- **Why R only:** MCMC-based inference requires specialised software. The `saeHB` R package + provides full posterior inference; there is no equivalent in Stata. +- **R package:** `saeHB` (https://cran.r-project.org/package=saeHB) + +### Hierarchical Bayes Unit-Level +- **Why R only:** Same as above. Full Bayesian unit-level models are not available in Stata. +- **R package:** `saeHB` + +### M-Quantile Estimator +- **Why R only:** M-quantile regression for SAE requires iteratively reweighted estimation + that is not available as a standard Stata command. +- **R package:** `mquantreg` (https://cran.r-project.org/package=mquantreg) + +### M-Quantile GWR (Geographically Weighted) +- **Why R only:** Combines geographically weighted regression with M-quantile estimation. + No Stata package exists. +- **R package:** Custom implementation; see Salvati et al. (2012). + +### REBLUP (Robust Unit-Level EBLUP) +- **Why R only:** Sinha–Rao M-estimation for unit-level SAE is not available in any + released Stata package. +- **R package:** `saeRobust` (https://cran.r-project.org/package=saeRobust) + +--- + +## General advice for Stata 14 users + +1. **Try R for complex methods.** If your target method is R-only, the generator produces a + complete R script that you can run in RStudio. R is free and available at + https://www.r-project.org/. + +2. **Bootstrap MSE in Stata.** Stata's `bootstrap` prefix can approximate MSE for any + model, including the `mixed`-based fallbacks. The generated scripts include a commented + bootstrap block. + +3. **Upgrading Stata.** If your institution can upgrade to Stata 17+, the full World Bank + `sae` package becomes available for EBP and ELL, providing the official Monte Carlo + simulation and household-level poverty mapping. + +4. **World Bank resources.** The World Bank's SAE team maintains the `sae` Stata package + and detailed training materials: + https://github.com/pcorralrodas/SAE-Stata-Package + +5. **FAO reference.** The FAO guide covers Stata implementations for many methods in this + catalogue: https://www.fao.org/3/i4818e/i4818e.pdf diff --git a/index.html b/index.html index 41f044f..f351f3b 100644 --- a/index.html +++ b/index.html @@ -2,7 +2,9 @@ - + + + diff --git a/package-lock.json b/package-lock.json index bd7b077..891e806 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "@types/react-dom": "^19.2.3", "@typescript-eslint/eslint-plugin": "^8.60.1", "@typescript-eslint/parser": "^8.60.1", + "@vite-pwa/assets-generator": "^1.0.2", "@vitejs/plugin-react": "^6.0.2", "@vitest/coverage-v8": "^4.1.8", "autoprefixer": "^10.5.0", @@ -1735,6 +1736,13 @@ "specificity": "bin/cli.js" } }, + "node_modules/@canvas/image-data": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@canvas/image-data/-/image-data-1.1.0.tgz", + "integrity": "sha512-QdObRRjRbcXGmM1tmJ+MrHcaz1MftF2+W7YI+MsphnsCrmtyfS0d5qJbk0MeSbUeyM/jCb0hmnkXPsy026L7dA==", + "dev": true, + "license": "MIT" + }, "node_modules/@csstools/color-helpers": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.0.2.tgz", @@ -2108,6 +2116,422 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", + "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", + "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", + "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", + "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", + "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", + "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", + "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", + "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", + "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.5" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", + "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", + "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", + "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", + "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", + "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", + "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.2.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", + "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", + "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/@isaacs/cliui": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", @@ -2262,6 +2686,19 @@ "node": ">=18" } }, + "node_modules/@quansync/fs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@quansync/fs/-/fs-1.0.0.tgz", + "integrity": "sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "quansync": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, "node_modules/@rolldown/binding-android-arm64": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz", @@ -3484,6 +3921,30 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@vite-pwa/assets-generator": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@vite-pwa/assets-generator/-/assets-generator-1.0.2.tgz", + "integrity": "sha512-MCbrb508JZHqe7bUibmZj/lyojdhLRnfkmyXnkrCM2zVrjTgL89U8UEfInpKTvPeTnxsw2hmyZxnhsdNR6yhwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "colorette": "^2.0.20", + "consola": "^3.4.2", + "sharp": "^0.33.5", + "sharp-ico": "^0.1.5", + "unconfig": "^7.3.1" + }, + "bin": { + "pwa-assets-generator": "bin/pwa-assets-generator.mjs" + }, + "engines": { + "node": ">=16.14.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/@vitejs/plugin-react": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.2.tgz", @@ -4083,6 +4544,16 @@ "dev": true, "license": "MIT" }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/call-bind": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", @@ -4212,6 +4683,58 @@ "node": ">= 6" } }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", @@ -4232,6 +4755,16 @@ "node": ">=4.0.0" } }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -4412,6 +4945,35 @@ "dev": true, "license": "MIT" }, + "node_modules/decode-bmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/decode-bmp/-/decode-bmp-0.2.1.tgz", + "integrity": "sha512-NiOaGe+GN0KJqi2STf24hfMkFitDUaIoUU3eKvP/wAbLe8o6FuW5n/x7MHPR0HKvBokp6MQY/j7w8lewEeVCIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@canvas/image-data": "^1.0.0", + "to-data-view": "^1.1.0" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/decode-ico": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/decode-ico/-/decode-ico-0.4.1.tgz", + "integrity": "sha512-69NZfbKIzux1vBOd31al3XnMnH+2mqDhEgLdpygErm4d60N+UwA5Sq5WFjmEDQzumgB9fElojGwWG0vybVfFmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@canvas/image-data": "^1.0.0", + "decode-bmp": "^0.2.0", + "to-data-view": "^1.1.0" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -4465,6 +5027,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/defu": { + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.7.tgz", + "integrity": "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==", + "dev": true, + "license": "MIT" + }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", @@ -5613,6 +6182,13 @@ "dev": true, "license": "MIT" }, + "node_modules/ico-endec": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ico-endec/-/ico-endec-0.1.6.tgz", + "integrity": "sha512-ZdLU38ZoED3g1j3iEyzcQj+wAkY2xfWNkymszfJPoxucIUhK7NayQ+/C4Kv0nDFMIsbtbEHldv3V8PU494/ueQ==", + "dev": true, + "license": "MPL-2.0" + }, "node_modules/idb": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", @@ -5683,6 +6259,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-arrayish": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", + "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", + "dev": true, + "license": "MIT" + }, "node_modules/is-async-function": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", @@ -7442,6 +8025,23 @@ "node": ">=6" } }, + "node_modules/quansync": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-1.0.0.tgz", + "integrity": "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT" + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -7936,6 +8536,58 @@ "node": ">= 0.4" } }, + "node_modules/sharp": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", + "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.5", + "@img/sharp-darwin-x64": "0.33.5", + "@img/sharp-libvips-darwin-arm64": "1.0.4", + "@img/sharp-libvips-darwin-x64": "1.0.4", + "@img/sharp-libvips-linux-arm": "1.0.5", + "@img/sharp-libvips-linux-arm64": "1.0.4", + "@img/sharp-libvips-linux-s390x": "1.0.4", + "@img/sharp-libvips-linux-x64": "1.0.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", + "@img/sharp-libvips-linuxmusl-x64": "1.0.4", + "@img/sharp-linux-arm": "0.33.5", + "@img/sharp-linux-arm64": "0.33.5", + "@img/sharp-linux-s390x": "0.33.5", + "@img/sharp-linux-x64": "0.33.5", + "@img/sharp-linuxmusl-arm64": "0.33.5", + "@img/sharp-linuxmusl-x64": "0.33.5", + "@img/sharp-wasm32": "0.33.5", + "@img/sharp-win32-ia32": "0.33.5", + "@img/sharp-win32-x64": "0.33.5" + } + }, + "node_modules/sharp-ico": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/sharp-ico/-/sharp-ico-0.1.5.tgz", + "integrity": "sha512-a3jODQl82NPp1d5OYb0wY+oFaPk7AvyxipIowCHk7pBsZCWgbe0yAkU2OOXdoH0ENyANhyOQbs9xkAiRHcF02Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "decode-ico": "*", + "ico-endec": "*", + "sharp": "*" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -8055,6 +8707,16 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/simple-swizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz", + "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, "node_modules/smob": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/smob/-/smob-1.6.2.tgz", @@ -8528,6 +9190,13 @@ "dev": true, "license": "MIT" }, + "node_modules/to-data-view": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/to-data-view/-/to-data-view-1.1.0.tgz", + "integrity": "sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==", + "dev": true, + "license": "MIT" + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -8756,6 +9425,47 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/unconfig": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/unconfig/-/unconfig-7.5.0.tgz", + "integrity": "sha512-oi8Qy2JV4D3UQ0PsopR28CzdQ3S/5A1zwsUwp/rosSbfhJ5z7b90bIyTwi/F7hCLD4SGcZVjDzd4XoUQcEanvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@quansync/fs": "^1.0.0", + "defu": "^6.1.4", + "jiti": "^2.6.1", + "quansync": "^1.0.0", + "unconfig-core": "7.5.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/unconfig-core": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/unconfig-core/-/unconfig-core-7.5.0.tgz", + "integrity": "sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@quansync/fs": "^1.0.0", + "quansync": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/unconfig/node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, "node_modules/undici": { "version": "7.27.0", "resolved": "https://registry.npmjs.org/undici/-/undici-7.27.0.tgz", diff --git a/package.json b/package.json index 4247966..8304253 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "@types/react-dom": "^19.2.3", "@typescript-eslint/eslint-plugin": "^8.60.1", "@typescript-eslint/parser": "^8.60.1", + "@vite-pwa/assets-generator": "^1.0.2", "@vitejs/plugin-react": "^6.0.2", "@vitest/coverage-v8": "^4.1.8", "autoprefixer": "^10.5.0", @@ -41,5 +42,8 @@ "vite": "^8.0.16", "vite-plugin-pwa": "^1.3.0", "vitest": "^4.1.8" + }, + "allowScripts": { + "sharp@0.33.5": true } } diff --git a/public/icons/apple-touch-icon-180x180.png b/public/icons/apple-touch-icon-180x180.png new file mode 100644 index 0000000000000000000000000000000000000000..543762061fee856983116c2cceeb06d542655d8c GIT binary patch literal 521 zcmeAS@N?(olHy`uVBq!ia0vp^TR@nD8Ax&oe*=;XasfUeu5u3R|Ns9#`RLz-rN8#y z{&(lq-`X|r0`iWAPI$Rs=POpF&l7+uISV`@iy0W0Uw|;<*6N^a1_s87o-U3d6}R5r zIhc1ufyXuQ5@XK4|LwDHhAckjwak-Yck%sMM<+g=su~x?q}IsBD`k>#VS!^af?>-L zJImvh+{Cav=jn_OpHiblPz}cafNF;f3Fe?>TRu`Jzln*ZATm&le`95G%gK>#^>CET@Bx4STWpL)}L27`I&6)jO#z# z!Y|KRoxR2O#dKCi40Rxnz36v}xBq(Xhw60xzE>yR_S;DOk>6-L`Lx>3y~kqaZF$dTIOBf+_L+>PB{1Qeua+7T+_uD6t#Purn$GSdD#`&u`Q!3+}3;{!>6`M`zMrk z8Fp(YhqbKB>J2|8wfUP_#=#Fx|B?Lw4bm6?TmP|rR&O}6zb{%F6uF+RelF{r5}E*+ C)8@zk literal 0 HcmV?d00001 diff --git a/public/icons/favicon.ico b/public/icons/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..a835719b2c4be8e5718ef38b036ae2b00dd89b6f GIT binary patch literal 490 zcmZQzU<5)32L>R?!El9O>_%)r3>0)!d2RtIGR&1mywFkID~D)l7dS9|@YmixbT+EqSyT$z-_cQ*FG zorT5XlNQ}nas51LopfB4kNh%u^@c4s);eX@a2)zlE~cPcwt8pxmq~I=k;m;$sN0ta z{bNvZ-8^%*!Fi75=UZOP+gHo=;``tIO^a&W8621z7y_6ZrZG*Js(b&=TleH^tehWK z?4Khn;}BOmnIXonk)eTwfpGyF7@xhHAi{9de&0z}#)8#$AVp!@CNsQYV+deuU|hg> zfZ+l|0z(Fa0fPy{4QrqQe?I)NliIB3(Qy6n^5Qp4V*C@r@2W8T7GYSx!ochR(!+3o zApodH1E@!YL4qMmksUGR#V6i~ X1!=M@S4{r{qlv-O)z4*}Q$iB}CFHm< literal 0 HcmV?d00001 diff --git a/public/icons/maskable-icon-512x512.png b/public/icons/maskable-icon-512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..8bc45711078e009ee736d1885ea882644c74fe9c GIT binary patch literal 1990 zcmc&#eN0nV6hHU9*S=C|Eg(>lj}EEMEyd0`X>66J1M3G$$8ckU*ccO?ZcB zp~6D9X=HOm`o~Zg=d3|jI^FsvI+>Z4L=+r4I^)+WD`@A6K>PNJ{J&(G+ez;I{qD`p zJ->U;Irr`{tk6ru31R?{ELohD2SD(Y01?SU`=PWB9%2nS`Ps?LagO8mo(~#ZhS}aw zuQ&Ai_ReeCJ<)JN{#BD=rT2p5r0gMG;*14($xBy1R00DcKnkER$bk4S2P&a0=~STjkCv1*`zlUe zLMPjQbd`0M3px`+uG9@9$UHabj?_5_&rqY%kZ9RVWPm2|&h-Wf6a=po)Ad%1?>Y5k zY~{S4vH6gD;k|745jfC#`cPa9_FEM;4R?d6^Sf2H9c=KK?SMjW`gZr8-!6g%Ql z4^Z_2bs)8%2%IykZxJ0;5tDMk*(|7^pa>`pk@&_`n;e{a<|Qb#;|4^lyg4a!d@fY(7`C>qghx9^Ekfp& zo5KLt-tHgG^&#lrf|`M_*-b`p%?WaZ6B13P{KRth-c=`2nHh4pkm%?S}`A2`z_O1sSMc8C$1v5k}^Fvnu_V}6bALRBI|hkZUP zq0i`AundNG?Ydg&Ap1$rhV|ZQY%*-r7Scu%^qcllAVX|N_~f(*Y>pE-*aJehYb7is zVO=2(UBOM9TJ(hTB_QiN6LEQ27UD! z|ES)933gCv=<~_1q~l+g+0ulamXV%Jx}s#=UDwU@;bu$elzy;fK5jWE#{N)i4n*RQ zqQ;V3R!M7`0^JQo)@rJ0KDWG>Dhs~h&8S`)dZ8fv%Gx~e&6Q8rjAds*G*hPYADuvI z65XQ>@1xllUUuC(3p#pHrT9z&R;hcW=2xK5Xipm42>bDGr&>?}QF9C$Njr6J6-uW) z(%ofbk(5o6JrK4fW38e~Vw#5!zgp){FbQF*qKhwHRNRe~qO2bdv^Ldc9Y zEF4W^b&y`Ij%U-Ln65QPXeQ!iii-mE1RgpBY6&ih*mugI0omS3&f(B~;ywGV-*zZ5=quIG_UEY8SLK!Az@K47PN1^q0F=R${xp!(S4(uIx qyup!jAqXe)0sfC)3Wc2(2U6l2zRSBj5dCpD&`YvcWPP>JSo0TdyA4JF literal 0 HcmV?d00001 diff --git a/public/icons/pwa-192x192.png b/public/icons/pwa-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..dbe68d0595c0920ca39de87681c56c4f25d8c188 GIT binary patch literal 659 zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE8Azrw%`pX1>H$6>u0ENCN^V3D|R%JWK`t%c` zjQ{)?f>~}@GiHhYmt+Du77PSfZ|uoQBIOeldW;6+3vs9&sj` zlhwhe_l}P3g2?~rI+h2lzWOH@Ijm<~E%t<2C)NSGMikL=OizB>f2=W6h^xJkT$+^e zy#CeeAD^V-r^oW%s9t^0`~982mRV)9m%aX$zSFwxnr6n_Z_K~`)!h(m@V#y_^9_T- zx=tZ?s|lP1OPEdbGKFH~=F1+?Teg|;jk2}0!v0Hsbt@PAi*o;Ybk?WUzF()GKDGY) z)%XoM`yWNspWN|p*7t=S9BX)@4WB+=|4Hrl1)pz*Sv}|Tg@uIAw5JD6;+r)6;Y*Qn i?<<_f_k(Q}T{Psk7)|9&PMRYP@`9(UpUXO@geCy#b@?y= literal 0 HcmV?d00001 diff --git a/public/icons/pwa-512x512.png b/public/icons/pwa-512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..661db4bca29cd930ed768779bf0cc9a8d8129d32 GIT binary patch literal 1856 zcmeHIZA_b06h8O%11NSdpn%NLqNp1nlx5l22&`KQrAmNd2e_5>O(6To7#5jAsI)H& zW-d-g=9I-{lx(1=WONR;MTK^3z=8;NfH)YoLWIFUieMI1{{c^TgRz|tN@GY@6bD}?}z2d<5pROv?m*aoS1r>uBz z`rhu>`h?yIM)ACO*%Y0;Saxy4=99Tn^?1JEt>v11hN1JJ(le`TuHi@R`j3p(-qfn* zkcgW^=UgdO>vt}mF>qAPSM}$ZD@{Q{HS-j|EQD$_GHpu|PoX0Zk7-{pjNgyeJ3b^S zU&6sWw*ysas*aDPlJ*%6O=yMkHKPY1haAipc+W*32K$pd+SkQd1S<=E3O8VP1!|Ga zb9B&}NzR;Y#u2222cj5IY+Poqcx>e;Q2g#K5FoIz7kAMiZk=p1E;rFNNZSOa=WT1v z)?9`XwZ2MQ+@TFyUT;;D#jgP@qA3yplLT+Tk4?&DFKyHB+1P}259fMPcyOk}S&zNr zoLZ#I{CO&yB`9&k6#;xT?d--7I9x$3#A3)RhLXzw*W_T&0ElgY?KGR01KeiRfmi`> z7x}@zj>k#s9}kTTPMk<%5xp;7ha~&7v(+EW`FclGB!c{H&NmR;FLZp1;l_k*9}ARM z7fhc=?Sx;xgrH1-qHK6K9LS-_)x0i7iH2OS`#%h_r)PG!pl>hwfhUUNXNU1fE}9E+ zUiBrX;jCmJ3{)tFe_Dzm3yBt}>z+U$V2qg}fTUnDCkdu7(Pdjlm#!B*v3I3-6VTn! z#RJ1JxHM*(pV;f4~I zC@<u5H z2Q!xs5`h|Jp$SitoTFl~(TxOa5%UW#pxe1<$>x!y)t?}y7!|aYHL~z~ldp)^q~82) zT>GqfKnqrhVX>LnW%5}a8H=+TAA;zgP(-Vb2&hUe>UEC#r|E8wXgAqSeoEodUkeXL e{V|DZ+LqBX@WTNRAt|ecuTTfi)z?A)xX@TSczLX8qr5pGdq#5QhMXrUt$}UsYFE$C485x$o7wH*q@e&OV9D{df08+`4~n-$cGwzm=of{d9Yo Q3((aJp00i_>zopr0IDW}-~a#s literal 0 HcmV?d00001 diff --git a/src/catalogue/bhf-eblup.ts b/src/catalogue/bhf-eblup.ts index 3cc1840..c253298 100644 --- a/src/catalogue/bhf-eblup.ts +++ b/src/catalogue/bhf-eblup.ts @@ -40,9 +40,9 @@ const entry: CatalogueEntry = { 'At least some sampled units in each area (out-of-sample: synthetic predictor only).', ], references: [ - 'Battese, G.E., Harter, R.M. & Fuller, W.A. (1988). JASA 83, 28–36.', - 'Rao & Molina (2015). Small Area Estimation, 2nd ed. Ch. 7.', - 'Molina, I. & Marhuenda, Y. (2015). The R Journal 7(1). [sae package]', + 'Battese, G.E., Harter, R.M. & Fuller, W.A. (1988). JASA 83, 28–36. https://doi.org/10.1080/01621459.1988.10477104', + 'Rao, J.N.K. & Molina, I. (2015). Small Area Estimation, 2nd ed. Wiley. Ch. 7. https://onlinelibrary.wiley.com/doi/book/10.1002/9781118735855', + 'Molina, I. & Marhuenda, Y. (2015). The R Journal 7(1). [sae package] https://doi.org/10.32614/RJ-2015-009', ], rTemplate: `# ============================================================ # Battese–Harter–Fuller Nested-Error EBLUP (Unit-Level) diff --git a/src/catalogue/direct.ts b/src/catalogue/direct.ts index 191b69a..823069a 100644 --- a/src/catalogue/direct.ts +++ b/src/catalogue/direct.ts @@ -36,8 +36,9 @@ const entry: CatalogueEntry = { 'Survey weights correctly reflect the sampling design.', ], references: [ - 'Kish, L. (1965). Survey Sampling. Wiley.', - 'Cochran, W.G. (1977). Sampling Techniques, 3rd ed. Wiley.', + 'Kish, L. (1965). Survey Sampling. Wiley. https://www.wiley.com/en-gb/Survey+Sampling-p-9780471489009', + 'Cochran, W.G. (1977). Sampling Techniques, 3rd ed. Wiley. https://www.wiley.com/en-gb/Sampling+Techniques%2C+3rd+Edition-p-9780471162407', + 'survey package for R (Lumley, T.). https://cran.r-project.org/package=survey', ], rTemplate: `# ============================================================ # Direct Estimator — Design-Based Benchmark diff --git a/src/catalogue/ebp-censuseb.ts b/src/catalogue/ebp-censuseb.ts index 798b285..baa1392 100644 --- a/src/catalogue/ebp-censuseb.ts +++ b/src/catalogue/ebp-censuseb.ts @@ -43,10 +43,10 @@ const entry: CatalogueEntry = { 'No informative sampling given the model covariates.', ], references: [ - 'Molina, I. & Rao, J.N.K. (2010). Canadian Journal of Statistics 38, 369–385.', + 'Molina, I. & Rao, J.N.K. (2010). Canadian Journal of Statistics 38, 369–385. https://doi.org/10.1002/cjs.10051', 'Corral, P., Molina, I., Cojocaru, A. & Segovia, S. (2022). Guidelines to SAE for Poverty Mapping. World Bank. http://hdl.handle.net/10986/37728', - 'Kreutzmann, A.-K. et al. (2019). The R Journal 11(1). [emdi package]', - 'povmap package: https://cran.r-project.org/package=povmap', + 'Kreutzmann, A.-K. et al. (2019). The R Journal 11(1). [emdi package] https://doi.org/10.32614/RJ-2019-057', + 'povmap package: CRAN. https://cran.r-project.org/package=povmap', ], caveats: [ 'Stata implementation requires v17+; use R (emdi/povmap) for Stata 14 users.', diff --git a/src/catalogue/ell.ts b/src/catalogue/ell.ts index 05e850d..a2d6e8b 100644 --- a/src/catalogue/ell.ts +++ b/src/catalogue/ell.ts @@ -41,9 +41,9 @@ const entry: CatalogueEntry = { 'Survey and census share comparable variable definitions and measurement periods.', ], references: [ - 'Elbers, C., Lanjouw, J. & Lanjouw, P. (2003). Econometrica 71(1), 355–364.', - 'Corral, P. et al. (2022). Guidelines to SAE for Poverty Mapping. World Bank.', - 'World Bank PovMap software: https://www.worldbank.org/en/data/datatopics/povmap', + 'Elbers, C., Lanjouw, J. & Lanjouw, P. (2003). Econometrica 71(1), 355–364. https://doi.org/10.1111/1468-0262.00416', + 'Corral, P. et al. (2022). Guidelines to SAE for Poverty Mapping. World Bank. http://hdl.handle.net/10986/37728', + 'World Bank PovMap software. https://www.worldbank.org/en/data/datatopics/povmap', ], caveats: [ 'EBP is statistically superior for most applications; prefer EBP unless required.', diff --git a/src/catalogue/fh-eblup.ts b/src/catalogue/fh-eblup.ts index 20bfb77..6590ad0 100644 --- a/src/catalogue/fh-eblup.ts +++ b/src/catalogue/fh-eblup.ts @@ -39,10 +39,10 @@ const entry: CatalogueEntry = { 'There are enough areas (m ≥ 20) for reliable variance component estimation.', ], references: [ - 'Fay, R.E. & Herriot, R.A. (1979). JASA 74, 269–277.', - 'Prasad, N. & Rao, J. (1990). JASA 85, 163–171.', - 'Rao & Molina (2015). Small Area Estimation, 2nd ed. Ch. 4.', - 'Molina, I. & Marhuenda, Y. (2015). The R Journal 7(1). [sae package]', + 'Fay, R.E. & Herriot, R.A. (1979). JASA 74, 269–277. https://doi.org/10.1080/01621459.1979.10481623', + 'Prasad, N. & Rao, J. (1990). JASA 85, 163–171. https://doi.org/10.1080/01621459.1990.10474803', + 'Rao, J.N.K. & Molina, I. (2015). Small Area Estimation, 2nd ed. Wiley. Ch. 4. https://onlinelibrary.wiley.com/doi/book/10.1002/9781118735855', + 'Molina, I. & Marhuenda, Y. (2015). The R Journal 7(1). [sae package] https://doi.org/10.32614/RJ-2015-009', ], rTemplate: `# ============================================================ # Fay–Herriot EBLUP (Area-Level) diff --git a/src/catalogue/glmm-binary.ts b/src/catalogue/glmm-binary.ts index 16c2b43..929f334 100644 --- a/src/catalogue/glmm-binary.ts +++ b/src/catalogue/glmm-binary.ts @@ -38,9 +38,9 @@ const entry: CatalogueEntry = { 'Units within each area are conditionally independent given the random effect.', ], references: [ - 'Jiang, J. & Lahiri, P. (2001). Ann. Inst. Statistical Mathematics 53, 217–243.', - 'Jiang, J. (2003). Journal of Statistical Planning and Inference 111, 117–127.', - 'FAO (2015). SAE Methods for Agricultural Surveys. Ch. 2.6.7.', + 'Jiang, J. & Lahiri, P. (2001). Ann. Inst. Statistical Mathematics 53, 217–243. https://doi.org/10.1023/A:1017553022248', + 'Jiang, J. (2003). Journal of Statistical Planning and Inference 111, 117–127. https://doi.org/10.1016/S0378-3758(02)00196-2', + 'FAO (2015). SAE Methods for Agricultural Surveys. Ch. 2.6.7. https://www.fao.org/3/i4818e/i4818e.pdf', ], rTemplate: `# ============================================================ # GLMM-EBP — Binary / Proportion (Logit) diff --git a/src/catalogue/glmm-count.ts b/src/catalogue/glmm-count.ts index 2ded779..ead3466 100644 --- a/src/catalogue/glmm-count.ts +++ b/src/catalogue/glmm-count.ts @@ -37,8 +37,8 @@ const entry: CatalogueEntry = { 'Area random effects are normally distributed on the log scale.', ], references: [ - 'Jiang, J. (2003). Journal of Statistical Planning and Inference 111, 117–127.', - 'FAO (2015). SAE Methods for Agricultural Surveys. Ch. 2.6.7.', + 'Jiang, J. (2003). Journal of Statistical Planning and Inference 111, 117–127. https://doi.org/10.1016/S0378-3758(02)00196-2', + 'FAO (2015). SAE Methods for Agricultural Surveys. Ch. 2.6.7. https://www.fao.org/3/i4818e/i4818e.pdf', ], rTemplate: `# ============================================================ # GLMM-EBP — Count Data (Poisson / Log Link) diff --git a/src/catalogue/greg.ts b/src/catalogue/greg.ts index 8349cf5..8b3e752 100644 --- a/src/catalogue/greg.ts +++ b/src/catalogue/greg.ts @@ -37,8 +37,8 @@ const entry: CatalogueEntry = { 'Survey weights are correct.', ], references: [ - 'Rao, J.N.K. & Molina, I. (2015). Small Area Estimation, 2nd ed. Wiley. Ch. 3.', - 'FAO (2015). Spatial Disaggregation and SAE Methods for Agricultural Surveys. Ch. 2.3.', + 'Rao, J.N.K. & Molina, I. (2015). Small Area Estimation, 2nd ed. Wiley. Ch. 3. https://onlinelibrary.wiley.com/doi/book/10.1002/9781118735855', + 'FAO (2015). SAE Methods for Agricultural Surveys. Ch. 2.3. https://www.fao.org/3/i4818e/i4818e.pdf', ], rTemplate: `# ============================================================ # GREG — Generalised Regression Estimator diff --git a/src/catalogue/hb-fh.ts b/src/catalogue/hb-fh.ts index 85fba1a..d2c29a1 100644 --- a/src/catalogue/hb-fh.ts +++ b/src/catalogue/hb-fh.ts @@ -41,9 +41,9 @@ const entry: CatalogueEntry = { 'Likelihood model (Normal/Beta/Poisson) suits the data.', ], references: [ - 'Rao & Molina (2015). Small Area Estimation, 2nd ed. Ch. 10.', - 'Datta, G.S. & Ghosh, M. (1991). Annals of Statistics 19, 1748–1770.', - 'saeHB package: CRAN, https://cran.r-project.org/package=saeHB', + 'Rao, J.N.K. & Molina, I. (2015). Small Area Estimation, 2nd ed. Wiley. Ch. 10. https://onlinelibrary.wiley.com/doi/book/10.1002/9781118735855', + 'Datta, G.S. & Ghosh, M. (1991). Annals of Statistics 19, 1748–1770. https://doi.org/10.1214/aos/1176348381', + 'saeHB package: CRAN. https://cran.r-project.org/package=saeHB', ], caveats: [ 'MCMC can be slow for many areas or complex models.', diff --git a/src/catalogue/hb-unit.ts b/src/catalogue/hb-unit.ts index 906237f..cac529c 100644 --- a/src/catalogue/hb-unit.ts +++ b/src/catalogue/hb-unit.ts @@ -41,9 +41,9 @@ const entry: CatalogueEntry = { 'The chosen likelihood (Normal/Beta/Poisson) suits the data.', ], references: [ - 'Rao & Molina (2015). Small Area Estimation, 2nd ed. Ch. 10–11.', - 'Datta, G.S. & Ghosh, M. (1991). Annals of Statistics 19, 1748–1770.', - 'saeHB package: https://cran.r-project.org/package=saeHB', + 'Rao, J.N.K. & Molina, I. (2015). Small Area Estimation, 2nd ed. Wiley. Ch. 10–11. https://onlinelibrary.wiley.com/doi/book/10.1002/9781118735855', + 'Datta, G.S. & Ghosh, M. (1991). Annals of Statistics 19, 1748–1770. https://doi.org/10.1214/aos/1176348381', + 'saeHB package: CRAN. https://cran.r-project.org/package=saeHB', ], caveats: [ 'MCMC is computationally intensive for large areas or complex models.', diff --git a/src/catalogue/m-quantile.ts b/src/catalogue/m-quantile.ts index 059f597..70de4d1 100644 --- a/src/catalogue/m-quantile.ts +++ b/src/catalogue/m-quantile.ts @@ -42,9 +42,9 @@ const entry: CatalogueEntry = { 'Population means of auxiliary variables are known for all target areas.', ], references: [ - 'Chambers, R. & Tzavidis, N. (2006). Biometrika 93, 255–268.', - 'Marchetti, S., Tzavidis, N. & Pratesi, M. (2012). CSDA 56, 2889–2902.', - 'FAO (2015). SAE Methods for Agricultural Surveys. Ch. 2.5.3.', + 'Chambers, R. & Tzavidis, N. (2006). Biometrika 93, 255–268. https://doi.org/10.1093/biomet/93.2.255', + 'Marchetti, S., Tzavidis, N. & Pratesi, M. (2012). CSDA 56, 2889–2902. https://doi.org/10.1016/j.csda.2011.10.017', + 'FAO (2015). SAE Methods for Agricultural Surveys. Ch. 2.5.3. https://www.fao.org/3/i4818e/i4818e.pdf', ], rTemplate: `# ============================================================ # M-Quantile Estimator (Unit-Level, Robust) diff --git a/src/catalogue/mqgwr.ts b/src/catalogue/mqgwr.ts index e275f81..007e3ba 100644 --- a/src/catalogue/mqgwr.ts +++ b/src/catalogue/mqgwr.ts @@ -40,8 +40,8 @@ const entry: CatalogueEntry = { 'Coordinates (centroids) are available for sampled and non-sampled areas.', ], references: [ - 'Salvati, N. et al. (2012). CSDA 56, 2875–2888.', - 'FAO (2015). SAE Methods for Agricultural Surveys. Ch. 2.5.4.', + 'Salvati, N. et al. (2012). CSDA 56, 2875–2888. https://doi.org/10.1016/j.csda.2011.11.006', + 'FAO (2015). SAE Methods for Agricultural Surveys. Ch. 2.5.4. https://www.fao.org/3/i4818e/i4818e.pdf', ], rTemplate: `# ============================================================ # M-Quantile GWR (Unit-Level, Robust + Spatial) diff --git a/src/catalogue/reblup.ts b/src/catalogue/reblup.ts index 7a56672..86f3bb6 100644 --- a/src/catalogue/reblup.ts +++ b/src/catalogue/reblup.ts @@ -39,8 +39,8 @@ const entry: CatalogueEntry = { 'A small proportion of units are outliers; Huber tuning constant c = 1.345 is appropriate.', ], references: [ - 'Sinha, S.K. & Rao, J.N.K. (2009). Canadian Journal of Statistics 37, 381–399.', - 'FAO (2015). SAE Methods for Agricultural Surveys. Ch. 5.2.2.', + 'Sinha, S.K. & Rao, J.N.K. (2009). Canadian Journal of Statistics 37, 381–399. https://doi.org/10.1002/cjs.10007', + 'FAO (2015). SAE Methods for Agricultural Surveys. Ch. 5.2.2. https://www.fao.org/3/i4818e/i4818e.pdf', ], rTemplate: `# ============================================================ # Robust EBLUP (REBLUP) — Sinha–Rao diff --git a/src/catalogue/robust-fh.ts b/src/catalogue/robust-fh.ts index 28f74a3..4bf0db4 100644 --- a/src/catalogue/robust-fh.ts +++ b/src/catalogue/robust-fh.ts @@ -35,9 +35,9 @@ const entry: CatalogueEntry = { 'A small proportion of areas are outliers; the majority follow the FH model.', ], references: [ - 'Chambers, R. & Tzavidis, N. (2006). Biometrika 93, 255–268.', - 'Sinha, S.K. & Rao, J.N.K. (2009). Canadian Journal of Statistics 37, 381–399.', - 'Rao & Molina (2015). Small Area Estimation, 2nd ed. Ch. 7.', + 'Chambers, R. & Tzavidis, N. (2006). Biometrika 93, 255–268. https://doi.org/10.1093/biomet/93.2.255', + 'Sinha, S.K. & Rao, J.N.K. (2009). Canadian Journal of Statistics 37, 381–399. https://doi.org/10.1002/cjs.10007', + 'Rao, J.N.K. & Molina, I. (2015). Small Area Estimation, 2nd ed. Wiley. Ch. 7. https://onlinelibrary.wiley.com/doi/book/10.1002/9781118735855', ], rTemplate: `# ============================================================ # Robust Fay–Herriot diff --git a/src/catalogue/spatial-fh.ts b/src/catalogue/spatial-fh.ts index c13ee17..58df2ee 100644 --- a/src/catalogue/spatial-fh.ts +++ b/src/catalogue/spatial-fh.ts @@ -37,10 +37,10 @@ const entry: CatalogueEntry = { 'The contiguity matrix correctly represents neighbourhood relationships.', ], references: [ - 'Pratesi, M. & Salvati, N. (2008). Statistical Methods and Applications 17, 113–141.', - 'Singh, B. et al. (2005). Survey Methodology 31(1), 33–40.', - 'Rao & Molina (2015). Small Area Estimation, 2nd ed. Ch. 8.', - 'FAO (2015). SAE Methods for Agricultural Surveys. Ch. 2.4.3.', + 'Pratesi, M. & Salvati, N. (2008). Statistical Methods and Applications 17, 113–141. https://doi.org/10.1007/s10260-006-0031-z', + 'Singh, B. et al. (2005). Survey Methodology 31(1), 33–40. https://www150.statcan.gc.ca/n1/pub/12-001-x/2005001/article/8036-eng.pdf', + 'Rao, J.N.K. & Molina, I. (2015). Small Area Estimation, 2nd ed. Wiley. Ch. 8. https://onlinelibrary.wiley.com/doi/book/10.1002/9781118735855', + 'FAO (2015). SAE Methods for Agricultural Surveys. Ch. 2.4.3. https://www.fao.org/3/i4818e/i4818e.pdf', ], caveats: [ 'Constructing the contiguity matrix requires GIS boundary files or coordinates.', diff --git a/src/catalogue/two-part-zinfl.ts b/src/catalogue/two-part-zinfl.ts index 179a786..de12727 100644 --- a/src/catalogue/two-part-zinfl.ts +++ b/src/catalogue/two-part-zinfl.ts @@ -37,9 +37,9 @@ const entry: CatalogueEntry = { 'Area random effects in both parts may be correlated.', ], references: [ - 'Pfeffermann, D. et al. (2008). Survey Methodology 34, 105–116.', - 'Chandra, H. & Chambers, R. (2014). Computational Statistics 29, 1023–1050.', - 'FAO (2015). SAE Methods for Agricultural Surveys. Ch. 8.', + 'Pfeffermann, D. et al. (2008). Survey Methodology 34, 105–116. https://www150.statcan.gc.ca/n1/pub/12-001-x/2008001/article/10612-eng.pdf', + 'Chandra, H. & Chambers, R. (2014). Computational Statistics 29, 1023–1050. https://doi.org/10.1007/s00180-013-0409-8', + 'FAO (2015). SAE Methods for Agricultural Surveys. Ch. 8. https://www.fao.org/3/i4818e/i4818e.pdf', ], rTemplate: `# ============================================================ # Two-Part / Zero-Inflated Model (Unit-Level) diff --git a/vite.config.ts b/vite.config.ts index e4f4cfb..d3238ed 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -21,15 +21,24 @@ export default defineConfig({ start_url: '/SAE_Syntax_Generator/', icons: [ { - src: 'icons/icon-192x192.svg', + src: 'icons/pwa-64x64.png', + sizes: '64x64', + type: 'image/png', + }, + { + src: 'icons/pwa-192x192.png', sizes: '192x192', - type: 'image/svg+xml', - purpose: 'any', + type: 'image/png', + }, + { + src: 'icons/pwa-512x512.png', + sizes: '512x512', + type: 'image/png', }, { - src: 'icons/icon-512x512.svg', + src: 'icons/maskable-icon-512x512.png', sizes: '512x512', - type: 'image/svg+xml', + type: 'image/png', purpose: 'maskable', }, ], From 6a72e6e2d030d7173a0f4cc2d438afa8ce7684bf Mon Sep 17 00:00:00 2001 From: bakodramane Date: Thu, 4 Jun 2026 15:04:55 +0200 Subject: [PATCH 2/2] chore: add lighthouse-report.json to .gitignore Co-Authored-By: Claude Sonnet 4.6 --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index c2aba67..e25c93a 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,7 @@ test-results/ # Logs *.log npm-debug.log* + +# Lighthouse reports (local only) +lighthouse-report.json +lighthouse-report.html