Japan research app

One SvelteKit application, served by adapter-node. See the repository README for database setup and commands. No generated dataset is an application input.

At startup, SvelteKit's src/hooks.server.ts init hook calls initializeRoutes in src/lib/server/japan.ts. It reads the configured transmitter associations, runs sql/queries/japan_routes.sql once for all of them, and retains the returned rows in memory. Both the connection and DuckDB instance close immediately afterward. Initialization is skipped during builds; a runtime query failure aborts startup.

Following a dossier request

  1. /dossier/tower selects src/routes/dossier/tower/+page.svelte, an authored page with prose, route summaries and catalogue photo IDs.
  2. The shared src/routes/dossier/+layout.server.ts loads the photo catalogue. SvelteKit supplies that data to each dossier; there are no per-operator loaders.
  3. +layout.svelte imports dossier.css: shared typography, spacing, grids and responsive behavior. Pages set an accent colour and may keep small, local styles for a particular arrangement. They do not duplicate the page stylesheet.
  4. PhotoFigure renders each photograph and PhotoGallery groups navigation. ArticleLink pairs original and local English links in both captions and prose.
  5. Photos point into the original blog mirror. media.mjs mounts it with sirv; nothing copies or rebuilds the pictures.

The overview loader attaches the startup results to all operators. Selecting an operator filters this loaded page data. SvelteKit tracks URL parameters: changing operator does not rerun the loader, which only reads dossier for old bookmark redirects. Opening a dossier is a new page load.

All eight dossiers use this arrangement. Their Markdown retains source notes. There is no generic inventory renderer, per-operator timeline/gallery configuration or dossier database query. The map continues to use the queried ITU routes. The old /nln-preview.html URL redirects to /dossier/nln.

What the files own

  • config/japan-network.toml: map identities, sites, transport and route annotations. display_name pairs the Japanese company with the familiar operator name; identity_url links to its section in docs/japan-operators.md, which explains the company connections and station identifications using corporate, licence and field sources. Site attribution describes the installation; transport attribution describes the recorded link. Co-location alone does not establish carriage. itu_tx is a declared transmitter centre, distinct from a field-site coordinate. Transport status records reported/observed/inferred evidence; omitted_intermediates separately marks multi-hop paths simplified to a line. A reported path with omitted hops is not an inferred connection.
  • sql/queries/japan_routes.sql: the actual route selection and aggregation. $transmitters is a DuckDB list of structs containing id, latitude, and longitude, bound through the Node API. It identifies transmitters, not routes.
  • src/lib/types.ts: the research shapes and SQL route fields consumed by the UI.
  • src/lib/network.ts: the overview's network selection function. footprint contains attributed installations; edges are the explicitly recorded links with resolved sites; sites also includes their endpoints. It neither transfers site attribution nor follows links transitively to infer onward carriage. Operator attribution plus endpoint pairs identify links; GTT and NuVo have separate microwave links between the same shared towers. Terrestrial endpoints are displayed with โ†”; their ordering is not traffic direction.
  • src/lib/SiteMap.svelte: renders that selection and controls the camera. Other operators' endpoints are marked as context and keep their own attribution. svelte-maplibre-gl owns map/source/layer/popup/control lifecycles.
  • src/lib/routes.ts: destination display names shared by maps, cards and routes.
  • src/lib/Routes.svelte: counterpart coordinates, notification batches and research annotations on the overview.
  • src/routes/[...file]/: reads and renders linked research documents and SQL or configuration sources. It only exposes the named research trees.
  • server.mjs: mounts sirv and the SvelteKit handler, listening on explicit local and Tailscale addresses. Vite uses the same media middleware in development.

The operator selector uses native links and SvelteKit navigation. There is no deck.gl overlay, map adapter of our own, Markdown parser, HTML string renderer, separate API service, or export schema.

Queried route fields

These rows are page data, not a public JSON API. SvelteKit handles transport.

Field Meaning
competitor ID of the attributed Japanese transmitter's operator.
destination_source_label Uppercase ITU receiver label from its latest selected appearance; can be null. Display spelling is supplied separately by destination_labels.
destination_country ITU country code, not an ISO conversion.
destination_latitude, destination_longitude Declared receiver coordinates; nullable. No FCC/field coordinates are substituted.
publications Sorted distinct {issue, date, intent} Part I notification batches belonging to their own extract issue. These are neither commissioning dates nor Part II outcomes.

A row groups one operator and one receiver country/coordinate pair. Frequency and emission differences do not create separate rows. The source records remain in DuckDB. route_annotations adds Japanese callsigns and FCC comparisons by the raw destination label after selection; it does not filter or generate routes. Empty query results say only that no outbound pair was found. Receive-only status comes from the operator's research, not from that absence.

Research text and label edits take effect on the next page load. Restart to pick up changed transmitter associations, route SQL, or a rebuilt database with its maintained views. Existing ITU results remain available while the database is rebuilt; the app does not hold it open. Rebuild and restart for application code changes.

Selected photographs

config/jj1wtl-catalog.toml groups selected photographs by location, with captions, capture dates and article references. src/lib/server/photo-catalog.ts reads it. Site popups show a compact thumbnail grid that opens PhotoSwipe directly. The map and popup stay mounted while the viewer is open; PhotoSwipe handles previous/next, closing and focus return. /photos/[location] remains available for a standalone view. Several Chikura pins share one gallery; Cosmo East shows Raft and McKay equipment.

The authored dossier pages refer to catalogue photo IDs directly in their src/routes/dossier/<operator>/+page.svelte files. PhotoFigure.svelte supplies captions, capture dates and original/English source links. PhotoGallery.svelte uses PhotoSwipe's normal DOM gallery API and its caption plugin for zoom and navigation around any arrangement of figures and prose. Images stay in the local mirror.

When selecting photographs, read their article context and look at the images, including diagrams. Caption the useful detail; use loose subjects labels for retrieval. Group by physical location and identify each operator's equipment in the caption. Prefer full-size images and keep capture dates separate from later republications. Choose the article that best explains the photograph; do not maintain every reuse. Dossier prose remains freely arranged. Record useful research findings in the existing notes, without maintaining a second article index here.