@harness-engineering/cli 1.6.2 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/personas/documentation-maintainer.yaml +3 -1
- package/dist/agents/personas/performance-guardian.yaml +23 -0
- package/dist/agents/personas/planner.yaml +27 -0
- package/dist/agents/personas/verifier.yaml +30 -0
- package/dist/agents/skills/claude-code/align-documentation/SKILL.md +13 -0
- package/dist/agents/skills/claude-code/cleanup-dead-code/SKILL.md +25 -1
- package/dist/agents/skills/claude-code/cleanup-dead-code/skill.yaml +5 -2
- package/dist/agents/skills/claude-code/detect-doc-drift/SKILL.md +12 -0
- package/dist/agents/skills/claude-code/enforce-architecture/SKILL.md +67 -1
- package/dist/agents/skills/claude-code/enforce-architecture/skill.yaml +5 -2
- package/dist/agents/skills/claude-code/harness-accessibility/SKILL.md +281 -0
- package/dist/agents/skills/claude-code/harness-accessibility/skill.yaml +51 -0
- package/dist/agents/skills/claude-code/harness-autopilot/SKILL.md +119 -72
- package/dist/agents/skills/claude-code/harness-autopilot/skill.yaml +4 -2
- package/dist/agents/skills/claude-code/harness-brainstorming/SKILL.md +76 -4
- package/dist/agents/skills/claude-code/harness-brainstorming/skill.yaml +2 -0
- package/dist/agents/skills/claude-code/harness-code-review/SKILL.md +487 -234
- package/dist/agents/skills/claude-code/harness-code-review/skill.yaml +15 -2
- package/dist/agents/skills/claude-code/harness-codebase-cleanup/SKILL.md +226 -0
- package/dist/agents/skills/claude-code/harness-codebase-cleanup/skill.yaml +64 -0
- package/dist/agents/skills/claude-code/harness-dependency-health/SKILL.md +35 -6
- package/dist/agents/skills/claude-code/harness-dependency-health/skill.yaml +1 -1
- package/dist/agents/skills/claude-code/harness-design/SKILL.md +265 -0
- package/dist/agents/skills/claude-code/harness-design/skill.yaml +53 -0
- package/dist/agents/skills/claude-code/harness-design-mobile/SKILL.md +336 -0
- package/dist/agents/skills/claude-code/harness-design-mobile/skill.yaml +49 -0
- package/dist/agents/skills/claude-code/harness-design-system/SKILL.md +282 -0
- package/dist/agents/skills/claude-code/harness-design-system/skill.yaml +50 -0
- package/dist/agents/skills/claude-code/harness-design-web/SKILL.md +360 -0
- package/dist/agents/skills/claude-code/harness-design-web/skill.yaml +52 -0
- package/dist/agents/skills/claude-code/harness-docs-pipeline/SKILL.md +460 -0
- package/dist/agents/skills/claude-code/harness-docs-pipeline/skill.yaml +69 -0
- package/dist/agents/skills/claude-code/harness-execution/SKILL.md +73 -8
- package/dist/agents/skills/claude-code/harness-execution/skill.yaml +1 -0
- package/dist/agents/skills/claude-code/harness-hotspot-detector/SKILL.md +32 -6
- package/dist/agents/skills/claude-code/harness-hotspot-detector/skill.yaml +1 -1
- package/dist/agents/skills/claude-code/harness-i18n/SKILL.md +484 -0
- package/dist/agents/skills/claude-code/harness-i18n/skill.yaml +54 -0
- package/dist/agents/skills/claude-code/harness-i18n-process/SKILL.md +388 -0
- package/dist/agents/skills/claude-code/harness-i18n-process/skill.yaml +43 -0
- package/dist/agents/skills/claude-code/harness-i18n-workflow/SKILL.md +512 -0
- package/dist/agents/skills/claude-code/harness-i18n-workflow/skill.yaml +53 -0
- package/dist/agents/skills/claude-code/harness-impact-analysis/SKILL.md +51 -6
- package/dist/agents/skills/claude-code/harness-integrity/SKILL.md +35 -1
- package/dist/agents/skills/claude-code/harness-knowledge-mapper/SKILL.md +46 -5
- package/dist/agents/skills/claude-code/harness-knowledge-mapper/skill.yaml +1 -1
- package/dist/agents/skills/claude-code/harness-onboarding/SKILL.md +19 -1
- package/dist/agents/skills/claude-code/harness-perf/SKILL.md +37 -8
- package/dist/agents/skills/claude-code/harness-perf/skill.yaml +3 -0
- package/dist/agents/skills/claude-code/harness-perf-tdd/SKILL.md +17 -4
- package/dist/agents/skills/claude-code/harness-planning/SKILL.md +57 -3
- package/dist/agents/skills/claude-code/harness-planning/skill.yaml +2 -0
- package/dist/agents/skills/claude-code/harness-release-readiness/SKILL.md +29 -9
- package/dist/agents/skills/claude-code/harness-roadmap/SKILL.md +562 -0
- package/dist/agents/skills/claude-code/harness-roadmap/skill.yaml +43 -0
- package/dist/agents/skills/claude-code/harness-security-review/SKILL.md +36 -2
- package/dist/agents/skills/claude-code/harness-security-review/skill.yaml +8 -6
- package/dist/agents/skills/claude-code/harness-security-scan/skill.yaml +1 -1
- package/dist/agents/skills/claude-code/harness-soundness-review/SKILL.md +1267 -0
- package/dist/agents/skills/claude-code/harness-soundness-review/skill.yaml +48 -0
- package/dist/agents/skills/claude-code/harness-test-advisor/SKILL.md +35 -6
- package/dist/agents/skills/claude-code/harness-verification/SKILL.md +66 -0
- package/dist/agents/skills/claude-code/harness-verification/skill.yaml +1 -0
- package/dist/agents/skills/claude-code/harness-verify/SKILL.md +37 -0
- package/dist/agents/skills/claude-code/initialize-harness-project/SKILL.md +15 -1
- package/dist/agents/skills/claude-code/validate-context-engineering/SKILL.md +12 -0
- package/dist/agents/skills/gemini-cli/harness-accessibility/SKILL.md +281 -0
- package/dist/agents/skills/gemini-cli/harness-accessibility/skill.yaml +51 -0
- package/dist/agents/skills/gemini-cli/harness-autopilot/SKILL.md +119 -72
- package/dist/agents/skills/gemini-cli/harness-autopilot/skill.yaml +4 -2
- package/dist/agents/skills/gemini-cli/harness-codebase-cleanup/SKILL.md +226 -0
- package/dist/agents/skills/gemini-cli/harness-codebase-cleanup/skill.yaml +64 -0
- package/dist/agents/skills/gemini-cli/harness-dependency-health/SKILL.md +35 -6
- package/dist/agents/skills/gemini-cli/harness-dependency-health/skill.yaml +1 -1
- package/dist/agents/skills/gemini-cli/harness-design/SKILL.md +265 -0
- package/dist/agents/skills/gemini-cli/harness-design/skill.yaml +53 -0
- package/dist/agents/skills/gemini-cli/harness-design-mobile/SKILL.md +336 -0
- package/dist/agents/skills/gemini-cli/harness-design-mobile/skill.yaml +49 -0
- package/dist/agents/skills/gemini-cli/harness-design-system/SKILL.md +282 -0
- package/dist/agents/skills/gemini-cli/harness-design-system/skill.yaml +50 -0
- package/dist/agents/skills/gemini-cli/harness-design-web/SKILL.md +360 -0
- package/dist/agents/skills/gemini-cli/harness-design-web/skill.yaml +52 -0
- package/dist/agents/skills/gemini-cli/harness-docs-pipeline/SKILL.md +460 -0
- package/dist/agents/skills/gemini-cli/harness-docs-pipeline/skill.yaml +69 -0
- package/dist/agents/skills/gemini-cli/harness-hotspot-detector/SKILL.md +32 -6
- package/dist/agents/skills/gemini-cli/harness-hotspot-detector/skill.yaml +1 -1
- package/dist/agents/skills/gemini-cli/harness-i18n/SKILL.md +484 -0
- package/dist/agents/skills/gemini-cli/harness-i18n/skill.yaml +54 -0
- package/dist/agents/skills/gemini-cli/harness-i18n-process/SKILL.md +388 -0
- package/dist/agents/skills/gemini-cli/harness-i18n-process/skill.yaml +43 -0
- package/dist/agents/skills/gemini-cli/harness-i18n-workflow/SKILL.md +512 -0
- package/dist/agents/skills/gemini-cli/harness-i18n-workflow/skill.yaml +53 -0
- package/dist/agents/skills/gemini-cli/harness-impact-analysis/SKILL.md +51 -6
- package/dist/agents/skills/gemini-cli/harness-knowledge-mapper/SKILL.md +46 -5
- package/dist/agents/skills/gemini-cli/harness-knowledge-mapper/skill.yaml +1 -1
- package/dist/agents/skills/gemini-cli/harness-perf/SKILL.md +37 -8
- package/dist/agents/skills/gemini-cli/harness-perf/skill.yaml +3 -0
- package/dist/agents/skills/gemini-cli/harness-perf-tdd/SKILL.md +17 -4
- package/dist/agents/skills/gemini-cli/harness-release-readiness/SKILL.md +29 -9
- package/dist/agents/skills/gemini-cli/harness-roadmap/SKILL.md +562 -0
- package/dist/agents/skills/gemini-cli/harness-roadmap/skill.yaml +43 -0
- package/dist/agents/skills/gemini-cli/harness-security-review/skill.yaml +8 -6
- package/dist/agents/skills/gemini-cli/harness-security-scan/skill.yaml +1 -1
- package/dist/agents/skills/gemini-cli/harness-soundness-review/SKILL.md +1267 -0
- package/dist/agents/skills/gemini-cli/harness-soundness-review/skill.yaml +48 -0
- package/dist/agents/skills/gemini-cli/harness-test-advisor/SKILL.md +35 -6
- package/dist/agents/skills/node_modules/.bin/vitest +2 -2
- package/dist/agents/skills/shared/design-knowledge/anti-patterns/color.yaml +106 -0
- package/dist/agents/skills/shared/design-knowledge/anti-patterns/layout.yaml +109 -0
- package/dist/agents/skills/shared/design-knowledge/anti-patterns/motion.yaml +109 -0
- package/dist/agents/skills/shared/design-knowledge/anti-patterns/typography.yaml +112 -0
- package/dist/agents/skills/shared/design-knowledge/industries/creative.yaml +80 -0
- package/dist/agents/skills/shared/design-knowledge/industries/ecommerce.yaml +80 -0
- package/dist/agents/skills/shared/design-knowledge/industries/emerging-tech.yaml +83 -0
- package/dist/agents/skills/shared/design-knowledge/industries/fintech.yaml +80 -0
- package/dist/agents/skills/shared/design-knowledge/industries/healthcare.yaml +80 -0
- package/dist/agents/skills/shared/design-knowledge/industries/lifestyle.yaml +80 -0
- package/dist/agents/skills/shared/design-knowledge/industries/saas.yaml +80 -0
- package/dist/agents/skills/shared/design-knowledge/industries/services.yaml +80 -0
- package/dist/agents/skills/shared/design-knowledge/palettes/curated.yaml +234 -0
- package/dist/agents/skills/shared/design-knowledge/platform-rules/android.yaml +125 -0
- package/dist/agents/skills/shared/design-knowledge/platform-rules/flutter.yaml +144 -0
- package/dist/agents/skills/shared/design-knowledge/platform-rules/ios.yaml +106 -0
- package/dist/agents/skills/shared/design-knowledge/platform-rules/web.yaml +102 -0
- package/dist/agents/skills/shared/design-knowledge/typography/pairings.yaml +274 -0
- package/dist/agents/skills/shared/i18n-knowledge/accessibility/intersection.yaml +142 -0
- package/dist/agents/skills/shared/i18n-knowledge/anti-patterns/encoding.yaml +67 -0
- package/dist/agents/skills/shared/i18n-knowledge/anti-patterns/formatting.yaml +106 -0
- package/dist/agents/skills/shared/i18n-knowledge/anti-patterns/layout.yaml +80 -0
- package/dist/agents/skills/shared/i18n-knowledge/anti-patterns/pluralization.yaml +80 -0
- package/dist/agents/skills/shared/i18n-knowledge/anti-patterns/string-handling.yaml +106 -0
- package/dist/agents/skills/shared/i18n-knowledge/frameworks/android-resources.yaml +47 -0
- package/dist/agents/skills/shared/i18n-knowledge/frameworks/apple-strings.yaml +47 -0
- package/dist/agents/skills/shared/i18n-knowledge/frameworks/backend-patterns.yaml +50 -0
- package/dist/agents/skills/shared/i18n-knowledge/frameworks/flutter-intl.yaml +47 -0
- package/dist/agents/skills/shared/i18n-knowledge/frameworks/i18next.yaml +47 -0
- package/dist/agents/skills/shared/i18n-knowledge/frameworks/react-intl.yaml +47 -0
- package/dist/agents/skills/shared/i18n-knowledge/frameworks/vue-i18n.yaml +47 -0
- package/dist/agents/skills/shared/i18n-knowledge/industries/ecommerce.yaml +66 -0
- package/dist/agents/skills/shared/i18n-knowledge/industries/fintech.yaml +66 -0
- package/dist/agents/skills/shared/i18n-knowledge/industries/gaming.yaml +69 -0
- package/dist/agents/skills/shared/i18n-knowledge/industries/healthcare.yaml +66 -0
- package/dist/agents/skills/shared/i18n-knowledge/industries/legal.yaml +66 -0
- package/dist/agents/skills/shared/i18n-knowledge/locales/ar.yaml +41 -0
- package/dist/agents/skills/shared/i18n-knowledge/locales/de.yaml +35 -0
- package/dist/agents/skills/shared/i18n-knowledge/locales/en.yaml +32 -0
- package/dist/agents/skills/shared/i18n-knowledge/locales/es.yaml +35 -0
- package/dist/agents/skills/shared/i18n-knowledge/locales/fi.yaml +35 -0
- package/dist/agents/skills/shared/i18n-knowledge/locales/fr.yaml +35 -0
- package/dist/agents/skills/shared/i18n-knowledge/locales/he.yaml +41 -0
- package/dist/agents/skills/shared/i18n-knowledge/locales/hi.yaml +35 -0
- package/dist/agents/skills/shared/i18n-knowledge/locales/it.yaml +32 -0
- package/dist/agents/skills/shared/i18n-knowledge/locales/ja.yaml +38 -0
- package/dist/agents/skills/shared/i18n-knowledge/locales/ko.yaml +38 -0
- package/dist/agents/skills/shared/i18n-knowledge/locales/nl.yaml +32 -0
- package/dist/agents/skills/shared/i18n-knowledge/locales/pl.yaml +35 -0
- package/dist/agents/skills/shared/i18n-knowledge/locales/pt.yaml +32 -0
- package/dist/agents/skills/shared/i18n-knowledge/locales/ru.yaml +35 -0
- package/dist/agents/skills/shared/i18n-knowledge/locales/sv.yaml +32 -0
- package/dist/agents/skills/shared/i18n-knowledge/locales/th.yaml +35 -0
- package/dist/agents/skills/shared/i18n-knowledge/locales/tr.yaml +35 -0
- package/dist/agents/skills/shared/i18n-knowledge/locales/zh-Hans.yaml +38 -0
- package/dist/agents/skills/shared/i18n-knowledge/locales/zh-Hant.yaml +35 -0
- package/dist/agents/skills/shared/i18n-knowledge/mcp-interop/i18next-mcp.yaml +56 -0
- package/dist/agents/skills/shared/i18n-knowledge/mcp-interop/lingo-dev.yaml +56 -0
- package/dist/agents/skills/shared/i18n-knowledge/mcp-interop/lokalise.yaml +60 -0
- package/dist/agents/skills/shared/i18n-knowledge/mcp-interop/tolgee.yaml +60 -0
- package/dist/agents/skills/shared/i18n-knowledge/testing/locale-testing.yaml +107 -0
- package/dist/agents/skills/shared/i18n-knowledge/testing/pseudo-localization.yaml +86 -0
- package/dist/bin/harness.js +64 -4
- package/dist/{chunk-UDWGSL3T.js → chunk-3JWCBVUZ.js} +3 -3
- package/dist/{chunk-IUFFBBYV.js → chunk-LNI4T7R6.js} +179 -61
- package/dist/{chunk-USEYPS7F.js → chunk-SJECMKSS.js} +2250 -40
- package/dist/{dist-4MYPT3OE.js → dist-BDO5GFEM.js} +295 -14
- package/dist/{dist-RBZXXJHG.js → dist-NT3GXHQZ.js} +95 -1
- package/dist/index.d.ts +266 -7
- package/dist/index.js +7 -3
- package/dist/validate-cross-check-2OPGCGGU.js +7 -0
- package/package.json +7 -7
- package/dist/validate-cross-check-CPEPNLOD.js +0 -7
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
name: "React Intl (FormatJS)"
|
|
2
|
+
description: "ICU MessageFormat-based i18n library for React, part of the FormatJS ecosystem"
|
|
3
|
+
platforms: ["web"]
|
|
4
|
+
message_format: "icu"
|
|
5
|
+
|
|
6
|
+
detection:
|
|
7
|
+
package_json_keys:
|
|
8
|
+
dependencies: ["react-intl", "@formatjs/intl", "@formatjs/intl-messageformat"]
|
|
9
|
+
devDependencies: ["@formatjs/cli", "eslint-plugin-formatjs", "@formatjs/ts-transformer"]
|
|
10
|
+
file_patterns: ["src/**/*.{ts,tsx,js,jsx}"]
|
|
11
|
+
config_files: [".formatjsrc", ".formatjsrc.json"]
|
|
12
|
+
|
|
13
|
+
conventions:
|
|
14
|
+
key_format: "dot-notation"
|
|
15
|
+
file_format: "json"
|
|
16
|
+
file_structure: "lang/{locale}.json"
|
|
17
|
+
plural_syntax: "ICU {count, plural, one {# item} other {# items}}"
|
|
18
|
+
interpolation_syntax: "{variable}"
|
|
19
|
+
|
|
20
|
+
recommended_tooling:
|
|
21
|
+
extraction: ["@formatjs/cli extract"]
|
|
22
|
+
linting: ["eslint-plugin-formatjs"]
|
|
23
|
+
pseudo_locale: ["@formatjs/cli compile --pseudo-locale"]
|
|
24
|
+
|
|
25
|
+
anti_patterns:
|
|
26
|
+
- pattern: "String concatenation inside FormattedMessage"
|
|
27
|
+
severity: error
|
|
28
|
+
instead: "Use ICU MessageFormat with placeholders: <FormattedMessage id='greeting' values={{name}} />"
|
|
29
|
+
- pattern: "Using defaultMessage as the translation key"
|
|
30
|
+
severity: warning
|
|
31
|
+
instead: "Use explicit message IDs (dot-notation) for stable keys; defaultMessage is a fallback, not an ID"
|
|
32
|
+
- pattern: "Inline messages without extraction"
|
|
33
|
+
severity: warning
|
|
34
|
+
instead: "Run @formatjs/cli extract to generate message catalogs; do not manually maintain translation files"
|
|
35
|
+
- pattern: "Using dangerouslySetInnerHTML with translated strings"
|
|
36
|
+
severity: error
|
|
37
|
+
instead: "Use FormattedMessage rich text support: <FormattedMessage values={{b: chunks => <b>{chunks}</b>}} />"
|
|
38
|
+
- pattern: "Not wrapping date/number formatting with FormatJS APIs"
|
|
39
|
+
severity: warning
|
|
40
|
+
instead: "Use intl.formatDate(), intl.formatNumber(), and intl.formatRelativeTime() for locale-aware formatting"
|
|
41
|
+
|
|
42
|
+
migration_notes:
|
|
43
|
+
from:
|
|
44
|
+
- framework: "i18next"
|
|
45
|
+
guidance: "Convert {{variable}} interpolation to {variable}; convert i18next plural suffixes (_one, _other) to ICU plural syntax; update extraction pipeline from i18next-parser to @formatjs/cli"
|
|
46
|
+
- framework: "vue-i18n"
|
|
47
|
+
guidance: "Convert $t() calls to useIntl().formatMessage(); convert named interpolation to ICU syntax; move from SFC i18n blocks to centralized message files"
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
name: "Vue I18n"
|
|
2
|
+
description: "Internationalization plugin for Vue.js with SFC support and composition API integration"
|
|
3
|
+
platforms: ["web"]
|
|
4
|
+
message_format: "icu"
|
|
5
|
+
|
|
6
|
+
detection:
|
|
7
|
+
package_json_keys:
|
|
8
|
+
dependencies: ["vue-i18n", "@intlify/vue-i18n-extensions", "@intlify/unplugin-vue-i18n"]
|
|
9
|
+
devDependencies: ["@intlify/vite-plugin-vue-i18n", "@intlify/eslint-plugin-vue-i18n"]
|
|
10
|
+
file_patterns: ["src/**/*.vue", "src/locales/**/*.{json,yaml}"]
|
|
11
|
+
config_files: ["vue-i18n.config.ts", "i18n.ts"]
|
|
12
|
+
|
|
13
|
+
conventions:
|
|
14
|
+
key_format: "dot-notation"
|
|
15
|
+
file_format: "json"
|
|
16
|
+
file_structure: "src/locales/{locale}.json"
|
|
17
|
+
plural_syntax: "ICU {count, plural, one {# item} other {# items}} or pipe syntax: item | items"
|
|
18
|
+
interpolation_syntax: "{variable} or @:key for linked messages"
|
|
19
|
+
|
|
20
|
+
recommended_tooling:
|
|
21
|
+
extraction: ["@intlify/cli"]
|
|
22
|
+
linting: ["@intlify/eslint-plugin-vue-i18n"]
|
|
23
|
+
pseudo_locale: ["custom generator with vue-i18n message compiler"]
|
|
24
|
+
|
|
25
|
+
anti_patterns:
|
|
26
|
+
- pattern: "Using v-html with translated strings"
|
|
27
|
+
severity: error
|
|
28
|
+
instead: "Use the <i18n-t> component with named slots for HTML in translations — v-html creates XSS risk"
|
|
29
|
+
- pattern: "Hardcoding messages in template attributes"
|
|
30
|
+
severity: warning
|
|
31
|
+
instead: "Use $t() in attribute bindings: :placeholder=\"$t('search.placeholder')\" instead of hardcoded strings"
|
|
32
|
+
- pattern: "Not using SFC <i18n> blocks for component-local messages"
|
|
33
|
+
severity: info
|
|
34
|
+
instead: "Put component-specific messages in <i18n> blocks to co-locate translations with the component"
|
|
35
|
+
- pattern: "Ignoring SSR hydration mismatch with locale detection"
|
|
36
|
+
severity: error
|
|
37
|
+
instead: "Detect locale server-side (Accept-Language header) and pass to client to prevent hydration mismatch"
|
|
38
|
+
- pattern: "Using legacy API ($t) in Composition API components"
|
|
39
|
+
severity: warning
|
|
40
|
+
instead: "Use useI18n() composable in <script setup> components for type-safe translation access"
|
|
41
|
+
|
|
42
|
+
migration_notes:
|
|
43
|
+
from:
|
|
44
|
+
- framework: "vue-i18n v8 (Vue 2)"
|
|
45
|
+
guidance: "Migrate from VueI18n class to createI18n(); update $t() to useI18n().t() in Composition API; convert <i18n> blocks to new format"
|
|
46
|
+
- framework: "i18next"
|
|
47
|
+
guidance: "Convert {{variable}} to {variable}; map namespaces to vue-i18n scoped messages; replace useTranslation() with useI18n()"
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
name: "Ecommerce"
|
|
2
|
+
description: "i18n challenges in ecommerce — address formats, measurement units, tax display, and payment localization across markets"
|
|
3
|
+
|
|
4
|
+
requirements:
|
|
5
|
+
- area: "Address Format"
|
|
6
|
+
description: "Address field order and content varies dramatically by country — Japan puts postal code first, US puts it last"
|
|
7
|
+
severity: error
|
|
8
|
+
locales_affected: "all"
|
|
9
|
+
examples:
|
|
10
|
+
- bad: "Fixed form: Street, City, State, Zip, Country"
|
|
11
|
+
good: "Use Google's libaddressinput or similar to render country-specific address forms"
|
|
12
|
+
- area: "Measurement Units"
|
|
13
|
+
description: "Product dimensions, weight, and volume must display in locale-expected units"
|
|
14
|
+
severity: warning
|
|
15
|
+
locales_affected: "all"
|
|
16
|
+
examples:
|
|
17
|
+
- bad: "Showing all dimensions in inches regardless of locale"
|
|
18
|
+
good: "Display metric units (cm, kg, L) for most locales; imperial (in, lb, fl oz) for US/UK where expected"
|
|
19
|
+
- area: "Tax Display"
|
|
20
|
+
description: "VAT-inclusive (most of world) vs tax-exclusive (US) pricing causes confusion if not handled per locale"
|
|
21
|
+
severity: error
|
|
22
|
+
locales_affected: "all"
|
|
23
|
+
examples:
|
|
24
|
+
- bad: "Showing $99.99 without indicating whether tax is included"
|
|
25
|
+
good: "Show 'incl. VAT' for EU locales, separate tax line for US locales, GST-inclusive for AU/NZ"
|
|
26
|
+
- area: "Phone Number Formatting"
|
|
27
|
+
description: "Phone number input and display must support international formats"
|
|
28
|
+
severity: warning
|
|
29
|
+
locales_affected: "all"
|
|
30
|
+
examples:
|
|
31
|
+
- bad: "Validating phone with regex: /^\\d{10}$/"
|
|
32
|
+
good: "Use libphonenumber for validation and formatting; store in E.164 format (+1234567890)"
|
|
33
|
+
- area: "Sizing Charts"
|
|
34
|
+
description: "Clothing and shoe sizes vary by country — US 8 is EU 38 for women's shoes"
|
|
35
|
+
severity: warning
|
|
36
|
+
locales_affected: "all"
|
|
37
|
+
examples:
|
|
38
|
+
- bad: "Showing only US sizes for international customers"
|
|
39
|
+
good: "Display size conversion charts; show locale-primary sizing with equivalents"
|
|
40
|
+
|
|
41
|
+
anti_patterns:
|
|
42
|
+
- pattern: "Hardcoding address field order"
|
|
43
|
+
reason: "Japan: postal-code, prefecture, city, street; Germany: street, postal-code city; varied worldwide"
|
|
44
|
+
instead: "Use a country-aware address component that adapts field order per shipping country"
|
|
45
|
+
- pattern: "Validating postal codes with a single regex"
|
|
46
|
+
reason: "Postal code formats range from 5 digits (US) to alphanumeric (UK: SW1A 1AA) to none (Ireland historically)"
|
|
47
|
+
instead: "Use country-specific postal code validation or a library like i18n-postal-code"
|
|
48
|
+
- pattern: "Displaying prices without currency context"
|
|
49
|
+
reason: "$99 is ambiguous — USD, CAD, AUD, and others use $; customer may see wrong currency"
|
|
50
|
+
instead: "Always show the currency code or unambiguous symbol; use Intl.NumberFormat with currency"
|
|
51
|
+
- pattern: "Shipping method names not localized"
|
|
52
|
+
reason: "'2-Day Shipping' is meaningless outside the origin country's postal system"
|
|
53
|
+
instead: "Show estimated delivery date instead of carrier-specific service names"
|
|
54
|
+
|
|
55
|
+
regulations:
|
|
56
|
+
- name: "EU Consumer Rights Directive"
|
|
57
|
+
locales: ["EU member states"]
|
|
58
|
+
impact: "Prices must be displayed inclusive of VAT in the currency of the target market"
|
|
59
|
+
- name: "GDPR"
|
|
60
|
+
locales: ["EU member states"]
|
|
61
|
+
impact: "Privacy policy and consent language must be in the user's language and legally accurate per jurisdiction"
|
|
62
|
+
- name: "California Consumer Privacy Act (CCPA)"
|
|
63
|
+
locales: ["en-US"]
|
|
64
|
+
impact: "Privacy notices must be accessible; consider multilingual California population"
|
|
65
|
+
|
|
66
|
+
reference_products: ["shopify.com", "amazon.com", "etsy.com", "zalando.com"]
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
name: "Fintech"
|
|
2
|
+
description: "i18n challenges in financial technology — currency precision, number formatting, and regulatory compliance across markets"
|
|
3
|
+
|
|
4
|
+
requirements:
|
|
5
|
+
- area: "Currency Display"
|
|
6
|
+
description: "Currency formatting varies by locale — symbol position, decimal precision, and grouping separators differ"
|
|
7
|
+
severity: error
|
|
8
|
+
locales_affected: "all"
|
|
9
|
+
examples:
|
|
10
|
+
- bad: "'$' + amount.toFixed(2)"
|
|
11
|
+
good: "new Intl.NumberFormat(locale, { style: 'currency', currency: currencyCode }).format(amount)"
|
|
12
|
+
- area: "Currency Precision"
|
|
13
|
+
description: "Decimal places vary by currency — JPY has 0, USD/EUR have 2, BHD/KWD have 3"
|
|
14
|
+
severity: error
|
|
15
|
+
locales_affected: "all"
|
|
16
|
+
examples:
|
|
17
|
+
- bad: "amount.toFixed(2) for all currencies"
|
|
18
|
+
good: "Use Intl.NumberFormat with currency option which auto-selects correct decimal places"
|
|
19
|
+
- area: "Number Formatting"
|
|
20
|
+
description: "Thousands separators and decimal points vary — 1,234.56 (en) vs 1.234,56 (de) vs 1 234,56 (fr)"
|
|
21
|
+
severity: error
|
|
22
|
+
locales_affected: "all"
|
|
23
|
+
examples:
|
|
24
|
+
- bad: "amount.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',')"
|
|
25
|
+
good: "new Intl.NumberFormat(locale).format(amount)"
|
|
26
|
+
- area: "Regulatory Date Formats"
|
|
27
|
+
description: "Financial regulations often mandate specific date formats — ambiguous dates (01/02/2025) cause compliance issues"
|
|
28
|
+
severity: error
|
|
29
|
+
locales_affected: "all"
|
|
30
|
+
examples:
|
|
31
|
+
- bad: "01/02/2025 (is this Jan 2 or Feb 1?)"
|
|
32
|
+
good: "Use unambiguous formats (2025-01-02) for regulatory documents; locale-specific for user display"
|
|
33
|
+
- area: "Financial Amount Display"
|
|
34
|
+
description: "Negative amounts, accounting notation, and color coding must follow locale conventions"
|
|
35
|
+
severity: warning
|
|
36
|
+
locales_affected: "all"
|
|
37
|
+
examples:
|
|
38
|
+
- bad: "Showing -$1,234.56 in all locales"
|
|
39
|
+
good: "Use Intl.NumberFormat with signDisplay and currencySign: 'accounting' for locale-correct negative display"
|
|
40
|
+
|
|
41
|
+
anti_patterns:
|
|
42
|
+
- pattern: "Hardcoding currency symbol position"
|
|
43
|
+
reason: "Symbol placement varies: $100 (en-US), 100$ (fr-CA), 100 $ (fr-FR)"
|
|
44
|
+
instead: "Use Intl.NumberFormat with currency style which handles symbol placement per locale"
|
|
45
|
+
- pattern: "Converting currencies with hardcoded exchange rates"
|
|
46
|
+
reason: "Exchange rates change constantly; stale rates in code cause incorrect financial displays"
|
|
47
|
+
instead: "Fetch exchange rates from a reliable API; cache with appropriate TTL"
|
|
48
|
+
- pattern: "Using floating point for financial calculations"
|
|
49
|
+
reason: "IEEE 754 floating point causes rounding errors: 0.1 + 0.2 !== 0.3"
|
|
50
|
+
instead: "Use integer arithmetic in smallest currency unit (cents) or a decimal library"
|
|
51
|
+
- pattern: "Displaying amounts without locale-specific accounting format"
|
|
52
|
+
reason: "Negative amounts display differently: -$100 (US), ($100) (accounting), -100$ (other locales)"
|
|
53
|
+
instead: "Use Intl.NumberFormat with currencySign: 'accounting' for financial contexts"
|
|
54
|
+
|
|
55
|
+
regulations:
|
|
56
|
+
- name: "PSD2 (Payment Services Directive 2)"
|
|
57
|
+
locales: ["EU member states"]
|
|
58
|
+
impact: "Transaction amounts must be displayed in the customer's local currency with correct formatting"
|
|
59
|
+
- name: "MiFID II"
|
|
60
|
+
locales: ["EU member states"]
|
|
61
|
+
impact: "Financial documents must show costs in the client's preferred currency with mandated precision"
|
|
62
|
+
- name: "RBI Guidelines"
|
|
63
|
+
locales: ["hi", "en-IN"]
|
|
64
|
+
impact: "Indian Rupee amounts must use Indian number grouping (lakhs/crores) in customer-facing displays"
|
|
65
|
+
|
|
66
|
+
reference_products: ["wise.com", "stripe.com", "revolut.com", "mercury.com"]
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
name: "Gaming"
|
|
2
|
+
description: "i18n challenges in gaming — character limits in UI, cultural adaptation, rating systems, and in-game text rendering"
|
|
3
|
+
|
|
4
|
+
requirements:
|
|
5
|
+
- area: "Character Limits in HUD/UI"
|
|
6
|
+
description: "Game HUDs and menus have fixed-width pixel budgets — translated text must fit without overflow"
|
|
7
|
+
severity: error
|
|
8
|
+
locales_affected: "all"
|
|
9
|
+
examples:
|
|
10
|
+
- bad: "Fixed 120px button with English text 'Attack' that becomes 'Angreifen' (German, does not fit)"
|
|
11
|
+
good: "Design UI with flexible text containers or set per-locale character limits with translator guidance"
|
|
12
|
+
- area: "Cultural Adaptation"
|
|
13
|
+
description: "Colors, gestures, symbols, and themes have different meanings across cultures"
|
|
14
|
+
severity: warning
|
|
15
|
+
locales_affected: "all"
|
|
16
|
+
examples:
|
|
17
|
+
- bad: "Using white for death/mourning themes globally (white = mourning in East Asia, black in Western cultures)"
|
|
18
|
+
good: "Audit cultural symbols and adapt color meanings, gestures, and imagery per target market"
|
|
19
|
+
- area: "Rating Systems"
|
|
20
|
+
description: "Age ratings differ by region — ESRB (US), PEGI (EU), CERO (JP), USK (DE) have different criteria"
|
|
21
|
+
severity: error
|
|
22
|
+
locales_affected: "all"
|
|
23
|
+
examples:
|
|
24
|
+
- bad: "Showing ESRB rating to European players"
|
|
25
|
+
good: "Display the correct regional rating system with proper locale-specific rating icons and descriptions"
|
|
26
|
+
- area: "In-Game Text Rendering"
|
|
27
|
+
description: "Bitmap fonts may not support all scripts; dynamic text needs proper shaping for CJK, Arabic, Devanagari"
|
|
28
|
+
severity: error
|
|
29
|
+
locales_affected: ["ja", "zh-Hans", "zh-Hant", "ko", "ar", "he", "hi", "th"]
|
|
30
|
+
examples:
|
|
31
|
+
- bad: "Using a bitmap font that only contains Latin glyphs for all locales"
|
|
32
|
+
good: "Use Unicode-capable font rendering or locale-specific bitmap fonts with full glyph coverage"
|
|
33
|
+
- area: "Voiceover and Subtitle Synchronization"
|
|
34
|
+
description: "Dubbed audio and subtitles must match game timing — translated dialogue may be longer or shorter"
|
|
35
|
+
severity: warning
|
|
36
|
+
locales_affected: "all"
|
|
37
|
+
examples:
|
|
38
|
+
- bad: "Subtitles that flash too quickly because translated text is longer than English source"
|
|
39
|
+
good: "Adjust subtitle display timing based on translated text length; allow subtitle speed settings"
|
|
40
|
+
|
|
41
|
+
anti_patterns:
|
|
42
|
+
- pattern: "Hardcoding text in texture/sprite assets"
|
|
43
|
+
reason: "Text baked into images cannot be translated without re-creating the entire asset per locale"
|
|
44
|
+
instead: "Render text dynamically over images; use text layers separate from background art"
|
|
45
|
+
- pattern: "Concatenating strings for item descriptions"
|
|
46
|
+
reason: "'Legendary' + 'Sword' + 'of Fire' — word order changes by language, adjective placement varies"
|
|
47
|
+
instead: "Use complete translatable strings: '{quality} {weapon} {element}' with locale-aware ordering"
|
|
48
|
+
- pattern: "Assuming left-to-right menu navigation for all locales"
|
|
49
|
+
reason: "Arabic and Hebrew players expect RTL menu flow and mirrored UI layouts"
|
|
50
|
+
instead: "Mirror the full game UI for RTL locales including menus, HUD, and inventory screens"
|
|
51
|
+
- pattern: "Using player-facing dates without locale formatting"
|
|
52
|
+
reason: "Event dates like '12/1' are ambiguous — December 1 or January 12 depending on locale"
|
|
53
|
+
instead: "Use locale-aware date formatting or unambiguous formats with month names for in-game events"
|
|
54
|
+
- pattern: "Embedding culturally specific humor or idioms"
|
|
55
|
+
reason: "Jokes and idioms rarely translate directly — they fall flat or cause offense in other cultures"
|
|
56
|
+
instead: "Flag humor/idioms for cultural adaptation (not just translation) in localization notes"
|
|
57
|
+
|
|
58
|
+
regulations:
|
|
59
|
+
- name: "ESRB (Entertainment Software Rating Board)"
|
|
60
|
+
locales: ["en-US", "en-CA"]
|
|
61
|
+
impact: "Content descriptors and rating labels must be in English; may require Spanish for US market"
|
|
62
|
+
- name: "PEGI (Pan European Game Information)"
|
|
63
|
+
locales: ["EU member states"]
|
|
64
|
+
impact: "Rating icons and content descriptors must follow PEGI standards; some content prohibited in certain countries"
|
|
65
|
+
- name: "CERO (Computer Entertainment Rating Organization)"
|
|
66
|
+
locales: ["ja"]
|
|
67
|
+
impact: "Japanese rating system with different thresholds; some content requires modification for Japan market"
|
|
68
|
+
|
|
69
|
+
reference_products: ["store.steampowered.com", "playstation.com", "xbox.com", "nintendo.com"]
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
name: "Healthcare"
|
|
2
|
+
description: "i18n challenges in healthcare — patient safety through unambiguous dates, medical terminology precision, and regulatory compliance"
|
|
3
|
+
|
|
4
|
+
requirements:
|
|
5
|
+
- area: "Date Format Safety"
|
|
6
|
+
description: "Ambiguous dates in medical contexts can be life-threatening — 01/02 could mean Jan 2 or Feb 1"
|
|
7
|
+
severity: error
|
|
8
|
+
locales_affected: "all"
|
|
9
|
+
examples:
|
|
10
|
+
- bad: "Prescription date: 01/02/2025"
|
|
11
|
+
good: "Prescription date: 02 Jan 2025 (unambiguous month name format per FDA/EMA guidance)"
|
|
12
|
+
- area: "Medical Terminology Precision"
|
|
13
|
+
description: "Medical terms must not be machine-translated — incorrect translation of drug names or dosages risks patient safety"
|
|
14
|
+
severity: error
|
|
15
|
+
locales_affected: "all"
|
|
16
|
+
examples:
|
|
17
|
+
- bad: "Auto-translating 'once' (English: one time) which means 'eleven' in Spanish"
|
|
18
|
+
good: "Use verified medical glossaries; have translations reviewed by locale-specific medical professionals"
|
|
19
|
+
- area: "Unit of Measurement"
|
|
20
|
+
description: "Dosage units, body measurements, and lab values use different systems by region"
|
|
21
|
+
severity: error
|
|
22
|
+
locales_affected: "all"
|
|
23
|
+
examples:
|
|
24
|
+
- bad: "Displaying weight in pounds for a metric-system locale"
|
|
25
|
+
good: "Detect locale and display in expected units (kg/cm for most locales, lb/in for US)"
|
|
26
|
+
- area: "Patient Consent Forms"
|
|
27
|
+
description: "Informed consent must be in the patient's language and meet local legal requirements"
|
|
28
|
+
severity: error
|
|
29
|
+
locales_affected: "all"
|
|
30
|
+
examples:
|
|
31
|
+
- bad: "Presenting consent form only in English for non-English-speaking patients"
|
|
32
|
+
good: "Provide certified translations of consent forms in all supported patient languages"
|
|
33
|
+
- area: "Instructions for Use (IFU)"
|
|
34
|
+
description: "Medical device IFU must be translated per MDR/IVDR requirements for EU markets"
|
|
35
|
+
severity: error
|
|
36
|
+
locales_affected: ["EU member states"]
|
|
37
|
+
examples:
|
|
38
|
+
- bad: "Shipping medical device with English-only IFU to Germany"
|
|
39
|
+
good: "Include IFU in the official language(s) of each target market per MDR Article 10(11)"
|
|
40
|
+
|
|
41
|
+
anti_patterns:
|
|
42
|
+
- pattern: "Machine-translating drug names or medical procedures"
|
|
43
|
+
reason: "Drug brand names differ by country; procedures have specific medical terminology per locale"
|
|
44
|
+
instead: "Use locale-specific medical dictionaries and have all medical content reviewed by qualified translators"
|
|
45
|
+
- pattern: "Using ambiguous date formats in clinical records"
|
|
46
|
+
reason: "Date misinterpretation in medical contexts can lead to wrong treatment timing"
|
|
47
|
+
instead: "Use DD-MMM-YYYY format (02-Jan-2025) in clinical records per ICH guidelines"
|
|
48
|
+
- pattern: "Displaying lab reference ranges without locale context"
|
|
49
|
+
reason: "Reference ranges and units vary by country (mmol/L vs mg/dL for blood glucose)"
|
|
50
|
+
instead: "Store values in a canonical unit and convert for display based on locale medical conventions"
|
|
51
|
+
- pattern: "Truncating patient names to fit fixed-width fields"
|
|
52
|
+
reason: "Names in many scripts (Arabic, Devanagari, CJK) may be truncated incorrectly, causing identity errors"
|
|
53
|
+
instead: "Use flexible-width name fields; never truncate patient identification information"
|
|
54
|
+
|
|
55
|
+
regulations:
|
|
56
|
+
- name: "FDA 21 CFR Part 11"
|
|
57
|
+
locales: ["en-US"]
|
|
58
|
+
impact: "Electronic records must maintain data integrity including proper date/time formatting"
|
|
59
|
+
- name: "EU MDR (Medical Device Regulation)"
|
|
60
|
+
locales: ["EU member states"]
|
|
61
|
+
impact: "Labeling and IFU must be in the official language(s) of the member state where the device is sold"
|
|
62
|
+
- name: "HIPAA"
|
|
63
|
+
locales: ["en-US"]
|
|
64
|
+
impact: "Translation workflows must maintain PHI security; translators need BAA agreements"
|
|
65
|
+
|
|
66
|
+
reference_products: ["epic.com", "cerner.com", "athenahealth.com"]
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
name: "Legal"
|
|
2
|
+
description: "i18n challenges in legal technology — jurisdiction-specific terminology, unambiguous dates, and certified translation requirements"
|
|
3
|
+
|
|
4
|
+
requirements:
|
|
5
|
+
- area: "Contract Date Formats"
|
|
6
|
+
description: "Ambiguous dates in legal documents can invalidate contracts or cause disputes"
|
|
7
|
+
severity: error
|
|
8
|
+
locales_affected: "all"
|
|
9
|
+
examples:
|
|
10
|
+
- bad: "Effective date: 01/02/2025 (ambiguous month/day)"
|
|
11
|
+
good: "Effective date: 2 January 2025 (unambiguous written month format)"
|
|
12
|
+
- area: "Legal Terminology Precision"
|
|
13
|
+
description: "Legal terms have specific meanings per jurisdiction — 'tort' in common law vs civil law systems"
|
|
14
|
+
severity: error
|
|
15
|
+
locales_affected: "all"
|
|
16
|
+
examples:
|
|
17
|
+
- bad: "Machine-translating 'consideration' (legal: something of value in a contract)"
|
|
18
|
+
good: "Use jurisdiction-specific legal glossaries maintained by qualified legal translators"
|
|
19
|
+
- area: "Jurisdiction-Specific Formatting"
|
|
20
|
+
description: "Legal citations, court names, and statutory references follow jurisdiction-specific formats"
|
|
21
|
+
severity: warning
|
|
22
|
+
locales_affected: "all"
|
|
23
|
+
examples:
|
|
24
|
+
- bad: "Using US legal citation format (Bluebook) for EU legal documents"
|
|
25
|
+
good: "Apply jurisdiction-appropriate citation styles (OSCOLA for UK, Guide des citations for France)"
|
|
26
|
+
- area: "Right-to-Left Legal Documents"
|
|
27
|
+
description: "Legal documents in Arabic and Hebrew must maintain correct reading order, especially for numbered clauses"
|
|
28
|
+
severity: error
|
|
29
|
+
locales_affected: ["ar", "he"]
|
|
30
|
+
examples:
|
|
31
|
+
- bad: "Generating Arabic legal PDF with LTR numbered lists"
|
|
32
|
+
good: "Use RTL-aware document generation with proper clause numbering direction"
|
|
33
|
+
- area: "Certified Translation Requirements"
|
|
34
|
+
description: "Legal documents often require certified or sworn translations with specific attestation formats"
|
|
35
|
+
severity: error
|
|
36
|
+
locales_affected: "all"
|
|
37
|
+
examples:
|
|
38
|
+
- bad: "Using uncertified machine translation for court filings"
|
|
39
|
+
good: "Use certified translators; include translator attestation in format required by target jurisdiction"
|
|
40
|
+
|
|
41
|
+
anti_patterns:
|
|
42
|
+
- pattern: "Machine-translating legal contracts without human review"
|
|
43
|
+
reason: "Legal language is precise and jurisdiction-specific; MT errors can create unintended obligations"
|
|
44
|
+
instead: "Use qualified legal translators with jurisdiction expertise; MT may assist but never replace review"
|
|
45
|
+
- pattern: "Using the same legal terms across jurisdictions"
|
|
46
|
+
reason: "'Privacy policy' has different legal implications and required content across GDPR, CCPA, LGPD, PIPA"
|
|
47
|
+
instead: "Maintain jurisdiction-specific legal content; do not just translate — adapt to local legal frameworks"
|
|
48
|
+
- pattern: "Displaying contract amounts without locale-appropriate number formatting"
|
|
49
|
+
reason: "A contract for 1.000 means 1 in English but 1000 in German — financial disputes result"
|
|
50
|
+
instead: "Spell out amounts in words alongside numerals in legal documents; use locale-correct formatting"
|
|
51
|
+
- pattern: "Fixed-width contract templates for all languages"
|
|
52
|
+
reason: "German legal text expands 30-35% over English; Arabic/Hebrew need RTL-aware templates"
|
|
53
|
+
instead: "Use flexible document templates that adapt to text direction and expansion per locale"
|
|
54
|
+
|
|
55
|
+
regulations:
|
|
56
|
+
- name: "GDPR (Article 12)"
|
|
57
|
+
locales: ["EU member states"]
|
|
58
|
+
impact: "Privacy information must be provided in clear and plain language — implies user's language"
|
|
59
|
+
- name: "LGPD (Brazil)"
|
|
60
|
+
locales: ["pt-BR"]
|
|
61
|
+
impact: "Data processing notices must be in Portuguese and comply with Brazilian data protection law"
|
|
62
|
+
- name: "Hague Convention"
|
|
63
|
+
locales: ["all signatory countries"]
|
|
64
|
+
impact: "International legal documents must follow apostille and translation requirements per country"
|
|
65
|
+
|
|
66
|
+
reference_products: ["clio.com", "docusign.com", "ironclad.com"]
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
locale: "ar"
|
|
2
|
+
name: "Arabic"
|
|
3
|
+
native_name: "العربية"
|
|
4
|
+
script: "Arabic"
|
|
5
|
+
direction: rtl
|
|
6
|
+
cldr_plural_categories: [zero, one, two, few, many, other]
|
|
7
|
+
expansion_factor: 1.25
|
|
8
|
+
script_characteristics:
|
|
9
|
+
avg_char_width: "standard"
|
|
10
|
+
requires_complex_shaping: true
|
|
11
|
+
line_break_rules: "standard"
|
|
12
|
+
bidi_considerations:
|
|
13
|
+
mirror_icons: true
|
|
14
|
+
mirror_layout: true
|
|
15
|
+
mixed_direction_text: true
|
|
16
|
+
calendar_system: "gregorian"
|
|
17
|
+
digit_system: "arabic-indic"
|
|
18
|
+
number_format:
|
|
19
|
+
decimal_separator: "٫"
|
|
20
|
+
grouping_separator: "٬"
|
|
21
|
+
grouping_size: 3
|
|
22
|
+
date_format:
|
|
23
|
+
short: "DD/MM/YYYY"
|
|
24
|
+
long: "DD Month YYYY"
|
|
25
|
+
first_day_of_week: "saturday"
|
|
26
|
+
common_pitfalls:
|
|
27
|
+
- pitfall: "Six plural forms — the most of any major language"
|
|
28
|
+
example: "Arabic has zero, one, two, few (3-10), many (11-99), and other (100+) — binary singular/plural fails"
|
|
29
|
+
fix: "Use ICU MessageFormat with all 6 CLDR categories; test with values 0, 1, 2, 3, 11, and 100"
|
|
30
|
+
- pitfall: "Letter reshaping based on position"
|
|
31
|
+
example: "Arabic letters change shape depending on position (initial, medial, final, isolated)"
|
|
32
|
+
fix: "Never split Arabic strings mid-word; use proper Arabic-capable fonts and text rendering engines"
|
|
33
|
+
- pitfall: "Layout mirroring — not just text direction"
|
|
34
|
+
example: "Navigation, icons, progress bars, and sliders must all mirror for RTL"
|
|
35
|
+
fix: "Use CSS logical properties (margin-inline-start, padding-inline-end) instead of left/right"
|
|
36
|
+
- pitfall: "Mixed LTR content within RTL context"
|
|
37
|
+
example: "Numbers, URLs, code, and brand names remain LTR within an RTL paragraph — bidi algorithm needed"
|
|
38
|
+
fix: "Use Unicode bidi algorithm correctly; wrap embedded LTR content with dir='ltr' or bidi control characters"
|
|
39
|
+
- pitfall: "Arabic-Indic digits vs Western digits"
|
|
40
|
+
example: "Some Arabic locales use ٠١٢٣٤٥٦٧٨٩ instead of 0123456789 — user expectation varies by region"
|
|
41
|
+
fix: "Default to Western digits for digital interfaces; provide Arabic-Indic digit option per user preference"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
locale: "de"
|
|
2
|
+
name: "German"
|
|
3
|
+
native_name: "Deutsch"
|
|
4
|
+
script: "Latin"
|
|
5
|
+
direction: ltr
|
|
6
|
+
cldr_plural_categories: [one, other]
|
|
7
|
+
expansion_factor: 1.35
|
|
8
|
+
script_characteristics:
|
|
9
|
+
avg_char_width: "narrow"
|
|
10
|
+
requires_complex_shaping: false
|
|
11
|
+
line_break_rules: "standard"
|
|
12
|
+
number_format:
|
|
13
|
+
decimal_separator: ","
|
|
14
|
+
grouping_separator: "."
|
|
15
|
+
grouping_size: 3
|
|
16
|
+
date_format:
|
|
17
|
+
short: "DD.MM.YYYY"
|
|
18
|
+
long: "DD. Month YYYY"
|
|
19
|
+
first_day_of_week: "monday"
|
|
20
|
+
common_pitfalls:
|
|
21
|
+
- pitfall: "Long compound words overflowing containers"
|
|
22
|
+
example: "'Geschwindigkeitsbegrenzung' (speed limit) is 26 characters with no natural break point"
|
|
23
|
+
fix: "Use CSS hyphens: auto with lang='de', or soft hyphens (U+00AD) for compound word break hints"
|
|
24
|
+
- pitfall: "Formal vs informal address (Sie/du)"
|
|
25
|
+
example: "Using informal 'du' in a banking app where formal 'Sie' is expected"
|
|
26
|
+
fix: "Establish formal/informal convention per product and apply consistently across all translations"
|
|
27
|
+
- pitfall: "Noun capitalization rules"
|
|
28
|
+
example: "Lowercasing a translated noun — all German nouns are capitalized regardless of position"
|
|
29
|
+
fix: "Never apply text-transform: lowercase to German text; preserve translator-specified capitalization"
|
|
30
|
+
- pitfall: "Text expansion of 30-35% breaking UI layouts"
|
|
31
|
+
example: "'Submit' (6 chars) becomes 'Absenden' (8 chars); 'Settings' becomes 'Einstellungen' (13 chars)"
|
|
32
|
+
fix: "Design for at least 35% text expansion; German is often the longest common Western European language"
|
|
33
|
+
- pitfall: "Date format with periods"
|
|
34
|
+
example: "Using DD/MM/YYYY instead of DD.MM.YYYY — German dates use periods as separators"
|
|
35
|
+
fix: "Use Intl.DateTimeFormat('de') for correct date formatting with period separators"
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
locale: "en"
|
|
2
|
+
name: "English"
|
|
3
|
+
native_name: "English"
|
|
4
|
+
script: "Latin"
|
|
5
|
+
direction: ltr
|
|
6
|
+
cldr_plural_categories: [one, other]
|
|
7
|
+
expansion_factor: 1.0
|
|
8
|
+
script_characteristics:
|
|
9
|
+
avg_char_width: "narrow"
|
|
10
|
+
requires_complex_shaping: false
|
|
11
|
+
line_break_rules: "standard"
|
|
12
|
+
number_format:
|
|
13
|
+
decimal_separator: "."
|
|
14
|
+
grouping_separator: ","
|
|
15
|
+
grouping_size: 3
|
|
16
|
+
date_format:
|
|
17
|
+
short: "MM/DD/YYYY"
|
|
18
|
+
long: "Month DD, YYYY"
|
|
19
|
+
first_day_of_week: "sunday"
|
|
20
|
+
common_pitfalls:
|
|
21
|
+
- pitfall: "Assuming English word order applies universally"
|
|
22
|
+
example: "'Welcome, {name}!' — many languages place the name first or use different greeting structures"
|
|
23
|
+
fix: "Use complete translatable sentences with placeholders, never concatenate greeting + name"
|
|
24
|
+
- pitfall: "Using English-only date format assumptions"
|
|
25
|
+
example: "03/04/2025 is March 4 in US English but April 3 in most other locales"
|
|
26
|
+
fix: "Always use locale-aware date formatting (Intl.DateTimeFormat) and avoid ambiguous numeric dates"
|
|
27
|
+
- pitfall: "Hardcoding singular/plural as the only two forms"
|
|
28
|
+
example: "count === 1 ? 'item' : 'items' — works for English but fails for languages with more plural forms"
|
|
29
|
+
fix: "Use ICU MessageFormat or framework plural support that references CLDR plural rules"
|
|
30
|
+
- pitfall: "Relying on ASCII-only input validation"
|
|
31
|
+
example: "Regex [a-zA-Z]+ rejects valid names like 'René' or 'Müller'"
|
|
32
|
+
fix: "Use Unicode-aware patterns (\\p{Letter}) or avoid restricting character sets in name fields"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
locale: "es"
|
|
2
|
+
name: "Spanish"
|
|
3
|
+
native_name: "Español"
|
|
4
|
+
script: "Latin"
|
|
5
|
+
direction: ltr
|
|
6
|
+
cldr_plural_categories: [one, other]
|
|
7
|
+
expansion_factor: 1.25
|
|
8
|
+
script_characteristics:
|
|
9
|
+
avg_char_width: "narrow"
|
|
10
|
+
requires_complex_shaping: false
|
|
11
|
+
line_break_rules: "standard"
|
|
12
|
+
number_format:
|
|
13
|
+
decimal_separator: ","
|
|
14
|
+
grouping_separator: "."
|
|
15
|
+
grouping_size: 3
|
|
16
|
+
date_format:
|
|
17
|
+
short: "DD/MM/YYYY"
|
|
18
|
+
long: "DD de Month de YYYY"
|
|
19
|
+
first_day_of_week: "monday"
|
|
20
|
+
common_pitfalls:
|
|
21
|
+
- pitfall: "Ignoring inverted punctuation marks"
|
|
22
|
+
example: "Displaying 'How are you?' without the opening inverted question mark"
|
|
23
|
+
fix: "Spanish requires opening punctuation: 'Como estas?' — ensure translation tools preserve these characters"
|
|
24
|
+
- pitfall: "Not accounting for es-ES vs es-MX vs es-419 differences"
|
|
25
|
+
example: "Using 'ordenador' (Spain) when targeting Latin America where 'computadora' is standard"
|
|
26
|
+
fix: "Support regional variants (es-ES, es-MX, es-419) or use neutral Spanish as a fallback"
|
|
27
|
+
- pitfall: "Assuming gender-neutral nouns"
|
|
28
|
+
example: "Translating 'the user' — Spanish requires gendered articles (el usuario / la usuaria)"
|
|
29
|
+
fix: "Design UI strings to avoid gendered references or provide both forms where grammar requires it"
|
|
30
|
+
- pitfall: "Text expansion breaking fixed-width layouts"
|
|
31
|
+
example: "'Settings' (8 chars) becomes 'Configuracion' (13 chars) — a 62% expansion"
|
|
32
|
+
fix: "Design containers to accommodate 20-25% text expansion; test with Spanish translations early"
|
|
33
|
+
- pitfall: "Incorrect number formatting"
|
|
34
|
+
example: "Displaying 1,234.56 instead of 1.234,56 for Spanish locales"
|
|
35
|
+
fix: "Use Intl.NumberFormat('es') to format numbers with correct decimal comma and period grouping"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
locale: "fi"
|
|
2
|
+
name: "Finnish"
|
|
3
|
+
native_name: "Suomi"
|
|
4
|
+
script: "Latin"
|
|
5
|
+
direction: ltr
|
|
6
|
+
cldr_plural_categories: [one, other]
|
|
7
|
+
expansion_factor: 1.40
|
|
8
|
+
script_characteristics:
|
|
9
|
+
avg_char_width: "narrow"
|
|
10
|
+
requires_complex_shaping: false
|
|
11
|
+
line_break_rules: "standard"
|
|
12
|
+
number_format:
|
|
13
|
+
decimal_separator: ","
|
|
14
|
+
grouping_separator: "\u00A0"
|
|
15
|
+
grouping_size: 3
|
|
16
|
+
date_format:
|
|
17
|
+
short: "DD.MM.YYYY"
|
|
18
|
+
long: "DD. MonthTA YYYY"
|
|
19
|
+
first_day_of_week: "monday"
|
|
20
|
+
common_pitfalls:
|
|
21
|
+
- pitfall: "Extreme text expansion due to agglutinative grammar"
|
|
22
|
+
example: "'in the house' translates to 'talossa' (one word); but compound phrases can be very long"
|
|
23
|
+
fix: "Design for up to 40% expansion; Finnish is one of the longest Western languages for UI strings"
|
|
24
|
+
- pitfall: "15 grammatical cases affecting word forms"
|
|
25
|
+
example: "'talo' (house) has forms: talon, taloa, talossa, talosta, taloon, talolla, talolta, talolle..."
|
|
26
|
+
fix: "Never programmatically construct Finnish phrases — let translators handle case inflection in full sentences"
|
|
27
|
+
- pitfall: "Vowel harmony in suffixes"
|
|
28
|
+
example: "Suffixes must match the vowel pattern of the root word — back vowels (a, o, u) vs front vowels (ä, ö, y)"
|
|
29
|
+
fix: "Do not attempt to programmatically add Finnish suffixes; always use translator-provided complete forms"
|
|
30
|
+
- pitfall: "No grammatical gender but complex number agreement"
|
|
31
|
+
example: "Finnish has no gendered nouns, but number-noun agreement is partitive: '1 talo' but '2 taloa'"
|
|
32
|
+
fix: "Use CLDR plural rules (Finnish has only one/other) and let translators handle partitive case in plural form"
|
|
33
|
+
- pitfall: "Long words breaking fixed layouts"
|
|
34
|
+
example: "'lentokonesuihkuturbiinimoottoriapumekaanikkoaliupseerioppilas' — valid compound word"
|
|
35
|
+
fix: "Use CSS overflow-wrap: break-word and hyphens: auto with lang='fi' to handle extreme compound words"
|