(() => {
const cfg = window.APP_CONFIG;
if (!cfg) return;
const base = cfg.baseURL.replace(/\/$/, '');
const form = document.getElementById('generator-form');
if (!form) return;
const $ = id => document.getElementById(id);
const ARTICLE_50_START = '2026-08-02';
const presets = {
// Human/editorial review is a factual workflow statement and must never be inferred.
'no-ai': {extent:'none', activities:'', review:'none'},
research: {extent:'assisted', activities:'research', review:'none'},
summary: {extent:'assisted', activities:'summarisation', review:'none'},
full: {extent:'full', activities:'generation', review:'none'}
};
function value(id) {
const el = $(id);
return el && !el.disabled ? el.value.trim() : '';
}
function validValue(id) {
const el = $(id);
if (!el || el.disabled) return '';
const v = el.value.trim();
return v && (!el.validity || el.validity.valid) ? v : '';
}
function setHidden(id, hidden) {
const el = $(id);
if (!el) return;
el.hidden = hidden;
el.querySelectorAll?.('input,select,textarea').forEach(input => { input.disabled = hidden; });
}
function setArticleParams(params) {
params.set('mode', 'article');
const fields = {
text: 'article-text',
coverImage: 'article-cover-image',
image: 'article-image',
research: 'article-research',
translation: 'article-translation',
audio: 'article-audio',
video: 'article-video',
code: 'article-code'
};
Object.entries(fields).forEach(([name, id]) => {
const extent = $(id).value;
params.set(name + 'Extent', extent);
params.set(name + 'Review', extent === 'none' ? 'none' : $(`${id}-review`).value);
});
}
function legalCategories() {
const values = [];
if (value('legal-deepfake') === 'yes') values.push('deepfake');
if (value('legal-public-interest') === 'yes') values.push('publicInterestText');
if (value('legal-creative') === 'yes') values.push('artisticCreativeSatiricalFictional');
if ($('legal-other-voluntary')?.checked && !$('legal-other-voluntary').disabled) values.push('otherVoluntary');
return values;
}
function substantiveReview(mode) {
return mode === 'editorial' || mode === 'expert';
}
function articleMode() {
return $('declaration-mode').value === 'article';
}
function extentHasAI(extent) {
return Boolean(extent && extent !== 'none');
}
function singleHasAI(component) {
return $('component').value === component && extentHasAI($('extent').value);
}
function articleHasAI(id) {
return extentHasAI($(id)?.value || 'none');
}
function hasAIText() {
return articleMode() ? articleHasAI('article-text') : singleHasAI('text');
}
function hasAIMedia() {
if (articleMode()) {
return ['article-cover-image', 'article-image', 'article-audio', 'article-video'].some(articleHasAI);
}
return ['coverImage', 'image', 'audio', 'video'].includes($('component').value) && extentHasAI($('extent').value);
}
function hasAnyAI() {
if (!articleMode()) return extentHasAI($('extent').value);
return ['article-text','article-cover-image','article-image','article-research','article-translation','article-audio','article-video','article-code'].some(articleHasAI);
}
function currentTextReview() {
if (articleMode()) return $('article-text-review').value;
return $('component').value === 'text' && extentHasAI($('extent').value) ? $('review').value : 'none';
}
function selectedLegalContext() {
return {
role: value('legal-role'),
useContext: value('use-context'),
outputDate: value('output-date'),
deepfakeAssessment: value('legal-deepfake'),
publicInterestAssessment: value('legal-public-interest'),
creativeWorkAssessment: value('legal-creative'),
lawEnforcementAuthorization: value('law-enforcement-authorization'),
categories: legalCategories()
};
}
function legalAssessment(locale) {
const ctx = selectedLegalContext();
const deepfake = ctx.deepfakeAssessment === 'yes' || ctx.categories.includes('deepfake');
const publicInterest = ctx.publicInterestAssessment === 'yes' || ctx.categories.includes('publicInterestText');
const creative = ctx.creativeWorkAssessment === 'yes' || ctx.categories.includes('artisticCreativeSatiricalFictional');
const deepfakeUnsure = ctx.deepfakeAssessment === 'unsure';
const publicInterestUnsure = ctx.publicInterestAssessment === 'unsure';
if (!hasAnyAI()) {
return {text: locale.text.legal_assessment_none, legal: false, level: 'info', consequence: locale.text.consequence_voluntary, badge: locale.text.badge_article || 'Article transparency'};
}
if (!ctx.role || !ctx.useContext) {
return {text: locale.text.legal_assessment_pending, legal: false, level: 'attention', consequence: '', badge: locale.text.badge_article || 'Article transparency'};
}
if (ctx.useContext === 'personalNonProfessional') {
return {text: locale.text.legal_assessment_personal, legal: false, level: 'info', consequence: locale.text.consequence_voluntary, badge: locale.text.badge_article || 'Article transparency'};
}
if (ctx.role === 'provider') {
return {text: locale.text.legal_assessment_provider, legal: false, level: 'attention', consequence: locale.text.consequence_provider, badge: locale.text.badge_article || 'Article transparency'};
}
const mediaRelevant = hasAIMedia();
const textRelevant = hasAIText();
const lawEnforcementRelevant = [ctx.deepfakeAssessment, ctx.publicInterestAssessment].some(v => v === 'yes' || v === 'unsure');
const initialPending = (mediaRelevant && !ctx.deepfakeAssessment)
|| (textRelevant && !ctx.publicInterestAssessment)
|| (lawEnforcementRelevant && !ctx.lawEnforcementAuthorization);
if (initialPending) {
return {text: locale.text.legal_assessment_pending, legal: false, level: 'attention', consequence: '', badge: locale.text.badge_article || 'Article transparency'};
}
if (ctx.outputDate && ctx.outputDate < ARTICLE_50_START) {
return {text: locale.text.legal_assessment_pre_application, legal: false, level: 'info', consequence: locale.text.consequence_voluntary, badge: locale.text.badge_article || 'Article transparency'};
}
if ((deepfake || publicInterest || deepfakeUnsure || publicInterestUnsure) && ctx.lawEnforcementAuthorization === 'yes') {
return {text: locale.text.legal_assessment_law_enforcement, legal: false, level: 'info', consequence: locale.text.consequence_voluntary, badge: locale.text.badge_article || 'Article transparency'};
}
if (ctx.deepfakeAssessment === 'yes' && !ctx.creativeWorkAssessment) {
return {text: locale.text.legal_assessment_pending, legal: false, level: 'attention', consequence: '', badge: locale.text.badge_article || 'Article transparency'};
}
if (deepfakeUnsure) {
return {text: locale.text.legal_assessment_deepfake_unsure, legal: true, level: 'attention', consequence: locale.text.consequence_disclosure, badge: locale.text.badge_legal_disclosure || 'AI-generated / manipulated content'};
}
if (deepfake) {
return {
text: creative ? locale.text.legal_assessment_deepfake_creative : locale.text.legal_assessment_deepfake,
legal: true,
level: 'attention',
consequence: locale.text.consequence_disclosure,
badge: locale.text.badge_legal_disclosure || 'AI-generated / manipulated content'
};
}
if (publicInterestUnsure) {
return {text: locale.text.legal_assessment_public_unsure, legal: true, level: 'attention', consequence: locale.text.consequence_disclosure, badge: locale.text.badge_public_interest || 'AI-generated / edited content'};
}
if (publicInterest) {
const hasResponsibility = Boolean(value('responsible-role') && value('responsible'));
if (substantiveReview(currentTextReview()) && hasResponsibility) {
return {text: locale.text.legal_assessment_public_exemption, legal: false, level: 'info', consequence: locale.text.consequence_voluntary, badge: locale.text.badge_article || 'Article transparency'};
}
return {text: locale.text.legal_assessment_public_required, legal: true, level: 'attention', consequence: locale.text.consequence_disclosure, badge: locale.text.badge_public_interest || 'AI-generated / edited content'};
}
if (ctx.categories.includes('otherVoluntary')) {
return {text: locale.text.legal_assessment_voluntary, legal: false, level: 'info', consequence: locale.text.consequence_voluntary, badge: locale.text.badge_article || 'Article transparency'};
}
return {text: locale.text.legal_assessment_none, legal: false, level: 'info', consequence: locale.text.consequence_voluntary, badge: locale.text.badge_article || 'Article transparency'};
}
function renderAssessment(locale, assessment) {
const target = $('legal-assessment');
if (!target) return;
target.replaceChildren();
const heading = document.createElement('strong');
heading.textContent = locale.text.legal_assessment_heading || 'Article 50 assessment';
const text = document.createElement('span');
text.textContent = assessment.text || '';
const consequence = document.createElement('span');
consequence.className = 'assessment-consequence';
consequence.textContent = assessment.consequence || '';
target.append(heading, text, consequence);
target.dataset.level = assessment.level || (assessment.legal ? 'attention' : 'info');
}
function addValidationMessage(container, text, level = 'warning') {
if (!text) return;
const p = document.createElement('p');
p.className = `validation-message ${level}`;
p.textContent = text;
container.appendChild(p);
}
function renderValidationMessages(locale) {
const target = $('validation-messages');
if (!target) return;
target.replaceChildren();
if (!hasAnyAI()) return;
const ctx = selectedLegalContext();
const categories = ctx.categories;
const review = currentTextReview();
if (ctx.role === 'provider' || ctx.role === 'both') addValidationMessage(target, locale.text.validation_provider, 'info');
if (ctx.role === 'unsure') addValidationMessage(target, locale.text.validation_role_unsure);
if (ctx.useContext === 'personalNonProfessional') addValidationMessage(target, locale.text.validation_personal, 'info');
if (ctx.useContext === 'unsure') addValidationMessage(target, locale.text.validation_use_context_unsure);
if (ctx.outputDate && ctx.outputDate < ARTICLE_50_START) addValidationMessage(target, locale.text.validation_pre_application, 'info');
if (ctx.lawEnforcementAuthorization === 'unsure') addValidationMessage(target, locale.text.validation_law_enforcement_unsure);
if (ctx.deepfakeAssessment === 'unsure') addValidationMessage(target, locale.text.validation_deepfake_unsure);
if (ctx.publicInterestAssessment === 'unsure') addValidationMessage(target, locale.text.validation_public_unsure);
if (ctx.creativeWorkAssessment === 'unsure') addValidationMessage(target, locale.text.validation_creative_unsure, 'info');
if (categories.includes('publicInterestText') && !hasAIText()) addValidationMessage(target, locale.text.validation_public_no_ai);
if (categories.includes('deepfake') && !hasAIMedia()) addValidationMessage(target, locale.text.validation_deepfake_no_media);
if (categories.includes('publicInterestText') && review === 'basic') addValidationMessage(target, locale.text.validation_formal_review);
if (categories.includes('publicInterestText') && substantiveReview(review) && (!value('responsible-role') || !value('responsible'))) {
addValidationMessage(target, locale.text.validation_missing_responsibility);
}
const complaintStarted = value('complaint-name') || value('complaint-email') || value('complaint-url');
if (complaintStarted && (!value('complaint-name') || (!validValue('complaint-email') && !validValue('complaint-url')))) {
addValidationMessage(target, locale.text.validation_complaint_incomplete || 'Complete the complaint contact with a name and at least one valid contact method.');
}
}
function syncVisibility(locale) {
const isArticle = articleMode();
$('single-fields').hidden = isArticle;
$('article-fields').hidden = !isArticle;
const noSingleAI = !isArticle && !extentHasAI($('extent').value);
setHidden('single-review-field', noSingleAI);
setHidden('single-activities-field', noSingleAI);
if (noSingleAI) $('review').value = 'none';
document.querySelectorAll('#article-fields select[data-review]').forEach(extentSelect => {
const reviewID = extentSelect.dataset.review;
const wrap = document.querySelector(`[data-review-wrap="${reviewID}"]`);
const hidden = extentSelect.value === 'none';
if (wrap) {
wrap.hidden = hidden;
const reviewSelect = $(reviewID);
if (reviewSelect) {
reviewSelect.disabled = hidden;
if (hidden) reviewSelect.value = 'none';
}
}
});
const anyAI = hasAnyAI();
setHidden('legal-context-builder', !anyAI);
$('legal-role').required = anyAI;
$('use-context').required = anyAI;
$('legal-role').disabled = !anyAI;
$('use-context').disabled = !anyAI;
if (!anyAI) {
$('legal-role').value = '';
$('use-context').value = '';
['legal-deepfake','legal-public-interest','legal-creative','law-enforcement-authorization'].forEach(id => { if ($(id)) $(id).value = ''; });
if ($('legal-other-voluntary')) $('legal-other-voluntary').checked = false;
setHidden('legal-deepfake-row', true);
setHidden('legal-public-interest-row', true);
setHidden('legal-creative-row', true);
setHidden('law-enforcement-fields', true);
setHidden('legal-timing-fields', true);
setHidden('legal-other-voluntary-row', true);
}
if (anyAI) {
const prerequisitesAnswered = Boolean(value('legal-role') && value('use-context'));
const deployerScopeRelevant = prerequisitesAnswered && value('use-context') !== 'personalNonProfessional' && value('legal-role') !== 'provider';
const mediaRelevant = deployerScopeRelevant && hasAIMedia();
const textRelevant = deployerScopeRelevant && hasAIText();
setHidden('legal-deepfake-row', !mediaRelevant);
$('legal-deepfake').required = mediaRelevant;
$('legal-deepfake').disabled = !mediaRelevant;
if (!mediaRelevant) $('legal-deepfake').value = '';
setHidden('legal-public-interest-row', !textRelevant);
$('legal-public-interest').required = textRelevant;
$('legal-public-interest').disabled = !textRelevant;
if (!textRelevant) $('legal-public-interest').value = '';
const legalExceptionRelevant = deployerScopeRelevant && [value('legal-deepfake'), value('legal-public-interest')].some(v => v === 'yes' || v === 'unsure');
setHidden('law-enforcement-fields', !legalExceptionRelevant);
$('law-enforcement-authorization').required = legalExceptionRelevant;
$('law-enforcement-authorization').disabled = !legalExceptionRelevant;
if (!legalExceptionRelevant) $('law-enforcement-authorization').value = '';
const creativeRelevant = mediaRelevant && value('legal-deepfake') === 'yes' && ['no', 'unsure'].includes(value('law-enforcement-authorization'));
setHidden('legal-creative-row', !creativeRelevant);
$('legal-creative').required = creativeRelevant;
$('legal-creative').disabled = !creativeRelevant;
if (!creativeRelevant) $('legal-creative').value = '';
const allRelevantScopeQuestionsResolvedNo = deployerScopeRelevant && (!mediaRelevant || value('legal-deepfake') === 'no') && (!textRelevant || value('legal-public-interest') === 'no');
const noContentScopeQuestions = deployerScopeRelevant && !mediaRelevant && !textRelevant;
const showVoluntary = noContentScopeQuestions || allRelevantScopeQuestionsResolvedNo;
setHidden('legal-other-voluntary-row', !showVoluntary);
if (!showVoluntary) $('legal-other-voluntary').checked = false;
const legalQuestionAnswered = [value('legal-deepfake'), value('legal-public-interest')].some(Boolean);
setHidden('legal-timing-fields', !deployerScopeRelevant || !legalQuestionAnswered);
$('output-date').disabled = !deployerScopeRelevant || !legalQuestionAnswered;
}
const publicInterest = value('legal-public-interest') === 'yes';
const showResponsibility = anyAI && publicInterest && ['no', 'unsure'].includes(value('law-enforcement-authorization')) && substantiveReview(currentTextReview()) && value('use-context') !== 'personalNonProfessional' && value('legal-role') !== 'provider';
setHidden('responsibility-fields', !showResponsibility);
$('responsible-role').required = showResponsibility;
$('responsible').required = showResponsibility;
const showAuthor = anyAI && (isArticle || hasAIText());
setHidden('author-fields', !showAuthor);
setHidden('author-url-field', !showAuthor || !value('author'));
const accountabilityRelevant = anyAI && [value('legal-deepfake'), value('legal-public-interest')].some(v => v === 'yes' || v === 'unsure') && value('law-enforcement-authorization') !== 'yes' && value('use-context') !== 'personalNonProfessional';
setHidden('complaint-fields', !accountabilityRelevant);
renderValidationMessages(locale);
}
function appendMetadataParams(params) {
if (validValue('subject')) params.set('subject', validValue('subject'));
if (!$('author-fields')?.hidden && value('author')) {
params.set('author', value('author'));
if (validValue('author-url')) params.set('authorUrl', validValue('author-url'));
}
if (!$('responsibility-fields')?.hidden && value('responsible-role') && value('responsible')) {
params.set('responsibleRole', value('responsible-role'));
params.set('responsible', value('responsible'));
if (validValue('responsible-url')) params.set('responsibleUrl', validValue('responsible-url'));
}
if (!$('complaint-fields')?.hidden && value('complaint-name') && (validValue('complaint-email') || validValue('complaint-url'))) {
params.set('complaintName', value('complaint-name'));
if (validValue('complaint-email')) params.set('complaintEmail', validValue('complaint-email'));
if (validValue('complaint-url')) params.set('complaintUrl', validValue('complaint-url'));
}
}
function update(applyPreset = false) {
const isArticle = articleMode();
const preset = $('preset').value;
if (!isArticle && applyPreset && presets[preset]) {
$('extent').value = presets[preset].extent;
$('activities').value = presets[preset].activities;
$('review').value = presets[preset].review;
}
const lang = $('lang').value;
const locale = cfg.locales[lang] || cfg.locales.en;
syncVisibility(locale);
const assurance = $('assurance').value;
const assuranceDescription = locale.text[`assurance_${assurance}_description`];
if ($('assurance-description') && assuranceDescription) $('assurance-description').textContent = assuranceDescription;
const params = new URLSearchParams();
if (isArticle) {
setArticleParams(params);
} else {
if (preset) params.set('preset', preset);
params.set('component', $('component').value);
params.set('extent', $('extent').value);
if (extentHasAI($('extent').value) && $('activities').value.trim()) params.set('activities', $('activities').value.trim());
params.set('review', extentHasAI($('extent').value) ? $('review').value : 'none');
}
params.set('lang', lang);
params.set('assurance', assurance);
if (hasAnyAI() && !$('legal-context-builder').hidden) {
if (value('legal-role')) params.set('legalRole', value('legal-role'));
if (value('use-context')) params.set('useContext', value('use-context'));
if (value('output-date')) params.set('outputDate', value('output-date'));
if (value('legal-deepfake')) params.set('deepfakeAssessment', value('legal-deepfake'));
if (value('legal-public-interest')) params.set('publicInterestAssessment', value('legal-public-interest'));
if (value('legal-creative')) params.set('creativeWorkAssessment', value('legal-creative'));
if (!$('law-enforcement-fields')?.hidden && value('law-enforcement-authorization')) params.set('lawEnforcementAuthorization', value('law-enforcement-authorization'));
const legal = legalCategories();
if (legal.length) params.set('legalContext', legal.join(','));
}
appendMetadataParams(params);
if (cfg.capabilities.custom_text) {
if (value('custom-title')) params.set('customTitle', value('custom-title'));
if (value('custom-description')) params.set('customDescription', value('custom-description'));
}
if (cfg.capabilities.custom_badge) {
if (value('badge-label')) params.set('badgeLabel', value('badge-label'));
if (value('badge-message')) params.set('badgeMessage', value('badge-message'));
if (value('left-color')) params.set('leftColor', value('left-color'));
if (value('right-color')) params.set('rightColor', value('right-color'));
}
const declarationURL = `${base}/declaration?${params}`;
const badgeParams = new URLSearchParams(params);
badgeParams.set('theme', $('theme').value);
badgeParams.set('link', declarationURL);
const badgeURL = `${base}/v1/badge.svg?${badgeParams}`;
const manifestURL = `${base}/v1/declaration.json?${params}`;
const assessment = legalAssessment(locale);
renderAssessment(locale, assessment);
const alt = assessment.legal
? assessment.badge
: (isArticle
? (locale.text.badge_article || 'Article transparency')
: ((locale.presets[preset] && locale.presets[preset].title) || locale.extents[$('extent').value] || 'AI usage disclosure'));
$('preview-badge').src = badgeURL;
$('preview-badge').alt = alt;
$('preview-link').href = declarationURL;
const imageMarkup = `
`;
$('html-code').value = assessment.legal && $('theme').value === 'emoji'
? `${imageMarkup} ${assessment.badge}`
: imageMarkup;
$('markdown-code').value = assessment.legal && $('theme').value === 'emoji'
? `[](${declarationURL}) **${assessment.badge}**`
: `[](${declarationURL})`;
$('json-code').value = manifestURL;
const bulkLink = $('bulk-template-link');
if (bulkLink) {
bulkLink.hidden = !cfg.bulkURL;
if (cfg.bulkURL) {
const bulkParams = new URLSearchParams(params);
bulkParams.delete('subject');
bulkParams.delete('link');
const payload = {version: 1, query: bulkParams.toString(), theme: $('theme').value};
bulkLink.href = `${cfg.bulkURL}/#template=${encodeURIComponent(JSON.stringify(payload))}`;
}
}
}
function enforceLegalExclusivity(changedId) {
if (['legal-deepfake','legal-public-interest'].includes(changedId) && ['yes','unsure'].includes(value(changedId)) && $('legal-other-voluntary')) {
$('legal-other-voluntary').checked = false;
}
}
form.addEventListener('input', event => {
enforceLegalExclusivity(event.target.id);
update(event.target.id === 'preset');
});
form.addEventListener('change', event => {
enforceLegalExclusivity(event.target.id);
update(event.target.id === 'preset');
});
document.querySelector('.pro-panel')?.addEventListener('input', () => update(false));
$('copy-html')?.addEventListener('click', async () => {
await navigator.clipboard.writeText($('html-code').value);
const locale = cfg.locales[$('lang').value] || cfg.locales.en;
$('copy-html').textContent = locale.text.copied || 'Copied';
setTimeout(() => { $('copy-html').textContent = locale.text.copy_html || 'Copy HTML'; }, 1600);
});
$('page-language')?.addEventListener('change', event => {
const url = new URL(window.location.href);
url.searchParams.set('lang', event.target.value);
window.location.href = url.toString();
});
update(true);
})();