# Vendored: Leaflet

- **Package:** `leaflet`
- **Version:** 1.9.4
- **Licence:** BSD-2-Clause (Copyright © 2010-2023 Volodymyr Agafonkin, Copyright © 2010-2011
  CloudMade).
- **Source:** `https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz`
- **Retrieved:** 2026-09-07

## Why Leaflet is vendored

Leaflet is a client-side mapping library required for the light pollution map on the
startrailstacker.com site. The fleet's CSP forbids CDN scripts (`script-src 'self'
https://analytics.pagefabrica.com 'wasm-unsafe-eval'`), so Leaflet must be served from
the origin to work in production. It functions perfectly in local CI without CSP, so
vendoring was the only way to catch CSP breakage before live deployment.

## The one local modification

`leaflet.js` is the upstream minified build with exactly one byte-range changed, and it
is recorded here because a vendor refresh would silently undo it:

```
-var K="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="
+var K="/assets/blank.gif"
```

`K` is `L.Util.emptyImageUrl`: the 1x1 transparent GIF Leaflet assigns to a tile's
`img.src` to cancel an in-flight request (`GridLayer._abortLoading`). No policy in this
fleet carries `data:` in `img-src`, so every abort was refused — an independent QA pass
counted **174 identical console errors in a fifteen-second pan/zoom storm**, enough to
bury the next real error and enough to flood a CSP report endpoint. The alternatives were
to widen `img-src` with `data:` (a real loosening of a policy a basemap decision depends
on staying strict) or to reassign `L.Util.emptyImageUrl` at runtime — which does nothing,
because `_abortLoading` closes over the module-local `K` rather than reading the export.
So the constant points at `public/assets/blank.gif`, the same 26 bytes served from this
origin: one request, cached thereafter, and no policy anywhere has to change.

`test/lp-tiles.test.js` holds the guard that the shipped bundle carries no `data:` image
URL, so a refresh that drops this patch fails rather than quietly reintroducing 174
console errors.

BSD-2-Clause permits redistribution "with or without modification" provided the notice
below travels with it, which it does.

## Files kept

- `leaflet.js` — the minified UMD build (147.5 KB). This is the production-ready
  distribution.
- `leaflet.css` — the stylesheet that styles the map container and controls. It
  references marker and layer control icons by relative path (`url(images/...)`), so
  the images directory must accompany it.
- `images/` — marker and layer control icons referenced by the CSS:
  - `marker-icon.png` — the default blue marker pin (1466 bytes).
  - `marker-icon-2x.png` — retina version of the marker (2464 bytes).
  - `marker-shadow.png` — drop shadow beneath the marker (618 bytes).
  - `layers.png` — layer control icon for toggling background/overlay layers (696 bytes).
  - `layers-2x.png` — retina version of the layer control icon (1259 bytes).

All other files in the npm tarball (source maps, ESM variants, source code) are dropped.
The minified UMD build is sufficient for the light pollution map use case, and the
source files have no bearing on the running site. Leaflet does not ship TypeScript
definitions in the tarball, so none are available.

## BSD 2-Clause License

```
BSD 2-Clause License

Copyright (c) 2010-2023, Volodymyr Agafonkin
Copyright (c) 2010-2011, CloudMade
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
```
