feat: add Legal Translation tool (translate.php)
New dedicated tool for translating Norwegian legal documents (Barnevernet letters, court decisions, correspondence) into the user's chosen language with legal-terminology annotations. - translate.php: new tool page with source/target language selectors, 4-way UI lang switcher, file upload, doc picker, streaming results - api/translate.php: NDJSON streaming endpoint; Azure GPT-4o-mini with legal-aware prompt that preserves Norwegian statute refs verbatim and annotates terms with no target-language equivalent; 2-credit cost - assets/js/translate.js: form handler, NDJSON stream reader, copy button - assets/css/tools.css: .lt-* styles for translation result + annotations - includes/i18n.php: 22 lt_* keys × 4 languages; translate entry in nav - includes/FreeTier.php: translate → 2 credits - includes/CaseResults.php + case-result.php: translate in eligible tools, toolLabel, toolIcon, deriveTitle, rendering block, rerun map Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -34,6 +34,7 @@ final class CaseResults
|
||||
'redact',
|
||||
'transcribe',
|
||||
'legal-analysis',
|
||||
'translate',
|
||||
];
|
||||
|
||||
/** True when the user is on a tier that gets saved results (Plus, Pro, or active Plus trial). */
|
||||
@@ -240,6 +241,7 @@ final class CaseResults
|
||||
'redact' => 'Anonymisering',
|
||||
'transcribe' => 'Transkripsjon',
|
||||
'legal-analysis' => 'Juridisk analyse',
|
||||
'translate' => 'Oversettelse',
|
||||
][$tool] ?? ucfirst($tool);
|
||||
}
|
||||
|
||||
@@ -258,6 +260,7 @@ final class CaseResults
|
||||
'redact' => '🖊️',
|
||||
'transcribe' => '🎙️',
|
||||
'legal-analysis' => '⚖️🇳🇴',
|
||||
'translate' => '🌐',
|
||||
][$tool] ?? '📄';
|
||||
}
|
||||
|
||||
@@ -276,6 +279,7 @@ final class CaseResults
|
||||
'redact' => [$input['text'] ?? null],
|
||||
'transcribe' => [$input['filename'] ?? null],
|
||||
'legal-analysis' => [$input['doc_type'] ?? null, $input['text'] ?? null],
|
||||
'translate' => [$input['source_lang'] ?? null, $input['target_lang'] ?? null, $input['text'] ?? null],
|
||||
default => [$input['title'] ?? null, $input['query'] ?? null, $input['text'] ?? null],
|
||||
};
|
||||
foreach ($candidates as $c) {
|
||||
|
||||
@@ -38,6 +38,7 @@ final class FreeTier
|
||||
'transcribe' => 2,
|
||||
'discrepancy' => 4,
|
||||
'korrespond' => 3,
|
||||
'translate' => 2,
|
||||
];
|
||||
|
||||
/** Monthly credit allowance per tier. */
|
||||
|
||||
+98
-1
@@ -435,6 +435,29 @@ function dbnToolsTranslations(): array
|
||||
'la_addon_button' => '⚖️🇳🇴 Run deep legal analysis on this text',
|
||||
'la_addon_button_busy' => 'Running deep legal analysis…',
|
||||
'la_addon_section' => 'Deep Legal Analysis',
|
||||
|
||||
'lt_source_label' => 'Source language',
|
||||
'lt_target_label' => 'Translate to',
|
||||
'lt_doc_type_label' => 'Document type',
|
||||
'lt_run_button' => 'Translate document',
|
||||
'lt_run_button_busy' => 'Translating…',
|
||||
'lt_input_label' => 'Paste text to translate',
|
||||
'lt_input_hint' => '(optional if uploading files)',
|
||||
'lt_input_placeholder' => 'Paste Norwegian legal text here…',
|
||||
'lt_translating_status' => 'Translating…',
|
||||
'lt_ready_title' => 'Ready to translate',
|
||||
'lt_ready_intro' => 'Upload a PDF, DOCX or TXT, or paste text below.',
|
||||
'lt_result_title' => 'Translation',
|
||||
'lt_annotations_title' => 'Legal term notes',
|
||||
'lt_copy_button' => 'Copy translation',
|
||||
'lt_copy_done' => 'Copied!',
|
||||
'lt_need_input' => 'Please paste text or upload a file.',
|
||||
'lt_error_prefix' => 'Error',
|
||||
'lt_server_returned' => 'Server returned',
|
||||
'lt_extracting_files' => 'Extracting text from {n} file(s)…',
|
||||
'lt_engine_hint' => 'Engine: Azure GPT-4o · Legal documents are processed in memory and never stored.',
|
||||
'lt_same_lang_error' => 'Source and target languages must be different.',
|
||||
'lt_disclaimer' => 'This is an AI-assisted translation. Always verify with a qualified legal interpreter for official use.',
|
||||
],
|
||||
'no' => [
|
||||
'meta_title' => 'Do Better Norge - juridiske AI-verktøy',
|
||||
@@ -802,6 +825,29 @@ function dbnToolsTranslations(): array
|
||||
'la_addon_button' => '⚖️🇳🇴 Kjør dyp juridisk analyse på denne teksten',
|
||||
'la_addon_button_busy' => 'Kjører dyp juridisk analyse…',
|
||||
'la_addon_section' => 'Dyp juridisk analyse',
|
||||
|
||||
'lt_source_label' => 'Kildespråk',
|
||||
'lt_target_label' => 'Oversett til',
|
||||
'lt_doc_type_label' => 'Dokumenttype',
|
||||
'lt_run_button' => 'Oversett dokument',
|
||||
'lt_run_button_busy' => 'Oversetter…',
|
||||
'lt_input_label' => 'Lim inn tekst som skal oversettes',
|
||||
'lt_input_hint' => '(valgfritt ved filopplasting)',
|
||||
'lt_input_placeholder' => 'Lim inn norsk juridisk tekst her…',
|
||||
'lt_translating_status' => 'Oversetter…',
|
||||
'lt_ready_title' => 'Klar til å oversette',
|
||||
'lt_ready_intro' => 'Last opp PDF, DOCX eller TXT, eller lim inn tekst nedenfor.',
|
||||
'lt_result_title' => 'Oversettelse',
|
||||
'lt_annotations_title' => 'Juridiske termer',
|
||||
'lt_copy_button' => 'Kopier oversettelse',
|
||||
'lt_copy_done' => 'Kopiert!',
|
||||
'lt_need_input' => 'Lim inn tekst eller last opp en fil.',
|
||||
'lt_error_prefix' => 'Feil',
|
||||
'lt_server_returned' => 'Serveren svarte',
|
||||
'lt_extracting_files' => 'Henter tekst fra {n} fil(er)…',
|
||||
'lt_engine_hint' => 'Motor: Azure GPT-4o · Juridiske dokumenter behandles i minnet og lagres aldri.',
|
||||
'lt_same_lang_error' => 'Kilde- og målspråk må være forskjellige.',
|
||||
'lt_disclaimer' => 'Dette er en AI-assistert oversettelse. Verifiser alltid med en kvalifisert juridisk tolk til offisielt bruk.',
|
||||
],
|
||||
'uk' => [
|
||||
'meta_title' => 'Do Better Norge - юридичні AI інструменти',
|
||||
@@ -1169,6 +1215,29 @@ function dbnToolsTranslations(): array
|
||||
'la_addon_button' => '⚖️🇳🇴 Запустити глибокий юридичний аналіз цього тексту',
|
||||
'la_addon_button_busy' => 'Виконується глибокий юридичний аналіз…',
|
||||
'la_addon_section' => 'Глибокий юридичний аналіз',
|
||||
|
||||
'lt_source_label' => 'Мова оригіналу',
|
||||
'lt_target_label' => 'Перекласти на',
|
||||
'lt_doc_type_label' => 'Тип документу',
|
||||
'lt_run_button' => 'Перекласти документ',
|
||||
'lt_run_button_busy' => 'Перекладаю…',
|
||||
'lt_input_label' => 'Вставте текст для перекладу',
|
||||
'lt_input_hint' => '(необов\'язково при завантаженні)',
|
||||
'lt_input_placeholder' => 'Вставте норвезький юридичний текст тут…',
|
||||
'lt_translating_status' => 'Перекладаю…',
|
||||
'lt_ready_title' => 'Готовий до перекладу',
|
||||
'lt_ready_intro' => 'Завантажте PDF, DOCX або TXT, або вставте текст нижче.',
|
||||
'lt_result_title' => 'Переклад',
|
||||
'lt_annotations_title' => 'Юридичні терміни',
|
||||
'lt_copy_button' => 'Копіювати переклад',
|
||||
'lt_copy_done' => 'Скопійовано!',
|
||||
'lt_need_input' => 'Будь ласка, вставте текст або завантажте файл.',
|
||||
'lt_error_prefix' => 'Помилка',
|
||||
'lt_server_returned' => 'Сервер повернув',
|
||||
'lt_extracting_files' => 'Витягую текст з {n} файл(ів)…',
|
||||
'lt_engine_hint' => 'Механізм: Azure GPT-4o · Юридичні документи обробляються в пам\'яті та не зберігаються.',
|
||||
'lt_same_lang_error' => 'Мова оригіналу та мова перекладу повинні бути різними.',
|
||||
'lt_disclaimer' => 'Це переклад за допомогою штучного інтелекту. Завжди перевіряйте з кваліфікованим юридичним перекладачем для офіційного використання.',
|
||||
],
|
||||
'pl' => [
|
||||
'meta_title' => 'Do Better Norge - prawne narzędzia AI',
|
||||
@@ -1536,6 +1605,29 @@ function dbnToolsTranslations(): array
|
||||
'la_addon_button' => '⚖️🇳🇴 Uruchom głęboką analizę prawną tego tekstu',
|
||||
'la_addon_button_busy' => 'Trwa głęboka analiza prawna…',
|
||||
'la_addon_section' => 'Głęboka analiza prawna',
|
||||
|
||||
'lt_source_label' => 'Język źródłowy',
|
||||
'lt_target_label' => 'Przetłumacz na',
|
||||
'lt_doc_type_label' => 'Typ dokumentu',
|
||||
'lt_run_button' => 'Przetłumacz dokument',
|
||||
'lt_run_button_busy' => 'Tłumaczę…',
|
||||
'lt_input_label' => 'Wklej tekst do tłumaczenia',
|
||||
'lt_input_hint' => '(opcjonalne przy wgrywaniu pliku)',
|
||||
'lt_input_placeholder' => 'Wklej tu norweski tekst prawny…',
|
||||
'lt_translating_status' => 'Tłumaczę…',
|
||||
'lt_ready_title' => 'Gotowy do tłumaczenia',
|
||||
'lt_ready_intro' => 'Prześlij PDF, DOCX lub TXT, lub wklej tekst poniżej.',
|
||||
'lt_result_title' => 'Tłumaczenie',
|
||||
'lt_annotations_title' => 'Terminy prawne',
|
||||
'lt_copy_button' => 'Skopiuj tłumaczenie',
|
||||
'lt_copy_done' => 'Skopiowano!',
|
||||
'lt_need_input' => 'Wklej tekst lub prześlij plik.',
|
||||
'lt_error_prefix' => 'Błąd',
|
||||
'lt_server_returned' => 'Serwer zwrócił',
|
||||
'lt_extracting_files' => 'Wyodrębniam tekst z {n} plik(ów)…',
|
||||
'lt_engine_hint' => 'Silnik: Azure GPT-4o · Dokumenty prawne są przetwarzane w pamięci i nigdy nie zapisywane.',
|
||||
'lt_same_lang_error' => 'Języki źródłowy i docelowy muszą być różne.',
|
||||
'lt_disclaimer' => 'To jest tłumaczenie wspomagane AI. Zawsze weryfikuj z wykwalifikowanym tłumaczem prawnym do oficjalnego użytku.',
|
||||
],
|
||||
];
|
||||
}
|
||||
@@ -1679,6 +1771,7 @@ function dbnToolsLaunchedTools(?string $language = null): array
|
||||
'discrepancy' => ['Discrepancy Finder', 'Document comparison', 'Upload two versions of a Barnevernet document and find contradictions, deleted facts, and new allegations.', 'Cross-document AI'],
|
||||
'corpus' => ['Corpus', 'Legal knowledge base', 'Inspect indexed sources, corpus health, legal categories, and retrieval behavior.', '~220 K passages'],
|
||||
'citations' => ['Citations', 'Citation graph', 'Browse the legal citation graph — what a statute cites, what cites it, and what implements or amends it.', 'Graph topology'],
|
||||
'translate' => ['Translate', 'Legal translation', 'Translate Barnevernet letters and legal documents into your language with legal-terminology annotations.', 'Azure · GPT-4o'],
|
||||
],
|
||||
'no' => [
|
||||
'transcribe' => ['Transkriber', 'Lyd og møter', 'Gjør lyd eller video om til tekst med talerinndeling og juridisk ordforråd.', 'Whisper / GPU'],
|
||||
@@ -1693,6 +1786,7 @@ function dbnToolsLaunchedTools(?string $language = null): array
|
||||
'discrepancy' => ['Avviksfinner', 'Dokumentsammenligning', 'Last opp to versjoner av et barneverndokument og finn motsigelser, slettede fakta og nye påstander.', 'Kryssdokument AI'],
|
||||
'corpus' => ['Korpus', 'Juridisk kunnskapsbase', 'Se indekserte kilder, korpushelse, juridiske kategorier og søkeoppsett.', '~220 K utdrag'],
|
||||
'citations' => ['Siteringer', 'Siteringsgraf', 'Utforsk siteringsgrafen — hva et dokument siterer, hva som siterer det, og hva som implementerer det.', 'Grafstruktur'],
|
||||
'translate' => ['Oversett', 'Juridisk oversettelse', 'Oversett Barnevernet-brev og juridiske dokumenter til ditt språk med juridisk terminologi.', 'Azure · GPT-4o'],
|
||||
],
|
||||
'uk' => [
|
||||
'transcribe' => ['Транскрипція', 'Аудіо та зустрічі', 'Перетворюйте аудіо або відео на текст із розділенням мовців і юридичною лексикою.', 'Whisper / GPU'],
|
||||
@@ -1707,6 +1801,7 @@ function dbnToolsLaunchedTools(?string $language = null): array
|
||||
'discrepancy' => ['Пошук розбіжностей', 'Порівняння документів', 'Завантажте дві версії документа Barnevernet і знайдіть суперечності, видалені факти та нові твердження.', 'Міждокументний AI'],
|
||||
'corpus' => ['Корпус', 'Юридична база знань', 'Переглядайте індексовані джерела, стан корпусу, категорії та поведінку пошуку.', '~220 тис. уривків'],
|
||||
'citations' => ['Граф цитувань', 'Мережа посилань', 'Граф правових посилань — що цитує документ, хто цитує його, що його реалізує.', 'Граф-топологія'],
|
||||
'translate' => ['Перекласти', 'Юридичний переклад', 'Перекладайте листи Barnevernet та юридичні документи на свою мову з юридичними термінами.', 'Azure · GPT-4o'],
|
||||
],
|
||||
'pl' => [
|
||||
'transcribe' => ['Transkrypcja', 'Audio i spotkania', 'Zamień audio lub wideo na tekst z rozdzieleniem mówców i słownictwem prawnym.', 'Whisper / GPU'],
|
||||
@@ -1721,11 +1816,12 @@ function dbnToolsLaunchedTools(?string $language = null): array
|
||||
'discrepancy' => ['Wyszukiwacz rozbieżności', 'Porównanie dokumentów', 'Prześlij dwie wersje dokumentu Barnevernet i znajdź sprzeczności, usunięte fakty i nowe zarzuty.', 'AI Między-dokumentowe'],
|
||||
'corpus' => ['Korpus', 'Prawna baza wiedzy', 'Sprawdzaj indeksowane źródła, stan korpusu, kategorie prawne i działanie wyszukiwania.', '~220 tys. fragmentów'],
|
||||
'citations' => ['Graf cytowań', 'Sieć cytowań', 'Przeglądaj sieć cytowań — co cytuje dokument, kto go cytuje i co go implementuje.', 'Topologia grafu'],
|
||||
'translate' => ['Tłumacz', 'Tłumaczenie prawne', 'Tłumacz listy Barnevernet i dokumenty prawne na swój język z adnotacjami terminologicznymi.', 'Azure · GPT-4o'],
|
||||
],
|
||||
];
|
||||
|
||||
$selected = $copy[$language] ?? $copy['en'];
|
||||
$order = ['transcribe', 'timeline', 'redact', 'summarize', 'legal-analysis', 'korrespond', 'barnevernet', 'advocate', 'deep-research', 'discrepancy', 'corpus', 'citations'];
|
||||
$order = ['transcribe', 'timeline', 'redact', 'summarize', 'legal-analysis', 'korrespond', 'barnevernet', 'advocate', 'deep-research', 'discrepancy', 'corpus', 'citations', 'translate'];
|
||||
$icons = [
|
||||
'transcribe' => 'TR',
|
||||
'timeline' => 'TL',
|
||||
@@ -1739,6 +1835,7 @@ function dbnToolsLaunchedTools(?string $language = null): array
|
||||
'discrepancy' => 'DC',
|
||||
'corpus' => 'KB',
|
||||
'citations' => 'CIT',
|
||||
'translate' => 'TX',
|
||||
];
|
||||
$out = [];
|
||||
foreach ($order as $slug) {
|
||||
|
||||
Reference in New Issue
Block a user