@tensor_1/react 2.47.0 → 2.49.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/README.md +540 -2
- package/dist/{SchedulingCalendar-B6TakO2h.d.ts → SchedulingCalendar-WWyFL3Eo.d.ts} +51 -2
- package/dist/announce.d.ts +10 -0
- package/dist/announce.js +30 -0
- package/dist/chart-analytic.cjs +33 -25
- package/dist/chart-preset.cjs +23 -15
- package/dist/chart.cjs +23 -15
- package/dist/combobox-model.d.ts +10 -1
- package/dist/combobox-model.js +15 -0
- package/dist/command-palette-model.d.ts +44 -0
- package/dist/command-palette-model.js +36 -0
- package/dist/components/AccountMenu.d.ts +44 -0
- package/dist/components/AccountMenu.js +43 -0
- package/dist/components/AppShell.d.ts +45 -2
- package/dist/components/AppShell.js +116 -5
- package/dist/components/AuditLog.d.ts +128 -0
- package/dist/components/AuditLog.js +196 -0
- package/dist/components/BrandProfiles.js +4 -3
- package/dist/components/Breadcrumbs.d.ts +9 -2
- package/dist/components/Breadcrumbs.js +3 -2
- package/dist/components/Button.d.ts +12 -5
- package/dist/components/Button.js +7 -3
- package/dist/components/Card.d.ts +18 -1
- package/dist/components/Card.js +5 -1
- package/dist/components/ChangeHighlight.d.ts +30 -0
- package/dist/components/ChangeHighlight.js +21 -0
- package/dist/components/ChartCore.js +2 -1
- package/dist/components/Checkbox.d.ts +27 -1
- package/dist/components/Checkbox.js +31 -2
- package/dist/components/Chip.d.ts +7 -3
- package/dist/components/Chip.js +2 -2
- package/dist/components/CodeDisplay.d.ts +65 -0
- package/dist/components/CodeDisplay.js +124 -0
- package/dist/components/Combobox.d.ts +27 -6
- package/dist/components/Combobox.js +195 -58
- package/dist/components/CommandPalette.d.ts +36 -1
- package/dist/components/CommandPalette.js +254 -2
- package/dist/components/ContactCard.d.ts +66 -0
- package/dist/components/ContactCard.js +74 -0
- package/dist/components/Count.d.ts +24 -0
- package/dist/components/Count.js +32 -0
- package/dist/components/DashboardCanvas.js +14 -0
- package/dist/components/DataWorkspace.d.ts +167 -0
- package/dist/components/DataWorkspace.js +380 -0
- package/dist/components/DateFieldParts.d.ts +2 -1
- package/dist/components/DateFieldParts.js +7 -0
- package/dist/components/DatePicker.d.ts +9 -2
- package/dist/components/DatePicker.js +67 -28
- package/dist/components/DateRangePicker.d.ts +12 -2
- package/dist/components/DateRangePicker.js +13 -12
- package/dist/components/DetailPage.d.ts +7 -1
- package/dist/components/DetailPage.js +2 -1
- package/dist/components/Dialogs.d.ts +71 -10
- package/dist/components/Dialogs.js +130 -30
- package/dist/components/DiffViewer.d.ts +23 -3
- package/dist/components/DiffViewer.js +26 -12
- package/dist/components/DiscardPrompt.js +16 -0
- package/dist/components/DisplayPreferences.d.ts +83 -0
- package/dist/components/DisplayPreferences.js +185 -0
- package/dist/components/EditorialHome.d.ts +23 -3
- package/dist/components/EditorialHome.js +16 -11
- package/dist/components/EntityPicker.d.ts +20 -3
- package/dist/components/EntityPicker.js +32 -13
- package/dist/components/FilterEditor.d.ts +18 -4
- package/dist/components/FilterEditor.js +141 -19
- package/dist/components/FocusOnMount.d.ts +282 -0
- package/dist/components/FocusOnMount.js +12 -0
- package/dist/components/InfoTip.js +11 -12
- package/dist/components/InlineEdit.d.ts +87 -20
- package/dist/components/InlineEdit.js +197 -54
- package/dist/components/Input.d.ts +12 -2
- package/dist/components/Input.js +5 -3
- package/dist/components/Kanban.d.ts +14 -3
- package/dist/components/Kanban.js +9 -4
- package/dist/components/Kbd.d.ts +6 -1
- package/dist/components/Kbd.js +6 -6
- package/dist/components/Lightbox.d.ts +41 -5
- package/dist/components/Lightbox.js +95 -9
- package/dist/components/MatchReview.d.ts +40 -1
- package/dist/components/MatchReview.js +130 -4
- package/dist/components/MetricInput.js +3 -2
- package/dist/components/Modal.d.ts +2 -1
- package/dist/components/Modal.js +13 -4
- package/dist/components/MotionList.d.ts +303 -0
- package/dist/components/MotionList.js +175 -0
- package/dist/components/NavFavourites.d.ts +5 -0
- package/dist/components/NavFavourites.js +7 -7
- package/dist/components/OtpInput.d.ts +33 -0
- package/dist/components/OtpInput.js +123 -0
- package/dist/components/PageHeader.d.ts +7 -1
- package/dist/components/PageHeader.js +2 -2
- package/dist/components/Pagination.js +6 -5
- package/dist/components/PasswordInput.d.ts +34 -0
- package/dist/components/PasswordInput.js +101 -0
- package/dist/components/Peek.js +3 -3
- package/dist/components/Popover.js +11 -0
- package/dist/components/PrintLayout.d.ts +63 -0
- package/dist/components/PrintLayout.js +114 -0
- package/dist/components/QrCode.d.ts +47 -0
- package/dist/components/QrCode.js +55 -0
- package/dist/components/QrScanner.d.ts +95 -0
- package/dist/components/QrScanner.js +266 -0
- package/dist/components/RelationshipGraph.d.ts +32 -1
- package/dist/components/RelationshipGraph.js +22 -6
- package/dist/components/RelationshipGraphLayered.d.ts +1 -1
- package/dist/components/RelationshipGraphLayered.js +268 -118
- package/dist/components/RelationshipGraphList.js +33 -6
- package/dist/components/RuleBuilder.js +39 -7
- package/dist/components/SchedulingAgenda.d.ts +3 -1
- package/dist/components/SchedulingCalendar.d.ts +3 -1
- package/dist/components/SchedulingCalendar.js +43 -4
- package/dist/components/SchedulingResourceDay.d.ts +57 -0
- package/dist/components/SchedulingResourceDay.js +287 -0
- package/dist/components/SchedulingTimeGrid.d.ts +3 -1
- package/dist/components/SchedulingTimeline.d.ts +3 -1
- package/dist/components/SearchSuggest.d.ts +23 -3
- package/dist/components/SearchSuggest.js +56 -18
- package/dist/components/Segmented.d.ts +39 -4
- package/dist/components/Segmented.js +39 -5
- package/dist/components/Select.d.ts +3 -2
- package/dist/components/Select.js +7 -1
- package/dist/components/ShortcutHint.d.ts +11 -10
- package/dist/components/ShortcutHint.js +44 -38
- package/dist/components/Sidebar.d.ts +36 -4
- package/dist/components/Sidebar.js +37 -12
- package/dist/components/SortableList.d.ts +45 -0
- package/dist/components/SortableList.js +147 -0
- package/dist/components/Stat.d.ts +28 -3
- package/dist/components/Stat.js +13 -3
- package/dist/components/States.d.ts +33 -1
- package/dist/components/States.js +43 -1
- package/dist/components/StatusPill.d.ts +14 -3
- package/dist/components/StatusPill.js +11 -3
- package/dist/components/Steps.js +2 -1
- package/dist/components/Table.d.ts +9 -2
- package/dist/components/Table.js +4 -2
- package/dist/components/TableControls.js +18 -58
- package/dist/components/TableOverflowProbe.d.ts +12 -0
- package/dist/components/TableOverflowProbe.js +27 -0
- package/dist/components/Tabs.d.ts +2 -1
- package/dist/components/Tabs.js +10 -2
- package/dist/components/TagInput.d.ts +67 -0
- package/dist/components/TagInput.js +342 -0
- package/dist/components/Textarea.d.ts +5 -0
- package/dist/components/Textarea.js +2 -2
- package/dist/components/TimePicker.d.ts +80 -0
- package/dist/components/TimePicker.js +347 -0
- package/dist/components/Toast.d.ts +1 -1
- package/dist/components/Toast.js +109 -4
- package/dist/components/Tooltip.d.ts +8 -4
- package/dist/components/Tooltip.js +86 -28
- package/dist/components/Tree.d.ts +8 -0
- package/dist/components/Tree.js +11 -5
- package/dist/display-preferences-model.d.ts +53 -0
- package/dist/display-preferences-model.js +64 -0
- package/dist/emoji.cjs +143 -49
- package/dist/filter-model.d.ts +59 -3
- package/dist/filter-model.js +67 -2
- package/dist/hooks/useAnchoredPosition.js +14 -2
- package/dist/hooks/useChangeHighlight.d.ts +33 -0
- package/dist/hooks/useChangeHighlight.js +44 -0
- package/dist/hooks/useDeferredReorder.d.ts +32 -0
- package/dist/hooks/useDeferredReorder.js +47 -0
- package/dist/hooks/useDialog.d.ts +5 -0
- package/dist/hooks/useDialog.js +17 -3
- package/dist/hooks/useKeyboardGrab.d.ts +58 -0
- package/dist/hooks/useKeyboardGrab.js +118 -0
- package/dist/hooks/useOptimisticValue.d.ts +51 -0
- package/dist/hooks/useOptimisticValue.js +61 -0
- package/dist/hooks/useReducedMotion.d.ts +4 -1
- package/dist/hooks/useReducedMotion.js +7 -1
- package/dist/hooks/useResolvedFilterLabels.d.ts +15 -0
- package/dist/hooks/useResolvedFilterLabels.js +34 -0
- package/dist/hooks/useSlidingIndicator.d.ts +18 -0
- package/dist/hooks/useSlidingIndicator.js +80 -0
- package/dist/hooks/useVirtualRows.d.ts +21 -2
- package/dist/hooks/useVirtualRows.js +30 -3
- package/dist/icons/Icon.d.ts +1 -1
- package/dist/index.cjs +19687 -13423
- package/dist/index.d.cts +3419 -651
- package/dist/index.d.ts +48 -18
- package/dist/index.js +153 -9
- package/dist/labels-context.d.ts +93 -3
- package/dist/motion.d.ts +11 -0
- package/dist/motion.js +35 -0
- package/dist/overlay-stack.d.ts +6 -0
- package/dist/overlay-stack.js +13 -0
- package/dist/qr-model.d.ts +65 -0
- package/dist/qr-model.js +323 -0
- package/dist/relationship-graph-model.d.ts +92 -3
- package/dist/relationship-graph-model.js +134 -15
- package/dist/reorder.d.ts +30 -0
- package/dist/reorder.js +74 -0
- package/dist/rich-text.cjs +46 -4
- package/dist/scheduling-resource-model.d.ts +76 -0
- package/dist/scheduling-resource-model.js +74 -0
- package/dist/search-suggest-model.js +3 -1
- package/dist/shell-context.d.ts +11 -0
- package/dist/shell-context.js +7 -0
- package/dist/time-field-model.d.ts +46 -0
- package/dist/time-field-model.js +152 -0
- package/dist/toast-store.d.ts +22 -3
- package/dist/toast-store.js +26 -9
- package/package.json +2 -1
package/dist/labels-context.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { PaginationLabels } from './components/Pagination.js';
|
|
4
|
-
import { e as SchedulingCalendarLabels } from './SchedulingCalendar-
|
|
4
|
+
import { e as SchedulingCalendarLabels } from './SchedulingCalendar-WWyFL3Eo.js';
|
|
5
5
|
import { DateRangePickerLabels } from './components/DateRangePicker.js';
|
|
6
6
|
import { DatePickerLabels, DateTimePickerLabels } from './components/DatePicker.js';
|
|
7
7
|
import { SchedulingTimelineLabels } from './components/SchedulingTimeline.js';
|
|
@@ -17,10 +17,29 @@ import { OrgChartLabels } from './components/OrgChart.js';
|
|
|
17
17
|
import { InlineEditLabels } from './components/InlineEdit.js';
|
|
18
18
|
import { DiscardPromptLabels } from './components/DiscardPrompt.js';
|
|
19
19
|
import { SearchBarLabels } from './components/SearchBar.js';
|
|
20
|
+
import { KeyboardGrabLabels } from './hooks/useKeyboardGrab.js';
|
|
21
|
+
import { LightboxLabels } from './components/Lightbox.js';
|
|
22
|
+
import { SortableListLabels } from './components/SortableList.js';
|
|
23
|
+
import { DiffViewerLabels } from './components/DiffViewer.js';
|
|
24
|
+
import { MatchReviewLabels } from './components/MatchReview.js';
|
|
25
|
+
import { QrCodeLabels } from './components/QrCode.js';
|
|
26
|
+
import { CodeDisplayLabels } from './components/CodeDisplay.js';
|
|
27
|
+
import { ContactCardLabels } from './components/ContactCard.js';
|
|
28
|
+
import { PrintLayoutLabels } from './components/PrintLayout.js';
|
|
29
|
+
import { QrScannerLabels } from './components/QrScanner.js';
|
|
30
|
+
import { PasswordInputLabels } from './components/PasswordInput.js';
|
|
31
|
+
import { TimePickerLabels } from './components/TimePicker.js';
|
|
32
|
+
import { TagInputLabels } from './components/TagInput.js';
|
|
33
|
+
import { AccountMenuLabels } from './components/AccountMenu.js';
|
|
34
|
+
import { DisplayPreferencesLabels } from './components/DisplayPreferences.js';
|
|
20
35
|
import { ButtonResultLabels } from './components/ButtonFeedback.js';
|
|
36
|
+
import { AuditLogLabels } from './components/AuditLog.js';
|
|
37
|
+
import { DataWorkspaceLabels } from './components/DataWorkspace.js';
|
|
21
38
|
import './link.js';
|
|
22
39
|
import './calendar-model.js';
|
|
23
40
|
import './scheduling-calendar-model.js';
|
|
41
|
+
import './components/SchedulingResourceDay.js';
|
|
42
|
+
import './scheduling-resource-model.js';
|
|
24
43
|
import './overlay-position.js';
|
|
25
44
|
import './scheduling-timeline-model.js';
|
|
26
45
|
import './text-diff-model.js';
|
|
@@ -32,6 +51,14 @@ import './file-model.js';
|
|
|
32
51
|
import './components/SearchSuggest.js';
|
|
33
52
|
import './components/Button.js';
|
|
34
53
|
import './components/Kbd.js';
|
|
54
|
+
import './diff-model.js';
|
|
55
|
+
import './qr-model.js';
|
|
56
|
+
import './components/Input.js';
|
|
57
|
+
import './components/Avatar.js';
|
|
58
|
+
import './display-preferences-model.js';
|
|
59
|
+
import './components/StatusPill.js';
|
|
60
|
+
import './components/Table.js';
|
|
61
|
+
import './components/TableControls.js';
|
|
35
62
|
|
|
36
63
|
/**
|
|
37
64
|
* Kit chrome strings by component (HAR-1358; TENSOR C20, MOTUS executive summary #3).
|
|
@@ -58,16 +85,28 @@ interface UixLabels {
|
|
|
58
85
|
next?: string;
|
|
59
86
|
close?: string;
|
|
60
87
|
};
|
|
88
|
+
/** `Lightbox` (HAR-1826): previous / next / close, the counter, the zoom toggle. */
|
|
89
|
+
lightbox?: Partial<LightboxLabels>;
|
|
61
90
|
toast?: {
|
|
62
91
|
dismiss?: string;
|
|
63
92
|
};
|
|
64
93
|
toaster?: {
|
|
65
94
|
region?: string;
|
|
66
95
|
};
|
|
96
|
+
/**
|
|
97
|
+
* `openNav`: the phone-tier button that opens the navigation drawer; `navigation`: that
|
|
98
|
+
* drawer's title (HAR-1371).
|
|
99
|
+
*/
|
|
67
100
|
appShell?: {
|
|
68
101
|
skipToContent?: string;
|
|
69
102
|
exitFocus?: string;
|
|
103
|
+
openNav?: string;
|
|
104
|
+
navigation?: string;
|
|
70
105
|
};
|
|
106
|
+
/** `ThemeSwitcher` and `DisplayPreferences` (HAR-1372): the setting names and their choices. */
|
|
107
|
+
displayPreferences?: Partial<DisplayPreferencesLabels>;
|
|
108
|
+
/** `AccountMenu` (HAR-1371): the menu's name. */
|
|
109
|
+
accountMenu?: Partial<AccountMenuLabels>;
|
|
71
110
|
sidebar?: {
|
|
72
111
|
expand?: string;
|
|
73
112
|
collapse?: string;
|
|
@@ -77,32 +116,67 @@ interface UixLabels {
|
|
|
77
116
|
};
|
|
78
117
|
/** `SearchBar` (HAR-2030): the clear button's name and the submit button's text. */
|
|
79
118
|
searchBar?: Partial<SearchBarLabels>;
|
|
80
|
-
/**
|
|
119
|
+
/**
|
|
120
|
+
* `resultsOne` / `resultsMany`: the polite result count; `{count}`. Items mode (HAR-1378):
|
|
121
|
+
* `empty` when nothing matches, `recent` the heading of the recent items.
|
|
122
|
+
*/
|
|
81
123
|
commandPalette?: {
|
|
82
124
|
input?: string;
|
|
83
125
|
resultsOne?: string;
|
|
84
126
|
resultsMany?: string;
|
|
127
|
+
empty?: string;
|
|
128
|
+
recent?: string;
|
|
85
129
|
};
|
|
130
|
+
/** `QrCode` (HAR-1251): the text shown when the value is too long for a QR code. */
|
|
131
|
+
qrCode?: Partial<QrCodeLabels>;
|
|
132
|
+
/** `CodeDisplay` (HAR-1253): the countdown, the expiry announcements, the copy button's words. */
|
|
133
|
+
codeDisplay?: Partial<CodeDisplayLabels>;
|
|
134
|
+
/** `ContactCard` (HAR-1379): the Email / Call actions and the erased and unavailable states. */
|
|
135
|
+
contactCard?: Partial<ContactCardLabels>;
|
|
136
|
+
/** `PrintSignature` (HAR-986): the captions of the signature line and the stamp box. */
|
|
137
|
+
printLayout?: Partial<PrintLayoutLabels>;
|
|
138
|
+
/** `QrScanner` (HAR-1254): the start / stop buttons, every state's title and text, the read announcement. */
|
|
139
|
+
qrScanner?: Partial<QrScannerLabels>;
|
|
86
140
|
entityPicker?: Partial<EntityPickerLabels>;
|
|
87
141
|
tree?: Partial<TreeLabels>;
|
|
88
142
|
/** `OrgChart` (HAR-1807): loading and error rows, the report count, the zoom toolbar. */
|
|
89
143
|
orgChart?: Partial<OrgChartLabels>;
|
|
90
144
|
inlineEdit?: Partial<InlineEditLabels>;
|
|
145
|
+
/** `SortableList` (HAR-1375): the grip, Move up / Move down, the move announcement. */
|
|
146
|
+
sortableList?: Partial<SortableListLabels>;
|
|
147
|
+
/** `useKeyboardGrab` (HAR-2590): picked up, dropped, cancelled; `{label}`. */
|
|
148
|
+
keyboardGrab?: Partial<KeyboardGrabLabels>;
|
|
149
|
+
/** `typeToConfirmMismatch` (HAR-1831): `{value}` is the text to type. */
|
|
91
150
|
confirmDialog?: {
|
|
92
151
|
typeToConfirm?: string;
|
|
93
152
|
compensation?: string;
|
|
153
|
+
typeToConfirmMismatch?: string;
|
|
94
154
|
};
|
|
95
155
|
schedulingCalendar?: Partial<SchedulingCalendarLabels>;
|
|
96
156
|
dateRangePicker?: Partial<DateRangePickerLabels>;
|
|
97
157
|
datePicker?: Partial<DatePickerLabels>;
|
|
98
158
|
dateTimePicker?: Partial<DateTimePickerLabels>;
|
|
159
|
+
/** `TimePicker` (HAR-1835), also the time part of `DateTimePicker`. */
|
|
160
|
+
timePicker?: Partial<TimePickerLabels>;
|
|
99
161
|
schedulingTimeline?: Partial<SchedulingTimelineLabels>;
|
|
100
162
|
textDiff?: Partial<TextDiffLabels>;
|
|
163
|
+
/** `DiffViewer` (HAR-1369): the version names, the resolution buttons, the summary. */
|
|
164
|
+
diffViewer?: Partial<DiffViewerLabels>;
|
|
165
|
+
/** `MatchReview` (HAR-1369): the decision table, bulk actions and the adopt mode. */
|
|
166
|
+
matchReview?: Partial<MatchReviewLabels>;
|
|
167
|
+
/** `AuditLog` (HAR-987): the filters, Details, Show older entries, and every state. */
|
|
168
|
+
auditLog?: Partial<AuditLogLabels>;
|
|
169
|
+
/** `DataWorkspace` (HAR-1388): the toolbar, selection, footer and states. */
|
|
170
|
+
dataWorkspace?: Partial<DataWorkspaceLabels>;
|
|
101
171
|
filterEditor?: Partial<FilterEditorLabels>;
|
|
102
172
|
select?: Partial<SelectLabels>;
|
|
103
173
|
ruleBuilder?: Partial<RuleBuilderLabels>;
|
|
104
174
|
fileUpload?: Partial<FileUploadLabels>;
|
|
105
175
|
attachment?: Partial<AttachmentLabels>;
|
|
176
|
+
/** `TagInput` (HAR-1377): the chips' × names, the announcements and the refusals. */
|
|
177
|
+
tagInput?: Partial<TagInputLabels>;
|
|
178
|
+
/** `PasswordInput` (HAR-1376): the reveal toggle's name. */
|
|
179
|
+
passwordInput?: Partial<PasswordInputLabels>;
|
|
106
180
|
/** `remove`: the name of a removable chip's × button; `{label}` is the chip text. */
|
|
107
181
|
chip?: {
|
|
108
182
|
remove?: string;
|
|
@@ -111,6 +185,8 @@ interface UixLabels {
|
|
|
111
185
|
alert?: {
|
|
112
186
|
dismiss?: string;
|
|
113
187
|
};
|
|
188
|
+
/** Not words: the date format of every date field (HAR-2432). See {@link UixDateFormat}. */
|
|
189
|
+
dateFormat?: UixDateFormat;
|
|
114
190
|
/** Read by `useUixLabels()` callers; `Pagination` itself is server-safe and takes `labels`. */
|
|
115
191
|
pagination?: Partial<PaginationLabels>;
|
|
116
192
|
/** Read by `useUixLabels()` callers; `BulkBar` itself is server-safe and takes `label`. */
|
|
@@ -118,6 +194,20 @@ interface UixLabels {
|
|
|
118
194
|
region?: string;
|
|
119
195
|
};
|
|
120
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* One date format for every date field below the provider (HAR-2432): `DatePicker`,
|
|
199
|
+
* `DateTimePicker`, `DateRangePicker` and `TimePicker` (its `locale`). Each field's own prop wins.
|
|
200
|
+
*/
|
|
201
|
+
interface UixDateFormat {
|
|
202
|
+
/** The locale of the field's text, month and weekday names, and the clock. */
|
|
203
|
+
locale?: string;
|
|
204
|
+
/** How a field writes a `YYYY-MM-DD` date, e.g. `(d) => d.split('-').reverse().join('.')`. */
|
|
205
|
+
formatDate?: (date: string) => string;
|
|
206
|
+
/** Read typed text into `YYYY-MM-DD`, or `null` when it is not a date. Pass it with `formatDate`. */
|
|
207
|
+
parseDate?: (text: string) => string | null;
|
|
208
|
+
/** The date field's placeholder, e.g. `TT.MM.JJJJ`. */
|
|
209
|
+
placeholder?: string;
|
|
210
|
+
}
|
|
121
211
|
interface UixLabelsProviderProps {
|
|
122
212
|
labels: UixLabels;
|
|
123
213
|
children?: ReactNode;
|
|
@@ -127,4 +217,4 @@ declare function UixLabelsProvider({ labels, children }: UixLabelsProviderProps)
|
|
|
127
217
|
/** The chrome strings in effect here (empty outside a provider). */
|
|
128
218
|
declare function useUixLabels(): UixLabels;
|
|
129
219
|
|
|
130
|
-
export { type UixLabels, UixLabelsProvider, type UixLabelsProviderProps, useUixLabels };
|
|
220
|
+
export { type UixDateFormat, type UixLabels, UixLabelsProvider, type UixLabelsProviderProps, useUixLabels };
|
package/dist/motion.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
declare const KEY_OPENED = "data-uix-key-opened";
|
|
2
|
+
/** Start following the input modality (idempotent; capture phase, so nothing can hide it). */
|
|
3
|
+
declare function watchInputModality(): void;
|
|
4
|
+
/** Was the input that led here a key press? `false` before any input and on the server. */
|
|
5
|
+
declare function keyboardInitiated(): boolean;
|
|
6
|
+
/** Mark `el` instant when the current open or close came from the keyboard; clear it otherwise. */
|
|
7
|
+
declare function markKeyOpened(el: Element | null | undefined): void;
|
|
8
|
+
/** A time token (`--uix-dur-exit`) in milliseconds, read from `el` (default: the root), or `fallback`. */
|
|
9
|
+
declare function tokenMs(name: string, fallback: number, el?: Element | null): number;
|
|
10
|
+
|
|
11
|
+
export { KEY_OPENED, keyboardInitiated, markKeyOpened, tokenMs, watchInputModality };
|
package/dist/motion.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const KEY_OPENED = "data-uix-key-opened";
|
|
2
|
+
let keyboard = false;
|
|
3
|
+
let watching = false;
|
|
4
|
+
function watchInputModality() {
|
|
5
|
+
if (watching || typeof document === "undefined") return;
|
|
6
|
+
watching = true;
|
|
7
|
+
document.addEventListener("keydown", (event) => {
|
|
8
|
+
if (!["Shift", "Control", "Alt", "Meta"].includes(event.key)) keyboard = true;
|
|
9
|
+
}, true);
|
|
10
|
+
document.addEventListener("pointerdown", () => {
|
|
11
|
+
keyboard = false;
|
|
12
|
+
}, true);
|
|
13
|
+
}
|
|
14
|
+
function keyboardInitiated() {
|
|
15
|
+
return keyboard;
|
|
16
|
+
}
|
|
17
|
+
function markKeyOpened(el) {
|
|
18
|
+
if (!el) return;
|
|
19
|
+
if (keyboard) el.setAttribute(KEY_OPENED, "");
|
|
20
|
+
else el.removeAttribute(KEY_OPENED);
|
|
21
|
+
}
|
|
22
|
+
function tokenMs(name, fallback, el) {
|
|
23
|
+
if (typeof getComputedStyle === "undefined" || typeof document === "undefined") return fallback;
|
|
24
|
+
const raw = getComputedStyle(el ?? document.documentElement).getPropertyValue(name).trim();
|
|
25
|
+
const m = /^(-?\d*\.?\d+)(ms|s)$/.exec(raw);
|
|
26
|
+
if (!m) return fallback;
|
|
27
|
+
return m[2] === "s" ? Number(m[1]) * 1e3 : Number(m[1]);
|
|
28
|
+
}
|
|
29
|
+
export {
|
|
30
|
+
KEY_OPENED,
|
|
31
|
+
keyboardInitiated,
|
|
32
|
+
markKeyOpened,
|
|
33
|
+
tokenMs,
|
|
34
|
+
watchInputModality
|
|
35
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Register an open overlay; the returned function removes it (call it when it closes). */
|
|
2
|
+
declare function pushLayer(token: object): () => void;
|
|
3
|
+
/** Whether `token` is the newest open overlay. */
|
|
4
|
+
declare const isTopLayer: (token: object) => boolean;
|
|
5
|
+
|
|
6
|
+
export { isTopLayer, pushLayer };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const layers = [];
|
|
2
|
+
function pushLayer(token) {
|
|
3
|
+
layers.push(token);
|
|
4
|
+
return () => {
|
|
5
|
+
const i = layers.lastIndexOf(token);
|
|
6
|
+
if (i >= 0) layers.splice(i, 1);
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
const isTopLayer = (token) => layers[layers.length - 1] === token;
|
|
10
|
+
export {
|
|
11
|
+
isTopLayer,
|
|
12
|
+
pushLayer
|
|
13
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A QR Code encoder (ISO/IEC 18004) for `QrCode` (HAR-1251): byte mode (UTF-8), the four
|
|
3
|
+
* error-correction levels, versions 1 to 40, all eight masks scored by the standard's
|
|
4
|
+
* penalty rules. Pure and dependency-free, so a consumer never pulls a QR library in for a
|
|
5
|
+
* poster or a voucher. `qr-model.test.mjs` decodes its output with a reference decoder.
|
|
6
|
+
*
|
|
7
|
+
* The algorithm follows the standard's own construction (function patterns, Reed-Solomon over
|
|
8
|
+
* GF(256) with 0x11D, zig-zag placement, BCH-coded format and version information).
|
|
9
|
+
*/
|
|
10
|
+
/** How much of the symbol can be lost and still read: about 7, 15, 25 and 30 % of codewords. */
|
|
11
|
+
type QrErrorCorrection = 'L' | 'M' | 'Q' | 'H';
|
|
12
|
+
interface QrMatrix {
|
|
13
|
+
/** 1 to 40. Each version is 4 modules wider than the one before (version 1 is 21 × 21). */
|
|
14
|
+
version: number;
|
|
15
|
+
/** Modules per side, without the quiet zone. */
|
|
16
|
+
size: number;
|
|
17
|
+
errorCorrection: QrErrorCorrection;
|
|
18
|
+
/** The mask the penalty rules chose, 0 to 7. */
|
|
19
|
+
mask: number;
|
|
20
|
+
/** `modules[y][x]` is true for a dark module. */
|
|
21
|
+
modules: boolean[][];
|
|
22
|
+
}
|
|
23
|
+
interface QrEncodeOptions {
|
|
24
|
+
/** Default `M`: survives a crease or a smudge on a printed poster. */
|
|
25
|
+
errorCorrection?: QrErrorCorrection;
|
|
26
|
+
/**
|
|
27
|
+
* The smallest version to use (1 to 40); a larger one is chosen when the text needs it. A
|
|
28
|
+
* value that is not a finite number throws a `RangeError` (it is a mistake, not a long text).
|
|
29
|
+
*/
|
|
30
|
+
minVersion?: number;
|
|
31
|
+
/**
|
|
32
|
+
* Mark text with characters beyond ASCII as UTF-8 with an ECI 26 designator (12 bits before
|
|
33
|
+
* the data). Off by default: most scanners read UTF-8 without it and a few old ones misread a
|
|
34
|
+
* symbol that has one; turn it on for a scanner that assumes ISO 8859-1 otherwise.
|
|
35
|
+
*/
|
|
36
|
+
eci?: boolean;
|
|
37
|
+
/** Force a mask (0 to 7) instead of the lowest-penalty one; for tests. */
|
|
38
|
+
mask?: number;
|
|
39
|
+
}
|
|
40
|
+
/** Thrown when the text does not fit in version 40 at the requested level. */
|
|
41
|
+
declare class QrCapacityError extends Error {
|
|
42
|
+
readonly bytes: number;
|
|
43
|
+
readonly errorCorrection: QrErrorCorrection;
|
|
44
|
+
constructor(bytes: number, errorCorrection: QrErrorCorrection);
|
|
45
|
+
}
|
|
46
|
+
/** Data codewords (bytes) a version holds at a level. */
|
|
47
|
+
declare function qrDataCapacity(version: number, errorCorrection: QrErrorCorrection): number;
|
|
48
|
+
/**
|
|
49
|
+
* The smallest version that holds `bytes` bytes at a level, or undefined past version 40.
|
|
50
|
+
* `headerBits` counts bits before the byte segment (12 for an ECI designator).
|
|
51
|
+
*/
|
|
52
|
+
declare function qrVersionFor(bytes: number, errorCorrection: QrErrorCorrection, minVersion?: number, headerBits?: number): number | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* Encodes `text` (as UTF-8 bytes) into a QR matrix: the smallest version that fits at the
|
|
55
|
+
* level, the mask with the lowest penalty. Throws `QrCapacityError` past version 40
|
|
56
|
+
* (2,953 bytes at L, 1,273 at H).
|
|
57
|
+
*/
|
|
58
|
+
declare function encodeQr(text: string, options?: QrEncodeOptions): QrMatrix;
|
|
59
|
+
/**
|
|
60
|
+
* The dark modules as one SVG path in module units, offset by `margin` (the quiet zone):
|
|
61
|
+
* one `h`-run per stretch of dark modules in a row, so a version-10 symbol is one short path.
|
|
62
|
+
*/
|
|
63
|
+
declare function qrPath(matrix: QrMatrix, margin?: number): string;
|
|
64
|
+
|
|
65
|
+
export { QrCapacityError, type QrEncodeOptions, type QrErrorCorrection, type QrMatrix, encodeQr, qrDataCapacity, qrPath, qrVersionFor };
|
package/dist/qr-model.js
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
class QrCapacityError extends Error {
|
|
2
|
+
constructor(bytes, errorCorrection) {
|
|
3
|
+
super(`QR: ${bytes} bytes do not fit in version 40 at error correction ${errorCorrection}`);
|
|
4
|
+
this.name = "QrCapacityError";
|
|
5
|
+
this.bytes = bytes;
|
|
6
|
+
this.errorCorrection = errorCorrection;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
const LEVEL_INDEX = { L: 0, M: 1, Q: 2, H: 3 };
|
|
10
|
+
const FORMAT_BITS = { L: 1, M: 0, Q: 3, H: 2 };
|
|
11
|
+
const ECC_PER_BLOCK = [
|
|
12
|
+
[-1, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
|
|
13
|
+
[-1, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28],
|
|
14
|
+
[-1, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
|
|
15
|
+
[-1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]
|
|
16
|
+
];
|
|
17
|
+
const BLOCKS = [
|
|
18
|
+
[-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25],
|
|
19
|
+
[-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49],
|
|
20
|
+
[-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68],
|
|
21
|
+
[-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81]
|
|
22
|
+
];
|
|
23
|
+
function rawDataModules(version) {
|
|
24
|
+
let result = (16 * version + 128) * version + 64;
|
|
25
|
+
if (version >= 2) {
|
|
26
|
+
const align = Math.floor(version / 7) + 2;
|
|
27
|
+
result -= (25 * align - 10) * align - 55;
|
|
28
|
+
if (version >= 7) result -= 36;
|
|
29
|
+
}
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
function qrDataCapacity(version, errorCorrection) {
|
|
33
|
+
const level = LEVEL_INDEX[errorCorrection];
|
|
34
|
+
return Math.floor(rawDataModules(version) / 8) - ECC_PER_BLOCK[level][version] * BLOCKS[level][version];
|
|
35
|
+
}
|
|
36
|
+
const segmentBits = (bytes, version) => 4 + (version <= 9 ? 8 : 16) + bytes * 8;
|
|
37
|
+
const ECI_UTF8_BITS = 12;
|
|
38
|
+
function qrVersionFor(bytes, errorCorrection, minVersion = 1, headerBits = 0) {
|
|
39
|
+
if (!Number.isFinite(minVersion)) throw new RangeError(`QR: minVersion must be a number from 1 to 40, not ${minVersion}`);
|
|
40
|
+
for (let version = Math.max(1, Math.min(40, Math.floor(minVersion))); version <= 40; version += 1) {
|
|
41
|
+
if (bytes < (version <= 9 ? 256 : 65536) && headerBits + segmentBits(bytes, version) <= qrDataCapacity(version, errorCorrection) * 8) return version;
|
|
42
|
+
}
|
|
43
|
+
return void 0;
|
|
44
|
+
}
|
|
45
|
+
function gfMultiply(x, y) {
|
|
46
|
+
let z = 0;
|
|
47
|
+
for (let i = 7; i >= 0; i -= 1) {
|
|
48
|
+
z = z << 1 ^ (z >>> 7) * 285;
|
|
49
|
+
z ^= (y >>> i & 1) * x;
|
|
50
|
+
}
|
|
51
|
+
return z;
|
|
52
|
+
}
|
|
53
|
+
function rsDivisor(degree) {
|
|
54
|
+
const result = new Array(degree).fill(0);
|
|
55
|
+
result[degree - 1] = 1;
|
|
56
|
+
let root = 1;
|
|
57
|
+
for (let i = 0; i < degree; i += 1) {
|
|
58
|
+
for (let j = 0; j < result.length; j += 1) {
|
|
59
|
+
result[j] = gfMultiply(result[j], root);
|
|
60
|
+
if (j + 1 < result.length) result[j] ^= result[j + 1];
|
|
61
|
+
}
|
|
62
|
+
root = gfMultiply(root, 2);
|
|
63
|
+
}
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
function rsRemainder(data, divisor) {
|
|
67
|
+
const result = divisor.map(() => 0);
|
|
68
|
+
for (const byte of data) {
|
|
69
|
+
const factor = byte ^ result.shift();
|
|
70
|
+
result.push(0);
|
|
71
|
+
divisor.forEach((coefficient, i) => {
|
|
72
|
+
result[i] ^= gfMultiply(coefficient, factor);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
function withErrorCorrection(data, version, errorCorrection) {
|
|
78
|
+
const level = LEVEL_INDEX[errorCorrection];
|
|
79
|
+
const blockCount = BLOCKS[level][version];
|
|
80
|
+
const eccLength = ECC_PER_BLOCK[level][version];
|
|
81
|
+
const rawCodewords = Math.floor(rawDataModules(version) / 8);
|
|
82
|
+
const shortBlocks = blockCount - rawCodewords % blockCount;
|
|
83
|
+
const shortLength = Math.floor(rawCodewords / blockCount);
|
|
84
|
+
const divisor = rsDivisor(eccLength);
|
|
85
|
+
const blocks = [];
|
|
86
|
+
for (let i = 0, k = 0; i < blockCount; i += 1) {
|
|
87
|
+
const block = data.slice(k, k + shortLength - eccLength + (i < shortBlocks ? 0 : 1));
|
|
88
|
+
k += block.length;
|
|
89
|
+
const ecc = rsRemainder(block, divisor);
|
|
90
|
+
if (i < shortBlocks) block.push(0);
|
|
91
|
+
blocks.push(block.concat(ecc));
|
|
92
|
+
}
|
|
93
|
+
const result = [];
|
|
94
|
+
for (let i = 0; i < blocks[0].length; i += 1) {
|
|
95
|
+
blocks.forEach((block, j) => {
|
|
96
|
+
if (i !== shortLength - eccLength || j >= shortBlocks) result.push(block[i]);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
function dataCodewords(bytes, version, errorCorrection, eci) {
|
|
102
|
+
const bits = [];
|
|
103
|
+
const append = (value, length) => {
|
|
104
|
+
for (let i = length - 1; i >= 0; i -= 1) bits.push(value >>> i & 1);
|
|
105
|
+
};
|
|
106
|
+
if (eci) {
|
|
107
|
+
append(7, 4);
|
|
108
|
+
append(26, 8);
|
|
109
|
+
}
|
|
110
|
+
append(4, 4);
|
|
111
|
+
append(bytes.length, version <= 9 ? 8 : 16);
|
|
112
|
+
for (const byte of bytes) append(byte, 8);
|
|
113
|
+
const capacity = qrDataCapacity(version, errorCorrection) * 8;
|
|
114
|
+
append(0, Math.min(4, capacity - bits.length));
|
|
115
|
+
append(0, (8 - bits.length % 8) % 8);
|
|
116
|
+
for (let pad = 236; bits.length < capacity; pad ^= 236 ^ 17) append(pad, 8);
|
|
117
|
+
const codewords = [];
|
|
118
|
+
for (let i = 0; i < bits.length; i += 8) codewords.push(bits.slice(i, i + 8).reduce((byte, bit) => byte << 1 | bit, 0));
|
|
119
|
+
return codewords;
|
|
120
|
+
}
|
|
121
|
+
function alignmentPositions(version) {
|
|
122
|
+
if (version === 1) return [];
|
|
123
|
+
const count = Math.floor(version / 7) + 2;
|
|
124
|
+
const step = Math.floor((version * 8 + count * 3 + 5) / (count * 4 - 4)) * 2;
|
|
125
|
+
const result = [6];
|
|
126
|
+
for (let position = version * 4 + 17 - 7; result.length < count; position -= step) result.splice(1, 0, position);
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
const MASKS = [
|
|
130
|
+
(x, y) => (x + y) % 2 === 0,
|
|
131
|
+
(_x, y) => y % 2 === 0,
|
|
132
|
+
(x) => x % 3 === 0,
|
|
133
|
+
(x, y) => (x + y) % 3 === 0,
|
|
134
|
+
(x, y) => (Math.floor(x / 3) + Math.floor(y / 2)) % 2 === 0,
|
|
135
|
+
(x, y) => x * y % 2 + x * y % 3 === 0,
|
|
136
|
+
(x, y) => (x * y % 2 + x * y % 3) % 2 === 0,
|
|
137
|
+
(x, y) => ((x + y) % 2 + x * y % 3) % 2 === 0
|
|
138
|
+
];
|
|
139
|
+
class QrSymbol {
|
|
140
|
+
constructor(version, errorCorrection) {
|
|
141
|
+
this.version = version;
|
|
142
|
+
this.errorCorrection = errorCorrection;
|
|
143
|
+
this.size = version * 4 + 17;
|
|
144
|
+
this.modules = Array.from({ length: this.size }, () => new Array(this.size).fill(false));
|
|
145
|
+
this.reserved = Array.from({ length: this.size }, () => new Array(this.size).fill(false));
|
|
146
|
+
this.drawFunctionPatterns();
|
|
147
|
+
}
|
|
148
|
+
set(x, y, dark) {
|
|
149
|
+
this.modules[y][x] = dark;
|
|
150
|
+
this.reserved[y][x] = true;
|
|
151
|
+
}
|
|
152
|
+
drawFunctionPatterns() {
|
|
153
|
+
const { size } = this;
|
|
154
|
+
for (let i = 0; i < size; i += 1) {
|
|
155
|
+
this.set(6, i, i % 2 === 0);
|
|
156
|
+
this.set(i, 6, i % 2 === 0);
|
|
157
|
+
}
|
|
158
|
+
for (const [cx, cy] of [[3, 3], [size - 4, 3], [3, size - 4]]) {
|
|
159
|
+
for (let dy = -4; dy <= 4; dy += 1) {
|
|
160
|
+
for (let dx = -4; dx <= 4; dx += 1) {
|
|
161
|
+
const x = cx + dx;
|
|
162
|
+
const y = cy + dy;
|
|
163
|
+
if (x < 0 || x >= size || y < 0 || y >= size) continue;
|
|
164
|
+
const ring = Math.max(Math.abs(dx), Math.abs(dy));
|
|
165
|
+
this.set(x, y, ring !== 2 && ring !== 4);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const positions = alignmentPositions(this.version);
|
|
170
|
+
const last = positions.length - 1;
|
|
171
|
+
positions.forEach((cx, i) => positions.forEach((cy, j) => {
|
|
172
|
+
if (i === 0 && j === 0 || i === 0 && j === last || i === last && j === 0) return;
|
|
173
|
+
for (let dy = -2; dy <= 2; dy += 1) {
|
|
174
|
+
for (let dx = -2; dx <= 2; dx += 1) this.set(cx + dx, cy + dy, Math.max(Math.abs(dx), Math.abs(dy)) !== 1);
|
|
175
|
+
}
|
|
176
|
+
}));
|
|
177
|
+
this.drawFormat(0);
|
|
178
|
+
this.drawVersion();
|
|
179
|
+
}
|
|
180
|
+
drawFormat(mask) {
|
|
181
|
+
const data = FORMAT_BITS[this.errorCorrection] << 3 | mask;
|
|
182
|
+
let remainder = data;
|
|
183
|
+
for (let i = 0; i < 10; i += 1) remainder = remainder << 1 ^ (remainder >>> 9) * 1335;
|
|
184
|
+
const bits = (data << 10 | remainder) ^ 21522;
|
|
185
|
+
const bit = (i) => (bits >>> i & 1) !== 0;
|
|
186
|
+
const { size } = this;
|
|
187
|
+
for (let i = 0; i <= 5; i += 1) this.set(8, i, bit(i));
|
|
188
|
+
this.set(8, 7, bit(6));
|
|
189
|
+
this.set(8, 8, bit(7));
|
|
190
|
+
this.set(7, 8, bit(8));
|
|
191
|
+
for (let i = 9; i < 15; i += 1) this.set(14 - i, 8, bit(i));
|
|
192
|
+
for (let i = 0; i < 8; i += 1) this.set(size - 1 - i, 8, bit(i));
|
|
193
|
+
for (let i = 8; i < 15; i += 1) this.set(8, size - 15 + i, bit(i));
|
|
194
|
+
this.set(8, size - 8, true);
|
|
195
|
+
}
|
|
196
|
+
drawVersion() {
|
|
197
|
+
if (this.version < 7) return;
|
|
198
|
+
let remainder = this.version;
|
|
199
|
+
for (let i = 0; i < 12; i += 1) remainder = remainder << 1 ^ (remainder >>> 11) * 7973;
|
|
200
|
+
const bits = this.version << 12 | remainder;
|
|
201
|
+
for (let i = 0; i < 18; i += 1) {
|
|
202
|
+
const dark = (bits >>> i & 1) !== 0;
|
|
203
|
+
const a = this.size - 11 + i % 3;
|
|
204
|
+
const b = Math.floor(i / 3);
|
|
205
|
+
this.set(a, b, dark);
|
|
206
|
+
this.set(b, a, dark);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
drawCodewords(codewords) {
|
|
210
|
+
const { size } = this;
|
|
211
|
+
let i = 0;
|
|
212
|
+
for (let right = size - 1; right >= 1; right -= 2) {
|
|
213
|
+
if (right === 6) right = 5;
|
|
214
|
+
for (let vertical = 0; vertical < size; vertical += 1) {
|
|
215
|
+
for (let j = 0; j < 2; j += 1) {
|
|
216
|
+
const x = right - j;
|
|
217
|
+
const upward = (right + 1 & 2) === 0;
|
|
218
|
+
const y = upward ? size - 1 - vertical : vertical;
|
|
219
|
+
if (this.reserved[y][x] || i >= codewords.length * 8) continue;
|
|
220
|
+
this.modules[y][x] = (codewords[i >>> 3] >>> 7 - (i & 7) & 1) !== 0;
|
|
221
|
+
i += 1;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/** XORs a mask over the data modules; applying it twice undoes it. */
|
|
227
|
+
applyMask(mask) {
|
|
228
|
+
const flip = MASKS[mask];
|
|
229
|
+
for (let y = 0; y < this.size; y += 1) {
|
|
230
|
+
for (let x = 0; x < this.size; x += 1) {
|
|
231
|
+
if (!this.reserved[y][x] && flip(x, y)) this.modules[y][x] = !this.modules[y][x];
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/** The standard's four penalty rules: runs, 2 × 2 blocks, finder look-alikes, dark balance. */
|
|
236
|
+
penalty() {
|
|
237
|
+
const { size, modules } = this;
|
|
238
|
+
let score = 0;
|
|
239
|
+
const line = (get) => {
|
|
240
|
+
let run = 1;
|
|
241
|
+
for (let i = 1; i <= size; i += 1) {
|
|
242
|
+
if (i < size && get(i) === get(i - 1)) {
|
|
243
|
+
run += 1;
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
if (run >= 5) score += 3 + (run - 5);
|
|
247
|
+
run = 1;
|
|
248
|
+
}
|
|
249
|
+
for (let i = 0; i + 11 <= size; i += 1) {
|
|
250
|
+
const window = Array.from({ length: 11 }, (_, k) => get(i + k));
|
|
251
|
+
const core = window[4] && !window[5] && window[6] && window[7] && window[8] && !window[9] && window[10];
|
|
252
|
+
const coreReverse = window[0] && !window[1] && window[2] && window[3] && window[4] && !window[5] && window[6];
|
|
253
|
+
if (core && !window[0] && !window[1] && !window[2] && !window[3]) score += 40;
|
|
254
|
+
if (coreReverse && !window[7] && !window[8] && !window[9] && !window[10]) score += 40;
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
for (let y = 0; y < size; y += 1) line((x) => modules[y][x]);
|
|
258
|
+
for (let x = 0; x < size; x += 1) line((y) => modules[y][x]);
|
|
259
|
+
let dark = 0;
|
|
260
|
+
for (let y = 0; y < size; y += 1) {
|
|
261
|
+
for (let x = 0; x < size; x += 1) {
|
|
262
|
+
const value = modules[y][x];
|
|
263
|
+
if (value) dark += 1;
|
|
264
|
+
if (x + 1 < size && y + 1 < size && value === modules[y][x + 1] && value === modules[y + 1][x] && value === modules[y + 1][x + 1]) score += 3;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
const total = size * size;
|
|
268
|
+
score += (Math.ceil(Math.abs(dark * 20 - total * 10) / total) - 1) * 10;
|
|
269
|
+
return score;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
function utf8(text) {
|
|
273
|
+
if (typeof TextEncoder !== "undefined") return new TextEncoder().encode(text);
|
|
274
|
+
const escaped = unescape(encodeURIComponent(text));
|
|
275
|
+
return Uint8Array.from(escaped, (c) => c.charCodeAt(0));
|
|
276
|
+
}
|
|
277
|
+
function encodeQr(text, options = {}) {
|
|
278
|
+
const errorCorrection = options.errorCorrection ?? "M";
|
|
279
|
+
const bytes = utf8(text);
|
|
280
|
+
const eci = options.eci === true && bytes.some((byte) => byte >= 128);
|
|
281
|
+
const version = qrVersionFor(bytes.length, errorCorrection, options.minVersion ?? 1, eci ? ECI_UTF8_BITS : 0);
|
|
282
|
+
if (version === void 0) throw new QrCapacityError(bytes.length, errorCorrection);
|
|
283
|
+
const symbol = new QrSymbol(version, errorCorrection);
|
|
284
|
+
symbol.drawCodewords(withErrorCorrection(dataCodewords(bytes, version, errorCorrection, eci), version, errorCorrection));
|
|
285
|
+
let mask = options.mask;
|
|
286
|
+
if (mask === void 0) {
|
|
287
|
+
let best = Infinity;
|
|
288
|
+
for (let candidate = 0; candidate < 8; candidate += 1) {
|
|
289
|
+
symbol.applyMask(candidate);
|
|
290
|
+
symbol.drawFormat(candidate);
|
|
291
|
+
const score = symbol.penalty();
|
|
292
|
+
if (score < best) {
|
|
293
|
+
best = score;
|
|
294
|
+
mask = candidate;
|
|
295
|
+
}
|
|
296
|
+
symbol.applyMask(candidate);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
symbol.applyMask(mask);
|
|
300
|
+
symbol.drawFormat(mask);
|
|
301
|
+
return { version, size: symbol.size, errorCorrection, mask, modules: symbol.modules };
|
|
302
|
+
}
|
|
303
|
+
function qrPath(matrix, margin = 4) {
|
|
304
|
+
const parts = [];
|
|
305
|
+
matrix.modules.forEach((row, y) => {
|
|
306
|
+
for (let x = 0; x < row.length; x += 1) {
|
|
307
|
+
if (!row[x]) continue;
|
|
308
|
+
let end = x;
|
|
309
|
+
while (end + 1 < row.length && row[end + 1]) end += 1;
|
|
310
|
+
const length = end - x + 1;
|
|
311
|
+
parts.push(`M${x + margin} ${y + margin}h${length}v1h-${length}z`);
|
|
312
|
+
x = end;
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
return parts.join("");
|
|
316
|
+
}
|
|
317
|
+
export {
|
|
318
|
+
QrCapacityError,
|
|
319
|
+
encodeQr,
|
|
320
|
+
qrDataCapacity,
|
|
321
|
+
qrPath,
|
|
322
|
+
qrVersionFor
|
|
323
|
+
};
|