@eifi1/ui-kit 0.28.0 → 0.29.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.
Files changed (166) hide show
  1. package/README.md +22 -4
  2. package/dist/auth/accept-invitation.d.ts +90 -0
  3. package/dist/auth/accept-invitation.js +117 -0
  4. package/dist/auth/accept-invitation.js.map +1 -0
  5. package/dist/auth/auth-errors.d.ts +60 -0
  6. package/dist/auth/auth-errors.js +32 -0
  7. package/dist/auth/auth-errors.js.map +1 -0
  8. package/dist/auth/complete-name-dialog.d.ts +71 -0
  9. package/dist/auth/complete-name-dialog.js +168 -0
  10. package/dist/auth/complete-name-dialog.js.map +1 -0
  11. package/dist/auth/email-tag.d.ts +60 -0
  12. package/dist/auth/email-tag.js +23 -0
  13. package/dist/auth/email-tag.js.map +1 -0
  14. package/dist/auth/forgot-password-form.d.ts +79 -0
  15. package/dist/auth/forgot-password-form.js +120 -0
  16. package/dist/auth/forgot-password-form.js.map +1 -0
  17. package/dist/auth/form-rules.d.ts +27 -0
  18. package/dist/auth/form-rules.js +23 -0
  19. package/dist/auth/form-rules.js.map +1 -0
  20. package/dist/auth/new-password-fields.d.ts +38 -0
  21. package/dist/auth/new-password-fields.js +54 -0
  22. package/dist/auth/new-password-fields.js.map +1 -0
  23. package/dist/auth/not-found-page.d.ts +57 -0
  24. package/dist/auth/not-found-page.js +40 -0
  25. package/dist/auth/not-found-page.js.map +1 -0
  26. package/dist/auth/register-form.d.ts +86 -0
  27. package/dist/auth/register-form.js +268 -0
  28. package/dist/auth/register-form.js.map +1 -0
  29. package/dist/auth/reset-password-form.d.ts +124 -0
  30. package/dist/auth/reset-password-form.js +164 -0
  31. package/dist/auth/reset-password-form.js.map +1 -0
  32. package/dist/auth/sign-in-form.d.ts +243 -0
  33. package/dist/auth/sign-in-form.js +345 -0
  34. package/dist/auth/sign-in-form.js.map +1 -0
  35. package/dist/auth/status-parts.d.ts +78 -0
  36. package/dist/auth/status-parts.js +83 -0
  37. package/dist/auth/status-parts.js.map +1 -0
  38. package/dist/auth/verify-email.d.ts +121 -0
  39. package/dist/auth/verify-email.js +207 -0
  40. package/dist/auth/verify-email.js.map +1 -0
  41. package/dist/chart.d.ts +17 -2
  42. package/dist/components/amount-input.d.ts +18 -2
  43. package/dist/components/button-group.d.ts +18 -2
  44. package/dist/components/calculator.d.ts +18 -2
  45. package/dist/components/confirm-dialog.d.ts +18 -2
  46. package/dist/components/copy-button.d.ts +18 -2
  47. package/dist/components/danger-confirm.d.ts +18 -2
  48. package/dist/components/facing-pair.d.ts +18 -2
  49. package/dist/components/file-button.d.ts +18 -2
  50. package/dist/components/file-dropzone.d.ts +18 -2
  51. package/dist/components/form-actions.d.ts +18 -2
  52. package/dist/components/iban-input.d.ts +18 -2
  53. package/dist/components/language-select.d.ts +18 -9
  54. package/dist/components/legal-page.d.ts +26 -4
  55. package/dist/components/legal-page.js +24 -5
  56. package/dist/components/legal-page.js.map +1 -1
  57. package/dist/components/legal.d.ts +18 -2
  58. package/dist/components/legal.js +49 -5
  59. package/dist/components/legal.js.map +1 -1
  60. package/dist/components/money-field.d.ts +18 -2
  61. package/dist/components/number-field.d.ts +18 -2
  62. package/dist/components/number-input.d.ts +18 -2
  63. package/dist/components/numpad-sheet.d.ts +18 -2
  64. package/dist/components/phone-input.d.ts +18 -2
  65. package/dist/components/series-chart.d.ts +18 -2
  66. package/dist/components/settings-fields.d.ts +15 -2
  67. package/dist/components/share-card.d.ts +18 -2
  68. package/dist/components/text-link.d.ts +18 -2
  69. package/dist/components/time-input.d.ts +18 -2
  70. package/dist/components/ui.d.ts +17 -1
  71. package/dist/components/user-avatar.d.ts +16 -2
  72. package/dist/components/user-avatar.js +7 -3
  73. package/dist/components/user-avatar.js.map +1 -1
  74. package/dist/feedback/feedback-attachment.d.ts +18 -2
  75. package/dist/feedback/feedback-context.d.ts +18 -2
  76. package/dist/feedback/feedback-crash.d.ts +18 -2
  77. package/dist/feedback/feedback-dialog.d.ts +18 -2
  78. package/dist/feedback/feedback-inbox.d.ts +18 -2
  79. package/dist/feedback/feedback-labels.d.ts +18 -2
  80. package/dist/feedback/feedback-menu.d.ts +18 -2
  81. package/dist/feedback/feedback-record.d.ts +18 -2
  82. package/dist/feedback/feedback-row-detail.d.ts +18 -2
  83. package/dist/feedback/feedback-status-undo.d.ts +18 -2
  84. package/dist/feedback/feedback-submit.d.ts +18 -2
  85. package/dist/feedback/feedback-swipe.d.ts +18 -2
  86. package/dist/feedback/feedback-table.d.ts +18 -2
  87. package/dist/feedback/feedback-thread.d.ts +18 -2
  88. package/dist/feedback.d.ts +18 -2
  89. package/dist/hooks/use-file-drop.d.ts +18 -2
  90. package/dist/i18n/defaults.d.ts +18 -2
  91. package/dist/i18n/defaults.js +18 -0
  92. package/dist/i18n/defaults.js.map +1 -1
  93. package/dist/i18n/german.d.ts +18 -2
  94. package/dist/i18n/german.js +145 -0
  95. package/dist/i18n/german.js.map +1 -1
  96. package/dist/i18n/kit-labels.d.ts +18 -2
  97. package/dist/i18n/kit-labels.js.map +1 -1
  98. package/dist/i18n/languages.d.ts +13 -201
  99. package/dist/i18n/locales/de-CH.d.ts +18 -2
  100. package/dist/i18n/locales/en.d.ts +18 -2
  101. package/dist/i18n/locales/es.d.ts +18 -2
  102. package/dist/i18n/locales/es.js +147 -3
  103. package/dist/i18n/locales/es.js.map +1 -1
  104. package/dist/i18n/locales/fr.d.ts +18 -2
  105. package/dist/i18n/locales/fr.js +147 -0
  106. package/dist/i18n/locales/fr.js.map +1 -1
  107. package/dist/i18n/locales/hu.d.ts +18 -2
  108. package/dist/i18n/locales/hu.js +149 -3
  109. package/dist/i18n/locales/hu.js.map +1 -1
  110. package/dist/i18n/locales/it.d.ts +18 -2
  111. package/dist/i18n/locales/it.js +146 -1
  112. package/dist/i18n/locales/it.js.map +1 -1
  113. package/dist/i18n/locales/zh.d.ts +18 -2
  114. package/dist/i18n/locales/zh.js +146 -1
  115. package/dist/i18n/locales/zh.js.map +1 -1
  116. package/dist/i18n/review.d.ts +18 -2
  117. package/dist/i18n/review.js +17 -7
  118. package/dist/i18n/review.js.map +1 -1
  119. package/dist/index.d.ts +13 -2
  120. package/dist/index.js +49 -1
  121. package/dist/index.js.map +1 -1
  122. package/dist/lib/person-name.d.ts +69 -0
  123. package/dist/lib/person-name.js +65 -0
  124. package/dist/lib/person-name.js.map +1 -0
  125. package/dist/{kit-labels-SBN0biPl.d.ts → register-form-V1OeNlMr.d.ts} +423 -6
  126. package/dist/rhf/fields.d.ts +18 -2
  127. package/dist/rhf/form.d.ts +18 -2
  128. package/dist/rhf.d.ts +18 -2
  129. package/dist/shell/app-shell.d.ts +18 -2
  130. package/dist/shell/company-switcher.d.ts +59 -0
  131. package/dist/shell/company-switcher.js +85 -0
  132. package/dist/shell/company-switcher.js.map +1 -0
  133. package/dist/shell/top-bar-brand.d.ts +18 -2
  134. package/dist/shell/topbar-action-menu.d.ts +1 -0
  135. package/dist/shell.d.ts +12 -2
  136. package/dist/wizard/stepper-nav.d.ts +18 -2
  137. package/dist/wizard.d.ts +18 -2
  138. package/package.json +1 -1
  139. package/src/auth/accept-invitation.tsx +227 -0
  140. package/src/auth/auth-errors.ts +105 -0
  141. package/src/auth/complete-name-dialog.tsx +253 -0
  142. package/src/auth/email-tag.ts +75 -0
  143. package/src/auth/forgot-password-form.tsx +213 -0
  144. package/src/auth/form-rules.ts +40 -0
  145. package/src/auth/new-password-fields.tsx +85 -0
  146. package/src/auth/not-found-page.tsx +98 -0
  147. package/src/auth/register-form.tsx +459 -0
  148. package/src/auth/reset-password-form.tsx +337 -0
  149. package/src/auth/sign-in-form.tsx +687 -0
  150. package/src/auth/status-parts.tsx +138 -0
  151. package/src/auth/verify-email.tsx +358 -0
  152. package/src/components/legal-page.tsx +35 -0
  153. package/src/components/legal.tsx +93 -7
  154. package/src/components/user-avatar.tsx +22 -4
  155. package/src/i18n/defaults.ts +18 -0
  156. package/src/i18n/german.ts +153 -0
  157. package/src/i18n/kit-labels.tsx +27 -0
  158. package/src/i18n/locales/es.ts +156 -3
  159. package/src/i18n/locales/fr.ts +157 -0
  160. package/src/i18n/locales/hu.ts +159 -3
  161. package/src/i18n/locales/it.ts +154 -1
  162. package/src/i18n/locales/zh.ts +149 -1
  163. package/src/i18n/review.ts +15 -6
  164. package/src/index.ts +63 -1
  165. package/src/lib/person-name.ts +157 -0
  166. package/src/shell/company-switcher.tsx +140 -0
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { InputHTMLAttributes, ReactNode, AnchorHTMLAttributes, Ref, ReactElement, ButtonHTMLAttributes, SelectHTMLAttributes, ComponentPropsWithoutRef, TextareaHTMLAttributes, RefObject } from 'react';
2
+ import { InputHTMLAttributes, ReactNode, AnchorHTMLAttributes, Ref, ReactElement, ButtonHTMLAttributes, SelectHTMLAttributes, ComponentPropsWithoutRef, TextareaHTMLAttributes, RefObject, MouseEvent } from 'react';
3
3
  import { d as DataTableColumn, f as DataTableLabels } from './data-table-labels-DUELeXpa.js';
4
4
  import { MiniCalendarLabels, WeekDay } from './components/mini-calendar.js';
5
5
  import { CalendarHeatmapLabels } from './components/calendar-heatmap.js';
@@ -7,6 +7,7 @@ import { PopoverLabels } from './components/popover.js';
7
7
  import { ChipInputLabels } from './components/chip.js';
8
8
  import { FieldSyncLabels } from './components/field-sync.js';
9
9
  import { TooltipSide } from './components/tooltip.js';
10
+ import './components/field-parts.js';
10
11
  import { WizardLabels } from './wizard/types.js';
11
12
  import { TourLabels } from './tour/tour.js';
12
13
  import { CommandPaletteLabels } from './search/command-palette.js';
@@ -42,6 +43,14 @@ import { AuthedImageLabels } from './components/authed-image.js';
42
43
  import { ImageGridLabels } from './components/image-grid.js';
43
44
  import { LightboxLabels } from './components/lightbox.js';
44
45
  import { WriteLockLabels } from './components/write-lock.js';
46
+ import { SignInLabels } from './auth/sign-in-form.js';
47
+ import { CompleteNameLabels } from './auth/complete-name-dialog.js';
48
+ import { ForgotPasswordLabels } from './auth/forgot-password-form.js';
49
+ import { ResetPasswordLabels } from './auth/reset-password-form.js';
50
+ import { VerifyEmailLabels } from './auth/verify-email.js';
51
+ import { NotFoundLabels } from './auth/not-found-page.js';
52
+ import { AcceptInvitationLabels } from './auth/accept-invitation.js';
53
+ import { CompanySwitcherLabels } from './shell/company-switcher.js';
45
54
  import { RoleDefinition, AccountStateLabels } from './components/account-chips.js';
46
55
  import { ReauthDialogLabels } from './components/reauth-dialog.js';
47
56
  import { ServerWakeLabels } from './components/server-wake.js';
@@ -52,7 +61,7 @@ import { IbanKind } from './lib/iban.js';
52
61
  import { PhoneCountry, PhoneCountryCode } from './lib/phone.js';
53
62
  import { SignChipLabels } from './components/sign-chip.js';
54
63
  import { ColumnMapperLabels } from './components/column-mapper.js';
55
- import './components/field-parts.js';
64
+ import { LanguageOption } from './shell/topbar-controls.js';
56
65
 
57
66
  type ButtonVariant = "primary" | "secondary" | "ghost" | "danger" | "brand" | "link";
58
67
  type ButtonSize = "sm" | "md";
@@ -4781,6 +4790,14 @@ interface LegalOperator {
4781
4790
  country: string;
4782
4791
  /** The contact address the imprint and the privacy policy print. */
4783
4792
  email: string;
4793
+ /**
4794
+ * The language whose version of the legal texts is BINDING ("de-CH"), a BCP 47 code
4795
+ * (0.28.1, Marcel 2026-10-05). The lawyer reviews that one; the others are translations
4796
+ * for convenience. With it, {@link LegalPage} shows a note on every page read in
4797
+ * another language, and the terms' `language` section says which version prevails.
4798
+ * Only the language subtag counts: "de-CH" and "de" are the same language here.
4799
+ */
4800
+ bindingLanguage?: string;
4784
4801
  }
4785
4802
  /**
4786
4803
  * The operator as the kit's texts read it: {@link LegalOperator} with `country` already
@@ -4791,6 +4808,8 @@ interface LegalOperator {
4791
4808
  * `Intl`, and a review row can be rendered from placeholders (`{{country}}`).
4792
4809
  */
4793
4810
  type LegalOperatorText = Readonly<Record<keyof LegalOperator, string>>;
4811
+ /** The language subtag of a BCP 47 code, lower-cased: "de-CH" → "de". */
4812
+ declare function baseLanguage(code: string): string;
4794
4813
  /** @internal The operator as the texts read it: its country named in `locale` (English
4795
4814
  * without one — `countryName`'s rule, so an app that set no locale reads English). */
4796
4815
  declare function legalOperatorText(operator: LegalOperator, locale?: string): LegalOperatorText;
@@ -4847,6 +4866,16 @@ interface LegalLabels {
4847
4866
  beta: string;
4848
4867
  privacy: string;
4849
4868
  };
4869
+ /**
4870
+ * 0.28.1: on a page read in another language than the operator's `bindingLanguage` —
4871
+ * `note` under the title, `show` on the button that switches to the binding version
4872
+ * (when the app passes `onShowBindingLanguage`). `o.bindingLanguage` is the binding
4873
+ * language's NAME in the reader's language ("German", "allemand").
4874
+ */
4875
+ translation: {
4876
+ note: (o: LegalOperatorText) => string;
4877
+ show: (o: LegalOperatorText) => string;
4878
+ };
4850
4879
  /** The kit's sections (§4.3), by page and section key. */
4851
4880
  sections: {
4852
4881
  impressum: {
@@ -4869,6 +4898,8 @@ interface LegalLabels {
4869
4898
  warranty: LegalTextSectionLabels;
4870
4899
  liability: LegalTextSectionLabels;
4871
4900
  changes: LegalTextSectionLabels;
4901
+ /** 0.28.1: which language's version prevails — `o.bindingLanguage`, named. */
4902
+ language: LegalOperatorSectionLabels;
4872
4903
  /** The place of jurisdiction is the operator's `{city} ({region}), {country}`. */
4873
4904
  law: LegalOperatorSectionLabels;
4874
4905
  };
@@ -4941,6 +4972,9 @@ interface LegalLinksProps {
4941
4972
  * links, so in a plain container — Kurvenschmiede's account-menu `<li>` — they ran
4942
4973
  * together as "ImpressumDatenschutzerklärungNutz…" and overflowed). Default true. */
4943
4974
  nav?: boolean;
4975
+ /** Called on a click on any of the links, before it navigates — an account menu closes
4976
+ * itself here (0.28.1, keksdose: it had to catch the click on a wrapping `<div>`). */
4977
+ onLinkClick?: (event: MouseEvent<HTMLAnchorElement>) => void;
4944
4978
  labels?: LabelOverride<LegalLabels>;
4945
4979
  className?: string;
4946
4980
  }
@@ -4953,7 +4987,7 @@ interface LegalLinksProps {
4953
4987
  * already hears three links, and "middle dot" between them is noise. They are flex items
4954
4988
  * of the row like the links, so the row's gap spaces them evenly.
4955
4989
  */
4956
- declare function LegalLinks({ links, currentHref, nav, labels: labelsProp, className }: LegalLinksProps): react.JSX.Element;
4990
+ declare function LegalLinks({ links, currentHref, nav, onLinkClick, labels: labelsProp, className, }: LegalLinksProps): react.JSX.Element;
4957
4991
  interface LegalFooterProps {
4958
4992
  /** Under the links, centred — the app's tagline (keksdose: "Self-hosted household
4959
4993
  * budgeting & bookkeeping."). */
@@ -4963,6 +4997,14 @@ interface LegalFooterProps {
4963
4997
  /** Marks that link `aria-current="page"`. {@link LegalPage}'s default footer passes
4964
4998
  * its own page. */
4965
4999
  currentHref?: string;
5000
+ /**
5001
+ * Default true: the footer is a `<footer>`. `false` draws a `<div>` — for a host that is
5002
+ * a footer already: `AuthLayout`'s `footer` slot is one, and HTML forbids a footer inside
5003
+ * a footer (0.28.1, kastlan). On an `AuthLayout` page the usual choice is simpler still:
5004
+ * `footer={<LegalLinks nav={false} />}` with `footerLabel` set to the kit's `navLabel`
5005
+ * ({@link useLegalLabels}).
5006
+ */
5007
+ landmark?: boolean;
4966
5008
  className?: string;
4967
5009
  labels?: LabelOverride<LegalLabels>;
4968
5010
  }
@@ -4977,7 +5019,7 @@ interface LegalFooterProps {
4977
5019
  * only. Its palette classes (`border-slate-200 bg-white dark:…`) became the surface and
4978
5020
  * border tokens, so it follows the theme like the rest of the kit.
4979
5021
  */
4980
- declare function LegalFooter({ children, links, currentHref, className, labels }: LegalFooterProps): react.JSX.Element;
5022
+ declare function LegalFooter({ children, links, currentHref, landmark, className, labels }: LegalFooterProps): react.JSX.Element;
4981
5023
  interface LegalSectionProps {
4982
5024
  heading: ReactNode;
4983
5025
  /** Running text. Line breaks in it are kept (`white-space: pre-line`), so a
@@ -5018,6 +5060,9 @@ interface LegalLayoutProps {
5018
5060
  * than the others (its technical sections describe running code).
5019
5061
  */
5020
5062
  notice?: ReactNode;
5063
+ /** 0.28.1: under the title, before the notice — {@link LegalPage}'s note that this
5064
+ * page is a translation and which language is binding. */
5065
+ translationNote?: ReactNode;
5021
5066
  /** The sections — {@link LegalSection}s. */
5022
5067
  children: ReactNode;
5023
5068
  /** The three pages, linked at the end of the column with the current one marked.
@@ -5030,7 +5075,7 @@ interface LegalLayoutProps {
5030
5075
  className?: string;
5031
5076
  labels?: LabelOverride<LegalLabels>;
5032
5077
  }
5033
- declare function LegalLayout({ title, back, notice, children, links, currentHref, headingAs: Heading, className, labels, }: LegalLayoutProps): react.JSX.Element;
5078
+ declare function LegalLayout({ title, back, notice, translationNote, children, links, currentHref, headingAs: Heading, className, labels, }: LegalLayoutProps): react.JSX.Element;
5034
5079
 
5035
5080
  /**
5036
5081
  * Who holds one record, and the owner's every way of changing that — Kurvenschmiede's
@@ -5593,6 +5638,24 @@ interface UiKitLabels {
5593
5638
  * sections that are the same in every app, filled in with the app's operator
5594
5639
  * (docs/legal-harmonization.md §4.3/§4.4). */
5595
5640
  legal: LegalLabels;
5641
+ /** 0.29.0: sign-in form: credentials, passkey, 2FA, forced new password (docs/auth-harmonization.md §5). */
5642
+ signIn: SignInLabels;
5643
+ /** 0.29.0: the sign-up form, with the +app address tag (§4.1, §4.5). */
5644
+ register: RegisterLabels;
5645
+ /** 0.29.0: asking a migrated account for first and last name once (§3.3). */
5646
+ completeName: CompleteNameLabels;
5647
+ /** 0.29.0: requesting a reset link (always the same answer). */
5648
+ forgotPassword: ForgotPasswordLabels;
5649
+ /** 0.29.0: choosing a new password from a reset link; not a sign-in (§6.3). */
5650
+ resetPassword: ResetPasswordLabels;
5651
+ /** 0.29.0: the verify-email page and the unverified banner. */
5652
+ verifyEmail: VerifyEmailLabels;
5653
+ /** 0.29.0: the 404 page. */
5654
+ notFound: NotFoundLabels;
5655
+ /** 0.29.0: accepting an invitation with an account (§4.4). */
5656
+ acceptInvitation: AcceptInvitationLabels;
5657
+ /** 0.29.0: kastlan's switcher between a user's companies (§5.3). */
5658
+ companySwitcher: CompanySwitcherLabels;
5596
5659
  /** 0.22.0: the screen-reader words of `Input` / `Textarea`'s `showCount` counter. */
5597
5660
  characterCount: CharacterCountLabels;
5598
5661
  /** 0.22.0: `CountrySelect`. Its list's "no results" and counts are `combobox`'s. */
@@ -5802,4 +5865,358 @@ declare function useKitFileLabels(prop?: Partial<FileLabels>): FileLabels;
5802
5865
  */
5803
5866
  declare function missingKitLabels(labels: UiKitLabelOverrides | undefined, reference: UiKitLabels): string[];
5804
5867
 
5805
- export { type FeedbackContext as $, type FeedbackAttachmentError as A, type FeedbackAttachmentErrorInfo as B, ChatComposer as C, DEFAULT_ATTACHMENT_ACCEPT as D, FeedbackAttachmentField as E, FEEDBACK_ATTACHMENT_ACCEPT as F, type FeedbackAttachmentFieldLabels as G, type FeedbackAttachmentFieldMultipleProps as H, type FeedbackAttachmentFieldProps as I, type FeedbackAttachmentFieldRefsProps as J, type FeedbackAttachmentFieldSingleProps as K, type FeedbackAttachmentLabels as L, type FeedbackAttachmentRef as M, type FeedbackAttachmentRefsError as N, FeedbackAwaitingToggle as O, type FeedbackAwaitingToggleProps as P, type FeedbackCategory as Q, FeedbackCategoryBadge as R, type FeedbackCategoryLabels as S, type FeedbackCategoryOption as T, type FeedbackColumnsOptions as U, FeedbackComposer as V, type FeedbackComposerAttachment as W, type FeedbackComposerHandle as X, type FeedbackComposerLabels as Y, type FeedbackComposerProps as Z, type FeedbackComposerSlotContext as _, type ChatComposerHandle as a, feedbackAttachmentUrls as a$, FeedbackContextBox as a0, type FeedbackContextBoxProps as a1, type FeedbackContextInput as a2, type FeedbackContextLabels as a3, FeedbackDetail as a4, type FeedbackDetailLabels as a5, type FeedbackDetailPatch as a6, FeedbackDetailSection as a7, type FeedbackDetailUpdate as a8, FeedbackDialog as a9, FeedbackStatusBadge as aA, type FeedbackStatusChange as aB, type FeedbackStatusLabels as aC, type FeedbackStatusMutate as aD, type FeedbackStatusPatch as aE, type FeedbackStatusRow as aF, FeedbackStatusTransitions as aG, type FeedbackStatusUndoOptions as aH, FeedbackSubject as aI, type FeedbackSubjectProps as aJ, type FeedbackSubmission as aK, type FeedbackSubmitHint as aL, type FeedbackSubmitter as aM, type FeedbackTableRow as aN, FeedbackThread as aO, type FeedbackThreadAttachment as aP, type FeedbackThreadEvent as aQ, type FeedbackThreadItem as aR, type FeedbackThreadLabels as aS, type FeedbackThreadMessage as aT, type FeedbackThreadProps as aU, type FeedbackToastLabels as aV, type FeedbackUpload as aW, type UseFeedbackColumnsOptions as aX, appendRework as aY, attachmentName as aZ, feedbackAttachmentLine as a_, type FeedbackDialogLabels as aa, type FeedbackDialogMultipleProps as ab, type FeedbackDialogProps as ac, type FeedbackDialogSingleProps as ad, type FeedbackDialogTextLabels as ae, FeedbackEmptyState as af, type FeedbackEmptyStateProps as ag, type FeedbackEnvironment as ah, FeedbackMenu as ai, type FeedbackMenuLabels as aj, type FeedbackMenuProps as ak, FeedbackMobileCard as al, type FeedbackMobileCardProps as am, type FeedbackMultipleSubmission as an, type FeedbackNoteAttachment as ao, FeedbackNoteEditor as ap, type FeedbackPageLabels as aq, FeedbackProse as ar, type FeedbackRecord as as, type FeedbackRenderDate as at, FeedbackReworkSection as au, type FeedbackReworkSectionProps as av, type FeedbackRowAccess as aw, FeedbackRowDetail as ax, type FeedbackRowDetailProps as ay, type FeedbackStatus as az, type ChatComposerLabels as b, type ConfirmProviderProps as b$, feedbackCategoryRank as b0, feedbackColumns as b1, feedbackContext as b2, feedbackEnvironment as b3, feedbackMobileGroupBy as b4, feedbackPageHref as b5, feedbackPagePath as b6, feedbackPageUrl as b7, feedbackRowAccess as b8, feedbackSubmitter as b9, type ButtonVariant as bA, type CalculatorLabels as bB, Card as bC, CardAction as bD, type CardActionProps as bE, CardContent as bF, type CardContentProps as bG, type CardDensity as bH, CardDescription as bI, type CardDescriptionProps as bJ, CardFooter as bK, type CardFooterProps as bL, CardHeader as bM, type CardHeaderProps as bN, type CardProps as bO, CardTitle as bP, type CardTitleLevel as bQ, type CardTitleProps as bR, type CardTone as bS, type CharacterCountLabels as bT, type ChartTooltipPlacement as bU, type ComboboxLabels as bV, type CommonLabels as bW, type ConfirmDialogLabels as bX, type ConfirmFn as bY, type ConfirmOptions as bZ, ConfirmProvider as b_, feedbackSubmitterEmail as ba, isFeedbackAwaiting as bb, isImageAttachment as bc, nextFeedbackStatus as bd, pastedName as be, replaceDescription as bf, reworkCount as bg, selectableFeedbackStatuses as bh, splitBodyAttachments as bi, splitDescription as bj, useFeedbackCategoryLabels as bk, useFeedbackColumns as bl, useFeedbackDetailLabels as bm, useFeedbackPageLabels as bn, useFeedbackRenderDate as bo, useFeedbackStatusLabels as bp, useFeedbackStatusUndo as bq, useFeedbackToastLabels as br, visibleFeedbackStatuses as bs, type AppShellLabels as bt, Button as bu, type ButtonClassesOptions as bv, type ButtonLinkProps as bw, type ButtonProps as bx, type ButtonSize as by, type ButtonTone as bz, type ChatComposerProps as c, type FormActionsLabels as c$, type ConfirmTone as c0, CopyButton as c1, type CopyButtonLabels as c2, type CopyButtonProps as c3, type CurrencyLabels as c4, CurrentPasswordInput as c5, type CurrentPasswordInputLabels as c6, type CurrentPasswordInputProps as c7, DEFAULT_APP_SHELL_LABELS as c8, DEFAULT_CALCULATOR_LABELS as c9, type DatePickerLabels as cA, EmptyState as cB, type EmptyStateProps as cC, FIELD_BASE as cD, FIELD_DISPLAY as cE, FIELD_FLOATING_PAD as cF, FIELD_INVALID as cG, FIELD_TRIGGER as cH, FIELD_WRITABLE_LOOK as cI, FLOATING_INPUT_CLASS as cJ, FLOATING_LABEL_CLASS as cK, FieldChevron as cL, type FieldChevronProps as cM, FieldHint as cN, type FieldHintProps as cO, FileButton as cP, type FileButtonProps as cQ, type FileLabels as cR, type FilePickerLabels as cS, type FileRejection as cT, type FileRejectionReason as cU, type FileScreenOptions as cV, FloatingField as cW, type FloatingFieldProps as cX, FormActions as cY, type FormActionsAlign as cZ, type FormActionsDestructive as c_, DEFAULT_CHARACTER_COUNT_LABELS as ca, DEFAULT_COMBOBOX_LABELS as cb, DEFAULT_COMMON_LABELS as cc, DEFAULT_CONFIRM_DIALOG_LABELS as cd, DEFAULT_COPY_BUTTON_LABELS as ce, DEFAULT_CURRENCY_LABELS as cf, DEFAULT_DANGER_CONFIRM_LABELS as cg, DEFAULT_DATE_PICKER_LABELS as ch, DEFAULT_FILE_LABELS as ci, DEFAULT_FILE_PICKER_LABELS as cj, DEFAULT_FORM_ACTIONS_LABELS as ck, DEFAULT_IBAN_INPUT_LABELS as cl, DEFAULT_LEGAL_LABELS as cm, DEFAULT_MULTI_SELECT_LABELS as cn, DEFAULT_PASSWORD_REVEAL_LABELS as co, DEFAULT_PHONE_INPUT_LABELS as cp, DEFAULT_PICKER_SHEET_LABELS as cq, DEFAULT_SHARE_CARD_LABELS as cr, DEFAULT_SWIPEABLE_ROW_LABELS as cs, DEFAULT_TABS_LABELS as ct, DEFAULT_TOP_BAR_LABELS as cu, DangerConfirm as cv, type DangerConfirmLabels as cw, type DangerConfirmProps as cx, type DangerConfirmValues as cy, type DangerConsequence as cz, type ChatComposerSlotContext as d, type ShareRole as d$, type FormActionsPlacement as d0, type FormActionsProps as d1, type FormActionsStickyWithin as d2, type FormActionsSubmitProps as d3, type FormActionsSubmitShortcut as d4, IbanInput as d5, type IbanInputLabels as d6, type IbanInputProps as d7, IconButton as d8, type IconButtonGlyphSize as d9, type LegalOperatorSectionLabels as dA, type LegalOperatorText as dB, type LegalPageKey as dC, LegalSection as dD, type LegalSectionProps as dE, type LegalTextSectionLabels as dF, type MultiSelectLabels as dG, PHONE_QUERY as dH, type PasswordRevealLabels as dI, PhoneInput as dJ, type PhoneInputLabels as dK, type PhoneInputProps as dL, type PickerSheetLabels as dM, type ResponsiveFormActionsPlacement as dN, Select as dO, type SelectProps as dP, type ShareAddRequest as dQ, type ShareCandidate as dR, ShareCard as dS, type ShareCardLabels as dT, type ShareCardProps as dU, ShareDialog as dV, type ShareDialogProps as dW, type ShareGrantee as dX, SharePanel as dY, type SharePanelProps as dZ, type SharePendingGrant as d_, type IconButtonLinkProps as da, type IconButtonProps as db, type IconButtonSize as dc, type IconButtonTone as dd, type IconButtonToneColor as de, type IconButtonVariant as df, Input as dg, type InputProps as dh, type KitDateFormatContext as di, type KitDateFormatter as dj, type KitLinkComponent as dk, type KitLinkProps as dl, Label as dm, type LabelOverride as dn, type LabelProps as dp, LegalFooter as dq, type LegalFooterProps as dr, type LegalFramedSectionLabels as ds, type LegalLabels as dt, LegalLayout as du, type LegalLayoutProps as dv, type LegalLink as dw, LegalLinks as dx, type LegalLinksProps as dy, type LegalOperator as dz, DEFAULT_FEEDBACK_ATTACHMENT_LABELS as e, Spinner as e0, type SpinnerProps as e1, type SwipeableRowLabels as e2, type TabItem as e3, Tabs as e4, type TabsLabels as e5, type TabsProps as e6, Textarea as e7, type TextareaProps as e8, type TopBarLabels as e9, type FilePickHandler as eA, usePromisePending as eB, formatAccept as eC, judgePick as eD, screenFiles as eE, summariseRejections as eF, LEGAL_HREFS as eG, LegalPageContext as eH, type LegalPageContextValue as eI, type LegalRefTarget as eJ, type LegalSectionSlot as eK, LegalSlotContext as eL, LegalText as eM, legalOperatorText as eN, resolveLegalRefs as eO, useLegalLabels as eP, warnLegalOnce as eQ, TypedConfirmField as ea, type TypedConfirmFieldLabels as eb, type TypedConfirmFieldProps as ec, type TypedMatch as ed, type UiKitLabelOverrides as ee, type UiKitLabels as ef, UiKitProvider as eg, type UiKitProviderProps as eh, type UseFilePickerOptions as ei, type UseFilePickerReturn as ej, buttonClasses as ek, formatFileSize as el, matchesAccept as em, missingKitLabels as en, resolvePasswordRevealLabels as eo, typedMatches as ep, useConfirm as eq, useFilePicker as er, useKitChartTooltipPlacement as es, useKitDateFormatter as et, useKitFileLabels as eu, useKitLabelOverrides as ev, useKitLabels as ew, useKitLink as ex, useKitLocale as ey, useKitWeekStart as ez, DEFAULT_FEEDBACK_CATEGORY_LABELS as f, DEFAULT_FEEDBACK_COMPOSER_LABELS as g, DEFAULT_FEEDBACK_CONTEXT_LABELS as h, DEFAULT_FEEDBACK_DETAIL_LABELS as i, DEFAULT_FEEDBACK_DIALOG_LABELS as j, DEFAULT_FEEDBACK_MENU_LABELS as k, DEFAULT_FEEDBACK_PAGE_LABELS as l, DEFAULT_FEEDBACK_STATUS_LABELS as m, DEFAULT_FEEDBACK_THREAD_LABELS as n, DEFAULT_FEEDBACK_TOAST_LABELS as o, DEFAULT_MAX_ATTACHMENTS as p, DEFAULT_MAX_ATTACHMENT_BYTES as q, FEEDBACK_AUTHOR_EDITABLE_STATUSES as r, FEEDBACK_AWAITING_STATUSES as s, FEEDBACK_CATEGORY_META as t, FEEDBACK_CATEGORY_ORDER as u, FEEDBACK_PICKABLE_CATEGORIES as v, FEEDBACK_REWORKABLE_STATUSES as w, FEEDBACK_STATUS_META as x, FEEDBACK_STATUS_ORDER as y, FEEDBACK_UNDO_DURATION as z };
5868
+ /**
5869
+ * "Which language is this reader in, and what does the kit say in it?" — the one
5870
+ * answer the three apps each wrote for themselves (docs/i18n-harmonization.md, H2).
5871
+ *
5872
+ * kastlan, keksdose and Kurvenschmiede all ship a subset of the same seven languages,
5873
+ * and every one of them hand-rolled the same three things: a list of languages with
5874
+ * their names and flags, a rule for turning what a browser asks for (`de-AT`, `zh-TW`,
5875
+ * `en-AU`) into a code the app ships, and a bridge from that code to the kit's label
5876
+ * catalogue. The three disagreed where nobody was looking: a reader asking for `zh-TW`
5877
+ * got German in kastlan and Chinese in Kurvenschmiede; keksdose's English got the raw
5878
+ * defaults, so its counts read "12345" where the other two wrote "12,345"; kastlan
5879
+ * formatted French as `fr-CH` and Kurvenschmiede as `fr-FR`. None of it was a decision.
5880
+ * This module makes it one, in one place, tested once.
5881
+ *
5882
+ * WHAT IT IS NOT: an i18n library. It resolves no app strings, carries no detector and
5883
+ * depends on nothing — the app keeps i18next (or whatever it uses) for its own words and
5884
+ * asks this module only the questions the kit can answer for all three apps alike:
5885
+ * - {@link KIT_LANGUAGES}: the seven codes, each with its own name, its English name,
5886
+ * the flag it flies and the locale it formats in;
5887
+ * - {@link resolveLanguage}: which of the codes an app offers answers a reader;
5888
+ * - {@link formatLocaleOf}: the `Intl` tag for a code (the provider's `locale`,
5889
+ * `<html lang>`, every `toLocaleString` in the app);
5890
+ * - {@link loadUiKitLabels}: the kit's catalogue for a code, fetched on demand;
5891
+ * - {@link languageOptions}: the rows `LanguageMenu` and `LanguageSetting` take.
5892
+ *
5893
+ * THE CODE AND THE FORMATTING LOCALE ARE TWO THINGS (Kurvenschmiede's insight, made
5894
+ * the rule). The code names a catalogue — what the account stores, what i18next
5895
+ * resolves, what a mail is chosen by — and a bare `en` says nothing about how a date is
5896
+ * written. Each language formats like its home (Marcel, 2026-10-02, H6): `de-CH`,
5897
+ * `en-GB` (British, like the spelling), `es-ES`, `fr-FR`, `it-IT`, `hu-HU`, `zh-CN`. An
5898
+ * app that must format otherwise — kastlan's QR bill follows the SIX spec, not the
5899
+ * reader — passes its own locale where it needs it; the registry is the default.
5900
+ *
5901
+ * THERE IS ONE GERMAN, `de-CH`: Swiss Standard German, formal (0.18). Every other
5902
+ * German a browser or an old localStorage can hand over — `de`, `de-DE`, `de-AT`,
5903
+ * `de-LI`, the briefly offered `de-informal` / `de-CH-informal` — is read as it.
5904
+ * Its name is plain "Deutsch": it is the only German, so there is nothing to tell it
5905
+ * apart from, and the Swiss flag beside it is what says where the spelling comes from.
5906
+ *
5907
+ * AND ONE CHINESE, `zh`, WHICH IS SIMPLIFIED. `zh-TW`, `zh-HK` and `zh-Hant` resolve to
5908
+ * it: there is no Traditional catalogue, and a reader of Traditional characters reads
5909
+ * Simplified far more readily than whichever second language a fallback would guess
5910
+ * at (Kurvenschmiede's reasoning, now everyone's). Its name says "简体中文" so that
5911
+ * reader sees what they are getting before they pick it.
5912
+ */
5913
+ /** The seven languages the kit ships a catalogue for. An app offers a subset. */
5914
+ type KitLanguageCode = "de-CH" | "en" | "es" | "fr" | "it" | "hu" | "zh";
5915
+ /** One language the kit ships: what it is called, which flag it flies and which
5916
+ * BCP 47 tag it formats in. */
5917
+ interface KitLanguage {
5918
+ /** The catalogue code — what an app stores, sends and hands i18next. */
5919
+ readonly code: KitLanguageCode;
5920
+ /** The language's name in itself, for a switcher: the reader looking for theirs may
5921
+ * not read the language the page is currently in. */
5922
+ readonly nativeName: string;
5923
+ /** The name in English, for places that list languages to a team rather than to a
5924
+ * reader (a translation review's locale column, an admin's reviewer grant). */
5925
+ readonly englishName: string;
5926
+ /** The BCP 47 tag the language formats numbers and dates in, and declares itself in
5927
+ * on `<html lang>`. See {@link formatLocaleOf}. */
5928
+ readonly formatLocale: string;
5929
+ /** ISO 3166-1 alpha-2 country (lowercase) for flag-icons' `fi fi-<flag>` class —
5930
+ * NOT the language code: English flies the UK flag, German the Swiss one, Chinese
5931
+ * the PRC's (the catalogue is Simplified). The kit renders the class name only; the
5932
+ * app supplies the flag stylesheet (README, "What you install alongside it"). */
5933
+ readonly flag: string;
5934
+ }
5935
+ /**
5936
+ * Every language the kit ships, in the order a switcher lists them: alphabetical by
5937
+ * native name (Deutsch, English, Español … 简体中文), which is what a reader scanning for
5938
+ * their own language's name expects.
5939
+ *
5940
+ * An app offering four of them passes those four codes to {@link resolveLanguage} and
5941
+ * {@link languageOptions}; it does not copy this list. A language added here is one the
5942
+ * kit has a catalogue for (the loader map below is typed by {@link KitLanguageCode}, so
5943
+ * a code without one does not compile).
5944
+ */
5945
+ declare const KIT_LANGUAGES: readonly KitLanguage[];
5946
+ /**
5947
+ * Which of the codes an app offers answers this reader.
5948
+ *
5949
+ * `candidates` are the reader's preferences **in precedence order**, and the first
5950
+ * one that matches wins — so the order is the policy. The one the harmonisation plan
5951
+ * gives every app (H5):
5952
+ *
5953
+ * resolveLanguage(
5954
+ * [localStorage.getItem("<app>-lang"), user?.locale, ...navigator.languages],
5955
+ * OFFERED,
5956
+ * );
5957
+ *
5958
+ * the choice stored on this device (the reader picked it, here) → the account's
5959
+ * language (read back on sign-in, so a new device starts in it) → the browser's list,
5960
+ * in its own order → the fallback. Missing sources are simply `null` / `undefined`;
5961
+ * they are skipped, as is an empty string.
5962
+ *
5963
+ * Each candidate is matched exactly (case-insensitively), then by language — every
5964
+ * German variant to `de-CH`, every Chinese to `zh` (Simplified), any other regional
5965
+ * form to its base language (`fr-CA` → `fr`, `en-AU` → `en`) — and only within
5966
+ * `offered`: a reader whose browser says `es-MX` first and `en` second, in an app that
5967
+ * offers no Spanish, gets English rather than the fallback. That is the difference
5968
+ * from a single-tag lookup, and why the browser's whole list is passed, not its first
5969
+ * entry.
5970
+ *
5971
+ * `fallback` is what a reader nothing matches gets: by default `de-CH` when the app
5972
+ * offers it — the kit's and the three apps' home language — else the app's first
5973
+ * offered code. It is returned as given, offered or not; the app chose it.
5974
+ *
5975
+ * Why not i18next's own matcher (`getBestMatchFromCodes`, which Kurvenschmiede calls):
5976
+ * it needs an i18next instance, it reduces `de-AT` to a `de` none of the apps ships
5977
+ * unless every caller remembers a converter first, and its answer to a list depends on
5978
+ * `supportedLngs` and `nonExplicitSupportedLngs` being set exactly so. This is a pure
5979
+ * function of its arguments, so the switcher, the account form, a server-rendered
5980
+ * guess and a test all get the same answer without one.
5981
+ */
5982
+ declare function resolveLanguage(candidates: readonly (string | null | undefined)[], offered: readonly KitLanguageCode[], fallback?: KitLanguageCode): KitLanguageCode;
5983
+ /**
5984
+ * The BCP 47 tag a language formats in — `formatLocaleOf("en")` is `"en-GB"`.
5985
+ *
5986
+ * For `<UiKitProvider locale>`, for `<html lang>` (a screen reader pronounces by it,
5987
+ * and `en` alone does not say which English) and for the app's own `Intl` calls, so
5988
+ * the kit's counts and the app's amounts group their digits the same way.
5989
+ *
5990
+ * Takes any tag, not only a {@link KitLanguageCode}. A tag of one of the seven
5991
+ * languages formats in that language's home, by decision — not the reader's region:
5992
+ * `de-AT` as `de-CH`, `en-AU` and `en-US` as `en-GB`, `zh-TW` as `zh-CN`. So an app can
5993
+ * hand it i18next's `resolvedLanguage` as it comes.
5994
+ *
5995
+ * A tag of a language the kit does NOT ship formats as itself (canonicalised): `sv-SE`
5996
+ * stays `sv-SE`. That is a formatting preference, not a language — keksdose's date
5997
+ * setting offers ISO order as `sv-SE`, and 0.19.0 turned it into a German weekday by
5998
+ * resolving it to the home language (keksdose's 0.19 adoption). Words are another
5999
+ * matter: {@link resolveLanguage} and {@link loadUiKitLabels} still fall back to
6000
+ * `de-CH` for such a tag. A tag `Intl` cannot read formats as `de-CH`.
6001
+ */
6002
+ declare function formatLocaleOf(code: string): string;
6003
+ /**
6004
+ * The kit's catalogue for a language, fetched on demand and formatted in
6005
+ * `formatLocale` — for `<UiKitProvider labels={…}>`.
6006
+ *
6007
+ * Every language goes through its catalogue's factory, English included:
6008
+ * `uiKitLabelsEn("en-GB")` writes "12,345 rows" where the bare
6009
+ * `DEFAULT_UI_KIT_LABELS` print "12345" (and keksdose's English did, by passing no
6010
+ * labels at all). `formatLocale` defaults to the language's own
6011
+ * ({@link formatLocaleOf}); pass another only for a reason, as the factories' own
6012
+ * docs describe (`"de-DE"` keeps the Swiss words and writes German digits).
6013
+ *
6014
+ * `code` may be any tag and is resolved like {@link formatLocaleOf}'s, so `de` loads
6015
+ * the one German and a language the kit does not ship loads `de-CH` — the same answer
6016
+ * the app's own fallback gives, rather than English beside the app's German.
6017
+ *
6018
+ * Asynchronous on purpose, and there is no synchronous twin: one would have to import
6019
+ * all seven catalogues statically, which puts every language in every app's entry
6020
+ * chunk — exactly what one subpath per language exists to prevent. Await it before the
6021
+ * first render, beside the app's own catalogue (the apps already await i18next's init
6022
+ * for the same reason: no frame in the wrong language), and keep the result in state.
6023
+ * To change a few words, spread over what it returns rather than copying a catalogue:
6024
+ * a copy misses every key a later release adds.
6025
+ *
6026
+ * A rejected fetch (a deploy replaced the chunk, the device went offline) is not
6027
+ * remembered, so the next call tries again.
6028
+ */
6029
+ declare function loadUiKitLabels(code: string, formatLocale?: string): Promise<UiKitLabels>;
6030
+ /**
6031
+ * The catalogue {@link loadUiKitLabels} already fetched for this language and format
6032
+ * locale — synchronously — or `undefined` while it has not arrived. For the provider's
6033
+ * render, which cannot await: kastlan wrapped the loader in a cache of its own
6034
+ * (`hasKitLabels` / `kitLabelsFor`) to get exactly this, and the other apps would have
6035
+ * written the same lines. Same object as the promise resolved to.
6036
+ */
6037
+ declare function peekUiKitLabels(code: string, formatLocale?: string): UiKitLabels | undefined;
6038
+ /**
6039
+ * The kit's catalogue for `code`, loading it on first use: `<UiKitProvider
6040
+ * labels={useUiKitLabels(language)} locale={formatLocaleOf(language)}>`.
6041
+ *
6042
+ * On a switch it keeps returning the PREVIOUS language's catalogue until the next one
6043
+ * has arrived, so the kit's words never blank out mid-switch; `undefined` only before
6044
+ * the very first catalogue (render nothing, or the English defaults, until then — or
6045
+ * await {@link loadUiKitLabels} before the first render, as the apps do for their own
6046
+ * catalogue). A failed fetch keeps the previous catalogue; the next switch tries again.
6047
+ */
6048
+ declare function useUiKitLabels(code: string, formatLocale?: string): UiKitLabels | undefined;
6049
+ /**
6050
+ * The rows `LanguageMenu` and `LanguageSetting` take, for the codes an app offers, in
6051
+ * the order given: `{ code, label: nativeName, country: flag }`.
6052
+ *
6053
+ * `LanguageMenu` draws `country` as a flag-icons class (`fi fi-ch`) and nothing more —
6054
+ * the kit ships no flag artwork and no flag CSS, the app loads the stylesheet (or just
6055
+ * the rules for its flags, as Kurvenschmiede and keksdose do). `LanguageSetting` is a
6056
+ * native `<select>`, whose options can hold text only, so it shows the names and
6057
+ * ignores `country`; the same array serves both.
6058
+ *
6059
+ * A label of the app's own (keksdose's "Deutsch (Schweiz)") is a `.map` over the
6060
+ * result.
6061
+ */
6062
+ declare function languageOptions(codes?: readonly KitLanguageCode[]): LanguageOption[];
6063
+
6064
+ /** What `RegisterForm` hands `onSubmit` — the core of `POST /auth/register` (§4.2). The
6065
+ * app adds its own fields (kastlan's company, keksdose's currency) and the
6066
+ * `invite_token` it read from the URL. */
6067
+ interface RegisterValues {
6068
+ /** Trimmed, 1–120 characters. */
6069
+ firstName: string;
6070
+ /** Trimmed, 1–120 characters. */
6071
+ lastName: string;
6072
+ /** Trimmed. Lower-casing is the server's (§3.1); a tag is never stripped (§4.5). */
6073
+ email: string;
6074
+ /** As typed: at least 8 characters, at most 72 bytes. */
6075
+ password: string;
6076
+ /** The language picked — one of `languages` — for every mail to the user (§3.1). */
6077
+ locale: KitLanguageCode;
6078
+ }
6079
+ /**
6080
+ * Every string `RegisterForm` renders — the `register` namespace of `<UiKitProvider
6081
+ * labels>`, overridable per instance through `labels`. keksdose's words where it has
6082
+ * them. The terms checkbox speaks `legal.accept`, the strength meter `passwordStrength`.
6083
+ */
6084
+ interface RegisterLabels {
6085
+ firstName: string;
6086
+ lastName: string;
6087
+ email: string;
6088
+ /** The address-tag button (§4.5), given the exact address it would use — and, with an
6089
+ * invitation, the button back to the invited address. */
6090
+ emailTagUse: (address: string) => string;
6091
+ /** The line after the address-tag button. */
6092
+ emailTagHint: string;
6093
+ /** Under an invited (read-only) email field. */
6094
+ invitedEmailHint: string;
6095
+ /** Once the invitee took the tagged address: it is not the invited one, so it is
6096
+ * confirmed by a mail of its own (§4.3). */
6097
+ invitedTagNote: string;
6098
+ password: string;
6099
+ confirmPassword: string;
6100
+ passwordMismatch: string;
6101
+ language: string;
6102
+ /** The submit button. */
6103
+ submit: string;
6104
+ /** Before the link to `signInHref`. */
6105
+ haveAccount: string;
6106
+ /** The link to `signInHref`. */
6107
+ signIn: string;
6108
+ /** `email_taken`, under the email field. */
6109
+ emailTaken: string;
6110
+ /** `registration_closed` — the gate refused the address (§4.3). */
6111
+ registrationClosed: string;
6112
+ /** `invitation_invalid` — the invitation link is unknown or spent. */
6113
+ invitationInvalid: string;
6114
+ /** `invitation_expired`. */
6115
+ invitationExpired: string;
6116
+ /** Any other failure. */
6117
+ failed: string;
6118
+ }
6119
+ declare const DEFAULT_REGISTER_LABELS: RegisterLabels;
6120
+ interface RegisterFormProps extends Omit<ComponentPropsWithoutRef<"div">, "onSubmit" | "children"> {
6121
+ /**
6122
+ * The form was submitted with everything filled in. Send it (`POST /auth/register`,
6123
+ * §4.2) and resolve once the user is signed in, or reject with the client's error:
6124
+ * `email_taken` shows under the email field, `registration_closed` and the
6125
+ * invitation codes above the button, anything else as "Registration failed". The form
6126
+ * never sends a request itself (§8): keksdose must see the password on its way.
6127
+ *
6128
+ * On resolve the form stays busy while the app navigates.
6129
+ */
6130
+ onSubmit: (values: RegisterValues) => Promise<unknown>;
6131
+ /**
6132
+ * The app's address tag (`"kastlan"`, §4.5). Once the email is plausible, a button
6133
+ * under it offers the tagged address — "Use ada+kastlan@example.com" — with a line on
6134
+ * why; one click puts it in the field. Never applied on its own. Left out, no offer.
6135
+ */
6136
+ emailTag?: string;
6137
+ /**
6138
+ * The address of the invitation this sign-up comes from (§4.4): the field starts with
6139
+ * it and is read-only. With `emailTag`, the invitee may still take the tagged form of
6140
+ * it — the server accepts exactly that variant — and go back.
6141
+ */
6142
+ invitedEmail?: string;
6143
+ /**
6144
+ * The language field's value — controlled. Pass the app's UI language
6145
+ * (`i18n.resolvedLanguage`) with `onLocaleChange` switching it, and the field IS the
6146
+ * app's language switch, with no copy of its own to drift from a second switcher on
6147
+ * the page (keksdose's register page has one in its header). Any tag; it shows (and
6148
+ * submits) the offered code it resolves to. Left out, the form keeps its own, starting
6149
+ * from `defaultLocale`, else the provider's language, else the browser's.
6150
+ */
6151
+ locale?: string;
6152
+ /** The uncontrolled language field's start value. */
6153
+ defaultLocale?: string;
6154
+ /** A language was picked. */
6155
+ onLocaleChange?: (code: KitLanguageCode) => void;
6156
+ /** The languages to offer, in order. Default all seven. */
6157
+ languages?: readonly KitLanguageCode[];
6158
+ /**
6159
+ * The app's own language field in place of the kit's select — keksdose's
6160
+ * `LanguageSetting` bound to its i18n. `null` draws none (an app with one language);
6161
+ * the submitted `locale` is then `locale`'s.
6162
+ */
6163
+ languageField?: ReactNode;
6164
+ /** Above the form — keksdose's closed-beta banner. */
6165
+ aboveForm?: ReactNode;
6166
+ /** Under the email field and its tag offer — an app's own hint. */
6167
+ underEmail?: ReactNode;
6168
+ /** The app's sign-up fields (§4.1 item 7): kastlan's Company, keksdose's reporting
6169
+ * currency. Their values are the app's; say whether they are complete with
6170
+ * `appFieldsComplete`. */
6171
+ appFields?: ReactNode;
6172
+ /** After the app fields, before the terms — keksdose's privacy-mode note. */
6173
+ afterFields?: ReactNode;
6174
+ /** Whether the app fields are filled in as required — kastlan's Company without an
6175
+ * invitation. The submit waits for it. Default `true`. */
6176
+ appFieldsComplete?: boolean;
6177
+ /** The terms checkbox's links. Default `/terms` and `/privacy`. */
6178
+ termsHref?: string;
6179
+ privacyHref?: string;
6180
+ /** "Already have an account? Sign in" goes here — `/login`. Left out, no line. */
6181
+ signInHref?: string;
6182
+ /** The app's own words for a failure the kit cannot know (a throttled attempt), or
6183
+ * `undefined` for the kit's. Asked first, for every failure. */
6184
+ describeError?: (error: unknown) => ReactNode | undefined;
6185
+ labels?: Partial<RegisterLabels>;
6186
+ }
6187
+ /**
6188
+ * Sign-up for every app (docs/auth-harmonization.md §4.1, §8): first and last name,
6189
+ * email with the address-tag offer, password with the strength meter and its
6190
+ * confirmation, language, the app's own fields in a slot, and the terms. keksdose's
6191
+ * `RegisterPage` (features/auth/register-page.tsx) with its slots made props.
6192
+ *
6193
+ * **It never sends a request.** `onSubmit` gets the values; what the request carries
6194
+ * besides them (kastlan's company, keksdose's currency, the `invite_token`) is the
6195
+ * app's, as are the role and the associations, which never come from the form (§4.3).
6196
+ *
6197
+ * **The submit waits for a complete form**: both names (1–120 characters after
6198
+ * trimming), a plausible address, a password of at least 8 characters and at most 72
6199
+ * bytes, the same password again, the terms ticked, and `appFieldsComplete`. Nothing
6200
+ * else is a rule — the strength checklist is advice (keksdose #124), and the kit adds
6201
+ * none of its own (§8). So there is never a failed attempt for a missing field, and no
6202
+ * field error to show for one.
6203
+ *
6204
+ * **The address tag** (§4.5) is offered under the email field as one click with the
6205
+ * exact result on the button, never applied: sub-addressing is a convention the
6206
+ * receiving server may or may not implement, and a silent rewrite would send the
6207
+ * verification mail down a path nobody checked. With an invitation the field is fixed
6208
+ * to the invited address; the invitee may still take its tagged form, and is told it
6209
+ * will be confirmed by a mail of its own (§4.3).
6210
+ *
6211
+ * **Refusals** are read by code ({@link authErrorCode}): `email_taken` under the email
6212
+ * field, which takes the focus; `registration_closed`, `invitation_invalid` and
6213
+ * `invitation_expired` above the button; anything else as "Registration failed", unless
6214
+ * `describeError` has the app's words.
6215
+ *
6216
+ * Laid out for a 390 px phone: the names sit side by side only where the form is at
6217
+ * least 20rem wide (a container query), which the narrow `AuthLayout` card is on a
6218
+ * desktop and a phone is not.
6219
+ */
6220
+ declare function RegisterForm({ onSubmit, emailTag, invitedEmail, locale: localeProp, defaultLocale, onLocaleChange, languages, languageField, aboveForm, underEmail, appFields, afterFields, appFieldsComplete, termsHref, privacyHref, signInHref, describeError, labels: labelsProp, className, ...rest }: RegisterFormProps): react.JSX.Element;
6221
+
6222
+ export { type FeedbackContext as $, type FeedbackAttachmentError as A, type FeedbackAttachmentErrorInfo as B, ChatComposer as C, DEFAULT_ATTACHMENT_ACCEPT as D, FeedbackAttachmentField as E, FEEDBACK_ATTACHMENT_ACCEPT as F, type FeedbackAttachmentFieldLabels as G, type FeedbackAttachmentFieldMultipleProps as H, type FeedbackAttachmentFieldProps as I, type FeedbackAttachmentFieldRefsProps as J, type FeedbackAttachmentFieldSingleProps as K, type FeedbackAttachmentLabels as L, type FeedbackAttachmentRef as M, type FeedbackAttachmentRefsError as N, FeedbackAwaitingToggle as O, type FeedbackAwaitingToggleProps as P, type FeedbackCategory as Q, FeedbackCategoryBadge as R, type FeedbackCategoryLabels as S, type FeedbackCategoryOption as T, type FeedbackColumnsOptions as U, FeedbackComposer as V, type FeedbackComposerAttachment as W, type FeedbackComposerHandle as X, type FeedbackComposerLabels as Y, type FeedbackComposerProps as Z, type FeedbackComposerSlotContext as _, type ChatComposerHandle as a, feedbackAttachmentUrls as a$, FeedbackContextBox as a0, type FeedbackContextBoxProps as a1, type FeedbackContextInput as a2, type FeedbackContextLabels as a3, FeedbackDetail as a4, type FeedbackDetailLabels as a5, type FeedbackDetailPatch as a6, FeedbackDetailSection as a7, type FeedbackDetailUpdate as a8, FeedbackDialog as a9, FeedbackStatusBadge as aA, type FeedbackStatusChange as aB, type FeedbackStatusLabels as aC, type FeedbackStatusMutate as aD, type FeedbackStatusPatch as aE, type FeedbackStatusRow as aF, FeedbackStatusTransitions as aG, type FeedbackStatusUndoOptions as aH, FeedbackSubject as aI, type FeedbackSubjectProps as aJ, type FeedbackSubmission as aK, type FeedbackSubmitHint as aL, type FeedbackSubmitter as aM, type FeedbackTableRow as aN, FeedbackThread as aO, type FeedbackThreadAttachment as aP, type FeedbackThreadEvent as aQ, type FeedbackThreadItem as aR, type FeedbackThreadLabels as aS, type FeedbackThreadMessage as aT, type FeedbackThreadProps as aU, type FeedbackToastLabels as aV, type FeedbackUpload as aW, type UseFeedbackColumnsOptions as aX, appendRework as aY, attachmentName as aZ, feedbackAttachmentLine as a_, type FeedbackDialogLabels as aa, type FeedbackDialogMultipleProps as ab, type FeedbackDialogProps as ac, type FeedbackDialogSingleProps as ad, type FeedbackDialogTextLabels as ae, FeedbackEmptyState as af, type FeedbackEmptyStateProps as ag, type FeedbackEnvironment as ah, FeedbackMenu as ai, type FeedbackMenuLabels as aj, type FeedbackMenuProps as ak, FeedbackMobileCard as al, type FeedbackMobileCardProps as am, type FeedbackMultipleSubmission as an, type FeedbackNoteAttachment as ao, FeedbackNoteEditor as ap, type FeedbackPageLabels as aq, FeedbackProse as ar, type FeedbackRecord as as, type FeedbackRenderDate as at, FeedbackReworkSection as au, type FeedbackReworkSectionProps as av, type FeedbackRowAccess as aw, FeedbackRowDetail as ax, type FeedbackRowDetailProps as ay, type FeedbackStatus as az, type ChatComposerLabels as b, type ConfirmProviderProps as b$, feedbackCategoryRank as b0, feedbackColumns as b1, feedbackContext as b2, feedbackEnvironment as b3, feedbackMobileGroupBy as b4, feedbackPageHref as b5, feedbackPagePath as b6, feedbackPageUrl as b7, feedbackRowAccess as b8, feedbackSubmitter as b9, type ButtonVariant as bA, type CalculatorLabels as bB, Card as bC, CardAction as bD, type CardActionProps as bE, CardContent as bF, type CardContentProps as bG, type CardDensity as bH, CardDescription as bI, type CardDescriptionProps as bJ, CardFooter as bK, type CardFooterProps as bL, CardHeader as bM, type CardHeaderProps as bN, type CardProps as bO, CardTitle as bP, type CardTitleLevel as bQ, type CardTitleProps as bR, type CardTone as bS, type CharacterCountLabels as bT, type ChartTooltipPlacement as bU, type ComboboxLabels as bV, type CommonLabels as bW, type ConfirmDialogLabels as bX, type ConfirmFn as bY, type ConfirmOptions as bZ, ConfirmProvider as b_, feedbackSubmitterEmail as ba, isFeedbackAwaiting as bb, isImageAttachment as bc, nextFeedbackStatus as bd, pastedName as be, replaceDescription as bf, reworkCount as bg, selectableFeedbackStatuses as bh, splitBodyAttachments as bi, splitDescription as bj, useFeedbackCategoryLabels as bk, useFeedbackColumns as bl, useFeedbackDetailLabels as bm, useFeedbackPageLabels as bn, useFeedbackRenderDate as bo, useFeedbackStatusLabels as bp, useFeedbackStatusUndo as bq, useFeedbackToastLabels as br, visibleFeedbackStatuses as bs, type AppShellLabels as bt, Button as bu, type ButtonClassesOptions as bv, type ButtonLinkProps as bw, type ButtonProps as bx, type ButtonSize as by, type ButtonTone as bz, type ChatComposerProps as c, type FormActionsDestructive as c$, type ConfirmTone as c0, CopyButton as c1, type CopyButtonLabels as c2, type CopyButtonProps as c3, type CurrencyLabels as c4, CurrentPasswordInput as c5, type CurrentPasswordInputLabels as c6, type CurrentPasswordInputProps as c7, DEFAULT_APP_SHELL_LABELS as c8, DEFAULT_CALCULATOR_LABELS as c9, type DangerConsequence as cA, type DatePickerLabels as cB, EmptyState as cC, type EmptyStateProps as cD, FIELD_BASE as cE, FIELD_DISPLAY as cF, FIELD_FLOATING_PAD as cG, FIELD_INVALID as cH, FIELD_TRIGGER as cI, FIELD_WRITABLE_LOOK as cJ, FLOATING_INPUT_CLASS as cK, FLOATING_LABEL_CLASS as cL, FieldChevron as cM, type FieldChevronProps as cN, FieldHint as cO, type FieldHintProps as cP, FileButton as cQ, type FileButtonProps as cR, type FileLabels as cS, type FilePickerLabels as cT, type FileRejection as cU, type FileRejectionReason as cV, type FileScreenOptions as cW, FloatingField as cX, type FloatingFieldProps as cY, FormActions as cZ, type FormActionsAlign as c_, DEFAULT_CHARACTER_COUNT_LABELS as ca, DEFAULT_COMBOBOX_LABELS as cb, DEFAULT_COMMON_LABELS as cc, DEFAULT_CONFIRM_DIALOG_LABELS as cd, DEFAULT_COPY_BUTTON_LABELS as ce, DEFAULT_CURRENCY_LABELS as cf, DEFAULT_DANGER_CONFIRM_LABELS as cg, DEFAULT_DATE_PICKER_LABELS as ch, DEFAULT_FILE_LABELS as ci, DEFAULT_FILE_PICKER_LABELS as cj, DEFAULT_FORM_ACTIONS_LABELS as ck, DEFAULT_IBAN_INPUT_LABELS as cl, DEFAULT_LEGAL_LABELS as cm, DEFAULT_MULTI_SELECT_LABELS as cn, DEFAULT_PASSWORD_REVEAL_LABELS as co, DEFAULT_PHONE_INPUT_LABELS as cp, DEFAULT_PICKER_SHEET_LABELS as cq, DEFAULT_REGISTER_LABELS as cr, DEFAULT_SHARE_CARD_LABELS as cs, DEFAULT_SWIPEABLE_ROW_LABELS as ct, DEFAULT_TABS_LABELS as cu, DEFAULT_TOP_BAR_LABELS as cv, DangerConfirm as cw, type DangerConfirmLabels as cx, type DangerConfirmProps as cy, type DangerConfirmValues as cz, type ChatComposerSlotContext as d, ShareCard as d$, type FormActionsLabels as d0, type FormActionsPlacement as d1, type FormActionsProps as d2, type FormActionsStickyWithin as d3, type FormActionsSubmitProps as d4, type FormActionsSubmitShortcut as d5, IbanInput as d6, type IbanInputLabels as d7, type IbanInputProps as d8, IconButton as d9, type LegalLayoutProps as dA, type LegalLink as dB, LegalLinks as dC, type LegalLinksProps as dD, type LegalOperator as dE, type LegalOperatorSectionLabels as dF, type LegalOperatorText as dG, type LegalPageKey as dH, LegalSection as dI, type LegalSectionProps as dJ, type LegalTextSectionLabels as dK, type MultiSelectLabels as dL, PHONE_QUERY as dM, type PasswordRevealLabels as dN, PhoneInput as dO, type PhoneInputLabels as dP, type PhoneInputProps as dQ, type PickerSheetLabels as dR, RegisterForm as dS, type RegisterFormProps as dT, type RegisterLabels as dU, type RegisterValues as dV, type ResponsiveFormActionsPlacement as dW, Select as dX, type SelectProps as dY, type ShareAddRequest as dZ, type ShareCandidate as d_, type IconButtonGlyphSize as da, type IconButtonLinkProps as db, type IconButtonProps as dc, type IconButtonSize as dd, type IconButtonTone as de, type IconButtonToneColor as df, type IconButtonVariant as dg, Input as dh, type InputProps as di, KIT_LANGUAGES as dj, type KitDateFormatContext as dk, type KitDateFormatter as dl, type KitLanguage as dm, type KitLanguageCode as dn, type KitLinkComponent as dp, type KitLinkProps as dq, LEGAL_HREFS as dr, Label as ds, type LabelOverride as dt, type LabelProps as du, LegalFooter as dv, type LegalFooterProps as dw, type LegalFramedSectionLabels as dx, type LegalLabels as dy, LegalLayout as dz, DEFAULT_FEEDBACK_ATTACHMENT_LABELS as e, LegalSlotContext as e$, type ShareCardLabels as e0, type ShareCardProps as e1, ShareDialog as e2, type ShareDialogProps as e3, type ShareGrantee as e4, SharePanel as e5, type SharePanelProps as e6, type SharePendingGrant as e7, type ShareRole as e8, Spinner as e9, missingKitLabels as eA, peekUiKitLabels as eB, resolveLanguage as eC, resolvePasswordRevealLabels as eD, typedMatches as eE, useConfirm as eF, useFilePicker as eG, useKitChartTooltipPlacement as eH, useKitDateFormatter as eI, useKitFileLabels as eJ, useKitLabelOverrides as eK, useKitLabels as eL, useKitLink as eM, useKitLocale as eN, useKitWeekStart as eO, useLegalLabels as eP, useUiKitLabels as eQ, type FilePickHandler as eR, usePromisePending as eS, formatAccept as eT, judgePick as eU, screenFiles as eV, summariseRejections as eW, LegalPageContext as eX, type LegalPageContextValue as eY, type LegalRefTarget as eZ, type LegalSectionSlot as e_, type SpinnerProps as ea, type SwipeableRowLabels as eb, type TabItem as ec, Tabs as ed, type TabsLabels as ee, type TabsProps as ef, Textarea as eg, type TextareaProps as eh, type TopBarLabels as ei, TypedConfirmField as ej, type TypedConfirmFieldLabels as ek, type TypedConfirmFieldProps as el, type TypedMatch as em, type UiKitLabelOverrides as en, type UiKitLabels as eo, UiKitProvider as ep, type UiKitProviderProps as eq, type UseFilePickerOptions as er, type UseFilePickerReturn as es, buttonClasses as et, formatFileSize as eu, formatLocaleOf as ev, languageOptions as ew, legalOperatorText as ex, loadUiKitLabels as ey, matchesAccept as ez, DEFAULT_FEEDBACK_CATEGORY_LABELS as f, LegalText as f0, baseLanguage as f1, resolveLegalRefs as f2, warnLegalOnce as f3, DEFAULT_FEEDBACK_COMPOSER_LABELS as g, DEFAULT_FEEDBACK_CONTEXT_LABELS as h, DEFAULT_FEEDBACK_DETAIL_LABELS as i, DEFAULT_FEEDBACK_DIALOG_LABELS as j, DEFAULT_FEEDBACK_MENU_LABELS as k, DEFAULT_FEEDBACK_PAGE_LABELS as l, DEFAULT_FEEDBACK_STATUS_LABELS as m, DEFAULT_FEEDBACK_THREAD_LABELS as n, DEFAULT_FEEDBACK_TOAST_LABELS as o, DEFAULT_MAX_ATTACHMENTS as p, DEFAULT_MAX_ATTACHMENT_BYTES as q, FEEDBACK_AUTHOR_EDITABLE_STATUSES as r, FEEDBACK_AWAITING_STATUSES as s, FEEDBACK_CATEGORY_META as t, FEEDBACK_CATEGORY_ORDER as u, FEEDBACK_PICKABLE_CATEGORIES as v, FEEDBACK_REWORKABLE_STATUSES as w, FEEDBACK_STATUS_META as x, FEEDBACK_STATUS_ORDER as y, FEEDBACK_UNDO_DURATION as z };
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, ReactElement } from 'react';
3
3
  import { FieldValues, FieldPath, ControllerProps, ControllerRenderProps, ControllerFieldState } from 'react-hook-form';
4
- import { d7 as IbanInputProps, dL as PhoneInputProps, dP as SelectProps, dh as InputProps, e8 as TextareaProps } from '../kit-labels-SBN0biPl.js';
4
+ import { d8 as IbanInputProps, dQ as PhoneInputProps, dY as SelectProps, di as InputProps, eh as TextareaProps } from '../register-form-V1OeNlMr.js';
5
5
  import { NumberFieldProps } from '../components/number-field.js';
6
6
  import { DatePickerProps, DateRangePickerProps } from '../components/date-picker.js';
7
7
  import { TimeInputProps } from '../components/time-input.js';
@@ -24,6 +24,7 @@ import '../components/field-sync.js';
24
24
  import '../components/tooltip.js';
25
25
  import '../hooks/use-anchored-rect.js';
26
26
  import '../lib/clipping.js';
27
+ import '../components/field-parts.js';
27
28
  import '../wizard/types.js';
28
29
  import '../tour/tour.js';
29
30
  import '../search/command-palette.js';
@@ -44,6 +45,7 @@ import '../components/modal.js';
44
45
  import '../hooks/use-search-param-state.js';
45
46
  import '../components/measured-grid.js';
46
47
  import '../components/user-avatar.js';
48
+ import '../lib/person-name.js';
47
49
  import '../components/status-dot.js';
48
50
  import '../components/progress-bar.js';
49
51
  import '../components/signed-amount.js';
@@ -63,6 +65,15 @@ import '../components/authed-image.js';
63
65
  import '../components/image-grid.js';
64
66
  import '../components/lightbox.js';
65
67
  import '../components/write-lock.js';
68
+ import '../auth/sign-in-form.js';
69
+ import '../auth/complete-name-dialog.js';
70
+ import '../auth/forgot-password-form.js';
71
+ import '../auth/status-parts.js';
72
+ import '../auth/reset-password-form.js';
73
+ import '../auth/verify-email.js';
74
+ import '../auth/not-found-page.js';
75
+ import '../auth/accept-invitation.js';
76
+ import '../shell/company-switcher.js';
66
77
  import '../components/account-chips.js';
67
78
  import '../lib/format.js';
68
79
  import '../components/reauth-dialog.js';
@@ -77,7 +88,12 @@ import '../components/sign-chip.js';
77
88
  import '../components/column-mapper.js';
78
89
  import '../lib/column-mapping.js';
79
90
  import '../lib/table-text.js';
80
- import '../components/field-parts.js';
91
+ import '../shell/topbar-controls.js';
92
+ import '../theme/palette-presets.js';
93
+ import '../theme/chart-palette.js';
94
+ import '../theme/theme-store.js';
95
+ import 'zustand/middleware';
96
+ import 'zustand';
81
97
  import '../components/number-input.js';
82
98
  import '../components/calculator.js';
83
99
  import '../components/numpad-sheet.js';