@hjmds/design-contracts 1.13.1 → 1.14.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/dist/agreement.d.ts +7 -1
- package/dist/agreement.d.ts.map +1 -1
- package/dist/agreement.js +14 -3
- package/dist/agreement.js.map +1 -1
- package/dist/behaviors.d.ts +1 -1
- package/dist/catalog.d.ts +4 -0
- package/dist/catalog.d.ts.map +1 -1
- package/dist/content-transition.d.ts +17 -0
- package/dist/content-transition.d.ts.map +1 -1
- package/dist/content-transition.js +21 -0
- package/dist/content-transition.js.map +1 -1
- package/dist/date-entry.d.ts +71 -0
- package/dist/date-entry.d.ts.map +1 -0
- package/dist/date-entry.js +78 -0
- package/dist/date-entry.js.map +1 -0
- package/dist/document-resource.d.ts +104 -0
- package/dist/document-resource.d.ts.map +1 -0
- package/dist/document-resource.js +77 -0
- package/dist/document-resource.js.map +1 -0
- package/dist/effect-surface.d.ts +6 -1
- package/dist/effect-surface.d.ts.map +1 -1
- package/dist/effect-surface.js +5 -2
- package/dist/effect-surface.js.map +1 -1
- package/dist/field-group.d.ts +47 -0
- package/dist/field-group.d.ts.map +1 -0
- package/dist/field-group.js +92 -0
- package/dist/field-group.js.map +1 -0
- package/dist/image.d.ts +17 -0
- package/dist/image.d.ts.map +1 -1
- package/dist/image.js +19 -0
- package/dist/image.js.map +1 -1
- package/dist/internal/effect-noise.d.ts +2 -0
- package/dist/internal/effect-noise.d.ts.map +1 -0
- package/dist/internal/effect-noise.js +4 -0
- package/dist/internal/effect-noise.js.map +1 -0
- package/dist/progressive-blur.d.ts +32 -0
- package/dist/progressive-blur.d.ts.map +1 -0
- package/dist/progressive-blur.js +28 -0
- package/dist/progressive-blur.js.map +1 -0
- package/dist/reference-controls.d.ts +32 -0
- package/dist/reference-controls.d.ts.map +1 -0
- package/dist/reference-controls.js +28 -0
- package/dist/reference-controls.js.map +1 -0
- package/dist/scroll-progress.d.ts +7 -1
- package/dist/scroll-progress.d.ts.map +1 -1
- package/dist/scroll-progress.js +21 -2
- package/dist/scroll-progress.js.map +1 -1
- package/dist/text-annotation.d.ts +43 -0
- package/dist/text-annotation.d.ts.map +1 -0
- package/dist/text-annotation.js +137 -0
- package/dist/text-annotation.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/docs/agreement.md +14 -0
- package/docs/dialog.md +16 -1
- package/docs/effect-surface.md +19 -3
- package/docs/generated/component-maturity.md +1 -1
- package/docs/generated/renderer-evidence.json +3 -3
- package/docs/generated/renderer-evidence.md +1 -1
- package/docs/generated/showcase-manifest.json +1 -1
- package/docs/image.md +17 -0
- package/docs/optional-adapters.md +25 -0
- package/docs/popover.md +15 -0
- package/docs/rating.md +6 -1
- package/docs/reference-controls.md +40 -0
- package/docs/task-list.md +15 -1
- package/docs/text-annotation.md +85 -0
- package/docs/usage/README.md +18 -1
- package/docs/usage/components/agreement.md +13 -3
- package/docs/usage/components/alert-dialog.md +7 -1
- package/docs/usage/components/avatar.md +33 -1
- package/docs/usage/components/card.md +7 -1
- package/docs/usage/components/carousel.md +5 -1
- package/docs/usage/components/chat-message.md +11 -1
- package/docs/usage/components/chip.md +5 -0
- package/docs/usage/components/content-transition.md +28 -4
- package/docs/usage/components/dialog.md +18 -1
- package/docs/usage/components/effect-surface.md +4 -2
- package/docs/usage/components/empty-state.md +10 -2
- package/docs/usage/components/field.md +23 -0
- package/docs/usage/components/form.md +6 -1
- package/docs/usage/components/image-comparison.md +82 -0
- package/docs/usage/components/image.md +81 -2
- package/docs/usage/components/keyboard-avoiding.md +6 -1
- package/docs/usage/components/link.md +3 -1
- package/docs/usage/components/list-row.md +3 -1
- package/docs/usage/components/list.md +6 -1
- package/docs/usage/components/message-composer.md +5 -0
- package/docs/usage/components/popover.md +7 -1
- package/docs/usage/components/progress.md +28 -0
- package/docs/usage/components/progressive-blur.md +113 -0
- package/docs/usage/components/rating.md +74 -0
- package/docs/usage/components/search-field.md +10 -0
- package/docs/usage/components/search-screen.md +5 -0
- package/docs/usage/components/segmented-control.md +17 -0
- package/docs/usage/components/statistic.md +11 -0
- package/docs/usage/components/tags-input.md +5 -0
- package/docs/usage/components/toast.md +5 -0
- package/docs/usage/components/upload-item.md +3 -1
- package/docs/usage/compositions/action-feedback.md +77 -0
- package/docs/usage/compositions/adaptive-content.md +81 -0
- package/docs/usage/compositions/context-toolbar.md +85 -0
- package/docs/usage/compositions/date-entry.md +108 -0
- package/docs/usage/compositions/document-resource.md +124 -0
- package/docs/usage/compositions/field-group.md +104 -0
- package/docs/usage/compositions/illustrated-outcome.md +91 -0
- package/docs/usage/compositions/live-list.md +104 -0
- package/docs/usage/compositions/optional-adapters.md +1 -1
- package/docs/usage/compositions/origin-dialog.md +108 -0
- package/docs/usage/compositions/selection-motion.md +73 -0
- package/docs/usage/compositions/texture-comparison.md +86 -0
- package/docs/usage/compositions/upload-recovery.md +80 -0
- package/docs/usage/compositions/video-dialog.md +100 -0
- package/docs/usage/screens/flow-onboarding.md +5 -3
- package/docs/usage/screens/product-bento.md +117 -0
- package/package.json +37 -1
package/dist/agreement.d.ts
CHANGED
|
@@ -29,6 +29,8 @@ export type AgreementDescriptor<Id extends string = string> = Readonly<{
|
|
|
29
29
|
/** 전체 동의 행의 라벨. 필수이므로 renderer가 임의 문구를 만들지 않는다. */
|
|
30
30
|
allLabel: string;
|
|
31
31
|
items: readonly AgreementItemDescriptor<Id>[];
|
|
32
|
+
/** Freeze consent changes during submission; detail reading remains available. */
|
|
33
|
+
disabled?: boolean;
|
|
32
34
|
}>;
|
|
33
35
|
export declare function validateAgreementDescriptor<Id extends string>(descriptor: AgreementDescriptor<Id>): void;
|
|
34
36
|
export type AgreementState<Id extends string = string> = Readonly<{
|
|
@@ -130,6 +132,9 @@ export declare const agreementRecipe: {
|
|
|
130
132
|
alpha?: number;
|
|
131
133
|
}>;
|
|
132
134
|
};
|
|
135
|
+
readonly itemLayout: {
|
|
136
|
+
readonly labelBasis: "70%";
|
|
137
|
+
};
|
|
133
138
|
readonly detail: {
|
|
134
139
|
readonly color: Readonly<{
|
|
135
140
|
source: "theme";
|
|
@@ -158,11 +163,12 @@ export declare const agreementRecipe: {
|
|
|
158
163
|
readonly width: 2;
|
|
159
164
|
readonly offset: 2;
|
|
160
165
|
};
|
|
166
|
+
readonly disabledOpacity: 0.5;
|
|
161
167
|
};
|
|
162
168
|
};
|
|
163
169
|
export declare const agreementBehavior: {
|
|
164
170
|
readonly controlled: readonly ["checkedIds", "defaultCheckedIds", "onCheckedIdsChange"];
|
|
165
|
-
readonly inputs: readonly ["items", "allLabel", "accessibilityLabel"];
|
|
171
|
+
readonly inputs: readonly ["items", "allLabel", "accessibilityLabel", "disabled"];
|
|
166
172
|
readonly events: readonly ["onDetail"];
|
|
167
173
|
readonly stateAxes: {
|
|
168
174
|
readonly availability: readonly ["enabled", "disabled"];
|
package/dist/agreement.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agreement.d.ts","sourceRoot":"","sources":["../src/agreement.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,qBAAqB,EAC1B,KAAK,aAAa,EACnB,MAAM,wBAAwB,CAAC;AAEhC;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,uBAAuB,CAAC,EAAE,SAAS,MAAM,GAAG,MAAM,IAC5D,qBAAqB,CAAC,EAAE,CAAC,GACvB,QAAQ,CAAC;IACP,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,MAAM,CAAC,EAAE,QAAQ,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrD,CAAC,CAAC;AAEP,MAAM,MAAM,mBAAmB,CAAC,EAAE,SAAS,MAAM,GAAG,MAAM,IAAI,QAAQ,CAAC;IACrE,0CAA0C;IAC1C,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,uBAAuB,CAAC,EAAE,CAAC,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"agreement.d.ts","sourceRoot":"","sources":["../src/agreement.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,qBAAqB,EAC1B,KAAK,aAAa,EACnB,MAAM,wBAAwB,CAAC;AAEhC;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,uBAAuB,CAAC,EAAE,SAAS,MAAM,GAAG,MAAM,IAC5D,qBAAqB,CAAC,EAAE,CAAC,GACvB,QAAQ,CAAC;IACP,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,MAAM,CAAC,EAAE,QAAQ,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrD,CAAC,CAAC;AAEP,MAAM,MAAM,mBAAmB,CAAC,EAAE,SAAS,MAAM,GAAG,MAAM,IAAI,QAAQ,CAAC;IACrE,0CAA0C;IAC1C,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,uBAAuB,CAAC,EAAE,CAAC,EAAE,CAAC;IAC9C,kFAAkF;IAClF,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC,CAAC;AAQH,wBAAgB,2BAA2B,CAAC,EAAE,SAAS,MAAM,EAC3D,UAAU,EAAE,mBAAmB,CAAC,EAAE,CAAC,GAClC,IAAI,CA0BN;AAED,MAAM,MAAM,cAAc,CAAC,EAAE,SAAS,MAAM,GAAG,MAAM,IAAI,QAAQ,CAAC;IAChE,8CAA8C;IAC9C,GAAG,EAAE,aAAa,CAAC;IACnB,yCAAyC;IACzC,SAAS,EAAE,OAAO,CAAC;IACnB,gDAAgD;IAChD,kBAAkB,EAAE,SAAS,EAAE,EAAE,CAAC;CACnC,CAAC,CAAC;AAEH;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,SAAS,MAAM,EACrD,UAAU,EAAE,mBAAmB,CAAC,EAAE,CAAC,EACnC,UAAU,EAAE,WAAW,CAAC,EAAE,CAAC,GAC1B,cAAc,CAAC,EAAE,CAAC,CAapB;AAED,gDAAgD;AAChD,wBAAgB,mBAAmB,CAAC,EAAE,SAAS,MAAM,EACnD,UAAU,EAAE,mBAAmB,CAAC,EAAE,CAAC,EACnC,UAAU,EAAE,WAAW,CAAC,EAAE,CAAC,EAC3B,EAAE,EAAE,EAAE,GACL,WAAW,CAAC,EAAE,CAAC,CAMjB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAClD,UAAU,EAAE,mBAAmB,CAAC,EAAE,CAAC,EACnC,UAAU,EAAE,WAAW,CAAC,EAAE,CAAC,GAC1B,WAAW,CAAC,EAAE,CAAC,CAUjB;AAED,gCAAgC;AAChC,wBAAgB,2BAA2B,CAAC,EAAE,SAAS,MAAM,EAC3D,UAAU,EAAE,mBAAmB,CAAC,EAAE,CAAC,EACnC,UAAU,EAAE,WAAW,CAAC,EAAE,CAAC,GAC1B,WAAW,CAAC,EAAE,CAAC,CAGjB;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0C3B,CAAC;AAEF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;CA4BO,CAAC"}
|
package/dist/agreement.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { collectionItemContract, focusIndicatorContract } from "./component-contracts.js";
|
|
2
|
-
import { control, spacing } from "./foundations.js";
|
|
2
|
+
import { control, opacity, spacing } from "./foundations.js";
|
|
3
3
|
import { semanticColors } from "./semantic-colors.js";
|
|
4
4
|
import { reconcileCheckboxSelection, toggleCheckboxSelection, } from "./selection-helpers.js";
|
|
5
5
|
function assertNonEmpty(value, field) {
|
|
@@ -13,6 +13,8 @@ export function validateAgreementDescriptor(descriptor) {
|
|
|
13
13
|
if (!Array.isArray(descriptor.items) || descriptor.items.length === 0) {
|
|
14
14
|
throw new RangeError("Agreement must contain at least one item");
|
|
15
15
|
}
|
|
16
|
+
if (descriptor.disabled !== undefined && typeof descriptor.disabled !== "boolean")
|
|
17
|
+
throw new TypeError("Agreement disabled must be a boolean");
|
|
16
18
|
const ids = new Set();
|
|
17
19
|
for (const item of descriptor.items) {
|
|
18
20
|
assertNonEmpty(item.id, "item id");
|
|
@@ -54,6 +56,10 @@ export function resolveAgreementState(descriptor, checkedIds) {
|
|
|
54
56
|
/** 개별 항목 토글. 비활성 항목 보호는 공용 helper가 이미 갖고 있다. */
|
|
55
57
|
export function toggleAgreementItem(descriptor, checkedIds, id) {
|
|
56
58
|
validateAgreementDescriptor(descriptor);
|
|
59
|
+
// Utilverse registration must freeze required consents during a request.
|
|
60
|
+
// Disabling each required item is invalid and would change the denominator.
|
|
61
|
+
if (descriptor.disabled)
|
|
62
|
+
return checkedIds;
|
|
57
63
|
return toggleCheckboxSelection(descriptor.items, checkedIds, id);
|
|
58
64
|
}
|
|
59
65
|
/**
|
|
@@ -63,6 +69,8 @@ export function toggleAgreementItem(descriptor, checkedIds, id) {
|
|
|
63
69
|
*/
|
|
64
70
|
export function toggleAgreementAll(descriptor, checkedIds) {
|
|
65
71
|
const { all } = resolveAgreementState(descriptor, checkedIds);
|
|
72
|
+
if (descriptor.disabled)
|
|
73
|
+
return checkedIds;
|
|
66
74
|
const next = new Set(checkedIds);
|
|
67
75
|
for (const item of descriptor.items) {
|
|
68
76
|
if (item.disabled)
|
|
@@ -96,6 +104,9 @@ export const agreementRecipe = {
|
|
|
96
104
|
color: semanticColors.content.primary,
|
|
97
105
|
},
|
|
98
106
|
item: collectionItemContract,
|
|
107
|
+
// Reserve most row width for consent text. Long detail labels wrap below it
|
|
108
|
+
// instead of squeezing large Korean labels into one-character columns.
|
|
109
|
+
itemLayout: { labelBasis: "70%" },
|
|
99
110
|
detail: {
|
|
100
111
|
color: semanticColors.content.secondary,
|
|
101
112
|
textVariant: "label",
|
|
@@ -103,11 +114,11 @@ export const agreementRecipe = {
|
|
|
103
114
|
},
|
|
104
115
|
required: { color: semanticColors.content.brand, textVariant: "label" },
|
|
105
116
|
gap: spacing.xs,
|
|
106
|
-
states: { focus: focusIndicatorContract },
|
|
117
|
+
states: { focus: focusIndicatorContract, disabledOpacity: opacity.disabled },
|
|
107
118
|
};
|
|
108
119
|
export const agreementBehavior = {
|
|
109
120
|
controlled: ["checkedIds", "defaultCheckedIds", "onCheckedIdsChange"],
|
|
110
|
-
inputs: ["items", "allLabel", "accessibilityLabel"],
|
|
121
|
+
inputs: ["items", "allLabel", "accessibilityLabel", "disabled"],
|
|
111
122
|
events: ["onDetail"],
|
|
112
123
|
stateAxes: {
|
|
113
124
|
availability: ["enabled", "disabled"],
|
package/dist/agreement.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agreement.js","sourceRoot":"","sources":["../src/agreement.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BehaviorContract } from \"./behaviors.js\";\nimport type { ColorReference } from \"./color-references.js\";\nimport { collectionItemContract, focusIndicatorContract } from \"./component-contracts.js\";\nimport { control, spacing } from \"./foundations.js\";\nimport { semanticColors } from \"./semantic-colors.js\";\nimport {\n reconcileCheckboxSelection,\n toggleCheckboxSelection,\n type CheckboxSelectionItem,\n type CheckboxState,\n} from \"./selection-helpers.js\";\n\n/**\n * 가입·결제 앞에 서는 \"약관 동의\" 묶음이다. CheckboxGroup으로 매번 조립하던 것을\n * 계약으로 올리는 이유는 세 가지가 **체크박스 목록이 아니라 법적 절차**이기 때문이다.\n *\n * 1. 필수/선택이 제출 가능 여부를 결정한다 — CheckboxGroup은 그 판정을 갖지 않는다.\n * 2. 전체 동의는 자식의 합이지 별도 항목이 아니다(DataTable 머리글·TreeSelect 부모와\n * 같은 파생 관계). 저장되는 것은 개별 항목뿐이다.\n * 3. 각 항목은 \"읽을 수 있어야\" 한다 — 상세 보기 경로가 없는 동의는 동의가 아니다.\n * 그래서 `detail`은 renderer가 장식으로 넣는 화살표가 아니라 계약된 행동이다.\n *\n * 문구·링크 주소·법적 유효성은 제품이 소유한다. 이 계약은 판정과 배치만 갖는다.\n */\nexport type AgreementItemDescriptor<Id extends string = string> =\n CheckboxSelectionItem<Id> &\n Readonly<{\n /** 필수 항목은 하나라도 비면 제출을 막는다. 기본값은 선택(false). */\n required?: boolean;\n /**\n * 전문을 여는 경로. 제품이 링크(`href`)로 열지 시트로 열지는 renderer 밖의\n * 결정이라 여기서는 \"열 수 있다\"는 사실만 계약한다.\n */\n detail?: Readonly<{ label: string; href?: string }>;\n }>;\n\nexport type AgreementDescriptor<Id extends string = string> = Readonly<{\n /** 묶음 전체의 접근성 이름. \"약관 동의\"처럼 제품이 현지화한다. */\n accessibilityLabel: string;\n /** 전체 동의 행의 라벨. 필수이므로 renderer가 임의 문구를 만들지 않는다. */\n allLabel: string;\n items: readonly AgreementItemDescriptor<Id>[];\n}>;\n\nfunction assertNonEmpty(value: string, field: string): void {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new TypeError(`Agreement ${field} must not be empty`);\n }\n}\n\nexport function validateAgreementDescriptor<Id extends string>(\n descriptor: AgreementDescriptor<Id>,\n): void {\n assertNonEmpty(descriptor.accessibilityLabel, \"accessibilityLabel\");\n assertNonEmpty(descriptor.allLabel, \"allLabel\");\n if (!Array.isArray(descriptor.items) || descriptor.items.length === 0) {\n throw new RangeError(\"Agreement must contain at least one item\");\n }\n const ids = new Set<Id>();\n for (const item of descriptor.items) {\n assertNonEmpty(item.id, \"item id\");\n assertNonEmpty(item.label, \"item label\");\n if (ids.has(item.id)) throw new TypeError(`Duplicate Agreement item id: ${item.id}`);\n ids.add(item.id);\n if (item.detail !== undefined) {\n assertNonEmpty(item.detail.label, `item ${item.id} detail label`);\n }\n if (item.required === true && item.disabled === true) {\n /*\n 비활성 필수 항목은 사용자가 영원히 제출할 수 없는 화면을 만든다. 조용히\n 허용하면 \"버튼이 왜 안 눌리는지\" 알 수 없는 상태가 되므로 여기서 막는다.\n */\n throw new TypeError(\n `Agreement item ${item.id} cannot be both required and disabled`,\n );\n }\n }\n}\n\nexport type AgreementState<Id extends string = string> = Readonly<{\n /** 전체 동의 행이 그릴 tri-state. 개별 항목의 합에서만 나온다. */\n all: CheckboxState;\n /** 필수 항목이 모두 체크됐는가 — 제품의 제출 버튼이 읽는 값. */\n satisfied: boolean;\n /** 아직 체크되지 않은 필수 항목. 제품이 \"무엇이 남았는지\" 문장을 만든다. */\n missingRequiredIds: readonly Id[];\n}>;\n\n/**\n * 비활성 항목은 분모에서 뺀다 — 사용자가 바꿀 수 없는 것을 \"덜 동의했다\"고 셀 수\n * 없기 때문이다(`resolveDataTableSelectAllState`·`resolveTreeCheckedStates`와 같은 규칙).\n * 필수 항목은 비활성일 수 없으므로(위 validate) `satisfied` 판정에는 이 예외가 없다.\n */\nexport function resolveAgreementState<Id extends string>(\n descriptor: AgreementDescriptor<Id>,\n checkedIds: ReadonlySet<Id>,\n): AgreementState<Id> {\n validateAgreementDescriptor(descriptor);\n const selectable = descriptor.items.filter((item) => !item.disabled);\n const checkedCount = selectable.filter((item) => checkedIds.has(item.id)).length;\n const all: CheckboxState = selectable.length === 0 || checkedCount === 0\n ? false\n : checkedCount === selectable.length\n ? true\n : \"mixed\";\n const missingRequiredIds = descriptor.items\n .filter((item) => item.required === true && !checkedIds.has(item.id))\n .map((item) => item.id);\n return { all, satisfied: missingRequiredIds.length === 0, missingRequiredIds };\n}\n\n/** 개별 항목 토글. 비활성 항목 보호는 공용 helper가 이미 갖고 있다. */\nexport function toggleAgreementItem<Id extends string>(\n descriptor: AgreementDescriptor<Id>,\n checkedIds: ReadonlySet<Id>,\n id: Id,\n): ReadonlySet<Id> {\n validateAgreementDescriptor(descriptor);\n return toggleCheckboxSelection(descriptor.items, checkedIds, id);\n}\n\n/**\n * 전체 동의는 \"모두 체크됨\"의 반대로 간다 — mixed에서 누르면 채운다(공용\n * `getCheckboxNextState`의 기본값과 같은 관습). 비활성 항목의 현재 상태는 건드리지\n * 않는다: 그 값은 사용자가 만든 것이 아니라 제품이 고정한 것이다.\n */\nexport function toggleAgreementAll<Id extends string>(\n descriptor: AgreementDescriptor<Id>,\n checkedIds: ReadonlySet<Id>,\n): ReadonlySet<Id> {\n const { all } = resolveAgreementState(descriptor, checkedIds);\n const next = new Set(checkedIds);\n for (const item of descriptor.items) {\n if (item.disabled) continue;\n if (all === true) next.delete(item.id);\n else next.add(item.id);\n }\n return next;\n}\n\n/** 목록에서 사라진 항목의 동의는 남기지 않는다. */\nexport function reconcileAgreementSelection<Id extends string>(\n descriptor: AgreementDescriptor<Id>,\n checkedIds: ReadonlySet<Id>,\n): ReadonlySet<Id> {\n validateAgreementDescriptor(descriptor);\n return reconcileCheckboxSelection(descriptor.items, checkedIds);\n}\n\n/**\n * 전체 동의 행은 개별 행보다 시각적으로 무겁다 — 목록의 제목 역할을 하기 때문이다.\n * 나머지는 `collectionItemContract`를 그대로 쓴다(Menu·Tree·ListRow와 같은 행 chrome).\n */\nexport const agreementRecipe = {\n slots: [\"root\", \"all\", \"list\", \"item\", \"label\", \"detail\"] as const,\n all: {\n minHeight: control.minTouchTarget,\n gap: spacing.sm,\n paddingHorizontal: spacing.md,\n paddingVertical: spacing.sm,\n background: semanticColors.canvas,\n radius: \"md\" as const,\n textVariant: \"bodyLarge\" as const,\n color: semanticColors.content.primary,\n },\n item: collectionItemContract,\n detail: {\n color: semanticColors.content.secondary,\n textVariant: \"label\" as const,\n minHeight: control.minTouchTarget,\n },\n required: { color: semanticColors.content.brand, textVariant: \"label\" as const },\n gap: spacing.xs,\n states: { focus: focusIndicatorContract },\n} as const satisfies {\n slots: readonly [\"root\", \"all\", \"list\", \"item\", \"label\", \"detail\"];\n all: {\n minHeight: number;\n gap: number;\n paddingHorizontal: number;\n paddingVertical: number;\n background: ColorReference;\n radius: \"md\";\n textVariant: \"bodyLarge\";\n color: ColorReference;\n };\n item: typeof collectionItemContract;\n detail: { color: ColorReference; textVariant: \"label\"; minHeight: number };\n required: { color: ColorReference; textVariant: \"label\" };\n gap: number;\n states: { focus: typeof focusIndicatorContract };\n};\n\nexport const agreementBehavior = {\n controlled: [\"checkedIds\", \"defaultCheckedIds\", \"onCheckedIdsChange\"],\n inputs: [\"items\", \"allLabel\", \"accessibilityLabel\"],\n events: [\"onDetail\"],\n stateAxes: {\n availability: [\"enabled\", \"disabled\"],\n value: [\"unchecked\", \"checked\", \"mixed\"],\n },\n web: {\n roles: [\"group\", \"checkbox\", \"link\", \"button\"],\n keyboard: [\"Tab\", \"Space\", \"Enter\"],\n focus: \"native\",\n },\n native: {\n roles: [\"checkbox\", \"link\", \"button\"],\n states: [\"checked\", \"disabled\"],\n actions: [\"toggle\", \"toggleAll\", \"openDetail\"],\n },\n scenarios: [\n \"all-agree-is-derived-from-the-items-never-stored-as-its-own-value\",\n \"checking-all-checks-every-enabled-item-and-leaves-disabled-ones-untouched\",\n \"required-items-alone-decide-whether-the-product-may-submit\",\n \"a-required-item-can-never-be-disabled-the-descriptor-is-rejected\",\n \"every-item-may-open-its-full-text-and-that-control-is-a-separate-tab-stop\",\n \"the-detail-control-never-toggles-the-agreement-it-only-opens-the-text\",\n \"optional-items-never-block-submission-and-are-announced-as-optional\",\n \"removing-an-item-drops-its-consent-instead-of-keeping-an-orphan-id\",\n ],\n} as const satisfies BehaviorContract;\n"]}
|
|
1
|
+
{"version":3,"file":"agreement.js","sourceRoot":"","sources":["../src/agreement.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BehaviorContract } from \"./behaviors.js\";\nimport type { ColorReference } from \"./color-references.js\";\nimport { collectionItemContract, focusIndicatorContract } from \"./component-contracts.js\";\nimport { control, opacity, spacing } from \"./foundations.js\";\nimport { semanticColors } from \"./semantic-colors.js\";\nimport {\n reconcileCheckboxSelection,\n toggleCheckboxSelection,\n type CheckboxSelectionItem,\n type CheckboxState,\n} from \"./selection-helpers.js\";\n\n/**\n * 가입·결제 앞에 서는 \"약관 동의\" 묶음이다. CheckboxGroup으로 매번 조립하던 것을\n * 계약으로 올리는 이유는 세 가지가 **체크박스 목록이 아니라 법적 절차**이기 때문이다.\n *\n * 1. 필수/선택이 제출 가능 여부를 결정한다 — CheckboxGroup은 그 판정을 갖지 않는다.\n * 2. 전체 동의는 자식의 합이지 별도 항목이 아니다(DataTable 머리글·TreeSelect 부모와\n * 같은 파생 관계). 저장되는 것은 개별 항목뿐이다.\n * 3. 각 항목은 \"읽을 수 있어야\" 한다 — 상세 보기 경로가 없는 동의는 동의가 아니다.\n * 그래서 `detail`은 renderer가 장식으로 넣는 화살표가 아니라 계약된 행동이다.\n *\n * 문구·링크 주소·법적 유효성은 제품이 소유한다. 이 계약은 판정과 배치만 갖는다.\n */\nexport type AgreementItemDescriptor<Id extends string = string> =\n CheckboxSelectionItem<Id> &\n Readonly<{\n /** 필수 항목은 하나라도 비면 제출을 막는다. 기본값은 선택(false). */\n required?: boolean;\n /**\n * 전문을 여는 경로. 제품이 링크(`href`)로 열지 시트로 열지는 renderer 밖의\n * 결정이라 여기서는 \"열 수 있다\"는 사실만 계약한다.\n */\n detail?: Readonly<{ label: string; href?: string }>;\n }>;\n\nexport type AgreementDescriptor<Id extends string = string> = Readonly<{\n /** 묶음 전체의 접근성 이름. \"약관 동의\"처럼 제품이 현지화한다. */\n accessibilityLabel: string;\n /** 전체 동의 행의 라벨. 필수이므로 renderer가 임의 문구를 만들지 않는다. */\n allLabel: string;\n items: readonly AgreementItemDescriptor<Id>[];\n /** Freeze consent changes during submission; detail reading remains available. */\n disabled?: boolean;\n}>;\n\nfunction assertNonEmpty(value: string, field: string): void {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new TypeError(`Agreement ${field} must not be empty`);\n }\n}\n\nexport function validateAgreementDescriptor<Id extends string>(\n descriptor: AgreementDescriptor<Id>,\n): void {\n assertNonEmpty(descriptor.accessibilityLabel, \"accessibilityLabel\");\n assertNonEmpty(descriptor.allLabel, \"allLabel\");\n if (!Array.isArray(descriptor.items) || descriptor.items.length === 0) {\n throw new RangeError(\"Agreement must contain at least one item\");\n }\n if (descriptor.disabled !== undefined && typeof descriptor.disabled !== \"boolean\") throw new TypeError(\"Agreement disabled must be a boolean\");\n const ids = new Set<Id>();\n for (const item of descriptor.items) {\n assertNonEmpty(item.id, \"item id\");\n assertNonEmpty(item.label, \"item label\");\n if (ids.has(item.id)) throw new TypeError(`Duplicate Agreement item id: ${item.id}`);\n ids.add(item.id);\n if (item.detail !== undefined) {\n assertNonEmpty(item.detail.label, `item ${item.id} detail label`);\n }\n if (item.required === true && item.disabled === true) {\n /*\n 비활성 필수 항목은 사용자가 영원히 제출할 수 없는 화면을 만든다. 조용히\n 허용하면 \"버튼이 왜 안 눌리는지\" 알 수 없는 상태가 되므로 여기서 막는다.\n */\n throw new TypeError(\n `Agreement item ${item.id} cannot be both required and disabled`,\n );\n }\n }\n}\n\nexport type AgreementState<Id extends string = string> = Readonly<{\n /** 전체 동의 행이 그릴 tri-state. 개별 항목의 합에서만 나온다. */\n all: CheckboxState;\n /** 필수 항목이 모두 체크됐는가 — 제품의 제출 버튼이 읽는 값. */\n satisfied: boolean;\n /** 아직 체크되지 않은 필수 항목. 제품이 \"무엇이 남았는지\" 문장을 만든다. */\n missingRequiredIds: readonly Id[];\n}>;\n\n/**\n * 비활성 항목은 분모에서 뺀다 — 사용자가 바꿀 수 없는 것을 \"덜 동의했다\"고 셀 수\n * 없기 때문이다(`resolveDataTableSelectAllState`·`resolveTreeCheckedStates`와 같은 규칙).\n * 필수 항목은 비활성일 수 없으므로(위 validate) `satisfied` 판정에는 이 예외가 없다.\n */\nexport function resolveAgreementState<Id extends string>(\n descriptor: AgreementDescriptor<Id>,\n checkedIds: ReadonlySet<Id>,\n): AgreementState<Id> {\n validateAgreementDescriptor(descriptor);\n const selectable = descriptor.items.filter((item) => !item.disabled);\n const checkedCount = selectable.filter((item) => checkedIds.has(item.id)).length;\n const all: CheckboxState = selectable.length === 0 || checkedCount === 0\n ? false\n : checkedCount === selectable.length\n ? true\n : \"mixed\";\n const missingRequiredIds = descriptor.items\n .filter((item) => item.required === true && !checkedIds.has(item.id))\n .map((item) => item.id);\n return { all, satisfied: missingRequiredIds.length === 0, missingRequiredIds };\n}\n\n/** 개별 항목 토글. 비활성 항목 보호는 공용 helper가 이미 갖고 있다. */\nexport function toggleAgreementItem<Id extends string>(\n descriptor: AgreementDescriptor<Id>,\n checkedIds: ReadonlySet<Id>,\n id: Id,\n): ReadonlySet<Id> {\n validateAgreementDescriptor(descriptor);\n // Utilverse registration must freeze required consents during a request.\n // Disabling each required item is invalid and would change the denominator.\n if (descriptor.disabled) return checkedIds;\n return toggleCheckboxSelection(descriptor.items, checkedIds, id);\n}\n\n/**\n * 전체 동의는 \"모두 체크됨\"의 반대로 간다 — mixed에서 누르면 채운다(공용\n * `getCheckboxNextState`의 기본값과 같은 관습). 비활성 항목의 현재 상태는 건드리지\n * 않는다: 그 값은 사용자가 만든 것이 아니라 제품이 고정한 것이다.\n */\nexport function toggleAgreementAll<Id extends string>(\n descriptor: AgreementDescriptor<Id>,\n checkedIds: ReadonlySet<Id>,\n): ReadonlySet<Id> {\n const { all } = resolveAgreementState(descriptor, checkedIds);\n if (descriptor.disabled) return checkedIds;\n const next = new Set(checkedIds);\n for (const item of descriptor.items) {\n if (item.disabled) continue;\n if (all === true) next.delete(item.id);\n else next.add(item.id);\n }\n return next;\n}\n\n/** 목록에서 사라진 항목의 동의는 남기지 않는다. */\nexport function reconcileAgreementSelection<Id extends string>(\n descriptor: AgreementDescriptor<Id>,\n checkedIds: ReadonlySet<Id>,\n): ReadonlySet<Id> {\n validateAgreementDescriptor(descriptor);\n return reconcileCheckboxSelection(descriptor.items, checkedIds);\n}\n\n/**\n * 전체 동의 행은 개별 행보다 시각적으로 무겁다 — 목록의 제목 역할을 하기 때문이다.\n * 나머지는 `collectionItemContract`를 그대로 쓴다(Menu·Tree·ListRow와 같은 행 chrome).\n */\nexport const agreementRecipe = {\n slots: [\"root\", \"all\", \"list\", \"item\", \"label\", \"detail\"] as const,\n all: {\n minHeight: control.minTouchTarget,\n gap: spacing.sm,\n paddingHorizontal: spacing.md,\n paddingVertical: spacing.sm,\n background: semanticColors.canvas,\n radius: \"md\" as const,\n textVariant: \"bodyLarge\" as const,\n color: semanticColors.content.primary,\n },\n item: collectionItemContract,\n // Reserve most row width for consent text. Long detail labels wrap below it\n // instead of squeezing large Korean labels into one-character columns.\n itemLayout: { labelBasis: \"70%\" as const },\n detail: {\n color: semanticColors.content.secondary,\n textVariant: \"label\" as const,\n minHeight: control.minTouchTarget,\n },\n required: { color: semanticColors.content.brand, textVariant: \"label\" as const },\n gap: spacing.xs,\n states: { focus: focusIndicatorContract, disabledOpacity: opacity.disabled },\n} as const satisfies {\n slots: readonly [\"root\", \"all\", \"list\", \"item\", \"label\", \"detail\"];\n all: {\n minHeight: number;\n gap: number;\n paddingHorizontal: number;\n paddingVertical: number;\n background: ColorReference;\n radius: \"md\";\n textVariant: \"bodyLarge\";\n color: ColorReference;\n };\n item: typeof collectionItemContract;\n itemLayout: { labelBasis: \"70%\" };\n detail: { color: ColorReference; textVariant: \"label\"; minHeight: number };\n required: { color: ColorReference; textVariant: \"label\" };\n gap: number;\n states: { focus: typeof focusIndicatorContract; disabledOpacity: number };\n};\n\nexport const agreementBehavior = {\n controlled: [\"checkedIds\", \"defaultCheckedIds\", \"onCheckedIdsChange\"],\n inputs: [\"items\", \"allLabel\", \"accessibilityLabel\", \"disabled\"],\n events: [\"onDetail\"],\n stateAxes: {\n availability: [\"enabled\", \"disabled\"],\n value: [\"unchecked\", \"checked\", \"mixed\"],\n },\n web: {\n roles: [\"group\", \"checkbox\", \"link\", \"button\"],\n keyboard: [\"Tab\", \"Space\", \"Enter\"],\n focus: \"native\",\n },\n native: {\n roles: [\"checkbox\", \"link\", \"button\"],\n states: [\"checked\", \"disabled\"],\n actions: [\"toggle\", \"toggleAll\", \"openDetail\"],\n },\n scenarios: [\n \"all-agree-is-derived-from-the-items-never-stored-as-its-own-value\",\n \"checking-all-checks-every-enabled-item-and-leaves-disabled-ones-untouched\",\n \"required-items-alone-decide-whether-the-product-may-submit\",\n \"a-required-item-can-never-be-disabled-the-descriptor-is-rejected\",\n \"every-item-may-open-its-full-text-and-that-control-is-a-separate-tab-stop\",\n \"the-detail-control-never-toggles-the-agreement-it-only-opens-the-text\",\n \"optional-items-never-block-submission-and-are-announced-as-optional\",\n \"removing-an-item-drops-its-consent-instead-of-keeping-an-orphan-id\",\n ],\n} as const satisfies BehaviorContract;\n"]}
|
package/dist/behaviors.d.ts
CHANGED
|
@@ -702,7 +702,7 @@ export declare const behaviorRegistry: {
|
|
|
702
702
|
};
|
|
703
703
|
readonly agreement: {
|
|
704
704
|
readonly controlled: readonly ["checkedIds", "defaultCheckedIds", "onCheckedIdsChange"];
|
|
705
|
-
readonly inputs: readonly ["items", "allLabel", "accessibilityLabel"];
|
|
705
|
+
readonly inputs: readonly ["items", "allLabel", "accessibilityLabel", "disabled"];
|
|
706
706
|
readonly events: readonly ["onDetail"];
|
|
707
707
|
readonly stateAxes: {
|
|
708
708
|
readonly availability: readonly ["enabled", "disabled"];
|
package/dist/catalog.d.ts
CHANGED
|
@@ -2175,6 +2175,9 @@ export declare const recipeRegistry: {
|
|
|
2175
2175
|
alpha?: number;
|
|
2176
2176
|
}>;
|
|
2177
2177
|
};
|
|
2178
|
+
readonly itemLayout: {
|
|
2179
|
+
readonly labelBasis: "70%";
|
|
2180
|
+
};
|
|
2178
2181
|
readonly detail: {
|
|
2179
2182
|
readonly color: Readonly<{
|
|
2180
2183
|
source: "theme";
|
|
@@ -2203,6 +2206,7 @@ export declare const recipeRegistry: {
|
|
|
2203
2206
|
readonly width: 2;
|
|
2204
2207
|
readonly offset: 2;
|
|
2205
2208
|
};
|
|
2209
|
+
readonly disabledOpacity: 0.5;
|
|
2206
2210
|
};
|
|
2207
2211
|
};
|
|
2208
2212
|
readonly topRecipe: {
|
package/dist/catalog.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiGjB,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,YAAY,GACZ,cAAc,GACd,UAAU,GACV,SAAS,GACT,UAAU,GACV,SAAS,CAAC;AAEd,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,UAAU,GAAG,KAAK,GAAG,QAAQ,CAAC;AACzE,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,YAAY,CAAC;AAC3E,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,QAAQ,CAAC;AAChD,MAAM,MAAM,sBAAsB,GAAG,eAAe,GAAG,aAAa,CAAC;AACrE,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAC7C,MAAM,CAAC,gBAAgB,EAAE,sBAAsB,CAAC,CACjD,CAAC;AACF,MAAM,MAAM,qBAAqB,GAC7B,gBAAgB,GAChB,UAAU,GACV,iBAAiB,GACjB,cAAc,GACd,UAAU,CAAC;AAEf,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,KAAK,EAAE,qBAAqB,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B,CAAC,CAAC;AAEH,MAAM,MAAM,0BAA0B,GAAG,kBAAkB,CAAC;AAE5D,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,iFAAiF;IACjF,MAAM,EAAE,eAAe,CAAC;IACxB;;;;OAIG;IACH,aAAa,CAAC,EAAE,wBAAwB,CAAC;IACzC,qFAAqF;IACrF,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,kFAAkF;IAClF,iBAAiB,CAAC,EAAE,0BAA0B,CAAC;IAC/C,kFAAkF;IAClF,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC,CAAC;AAOH,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM;;;;;CAElC,CAAC;AAYZ,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,EAAE,SAAS,SAAS,MAAM,EAAE;;;;;;CAE7D,CAAC;AAOZ;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,qBAAqB,EAC5B,OAAO,EAAE,gBAAgB,GACxB,sBAAsB,CAKxB;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsJwB,CAAC;AAEtD,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,SAAS,qBAAqB,EAAqB,GAC3D,QAAQ,CAAC,MAAM,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC,CAcjD;AA6FD,mFAAmF;AACnF,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiGjB,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,cAAc,CAAC"}
|
|
@@ -14,4 +14,21 @@ export declare function resolveContentTransition(preset?: ContentTransitionPrese
|
|
|
14
14
|
translateY: number;
|
|
15
15
|
scale: number;
|
|
16
16
|
};
|
|
17
|
+
/** Both rectangles must be measured in the same physical viewport coordinates.
|
|
18
|
+
* Router shared-element IDs are not a substitute for a local overlay's geometry. */
|
|
19
|
+
export type TransitionRect = Readonly<{
|
|
20
|
+
x: number;
|
|
21
|
+
y: number;
|
|
22
|
+
width: number;
|
|
23
|
+
height: number;
|
|
24
|
+
}>;
|
|
25
|
+
/** Invert the destination around its center so it starts at the trigger bounds.
|
|
26
|
+
* A renderer interpolates this transform to identity and owns cancellation,
|
|
27
|
+
* measurement freshness, presence and focus; this resolver never clones content. */
|
|
28
|
+
export declare function resolveOriginTransition(origin: TransitionRect | null | undefined, destination: TransitionRect | null | undefined, reducedMotion?: boolean): Readonly<{
|
|
29
|
+
translateX: number;
|
|
30
|
+
translateY: number;
|
|
31
|
+
scaleX: number;
|
|
32
|
+
scaleY: number;
|
|
33
|
+
}> | null;
|
|
17
34
|
//# sourceMappingURL=content-transition.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-transition.d.ts","sourceRoot":"","sources":["../src/content-transition.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAC1E;oFACoF;AACpF,eAAO,MAAM,uBAAuB;;;;CAAgD,CAAC;AACrF;8EAC8E;AAC9E,wBAAgB,wBAAwB,CAAC,MAAM,GAAE,uBAAgC,EAAE,SAAS,GAAE,KAAK,GAAG,KAAa;;;;;EAQlH"}
|
|
1
|
+
{"version":3,"file":"content-transition.d.ts","sourceRoot":"","sources":["../src/content-transition.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAC1E;oFACoF;AACpF,eAAO,MAAM,uBAAuB;;;;CAAgD,CAAC;AACrF;8EAC8E;AAC9E,wBAAgB,wBAAwB,CAAC,MAAM,GAAE,uBAAgC,EAAE,SAAS,GAAE,KAAK,GAAG,KAAa;;;;;EAQlH;AAED;oFACoF;AACpF,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE/F;;oFAEoF;AACpF,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS,EACzC,WAAW,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS,EAC9C,aAAa,UAAQ,GACpB,QAAQ,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,CAe7F"}
|
|
@@ -12,4 +12,25 @@ export function resolveContentTransition(preset = "fade", direction = "ltr") {
|
|
|
12
12
|
default: throw new TypeError("Unsupported content transition preset");
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
+
/** Invert the destination around its center so it starts at the trigger bounds.
|
|
16
|
+
* A renderer interpolates this transform to identity and owns cancellation,
|
|
17
|
+
* measurement freshness, presence and focus; this resolver never clones content. */
|
|
18
|
+
export function resolveOriginTransition(origin, destination, reducedMotion = false) {
|
|
19
|
+
// Missing/zero geometry occurs before layout and after trigger removal. Keep
|
|
20
|
+
// the canonical overlay available instead of throwing or guessing coordinates.
|
|
21
|
+
if (reducedMotion || !origin || !destination)
|
|
22
|
+
return null;
|
|
23
|
+
for (const rect of [origin, destination]) {
|
|
24
|
+
if (![rect.x, rect.y, rect.width, rect.height].every(Number.isFinite) || rect.width <= 0 || rect.height <= 0)
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const transform = {
|
|
28
|
+
translateX: (origin.x - destination.x) + (origin.width - destination.width) / 2,
|
|
29
|
+
translateY: (origin.y - destination.y) + (origin.height - destination.height) / 2,
|
|
30
|
+
scaleX: origin.width / destination.width,
|
|
31
|
+
scaleY: origin.height / destination.height,
|
|
32
|
+
};
|
|
33
|
+
// Finite measurements can still overflow or underflow during subtraction/division.
|
|
34
|
+
return Object.values(transform).every(Number.isFinite) && transform.scaleX > 0 && transform.scaleY > 0 ? transform : null;
|
|
35
|
+
}
|
|
15
36
|
//# sourceMappingURL=content-transition.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-transition.js","sourceRoot":"","sources":["../src/content-transition.ts"],"names":[],"mappings":"AACA;oFACoF;AACpF,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAW,CAAC;AACrF;8EAC8E;AAC9E,MAAM,UAAU,wBAAwB,CAAC,SAAkC,MAAM,EAAE,YAA2B,KAAK;IACjH,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,MAAM,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAC3E,KAAK,MAAM,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,uBAAuB,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QACtG,KAAK,OAAO,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,uBAAuB,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QACzI,KAAK,OAAO,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,uBAAuB,CAAC,KAAK,EAAE,CAAC;QACxG,OAAO,CAAC,CAAC,MAAM,IAAI,SAAS,CAAC,uCAAuC,CAAC,CAAC;IACxE,CAAC;AACH,CAAC","sourcesContent":["export type ContentTransitionPreset = \"fade\" | \"rise\" | \"slide\" | \"scale\";\n/** Small local travel preserves context; these are presentation values, never\n * gesture activation thresholds. Retain the existing geometry for compatibility. */\nexport const contentTransitionMotion = { rise: 12, slide: 16, scale: 0.96 } as const;\n/** Bounded travel keeps decorative motion close to the destination.\n * Single-subtree recipes: preserve wrapping, focus and accessible content. */\nexport function resolveContentTransition(preset: ContentTransitionPreset = \"fade\", direction: \"ltr\" | \"rtl\" = \"ltr\") {\n switch (preset) {\n case \"fade\": return { opacity: 0, translateX: 0, translateY: 0, scale: 1 };\n case \"rise\": return { opacity: 0, translateX: 0, translateY: contentTransitionMotion.rise, scale: 1 };\n case \"slide\": return { opacity: 0, translateX: (direction === \"rtl\" ? -1 : 1) * contentTransitionMotion.slide, translateY: 0, scale: 1 };\n case \"scale\": return { opacity: 0, translateX: 0, translateY: 0, scale: contentTransitionMotion.scale };\n default: throw new TypeError(\"Unsupported content transition preset\");\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"content-transition.js","sourceRoot":"","sources":["../src/content-transition.ts"],"names":[],"mappings":"AACA;oFACoF;AACpF,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAW,CAAC;AACrF;8EAC8E;AAC9E,MAAM,UAAU,wBAAwB,CAAC,SAAkC,MAAM,EAAE,YAA2B,KAAK;IACjH,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,MAAM,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAC3E,KAAK,MAAM,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,uBAAuB,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QACtG,KAAK,OAAO,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,uBAAuB,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QACzI,KAAK,OAAO,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,uBAAuB,CAAC,KAAK,EAAE,CAAC;QACxG,OAAO,CAAC,CAAC,MAAM,IAAI,SAAS,CAAC,uCAAuC,CAAC,CAAC;IACxE,CAAC;AACH,CAAC;AAMD;;oFAEoF;AACpF,MAAM,UAAU,uBAAuB,CACrC,MAAyC,EACzC,WAA8C,EAC9C,aAAa,GAAG,KAAK;IAErB,6EAA6E;IAC7E,+EAA+E;IAC/E,IAAI,aAAa,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAC1D,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;IAC5H,CAAC;IACD,MAAM,SAAS,GAAG;QAChB,UAAU,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC;QAC/E,UAAU,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC;QACjF,MAAM,EAAE,MAAM,CAAC,KAAK,GAAG,WAAW,CAAC,KAAK;QACxC,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM;KAC3C,CAAC;IACF,mFAAmF;IACnF,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5H,CAAC","sourcesContent":["export type ContentTransitionPreset = \"fade\" | \"rise\" | \"slide\" | \"scale\";\n/** Small local travel preserves context; these are presentation values, never\n * gesture activation thresholds. Retain the existing geometry for compatibility. */\nexport const contentTransitionMotion = { rise: 12, slide: 16, scale: 0.96 } as const;\n/** Bounded travel keeps decorative motion close to the destination.\n * Single-subtree recipes: preserve wrapping, focus and accessible content. */\nexport function resolveContentTransition(preset: ContentTransitionPreset = \"fade\", direction: \"ltr\" | \"rtl\" = \"ltr\") {\n switch (preset) {\n case \"fade\": return { opacity: 0, translateX: 0, translateY: 0, scale: 1 };\n case \"rise\": return { opacity: 0, translateX: 0, translateY: contentTransitionMotion.rise, scale: 1 };\n case \"slide\": return { opacity: 0, translateX: (direction === \"rtl\" ? -1 : 1) * contentTransitionMotion.slide, translateY: 0, scale: 1 };\n case \"scale\": return { opacity: 0, translateX: 0, translateY: 0, scale: contentTransitionMotion.scale };\n default: throw new TypeError(\"Unsupported content transition preset\");\n }\n}\n\n/** Both rectangles must be measured in the same physical viewport coordinates.\n * Router shared-element IDs are not a substitute for a local overlay's geometry. */\nexport type TransitionRect = Readonly<{ x: number; y: number; width: number; height: number }>;\n\n/** Invert the destination around its center so it starts at the trigger bounds.\n * A renderer interpolates this transform to identity and owns cancellation,\n * measurement freshness, presence and focus; this resolver never clones content. */\nexport function resolveOriginTransition(\n origin: TransitionRect | null | undefined,\n destination: TransitionRect | null | undefined,\n reducedMotion = false,\n): Readonly<{ translateX: number; translateY: number; scaleX: number; scaleY: number }> | null {\n // Missing/zero geometry occurs before layout and after trigger removal. Keep\n // the canonical overlay available instead of throwing or guessing coordinates.\n if (reducedMotion || !origin || !destination) return null;\n for (const rect of [origin, destination]) {\n if (![rect.x, rect.y, rect.width, rect.height].every(Number.isFinite) || rect.width <= 0 || rect.height <= 0) return null;\n }\n const transform = {\n translateX: (origin.x - destination.x) + (origin.width - destination.width) / 2,\n translateY: (origin.y - destination.y) + (origin.height - destination.height) / 2,\n scaleX: origin.width / destination.width,\n scaleY: origin.height / destination.height,\n };\n // Finite measurements can still overflow or underflow during subtraction/division.\n return Object.values(transform).every(Number.isFinite) && transform.scaleX > 0 && transform.scaleY > 0 ? transform : null;\n}\n"]}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/** Experimental direct date entry contract; date calculation remains product-owned. */
|
|
2
|
+
export type DateEntryPart = "year" | "month" | "day";
|
|
3
|
+
export type DateEntryDraft = Readonly<Record<DateEntryPart, string>>;
|
|
4
|
+
export type DateEntryOrder = readonly [DateEntryPart, DateEntryPart, DateEntryPart];
|
|
5
|
+
export type DateEntryParseResult = Readonly<{
|
|
6
|
+
status: "valid";
|
|
7
|
+
value: string;
|
|
8
|
+
}> | Readonly<{
|
|
9
|
+
status: "incomplete" | "invalid";
|
|
10
|
+
code: string;
|
|
11
|
+
fields: readonly DateEntryPart[];
|
|
12
|
+
}>;
|
|
13
|
+
export type DateEntryIssue = Readonly<{
|
|
14
|
+
kind: "missing";
|
|
15
|
+
fields: readonly DateEntryPart[];
|
|
16
|
+
}> | Readonly<{
|
|
17
|
+
kind: "parse";
|
|
18
|
+
code: string;
|
|
19
|
+
fields: readonly DateEntryPart[];
|
|
20
|
+
}>;
|
|
21
|
+
export type ResolvedDateEntry = Readonly<{
|
|
22
|
+
draft: DateEntryDraft;
|
|
23
|
+
status: "empty" | "incomplete" | "invalid" | "valid";
|
|
24
|
+
/** An optional empty date and any uncommitted draft have no committed value. */
|
|
25
|
+
value: string | null;
|
|
26
|
+
issue: DateEntryIssue | null;
|
|
27
|
+
fields: readonly Readonly<{
|
|
28
|
+
part: DateEntryPart;
|
|
29
|
+
value: string;
|
|
30
|
+
invalid: boolean;
|
|
31
|
+
}>[];
|
|
32
|
+
}>;
|
|
33
|
+
/** Preserve exact input, including partial years, names, whitespace and composition text. */
|
|
34
|
+
export declare function updateDateEntryDraft(draft: DateEntryDraft, part: DateEntryPart, value: string): DateEntryDraft;
|
|
35
|
+
export declare function resolveDateEntryDraft({ draft, order, required, parse }: {
|
|
36
|
+
draft: DateEntryDraft;
|
|
37
|
+
order: DateEntryOrder;
|
|
38
|
+
required: boolean;
|
|
39
|
+
parse: (draft: DateEntryDraft) => DateEntryParseResult;
|
|
40
|
+
}): ResolvedDateEntry;
|
|
41
|
+
export type DateEntryControlProps = Readonly<{
|
|
42
|
+
value: DateEntryDraft;
|
|
43
|
+
onValueChange: (draft: DateEntryDraft) => void;
|
|
44
|
+
order: DateEntryOrder;
|
|
45
|
+
parse: (draft: DateEntryDraft) => DateEntryParseResult;
|
|
46
|
+
labels: Readonly<Record<DateEntryPart | "label", string>>;
|
|
47
|
+
formatIssue: (issue: DateEntryIssue) => string;
|
|
48
|
+
description?: string;
|
|
49
|
+
required?: boolean;
|
|
50
|
+
disabled?: boolean;
|
|
51
|
+
readOnly?: boolean;
|
|
52
|
+
/** Products reveal validation on submit/blur; typing never forces errors visible. */
|
|
53
|
+
showErrors?: boolean;
|
|
54
|
+
purpose?: "date" | "birthdate";
|
|
55
|
+
/** Text is the default so localized month names remain enterable. */
|
|
56
|
+
monthInput?: "text" | "numeric";
|
|
57
|
+
onBlur?: (part: DateEntryPart) => void;
|
|
58
|
+
}>;
|
|
59
|
+
export declare function resolveDateEntryControl(props: DateEntryControlProps): {
|
|
60
|
+
error: string | undefined;
|
|
61
|
+
draft: DateEntryDraft;
|
|
62
|
+
status: "empty" | "incomplete" | "invalid" | "valid";
|
|
63
|
+
value: string | null;
|
|
64
|
+
issue: DateEntryIssue | null;
|
|
65
|
+
fields: readonly Readonly<{
|
|
66
|
+
part: DateEntryPart;
|
|
67
|
+
value: string;
|
|
68
|
+
invalid: boolean;
|
|
69
|
+
}>[];
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=date-entry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date-entry.d.ts","sourceRoot":"","sources":["../src/date-entry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
const parts = ["year", "month", "day"];
|
|
2
|
+
function assertDraft(draft) {
|
|
3
|
+
if (!draft || parts.some(part => typeof draft[part] !== "string")) {
|
|
4
|
+
throw new TypeError("Date entry requires string drafts for year, month and day");
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
function assertParts(values, complete = false) {
|
|
8
|
+
if (!Array.isArray(values) || !values.length || new Set(values).size !== values.length ||
|
|
9
|
+
values.some(part => !parts.includes(part)) || (complete && values.length !== 3)) {
|
|
10
|
+
throw new TypeError("Date entry requires distinct date parts and a complete display order");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/** Preserve exact input, including partial years, names, whitespace and composition text. */
|
|
14
|
+
export function updateDateEntryDraft(draft, part, value) {
|
|
15
|
+
assertDraft(draft);
|
|
16
|
+
if (!parts.includes(part) || typeof value !== "string")
|
|
17
|
+
throw new TypeError("Invalid date entry edit");
|
|
18
|
+
return { ...draft, [part]: value };
|
|
19
|
+
}
|
|
20
|
+
export function resolveDateEntryDraft({ draft, order, required, parse }) {
|
|
21
|
+
assertDraft(draft);
|
|
22
|
+
assertParts(order, true);
|
|
23
|
+
if (typeof required !== "boolean" || typeof parse !== "function")
|
|
24
|
+
throw new TypeError("Date entry requires required and parse policies");
|
|
25
|
+
// Calendar already leaves locale/calendar/clock policy to products. A second
|
|
26
|
+
// Date-based parser would normalize impossible dates and disagree with it.
|
|
27
|
+
// Freeze a snapshot so an adapter cannot rewrite the user's editing draft.
|
|
28
|
+
const snapshot = Object.freeze({ year: draft.year, month: draft.month, day: draft.day });
|
|
29
|
+
const missing = order.filter(part => !snapshot[part].trim());
|
|
30
|
+
let status;
|
|
31
|
+
let value = null;
|
|
32
|
+
let issue = null;
|
|
33
|
+
if (missing.length === 3) {
|
|
34
|
+
status = "empty";
|
|
35
|
+
if (required)
|
|
36
|
+
issue = { kind: "missing", fields: missing };
|
|
37
|
+
}
|
|
38
|
+
else if (missing.length) {
|
|
39
|
+
// Missing data takes priority over format/range errors, so filling one part
|
|
40
|
+
// cannot hide which other parts are still needed (GOV.UK date-input guidance).
|
|
41
|
+
status = "incomplete";
|
|
42
|
+
issue = { kind: "missing", fields: missing };
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
const result = parse(snapshot);
|
|
46
|
+
if (result?.status === "valid") {
|
|
47
|
+
if (typeof result.value !== "string" || !result.value.trim())
|
|
48
|
+
throw new TypeError("A valid date entry needs a nonempty value");
|
|
49
|
+
status = "valid";
|
|
50
|
+
value = result.value;
|
|
51
|
+
}
|
|
52
|
+
else if (result?.status === "incomplete" || result?.status === "invalid") {
|
|
53
|
+
if (typeof result.code !== "string" || !result.code.trim())
|
|
54
|
+
throw new TypeError("Date entry issue needs a localization code");
|
|
55
|
+
assertParts(result.fields);
|
|
56
|
+
status = result.status;
|
|
57
|
+
issue = { kind: "parse", code: result.code, fields: order.filter(part => result.fields.includes(part)) };
|
|
58
|
+
}
|
|
59
|
+
else
|
|
60
|
+
throw new TypeError("Invalid date entry parse result");
|
|
61
|
+
}
|
|
62
|
+
return { draft: snapshot, status, value, issue,
|
|
63
|
+
fields: order.map(part => ({ part, value: snapshot[part], invalid: issue?.fields.includes(part) ?? false })) };
|
|
64
|
+
}
|
|
65
|
+
export function resolveDateEntryControl(props) {
|
|
66
|
+
if (["label", ...parts].some(key => !props.labels?.[key]?.trim()) ||
|
|
67
|
+
typeof props.onValueChange !== "function" || typeof props.formatIssue !== "function" ||
|
|
68
|
+
(props.purpose !== undefined && !["date", "birthdate"].includes(props.purpose)) ||
|
|
69
|
+
(props.monthInput !== undefined && !["text", "numeric"].includes(props.monthInput))) {
|
|
70
|
+
throw new TypeError("Date entry needs labels, callbacks and valid input policies");
|
|
71
|
+
}
|
|
72
|
+
const resolved = resolveDateEntryDraft({ draft: props.value, order: props.order, required: props.required ?? false, parse: props.parse });
|
|
73
|
+
const error = props.showErrors && resolved.issue ? props.formatIssue(resolved.issue) : undefined;
|
|
74
|
+
if (error !== undefined && (typeof error !== "string" || !error.trim()))
|
|
75
|
+
throw new TypeError("Date entry issue text must not be empty");
|
|
76
|
+
return { ...resolved, error };
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=date-entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date-entry.js","sourceRoot":"","sources":["../src/date-entry.ts"],"names":[],"mappings":"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","sourcesContent":["/** Experimental direct date entry contract; date calculation remains product-owned. */\nexport type DateEntryPart = \"year\" | \"month\" | \"day\";\nexport type DateEntryDraft = Readonly<Record<DateEntryPart, string>>;\nexport type DateEntryOrder = readonly [DateEntryPart, DateEntryPart, DateEntryPart];\nexport type DateEntryParseResult =\n | Readonly<{ status: \"valid\"; value: string }>\n | Readonly<{ status: \"incomplete\" | \"invalid\"; code: string; fields: readonly DateEntryPart[] }>;\nexport type DateEntryIssue =\n | Readonly<{ kind: \"missing\"; fields: readonly DateEntryPart[] }>\n | Readonly<{ kind: \"parse\"; code: string; fields: readonly DateEntryPart[] }>;\nexport type ResolvedDateEntry = Readonly<{\n draft: DateEntryDraft;\n status: \"empty\" | \"incomplete\" | \"invalid\" | \"valid\";\n /** An optional empty date and any uncommitted draft have no committed value. */\n value: string | null;\n issue: DateEntryIssue | null;\n fields: readonly Readonly<{ part: DateEntryPart; value: string; invalid: boolean }>[];\n}>;\nconst parts: readonly DateEntryPart[] = [\"year\", \"month\", \"day\"];\nfunction assertDraft(draft: DateEntryDraft): void {\n if (!draft || parts.some(part => typeof draft[part] !== \"string\")) {\n throw new TypeError(\"Date entry requires string drafts for year, month and day\");\n }\n}\nfunction assertParts(values: readonly DateEntryPart[], complete = false): void {\n if (!Array.isArray(values) || !values.length || new Set(values).size !== values.length ||\n values.some(part => !parts.includes(part)) || (complete && values.length !== 3)) {\n throw new TypeError(\"Date entry requires distinct date parts and a complete display order\");\n }\n}\n\n/** Preserve exact input, including partial years, names, whitespace and composition text. */\nexport function updateDateEntryDraft(draft: DateEntryDraft, part: DateEntryPart, value: string): DateEntryDraft {\n assertDraft(draft);\n if (!parts.includes(part) || typeof value !== \"string\") throw new TypeError(\"Invalid date entry edit\");\n return { ...draft, [part]: value };\n}\n\nexport function resolveDateEntryDraft({ draft, order, required, parse }: {\n draft: DateEntryDraft;\n order: DateEntryOrder;\n required: boolean;\n parse: (draft: DateEntryDraft) => DateEntryParseResult;\n}): ResolvedDateEntry {\n assertDraft(draft);\n assertParts(order, true);\n if (typeof required !== \"boolean\" || typeof parse !== \"function\") throw new TypeError(\"Date entry requires required and parse policies\");\n // Calendar already leaves locale/calendar/clock policy to products. A second\n // Date-based parser would normalize impossible dates and disagree with it.\n // Freeze a snapshot so an adapter cannot rewrite the user's editing draft.\n const snapshot = Object.freeze({ year: draft.year, month: draft.month, day: draft.day });\n const missing = order.filter(part => !snapshot[part].trim());\n let status: ResolvedDateEntry[\"status\"];\n let value: string | null = null;\n let issue: DateEntryIssue | null = null;\n if (missing.length === 3) {\n status = \"empty\";\n if (required) issue = { kind: \"missing\", fields: missing };\n } else if (missing.length) {\n // Missing data takes priority over format/range errors, so filling one part\n // cannot hide which other parts are still needed (GOV.UK date-input guidance).\n status = \"incomplete\";\n issue = { kind: \"missing\", fields: missing };\n } else {\n const result = parse(snapshot);\n if (result?.status === \"valid\") {\n if (typeof result.value !== \"string\" || !result.value.trim()) throw new TypeError(\"A valid date entry needs a nonempty value\");\n status = \"valid\";\n value = result.value;\n } else if (result?.status === \"incomplete\" || result?.status === \"invalid\") {\n if (typeof result.code !== \"string\" || !result.code.trim()) throw new TypeError(\"Date entry issue needs a localization code\");\n assertParts(result.fields);\n status = result.status;\n issue = { kind: \"parse\", code: result.code, fields: order.filter(part => result.fields.includes(part)) };\n } else throw new TypeError(\"Invalid date entry parse result\");\n }\n return { draft: snapshot, status, value, issue,\n fields: order.map(part => ({ part, value: snapshot[part], invalid: issue?.fields.includes(part) ?? false })) };\n}\n\nexport type DateEntryControlProps = Readonly<{\n value: DateEntryDraft;\n onValueChange: (draft: DateEntryDraft) => void;\n order: DateEntryOrder;\n parse: (draft: DateEntryDraft) => DateEntryParseResult;\n labels: Readonly<Record<DateEntryPart | \"label\", string>>;\n formatIssue: (issue: DateEntryIssue) => string;\n description?: string;\n required?: boolean;\n disabled?: boolean;\n readOnly?: boolean;\n /** Products reveal validation on submit/blur; typing never forces errors visible. */\n showErrors?: boolean;\n purpose?: \"date\" | \"birthdate\";\n /** Text is the default so localized month names remain enterable. */\n monthInput?: \"text\" | \"numeric\";\n onBlur?: (part: DateEntryPart) => void;\n}>;\n\nexport function resolveDateEntryControl(props: DateEntryControlProps) {\n if ([\"label\", ...parts].some(key => !props.labels?.[key as keyof typeof props.labels]?.trim()) ||\n typeof props.onValueChange !== \"function\" || typeof props.formatIssue !== \"function\" ||\n (props.purpose !== undefined && ![\"date\", \"birthdate\"].includes(props.purpose)) ||\n (props.monthInput !== undefined && ![\"text\", \"numeric\"].includes(props.monthInput))) {\n throw new TypeError(\"Date entry needs labels, callbacks and valid input policies\");\n }\n const resolved = resolveDateEntryDraft({ draft: props.value, order: props.order, required: props.required ?? false, parse: props.parse });\n const error = props.showErrors && resolved.issue ? props.formatIssue(resolved.issue) : undefined;\n if (error !== undefined && (typeof error !== \"string\" || !error.trim())) throw new TypeError(\"Date entry issue text must not be empty\");\n return { ...resolved, error };\n}\n"]}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/** Candidate composition contract; file access, transfer and receipt verification stay with the host. */
|
|
2
|
+
export type DocumentPreviewState = Readonly<{
|
|
3
|
+
status: "none" | "loading" | "ready";
|
|
4
|
+
}> | Readonly<{
|
|
5
|
+
status: "error";
|
|
6
|
+
message: string;
|
|
7
|
+
retryable: boolean;
|
|
8
|
+
}>;
|
|
9
|
+
export type DocumentSaveState = Readonly<{
|
|
10
|
+
status: "idle" | "pending" | "started" | "saved" | "cancelled";
|
|
11
|
+
}> | Readonly<{
|
|
12
|
+
status: "error";
|
|
13
|
+
message: string;
|
|
14
|
+
retryable: boolean;
|
|
15
|
+
}>;
|
|
16
|
+
export type DocumentResourceDescriptor = Readonly<{
|
|
17
|
+
/** Include a revision when reusing a resource id for different file contents. */
|
|
18
|
+
id: string;
|
|
19
|
+
name: string;
|
|
20
|
+
formatLabel?: string;
|
|
21
|
+
sizeLabel?: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
disabled?: boolean;
|
|
24
|
+
/** Product review/permission gates may block export while keeping preview accessible. */
|
|
25
|
+
saveDisabled?: boolean;
|
|
26
|
+
preview: DocumentPreviewState;
|
|
27
|
+
save: DocumentSaveState;
|
|
28
|
+
}>;
|
|
29
|
+
export type DocumentResourceLabels = Readonly<{
|
|
30
|
+
preview: string;
|
|
31
|
+
previewLoading: string;
|
|
32
|
+
previewUnavailable: string;
|
|
33
|
+
retryPreview: string;
|
|
34
|
+
save: string;
|
|
35
|
+
saving: string;
|
|
36
|
+
started: string;
|
|
37
|
+
saved: string;
|
|
38
|
+
cancelled: string;
|
|
39
|
+
retrySave: string;
|
|
40
|
+
}>;
|
|
41
|
+
export type DocumentResourceControls = Readonly<{
|
|
42
|
+
descriptor: DocumentResourceDescriptor;
|
|
43
|
+
labels: DocumentResourceLabels;
|
|
44
|
+
onPreview?: () => void;
|
|
45
|
+
onRetryPreview?: () => void;
|
|
46
|
+
onSave: () => void;
|
|
47
|
+
onRetrySave?: () => void;
|
|
48
|
+
}>;
|
|
49
|
+
/** Controlled UI only: hosts connect the existing action session to their verified results. */
|
|
50
|
+
export declare function resolveDocumentResourceControls(props: DocumentResourceControls): Readonly<{
|
|
51
|
+
id: string;
|
|
52
|
+
name: string;
|
|
53
|
+
metadata: readonly string[];
|
|
54
|
+
description: string | undefined;
|
|
55
|
+
disabled: boolean;
|
|
56
|
+
saveDisabled: boolean;
|
|
57
|
+
preview: Readonly<{
|
|
58
|
+
status: "none" | "loading" | "ready";
|
|
59
|
+
} | {
|
|
60
|
+
status: "error";
|
|
61
|
+
message: string;
|
|
62
|
+
retryable: boolean;
|
|
63
|
+
}>;
|
|
64
|
+
save: Readonly<{
|
|
65
|
+
status: "idle" | "pending" | "started" | "saved" | "cancelled";
|
|
66
|
+
} | {
|
|
67
|
+
status: "error";
|
|
68
|
+
message: string;
|
|
69
|
+
retryable: boolean;
|
|
70
|
+
}>;
|
|
71
|
+
canPreview: boolean;
|
|
72
|
+
canRetryPreview: boolean;
|
|
73
|
+
canSave: boolean;
|
|
74
|
+
canRetrySave: boolean;
|
|
75
|
+
saved: boolean;
|
|
76
|
+
}>;
|
|
77
|
+
export declare function resolveDocumentResource(descriptor: DocumentResourceDescriptor): Readonly<{
|
|
78
|
+
id: string;
|
|
79
|
+
name: string;
|
|
80
|
+
metadata: readonly string[];
|
|
81
|
+
description: string | undefined;
|
|
82
|
+
disabled: boolean;
|
|
83
|
+
saveDisabled: boolean;
|
|
84
|
+
preview: Readonly<{
|
|
85
|
+
status: "none" | "loading" | "ready";
|
|
86
|
+
} | {
|
|
87
|
+
status: "error";
|
|
88
|
+
message: string;
|
|
89
|
+
retryable: boolean;
|
|
90
|
+
}>;
|
|
91
|
+
save: Readonly<{
|
|
92
|
+
status: "idle" | "pending" | "started" | "saved" | "cancelled";
|
|
93
|
+
} | {
|
|
94
|
+
status: "error";
|
|
95
|
+
message: string;
|
|
96
|
+
retryable: boolean;
|
|
97
|
+
}>;
|
|
98
|
+
canPreview: boolean;
|
|
99
|
+
canRetryPreview: boolean;
|
|
100
|
+
canSave: boolean;
|
|
101
|
+
canRetrySave: boolean;
|
|
102
|
+
saved: boolean;
|
|
103
|
+
}>;
|
|
104
|
+
//# sourceMappingURL=document-resource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-resource.d.ts","sourceRoot":"","sources":["../src/document-resource.ts"],"names":[],"mappings":"AAAA,yGAAyG;AACzG,MAAM,MAAM,oBAAoB,GAC5B,QAAQ,CAAC;IAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAA;CAAE,CAAC,GAClD,QAAQ,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAEvE,MAAM,MAAM,iBAAiB,GACzB,QAAQ,CAAC;IAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,CAAA;CAAE,CAAC,GAC5E,QAAQ,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAEvE,MAAM,MAAM,0BAA0B,GAAG,QAAQ,CAAC;IAChD,iFAAiF;IACjF,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yFAAyF;IACzF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,EAAE,oBAAoB,CAAC;IAC9B,IAAI,EAAE,iBAAiB,CAAC;CACzB,CAAC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC,CAAC;AAEH,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,UAAU,EAAE,0BAA0B,CAAC;IACvC,MAAM,EAAE,sBAAsB,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;CAC1B,CAAC,CAAC;AAEH,+FAA+F;AAC/F,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,wBAAwB;;;;;;;;gBA5CxD,MAAM,GAAG,SAAS,GAAG,OAAO;;gBAC5B,OAAO;iBAAW,MAAM;mBAAa,OAAO;;;gBAG5C,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW;;gBACtD,OAAO;iBAAW,MAAM;mBAAa,OAAO;;;;;;;GAmDlE;AAmBD,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,0BAA0B;;;;;;;;gBA3EvD,MAAM,GAAG,SAAS,GAAG,OAAO;;gBAC5B,OAAO;iBAAW,MAAM;mBAAa,OAAO;;;gBAG5C,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW;;gBACtD,OAAO;iBAAW,MAAM;mBAAa,OAAO;;;;;;;GA6GlE"}
|