ngwr 14.1.0 → 14.3.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 (136) hide show
  1. package/README.md +23 -22
  2. package/command-palette/styles/_index.scss +17 -0
  3. package/fesm2022/ngwr-breadcrumbs.mjs +2 -2
  4. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  5. package/fesm2022/ngwr-calendar.mjs +4 -2
  6. package/fesm2022/ngwr-calendar.mjs.map +1 -1
  7. package/fesm2022/ngwr-cascader.mjs +2 -2
  8. package/fesm2022/ngwr-cascader.mjs.map +1 -1
  9. package/fesm2022/ngwr-command-palette.mjs +2 -2
  10. package/fesm2022/ngwr-command-palette.mjs.map +1 -1
  11. package/fesm2022/ngwr-drag-drop.mjs +2 -2
  12. package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
  13. package/fesm2022/ngwr-event-calendar.mjs +17 -5
  14. package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
  15. package/fesm2022/ngwr-form.mjs +30 -1
  16. package/fesm2022/ngwr-form.mjs.map +1 -1
  17. package/fesm2022/ngwr-i18n-ar.mjs +429 -0
  18. package/fesm2022/ngwr-i18n-ar.mjs.map +1 -0
  19. package/fesm2022/ngwr-i18n-cs.mjs +399 -0
  20. package/fesm2022/ngwr-i18n-cs.mjs.map +1 -0
  21. package/fesm2022/ngwr-i18n-de.mjs +418 -0
  22. package/fesm2022/ngwr-i18n-de.mjs.map +1 -0
  23. package/fesm2022/ngwr-i18n-en.mjs +23 -0
  24. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  25. package/fesm2022/ngwr-i18n-es.mjs +399 -0
  26. package/fesm2022/ngwr-i18n-es.mjs.map +1 -0
  27. package/fesm2022/ngwr-i18n-fr.mjs +423 -0
  28. package/fesm2022/ngwr-i18n-fr.mjs.map +1 -0
  29. package/fesm2022/ngwr-i18n-he.mjs +422 -0
  30. package/fesm2022/ngwr-i18n-he.mjs.map +1 -0
  31. package/fesm2022/ngwr-i18n-hi.mjs +399 -0
  32. package/fesm2022/ngwr-i18n-hi.mjs.map +1 -0
  33. package/fesm2022/ngwr-i18n-id.mjs +399 -0
  34. package/fesm2022/ngwr-i18n-id.mjs.map +1 -0
  35. package/fesm2022/ngwr-i18n-it.mjs +418 -0
  36. package/fesm2022/ngwr-i18n-it.mjs.map +1 -0
  37. package/fesm2022/ngwr-i18n-ja.mjs +403 -0
  38. package/fesm2022/ngwr-i18n-ja.mjs.map +1 -0
  39. package/fesm2022/ngwr-i18n-ko.mjs +411 -0
  40. package/fesm2022/ngwr-i18n-ko.mjs.map +1 -0
  41. package/fesm2022/ngwr-i18n-nl.mjs +415 -0
  42. package/fesm2022/ngwr-i18n-nl.mjs.map +1 -0
  43. package/fesm2022/ngwr-i18n-pl.mjs +425 -0
  44. package/fesm2022/ngwr-i18n-pl.mjs.map +1 -0
  45. package/fesm2022/ngwr-i18n-pt.mjs +408 -0
  46. package/fesm2022/ngwr-i18n-pt.mjs.map +1 -0
  47. package/fesm2022/ngwr-i18n-ru.mjs +11 -0
  48. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  49. package/fesm2022/ngwr-i18n-sv.mjs +399 -0
  50. package/fesm2022/ngwr-i18n-sv.mjs.map +1 -0
  51. package/fesm2022/ngwr-i18n-tr.mjs +423 -0
  52. package/fesm2022/ngwr-i18n-tr.mjs.map +1 -0
  53. package/fesm2022/ngwr-i18n-uk.mjs +420 -0
  54. package/fesm2022/ngwr-i18n-uk.mjs.map +1 -0
  55. package/fesm2022/ngwr-i18n-vi.mjs +416 -0
  56. package/fesm2022/ngwr-i18n-vi.mjs.map +1 -0
  57. package/fesm2022/ngwr-i18n-zh-TW.mjs +407 -0
  58. package/fesm2022/ngwr-i18n-zh-TW.mjs.map +1 -0
  59. package/fesm2022/ngwr-i18n-zh.mjs +398 -0
  60. package/fesm2022/ngwr-i18n-zh.mjs.map +1 -0
  61. package/fesm2022/ngwr-lightbox.mjs +2 -2
  62. package/fesm2022/ngwr-lightbox.mjs.map +1 -1
  63. package/fesm2022/ngwr-line-chart.mjs +24 -4
  64. package/fesm2022/ngwr-line-chart.mjs.map +1 -1
  65. package/fesm2022/ngwr-list.mjs +2 -2
  66. package/fesm2022/ngwr-list.mjs.map +1 -1
  67. package/fesm2022/ngwr-pipes.mjs +75 -10
  68. package/fesm2022/ngwr-pipes.mjs.map +1 -1
  69. package/fesm2022/ngwr-schema-form.mjs +185 -0
  70. package/fesm2022/ngwr-schema-form.mjs.map +1 -0
  71. package/fesm2022/ngwr-select.mjs +2 -2
  72. package/fesm2022/ngwr-select.mjs.map +1 -1
  73. package/fesm2022/ngwr-validators.mjs +8 -1
  74. package/fesm2022/ngwr-validators.mjs.map +1 -1
  75. package/fesm2022/ngwr-version.mjs +1 -1
  76. package/fesm2022/ngwr-version.mjs.map +1 -1
  77. package/i18n/ar.json +389 -0
  78. package/i18n/cs.json +389 -0
  79. package/i18n/de.json +389 -0
  80. package/i18n/en.json +10 -2
  81. package/i18n/es.json +389 -0
  82. package/i18n/fr.json +389 -0
  83. package/i18n/he.json +389 -0
  84. package/i18n/hi.json +389 -0
  85. package/i18n/id.json +389 -0
  86. package/i18n/it.json +389 -0
  87. package/i18n/ja.json +389 -0
  88. package/i18n/ko.json +389 -0
  89. package/i18n/nl.json +389 -0
  90. package/i18n/pl.json +389 -0
  91. package/i18n/pt.json +389 -0
  92. package/i18n/ru.json +10 -2
  93. package/i18n/sv.json +389 -0
  94. package/i18n/tr.json +389 -0
  95. package/i18n/uk.json +389 -0
  96. package/i18n/vi.json +389 -0
  97. package/i18n/zh-TW.json +389 -0
  98. package/i18n/zh.json +389 -0
  99. package/llms-full.txt +87 -1
  100. package/llms.txt +1 -1
  101. package/package.json +89 -7
  102. package/schema-form/styles/_index.scss +15 -0
  103. package/schematics/migrations/v9/index.js +11 -3
  104. package/schematics/use/symbol-map.json +1 -0
  105. package/skills/ngwr/SKILL.md +1 -1
  106. package/skills/ngwr/references/catalog.md +21 -0
  107. package/styles.scss +1 -0
  108. package/theme/styles/_focus.scss +23 -2
  109. package/types/ngwr-calendar.d.ts +2 -0
  110. package/types/ngwr-command-palette.d.ts +1 -1
  111. package/types/ngwr-event-calendar.d.ts +5 -0
  112. package/types/ngwr-form.d.ts +88 -2
  113. package/types/ngwr-i18n-ar.d.ts +6 -0
  114. package/types/ngwr-i18n-cs.d.ts +6 -0
  115. package/types/ngwr-i18n-de.d.ts +6 -0
  116. package/types/ngwr-i18n-es.d.ts +6 -0
  117. package/types/ngwr-i18n-fr.d.ts +6 -0
  118. package/types/ngwr-i18n-he.d.ts +6 -0
  119. package/types/ngwr-i18n-hi.d.ts +6 -0
  120. package/types/ngwr-i18n-id.d.ts +6 -0
  121. package/types/ngwr-i18n-it.d.ts +6 -0
  122. package/types/ngwr-i18n-ja.d.ts +6 -0
  123. package/types/ngwr-i18n-ko.d.ts +6 -0
  124. package/types/ngwr-i18n-nl.d.ts +6 -0
  125. package/types/ngwr-i18n-pl.d.ts +6 -0
  126. package/types/ngwr-i18n-pt.d.ts +6 -0
  127. package/types/ngwr-i18n-sv.d.ts +6 -0
  128. package/types/ngwr-i18n-tr.d.ts +6 -0
  129. package/types/ngwr-i18n-uk.d.ts +6 -0
  130. package/types/ngwr-i18n-vi.d.ts +6 -0
  131. package/types/ngwr-i18n-zh-TW.d.ts +6 -0
  132. package/types/ngwr-i18n-zh.d.ts +6 -0
  133. package/types/ngwr-line-chart.d.ts +15 -0
  134. package/types/ngwr-pipes.d.ts +45 -4
  135. package/types/ngwr-schema-form.d.ts +90 -0
  136. package/types/ngwr-version.d.ts +1 -1
@@ -142,6 +142,13 @@ const WrValidators = {
142
142
  catch {
143
143
  return { url: true };
144
144
  }
145
+ // Unreachable, and kept as a guard rather than deleted. `https` is a
146
+ // WHATWG "special" scheme, which may not have an empty host, so
147
+ // `new URL('https://' + v)` either threw above or produced one —
148
+ // there is no `v` that lands here (checked by brute force over
149
+ // two-character ASCII as well as by the spec). It stays because the
150
+ // line above is the only thing making that true, and a future retry
151
+ // through a non-special scheme would need it back.
145
152
  if (retried.host === '') {
146
153
  return { url: true };
147
154
  }
@@ -280,7 +287,7 @@ const WrValidators = {
280
287
  return;
281
288
  warned = true;
282
289
  // `warn`, not `error`: a prerender worker forwards app console errors as
283
- // `ERROR …` and `scripts/build-showcase.ts` fails the build on them —
290
+ // `ERROR …` and `scripts/build-showcase-app.ts` fails the build on them —
284
291
  // and adding the control later is a legitimate pattern, not a red build.
285
292
  // Reported rather than thrown for the same reason.
286
293
  // eslint-disable-next-line no-console -- a silent pass is the very bug this validator removes
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-validators.mjs","sources":["../../../projects/lib/validators/wr-validators.ts","../../../projects/lib/validators/ngwr-validators.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { isDevMode } from '@angular/core';\nimport { type AbstractControl, type ValidationErrors, type ValidatorFn } from '@angular/forms';\n\nfunction stringValue(control: AbstractControl): string {\n const v: unknown = control.value;\n if (v == null) return '';\n if (typeof v === 'string') return v.trim();\n if (typeof v === 'number' || typeof v === 'boolean') return String(v).trim();\n return '';\n}\n\n/** Like {@link stringValue} but preserves whitespace — for checks that inspect spacing. */\nfunction rawStringValue(control: AbstractControl): string {\n const v: unknown = control.value;\n if (v == null) return '';\n if (typeof v === 'string') return v;\n if (typeof v === 'number' || typeof v === 'boolean') return String(v);\n return '';\n}\n\n/** Luhn checksum. Returns true when the digit string is a valid card number. */\nfunction luhn(digits: string): boolean {\n let sum = 0;\n let dbl = false;\n for (let i = digits.length - 1; i >= 0; i--) {\n let d = digits.charCodeAt(i) - 48;\n if (dbl) {\n d *= 2;\n if (d > 9) d -= 9;\n }\n sum += d;\n dbl = !dbl;\n }\n return sum % 10 === 0;\n}\n\n/** ISO 13616 mod-97 check for IBANs. Returns the remainder; valid IBANs yield 1. */\nfunction mod97(iban: string): number {\n // Move first 4 chars to the end + convert letters to digits (A=10..Z=35).\n const rearranged = iban.slice(4) + iban.slice(0, 4);\n let expanded = '';\n for (let i = 0; i < rearranged.length; i++) {\n const code = rearranged.charCodeAt(i);\n if (code >= 65 && code <= 90) expanded += (code - 55).toString();\n else expanded += rearranged.charAt(i);\n }\n // Apply mod 97 in chunks — BigInt isn't necessary.\n let remainder = 0;\n for (let i = 0; i < expanded.length; i += 7) {\n const slice = remainder.toString() + expanded.substring(i, i + 7);\n remainder = Number.parseInt(slice, 10) % 97;\n }\n return remainder;\n}\n\nfunction toMs(value: unknown): number {\n if (value instanceof Date) return value.getTime();\n if (typeof value === 'string' || typeof value === 'number') return new Date(value).getTime();\n return Number.NaN;\n}\n\n/**\n * Bundled `ValidatorFn`s — pure functions, no DOM, no DI. (`matchFields` keeps\n * one bit of per-instance state, a latch so its dev-mode misconfiguration\n * warning fires once rather than on every validation run; it is never read as\n * part of the result.) Mirrors the API shape of Angular's built-in\n * `Validators` so it composes cleanly:\n *\n * ```ts\n * import { Validators } from '@angular/forms';\n * import { WrValidators } from 'ngwr/validators';\n *\n * new FormControl('', [\n * Validators.required,\n * WrValidators.cardNumber,\n * WrValidators.cvc(3),\n * WrValidators.match('password'),\n * WrValidators.oneOf(['xs', 'sm', 'md', 'lg', 'xl']),\n * ]);\n * ```\n *\n * Each error is keyed under the validator name (e.g. `cardNumber`,\n * `cvc`, `iban`) so consumers can branch in templates.\n *\n * Anything Angular already ships (`required`, `email`, `min`, `max`,\n * `pattern`, …) is deliberately NOT duplicated here.\n *\n * @see https://ngwr.dev/reference/validators\n */\nexport const WrValidators = {\n // String shape\n\n /** No whitespace anywhere in the value. */\n noWhitespace: (control: AbstractControl): ValidationErrors | null => {\n const v = rawStringValue(control);\n if (v === '') return null;\n return /\\s/.test(v) ? { noWhitespace: true } : null;\n },\n\n /** 3, 4, 6, or 8-digit hex colour (`#abc`, `#1a2b3c`, `#1a2b3c4d`). */\n hexColor: (control: AbstractControl): ValidationErrors | null => {\n const v = stringValue(control);\n if (v === '') return null;\n return /^#([0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(v) ? null : { hexColor: true };\n },\n\n // Network / payments\n\n /**\n * Valid URL. Accepts any scheme by default; pass `{ protocols: ['https'] }`\n * to restrict. A scheme is required by default; pass `{ requireProtocol: false }`\n * to also accept bare domains (e.g. `ngwr.dev`), assuming `https`.\n */\n url: (options: { readonly protocols?: readonly string[]; readonly requireProtocol?: boolean } = {}): ValidatorFn => {\n const allow = options.protocols?.map(p => p.replace(/:$/, '').toLowerCase());\n const requireProtocol = options.requireProtocol ?? true;\n return (control: AbstractControl): ValidationErrors | null => {\n const v = stringValue(control);\n if (v === '') return null;\n let parsed: URL;\n try {\n parsed = new URL(v);\n } catch {\n // Bare domain support: when protocols aren't required and the input has\n // no scheme, retry assuming `https://`.\n if (!requireProtocol && !/^[a-z][a-z0-9+.-]*:/i.test(v)) {\n let retried: URL;\n try {\n retried = new URL(`https://${v}`);\n } catch {\n return { url: true };\n }\n if (retried.host === '') {\n return { url: true };\n }\n if (allow && !allow.includes('https')) {\n return { url: { allowed: allow } };\n }\n return null;\n }\n return { url: true };\n }\n const protocol = parsed.protocol.replace(/:$/, '').toLowerCase();\n // WHATWG auto-inserts the authority for \"special\" schemes, so `http:host`\n // (missing `//`) still parses. Require the explicit `//` for those.\n const needsAuthority = ['http', 'https', 'ws', 'wss', 'ftp', 'file'].includes(protocol);\n if (needsAuthority && !/^[a-z][a-z0-9+.-]*:\\/\\//i.test(v)) {\n return { url: true };\n }\n if (allow && !allow.includes(protocol)) {\n return { url: { allowed: allow } };\n }\n return null;\n };\n },\n\n /** Credit card number — Luhn check + 13-19 digit length. Spaces and dashes are stripped first. */\n cardNumber: (control: AbstractControl): ValidationErrors | null => {\n const raw = stringValue(control).replace(/[\\s-]/g, '');\n if (raw === '') return null;\n if (!/^\\d{13,19}$/.test(raw)) return { cardNumber: true };\n return luhn(raw) ? null : { cardNumber: true };\n },\n\n /** CVC / CVV — N digits (default 3). Common: 3 for Visa/MC, 4 for Amex. */\n cvc: (length = 3): ValidatorFn => {\n const re = new RegExp(`^\\\\d{${length}}$`);\n return (control: AbstractControl): ValidationErrors | null => {\n const v = stringValue(control);\n if (v === '') return null;\n return re.test(v) ? null : { cvc: { length } };\n };\n },\n\n /**\n * IBAN — basic structure (CC + 2 digits + up to 30 alphanumerics) +\n * the mod-97 check. Country-length tables not enforced.\n */\n iban: (control: AbstractControl): ValidationErrors | null => {\n const raw = stringValue(control).replace(/\\s/g, '').toUpperCase();\n if (raw === '') return null;\n if (!/^[A-Z]{2}\\d{2}[A-Z0-9]{4,30}$/.test(raw)) return { iban: true };\n return mod97(raw) === 1 ? null : { iban: true };\n },\n\n // Cross-field\n\n /**\n * Value must equal a sibling control's value (e.g. confirm-password).\n * The target lookup uses `control.parent.get(name)`, so it works\n * inside `FormGroup` and nested groups.\n *\n * **It cannot report a mismatch until something revalidates the control.**\n * Angular runs a control's validators inside the control's own constructor,\n * before the control has a parent — so the lookup finds nothing and this\n * returns `null`, and attaching the control to a group does not re-run it.\n *\n * `formControlName` revalidates when it binds, so a group rendered through\n * the reactive-forms directives corrects itself on its first change\n * detection. The window is open for everything that reads validity BEFORE\n * that: a route guard or resolver checking `form.valid`, a form built and\n * submitted from a service, a unit test. Such a group reports itself valid\n * with two values that plainly disagree.\n *\n * Put {@link WrValidators.matchFields} on the group to close it, and keep\n * this one on the child for the per-field message. They do not conflict —\n * different error keys, different hosts.\n *\n * @see WrValidators.matchFields\n */\n match: (targetName: string): ValidatorFn => {\n return (control: AbstractControl): ValidationErrors | null => {\n const target = control.parent?.get(targetName);\n if (!target) return null;\n return control.value === target.value ? null : { match: { target: targetName } };\n };\n },\n\n /**\n * Every named control must hold the same value — the group-level counterpart\n * to {@link WrValidators.match}. Attach it to the group that OWNS the fields,\n * not to one of its children.\n *\n * Unlike `match` this has no ordering hole: Angular attaches the children and\n * aggregates their values BEFORE it runs the group's own validators, so a\n * group built from a record whose fields already disagree is invalid the\n * moment it exists — no revalidation step, and nothing that depends on the\n * form having been rendered.\n *\n * Names are `AbstractControl.get()` paths, so `'billing.zip'` reaches into a\n * nested group. `null`, `undefined` and `''` all count as the same empty\n * value; everything else is compared with `===`, so two equal `Date`s are NOT\n * equal — compare a derived primitive instead. **Disabled controls are\n * skipped**, which makes the rule compare exactly what `group.value`\n * contains, and the error names only the controls it actually compared.\n *\n * A name that resolves to nothing, or to a group or an array rather than a\n * leaf control, turns the whole check off and warns once per validator\n * instance in dev — never a partial comparison of the names that did\n * resolve, and never an error the user has no way to satisfy.\n *\n * The error lands on the GROUP, and `<wr-form-field>` only reads the one\n * control projected into it — so pair this with `match` for a per-field\n * message, or render it yourself from `form.hasError('matchFields')`.\n *\n * @example\n * ```ts\n * new FormGroup(\n * {\n * password: new FormControl(''),\n * confirm: new FormControl('', [WrValidators.match('password')]),\n * },\n * { validators: [WrValidators.matchFields('password', 'confirm')] },\n * );\n * ```\n */\n matchFields: (first: string, second: string, ...rest: readonly string[]): ValidatorFn => {\n // Frozen because the payload hands these names out: a consumer who mutated\n // the array would be editing the validator's own configuration, and a\n // `push` of a name that resolves to nothing switches the check OFF — the\n // form then goes valid with two values that plainly disagree.\n const fields: readonly string[] = Object.freeze([first, second, ...rest]);\n\n // Per-instance, never module-level: a shared latch is process-wide state\n // under SSR, where one request's warning would silence every later one.\n let warned = false;\n\n const warn = (message: string): void => {\n if (!isDevMode() || warned) return;\n warned = true;\n // `warn`, not `error`: a prerender worker forwards app console errors as\n // `ERROR …` and `scripts/build-showcase.ts` fails the build on them —\n // and adding the control later is a legitimate pattern, not a red build.\n // Reported rather than thrown for the same reason.\n // eslint-disable-next-line no-console -- a silent pass is the very bug this validator removes\n console.warn(`[NGWR] matchFields: ${message} — the check did not run.`);\n };\n\n return (group: AbstractControl): ValidationErrors | null => {\n const compared: string[] = [];\n const values: unknown[] = [];\n\n for (const name of fields) {\n const found = group.get(name);\n if (!found) {\n warn(`no control at \"${name}\". Names are AbstractControl.get() paths, relative to this group`);\n return null;\n }\n\n // A group or an array RESOLVES, so it slips past the check above and\n // would then be compared by reference against another container —\n // never equal, whatever the user types. `'billing'` instead of\n // `'billing.zip'` is the easy mistake, and it makes a form that can\n // never be submitted and says nothing about why.\n if ('controls' in found) {\n warn(`\"${name}\" is a group or an array; name a leaf control, e.g. \"${name}.<field>\"`);\n return null;\n }\n\n // A disabled control is absent from `group.value` and its own\n // validators do not run; blocking a form on a value the user cannot\n // edit is not a rule anyone can satisfy.\n if (found.disabled) continue;\n\n compared.push(name);\n values.push((found.value as unknown) ?? '');\n }\n\n if (values.length < 2) return null;\n // A fresh array, and only the names that actually took part: naming a\n // disabled control would point the reader at something they cannot edit.\n // No control VALUES — this guards passwords, and error objects reach the\n // DOM, logs and error reporters.\n return values.every(v => v === values[0]) ? null : { matchFields: { fields: [...compared] } };\n };\n },\n\n // Choice\n\n /** Value must be one of the allowed entries (strict equality). */\n oneOf: <T>(allowed: readonly T[]): ValidatorFn => {\n return (control: AbstractControl): ValidationErrors | null => {\n const v = control.value as T;\n if (v == null || (v as unknown) === '') return null;\n return allowed.includes(v) ? null : { oneOf: { allowed } };\n };\n },\n\n // Date bounds\n\n /** Value (Date | parseable) must be ≥ `min`. */\n minDate: (min: Date | string | number): ValidatorFn => {\n const minMs = toMs(min);\n return (control: AbstractControl): ValidationErrors | null => {\n const v: unknown = control.value;\n if (v == null || v === '') return null;\n const got = toMs(v);\n if (Number.isNaN(got)) return { minDate: { min } };\n return got >= minMs ? null : { minDate: { min } };\n };\n },\n\n /** Value (Date | parseable) must be ≤ `max`. */\n maxDate: (max: Date | string | number): ValidatorFn => {\n const maxMs = toMs(max);\n return (control: AbstractControl): ValidationErrors | null => {\n const v: unknown = control.value;\n if (v == null || v === '') return null;\n const got = toMs(v);\n if (Number.isNaN(got)) return { maxDate: { max } };\n return got <= maxMs ? null : { maxDate: { max } };\n };\n },\n};\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-validators.mjs","sources":["../../../projects/lib/validators/wr-validators.ts","../../../projects/lib/validators/ngwr-validators.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { isDevMode } from '@angular/core';\nimport { type AbstractControl, type ValidationErrors, type ValidatorFn } from '@angular/forms';\n\nfunction stringValue(control: AbstractControl): string {\n const v: unknown = control.value;\n if (v == null) return '';\n if (typeof v === 'string') return v.trim();\n if (typeof v === 'number' || typeof v === 'boolean') return String(v).trim();\n return '';\n}\n\n/** Like {@link stringValue} but preserves whitespace — for checks that inspect spacing. */\nfunction rawStringValue(control: AbstractControl): string {\n const v: unknown = control.value;\n if (v == null) return '';\n if (typeof v === 'string') return v;\n if (typeof v === 'number' || typeof v === 'boolean') return String(v);\n return '';\n}\n\n/** Luhn checksum. Returns true when the digit string is a valid card number. */\nfunction luhn(digits: string): boolean {\n let sum = 0;\n let dbl = false;\n for (let i = digits.length - 1; i >= 0; i--) {\n let d = digits.charCodeAt(i) - 48;\n if (dbl) {\n d *= 2;\n if (d > 9) d -= 9;\n }\n sum += d;\n dbl = !dbl;\n }\n return sum % 10 === 0;\n}\n\n/** ISO 13616 mod-97 check for IBANs. Returns the remainder; valid IBANs yield 1. */\nfunction mod97(iban: string): number {\n // Move first 4 chars to the end + convert letters to digits (A=10..Z=35).\n const rearranged = iban.slice(4) + iban.slice(0, 4);\n let expanded = '';\n for (let i = 0; i < rearranged.length; i++) {\n const code = rearranged.charCodeAt(i);\n if (code >= 65 && code <= 90) expanded += (code - 55).toString();\n else expanded += rearranged.charAt(i);\n }\n // Apply mod 97 in chunks — BigInt isn't necessary.\n let remainder = 0;\n for (let i = 0; i < expanded.length; i += 7) {\n const slice = remainder.toString() + expanded.substring(i, i + 7);\n remainder = Number.parseInt(slice, 10) % 97;\n }\n return remainder;\n}\n\nfunction toMs(value: unknown): number {\n if (value instanceof Date) return value.getTime();\n if (typeof value === 'string' || typeof value === 'number') return new Date(value).getTime();\n return Number.NaN;\n}\n\n/**\n * Bundled `ValidatorFn`s — pure functions, no DOM, no DI. (`matchFields` keeps\n * one bit of per-instance state, a latch so its dev-mode misconfiguration\n * warning fires once rather than on every validation run; it is never read as\n * part of the result.) Mirrors the API shape of Angular's built-in\n * `Validators` so it composes cleanly:\n *\n * ```ts\n * import { Validators } from '@angular/forms';\n * import { WrValidators } from 'ngwr/validators';\n *\n * new FormControl('', [\n * Validators.required,\n * WrValidators.cardNumber,\n * WrValidators.cvc(3),\n * WrValidators.match('password'),\n * WrValidators.oneOf(['xs', 'sm', 'md', 'lg', 'xl']),\n * ]);\n * ```\n *\n * Each error is keyed under the validator name (e.g. `cardNumber`,\n * `cvc`, `iban`) so consumers can branch in templates.\n *\n * Anything Angular already ships (`required`, `email`, `min`, `max`,\n * `pattern`, …) is deliberately NOT duplicated here.\n *\n * @see https://ngwr.dev/reference/validators\n */\nexport const WrValidators = {\n // String shape\n\n /** No whitespace anywhere in the value. */\n noWhitespace: (control: AbstractControl): ValidationErrors | null => {\n const v = rawStringValue(control);\n if (v === '') return null;\n return /\\s/.test(v) ? { noWhitespace: true } : null;\n },\n\n /** 3, 4, 6, or 8-digit hex colour (`#abc`, `#1a2b3c`, `#1a2b3c4d`). */\n hexColor: (control: AbstractControl): ValidationErrors | null => {\n const v = stringValue(control);\n if (v === '') return null;\n return /^#([0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(v) ? null : { hexColor: true };\n },\n\n // Network / payments\n\n /**\n * Valid URL. Accepts any scheme by default; pass `{ protocols: ['https'] }`\n * to restrict. A scheme is required by default; pass `{ requireProtocol: false }`\n * to also accept bare domains (e.g. `ngwr.dev`), assuming `https`.\n */\n url: (options: { readonly protocols?: readonly string[]; readonly requireProtocol?: boolean } = {}): ValidatorFn => {\n const allow = options.protocols?.map(p => p.replace(/:$/, '').toLowerCase());\n const requireProtocol = options.requireProtocol ?? true;\n return (control: AbstractControl): ValidationErrors | null => {\n const v = stringValue(control);\n if (v === '') return null;\n let parsed: URL;\n try {\n parsed = new URL(v);\n } catch {\n // Bare domain support: when protocols aren't required and the input has\n // no scheme, retry assuming `https://`.\n if (!requireProtocol && !/^[a-z][a-z0-9+.-]*:/i.test(v)) {\n let retried: URL;\n try {\n retried = new URL(`https://${v}`);\n } catch {\n return { url: true };\n }\n // Unreachable, and kept as a guard rather than deleted. `https` is a\n // WHATWG \"special\" scheme, which may not have an empty host, so\n // `new URL('https://' + v)` either threw above or produced one —\n // there is no `v` that lands here (checked by brute force over\n // two-character ASCII as well as by the spec). It stays because the\n // line above is the only thing making that true, and a future retry\n // through a non-special scheme would need it back.\n if (retried.host === '') {\n return { url: true };\n }\n if (allow && !allow.includes('https')) {\n return { url: { allowed: allow } };\n }\n return null;\n }\n return { url: true };\n }\n const protocol = parsed.protocol.replace(/:$/, '').toLowerCase();\n // WHATWG auto-inserts the authority for \"special\" schemes, so `http:host`\n // (missing `//`) still parses. Require the explicit `//` for those.\n const needsAuthority = ['http', 'https', 'ws', 'wss', 'ftp', 'file'].includes(protocol);\n if (needsAuthority && !/^[a-z][a-z0-9+.-]*:\\/\\//i.test(v)) {\n return { url: true };\n }\n if (allow && !allow.includes(protocol)) {\n return { url: { allowed: allow } };\n }\n return null;\n };\n },\n\n /** Credit card number — Luhn check + 13-19 digit length. Spaces and dashes are stripped first. */\n cardNumber: (control: AbstractControl): ValidationErrors | null => {\n const raw = stringValue(control).replace(/[\\s-]/g, '');\n if (raw === '') return null;\n if (!/^\\d{13,19}$/.test(raw)) return { cardNumber: true };\n return luhn(raw) ? null : { cardNumber: true };\n },\n\n /** CVC / CVV — N digits (default 3). Common: 3 for Visa/MC, 4 for Amex. */\n cvc: (length = 3): ValidatorFn => {\n const re = new RegExp(`^\\\\d{${length}}$`);\n return (control: AbstractControl): ValidationErrors | null => {\n const v = stringValue(control);\n if (v === '') return null;\n return re.test(v) ? null : { cvc: { length } };\n };\n },\n\n /**\n * IBAN — basic structure (CC + 2 digits + up to 30 alphanumerics) +\n * the mod-97 check. Country-length tables not enforced.\n */\n iban: (control: AbstractControl): ValidationErrors | null => {\n const raw = stringValue(control).replace(/\\s/g, '').toUpperCase();\n if (raw === '') return null;\n if (!/^[A-Z]{2}\\d{2}[A-Z0-9]{4,30}$/.test(raw)) return { iban: true };\n return mod97(raw) === 1 ? null : { iban: true };\n },\n\n // Cross-field\n\n /**\n * Value must equal a sibling control's value (e.g. confirm-password).\n * The target lookup uses `control.parent.get(name)`, so it works\n * inside `FormGroup` and nested groups.\n *\n * **It cannot report a mismatch until something revalidates the control.**\n * Angular runs a control's validators inside the control's own constructor,\n * before the control has a parent — so the lookup finds nothing and this\n * returns `null`, and attaching the control to a group does not re-run it.\n *\n * `formControlName` revalidates when it binds, so a group rendered through\n * the reactive-forms directives corrects itself on its first change\n * detection. The window is open for everything that reads validity BEFORE\n * that: a route guard or resolver checking `form.valid`, a form built and\n * submitted from a service, a unit test. Such a group reports itself valid\n * with two values that plainly disagree.\n *\n * Put {@link WrValidators.matchFields} on the group to close it, and keep\n * this one on the child for the per-field message. They do not conflict —\n * different error keys, different hosts.\n *\n * @see WrValidators.matchFields\n */\n match: (targetName: string): ValidatorFn => {\n return (control: AbstractControl): ValidationErrors | null => {\n const target = control.parent?.get(targetName);\n if (!target) return null;\n return control.value === target.value ? null : { match: { target: targetName } };\n };\n },\n\n /**\n * Every named control must hold the same value — the group-level counterpart\n * to {@link WrValidators.match}. Attach it to the group that OWNS the fields,\n * not to one of its children.\n *\n * Unlike `match` this has no ordering hole: Angular attaches the children and\n * aggregates their values BEFORE it runs the group's own validators, so a\n * group built from a record whose fields already disagree is invalid the\n * moment it exists — no revalidation step, and nothing that depends on the\n * form having been rendered.\n *\n * Names are `AbstractControl.get()` paths, so `'billing.zip'` reaches into a\n * nested group. `null`, `undefined` and `''` all count as the same empty\n * value; everything else is compared with `===`, so two equal `Date`s are NOT\n * equal — compare a derived primitive instead. **Disabled controls are\n * skipped**, which makes the rule compare exactly what `group.value`\n * contains, and the error names only the controls it actually compared.\n *\n * A name that resolves to nothing, or to a group or an array rather than a\n * leaf control, turns the whole check off and warns once per validator\n * instance in dev — never a partial comparison of the names that did\n * resolve, and never an error the user has no way to satisfy.\n *\n * The error lands on the GROUP, and `<wr-form-field>` only reads the one\n * control projected into it — so pair this with `match` for a per-field\n * message, or render it yourself from `form.hasError('matchFields')`.\n *\n * @example\n * ```ts\n * new FormGroup(\n * {\n * password: new FormControl(''),\n * confirm: new FormControl('', [WrValidators.match('password')]),\n * },\n * { validators: [WrValidators.matchFields('password', 'confirm')] },\n * );\n * ```\n */\n matchFields: (first: string, second: string, ...rest: readonly string[]): ValidatorFn => {\n // Frozen because the payload hands these names out: a consumer who mutated\n // the array would be editing the validator's own configuration, and a\n // `push` of a name that resolves to nothing switches the check OFF — the\n // form then goes valid with two values that plainly disagree.\n const fields: readonly string[] = Object.freeze([first, second, ...rest]);\n\n // Per-instance, never module-level: a shared latch is process-wide state\n // under SSR, where one request's warning would silence every later one.\n let warned = false;\n\n const warn = (message: string): void => {\n if (!isDevMode() || warned) return;\n warned = true;\n // `warn`, not `error`: a prerender worker forwards app console errors as\n // `ERROR …` and `scripts/build-showcase-app.ts` fails the build on them —\n // and adding the control later is a legitimate pattern, not a red build.\n // Reported rather than thrown for the same reason.\n // eslint-disable-next-line no-console -- a silent pass is the very bug this validator removes\n console.warn(`[NGWR] matchFields: ${message} — the check did not run.`);\n };\n\n return (group: AbstractControl): ValidationErrors | null => {\n const compared: string[] = [];\n const values: unknown[] = [];\n\n for (const name of fields) {\n const found = group.get(name);\n if (!found) {\n warn(`no control at \"${name}\". Names are AbstractControl.get() paths, relative to this group`);\n return null;\n }\n\n // A group or an array RESOLVES, so it slips past the check above and\n // would then be compared by reference against another container —\n // never equal, whatever the user types. `'billing'` instead of\n // `'billing.zip'` is the easy mistake, and it makes a form that can\n // never be submitted and says nothing about why.\n if ('controls' in found) {\n warn(`\"${name}\" is a group or an array; name a leaf control, e.g. \"${name}.<field>\"`);\n return null;\n }\n\n // A disabled control is absent from `group.value` and its own\n // validators do not run; blocking a form on a value the user cannot\n // edit is not a rule anyone can satisfy.\n if (found.disabled) continue;\n\n compared.push(name);\n values.push((found.value as unknown) ?? '');\n }\n\n if (values.length < 2) return null;\n // A fresh array, and only the names that actually took part: naming a\n // disabled control would point the reader at something they cannot edit.\n // No control VALUES — this guards passwords, and error objects reach the\n // DOM, logs and error reporters.\n return values.every(v => v === values[0]) ? null : { matchFields: { fields: [...compared] } };\n };\n },\n\n // Choice\n\n /** Value must be one of the allowed entries (strict equality). */\n oneOf: <T>(allowed: readonly T[]): ValidatorFn => {\n return (control: AbstractControl): ValidationErrors | null => {\n const v = control.value as T;\n if (v == null || (v as unknown) === '') return null;\n return allowed.includes(v) ? null : { oneOf: { allowed } };\n };\n },\n\n // Date bounds\n\n /** Value (Date | parseable) must be ≥ `min`. */\n minDate: (min: Date | string | number): ValidatorFn => {\n const minMs = toMs(min);\n return (control: AbstractControl): ValidationErrors | null => {\n const v: unknown = control.value;\n if (v == null || v === '') return null;\n const got = toMs(v);\n if (Number.isNaN(got)) return { minDate: { min } };\n return got >= minMs ? null : { minDate: { min } };\n };\n },\n\n /** Value (Date | parseable) must be ≤ `max`. */\n maxDate: (max: Date | string | number): ValidatorFn => {\n const maxMs = toMs(max);\n return (control: AbstractControl): ValidationErrors | null => {\n const v: unknown = control.value;\n if (v == null || v === '') return null;\n const got = toMs(v);\n if (Number.isNaN(got)) return { maxDate: { max } };\n return got <= maxMs ? null : { maxDate: { max } };\n };\n },\n};\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -16,7 +16,7 @@ import { InjectionToken } from '@angular/core';
16
16
  * Distinct from `Version` exported by `@angular/core`, which reports the
17
17
  * loaded Angular runtime version (e.g. `'22.0.0'`), not ngwr's.
18
18
  */
19
- const NGWR_VERSION = '14.1.0';
19
+ const NGWR_VERSION = '14.3.0';
20
20
 
21
21
  /**
22
22
  * @license
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-version.mjs","sources":["../../../projects/lib/version/version.ts","../../../projects/lib/version/version.token.ts","../../../projects/lib/version/ngwr-version.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\n/**\n * The ngwr library version string, kept in sync with\n * `projects/lib/package.json` by `scripts/release-prepare.ts`.\n *\n * Prefer this over reading `package.json` at runtime — that requires a JSON\n * import or `require`, neither of which tree-shakes well in Angular builds.\n *\n * Distinct from `Version` exported by `@angular/core`, which reports the\n * loaded Angular runtime version (e.g. `'22.0.0'`), not ngwr's.\n */\nexport const NGWR_VERSION = '14.1.0';\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\nimport { NGWR_VERSION } from './version';\n\n/**\n * Injection token holding the ngwr library version string.\n *\n * Default factory returns {@link NGWR_VERSION}. Override it in tests or in\n * apps that want to surface a custom build identifier.\n *\n * @example\n * ```ts\n * @Component({...})\n * export class FooterComponent {\n * readonly version = inject(NGWR_VERSION_TOKEN);\n * }\n * ```\n */\nexport const NGWR_VERSION_TOKEN = new InjectionToken<string>('NGWR_VERSION_TOKEN', {\n providedIn: 'root',\n factory: () => NGWR_VERSION,\n});\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;AAAA;;;;;AAKG;AAEH;;;;;;;;;AASG;AACI,MAAM,YAAY,GAAG;;ACjB5B;;;;;AAKG;AAMH;;;;;;;;;;;;;AAaG;MACU,kBAAkB,GAAG,IAAI,cAAc,CAAS,oBAAoB,EAAE;AACjF,IAAA,UAAU,EAAE,MAAM;AAClB,IAAA,OAAO,EAAE,MAAM,YAAY;AAC5B,CAAA;;AC5BD;;AAEG;;;;"}
1
+ {"version":3,"file":"ngwr-version.mjs","sources":["../../../projects/lib/version/version.ts","../../../projects/lib/version/version.token.ts","../../../projects/lib/version/ngwr-version.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\n/**\n * The ngwr library version string, kept in sync with\n * `projects/lib/package.json` by `scripts/release-prepare.ts`.\n *\n * Prefer this over reading `package.json` at runtime — that requires a JSON\n * import or `require`, neither of which tree-shakes well in Angular builds.\n *\n * Distinct from `Version` exported by `@angular/core`, which reports the\n * loaded Angular runtime version (e.g. `'22.0.0'`), not ngwr's.\n */\nexport const NGWR_VERSION = '14.3.0';\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\nimport { NGWR_VERSION } from './version';\n\n/**\n * Injection token holding the ngwr library version string.\n *\n * Default factory returns {@link NGWR_VERSION}. Override it in tests or in\n * apps that want to surface a custom build identifier.\n *\n * @example\n * ```ts\n * @Component({...})\n * export class FooterComponent {\n * readonly version = inject(NGWR_VERSION_TOKEN);\n * }\n * ```\n */\nexport const NGWR_VERSION_TOKEN = new InjectionToken<string>('NGWR_VERSION_TOKEN', {\n providedIn: 'root',\n factory: () => NGWR_VERSION,\n});\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;AAAA;;;;;AAKG;AAEH;;;;;;;;;AASG;AACI,MAAM,YAAY,GAAG;;ACjB5B;;;;;AAKG;AAMH;;;;;;;;;;;;;AAaG;MACU,kBAAkB,GAAG,IAAI,cAAc,CAAS,oBAAoB,EAAE;AACjF,IAAA,UAAU,EAAE,MAAM;AAClB,IAAA,OAAO,EAAE,MAAM,YAAY;AAC5B,CAAA;;AC5BD;;AAEG;;;;"}
package/i18n/ar.json ADDED
@@ -0,0 +1,389 @@
1
+ {
2
+ "common": {
3
+ "ok": "موافق",
4
+ "cancel": "إلغاء",
5
+ "close": "إغلاق",
6
+ "confirm": "تأكيد",
7
+ "delete": "حذف",
8
+ "save": "حفظ",
9
+ "edit": "تعديل",
10
+ "add": "إضافة",
11
+ "remove": "إزالة",
12
+ "clear": "مسح",
13
+ "search": "بحث",
14
+ "loading": "جارٍ التحميل…",
15
+ "select": "تحديد",
16
+ "next": "التالي",
17
+ "previous": "السابق",
18
+ "back": "رجوع",
19
+ "today": "اليوم",
20
+ "yesterday": "أمس",
21
+ "tomorrow": "غدًا",
22
+ "of": "من"
23
+ },
24
+ "pagination": {
25
+ "prev": "الصفحة السابقة",
26
+ "next": "الصفحة التالية",
27
+ "itemsPerPage": "عدد العناصر في الصفحة",
28
+ "perPage": "{{size}} / صفحة",
29
+ "goToPage": "الانتقال إلى الصفحة {{page}}",
30
+ "label": "ترقيم الصفحات",
31
+ "pageOf": "الصفحة {{current}} من {{total}}",
32
+ "range": "{{from}}–{{to}} من {{total}}",
33
+ "compact": "{{current}} / {{total}}"
34
+ },
35
+ "table": {
36
+ "empty": "لا توجد بيانات",
37
+ "loading": "جارٍ التحميل…",
38
+ "sort": "فرز العمود",
39
+ "filter": "تصفية العمود",
40
+ "selectAll": "تحديد كل الصفوف",
41
+ "selectRow": "تحديد الصف",
42
+ "expandRow": "تبديل تفاصيل الصف",
43
+ "toggleRow": "تبديل الصفوف الفرعية",
44
+ "selectGroup": "تحديد المجموعة",
45
+ "toggleGroup": "تبديل المجموعة",
46
+ "noMatches": "لا توجد نتائج مطابقة",
47
+ "search": "بحث",
48
+ "reset": "إعادة تعيين"
49
+ },
50
+ "eventCalendar": {
51
+ "today": "اليوم",
52
+ "previous": "السابق",
53
+ "next": "التالي",
54
+ "month": "شهر",
55
+ "week": "أسبوع",
56
+ "day": "يوم",
57
+ "time": "الوقت",
58
+ "allDay": "طوال اليوم",
59
+ "label": "التقويم",
60
+ "more": "+{{count}} أخرى",
61
+ "header": "{{month}} {{year}}",
62
+ "range": "{{from}} – {{to}}",
63
+ "chipLabel": "{{title}}، {{time}}",
64
+ "slotLabel": "{{time}} — {{date}}",
65
+ "allDayCellLabel": "{{label}} — {{date}}"
66
+ },
67
+ "tour": {
68
+ "next": "التالي",
69
+ "back": "السابق",
70
+ "done": "تم",
71
+ "skip": "تخطي الجولة",
72
+ "progress": "الخطوة {{current}} من {{total}}"
73
+ },
74
+ "splitter": {
75
+ "divider": "تغيير حجم الأجزاء"
76
+ },
77
+ "stepper": {
78
+ "optional": "اختياري"
79
+ },
80
+ "transfer": {
81
+ "source": "المتاح",
82
+ "target": "المحدد",
83
+ "search": "بحث",
84
+ "empty": "لا شيء هنا",
85
+ "selectAll": "تحديد الكل",
86
+ "toTarget": "النقل إلى المحدد",
87
+ "toSource": "النقل إلى المتاح",
88
+ "count": "{{checked}} / {{total}}"
89
+ },
90
+ "form": {
91
+ "optional": "اختياري"
92
+ },
93
+ "validation": {
94
+ "required": "هذا الحقل مطلوب.",
95
+ "requiredTrue": "يجب تحديد هذا الحقل.",
96
+ "email": "أدخل عنوان بريد إلكتروني صالحًا.",
97
+ "minlength": "الحد الأدنى لعدد الأحرف: {{requiredLength}}.",
98
+ "maxlength": "الحد الأقصى لعدد الأحرف: {{requiredLength}}.",
99
+ "min": "أدخل {{min}} أو أكثر.",
100
+ "max": "أدخل {{max}} أو أقل.",
101
+ "pattern": "هذه القيمة لا تطابق التنسيق المتوقع.",
102
+ "noWhitespace": "لا يمكن أن تحتوي هذه القيمة على مسافات.",
103
+ "hexColor": "أدخل لونًا بالنظام الست عشري، مثل #1a2b3c.",
104
+ "url": "أدخل عنوان URL صالحًا.",
105
+ "cardNumber": "أدخل رقم بطاقة صالحًا.",
106
+ "cvc": "أدخل رمز الأمان (عدد الخانات: {{length}}).",
107
+ "iban": "أدخل رقم IBAN صالحًا.",
108
+ "match": "القيمتان غير متطابقتين.",
109
+ "matchFields": "الحقول غير متطابقة.",
110
+ "oneOf": "اختر إحدى القيم المسموح بها.",
111
+ "minDate": "اختر تاريخًا لاحقًا.",
112
+ "maxDate": "اختر تاريخًا سابقًا."
113
+ },
114
+ "select": {
115
+ "label": "اختيار",
116
+ "placeholder": "اختر…",
117
+ "empty": "لا توجد خيارات",
118
+ "clearSelection": "مسح التحديد",
119
+ "removeItem": "إزالة {{label}}",
120
+ "noResults": "لا توجد نتائج",
121
+ "loading": "جارٍ التحميل…",
122
+ "more": "+{{count}} أخرى"
123
+ },
124
+ "tree": {
125
+ "expand": "توسيع",
126
+ "collapse": "طي",
127
+ "placeholder": "اختر…",
128
+ "clearSelection": "مسح التحديد",
129
+ "removeItem": "إزالة {{label}}",
130
+ "more": "+{{count}} أخرى"
131
+ },
132
+ "commandPalette": {
133
+ "label": "لوحة الأوامر",
134
+ "placeholder": "اكتب أمرًا أو ابحث…",
135
+ "noResults": "لا توجد نتائج",
136
+ "loading": "جارٍ البحث…",
137
+ "escHint": "esc"
138
+ },
139
+ "empty": {
140
+ "noData": "لا توجد بيانات"
141
+ },
142
+ "fileUpload": {
143
+ "browse": "انقر للاستعراض",
144
+ "dropZone": "أو أفلت الملفات هنا",
145
+ "dropZoneLabel": "منطقة إفلات الملفات — انقر أو أفلت الملفات",
146
+ "removeFile": "إزالة الملف",
147
+ "invalid": "نوع ملف غير مدعوم",
148
+ "tooBig": "حجم الملف كبير جدًا",
149
+ "size": "{{value}} {{unit}}",
150
+ "unitByte": "بايت",
151
+ "unitKb": "كيلوبايت",
152
+ "unitMb": "ميجابايت",
153
+ "unitGb": "جيجابايت",
154
+ "unitTb": "تيرابايت"
155
+ },
156
+ "popconfirm": {
157
+ "label": "تأكيد الإجراء",
158
+ "confirm": "تأكيد",
159
+ "cancel": "إلغاء"
160
+ },
161
+ "toast": {
162
+ "region": "الإشعارات",
163
+ "close": "إغلاق",
164
+ "copy": "نسخ",
165
+ "copied": "تم النسخ",
166
+ "closeAll": "إغلاق الكل"
167
+ },
168
+ "input": {
169
+ "showPassword": "إظهار كلمة المرور",
170
+ "hidePassword": "إخفاء كلمة المرور"
171
+ },
172
+ "inputNumber": {
173
+ "increment": "زيادة",
174
+ "decrement": "إنقاص"
175
+ },
176
+ "inputOtp": {
177
+ "label": "رمز التحقق",
178
+ "digit": "الرقم {{index}}",
179
+ "character": "الحرف {{index}}"
180
+ },
181
+ "anchor": {
182
+ "label": "جدول المحتويات"
183
+ },
184
+ "avatar": {
185
+ "alt": "الصورة الرمزية"
186
+ },
187
+ "backTop": {
188
+ "label": "العودة إلى الأعلى"
189
+ },
190
+ "breadcrumbs": {
191
+ "label": "مسار التنقل"
192
+ },
193
+ "burger": {
194
+ "label": "تبديل القائمة"
195
+ },
196
+ "calendar": {
197
+ "prevMonth": "الشهر السابق",
198
+ "nextMonth": "الشهر التالي",
199
+ "prevYear": "السنة السابقة",
200
+ "nextYear": "السنة التالية",
201
+ "monthList": "الأشهر",
202
+ "yearList": "السنوات",
203
+ "prevYears": "12 سنة سابقة",
204
+ "nextYears": "12 سنة تالية",
205
+ "header": "{{month}} {{year}}",
206
+ "yearRange": "{{from}} – {{to}}",
207
+ "dayLabel": "{{weekday}}، {{date}}"
208
+ },
209
+ "imageCropper": {
210
+ "empty": "لا توجد صورة",
211
+ "window": "منطقة الاقتصاص",
212
+ "keyHelp": "مفاتيح الأسهم تحرّك منطقة الاقتصاص. اضغط باستمرار على Alt مع أحد مفاتيح الأسهم لتغيير حجمها، وعلى Shift لخطوات أكبر. يُعلن عن المنطقة بقيم اليسار والأعلى والعرض والارتفاع بالبكسل داخل الصورة."
213
+ },
214
+ "sortableList": {
215
+ "keyHelp": "اضغط مفتاح المسافة لالتقاط هذا العنصر، ثم استخدم مفاتيح الأسهم لتحريكه. اضغط مفتاح المسافة مرة أخرى لإفلاته، أو Escape لإعادته إلى مكانه.",
216
+ "grabbed": "تم الالتقاط. {{index}} من {{total}}.",
217
+ "moved": "{{index}} من {{total}}.",
218
+ "dropped": "تم الإفلات. {{index}} من {{total}}.",
219
+ "cancelled": "تم إلغاء النقل."
220
+ },
221
+ "colorPicker": {
222
+ "area": "التشبع والسطوع، {{saturation}}% و{{brightness}}%",
223
+ "hue": "درجة اللون",
224
+ "alpha": "العتامة",
225
+ "formatHex": "HEX",
226
+ "formatRgb": "RGB",
227
+ "formatHsl": "HSL",
228
+ "channelHex": "HEX",
229
+ "channelRed": "R",
230
+ "channelGreen": "G",
231
+ "channelBlue": "B",
232
+ "channelHue": "H",
233
+ "channelSaturation": "S%",
234
+ "channelLightness": "L%",
235
+ "channelAlpha": "A%"
236
+ },
237
+ "calendarHeatmap": {
238
+ "label": "خريطة حرارية للتقويم"
239
+ },
240
+ "lineChart": {
241
+ "label": "مخطط خطي",
242
+ "thousands": "{{value}} ألف"
243
+ },
244
+ "donutChart": {
245
+ "label": "مخطط دائري مجوف"
246
+ },
247
+ "compare": {
248
+ "label": "فاصل المقارنة"
249
+ },
250
+ "carousel": {
251
+ "label": "العرض الدوّار",
252
+ "goToSlide": "الانتقال إلى الشريحة {{index}}",
253
+ "prev": "الشريحة السابقة",
254
+ "next": "الشريحة التالية",
255
+ "pagination": "ترقيم شرائح العرض الدوّار",
256
+ "roledescription": "عرض دوّار",
257
+ "slideRoledescription": "شريحة"
258
+ },
259
+ "actionSheet": {
260
+ "label": "الإجراءات"
261
+ },
262
+ "alert": {
263
+ "close": "إغلاق التنبيه"
264
+ },
265
+ "qr": {
266
+ "label": "رمز QR"
267
+ },
268
+ "image": {
269
+ "viewer": "معاينة الصورة",
270
+ "open": "فتح المعاينة",
271
+ "close": "إغلاق المعاينة"
272
+ },
273
+ "window": {
274
+ "close": "إغلاق",
275
+ "minimize": "تصغير",
276
+ "maximize": "تكبير",
277
+ "restore": "استعادة",
278
+ "restoreDown": "استعادة لأسفل",
279
+ "restoreWindow": "استعادة {{title}}",
280
+ "closeWindow": "إغلاق النافذة",
281
+ "untitled": "بلا عنوان",
282
+ "taskbar": "النوافذ المصغّرة"
283
+ },
284
+ "dialog": {
285
+ "close": "إغلاق مربع الحوار"
286
+ },
287
+ "popover": {
288
+ "label": "لوحة منبثقة"
289
+ },
290
+ "markdown": {
291
+ "copy": "نسخ الكود",
292
+ "copied": "تم النسخ",
293
+ "taskDone": "تم:",
294
+ "taskTodo": "لم يتم:"
295
+ },
296
+ "marquee": {
297
+ "label": "شريط متحرك",
298
+ "link": "رابط"
299
+ },
300
+ "mention": {
301
+ "listbox": "الإشارات",
302
+ "available": "المطابقات المتاحة: {{count}}",
303
+ "inserted": "تم الإدراج: {{label}}"
304
+ },
305
+ "drawer": {
306
+ "close": "إغلاق اللوحة"
307
+ },
308
+ "datePicker": {
309
+ "open": "فتح التقويم",
310
+ "openTime": "فتح منتقي الوقت",
311
+ "openDateTime": "فتح منتقي التاريخ والوقت",
312
+ "openRange": "فتح تقويم الفترة",
313
+ "panel": "اختيار التاريخ",
314
+ "panelTime": "اختيار الوقت",
315
+ "panelDateTime": "اختيار التاريخ والوقت",
316
+ "panelRange": "اختيار الفترة",
317
+ "panelRangeDateTime": "اختيار الفترة بالتاريخ والوقت",
318
+ "rangeStart": "بداية الفترة",
319
+ "rangeEnd": "نهاية الفترة",
320
+ "startTime": "وقت البدء",
321
+ "endTime": "وقت الانتهاء",
322
+ "hours": "الساعات",
323
+ "minutes": "الدقائق",
324
+ "seconds": "الثواني",
325
+ "incrementHours": "زيادة الساعات",
326
+ "decrementHours": "إنقاص الساعات",
327
+ "incrementMinutes": "زيادة الدقائق",
328
+ "decrementMinutes": "إنقاص الدقائق",
329
+ "incrementSeconds": "زيادة الثواني",
330
+ "decrementSeconds": "إنقاص الثواني",
331
+ "toggleAmPm": "تبديل ص / م",
332
+ "am": "ص",
333
+ "pm": "م"
334
+ },
335
+ "sidebar": {
336
+ "label": "الشريط الجانبي"
337
+ },
338
+ "spinner": {
339
+ "label": "جارٍ التحميل"
340
+ },
341
+ "rating": {
342
+ "label": "التقييم"
343
+ },
344
+ "gauge": {
345
+ "label": "عداد"
346
+ },
347
+ "progress": {
348
+ "label": "التقدم"
349
+ },
350
+ "meterGroup": {
351
+ "label": "مقياس"
352
+ },
353
+ "knob": {
354
+ "label": "القيمة"
355
+ },
356
+ "slider": {
357
+ "label": "القيمة",
358
+ "lower": "القيمة الدنيا",
359
+ "upper": "القيمة العليا"
360
+ },
361
+ "speedDial": {
362
+ "label": "الإجراءات"
363
+ },
364
+ "statistic": {
365
+ "delta": "{{value}}{{suffix}}",
366
+ "deltaSuffix": "%"
367
+ },
368
+ "result": {
369
+ "notFound": "عذرًا، الصفحة التي زرتها غير موجودة.",
370
+ "forbidden": "عذرًا، ليس لديك إذن بالوصول إلى هذه الصفحة.",
371
+ "serverError": "عذرًا، حدث خطأ ما."
372
+ },
373
+ "date": {
374
+ "months": {
375
+ "jan": "يناير",
376
+ "feb": "فبراير",
377
+ "mar": "مارس",
378
+ "apr": "أبريل",
379
+ "may": "مايو",
380
+ "jun": "يونيو",
381
+ "jul": "يوليو",
382
+ "aug": "أغسطس",
383
+ "sep": "سبتمبر",
384
+ "oct": "أكتوبر",
385
+ "nov": "نوفمبر",
386
+ "dec": "ديسمبر"
387
+ }
388
+ }
389
+ }