Compare commits

...

16 commits

Author SHA1 Message Date
a08b5d2ae0 Render more
Some checks failed
Build and publish Docker image / build-and-push (push) Failing after 5m19s
CI / Check (push) Failing after 5m41s
2026-05-13 08:00:27 +01:00
bd6b511f16 Fmt 2026-05-13 08:00:12 +01:00
63713c3a2b good 2026-05-12 22:30:36 +01:00
81a16f543c lgtm 2026-05-12 22:13:07 +01:00
11711c57e6 lgtm 2026-05-12 22:00:56 +01:00
8708bf000d lgtm 2026-05-12 08:05:29 +01:00
a9e5a8ad96 Update storyboard 2026-05-12 07:44:47 +01:00
1483dc5224 gitignore 2026-05-12 06:45:21 +01:00
7ca29c2d81 Fix OOMs 2026-05-12 06:44:54 +01:00
b580c51b6d Add R5 validation 2026-05-12 06:44:15 +01:00
f2a2651b8a LGTM 2026-05-11 21:38:26 +01:00
9248e26af2 Move map assets out of CI 2026-05-10 15:05:42 +01:00
a5f2e6eabb . 2026-05-10 14:57:15 +01:00
ee231d2ee5 Make vide work with prod 2026-05-10 14:55:53 +01:00
3debacab4f Rust things 2026-05-10 14:55:43 +01:00
fc10381692 Rerun data pipelines 2026-05-10 14:49:53 +01:00
1036 changed files with 44926 additions and 3079 deletions

View file

@ -12,3 +12,4 @@ analyses/
property-data
manual-data
!property-data/arcgis_data.parquet
Dockerfile

View file

@ -17,12 +17,6 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- name: Install uv
run: curl -LsSf https://astral.sh/uv/install.sh | sh
- name: Download map assets (fonts, sprites, twemoji)
run: uv run python -m pipeline.download.map_assets --output frontend/public/assets
- name: Install Docker CLI
run: |
ARCH=$(uname -m)
@ -84,4 +78,3 @@ jobs:
${{ env.REGISTRY }}/${{ steps.tags.outputs.repo }}-screenshot:sha-${{ steps.tags.outputs.sha_short }}
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ steps.tags.outputs.repo }}-screenshot:buildcache
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ steps.tags.outputs.repo }}-screenshot:buildcache,mode=max

8
.gitignore vendored
View file

@ -6,6 +6,14 @@
server-rs/target
.task
frontend/public/assets/*
!frontend/public/assets/fonts/
!frontend/public/assets/fonts/**
!frontend/public/assets/sprites/
!frontend/public/assets/sprites/**
!frontend/public/assets/twemoji/
!frontend/public/assets/twemoji/**
!frontend/public/assets/poi-icons/
!frontend/public/assets/poi-icons/**
frontend/public/assets/.done
server-rs/logs
video/auth.*

View file

@ -8,5 +8,6 @@
"**/target": true,
"frontend/dist": true,
"**/.task": true
}
},
"python.terminal.activateEnvironment": false
}

View file

@ -1,8 +1,5 @@
# Data pipeline — download sources and build postcode.parquet + properties.parquet
#
# Usage:
# make -f Makefile.data prepare # Build all parquets (+ all deps)
# make -f Makefile.data tiles # Download UK map tiles
#
# Or include from the main Makefile and use targets directly.
@ -29,10 +26,11 @@ PROPERTIES_PQ := $(DATA_DIR)/properties.parquet
MERGE_STAMP := $(DATA_DIR)/.merge_done
PRICE_INDEX := $(DATA_DIR)/price_index.parquet
PRICES_STAMP := $(DATA_DIR)/.prices_done
EPC := $(MANUAL_DATA)/certificates.csv
EPC := $(MANUAL_DATA)/domestic-csv.zip
ETHNICITY := $(DATA_DIR)/ethnicity_by_la.parquet
CRIME_DIR := $(MANUAL_DATA)/crime
CRIME_DIR := $(DATA_DIR)/crime
CRIME := $(DATA_DIR)/crime_by_lsoa.parquet
CRIME_STAMP := $(CRIME_DIR)/.downloaded
NOISE := $(DATA_DIR)/road_noise.parquet
OFSTED := $(DATA_DIR)/ofsted.parquet
NAPTAN := $(DATA_DIR)/naptan.parquet
@ -42,42 +40,56 @@ RENTAL := $(DATA_DIR)/rental_prices.parquet
INSPIRE_DIR := $(DATA_DIR)/inspire
OA_BOUNDARIES := $(DATA_DIR)/oa_boundaries.gpkg
UPRN_LOOKUP := $(DATA_DIR)/uprn_lookup.parquet
PC_BOUNDARIES := $(MANUAL_DATA)/postcode_boundaries
PC_BOUNDARIES := $(DATA_DIR)/postcode_boundaries
TRANSIT_DIR := $(DATA_DIR)/transit
TRANSIT_STAMP := $(TRANSIT_DIR)/.done
R5_NETWORK_CACHE := $(DATA_DIR)/r5-network/network.dat
GREENSPACE := $(DATA_DIR)/greenspace_water.parquet
OS_GREENSPACE := $(DATA_DIR)/os_greenspace.parquet
PBF := $(DATA_DIR)/england-latest.osm.pbf
FR_TOW := $(DATA_DIR)/FR_TOW_V1_ALL.zip
TREE_DENSITY_PC := $(DATA_DIR)/tree_density_by_postcode.parquet
TREE_DENSITY_STREETS := $(DATA_DIR)/tree_density_by_street.parquet
TREE_DENSITY_ADDR := $(DATA_DIR)/tree_density_by_address.parquet
OFS_REGISTER := $(DATA_DIR)/ofs_register.xlsx
PLACES := $(DATA_DIR)/places.parquet
LSOA_POP := $(DATA_DIR)/lsoa_population.parquet
MEDIAN_AGE := $(DATA_DIR)/median_age.parquet
ELECTION := $(DATA_DIR)/election_results.parquet
ENGLAND_BOUNDARY := $(DATA_DIR)/england_boundary.geojson
RM_OUTCODES := frontend/src/lib/rightmove-outcodes.json
MAP_ASSETS_DIR := frontend/public/assets
# Sentinel files for directory targets (Make doesn't track directories well)
INSPIRE_STAMP := $(INSPIRE_DIR)/.done
MAP_ASSETS_STAMP := $(MAP_ASSETS_DIR)/.done
PMTILES_VERSION := 1.22.3
POI_PROXIMITY_DEPS := pipeline/transform/poi_proximity.py pipeline/utils/poi_counts.py
MERGE_DEPS := pipeline/transform/merge.py
TREE_DENSITY_DEPS := pipeline/transform/tree_density.py
# ── Phony aliases ─────────────────────────────────────────────────────────────
.PHONY: prepare merge tiles \
download-arcgis download-price-paid download-deprivation download-ethnicity \
download-naptan download-pois download-grocery-retail-points download-ofsted download-broadband download-rental-prices \
download-postcodes download-noise download-inspire \
download-oa-boundaries download-uprn-lookup download-transit-network download-greenspace download-os-greenspace download-pbf download-places download-lsoa-population download-median-age download-england-boundary download-rightmove-outcodes \
download-postcodes download-noise download-inspire download-crime \
download-oa-boundaries download-uprn-lookup download-transit-network download-greenspace download-os-greenspace download-pbf download-fr-tow download-ofs-register download-places download-lsoa-population download-median-age download-england-boundary download-rightmove-outcodes \
download-map-assets \
transform-pois transform-epc-pp transform-crime transform-poi-proximity \
transform-school-proximity transform-postcode-boundaries \
generate-postcode-boundaries
transform-school-proximity transform-tree-density \
generate-postcode-boundaries generate-travel-times
prepare: $(PRICES_STAMP)
prepare: $(PRICES_STAMP) download-places tiles generate-postcode-boundaries download-map-assets generate-travel-times
merge: $(MERGE_STAMP)
tiles: $(TILES)
download-arcgis: $(ARCGIS)
download-price-paid: $(PRICE_PAID)
download-deprivation: $(IOD)
download-ethnicity: $(ETHNICITY)
download-crime: $(CRIME_STAMP)
download-naptan: $(NAPTAN)
download-pois: $(POIS_RAW)
download-grocery-retail-points: $(GROCERY_RETAIL_POINTS)
@ -93,24 +105,33 @@ download-transit-network: $(TRANSIT_STAMP)
download-greenspace: $(GREENSPACE)
download-os-greenspace: $(OS_GREENSPACE)
download-pbf: $(PBF)
download-fr-tow: $(FR_TOW)
download-ofs-register: $(OFS_REGISTER)
download-places: $(PLACES)
download-lsoa-population: $(LSOA_POP)
download-median-age: $(MEDIAN_AGE)
download-election-results: $(ELECTION)
download-england-boundary: $(ENGLAND_BOUNDARY)
download-rightmove-outcodes: $(RM_OUTCODES)
download-map-assets: $(MAP_ASSETS_STAMP)
transform-pois: $(POIS_FILTERED)
transform-epc-pp: $(EPC_PP)
transform-crime: $(CRIME)
transform-poi-proximity: $(POI_PROXIMITY)
transform-school-proximity: $(SCHOOL_PROX)
transform-postcode-boundaries: $(PC_BOUNDARIES)
transform-tree-density: $(TREE_DENSITY_ADDR)
generate-postcode-boundaries: $(OA_BOUNDARIES) $(INSPIRE_STAMP) $(UPRN_LOOKUP)
uv run python -m pipeline.transform.postcode_boundaries \
--uprn $(UPRN_LOOKUP) \
--oa-boundaries $(OA_BOUNDARIES) \
--inspire $(INSPIRE_DIR) \
--output $(PC_BOUNDARIES)
generate-travel-times: $(ARCGIS) $(PLACES) $(PBF) download-transit-network
@if [ -f "$(R5_NETWORK_CACHE)" ] && { [ "$(PBF)" -nt "$(R5_NETWORK_CACHE)" ] || [ "$(TRANSIT_STAMP)" -nt "$(R5_NETWORK_CACHE)" ]; }; then \
echo "R5 inputs are newer than $(R5_NETWORK_CACHE); deleting stale cache"; \
rm -f "$(R5_NETWORK_CACHE)"; \
fi
./r5-java/run.sh
# ── Downloads ─────────────────────────────────────────────────────────────────
@ -121,10 +142,10 @@ $(TILES):
$(EPC):
@echo ""
@echo "=== EPC dataset not found ==="
@echo "The EPC certificates file is required: $@"
@echo "The EPC certificates archive is required: $@"
@echo ""
@echo "To obtain it, register at https://epc.opendatacommunities.org/login"
@echo "and place certificates.csv in manual-data/"
@echo "To obtain it, register at https://get-energy-performance-data.communities.gov.uk/filter-properties?property_type=domestic"
@echo "and place domestic-csv.zip in manual-data/"
@echo ""
@exit 1
@ -140,6 +161,10 @@ $(IOD):
$(ETHNICITY):
uv run python -m pipeline.download.ethnicity --output $@
$(CRIME_STAMP):
uv run python -m pipeline.download.crime --output $(CRIME_DIR)
@touch $@
$(NAPTAN):
uv run python -m pipeline.download.naptan --output $@
@ -148,6 +173,16 @@ $(PBF):
curl -L -o $@.tmp https://download.geofabrik.de/europe/united-kingdom/england-latest.osm.pbf
mv $@.tmp $@
$(FR_TOW):
@mkdir -p $(DATA_DIR)
curl -L -A "Mozilla/5.0" -o $@.tmp "https://www.mediafire.com/file_premium/p5fve6wswwwjqrq/FR_TOW_V1_ALL.zip/file"
mv $@.tmp $@
$(OFS_REGISTER):
@mkdir -p $(DATA_DIR)
curl -fL -A "Mozilla/5.0" -o $@.tmp https://register-api.officeforstudents.org.uk/api/Download/
mv $@.tmp $@
$(POIS_RAW): $(PBF) $(ENGLAND_BOUNDARY)
uv run python -m pipeline.download.pois --output $@ --pbf $(PBF) --boundary $(ENGLAND_BOUNDARY)
@ -189,8 +224,8 @@ $(GREENSPACE): $(PBF)
$(OS_GREENSPACE):
uv run python -m pipeline.download.os_greenspace --output $@
$(PLACES): $(PBF) $(ENGLAND_BOUNDARY) $(NAPTAN)
uv run python -m pipeline.download.places --output $@ --pbf $(PBF) --boundary $(ENGLAND_BOUNDARY) --naptan $(NAPTAN)
$(PLACES): $(PBF) $(ENGLAND_BOUNDARY) $(NAPTAN) $(OFS_REGISTER) $(ARCGIS)
uv run python -m pipeline.download.places --output $@ --pbf $(PBF) --boundary $(ENGLAND_BOUNDARY) --naptan $(NAPTAN) --university-register $(OFS_REGISTER) --postcodes $(ARCGIS)
$(LSOA_POP):
uv run python -m pipeline.download.lsoa_population --output $@
@ -208,6 +243,10 @@ $(ENGLAND_BOUNDARY):
$(RM_OUTCODES): $(MERGE_STAMP)
uv run python -m pipeline.download.rightmove_outcodes --postcodes $(POSTCODES_PQ) --output $@
$(MAP_ASSETS_STAMP):
uv run python -m pipeline.download.map_assets --output $(MAP_ASSETS_DIR)
@touch $@
# ── Transforms ────────────────────────────────────────────────────────────────
$(POIS_FILTERED): $(POIS_RAW) $(NAPTAN) $(GROCERY_RETAIL_POINTS) $(ENGLAND_BOUNDARY)
@ -216,23 +255,24 @@ $(POIS_FILTERED): $(POIS_RAW) $(NAPTAN) $(GROCERY_RETAIL_POINTS) $(ENGLAND_BOUND
$(EPC_PP): $(PRICE_PAID) $(EPC)
uv run python -m pipeline.transform.join_epc_pp --epc $(EPC) --price-paid $(PRICE_PAID) --output $@
$(CRIME):
@if [ ! -d "$(CRIME_DIR)" ]; then \
echo ""; \
echo "=== Crime dataset not found ==="; \
echo "Place police.uk crime CSVs in $(CRIME_DIR)/"; \
echo "Download from https://data.police.uk/data/"; \
echo ""; \
exit 1; \
fi
$(CRIME): $(CRIME_STAMP)
uv run python -m pipeline.transform.crime --input $(CRIME_DIR) --output $@
$(POI_PROXIMITY): $(ARCGIS) $(POIS_FILTERED) $(OS_GREENSPACE)
$(POI_PROXIMITY): $(ARCGIS) $(POIS_FILTERED) $(OS_GREENSPACE) $(POI_PROXIMITY_DEPS)
uv run python -m pipeline.transform.poi_proximity --arcgis $(ARCGIS) --pois $(POIS_FILTERED) --greenspace $(OS_GREENSPACE) --output $@
$(SCHOOL_PROX): $(OFSTED) $(ARCGIS)
uv run python -m pipeline.transform.school_proximity --ofsted $(OFSTED) --arcgis $(ARCGIS) --output $@
$(TREE_DENSITY_ADDR): $(FR_TOW) $(ARCGIS) $(PRICE_PAID) $(TREE_DENSITY_DEPS)
uv run python -m pipeline.transform.tree_density \
--tow-zip $(FR_TOW) \
--arcgis $(ARCGIS) \
--price-paid $(PRICE_PAID) \
--output-postcodes $(TREE_DENSITY_PC) \
--output-streets $(TREE_DENSITY_STREETS) \
--output-addresses $@
# Postcode boundaries require manual generation — fail with instructions
$(PC_BOUNDARIES):
@echo ""
@ -251,7 +291,7 @@ $(PC_BOUNDARIES):
# ── Final merge → postcode.parquet + properties.parquet ──────────────────────
$(MERGE_STAMP): $(EPC_PP) $(ARCGIS) $(IOD) $(POI_PROXIMITY) \
$(ETHNICITY) $(CRIME) $(NOISE) $(SCHOOL_PROX) $(BROADBAND) $(RENTAL) $(LSOA_POP) $(MEDIAN_AGE) $(ELECTION)
$(ETHNICITY) $(CRIME) $(NOISE) $(SCHOOL_PROX) $(BROADBAND) $(RENTAL) $(LSOA_POP) $(MEDIAN_AGE) $(ELECTION) $(TREE_DENSITY_ADDR) $(MERGE_DEPS)
uv run python -m pipeline.transform.merge \
--epc-pp $(EPC_PP) \
--arcgis $(ARCGIS) \
@ -266,6 +306,7 @@ $(MERGE_STAMP): $(EPC_PP) $(ARCGIS) $(IOD) $(POI_PROXIMITY) \
--lsoa-population $(LSOA_POP) \
--median-age $(MEDIAN_AGE) \
--election-results $(ELECTION) \
--tree-density-addresses $(TREE_DENSITY_ADDR) \
--output-postcodes $(POSTCODES_PQ) \
--output-properties $(PROPERTIES_PQ)
@touch $@

View file

@ -69,11 +69,10 @@ property-data/postcode_boundaries/
property-data/travel-times/
```
Most data can be downloaded or generated through `Makefile.data`. Some inputs
are deliberately manual:
Most data, including police.uk crime archives, can be downloaded or generated
through `Makefile.data`. Some inputs are deliberately manual:
- `manual-data/certificates.csv` from the EPC register
- `manual-data/crime/` CSV exports from police.uk
- `manual-data/domestic-csv.zip` from the EPC register
- postcode boundaries, generated from OA boundaries, INSPIRE polygons, and UPRN
lookup data
@ -94,8 +93,7 @@ The running server expects the same structure under
Travel times are built separately because they are expensive:
```bash
make -f Makefile.data download-transit-network
./r5-java/run.sh --threads 8 --heap 40g
make -f Makefile.data generate-travel-times
```
For a quick R5 smoke test:

File diff suppressed because one or more lines are too long

View file

@ -12,11 +12,7 @@ step() {
step "Python lint: ruff" uv run ruff check .
step "Python dependency lint: deptry" uv run deptry .
step "Python unit tests" uv run pytest \
pipeline/utils/test_haversine.py \
pipeline/utils/test_poi_counts.py \
pipeline/download/test_naptan.py \
pipeline/transform/postcode_boundaries/test_postcode_boundaries.py
step "Python unit tests" uv run pytest pipeline
(
cd "$ROOT_DIR/frontend"

View file

@ -6,6 +6,8 @@ services:
server:
image: rust:1.84
init: true
tty: true
stdin_open: true
working_dir: /app/server-rs
command: >
bash -c "

View file

@ -0,0 +1,3 @@

Sans Italic 10240-10495

View file

@ -0,0 +1,3 @@

Sans Italic 10496-10751

View file

@ -0,0 +1,3 @@

Sans Italic 10752-11007

View file

@ -0,0 +1,3 @@

Sans Italic 11008-11263

View file

@ -0,0 +1,3 @@

Sans Italic 12032-12287

View file

@ -0,0 +1,3 @@

Sans Italic 12288-12543

View file

@ -0,0 +1,3 @@

Sans Italic 12544-12799

View file

@ -0,0 +1,3 @@

Sans Italic 12800-13055

View file

@ -0,0 +1,3 @@

Sans Italic 13056-13311

View file

@ -0,0 +1,3 @@

Sans Italic 13312-13567

View file

@ -0,0 +1,3 @@

Sans Italic 13568-13823

View file

@ -0,0 +1,3 @@

Sans Italic 13824-14079

View file

@ -0,0 +1,3 @@

Sans Italic 14080-14335

View file

@ -0,0 +1,3 @@

Sans Italic 14336-14591

View file

@ -0,0 +1,3 @@

Sans Italic 14592-14847

View file

@ -0,0 +1,3 @@

Sans Italic 14848-15103

View file

@ -0,0 +1,3 @@

Sans Italic 15104-15359

View file

@ -0,0 +1,3 @@

Sans Italic 1536-1791

View file

@ -0,0 +1,3 @@

Sans Italic 15360-15615

View file

@ -0,0 +1,3 @@

Sans Italic 15616-15871

View file

@ -0,0 +1,3 @@

Sans Italic 15872-16127

View file

@ -0,0 +1,3 @@

Sans Italic 16128-16383

View file

@ -0,0 +1,3 @@

Sans Italic 16384-16639

View file

@ -0,0 +1,3 @@

Sans Italic 16640-16895

View file

@ -0,0 +1,3 @@

Sans Italic 16896-17151

View file

@ -0,0 +1,3 @@

Sans Italic 17152-17407

View file

@ -0,0 +1,3 @@

Sans Italic 17408-17663

View file

@ -0,0 +1,3 @@

Sans Italic 17664-17919

View file

@ -0,0 +1,3 @@

Sans Italic 1792-2047

View file

@ -0,0 +1,3 @@

Sans Italic 17920-18175

View file

@ -0,0 +1,3 @@

Sans Italic 18176-18431

View file

@ -0,0 +1,3 @@

Sans Italic 18432-18687

View file

@ -0,0 +1,3 @@

Sans Italic 18688-18943

View file

@ -0,0 +1,3 @@

Sans Italic 18944-19199

View file

@ -0,0 +1,3 @@

Sans Italic 19200-19455

View file

@ -0,0 +1,3 @@

Sans Italic 19456-19711

View file

@ -0,0 +1,3 @@

Sans Italic 19712-19967

View file

@ -0,0 +1,3 @@

Sans Italic 19968-20223

View file

@ -0,0 +1,3 @@

Sans Italic 20224-20479

View file

@ -0,0 +1,3 @@

Sans Italic 2048-2303

View file

@ -0,0 +1,3 @@

Sans Italic 20480-20735

View file

@ -0,0 +1,3 @@

Sans Italic 20736-20991

View file

@ -0,0 +1,3 @@

Sans Italic 20992-21247

View file

@ -0,0 +1,3 @@

Sans Italic 21248-21503

View file

@ -0,0 +1,3 @@

Sans Italic 21504-21759

View file

@ -0,0 +1,3 @@

Sans Italic 21760-22015

View file

@ -0,0 +1,3 @@

Sans Italic 22016-22271

View file

@ -0,0 +1,3 @@

Sans Italic 22272-22527

View file

@ -0,0 +1,3 @@

Sans Italic 22528-22783

View file

@ -0,0 +1,3 @@

Sans Italic 22784-23039

View file

@ -0,0 +1,3 @@

Sans Italic 2304-2559

View file

@ -0,0 +1,3 @@

Sans Italic 23040-23295

View file

@ -0,0 +1,3 @@

Sans Italic 23296-23551

View file

@ -0,0 +1,3 @@

Sans Italic 23552-23807

View file

@ -0,0 +1,3 @@

Sans Italic 23808-24063

View file

@ -0,0 +1,3 @@

Sans Italic 24064-24319

View file

@ -0,0 +1,3 @@

Sans Italic 24320-24575

View file

@ -0,0 +1,3 @@

Sans Italic 24576-24831

View file

@ -0,0 +1,3 @@

Sans Italic 24832-25087

View file

@ -0,0 +1,3 @@

Sans Italic 25088-25343

View file

@ -0,0 +1,3 @@

Sans Italic 25344-25599

View file

@ -0,0 +1,3 @@

Sans Italic 2560-2815

View file

@ -0,0 +1,3 @@

Sans Italic 25600-25855

View file

@ -0,0 +1,3 @@

Sans Italic 25856-26111

View file

@ -0,0 +1,3 @@

Sans Italic 26112-26367

View file

@ -0,0 +1,3 @@

Sans Italic 26368-26623

View file

@ -0,0 +1,3 @@

Sans Italic 26624-26879

View file

@ -0,0 +1,3 @@

Sans Italic 26880-27135

View file

@ -0,0 +1,3 @@

Sans Italic 27136-27391

View file

@ -0,0 +1,3 @@

Sans Italic 27392-27647

View file

@ -0,0 +1,3 @@

Sans Italic 27648-27903

View file

@ -0,0 +1,3 @@

Sans Italic 27904-28159

View file

@ -0,0 +1,3 @@

Sans Italic 2816-3071

View file

@ -0,0 +1,3 @@

Sans Italic 28160-28415

View file

@ -0,0 +1,3 @@

Sans Italic 28416-28671

View file

@ -0,0 +1,3 @@

Sans Italic 28672-28927

View file

@ -0,0 +1,3 @@

Sans Italic 28928-29183

View file

@ -0,0 +1,3 @@

Sans Italic 29184-29439

View file

@ -0,0 +1,3 @@

Sans Italic 29440-29695

View file

@ -0,0 +1,3 @@

Sans Italic 29696-29951

View file

@ -0,0 +1,3 @@

Sans Italic 29952-30207

View file

@ -0,0 +1,3 @@

Sans Italic 30208-30463

View file

@ -0,0 +1,3 @@

Sans Italic 30464-30719

View file

@ -0,0 +1,3 @@

Sans Italic 3072-3327

Some files were not shown because too many files have changed in this diff Show more