npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

colregs

v0.3.4

Published

COLREGS 72 and its national amalgamations as language-neutral JSON — rule text, light definitions, and applicability predicates — with cross-implementation fixtures

Readme

colregs

Two vessels are closing. What must they do? Who gives way? What must they display?

The COLREGS, the International Regulations for Preventing Collisions at Sea, answer all three. This project transforms the colregs so that a machine can evaluate and reason about them deterministically: the whole of the rules as structured data, so the same situation always yields the same result, and every result can be traced back to the rule that produced it. Going further, the engine and the rules are then checked with formal methods, which means mathematically proving the rule set is consistent and complete rather than just testing it a bunch and hoping it all works out.

This package is the data: the rules as language-neutral JSON, the USCG's own diagrams, and enough geometry to draw the lights yourself. Jurisdictions are deltas on the international base, so national amalgamations hang off it rather than forking it.

Related packages:

See a live demo of searoom and the colregs data/engine.

Status: pre-release. Not complete, and not fit for navigation. Navigate by the published rules.

data/rules.json          the skeleton: paragraph paths, rule numbers, jurisdictions -- no text; non-intl jurisdictions as deltas
data/editions.json       which edition of which instrument each jurisdiction is on
data/text/               rule text, one corpus per edition x language x source
data/corpora.json        index of those corpora and how much each covers
data/lights.json         the six Rule 21 lights: colour, arc, Rule 22 range
data/facts.json          the fact record, and how to decode SignalK navigation.state
data/applicability.json  predicate -> lights, each entry also carrying modality, citation, jurisdiction
data/geometry.json       Annex I: heights, spacings, colour, intensity
data/images.json         every image, its source, and what it illustrates
images/                  38 USCG diagrams + 5 arc GIFs
fixtures/                fact records and the entries that apply to them

What this package does not do

It has no runtime and no dependencies. It does not infer anything: it is a pure function of the fact record, and deciding that a vessel is fishing, or aground, or making way is the caller's job. Nothing here reads a sensor.

It does not select a single display. Where the rules permit a choice, every lawful option comes back and none is picked. Selection belongs to the consumer.

Coverage

Every rule with a machine-checkable consequence: Part B conduct, Part C lights and shapes, Part D sound and light signals, and Annex I geometry. intl is the base; us/inland, ca/inland and eu/cevni are deltas on it. docs/requirements.md is the numbered contract for all of it. One case the Convention cannot state, a vessel made fast to a mooring buoy, lives only under us/inland (ADR 0008); two the Inland Rules deliberately lack, Rule 28 and 23(d)(ii), are tombstoned there (ADR 0018); one it spells differently, 23(d), replaces the international entry, and one it states differently, the towing lights that replace 24(c)'s sternlight, is tombstoned and replaced under its own id. Its Part C skeleton is a delta of the same kind: the paths whose text differs, the paths only it has, the three it lacks (ADR 0020). That is the whole of us/inland today: seven records and a skeleton, not yet a model of the Inland Rules; its text and the entries for its own paths are the next work.

The layers

Rule text. Verbatim, keyed by paragraph path, like 27(a)(i), because the paragraph is the unit you actually cite. The paths live in a language-neutral skeleton; the words live in corpora, one per edition, language and source, each with its own provenance and legal tier. A mixed rendering across corpora is never a single authoritative edition. Where a licence bars republishing a jurisdiction's words, the paragraph is still modelled and its text withheld rather than paraphrased — evaluation never reads the text.

Light definitions. Rule 21's lights with colour, arc as a bearing range, and Rule 22 range by length band. Bearings run clockwise from right ahead; an arc whose from_deg exceeds its to_deg wraps through the bow.

Facts. Three orthogonal axes (fact:propulsion, fact:activity, fact:position), a fact:making_way modifier, and scalars such as fact:length_m. There is deliberately no vessel-class field: under COLREGS what a vessel is follows from what it is doing. A decode table maps SignalK's navigation.state onto the axes and names what the flattening loses.

Applicability entries. Each is a predicate over facts, a set of lights or references to other entries, a modality, a citation, and a jurisdiction. Every entry has an id (rule:25b, rule:27a_iii) a consumer can point at.

Identifiers. Paragraph paths carry no prefix, because the path is the citation. Every other id names its namespace: rule:30a, light:masthead, fact:activity, activity:nuc, rel:in_lieu_of. Every identifier is immutable from 1.0.0; before then it may be renamed or discarded outright, and the deprecation registry is absent. See docs/identifiers.md.

Design

Requirements-first: sessions work against the numbered requirements in docs/requirements.md and decisions live in docs/adr/ rather than being argued again; the amendment and national-adoption history is in docs/timeline.md. Four ideas carry most of it.

The paragraph is the unit. Rule text, citations and composition all key on the paragraph path. Citation unit and composition unit turn out to be the same thing.

Jurisdiction is a dimension, not a fork. Every record carries a jurisdiction: intl, or <country-or-body>/<waters> as a delta on it. Entries a jurisdiction doesn't override are inherited, not restated. The delta is an RFC 7396 merge patch over intl keyed by entry id: the jurisdiction's own entries are its keys, its suppressions are the keys set to null, and silence inherits (ADR 0018). Any conformant merge-patch library reproduces the resolved rule set.

Predicates, not enumerations. Gates are fact:length_m < 7, never a pre-built list of configurations. Enumerated tables are where prior art silently loses rules; a predicate cannot omit a case it was never asked about.

Alternatives are first-class. A tricolor in lieu of separate sidelights, a torch in lieu of either. The data carries every lawful option with its modality and gate, and picks none of them.

Predicate semantics

An entry applies when every constraint in its when is satisfied. An absent fact never satisfies a constraint, including not: a duty is never laid on a vessel because a consumer left a field out.

| form | where | means | |---|---|---| | {"gte": n}{"lt": n} | a fact's constraint | numeric comparison | | ["a", "b"] | a fact's constraint | membership | | "a" / true / 12 | a fact's constraint | equality | | {"not": C} | a fact's constraint | the fact is present and does not satisfy C | | {"any_of": [C, …]} | a fact's constraint | the fact satisfies at least one C | | "any_of": [W, …] | a key of a when | at least one sub-predicate W holds |

Entries compose: several apply to one fact record, and Rule 26 adds to Rule 23 rather than replacing it. A condition on whether a paragraph applies at all goes in the predicate; a condition on which of two applicable paragraphs prevails is a relation.

| relation | meaning | |---|---| | rel:includes | import the referenced entry's lights, their modality and its scalar gates — never its axes (ADR 0019) | | rel:conditional_includes | import lights when the stated when holds; one_of is a set of legal alternatives, exactly one per display, or none under a may carrier | | rel:in_lieu_of | this entry's lights replace the referenced entries' lights; two entries replacing overlapping sets are alternatives to each other | | rel:excludes | must not be shown together: a pick-one between alternatives, never one obligation vetoing another; a constraint on one display, never a removal | | rel:exempts | the referenced requirement does not apply (30(e)); reaches an entry in force, never an import | | rel:overrides | this paragraph's requirement prevails over the referenced one's when both apply (Rule 18; Rule 26(a) over Rule 30's anchor lights); reaches an entry in force, never an import |

Modality is modality:shall, modality:may, modality:shall-if-practicable, modality:shall-not, modality:shall-not-impede, or modality:conditional with a modality_by table when it turns on a fact.

Most entries read one vessel and produce lights. The Part B entries read two, a situation rather than a fact record, and produce an effect: which section governs, which vessel gives way, whether the encounter is encounter:head-on, encounter:crossing or encounter:overtaking. They address each vessel through a subject segment (self:fact:activity, other:fact:propulsion, pair:geo:in_sight); a key with no subject means self:. The encounter sectors partition relative bearing, so no crossing sector is enumerated and none can drift. docs/identifiers.md has the vocabulary, docs/part-b-invariants.md the invariants, and fixtures/situation-fixtures.json is the contract.

Verifying

npm test

Every fixture reproduces exactly; every citation, cross-reference, light and geometry reference resolves; every image is on disk with its SHA-256 recorded; every fact a predicate reads is declared. A drift test cross-checks fact record to lights and lights back to entries, and fails on any collision the data doesn't declare through a relation. Every numeric gate has fixtures either side of its threshold, and every entry is exercised by at least one fixture and absent from another. The encounter sweeps assert that exactly one encounter applies at every bearing, and that no steady-bearing geometry makes both vessels give-way.

fixtures/applicability-fixtures.json and fixtures/situation-fixtures.json are the cross-implementation contract: an implementation in any language should reproduce those exactly. data/operations.json names the verbs an engine implements and binds each to its input schema, its result schema and the fixture file that exercises it (ADR 0014).

Provenance and licence

Rule text, the NRHB_* diagrams and the five *arc.gif files are USCG publications, public domain; see PROVENANCE.md. The compilation is Apache-2.0.

Not authoritative, not endorsed by the Coast Guard. Navigate by the published rules. The ca/inland delta carries the same condition its licence does: it must not be represented as an official version.