neuron-explorer
Qwen3.5‑4B 전용 조향형 뉴런 탐색기, 모든 MLP 뉴런을 밀어 결과를 보관·탐색
LoyaltyDog은 영국·아일랜드 소매·환대업을 위한 디지털 로열티 프로그램이다
LoyaltyDog is a digital loyalty program for UK and Ireland retail and hospitality. Digital stamp cards, points rewards, and push notifications from $29/month. No setup fees. Try free for 14 days.
개발 도구JavaScript · PythonGitHub @loyaltydog온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Multi-language localization infrastructure for LoyaltyDog platform using Crowding + i18next
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Multi-language localization infrastructure for the LoyaltyDog platform using i18next + a shared i18n package. This repository is the source of truth for every locale. Translations are authored here, in main — there is no external translation service in the loop. This repository contains the shared localization infrastructure used across all LoyaltyDog platforms: • Merchant Dashboard (core_api) • Square Integration • Shopify Integration • EPOSNow Integration • Clover Integration • WordPress Plugin [README 설치·사용 부분 발췌] InstallationREADME 전문 보기 ↗
Multi-language localization infrastructure for the LoyaltyDog platform using i18next + a shared i18n package.
This repository is the source of truth for every locale. Translations are authored here, in main — there is no external translation service in the loop.
This repository contains the shared localization infrastructure used across all LoyaltyDog platforms:
┌─────────────────────────────────────────────────────────────────┐
│ @loyaltydog/i18n (Shared Package) │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ /locales # 11 namespaces × 5,049 keys per locale │ │
│ │ /en-US # Source of truth (English - United States)│ │
│ │ /en-GB # English - United Kingdom │ │
│ │ /es-ES # Spanish - Spain │ │
│ │ /es-MX # Spanish - Mexico │ │
│ │ /fr # French │ │
│ │ /it # Italian │ │
│ │ /pt-BR # Portuguese - Brazil │ │
│ │ /pt-PT # Portuguese - Portugal │ │
│ │ │ │
│ │ /src │ │
│ │ /react/ # i18next integration │ │
│ │ /node/ # Python/FastAPI loader │ │
│ │ /rtl/ # RTL hooks for future │ │
│ │ /__tests__/ # Key parity + placeholder integrity │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ core_api │ │ frontend │ │ Square │
│(FastAPI) │ │ (React) │ │ Shopify │
│ EPOSNow │ │ │ │ Clover │
└──────────┘ └──────────┘ └──────────┘
| Layer | Technology |
|---|---|
| Translation Management | In-repo, AI-authored, reviewed in PRs |
| Shared Package | @loyaltydog/i18n |
| Frontend | i18next + React |
| Backend | JSON loader for FastAPI |
| Quality gate | Vitest key-parity + placeholder tests in CI |
Locale directory names use the hyphenated codes below — these are the exact
strings SUPPORTED_LANGUAGES exports and the only ones the loaders resolve.
| Language | Code | Notes |
|---|---|---|
| English (US) | en-US | Source of truth. US spellings only — British forms belong in en-GB |
| English (GB) | en-GB | British spellings (programme, colour, authorise) |
| Spanish (Spain) | es-ES | AI translated |
| Spanish (Mexico) | es-MX | AI translated |
| French | fr | AI translated |
| Italian | it | AI translated |
| Portuguese (Brazil) | pt-BR | AI translated |
| Portuguese (Portugal) | pt-PT | AI translated |
Total: 5,049 keys per locale across 11 namespaces — every locale carries the identical key set, enforced by the test suite.
| Namespace | Keys | Namespace | Keys | |
|---|---|---|---|---|
common | 2,850 | notifications | 103 | |
wordpress | 618 | clover | 35 | |
giftCards | 536 | marketing | 32 | |
emails | 409 | shopify | 23 | |
errors | 284 | eposnow | 18 | |
validation | 141 |
Important: All platforms should release with English (en-US) only initially, but implement the localization mechanism from day one. This means:
@loyaltydog/i18n packageWhy? This makes future language rollout a simple configuration change rather than a rewrite.
@loyaltydog/i18n is not published to npm — npm install @loyaltydog/i18n
will 404. Consume it from a local path or a git dependency:
// package.json
{
"dependencies": {
// monorepo / sibling checkout
"@loyaltydog/i18n": "file:../localization-platform/packages/i18n"
// or straight from git
// "@loyaltydog/i18n": "github:loyaltydog/localization-platform#main"
}
}
The Python loader is likewise unpublished — vendor src/node/translation_loader.py
into the consuming service, or add packages/i18n/src/node to PYTHONPATH.
For React-based platforms (Core API Dashboard, EPOSNow, Square, Shopify, Clover):
1. Initialize i18next:
// src/i18n.ts or similar entry point
import { initI18n } from '@loyaltydog/i18n/react';
// Initialize with default language (en-US)
initI18n({
// Override default config if needed
detection: {
// For initial release, only support en-US
lookupLocalStorage: 'loyaltydog_language',
caches: ['localStorage'],
},
});
2. Wrap your app with I18nProvider:
// src/App.tsx or similar
import { I18nProvider } from '@loyaltydog/i18n/react';
function App() {
return (
<I18nProvider>
<YourAppRoutes />
</I18nProvider>
);
}
3. Replace hardcoded strings with translation calls:
import { useTranslation } from '@loyaltydog/i18n/react';
function Dashboard() {
const { t } = useTranslation('common');
return (
<div>
<h1>{t('nav.dashboard')}</h1>
<button>{t('actions.save')}</button>
<p>{t('loyalty.member')}: {memberName}</p>
</div>
);
}
4. For dynamic content with variables:
function WelcomeMessage() {
const { t } = useTranslation('notifications');
return (
<p>{t('sms.welcome', {
merchantName: 'Acme Store',
points: '100'
})}</p>
);
}
For Core API backend and Python services:
1. Import the translation loader:
from loyaltydog_i18n import TranslationLoader
# Initialize translator
translator = TranslationLoader()
2. Get translations for a specific language:
# Get translation for a specific language
subject = translator.translate(
language='en-US', # or 'es-ES', 'fr', etc.
namespace='emails',
key='welcome.subject',
merchantName='Acme Store'
)
# List available locales
available_locales = translator.get_available_locales()
3. API endpoint for language switching:
from fastapi import HTTPException
from pydantic import BaseModel
class LanguageUpdate(BaseModel):
language: str # e.g., 'en-US', 'es-ES', 'fr'
@router.put("/merchants/{merchant_id}/language")
async def update_merchant_language(merchant_id: str, data: LanguageUpdate):
"""Update the preferred language for a merchant account."""
# Validate language code using available locales
available = translator.get_available_locales()
if data.language not in available:
raise HTTPException(
status_code=400,
detail=f"Unsupported language. Available: {', '.join(available)}"
)
# Update merchant preference in database
# merchant.language_preference = data.language
# db.commit()
return {"message": "Language updated successfully"}
4. Email templates with translations:
def send_welcome_email(member_email: str, member_name: str, merchant_name: str):
"""Send welcome email using translated template."""
# Get member's preferred language from database
# member = db.query(Member).filter_by(email=member_email).first()
# language = member.language_preference or 'en-US'
language = 'en-US' # Default for initial release
subject = translator.translate(
language, 'emails', 'welcome.subject',
merchantName=merchant_name
)
body = translator.translate(
language, 'emails', 'welcome.body',
memberName=member_name,
merchantName=merchant_name,
passUrl='https://example.com/pass'
)
send_email(member_email, subject, body)
Each merchant account has a language preference setting that controls:
Via API:
curl -X PUT "https://api.loyalty.dog/v2/merchants/{merchant_id}/language" \
-H "Authorization: Bearer {api_token}" \
-H "Content-Type: application/json" \
-d '{
"language": "es-ES"
}'
Via Database (direct, for testing):
UPDATE merchants
SET language_preference = 'es-ES'
WHERE id = '{merchant_id}';
Supported Language Codes:
en-US - English (United States) - Defaulten-GB - English (United Kingdom)es-ES - Spanish (Spain)es-MX - Spanish (Mexico)fr - Frenchit - Italianpt-BR - Portuguese (Brazil)pt-PT - Portuguese (Portugal)If a translation is missing for the merchant's preferred language, the system automatically falls back to:
es-MX → es)This ensures that users always see some text, never blank placeholders.
localization-platform/
├── README.md # This file
├── CLAUDE.md # Project context for AI agents
├── docs/ # Untracked (see .gitignore) — local notes only
├── packages/
│ └── i18n/
│ ├── package.json
│ ├── locales/
│ │ ├── en-US/ # English - United States (source of truth)
│ │ │ ├── common.json # 2,850 keys - dashboard UI
│ │ │ ├── wordpress.json # 618 keys - WP/WooCommerce plugin
│ │ │ ├── giftCards.json # 536 keys - gift card flows
│ │ │ ├── emails.json # 409 keys - email templates
│ │ │ ├── errors.json # 284 keys - error messages
│ │ │ ├── validation.json # 141 keys - form validation
│ │ │ ├── notifications.json # 103 keys - SMS/push
│ │ │ ├── clover.json # 35 keys - Clover integration
│ │ │ ├── marketing.json # 32 keys - landing copy
│ │ │ ├── shopify.json # 23 keys - Shopify integration
│ │ │ └── eposnow.json # 18 keys - EPOSNow integration
│ │ ├── en-GB/ # English - United Kingdom
│ │ ├── es-ES/ # Spanish - Spain
│ │ ├── es-MX/ # Spanish - Mexico
│ │ ├── fr/ # French
│ │ ├── it/ # Italian
│ │ ├── pt-BR/ # Portuguese - Brazil
│ │ └── pt-PT/ # Portuguese - Portugal
│ └── src/
│ ├── react/ # i18next integration
│ ├── node/ # Python/FastAPI loader
│ ├── rtl/ # RTL support hooks
│ └── __tests__/ # Key parity + placeholder integrity tests
└── .github/
└── workflows/
└── ci.yml # Tests, lint, build on push and PR
# Install dependencies
cd packages/i18n
npm install
# Run the locale test suite (key parity + placeholder integrity)
npm test
# Structural validation of the locale files
npm run validate:locales
import { useTranslation } from '@loyaltydog/i18n/react';
function Dashboard() {
const { t } = useTranslation('common');
return <h1>{t('nav.dashboard')}</h1>;
}
from loyaltydog_i18n import TranslationLoader
translator = TranslationLoader()
subject = translator.translate('es-ES', 'emails', 'welcome.subject',
merchantName="Mi Tienda")
Translation happens in this repository. A key and its 7 translations land in the same branch, in the same pull request, and are reviewed together.
locales/en-US/*.json — en-US defines which keys exist{var}, and identical
{{variable}} sets across localesmain — main is the source of truth for every locale@loyaltydog/i18n dependencyThere is no external translation service, no sync step, and no round-trip to wait on. A key that is missing from a target locale is a defect the test suite reports, not a queued item.
1. Choose the right namespace file in packages/i18n/locales/en-US/:
| File | Use for |
|---|---|
common.json | UI labels, navigation, buttons, general strings |
errors.json | Error messages and validation feedback |
emails.json | Email subject lines and body templates |
notifications.json | SMS and push notification templates |
validation.json | Form field validation messages |
giftCards.json | Gift card-specific strings |
2. Add the key using dot-notation nesting in packages/i18n/locales/en-US/common.json:
{
"nav": {
"dashboard": "Dashboard",
"newSection": "My New Section"
}
}
3. Add the same key to all 7 target locales, translating the English value:
en-GB, es-ES, es-MX, fr, it, pt-BR, pt-PT — same file, same dot-path, same
{{variable}} names. Translations are AI-authored; ask Claude to translate the new keys
against the en-US source and to match the tone of the surrounding strings in each file.
Two rules matter more than wording:
{{merchantName}} stays {{merchantName}} in every
locale. Dropping one silently deletes data from the sentence; renaming or inventing one
renders the raw token, because nothing supplies a value for it.translation_loader.py both interpolate {{var}}.
A single-brace {var} renders literally.4. Verify before opening the PR:
cd packages/i18n
npm test
The suite in src/__tests__/ fails on a key present in en-US but absent from a target
locale, on any single-brace {var}, and on any locale whose variable set differs from
en-US. Known pre-existing exceptions are named individually in all-languages.test.js
with the reason each is unresolved — add to those lists only with a reason, never to
silence a new failure.
5. Use the key in code:
// React
const { t } = useTranslation('common');
t('nav.newSection') // → "My New Section"
# Python
translator.translate('es-ES', 'common', 'nav.newSection')
Note:
en-USis the source of truth for which keys exist — always add a new key there first. Target locales are then filled in from it in the same change; a key that exists only in en-US is an incomplete change, not a handoff to someone else.
.github/workflows/ci.yml runs on every push and pull request to main, staging, and
development. It runs the Vitest suite on Node 18, 20, and 22 — including the key-parity
and placeholder-integrity checks that guard the locale files — plus lint and build.
There is no translation sync workflow. Locale files change only through pull requests.
Everything you need is in this file — there is no separate contributing guide:
{{double}}, never {single}; never add,
drop, or rename a variable in a translationen-US takes US spellings only; British forms belong in en-GBlocales/<code>/ with all 11 namespaces, add the
code to SUPPORTED_LANGUAGES in src/index.js and to ALL_LANGUAGES in
src/__tests__/all-languages.test.js, then make the suite passMIT License — see LICENSE.md for details.
Copyright © 2026 LoyaltyDog.