# Vendored: @photostructure/tz-lookup

- **Package:** `@photostructure/tz-lookup`
- **Version:** 11.6.1
- **Licence:** CC0-1.0 (PhotoStructure, Inc.) — the full text is in
  `licences/tz-lookup-cc0-1.0.txt`.
- **Boundary data:** derived from
  [`timezone-boundary-builder`](https://github.com/evansiroky/timezone-boundary-builder),
  which is built from OpenStreetMap and released under the **Open Database Licence
  (ODbL)**. Commercial use is permitted and **attribution is required**; see
  `licences/tz-lookup-notices.txt` for the notice this site publishes, and
  `/light-pollution-map/how-it-works/` and `/about/` for where a visitor reads it.
- **Source:** `https://registry.npmjs.org/@photostructure/tz-lookup/-/tz-lookup-11.6.1.tgz`
- **Retrieved:** 2026-09-08

## Why it is vendored

The light pollution map prints times — the darkest window, the night curve's axis,
the cursor readout, the instant the sky dome is drawn for. Those are times *at the
pin*, not on the visitor's own clock, and the only way to render a civil local time
correctly (DST included) is to hold the point's IANA zone name and hand it to
`Intl.DateTimeFormat`. Nothing in the platform maps a coordinate to a zone name, so
that mapping has to ship.

Production CSP is `script-src 'self'`, so a CDN is not an option and the file is
served from this origin, exactly as `vendor/leaflet` is.

**Why this package and not a more accurate one.** Its encoding is a 48×24 global grid
recursively subdivided to depth 10, packed into a character-pair string: a lossy
quadtree, which is why the whole world fits in 73 KB raw / ~28 KB gzipped with zero
dependencies. The accurate alternatives are not close — `geo-tz` is 73.4 MB, `tzf-wasm`
9.1 MB, `lltz` 26–44 MiB — and none of them can be sent to a phone.

The price is stated in the package's own README: about **5% of random points differ
from `geo-tz` in the resulting offset**, and the errors sit on borders. That is the
reason the resolved zone is **printed on screen** rather than used silently
(`Times in America/Los_Angeles (UTC−7)`): a visitor whose pin lands on the wrong side
of a border can see that it did. A silently wrong clock is the defect this whole
change removes; it must not be replaced by a differently silent one.

## Files kept

- `tz.js` — the published `tz.js`, **byte-identical for its first 73,349 bytes**
  (sha256 `dca55aacebfbbb004788fb4beaa80b90b8f8a8606b5a2e7cd2c469f0b6d0489b`), with
  exactly one line appended:

  ```js
  export default tzlookup;
  ```

  The package is CommonJS (`"undefined"!=typeof module&&(module.exports=tzlookup)`),
  and this page has no bundler and no classic script tag — `lpmap.js` must install a
  Trusted Types policy before anything else evaluates, so every dependency on this
  route is an ES module. In a module `typeof module` is `"undefined"`, so the original
  export line is inert and is left in place rather than edited out: keeping the
  original bytes intact means the vendored copy can be diffed against the tarball, and
  `test/lp-timezone.test.js` asserts exactly that digest over exactly that prefix. CC0
  places no condition on modifying or redistributing the file.

- `licences/tz-lookup-cc0-1.0.txt` — the CC0-1.0 text as published in the tarball.
- `licences/tz-lookup-notices.txt` — the ODbL attribution the boundary data requires,
  published as part of the site because a notice nobody can reach is not a notice.

`README.md`, `index.d.ts` and `package.json` from the tarball are dropped: this
repository has no TypeScript and the package is not resolved through npm.

## No npm dependency

`sites/startrail/package.json` declares no runtime dependency (it gained six script entries with this feature, and no `dependencies` key). The
file is committed the way Leaflet and `rawlab.wasm` are, so CI installs nothing to
build or test this route.
