@junoput01/junoui 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +188 -0
- package/README.md +44 -14
- package/dist/classes.json +1614 -0
- package/dist/css/juno.css +339 -37
- package/dist/icons/inline.js +7 -9
- package/dist/icons/install.js +26 -0
- package/docs/accessibility.md +6 -0
- package/docs/browser-support.md +176 -0
- package/docs/components/button.md +11 -2
- package/docs/components/dock.md +34 -0
- package/docs/components/fold-slot.md +26 -1
- package/docs/conformance-kit.md +243 -0
- package/docs/getting-started.md +36 -0
- package/docs/icon-subsetting.md +29 -0
- package/docs/integration.md +52 -6
- package/docs/ios-conformance.md +403 -4
- package/docs/ios-pwa.md +273 -0
- package/docs/layout.md +35 -0
- package/package.json +15 -3
- package/src/css/base.css +103 -23
- package/src/css/components/button.css +42 -2
- package/src/css/components/dock.css +65 -6
- package/src/css/components/fold-slot.css +49 -3
- package/src/css/components/input.css +12 -0
- package/src/css/components/pillbar.css +1 -1
- package/src/css/components/segmented.css +15 -2
- package/src/css/overrides.css +51 -0
- package/tools/testing.mjs +177 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,193 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.7.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- aad6351: **`.juno-btn--sm` promotes to the tap target on touch; `.juno-btn--dense` is the opt-out.**
|
|
8
|
+
|
|
9
|
+
`--sm` names a **density**, and consumers reach for it as a **semantic**. Audited across one app: 40 call sites, nearly all `--sm --ghost` meaning "secondary", shipping a 24px target on a phone — and junoui's own showcase does it twice, in a navbar action slot.
|
|
10
|
+
|
|
11
|
+
A size modifier should not quietly become a tap-target decision. Under `(pointer: coarse)`, `.juno-btn--sm` now holds `--juno-size-tap-min` like every other control. Type and padding still shrink, so it stays a density modifier and stops being a touch-target one. **On a fine pointer nothing changes** — still 24px, the WCAG 2.2 AA floor (2.5.8) exactly.
|
|
12
|
+
|
|
13
|
+
`.juno-btn--dense` opts a `--sm` button back out, for a toolbar that is genuinely dense on touch (a scrubber, an editor rail). It is meaningful only in combination with `--sm`, on purpose: a dense touch target should be chosen by name, never inherited from a size.
|
|
14
|
+
|
|
15
|
+
**This is a visual change on touch devices.** Any `--sm` button in a phone layout grows to 44px unless you add `--dense`. Audit your `--sm` call sites: the ones that meant "secondary" want `--ghost` alone and are now correct for free; the ones that meant "dense" want `--dense` added.
|
|
16
|
+
|
|
17
|
+
The rule lives in `button.css`, not `base.css`'s coarse block — a media query adds no specificity, so a `.juno-btn--sm` there would lose to `button.css`'s own `.juno-btn--sm` later in the bundle.
|
|
18
|
+
|
|
19
|
+
- 40a5e43: **Class manifest + `junoui/testing` — conformance kit slice 1.**
|
|
20
|
+
|
|
21
|
+
A `juno-*` class name in a consumer's source is a string that has to match something in junoui's stylesheet, and nothing checked it. When it does not match, nothing fails: the file compiles, the tests pass, and the element renders as unstyled UA defaults. One consumer shipped eleven such names in a dialog; on a phone that put the confirm button off the bottom of the screen with no way to reach it. junoui had the same defect pointing the other way — `.juno-seg__option` sat in a `touch-action` list that never matched anything, because the shipped class is `.juno-seg__opt`.
|
|
22
|
+
|
|
23
|
+
**New: `junoui/classes.json`**, generated at build time from the bundle's own selectors — `all`, `public` (the documented subset), `roles`, `components` grouped BEM-wise, plus the other `juno-*` namespaces junoui ships and a consumer writes as bare strings: `tokens`, `keyframes`, `icons`.
|
|
24
|
+
|
|
25
|
+
**New: `junoui/testing`**, dependency-free and framework-agnostic:
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
import { assertJunoClasses } from 'junoui/testing';
|
|
29
|
+
assertJunoClasses(['src/**/*.tsx'], { allowed: ['my-own-juno-namespaced-thing'] });
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
It throws with every offending `file: name`, and throws rather than passing when its globs match no files.
|
|
33
|
+
|
|
34
|
+
**What it answers:** "junoui ships nothing by this name." **What it does not:** whether the class still does what your component assumes.
|
|
35
|
+
|
|
36
|
+
Nothing existing changes; both entries are additive.
|
|
37
|
+
|
|
38
|
+
- 447c133: The floating bar's offset from the bottom edge is now one token,
|
|
39
|
+
`--juno-dock-edge-offset`, consumed by both `.juno-dock--pill`/`--float`'s margin
|
|
40
|
+
and `--juno-dock-clearance`. Plus `--juno-dock-clearance-breathing` (default
|
|
41
|
+
`space-8`) for the gap between the bar and the last row.
|
|
42
|
+
|
|
43
|
+
No default changes: the offset still resolves to `space-16 + env(safe-area-inset-bottom)`
|
|
44
|
+
and the clearances to the same 86px / 78px they did at a 44px bubble.
|
|
45
|
+
|
|
46
|
+
What it fixes: the inset FORM used to be written separately at each site, so a
|
|
47
|
+
consumer whose design puts the bar flush above the home indicator —
|
|
48
|
+
`max(8px, env(safe-area-inset-bottom))` — changed its margin and could not change
|
|
49
|
+
the reservation, which kept adding. Measured at 16px of dead band at inset 0 and
|
|
50
|
+
24px at inset 34, with no value of `--juno-dock-h` able to reconcile them because
|
|
51
|
+
one side added the inset and the other maxed it. Both now follow the token, so
|
|
52
|
+
they agree by construction at every inset.
|
|
53
|
+
|
|
54
|
+
- e852323: **The dock publishes its horizontal item budget.**
|
|
55
|
+
|
|
56
|
+
`.juno-dock__item` is `flex: 1 1 0`, so the bar divides its inner width by however many items are present. A consumer deciding how many to render — and whether they still hold a tap target — had to re-derive that from the numbers in `dock.css`. Two did, in prose, twice, and both drifted the same way: they subtracted 12px of inline padding where the pill actually spends 8 (`--juno-space-4` a side), so every per-item width came out ~0.8px low.
|
|
57
|
+
|
|
58
|
+
New custom properties on `.juno-dock`:
|
|
59
|
+
|
|
60
|
+
| Property | What it is |
|
|
61
|
+
| --------------------------- | --------------------------------------------------------------------------------------------- |
|
|
62
|
+
| `--juno-dock-items` | The item budget. You set it to what you render (default `5`). |
|
|
63
|
+
| `--juno-dock-item-inline` | The width one item gets — a prediction of the flex layout, asserted against the measured box. |
|
|
64
|
+
| `--juno-dock-fit-inline` | The narrowest viewport at which every item still holds `--juno-size-tap-comfortable`. |
|
|
65
|
+
| `--juno-dock-chrome-inline` | The bar's total inline chrome. `0` full-bleed, `34px` on `--pill`/`--float`. |
|
|
66
|
+
| `--juno-dock-avail` | The width the budget divides (default `100vw`). |
|
|
67
|
+
|
|
68
|
+
The margin, padding and border terms are declared once and consumed by both the variant's own box and the sum, so the budget cannot disagree with the bar it describes — the same construction as `--juno-dock-edge-offset`. One consequence worth knowing: `--pill`/`--float` now paint their border from `--juno-dock-border-inline`, so overriding that term to `0` removes the hairline as well as widening the items. That is deliberate — the sum follows the paint.
|
|
69
|
+
|
|
70
|
+
**No scale floor is published.** `44px / --juno-dock-item-inline` is a ratio of two lengths and CSS cannot divide by a length. A consumer that must scale rather than drop an item compares the two values itself.
|
|
71
|
+
|
|
72
|
+
### Patch Changes
|
|
73
|
+
|
|
74
|
+
- 770f331: **fold-slot: the fold now reaches zero when composed with a component class.**
|
|
75
|
+
`.juno-fold` promises its inline-size folds to zero, and the canonical use puts it on an element that already carries the capsule chrome — `.juno-pillbar__item`, `.juno-btn`, `.juno-chip`. Composed that way it could not: `min-inline-size` (the 44px tap floor), `padding-inline` and `border-inline-width` each hold a border-box inline size open, and the folded state released none of them. Measured against the built bundle at a 390px viewport, composed with `.juno-pillbar__item`: 44px folded, 20px with the floor released, 0px with all three. A consumer's pill carried one dead 44px slot whenever the folded action was absent.
|
|
76
|
+
|
|
77
|
+
The folded state now releases all three, and each is in the fold's transition list so nothing snaps as the fold opens or shuts.
|
|
78
|
+
|
|
79
|
+
Also fixed, and invisible from the source: `transition` is a shorthand, `.juno-fold` was one class of specificity, and `pillbar.css` sorts after `fold-slot.css` — so `.juno-pillbar__item`'s own `transition` replaced the fold's whole list and the slot jumped shut instead of folding. The fold's declarations now sit at attribute specificity, and its transition list carries the chrome properties (`color`, `background-color`) too, since owning the shorthand means owning all of it. A component of your own that composes with `.juno-fold` and needs a third property transitioned must state it above `(0,2,0)`.
|
|
80
|
+
|
|
81
|
+
- a1f3f53: New `docs/ios-pwa.md`: a bounded statement of what junoui gives you on iOS and in
|
|
82
|
+
a Home-Screen web app — what you get for free, what your app must supply, and
|
|
83
|
+
what junoui explicitly does not do. `docs/ios-conformance.md` gains the
|
|
84
|
+
standalone `<head>` contract and names the letterbox flag
|
|
85
|
+
(`data-juno-letterboxed`, app-set, documented rather than shipped).
|
|
86
|
+
|
|
87
|
+
Docs ship in the package, so a consumer installing this version receives both.
|
|
88
|
+
Two corrections travel with them: the letterbox flag is **not** an upstream-fix
|
|
89
|
+
detector (that test needs a document that cannot scroll, and the unlock makes it
|
|
90
|
+
scroll), and `.juno-pagination`'s items take the coarse-pointer promotion on the
|
|
91
|
+
inline axis only — 44 × 32 on touch, which clears WCAG 2.5.8 AA and not the
|
|
92
|
+
44 px comfortable target the docs previously implied.
|
|
93
|
+
|
|
94
|
+
- 4568157: **Two mistyped class names in the touch-default lists, and a tap floor for the segmented pill.**
|
|
95
|
+
|
|
96
|
+
`base.css` carries two `:where()` lists of junoui's own tappable components — one dropping double-tap-to-zoom recognition (`touch-action: manipulation`), one killing the UA tap-highlight square under `(pointer: coarse)`. Two members named classes that do not exist, so `:where()` matched nothing, the rule still parsed, every other member kept working, and the named components silently kept the defaults they were listed to opt out of:
|
|
97
|
+
|
|
98
|
+
- `.juno-seg__option` → `.juno-seg__opt` (touch-action list)
|
|
99
|
+
- `.juno-list__item` → `.juno-list__row` (**both** lists)
|
|
100
|
+
|
|
101
|
+
Every segmented control and every grouped list row in every consumer has been carrying the ~300ms double-tap delay. No consumer change is needed — the fix lands in the shipped stylesheet.
|
|
102
|
+
|
|
103
|
+
`.juno-seg__opt` was also the only interactive primitive with no tap floor: it computed 25.39px from its padding, which meets WCAG 2.2 AA (2.5.8, 24px) by accident and misses the comfortable touch target entirely. It now holds `--juno-size-tap-min` on the painted box, like `.juno-btn`. Measured against the built bundle: **fine pointer unchanged at 25.39px, coarse 25.39 → 44.00**, width unchanged either way — so no showcase baseline moves.
|
|
104
|
+
|
|
105
|
+
Unlike `.juno-btn--sm`, `.juno-seg--sm` does **not** drop below that floor: it reduces type and padding only. A segmented row is routinely the only control on a whole settings section, so a sub-tap variant of it has no safe use on a phone.
|
|
106
|
+
|
|
107
|
+
## 0.6.0
|
|
108
|
+
|
|
109
|
+
### Minor Changes
|
|
110
|
+
|
|
111
|
+
- 71c069c: Two primitives stop encoding junoui's own dimensions and start exposing the
|
|
112
|
+
derivation, so a consumer that parameterizes them stays correct.
|
|
113
|
+
|
|
114
|
+
- **`junoui/icons/install`** — the sprite injector without the sprite (~1 kB).
|
|
115
|
+
A consumer that subsets with `junoui/subset` can now keep the same-document
|
|
116
|
+
injection Safari requires without pulling the 66-symbol payload that
|
|
117
|
+
`junoui/icons/inline` carries; both share one id-guarded holder, so mixing
|
|
118
|
+
them cannot produce two. `icons/inline` is unchanged for everyone else.
|
|
119
|
+
- **`--juno-dock-clearance` / `--juno-pillbar-clearance` are derived**, from
|
|
120
|
+
new published parts: `--juno-dock-h`, `--juno-pillbar-h` and
|
|
121
|
+
`--juno-dock-clearance-scale`. They were constants that promised to track the
|
|
122
|
+
dock's geometry and did not — past a 58px bubble they reserved less than the
|
|
123
|
+
pill's own height plus its margin, hiding content under the dock. Values at
|
|
124
|
+
the default 44px bubble change from 92px to 86px (dock) and 72px to 78px
|
|
125
|
+
(pillbar), both now equal to what the control actually measures plus its
|
|
126
|
+
margin and a breathing gap.
|
|
127
|
+
|
|
128
|
+
- 0ee41a8: Declare the browser-support baseline, and guard the one gap that is functional.
|
|
129
|
+
|
|
130
|
+
New `docs/browser-support.md`: the supported floor (Safari/iOS 17.5, Chrome/Edge
|
|
131
|
+
117, Firefox 129), the hard floor below which things break (17.0 / 114 / 125),
|
|
132
|
+
and a per-feature audit of the built bundle with a degrade-vs-break verdict on
|
|
133
|
+
each. `package.json` now carries a matching `browserslist`; README and
|
|
134
|
+
getting-started state the floor.
|
|
135
|
+
|
|
136
|
+
`base.css` ships one `@supports not selector(:popover-open)` guard. Below Safari
|
|
137
|
+
17.0 the Popover API is absent, and because the UA rule that hides a closed
|
|
138
|
+
popover is absent with it, `.juno-menu` and `.juno-popover` were rendering as
|
|
139
|
+
invisible fixed panels that swallowed taps. The guard hides them instead —
|
|
140
|
+
absent beats invisibly-present, and apps can branch on
|
|
141
|
+
`CSS.supports('selector(:popover-open)')`. Guards are for functional failures
|
|
142
|
+
only; cosmetic gaps (missing entry animations, unanchored placement) are
|
|
143
|
+
documented, not wrapped.
|
|
144
|
+
|
|
145
|
+
`docs/ios-conformance.md` gains the viewport-unit decision it was missing:
|
|
146
|
+
`dvh` stays at both `.juno-app-shell` and `.juno-drawer`, with the reasoning,
|
|
147
|
+
what each option costs at the moment browser chrome retracts, and a rule for
|
|
148
|
+
applying the choice to a new component. It also now records the iOS Home-Screen
|
|
149
|
+
standalone letterbox — iOS sizes the window from the document's resting
|
|
150
|
+
scrollability at launch — which is why `base.css` carries the standalone unlock.
|
|
151
|
+
|
|
152
|
+
Docs and defaults only; no token or component API changed.
|
|
153
|
+
|
|
154
|
+
### Patch Changes
|
|
155
|
+
|
|
156
|
+
- cacdb21: Fix: the 16px `.juno-input` font floor on touch never applied.
|
|
157
|
+
|
|
158
|
+
The rule lived in `base.css`'s `@media (pointer: coarse)` block, but a media
|
|
159
|
+
query adds no specificity — so `components/input.css`'s own
|
|
160
|
+
`.juno-input { font-size: var(--juno-font-size-14) }`, same 0,1,0 selector and
|
|
161
|
+
later in the bundle, won every time. On a coarse pointer the field measured
|
|
162
|
+
14px, i.e. exactly the condition the floor exists to avoid (iOS Safari zooming
|
|
163
|
+
the page onto a focused sub-16px field). The rule now lives in `input.css`,
|
|
164
|
+
after the declaration it has to beat.
|
|
165
|
+
|
|
166
|
+
Found by the new coarse-pointer visual-regression project (20260815-006): the
|
|
167
|
+
suite ran only `Desktop Chrome`, where `(pointer: coarse)` never matches, so
|
|
168
|
+
nothing had ever exercised the rule.
|
|
169
|
+
|
|
170
|
+
- da03666: Fix: the forced-colors (Windows High Contrast) border never applied.
|
|
171
|
+
|
|
172
|
+
`@media (forced-colors: active) { .juno-badge, .juno-btn, .juno-card,
|
|
173
|
+
.juno-readout { border: 1px solid CanvasText } }` lived in `base.css`, which the
|
|
174
|
+
bundler emits before `components/`. A media query adds no specificity, so each
|
|
175
|
+
component's own `border` declaration won on source order alone. Measured under
|
|
176
|
+
emulated forced-colors: `.juno-badge` computed a transparent border — it sets
|
|
177
|
+
`forced-color-adjust: none` to keep its status fill, and that opt-out also
|
|
178
|
+
disables the UA repaint that was silently rescuing `.juno-btn` and `.juno-card`.
|
|
179
|
+
|
|
180
|
+
New `src/css/overrides.css`, bundled last, is where cross-cutting `@media` /
|
|
181
|
+
`@supports` gates live now — after everything they guard. Same reasoning the
|
|
182
|
+
bundler already applied to `utilities.css`.
|
|
183
|
+
|
|
184
|
+
- 2ec7cff: Stop publishing junoui's internal release process to consumers: the pre-release
|
|
185
|
+
consumer gate document moves from `docs/release-gate.md` to `RELEASING.md` at
|
|
186
|
+
the repo root, beside CONTRIBUTING.md, which has never shipped. `files` carries
|
|
187
|
+
`docs` wholesale, so the rule is now positional — `docs/` IS the published
|
|
188
|
+
manual, and contributor or process documents live at the root. The published
|
|
189
|
+
surface loses one file (204 → 203) and no consumer-facing content changes.
|
|
190
|
+
|
|
3
191
|
## 0.5.0
|
|
4
192
|
|
|
5
193
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -61,22 +61,40 @@ build-time sRGB hex (identical rendering).
|
|
|
61
61
|
| ---------------- | -------------------------- | ------------------------------- |
|
|
62
62
|
| CSS, SCSS, JS/TS | Android (xml), iOS (Swift) | Flutter (Dart), JSON (W3C DTCG) |
|
|
63
63
|
|
|
64
|
+
## Browser support
|
|
65
|
+
|
|
66
|
+
**Supported floor: Safari / iOS 17.5, Chrome / Edge 117, Firefox 129.**
|
|
67
|
+
Below **17.0 / 114 / 125** (the `browserslist` in `package.json`) the Popover
|
|
68
|
+
API is absent and the overlay surfaces — menu, popover, tooltip, and the
|
|
69
|
+
pillbar's overflow slot — stop working; junoui ships an `@supports` guard so
|
|
70
|
+
they are absent rather than invisibly blocking taps. Between the two floors
|
|
71
|
+
everything functions and entry animations are missing. Full fidelity, including
|
|
72
|
+
anchored placement for those surfaces, wants Safari 26.
|
|
73
|
+
|
|
74
|
+
CSS failures are silent — an unsupported at-rule is dropped, never reported —
|
|
75
|
+
so the degrade-vs-break audit, the version table and the guard rule live in
|
|
76
|
+
**[browser-support.md](./docs/browser-support.md)**. Read it before adding a
|
|
77
|
+
feature newer than the floor.
|
|
78
|
+
|
|
64
79
|
## Documentation
|
|
65
80
|
|
|
66
|
-
| |
|
|
67
|
-
| -------------------------------------------------------------------------------- |
|
|
68
|
-
| [Getting started](./docs/getting-started.md) | Install, model, what ships
|
|
69
|
-
| [Integration](./docs/integration.md) | Consuming in an app: import order, fonts, token bridge
|
|
70
|
-
| [Web](./docs/web.md) · [Native](./docs/native.md) · [Flutter](./docs/flutter.md) | Per-platform usage
|
|
71
|
-
| [Design guidelines](./docs/design-guidelines.md) | Color semantics, a11y — for any tool
|
|
72
|
-
| [Layout](./docs/layout.md) | Responsive primitives + container queries (how blocks adapt)
|
|
73
|
-
| [Boot shell](./docs/boot-shell.md) | Fast first paint: pre-bundle shell, lazy screens, warming
|
|
74
|
-
| [Accessibility](./docs/accessibility.md) | WCAG 2.2 + WAI-ARIA references, focus, motion, targets, RTL
|
|
75
|
-
| [iOS
|
|
76
|
-
| [
|
|
77
|
-
| [
|
|
78
|
-
| [
|
|
79
|
-
| [
|
|
81
|
+
| | |
|
|
82
|
+
| -------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
|
|
83
|
+
| [Getting started](./docs/getting-started.md) | Install, model, what ships |
|
|
84
|
+
| [Integration](./docs/integration.md) | Consuming in an app: import order, fonts, token bridge |
|
|
85
|
+
| [Web](./docs/web.md) · [Native](./docs/native.md) · [Flutter](./docs/flutter.md) | Per-platform usage |
|
|
86
|
+
| [Design guidelines](./docs/design-guidelines.md) | Color semantics, a11y — for any tool |
|
|
87
|
+
| [Layout](./docs/layout.md) | Responsive primitives + container queries (how blocks adapt) |
|
|
88
|
+
| [Boot shell](./docs/boot-shell.md) | Fast first paint: pre-bundle shell, lazy screens, warming |
|
|
89
|
+
| [Accessibility](./docs/accessibility.md) | WCAG 2.2 + WAI-ARIA references, focus, motion, targets, RTL |
|
|
90
|
+
| [iOS & PWA](./docs/ios-pwa.md) | The bounded claim: what's free, what you supply, what it won't do |
|
|
91
|
+
| [iOS conformance](./docs/ios-conformance.md) | Sourced iOS metrics — safe areas, tap targets, viewport units |
|
|
92
|
+
| [Browser support](./docs/browser-support.md) | The supported floor, what degrades below it, what breaks |
|
|
93
|
+
| [Token reference](./docs/tokens-reference.md) | Every token + value + platform name (generated) |
|
|
94
|
+
| [Components](./docs/components/README.md) | 30+ — forms, overlays, table, alerts, tabs, icons, nav, more |
|
|
95
|
+
| [Release gate](./RELEASING.md) | The consumer build every release candidate must pass |
|
|
96
|
+
| [Contributing](./CONTRIBUTING.md) | Add tokens/components, lint, test, release |
|
|
97
|
+
| [Roadmap](./docs/roadmap.md) | Missing capabilities, prioritised |
|
|
80
98
|
|
|
81
99
|
## Repository
|
|
82
100
|
|
|
@@ -116,6 +134,18 @@ remain — publishes `@junoput01/junoui` to npm automatically. No manual `npm ru
|
|
|
116
134
|
version` step. Bump by the token contract: remove/rename a token or class → major,
|
|
117
135
|
additive → minor, fix → patch. See [CONTRIBUTING](./CONTRIBUTING.md#releasing).
|
|
118
136
|
|
|
137
|
+
One step is **not** automated, on purpose. Before merging the version PR, run
|
|
138
|
+
|
|
139
|
+
```sh
|
|
140
|
+
npm run gate:consumer
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
which packs the candidate, installs that tarball into a throwaway checkout of a real
|
|
144
|
+
consumer, and runs the consumer's typecheck, tests and production build against it. A
|
|
145
|
+
red gate blocks the release. It is a local step because the consumer lives on the dev
|
|
146
|
+
box, not in this repo's CI — [RELEASING.md](./RELEASING.md) explains
|
|
147
|
+
what it asserts and what it would take to move it into CI.
|
|
148
|
+
|
|
119
149
|
## License
|
|
120
150
|
|
|
121
151
|
MIT
|